/* src/box/compras_web/estilo.css — identidad BALAM v1.2 (docs/identidad-visual.md).
   El bloque :root se copia tal cual del sitio de pedidos y test_compras_identidad.py
   vigila que no se separen (tarea 8). Los componentes de abajo también son
   copia literal de src/box/pedidos_web/estilo.css (spec 2.8: "el sitio de
   compras no inventa componentes, usa los de pedidos con sus mismas clases y
   tokens"); solo lo de la sección final ("propio de compras") es nuevo. */
:root{
  --tinta:#17130F; --papel:#FFFFFF; --arena:#EFE6D8; --hueso-claro:#F6F0E6;
  --linea:#E6E6E2; --piedra:#6D665D;
  --cobalto:#2447C9; --cobalto-palido:#E9EDFD;
  --agave:#487243; --barro:#B4452C; --barro-tint:#F7E6E1;
  --font:ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  /* puente (guía §8.3): los nombres de siempre apuntan a los tokens */
  --ink:var(--tinta); --paper:var(--papel); --mist:var(--hueso-claro); --line:var(--linea); --muted:var(--piedra);
  --blue:var(--cobalto); --blue-tint:var(--cobalto-palido); --red:var(--barro); --red-tint:var(--barro-tint);
}

/* --- lo que todo el sitio necesita para pararse (idéntico a pedidos): reset,
   tipografía base y el armazón #app de una columna, 520 px, 100dvh --- */
*{box-sizing:border-box}
html,body{margin:0;height:100%;background:var(--papel);color:var(--ink);font-family:var(--font);font-size:16px;line-height:1.35;-webkit-font-smoothing:antialiased}
button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer;-webkit-tap-highlight-color:transparent}
button:focus-visible,input:focus-visible,select:focus-visible{outline:2px solid var(--cobalto);outline-offset:2px}
input{font:inherit}
small{font-size:13px;color:var(--muted)}
a{color:var(--blue)}

#app{position:relative;height:100%;height:100dvh;max-width:520px;margin:0 auto;background:var(--paper);display:flex;flex-direction:column;overflow:hidden;border-left:1px solid transparent;border-right:1px solid transparent}
@media (min-width:521px){#app{border-color:var(--linea)}}
.cargando{padding:40px 20px;color:var(--muted);text-align:center}

/* --- componentes (tabla 2.8) --- */

.brand{display:flex;align-items:center;gap:10px;padding:calc(12px + env(safe-area-inset-top)) 20px 0}
.brand img{height:26px;width:auto;display:block}
.brand b{font-size:15px;letter-spacing:.14em;font-weight:600}
.brand span{font-size:12px;color:var(--muted);margin-left:auto}
.prog{height:2px;background:var(--line);margin:10px 20px 0;border-radius:2px;overflow:hidden;opacity:0;transition:opacity .2s}
.prog.on{opacity:1} .prog i{display:block;height:100%;width:0;background:var(--cobalto);border-radius:2px}

.top{padding:10px 20px 8px}
.top h2{margin:0;font-size:26px;font-weight:600;letter-spacing:-.02em}
.top .sub{font-size:14px;color:var(--muted);margin-top:2px}
.body{flex:1;overflow:auto;padding:0 20px 120px;overscroll-behavior:contain;scrollbar-width:none;-webkit-overflow-scrolling:touch} .body::-webkit-scrollbar{display:none}

.search{display:flex;align-items:center;gap:10px;border-bottom:1px solid var(--ink);padding:0 2px;margin:4px 0 10px;min-height:48px}
.search input{flex:1;border:0;background:none;padding:10px 0;font-size:17px;outline:none;min-width:0;color:var(--tinta)}
.search input::placeholder{color:var(--muted)}
.search .x{color:var(--muted);font-size:20px}
.search .x[hidden]{display:none}
.search .lupa{width:18px;height:18px;flex:none;fill:none;stroke:var(--piedra);stroke-width:2;stroke-linecap:round}

.row{display:flex;align-items:center;gap:12px;padding:9px 0;border-bottom:1px solid var(--line);min-height:56px}
.row .name{flex:1;min-width:0}
.row .name b{display:block;font-weight:500;font-size:16px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.row .name span{display:block;font-size:13px;color:var(--muted)}
.row .name span.tot{color:var(--tinta);font-variant-numeric:tabular-nums}

.cta{width:100%;background:var(--ink);color:var(--papel);border-radius:12px;padding:15px 18px;font-weight:600;font-size:16px;display:flex;justify-content:center;gap:12px;align-items:center}
.cta:disabled{background:var(--mist);color:var(--muted)}
.cta .cnt{font-weight:400;font-size:14px;opacity:.75;font-variant-numeric:tabular-nums}
.ghost{width:100%;border:1px solid var(--line);border-radius:12px;padding:13px;font-weight:500;font-size:15px;margin-top:8px}
/* Coherente con `.cta:disabled`/`.kg:disabled` (hallazgo Minor, ronda de
   arreglos 1): sin esto "Flete agregado"/"Descuento agregado" se veían con
   el apagado por defecto del navegador, no con la guía. */
.ghost:disabled{opacity:.5;color:var(--muted)}

.p{font-size:14px;color:var(--muted);margin:10px 0 6px}

/* Un aviso en su propio recuadro (marcado de la v7, tarea 9): "Todavía no
   se capturan notas aquí." no es un error ni una diferencia de cuadre --
   mismo borde/radio que `.money-input`, sin inventar un tono nuevo. */
.notice{border:1px solid var(--line);border-radius:12px;padding:14px;font-size:14px;color:var(--muted);margin:10px 0}

.line{display:flex;justify-content:space-between;align-items:center;gap:10px;padding:10px 0;border-bottom:1px solid var(--line);font-size:15px}
.line .l{min-width:0} .line .l small{display:block}
.line .r{font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right;font-size:14px;color:var(--muted)}
.line .r b{color:var(--ink);font-size:16px;font-weight:600}
.line .r.diff, .line .r.diff b{color:var(--red)}

.tabs{display:flex;gap:18px;border-bottom:1px solid var(--line);margin:4px 0 6px}
.tabs button{padding:8px 0 10px;font-size:15px;color:var(--muted);border-bottom:2px solid transparent;margin-bottom:-1px}
.tabs button.on{color:var(--cobalto);border-color:var(--cobalto);font-weight:600}

.acc{border-bottom:1px solid var(--line)}
.acc>button{width:100%;display:flex;justify-content:space-between;align-items:center;padding:14px 0;text-align:left;gap:8px}
.acc>button b{font-size:16px;font-weight:600}
.acc>button .meta{font-size:13px;color:var(--muted);white-space:nowrap}
.acc .in{display:none;padding:0 0 8px} .acc.open .in{display:block}
.tag{font-size:12px;color:var(--muted);margin-left:8px;font-weight:400}
.tag.r{color:var(--red)} .tag.b{color:var(--blue)}

.sheet{position:absolute;inset:0;background:rgba(20,20,20,.4);display:flex;align-items:flex-end;z-index:10}
.sheet .card{background:var(--paper);border-radius:20px 20px 0 0;padding:20px 20px calc(24px + env(safe-area-inset-bottom));max-height:88%;overflow:auto;width:100%}
.sheet h3{margin:0 0 4px;font-size:18px;font-weight:600}
.sheet .sub{font-size:14px;color:var(--muted);margin-bottom:12px}
@media (prefers-reduced-motion:no-preference){ .sheet .card{animation:up .2s ease-out} .sheet .card.sin-entrada{animation:none} @keyframes up{from{transform:translateY(20px);opacity:0}to{transform:none;opacity:1}} }

.pick{width:100%;display:flex;justify-content:space-between;align-items:center;gap:10px;padding:12px 14px;border:1px solid var(--line);border-radius:12px;margin-bottom:8px;text-align:left}
.pick.on{border-color:var(--cobalto)} .pick small{display:block}
/* «¿Una cja trae?»: las unidades en una fila de opciones (Pendientes → Empaques) */
.units{display:flex;gap:8px;margin:-2px 0 10px}
.units .pick{width:auto;flex:1;justify-content:center;margin-bottom:0;padding:10px 12px}
.units .pick.on{background:var(--cobalto);color:var(--papel)}
.with-unit{display:flex;align-items:center;gap:8px} .with-unit input{flex:1;min-width:0} .with-unit .unit{color:var(--muted);font-size:14px}
.pick .tick{width:22px;height:22px;border-radius:50%;border:1px solid var(--line);display:grid;place-items:center;font-size:13px;flex:none}
.pick.on .tick{background:var(--cobalto);color:var(--papel);border-color:var(--cobalto)}

.login{display:flex;flex-direction:column;gap:14px;padding:24px 0}
.login label{display:flex;flex-direction:column;gap:6px;font-size:14px;color:var(--muted)}
.login input{border:1px solid var(--line);border-radius:12px;padding:13px 14px;font-size:16px;color:var(--ink);background:var(--paper)}
.login .hint{font-size:13px;text-align:center} .login .hint.err{color:var(--red)}
.ev{display:flex;gap:10px;align-items:baseline;padding:6px 0;font-size:14px;border-bottom:1px solid var(--line)}
.ev span:first-child{color:var(--muted);font-variant-numeric:tabular-nums;min-width:44px}
.ev b{font-weight:500} .ev span:last-child{margin-left:auto;color:var(--muted)}

.kg{width:88px;height:40px;border:1px solid var(--line);border-radius:999px;text-align:center;font-size:16px;font-weight:600;font-variant-numeric:tabular-nums;background:var(--paper);color:var(--ink)}
.kg.has{border-color:var(--cobalto);color:var(--cobalto)} .kg:disabled{opacity:.5}
.line .kg{width:76px;height:36px;flex:none}
.fotos{display:flex;gap:10px;flex-wrap:wrap;margin:10px 0}
.foto{position:relative;display:block;width:72px;height:72px;border-radius:10px;overflow:hidden;border:1px solid var(--line)}
.foto img{width:100%;height:100%;object-fit:cover;display:block}
.foto button{position:absolute;top:2px;right:2px;width:28px;height:28px;border-radius:50%;background:var(--ink);color:var(--paper);font-size:17px;line-height:28px;padding:0;border:0;cursor:pointer}
/* La foto grande del .lado de computadora y de la nota de solo lectura
   (Importante 7 de la revisión, 2026-09-19): mismo .foto (radio, borde),
   sin el recorte a 72×72 -- se ve completa, no recortada a cuadro. */
.foto.grande{display:block;width:100%;height:auto;margin-bottom:10px}
.foto.grande img{height:auto}
/* Mientras lee, o si se rindió sin haber llegado a mostrar renglones
   (tarea 7 de la migración v7): la miniatura crece para que se note el
   detalle -- 72 px alcanza para identificar la nota en la lista, no para
   ver si el modelo va a poder leerla. Mismo .foto (radio, botón ×);
   `object-fit:contain` para no recortar nada de la nota al agrandarla. */
.reading-photos{gap:16px}
.reading-photos .foto{width:160px;height:217px}
.reading-photos .foto img{object-fit:contain;background:var(--hueso-claro)}
.fotobtn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;padding:0 16px;cursor:pointer}

/* Éxito (guía §6.23, .ok): copiado literal de pedidos_web/estilo.css, solo
   el layout -- el dibujo animado circle+path de pedidos está hecho a la
   medida de SU trazo (dasharray 170/40); okHtml() usa un check más simple
   (spec de la tarea 7), así que copiar también esas reglas de animación
   dibujaría mal un trazo de otra longitud. */
.ok{display:grid;place-items:center;padding:22px 0 24px;gap:14px;text-align:center}

/* --- propio de compras --- */

/* "Leyendo la nota…" (decisión 27, guía §6.2: sin spinners): una barra de
   2 px que un `setInterval` de PANTALLA mueve a mano (ligarNota, tarea 7)
   en los mismos 50 s del plazo de armarPlazo() -- ya no es una animación
   de duración fija, porque el ancho lo empuja el reloj real, no un
   `@keyframes` que corre por su cuenta. Agave mientras hay margen, barro
   (`.tarde`) en los últimos 8 s -- la transición solo suaviza el salto de
   cada segundo. Modificador sobre .prog, no un componente nuevo (como ya
   hace .prog.on). */
.prog.leyendo i{background:var(--agave);transition:width 1s linear,background-color .4s}
.prog.leyendo.tarde i{background:var(--barro)}
@media(prefers-reduced-motion:reduce){.prog.leyendo i{transition:none}}

/* Total tecleado: input destacado (guía §6.21) — es el número que cuadra.
   Su único uso real (pantallaNota, "Confirmar compra") lo envuelve siempre
   en `.money-input.grande`, que ahora lleva el borde y el fondo cobalto
   (tarea 9: antes estaban dos veces, aquí Y en el contenedor, y esta copia
   quedaba siempre tapada por `.money-input.grande .total{border:0}` de
   abajo -- una caja destacada dentro de otra, invisible). Aquí solo queda
   el tamaño y la alineación del número. */
.total{width:100%;font-size:22px;font-weight:600;text-align:right;padding:14px 16px;
  font-variant-numeric:tabular-nums}
/* El renglón del cuadre que no da: barro, con signo y texto, nunca solo color */
.r.diff{color:var(--barro);font-variant-numeric:tabular-nums}
/* Un proveedor en mayúsculas, de una sola palabra larga, no se puede partir
   ni truncar sin perder el tag ("Corregida"…) que va en la misma línea —
   se deja partir la palabra en vez de desbordar a 390 px (Menor 7,
   revisión 2026-09-18). */
.line .l b{overflow-wrap:anywhere}

/* Revisión visual del 2026-09-20 */
.kgl{display:inline-flex;flex-direction:column;align-items:center;gap:3px;font-size:11px;letter-spacing:.02em;color:var(--muted)}
.line .r.duo{display:inline-flex;gap:8px;align-items:flex-end}
.ghost.peligro{color:var(--red)}
.p.aviso-fijo{color:var(--red)}
.line[role="button"]{cursor:pointer}
.line[role="button"]:focus-visible,.sheet .card:focus-visible{outline:2px solid var(--cobalto);outline-offset:2px}
.sheet .card:focus{outline:none}
#verBorrador{margin-bottom:10px}

/* El recorrido por pasos de la nota (decisión 32, 2026-09-21): una sola
   columna siempre -- el cuadre ya no vive en una segunda columna desde
   900 px (`.dos`/`.lado`, retiradas), va dentro del último paso. `.main`
   necesita ser flex para que `.body` (ya `flex:1;overflow:auto`) siga
   llenando el alto disponible con su propio scroll. */
.main{flex:1;display:flex;flex-direction:column;min-height:0}
.single-column{width:100%;max-width:520px;margin:0 auto}
.capture-panel{padding-top:10px}
.step-footer{padding:20px 0 8px}
.step-footer .p{margin-bottom:12px;min-height:19px}
.text-button{color:var(--cobalto);font-size:14px;min-height:44px;text-align:left}

/* La barra de pasos (marcado de la v7): gris el que falta, tinta el activo
   con una animación de avance, agave el que ya se completó. */
.purchase-timeline{display:flex;gap:12px;list-style:none;padding:0;margin:24px 0 28px}
.purchase-timeline li{flex:1;min-width:0;position:relative;padding-top:14px;color:var(--piedra)}
.purchase-timeline li::before{content:"";position:absolute;top:0;left:0;right:0;height:3px;border-radius:2px;background:var(--linea)}
.purchase-timeline li.done{color:var(--agave)}
.purchase-timeline li.done::before{background:var(--agave)}
.purchase-timeline li.active{color:var(--tinta)}
.purchase-timeline li.active::before{background:linear-gradient(90deg,var(--linea) 0%,var(--linea) 35%,var(--agave) 50%,var(--linea) 65%,var(--linea) 100%);background-size:280% 100%;animation:purchase-flow 1.9s linear infinite}
.purchase-timeline button{width:100%;min-height:44px;display:block;text-align:left;color:inherit;font-size:14px;font-weight:400;line-height:1.4;border-radius:3px;padding:0 2px}
.purchase-timeline .step-number{font-variant-numeric:tabular-nums}
@keyframes purchase-flow{0%{background-position:110% 0}100%{background-position:-40% 0}}

/* Un campo faltante (spec 2.9): se marca `aria-invalid`, tiembla una vez
   -- respetando `prefers-reduced-motion` -- y su aviso va debajo, nunca
   solo con color (guía). Mismo tono que `.line .r.diff`. */
[aria-invalid="true"]{border-color:var(--barro)!important;outline-color:var(--barro)}
/* Con el foco puesto, `input:focus-visible` (cobalto) le ganaba por
   especificidad al `outline-color` de arriba: un campo marcado en barro con
   contorno azul (punto 39 del ensayo de Alan, 2026-09-21). */
button[aria-invalid="true"]:focus-visible,input[aria-invalid="true"]:focus-visible,select[aria-invalid="true"]:focus-visible{outline-color:var(--barro)}
.inline-error{display:block;margin:6px 0 12px;font-size:13px;font-weight:500;color:var(--barro)}
@keyframes field-shake{0%,100%{transform:translateX(0)}20%,60%{transform:translateX(-4px)}40%,80%{transform:translateX(4px)}}
.field-shake{animation:field-shake .34s ease-out}
@media(prefers-reduced-motion:reduce){
  .purchase-timeline li.active::before{animation:none;background:var(--agave)}
  .field-shake{animation:none}
}
.visually-hidden{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%)}

/* El paso "Identificar la nota" (tarea 3, decisiones 33/34; marcado de
   referencia de la v7 -- su lógica no se copió, solo la forma). */
.identity-photo{padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--hueso-claro)}
.identity-photo .p{margin:6px 0 12px}
/* La casilla y su texto centrados en una cuadrícula (guía §6.9 adaptada):
   el error de mostrarFaltantes se inserta COMO HERMANO después de este
   label (insertAdjacentElement('afterend', …)), así que queda debajo del
   renglón de la casilla sin necesidad de un hueco en la cuadrícula. */
.check-label{display:grid;grid-template-columns:20px minmax(0,1fr);align-items:center;gap:6px 10px;font-size:14px;color:var(--ink);margin:12px 0;line-height:1.5;cursor:pointer}
.check-label input{width:20px;height:20px;min-height:20px;flex:none;margin:0;accent-color:var(--agave);border-radius:4px}
.provider-block{margin-top:24px}
.field-title{display:block;font-size:14px;color:var(--muted);margin-bottom:6px}
.provider-pick{min-height:52px;color:var(--cobalto);margin-bottom:4px}
.provider-pick span:first-child{min-width:0;overflow-wrap:anywhere}
.provider-pick small{margin-top:3px}
.provider-pick span:last-child{font-size:13px;flex:none}
.fields{display:grid;grid-template-columns:1fr 1fr;gap:12px;margin:18px 0}
.fields label,.entry{display:grid;gap:6px;font-size:14px;color:var(--muted);min-width:0}
.fields input,.entry input,.entry select{font:inherit;font-size:16px;background:var(--paper);color:var(--ink);border:1px solid var(--line);border-radius:12px;padding:12px;min-width:0;width:100%;min-height:44px}
/* La fecha en el iPhone (Alan, 2026-09-21): el `<input type="date">` de iOS
   trae un ancho y un alto propios. Sin `min-width:0` en su `label` (un
   elemento de cuadrícula no se encoge por debajo de su contenido) empujaba la
   columna y TODA la página ganaba scroll horizontal; y su caja salía más alta
   que la del folio. Se le quita la apariencia nativa y las dos cajas miden lo
   mismo. */
.fields input{box-sizing:border-box;height:48px}
.fields input[type="date"]{-webkit-appearance:none;appearance:none;display:block;max-width:100%}
.fields input[type="date"]::-webkit-date-and-time-value{text-align:left;margin:0}
@media(max-width:430px){.fields{grid-template-columns:1fr}}

/* Insumos de la nota (tarea 4, marcado v7, decisión 36a): un bloque por
   renglón -- ahí caben el nombre, de dónde salen cantidad y precio, la
   cantidad y las herramientas, sin apretarse como en la fila de 56 px que
   describía la spec 2.8 antes de esta migración. `.row` se reutiliza
   DENTRO del bloque para la pareja nombre/cantidad; el bloque completo no
   lleva el borde inferior de `.row` suelto (lo pone `.product`). */
.product{padding:14px 0;border-bottom:1px solid var(--line)}
.product .row{border-bottom:0;padding:0}
/* Las tarjetas de Pendientes llevan `.name` directo bajo `.product`, sin
   `.row`: sin estas dos reglas el nombre y el detalle corrían en una sola
   línea («Agua cielEmpaque de la nota: cja…», Alan, 2026-09-22). */
.product>.name b{display:block;font-weight:500;font-size:16px}
.product>.name span{display:block;font-size:13px;color:var(--muted)}
.pending-label{display:block;color:var(--barro)}
.quantity-label{display:flex;flex-direction:column;align-items:center;gap:4px;font-size:12px;color:var(--muted);flex:none;text-align:center}
.missing-price{margin-top:10px}
.tools{display:flex;flex-wrap:wrap;gap:8px;margin-top:10px}
.tools .ghost,.tools .text-button{width:auto;margin-top:0;flex:none}

/* Un campo de dinero con "$" al frente (decisión de marcado de esta
   migración, para el precio que falta y los cargos a mano): el mismo
   borde/alto que `.fields input`, pero envolviendo el `$` y el input en un
   solo control -- así el símbolo no se ve como un texto suelto junto a la
   caja. */
.money-input{display:flex;align-items:center;gap:4px;border:1px solid var(--line);border-radius:12px;padding:0 12px;min-height:44px;background:var(--paper)}
.money-input span:first-child{color:var(--muted)}
.money-input input{border:0;padding:12px 0;font-size:16px;background:none;width:100%;min-width:0;color:var(--ink)}

/* Fletes y descuentos (tarea 5): el mismo `.line` de siempre, con un poco
   más de aire porque ahora puede traer el `.money-input` de arriba y su
   aviso debajo, no solo un número o un input suelto. */
.extra-row{padding:12px 0}
.charge-options{margin-top:18px}
.charge-options>div{display:flex;gap:10px}
.charge-options .ghost{flex:1;margin-top:0}
/* "Sin flete ni descuento" quedaba pegado a los dos botones de arriba: el
   `margin-top:0` de la regla anterior también le caía a él (fotos de Alan,
   ensayo del 2026-09-21). */
.charge-options>.ghost{margin-top:10px;width:100%}
/* La foto pegada al encabezado del acordeón en una corrección (mismo ensayo). */
.correction-group .group-content>:first-child{margin-top:16px}

/* "Confirmar compra" (tarea 6, marcado v7). El resumen de arriba
   (`.checkout-review`) y su detalle (`.review-items`) solo se pintan en el
   recorrido real -- misma familia visual que `.line`/`.provider-block`, sin
   inventar un contenedor nuevo. */
.checkout-review{display:flex;justify-content:space-between;align-items:flex-start;gap:12px;padding:14px 0 6px}
.checkout-review b{display:block;font-size:16px;overflow-wrap:anywhere}
.checkout-review .text-button{flex:none;min-height:auto}
.review-items{border-bottom:1px solid var(--line);padding-bottom:6px;margin-bottom:18px}
.review-items summary{padding:8px 0;font-size:14px;color:var(--muted);cursor:pointer}
.review-items .line:last-child{border-bottom:0}

/* Cada campo de "Confirmar compra" con su propio aire, como ya hace
   `.provider-block` con el proveedor: son las mismas `label.entry` de los
   demás pasos, solo que aquí van varias seguidas. */
.entry{margin:16px 0}

/* El «= [campo] unidad» de la equivalencia en "Ligar a X" (spec «el campo
   que falta» §3.3): el «=» y las unidades son texto fijo, el campo solo
   pide el número -- sin componente nuevo, el mismo `.kg` de siempre. */
.equiv{display:flex;align-items:center;gap:8px}
.equiv input{width:8ch}

/* El total del comprobante conserva el destaque de siempre (`.total`),
   ahora con el "$" al frente: el borde y el fondo cobalto se quedan en el
   envoltorio (mismo patrón que `.foto.grande`) para no dibujar dos cajas
   encimadas una dentro de otra. */
.money-input.grande{border:2px solid var(--cobalto);background:var(--cobalto-palido);padding:0 16px}
.money-input.grande span:first-child{font-size:22px;font-weight:600;color:var(--ink)}
.money-input.grande .total{border:0;background:none;padding:14px 0;font-weight:600}
/* El foco de un campo con "$" lo dibuja el contenedor, no el input de adentro:
   con el contorno global de `input:focus-visible` salía una caja dentro de
   otra (Alan, 2026-09-21, el total en computadora). */
.money-input input:focus,.money-input input:focus-visible{outline:none}
.money-input:focus-within{outline:2px solid var(--cobalto);outline-offset:2px}

/* La línea de estado del cuadre (`aria-live`): gris mientras falta algo,
   agave cuando ya se puede guardar -- mismo tono que `.purchase-timeline
   li.done` para "ya está". */
.status{font-size:14px;color:var(--muted);margin:14px 0 6px}
.status.good{color:var(--agave);font-weight:600}

/* --- tarea 8 de la migración v7: el día, el acuse, el duplicado, corregir
   y solo lectura (referencia visual del prototipo, solo marcado/CSS) --- */

/* La lista del día y la del histórico (`.line` de siempre, con el número
   grande de dinero legible sin partirse). */
.list-note{min-height:64px}
.list-money{white-space:nowrap}

/* La ficha del borrador (día y hoja de "captura sin terminar"): mismo
   patrón que `.checkout-review`/`.provider-block`, sin inventar un
   contenedor nuevo. */
.draft-identity{display:grid;gap:6px;margin:12px 0;overflow-wrap:anywhere}
.draft-identity span{font-size:14px;color:var(--muted)}
.draft-identity small{display:block;color:var(--muted)}

/* El acuse (`.ok`, arriba): la palomita se dibuja con `stroke-dasharray`/
   `stroke-dashoffset` sobre `pathLength="1"` (así el trazo vale 0..1 sin
   importar su longitud real) en 0.5 s, agave como el resto de lo positivo
   de la guía; sin animación con movimiento reducido (guía §accesibilidad). */
.ok strong{font-size:28px;font-variant-numeric:tabular-nums}
.ok .success-mark{width:56px;height:56px;color:var(--agave)}
.ok .success-mark path{stroke-dasharray:1;stroke-dashoffset:1;animation:receipt-check .5s ease-out forwards}
@keyframes receipt-check{to{stroke-dashoffset:0}}
@media(prefers-reduced-motion:reduce){.ok .success-mark path{animation:none;stroke-dashoffset:0}}

/* Posible duplicado: "Ya guardada" contra "Esta captura", una junto a la
   otra -- una sola columna en celular, donde no caben las dos. */
.duplicate-compare{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin:16px 0}
.duplicate-compare>div{display:flex;flex-direction:column;gap:6px;padding:12px;border:1px solid var(--line);border-radius:12px;min-width:0;overflow-wrap:anywhere}
.duplicate-compare small{color:var(--cobalto)}
.duplicate-compare span{font-size:13px;color:var(--muted)}
.duplicate-compare strong{font-size:20px;font-variant-numeric:tabular-nums}
@media(max-width:430px){.duplicate-compare{grid-template-columns:1fr;gap:10px}}

/* Corregir antes del corte: los mismos cuatro pasos en acordeones, uno
   abierto a la vez (`n.grupoAbierto`). Mismo `.step-number` que ya usa la
   barra de pasos del recorrido normal. */
.correction-group{border:1px solid var(--line);border-radius:12px;margin:14px 0;overflow:hidden}
.correction-group>summary{list-style:none;display:flex;gap:12px;align-items:center;padding:16px;font-size:16px;font-weight:600;cursor:pointer}
.correction-group>summary::-webkit-details-marker{display:none}
.correction-group[open]>summary{background:var(--hueso-claro);border-bottom:1px solid var(--line)}
.correction-group .group-content{padding:0 16px 18px}
.correction-group .count{margin-left:auto;min-width:2ch;text-align:right;font-weight:500;color:var(--muted)}
/* El numero es quien empuja a la derecha; el '+' va pegado a el. Con los dos
   en margin-left:auto el espacio libre se repartia entre ambos y el numero
   quedaba a media fila, moviendose segun lo largo del titulo (Alan, iPhone,
   2026-09-22). Solo aplica donde hay numero: la captura de notas usa el mismo
   .correction-group SIN .count y conserva su '+' a la orilla. */
.correction-group .count + .accordion-icon{margin-left:0}
.accordion-icon{margin-left:auto;color:var(--cobalto);font-size:20px;transition:transform .15s ease}
.correction-group[open] .accordion-icon{transform:rotate(45deg)}
@media(prefers-reduced-motion:reduce){.accordion-icon{transition:none}}

/* Solo lectura: cabecera, la foto guardada en un `<details>`, la franja de
   IVA/pago/edición cerrada y el total, con el mismo `.line` de siempre
   para los renglones (`filaSoloLectura`). */
.receipt-head{display:grid;gap:6px;margin:16px 0}
.receipt-photo{margin:16px 0}
.receipt-photo summary{font-size:14px;color:var(--muted);cursor:pointer;padding:8px 0}
.receipt-meta{display:flex;align-items:center;flex-wrap:wrap;gap:8px 14px;padding:16px 0;font-size:13px;border-top:1px solid var(--line)}
.iva-badge{color:var(--cobalto);border:1px solid var(--cobalto);border-radius:6px;padding:5px 8px}
.closed-badge{color:var(--muted)}
.receipt-total{border-top:1px solid var(--line);padding:16px 0;display:flex;justify-content:space-between;align-items:center;gap:12px}
.receipt-total strong{font-size:26px;font-variant-numeric:tabular-nums}

/* --- propio de panadería (prototipo E0): tira de pasos, captura por pan, menú ---
   Lo primero son cinco reglas copiadas literales de src/box/pedidos_web/estilo.css
   (.bottom, .bottom .hint, .msg, .empty, .cat) que compras no trae; .eyebrow y
   .hint suelto se definen aquí con los mismos tokens. */
.bottom{position:absolute;left:0;right:0;bottom:0;background:var(--paper);padding:10px 20px calc(16px + env(safe-area-inset-bottom));box-shadow:0 -1px 0 var(--line)}
.bottom .hint{font-size:13px;color:var(--muted);text-align:center;margin-top:8px}
.msg{background:var(--mist);border-radius:10px;padding:12px 14px;font-size:14px;margin:8px 0 14px;white-space:pre-wrap;line-height:1.45}
.empty{padding:40px 12px;text-align:center;color:var(--muted);font-size:15px}
.empty b{display:block;color:var(--ink);font-size:17px;font-weight:600;margin-bottom:4px}
.cat{font-size:14px;font-weight:600;color:var(--tinta);padding:24px 0 4px}
.eyebrow{font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-bottom:2px}
.hint{font-size:13px;color:var(--muted);margin:10px 0}
.pasos{display:flex;gap:6px;padding:8px 20px 0}
.pasos i{flex:1;height:3px;border-radius:2px;background:var(--line)}
.pasos i.hecho{background:var(--cobalto)} .pasos i.actual{background:var(--ink)}
.fila{display:flex;align-items:center;gap:10px;min-height:56px;padding:6px 0;border-bottom:1px solid var(--line)}
.fila .nom{flex:1;min-width:0;font-size:16px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.fila .nom small{display:block;font-size:13px;color:var(--muted);font-weight:400}
.fila input{width:76px;height:48px;border:1px solid var(--line);border-radius:12px;padding:0 10px;font-size:18px;text-align:right;font-variant-numeric:tabular-nums;color:var(--tinta);background:var(--papel)}
.fila input::placeholder{color:var(--muted)}
.fila input.con{border-color:var(--cobalto);background:var(--cobalto-palido)}
.fila input.mal{border-color:var(--barro)}
.fila .saldo{width:44px;text-align:right;font-size:13px;color:var(--muted);font-variant-numeric:tabular-nums}
.cols{display:grid;grid-template-columns:1fr 76px 76px;gap:10px;align-items:center}
.cols.tres{grid-template-columns:1fr 66px 66px 66px}
.fila>.cols{flex:1;min-width:0}   /* la rejilla es hija de un flex: sin esto se encoge a su contenido y las columnas no alinean */
.cols input{width:100%}
.cab{display:grid;grid-template-columns:1fr 76px 76px;gap:10px;font-size:12px;color:var(--muted);padding:12px 0 2px;text-align:right}
.cab.tres{grid-template-columns:1fr 66px 66px 66px}
.cab span:first-child{text-align:left}
.total{display:flex;align-items:center;gap:10px;justify-content:space-between;padding:14px 0 4px;font-weight:600}
.total input{width:96px;height:48px;border:2px solid var(--cobalto);background:var(--cobalto-palido);border-radius:12px;padding:0 10px;font-size:20px;text-align:right;font-variant-numeric:tabular-nums}
.total .rot{position:relative}   /* el rótulo va centrado con el campo azul (Alan, 24-sep) */
.total .estado{position:absolute;left:0;top:100%;white-space:nowrap;line-height:19px}   /* el veredicto cuelga bajo el rótulo sin moverlo: el campo no salta al coincidir */
.total .dif{font-size:14px;font-weight:400;color:var(--barro)}
.total .ok{display:inline;padding:0;font-size:14px;font-weight:400;color:var(--agave)}   /* .ok de compras es la pantalla de éxito (grid + padding): aquí es solo el veredicto */
.menu{position:absolute;top:0;right:0;left:0;bottom:0;background:var(--papel);z-index:20;overflow:auto;padding:0 20px 40px}
.menu h3{font-size:18px;font-weight:600;margin:18px 0 6px}
.menub{margin-left:auto;font-size:14px;color:var(--cobalto);font-weight:500}
.linea{display:flex;justify-content:space-between;padding:8px 0;border-bottom:1px solid var(--line);font-size:15px}
.linea small{color:var(--muted)}
.porque{font-size:12px;color:var(--muted)}
.dia-grande{font-size:26px;font-weight:600;letter-spacing:-.02em}
.fila input.sd::placeholder{font-size:13px}
.body{padding-bottom:250px}                                  /* la barra de abajo con el total mide ~230 px */
.bottom{padding:6px 20px calc(8px + env(safe-area-inset-bottom))} /* menos aire abajo (Alan, 24-sep: hueco grande en el iPhone) */
.bottom .total{padding:4px 0 8px}
.bottom .total input.con{border-color:var(--cobalto)}
.bottom .hint{margin-top:6px}

/* el menú de la propuesta de Codex (Alan, 24-sep): hoja sobre la captura, con índice */
.underlay{display:flex;flex:1;min-height:0;flex-direction:column;overflow:hidden}
.menu-sheet{z-index:20}
.menu-sheet .card{height:86%;display:flex;flex-direction:column;overscroll-behavior:contain}
.sheet-head{display:flex;justify-content:space-between;align-items:center;gap:12px;position:sticky;top:-20px;background:var(--papel);padding:12px 0;z-index:1}
.sheet-head h3{margin:0}
.sheet-head .menub.izq{margin-left:0}
.menu-list button{display:flex;align-items:center;justify-content:space-between;width:100%;min-height:56px;padding:12px 0;border-bottom:1px solid var(--linea);text-align:left;font-size:16px}
.menu-list button span:last-child{color:var(--piedra);font-size:14px}
.sheet .card>h3{margin-top:16px}
.sheet .card>.ghost,.sheet .card>.cta{flex-shrink:0}

/* la hoja de la sugerencia para el grupo: solo existe al imprimir */
.impresion{display:none}
@media print{
  body *{visibility:hidden}
  .impresion,.impresion *{visibility:visible}
  @page{margin:12mm}
  .impresion{display:block;position:absolute;top:0;left:0;right:0;background:var(--papel);color:var(--tinta);padding:0;font-size:14px}
  .impresion img{width:40px;height:40px}
  .impresion h1{font-size:22px;margin:8px 0 2px}
  .impresion p{margin:0 0 14px;color:var(--piedra)}
  .impresion table{width:100%;border-collapse:collapse}
  .impresion th,.impresion td{text-align:left;padding:4px;font-size:13px;border-bottom:1px solid var(--linea)}
  .impresion .n{text-align:right;font-variant-numeric:tabular-nums;font-weight:600}
  .impresion .des{color:var(--piedra);font-size:12px}
  .impresion tfoot td{font-weight:700;border-top:2px solid var(--tinta);border-bottom:0}
}

/* encabezado compacto de los pasos (Alan, 24-sep): se quedan la tira y «Paso n de 6», el título ocupa menos */
.top.compacto{padding:6px 20px 2px}
.top.compacto h2{font-size:20px;line-height:1.2}

/* avisos en el menú (Alan, 24-sep): número rojo; lo que caja o cocina no han confirmado sale «No validado» */
.badge{display:inline-block;min-width:20px;height:20px;line-height:20px;padding:0 6px;border-radius:10px;background:var(--barro);color:var(--papel);font-size:12px;font-weight:600;text-align:center;vertical-align:1px}
.brand span.badge,.menu-list button span.badge{color:var(--papel);font-size:12px;margin-left:4px}   /* le gana a «.brand span» y «.menu-list button span:last-child» */
.novalid{align-self:center;font-size:12px;font-weight:600;color:var(--barro);background:var(--barro-tint);border-radius:8px;padding:3px 8px;white-space:nowrap}
.linea .menub{align-self:center}
/* paso 2 del domingo (sin sucursal): una sola columna, el campo pegado a la derecha como en los demás pasos */
.cols.una,.cab.una{grid-template-columns:1fr 76px}

/* ronda 4 del iPhone (Alan, 24-sep) */
/* el encabezado se separa de la lista: al hacer scroll el texto ya no se pega al título */
.top.compacto{padding:6px 20px 10px;border-bottom:1px solid var(--linea)}
.top.compacto + .body{padding-top:6px}
/* «Coincide» ya no choca con el botón: la fila del total deja lugar a su veredicto */
.bottom .total{padding:4px 0 24px}
/* los números al centro del campo y en negritas, también el total */
.fila input,.total input{text-align:center;font-weight:600}
.fila input::-webkit-inner-spin-button,.fila input::-webkit-outer-spin-button,.total input::-webkit-inner-spin-button,.total input::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}   /* sin flechas de escritorio: el número queda al centro */

/* explicar piezas (C21): motivos como botones y una nota */
.motivos{display:flex;flex-direction:column;gap:8px;margin:12px 0}
.motivos button{text-align:left;padding:12px 14px;border:1px solid var(--linea);border-radius:12px;font-size:15px;background:var(--papel)}
.motivos button.on{border-color:var(--cobalto);background:var(--cobalto-palido);font-weight:600}
.sheet textarea{width:100%;border:1px solid var(--linea);border-radius:12px;padding:10px 12px;font:inherit;font-size:16px;margin-bottom:12px;resize:none}
.sheet.encima{z-index:30}   /* se abre desde el menú, que ya es una hoja */

/* «Cómo acabó el día» y la vista del mensaje de las 22:00 */
.okc{align-self:center;font-size:12px;font-weight:600;color:var(--agave)}
.linea small{display:block}
.tg{background:var(--hueso-claro);border-radius:14px;padding:12px 14px;font-size:15px;line-height:1.45;margin:10px 0}

/* ronda 7 (Alan, 24-sep): los rótulos de las columnas al centro, sobre sus campos */
.cab span:not(:first-child){text-align:center}
.cab.con-saldo{grid-template-columns:1fr 44px 76px}   /* el saldo del paso 6 mide 44 px, no 76 */
.fila .saldo{text-align:center}

/* «Cómo acabó el día», más alegre (Alan, 24-sep) */
.fin-hero{display:flex;align-items:center;gap:14px;background:var(--hueso-claro);border-radius:18px;padding:16px;margin:12px 0 4px}
.fin-hero svg{width:52px;height:52px;flex:none;fill:none;stroke:var(--agave);stroke-width:3.5;stroke-linecap:round;stroke-linejoin:round}
.fin-hero b{display:block;font-size:22px;font-weight:700;letter-spacing:-.01em}
.fin-hero span{font-size:14px;color:var(--piedra)}
@media (prefers-reduced-motion:no-preference){
  .fin-hero circle{stroke-dasharray:145;stroke-dashoffset:145;animation:traza .6s ease-out forwards}
  .fin-hero path{stroke-dasharray:40;stroke-dashoffset:40;animation:traza .35s .5s ease-out forwards}
  @keyframes traza{to{stroke-dashoffset:0}}
}
.tiles{display:grid;grid-template-columns:repeat(3,1fr);gap:8px;margin:6px 0 4px}
.tile{background:var(--hueso-claro);border-radius:14px;padding:10px 10px 12px;min-width:0}
.tile span{display:block;font-size:12px;color:var(--piedra)}
.tile b{display:block;font-size:28px;font-weight:700;line-height:1.15;color:var(--cobalto);font-variant-numeric:tabular-nums}
.tile small{display:block;font-size:12px;color:var(--piedra)}
.tile i,.frio i.si,.frio i.no{display:inline-block;margin-top:6px;font-style:normal;font-size:11px;font-weight:600;border-radius:8px;padding:2px 7px}
i.si{color:var(--agave);background:var(--papel)}
i.no{color:var(--barro);background:var(--barro-tint)}
.frio{background:var(--hueso-claro);border-radius:14px;padding:12px}
.frio-cifras{display:flex;gap:14px;align-items:center;font-size:15px}
.frio-cifras b{font-size:20px;color:var(--cobalto)}
.frio-cifras i{margin-left:auto}
.barra{height:8px;background:var(--linea);border-radius:4px;margin-top:10px;overflow:hidden}
.barra i{display:block;height:100%;background:var(--cobalto);border-radius:4px}
.inv{display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-top:6px}
.inv div{display:flex;justify-content:space-between;gap:6px;background:var(--hueso-claro);border-radius:10px;padding:8px 10px;font-size:13px;min-width:0}
.inv span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.inv b{font-variant-numeric:tabular-nums}
.inv .neg b{color:var(--barro)} .inv .cero{opacity:.6}

/* la tira de pasos (Alan, 24-sep): el paso actual se ve «en proceso» (una franja que avanza, sin parpadeo); los hechos se quedan quietos con su color */
.pasos i{position:relative;overflow:visible}
.pasos i.actual{background:var(--cobalto)}
@media (prefers-reduced-motion:no-preference){
  .pasos i.actual{background:var(--cobalto-palido);overflow:hidden}
  .pasos i.actual::after{content:'';position:absolute;top:0;bottom:0;left:0;width:40%;border-radius:2px;background:var(--cobalto);animation:proceso 2.4s ease-in-out infinite}
  @keyframes proceso{0%{transform:translateX(-100%)}100%{transform:translateX(250%)}}
  .barra i{animation:crece .8s .2s ease-out both;transform-origin:left}
  @keyframes crece{from{transform:scaleX(0)}to{transform:scaleX(1)}}
  .tile{animation:asoma .35s ease-out both} .tiles .tile:nth-child(2){animation-delay:.06s} .tiles .tile:nth-child(3){animation-delay:.12s}
  @keyframes asoma{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
}
.fila.contar input{width:72px}
.fila.contar .menub{margin-left:4px}
.fila.contar .nom{white-space:normal}
.fila.contar .nom small{white-space:normal}

/* teléfono en horizontal (Alan, 25-sep: «se pierde todo»): con menos de 500 px de alto la lista
   quedaba en una franja de 140 px y, con el teclado, en nada. Ahí se desplaza toda la página, el
   encabezado se va con el scroll y la barra de abajo es una sola fila pegada al borde */
@media (max-height:500px){
  html,body{height:auto;overflow:visible}   /* sin contenedor de scroll propio: la barra se pega a la ventana */
  #app{height:auto;min-height:100dvh;overflow:visible}
  .body{flex:none;overflow:visible;padding-bottom:16px}
  .bottom{position:sticky;bottom:0;display:flex;align-items:center;gap:12px;padding:6px 20px calc(6px + env(safe-area-inset-bottom))}
  .bottom .total{flex:1;padding:0 0 16px}
  .bottom .total .rot{white-space:nowrap;font-size:17px}
  .bottom .acciones{flex:1}
  .bottom .acciones .cta{padding:12px 14px}
  .bottom .hint{display:none}
  .sheet{position:fixed}
  .menu-sheet .card{height:92%}
  .fin-hero{padding:10px 14px}
}
