/* comal screens. Step 1: the header, venta, the card pages (login, abrir turno,
   cobrar, errors) and the ticket. Step 2 (at the end): the options picker and
   the admin pages. Tokens and components come from comal.css
   (direccion E). Flat CSS only (DESIGN.md, the Don'ts list: cheap phones).
   Phone first (360 px is the floor); two panes from 1024 px. */

/* ---------- the header (templates/_header.html) ----------
   brand, the guino (the day's sales: the one green beat), Salir. */
header.shell{
  display:flex;align-items:center;gap:var(--sp-2);min-height:60px;
  padding:6px var(--sp-3);
  padding-left:max(var(--sp-3),env(safe-area-inset-left));
  padding-right:max(var(--sp-3),env(safe-area-inset-right));
  background:var(--bg);border-bottom:1px solid var(--line);
}
header.shell .marca{flex:0 0 auto;font-size:1.3rem}
header.shell .hoy{
  flex:0 1 auto;min-width:0;margin:0 auto 0 var(--sp-1);
  display:flex;align-items:baseline;gap:.4rem;
  padding:.35rem .7rem;border-radius:var(--r-sm);
  background:var(--grn-soft);color:var(--grn-text);white-space:nowrap;
}
.hoy-etq{min-width:0;overflow:hidden;text-overflow:ellipsis;font-size:.875rem;font-weight:700}
.hoy-val{flex:0 0 auto;font-size:1.05rem;font-weight:900;font-variant-numeric:tabular-nums}
header.shell form{flex:0 0 auto;margin:0}
.salir{min-height:48px;min-width:48px;padding:0 .9rem;border:1.5px solid var(--line-2);border-radius:var(--r-sm);background:var(--bg);color:var(--ink-2);font-weight:700;font-size:.95rem}

/* ---------- venta ---------- */
/* a refused tap answers 200 at /venta/agregar#t<id>, so the page opens at the
   tile: the error stays pinned under the sticky header (60 px), where it is seen */
body.venta>.flash-err{position:sticky;top:60px;z-index:25;margin:0;border-radius:0;border-width:0 0 1.5px;padding:.8rem var(--sp-3);font-size:.95rem;font-weight:600}
.split{display:flex;flex-direction:column;gap:var(--sp-4);padding:var(--sp-3)}
.menu .tile-form{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px;margin:0}
/* category names are titles: la voz, sentence case (DESIGN.md, dos voces) */
.menu h2.cat{grid-column:1/-1;margin:var(--sp-4) 0 0;padding:0;border:none;font-size:1.1rem;font-weight:800;color:var(--ink)}
.menu h2.cat:first-of-type{margin-top:var(--sp-1)}
/* a tile: name, then the price at the size the source image sets (18 px, ink) */
.tile{
  min-height:78px;padding:10px 12px;
  display:flex;flex-direction:column;justify-content:space-between;gap:.35rem;
  background:var(--bg);color:var(--ink);text-align:left;font-family:var(--ui);
  border:1.5px solid var(--line-2);border-radius:var(--r-sm);
  scroll-margin-top:30vh;   /* after a tap the page lands with this tile a third down, under the thumb */
}
.tile .nm{font-size:15px;font-weight:600;line-height:1.2}
.tile .tile-def{display:block;margin:-.25rem 0 auto;font-size:12px;font-weight:600;line-height:1.2;color:var(--ink-3)}
.tile .px{font-size:18px;font-weight:800;line-height:1;font-variant-numeric:tabular-nums}
.tile:active{border-color:var(--grn);background:var(--grn-soft)}
/* the tile in the URL fragment is the last one added */
.tile:target,.tile.ult{border-color:var(--grn);box-shadow:inset 0 0 0 1.5px var(--grn)}
/* ...unless the tap was refused (a flash precedes .split): no ring then */
body.venta>.flash-err~.split .tile:target{border-color:var(--line-2);box-shadow:none}
.tile:disabled{background:var(--panel);color:var(--ink-3);border-color:var(--line);cursor:not-allowed}

/* the cuenta: one row per item (qty, name, amount, x), the source image's lines */
.pedido{background:var(--bg)}
.pedido .cab h2{margin:0;padding:0;border:none;font-size:1.2rem}
.pedido form{margin-top:0;margin-bottom:0}
.lines{list-style:none;margin:0;padding:0}
.lines li{display:flex;align-items:center;gap:.6rem;min-height:56px;padding:4px 0;border-bottom:1px dashed var(--line-2)}
.lines li:last-child{border-bottom:none}
.lines .q{flex:0 0 auto;min-width:2ch;text-align:right;font-weight:800;color:var(--grn-text);font-variant-numeric:tabular-nums}
.lines .nm{flex:1 1 auto;min-width:0;font-weight:600;font-size:.98rem;line-height:1.25}
.lines .amt{flex:0 0 auto;font-weight:700;font-variant-numeric:tabular-nums}
/* the removal button takes one off the line: it reads "−1" (aria-label "Quitar uno: <producto>") */
.lines .x{flex:0 0 auto;min-width:52px;height:48px;margin-left:var(--sp-3);padding:0 .5rem;border:1.5px solid var(--line-2);border-radius:var(--r-sm);background:var(--bg);color:var(--ink);font-family:var(--ui);font-size:1.05rem;font-weight:800;line-height:1;font-variant-numeric:tabular-nums}
.lines .x:active{border-color:var(--ink-2)}
.vacio{margin:0;color:var(--ink-2);font-size:.95rem;line-height:1.35}
.vacio b{display:block;font-family:var(--voz);font-size:1.05rem;font-weight:800;color:var(--ink)}
.cobro .total{min-width:0;color:inherit;text-decoration:none;line-height:1.1}
.cobro .total span{font-size:var(--fs-caption);font-weight:700;color:var(--ink-2)}
.cobro .total .n{font-style:normal;font-weight:600}
.cobro .total b{font-size:1.75rem;font-weight:900;letter-spacing:-.01em;color:var(--grn-text);font-variant-numeric:tabular-nums;white-space:nowrap}
a.btn-cobrar{display:flex;align-items:center;justify-content:center;text-decoration:none;border-radius:var(--r-sm)}
.cerrar,.cerrar-barra{display:none}
/* a chevron, drawn: two borders of a turned square (no icon font, no image) */
.cerrar::before,.pedido .lineas::after{content:"";display:block;width:9px;height:9px;border:solid var(--ink-2);border-width:2.5px 0 0 2.5px;transform:rotate(45deg)}

/* ---------- the sheet: the cuenta on a phone (under 1024 px) ----------
   Closed: a bar in the thumb zone. One line of the order (the peek), then the
   total and Cobrar. The peek and the total open the sheet (#cuenta).
   Open: the full lines over the same bar; Cobrar does not move. The menu stays
   above it and live: a tile tap adds and closes the sheet. */
@media (max-width:1023px){
  body.venta{min-height:100vh;padding-bottom:calc(150px + env(safe-area-inset-bottom))}
  .pedido{
    position:fixed;left:0;right:0;bottom:0;z-index:20;
    display:flex;flex-direction:column;max-height:76vh;
    padding-top:14px;
    padding-left:env(safe-area-inset-left);padding-right:env(safe-area-inset-right);
    border-top:1px solid var(--line-2);border-radius:var(--r-lg) var(--r-lg) 0 0;
    box-shadow:0 -10px 24px -18px rgba(15,20,23,.35);
  }
  /* the grip: says "this pulls up" */
  .pedido::before{content:"";position:absolute;top:6px;left:50%;width:36px;height:4px;margin-left:-18px;border-radius:2px;background:var(--line-2)}
  .pedido>*{width:100%;max-width:640px;margin-left:auto;margin-right:auto}
  .pedido.vacia{padding-top:0;border-radius:0}
  .pedido.vacia::before{content:none}
  .pedido .cab{display:none}
  .cobro{display:flex;align-items:center;gap:var(--sp-3);min-height:80px;padding:6px var(--sp-3);padding-bottom:calc(10px + env(safe-area-inset-bottom))}
  .cobro .total{flex:1 1 50%;min-height:48px;display:flex;flex-direction:column;justify-content:center}
  .cobro .btn-cobrar{flex:1 1 50%;min-height:60px}
  .cobro .vacio{flex:1 1 auto}
  .pedido.vacia .cobro{padding-top:10px}

  /* closed: the peek. The same list, as one line: "3 Taco al pastor · 1 Agua..." */
  .pedido:not(:target) .lineas{position:relative;padding:2px 44px 0 var(--sp-3)}
  .pedido:not(:target) .lineas::after{position:absolute;right:20px;top:50%;margin-top:-2px}
  .pedido:not(:target) .lines{overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:.95rem;line-height:28px;color:var(--ink)}
  .pedido:not(:target) .lines li{display:inline;min-height:0;padding:0;border:none}
  .pedido:not(:target) .lines li+li::before{content:"\00B7";margin:0 .45em;color:var(--ink-3);font-weight:700}
  .pedido:not(:target) .lines .q{margin-right:.3em;font-weight:800}
  .pedido:not(:target) .lines .nm{font-size:inherit}
  .pedido:not(:target) .lines .amt,.pedido:not(:target) .lines .x{display:none}
  /* the motivo of a removal belongs to the open sheet, where the −1 buttons are; closed, the
     chevron then sits on the peek line, inside the tap that opens the sheet */
  .pedido:not(:target) .pide-motivo{display:none}
  /* the options stay in the one-line peek: Taco al pastor (Verde) */
  .pedido:not(:target) .lines small.mods{display:inline;font-size:inherit;color:var(--ink-2)}
  .pedido:not(:target) .lines small.mods::before{content:" ("}
  .pedido:not(:target) .lines small.mods::after{content:")"}
  /* the peek is part of the tap that opens: the total link reaches up over the
     peek line only, so a mesa bar above it keeps its own buttons */
  .pedido:not(:target) .cobro{position:relative}
  .pedido:not(:target) .cobro .total::after{content:"";position:absolute;left:0;right:0;top:-36px;height:36px}

  /* open */
  .pedido:target{box-shadow:0 -14px 36px -10px rgba(15,20,23,.4)}
  .pedido:target .cab{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);padding:0 var(--sp-3) var(--sp-1) var(--sp-4)}
  .pedido:target .cerrar{display:flex;align-items:center;justify-content:center;flex:0 0 auto;width:48px;height:48px;border:1.5px solid var(--line-2);border-radius:var(--r-sm)}
  .pedido:target .cerrar::before{margin-top:-5px;transform:rotate(225deg)}
  .pedido:target .lineas{flex:0 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:0 var(--sp-3) var(--sp-2) var(--sp-4);
    /* a long cuenta scrolls: a shade over the bar says there is more; at the
       end of the list a white cover (it scrolls with the rows) hides it */
    background:linear-gradient(var(--bg),var(--bg)) bottom/100% 20px no-repeat local,
               linear-gradient(rgba(15,20,23,0),rgba(15,20,23,.2)) bottom/100% 18px no-repeat scroll;
    background-color:var(--bg)}
  .pedido:target .lineas::after{content:none}
  .pedido:target .cobro{position:relative;border-top:2px solid var(--ink)}
  /* the total, tapped again, closes */
  .pedido:target .cerrar-barra{display:block;position:absolute;left:0;top:0;bottom:0;width:50%}
  /* the last line removed: the page lands on #cuenta with nothing to show; stay a bar */
  .pedido.vacia .cab{display:none}
  .pedido.vacia .cobro{border-top:none}
  .pedido.vacia:target{box-shadow:0 -10px 24px -18px rgba(15,20,23,.35)}
}

/* ---------- the pane: the cuenta beside the menu (1024 px and up) ---------- */
@media (min-width:1024px){
  .split{flex-direction:row;align-items:flex-start;padding:var(--sp-4)}
  .menu{flex:1 1 auto;min-width:0}
  .menu .tile-form{grid-template-columns:repeat(auto-fill,minmax(160px,1fr))}
  /* the pane stays in view; a long cuenta scrolls inside it, Cobrar never leaves */
  .pedido{flex:0 0 380px;position:sticky;top:calc(61px + var(--sp-4));max-height:calc(100vh - 61px - 2rem);display:flex;flex-direction:column;border:1px solid var(--line);border-radius:var(--r-md);padding:var(--sp-4);scroll-margin-top:var(--sp-3)}
  .pedido .cab{margin:0 0 var(--sp-2)}
  .pedido .lineas{flex:0 1 auto;min-height:0;overflow-y:auto}
  .pedido .lineas::after{content:none}
  .cobro{padding:var(--sp-3) 0 0;margin-top:var(--sp-2);border-top:2px solid var(--ink)}
  .cobro .total{display:flex;align-items:baseline;justify-content:space-between;min-height:48px;margin:0 0 var(--sp-2);padding:.4rem 0}
  .cobro .total span{font-size:1rem;color:var(--ink)}
  .cobro .total b{font-size:2rem}
  .cobro .btn-cobrar{width:100%}
  .cobro .vacio{padding:var(--sp-1) 0}
  .pedido.vacia .cobro{margin-top:0;padding-top:0;border-top:none}
}

/* ---------- the card pages: login, abrir turno, cobrar, errors ---------- */
main.card{width:auto;max-width:400px;margin:var(--sp-7) auto;padding:var(--sp-6) var(--sp-5)}
@media (max-width:431px){main.card{margin:var(--sp-3);padding:var(--sp-5) var(--sp-4) var(--sp-6)}}
.card .marca{display:block;margin-bottom:var(--sp-4);font-size:1.1rem;color:var(--ink-2)}
.card h1{font-size:var(--fs-lg);margin-bottom:var(--sp-2)}
.card>p{color:var(--ink-2)}
.card>p.flash-err{color:var(--warn)}
.card.entrar .marca{margin-bottom:var(--sp-1);font-size:2.4rem;color:var(--ink)}
.card .flash-err{margin:var(--sp-4) 0 0}
.card form{margin:0}
.card small{display:block;margin-top:.4rem;color:var(--ink-3);font-size:.9rem;line-height:1.35}
.card .btn-cobrar{width:100%;margin-top:var(--sp-5)}
.card .btn{width:100%}
.card .volver{margin-top:var(--sp-3)}
.card .nota{margin:var(--sp-4) 0 0;color:var(--ink-2)}
/* a money field: a $ sign inside, big tabular figures */
.peso{position:relative}
.peso span{position:absolute;left:.9rem;top:50%;transform:translateY(-50%);font-size:1.4rem;font-weight:800;color:var(--ink-3);pointer-events:none}
.peso input{min-height:60px;padding-left:2.1rem;font-size:1.5rem;font-weight:800;font-variant-numeric:tabular-nums}
/* cobrar: the total to charge, the one number on the page */
.cobrar .total{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-3);margin:var(--sp-4) 0 var(--sp-1);padding:var(--sp-3) 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.cobrar .total span{color:var(--ink-2);font-weight:600}
.cobrar .total b{font-size:var(--fs-money);font-weight:900;letter-spacing:-.02em;line-height:1;color:var(--grn-text);font-variant-numeric:tabular-nums}
.card .exacto{margin-top:var(--sp-3)}
.exacto .btn{gap:.4em}

/* ---------- Cobrado: paid. A check, the word, the change as the one big number ---------- */
.cobrado .listo{text-align:center;padding:var(--sp-2) 0 0}
.palomita{display:block;width:64px;height:64px;margin:0 auto var(--sp-3)}
.palomita circle{fill:var(--grn-soft)}
/* the check draws once (DESIGN.md, motion: "a check that draws"). It starts with its short
   stroke already drawn and no delay, so the circle is never empty: a slow phone, or a look in
   the first tenth of a second, still sees a check (owner walk, 2026-10-11). */
.palomita path{fill:none;stroke:var(--grn);stroke-width:4.5;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:32;animation:palomita .26s ease-out both}
@keyframes palomita{from{stroke-dashoffset:21}to{stroke-dashoffset:0}}
.cobrado h1{margin:0 0 var(--sp-4)}
.cobrado .cambio{display:flex;flex-direction:column;align-items:center;gap:.3rem;margin:0;padding:var(--sp-4) 0;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.cobrado .cambio span{color:var(--ink-2);font-weight:700}
.cobrado .cambio b{font-size:var(--fs-display);font-weight:900;letter-spacing:-.02em;line-height:1;color:var(--grn-text);font-variant-numeric:tabular-nums}
.cobrado .cambio.sin span{font-size:var(--fs-lg);font-weight:800;color:var(--ink)}
.cobrado .recap{margin:var(--sp-3) 0 0;font-size:.9rem;color:var(--ink-2);font-variant-numeric:tabular-nums}
/* a phone: the page is the white screen of a money app; Nueva venta in the thumb zone */
@media (max-width:599px){
  body.cobrado-page{background:var(--bg)}
  main.card.cobrado{border:none;box-shadow:none;padding-bottom:calc(96px + env(safe-area-inset-bottom))}
  .cobrado .listo{padding-top:7vh}
  .cobrado .btn-cobrar{position:fixed;left:var(--sp-3);right:var(--sp-3);bottom:calc(var(--sp-3) + env(safe-area-inset-bottom));z-index:20;width:auto;margin:0}
  .cobrado .volver{margin-top:var(--sp-5)}
}
/* the screen goes back to the sale by itself (comal-cobrado in cobrado.html); the thin line shows the time left */
.cobrado .regreso{height:4px;margin:var(--sp-4) 0 0;border-radius:2px;background:var(--grn);transform-origin:left;animation:regreso var(--regreso,5s) linear both}
@keyframes regreso{from{transform:scaleX(1)}to{transform:scaleX(0)}}
@media (prefers-reduced-motion:reduce){.palomita path{animation:none}.cobrado .regreso{animation:none;display:none}}

/* ---------- the ticket: a receipt on screen, 80 mm on paper ---------- */
body.ticket-page{display:flex;flex-direction:column;align-items:center;padding:var(--sp-4) var(--sp-3);background:var(--bg)}
.ticket{width:320px;max-width:100%;padding:1.1rem 1rem;font-size:.85rem;line-height:1.5;font-variant-numeric:tabular-nums;box-shadow:0 12px 22px -14px rgba(15,20,23,.16)}
.ticket .c{text-align:center}
.ticket h1{margin:0;font-family:var(--ui);font-size:1.1rem;font-weight:900;letter-spacing:.02em;text-transform:uppercase}
.ticket .small{font-size:.875rem;color:var(--ink-2)}
.ticket hr{margin:.6rem 0;border:none;border-top:1.5px dashed var(--line-2)}
.ticket table{width:100%;border-collapse:collapse}
.ticket th{padding:0 0 .3rem;border-bottom:1px solid var(--line-2);font-size:.875rem;font-weight:700;letter-spacing:.06em;color:var(--ink-2)}
.ticket td{padding:.18rem 0;border-bottom:none;vertical-align:top;font-size:.9rem}
.ticket th:first-child,.ticket td.qty{padding-right:.6rem;white-space:nowrap}
.ticket .amt{padding-left:.5rem;text-align:right;white-space:nowrap}
.ticket tr.tot td{padding-top:.4rem;border-top:2px solid var(--ink);font-size:1.05rem;font-weight:800;color:var(--grn-text)}
/* the change is the number the cajero hands over: it reads first */
.ticket tr.cambio td{padding-top:.3rem;font-size:1.2rem;font-weight:800}
.acciones{width:320px;max-width:100%;margin-top:var(--sp-4)}
.acciones .btn,.acciones .btn-cobrar{width:100%}
.acciones .btn-cobrar{margin-top:var(--sp-3)}
.acciones a[hidden]{display:none}
@media print{
  body.ticket-page{display:block;padding:0;background:#fff}
  .acciones{display:none}
  /* thermal heads print black only: no grey, no green, no hairlines */
  .ticket{width:72mm;max-width:none;margin:0 auto;padding:3mm 0 6mm;box-shadow:none;font-size:9.5pt;font-weight:500;line-height:1.35;color:#000}
  .ticket h1{font-size:12pt}
  .ticket .small,.ticket th,.ticket tr.tot td{color:#000}
  .ticket .small{font-size:8.5pt}
  .ticket th{font-size:8pt;border-bottom:1px solid #000}
  .ticket td{font-size:9.5pt}
  .ticket hr{border-top:1px dashed #000}
  .ticket tr.tot td{border-top:1.5px solid #000;font-size:11pt}
  .ticket tr.cambio td{font-size:11pt}
}

/* ---------- the options under a sale line and on the ticket ---------- */
.lines .nm small.cmb{display:inline-block;margin-left:.5em;padding:0 .45em;border-radius:99px;background:var(--grn-soft);color:var(--grn-text);font-weight:700;font-size:.75rem;line-height:1.5;vertical-align:middle}
.pedido:not(:target) .lines small.cmb{display:none}
.lines .nm small.en-cocina{font-size:.8rem;font-weight:700;color:var(--ink-2)}
.lines .nm small.mods{display:block;font-weight:500;font-size:.9rem;line-height:1.3;color:var(--ink-2)}
.ticket small.mods{font-size:.875rem;color:var(--ink-2)}
@media print{.ticket small.mods{font-size:8.5pt;color:#000}}

/* ---------- the options picker (templates/elegir.html) ----------
   The item is the title. Each option is a full-width row to tap; a 1-of-1
   group draws round marks (the script makes it a single choice). Phone: the
   bar with Cancelar and Agregar sits in the thumb zone, where Cobrar sits. */
main.card.elegir{max-width:480px}
.elegir .eyebrow{margin:0 0 var(--sp-1);font-size:var(--fs-meta);font-weight:700;color:var(--ink-2)}
.elegir h1{margin:0 0 var(--sp-2);font-size:var(--fs-lg)}
.elegir .flash-err{margin:var(--sp-3) 0 0}
.elegir form{margin:0}
.elegir h2.cat{display:flex;flex-wrap:wrap;align-items:baseline;gap:.15rem .6rem;margin:var(--sp-5) 0 var(--sp-2);padding:0;border:none;font-size:1.2rem}
.elegir h2.cat small{font-family:var(--ui);font-size:.9rem;font-weight:600;letter-spacing:0;color:var(--ink-2)}
.elegir label.opcion,.caja label.opcion{
  position:relative;z-index:0;display:flex;align-items:center;gap:var(--sp-3);
  min-height:56px;margin:8px 0 0;padding:0 var(--sp-4) 0 var(--sp-3);
  border:1.5px solid var(--line-2);border-radius:var(--r-sm);background:var(--bg);
  font-family:var(--ui);font-size:1.05rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--ink);cursor:pointer;
}
/* the mark: drawn, so a 1-of-1 group can show a round one */
.elegir .opcion input,.caja .opcion input{
  -webkit-appearance:none;appearance:none;flex:0 0 auto;width:24px;height:24px;min-height:0;margin:0;padding:0;
  border:2px solid var(--ink-3);border-radius:6px;background:var(--bg) center/16px 16px no-repeat;
}
.elegir .opcion[data-max="1"] input,.caja .opcion input{border-radius:50%}
.elegir .opcion input:checked,.caja .opcion input:checked{border-color:var(--grn);background-color:var(--grn);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
.elegir .opcion[data-max="1"] input:checked,.caja .opcion input:checked{background-image:none;box-shadow:inset 0 0 0 4px var(--bg)}
.elegir .opcion input:focus-visible,.caja .opcion input:focus-visible{outline:2px solid var(--grn);outline-offset:2px}
/* the chosen row: a green-soft ground behind the words (no :has() on cheap phones) */
.elegir .opcion input:checked~.nm::before,.caja .opcion input:checked~.nm::before{content:"";position:absolute;z-index:-1;left:-1.5px;top:-1.5px;right:-1.5px;bottom:-1.5px;border:2px solid var(--grn);border-radius:var(--r-sm);background:var(--grn-soft)}
.elegir .opcion .nm,.caja .opcion .nm{flex:1 1 auto;min-width:0;line-height:1.25}
.elegir .opcion .px{flex:0 0 auto;font-weight:700;color:var(--ink-2);font-variant-numeric:tabular-nums}
.elegir-barra{display:flex;gap:var(--sp-3);margin-top:var(--sp-6)}
.elegir-barra .btn{flex:1 1 35%;min-height:60px}
.elegir-barra .btn-cobrar{flex:1 1 65%;margin:0;width:auto}
@media (max-width:599px){
  body.elegir-page{background:var(--bg);padding-bottom:calc(96px + env(safe-area-inset-bottom))}
  main.card.elegir{margin:0;border:none;box-shadow:none;padding:var(--sp-5) var(--sp-4) var(--sp-4)}
  .elegir-barra{position:fixed;left:0;right:0;bottom:0;z-index:20;margin:0;
    padding:10px var(--sp-3) calc(10px + env(safe-area-inset-bottom));
    background:var(--bg);border-top:1px solid var(--line-2);box-shadow:0 -10px 24px -18px rgba(15,20,23,.35)}
}

/* ---------- the admin pages: Catálogo, producto, opciones, Negocio ----------
   Phone: one white page, no card in a card; the sections flow under their
   titles. 600 px and up: the page is a card. 1024 px and up: Catálogo and
   Opciones put the list in the main column and the add forms in a rail. */
.admin-nav{
  position:relative;z-index:29;
  padding:0 var(--sp-2);
  padding-left:max(var(--sp-2),env(safe-area-inset-left));padding-right:max(var(--sp-2),env(safe-area-inset-right));
  background:var(--bg);border-bottom:1px solid var(--line);
}
/* ---------- the places (owner-UX draft, 2026-10-11) ----------
   One row that fits a 360 px phone with no swipe: Venta, Caja, Mesas, Reportes
   and Más for an encargado or a dueno; Venta, Caja, Mesas, Cocina for a cajero.
   Más is a native <details>: its sheet drops under the row, every other place
   in groups, one line each that says what is in it. The row no longer scrolls,
   so the sheet is not clipped. A row without Más (none today) keeps the old
   sideways scroll and its edge shades. The you-are-here grammar is .tabs: ink-2
   links, the page you are on in green with a green underline. */
.lugares .ir{
  display:flex;align-items:stretch;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;scrollbar-width:none;
  background:
    linear-gradient(90deg,#fff 40%,rgba(255,255,255,0)) left/24px 100% no-repeat local,
    linear-gradient(270deg,#fff 40%,rgba(255,255,255,0)) right/24px 100% no-repeat local,
    linear-gradient(90deg,rgba(15,20,23,.16),rgba(15,20,23,0)) left/14px 100% no-repeat scroll,
    linear-gradient(270deg,rgba(15,20,23,.16),rgba(15,20,23,0)) right/14px 100% no-repeat scroll;
  background-color:var(--bg);
}
.lugares .ir::-webkit-scrollbar{display:none}
.lugares .ir.con-mas{overflow:visible;background:var(--bg)}
.lugares .ir>a,.lugares .mas>summary{
  flex:1 1 auto;min-width:0;display:flex;align-items:center;justify-content:center;gap:.3rem;min-height:52px;
  margin:0 0 -1px;padding:0 4px;border-bottom:2.5px solid transparent;box-shadow:none;
  font-size:.98rem;font-weight:700;color:var(--ink-2);text-decoration:none;white-space:nowrap;cursor:pointer;
}
.lugares .ir>a:active,.lugares .mas>summary:active{color:var(--ink)}
.lugares .ir>a[aria-current="page"],.lugares .mas>summary.aqui,
.pg-catalogo .lugares .mas>summary,.pg-opciones .lugares .mas>summary,.pg-negocio .lugares .mas>summary,
.pg-equipo .lugares .mas>summary,.pg-empiece .lugares .mas>summary{color:var(--grn-text);border-bottom-color:var(--grn);box-shadow:none}
.lugares .mas{flex:1 1 auto;display:flex;min-width:0}
.lugares .mas>summary{list-style:none;width:100%}
.lugares .mas>summary::-webkit-details-marker{display:none}
/* a small chevron: down when closed, up when open */
.lugares .mas>summary::after{content:"";width:7px;height:7px;margin:-3px 0 0 2px;border:solid currentColor;border-width:0 2px 2px 0;transform:rotate(45deg)}
.lugares .mas[open]>summary{color:var(--ink)}
.lugares .mas[open]>summary::after{margin-top:4px;transform:rotate(225deg)}
.lugares .hoja{
  position:absolute;left:0;right:0;top:100%;z-index:40;
  max-height:calc(100vh - 120px);overflow-y:auto;-webkit-overflow-scrolling:touch;
  padding:0 0 var(--sp-3);background:var(--bg);border-bottom:1px solid var(--line-2);
  box-shadow:0 18px 30px -14px rgba(15,20,23,.32);white-space:normal;text-align:left;
}
.lugares .hoja .grupo{margin:0;padding:var(--sp-4) var(--sp-4) var(--sp-2);font-family:var(--voz);font-size:1.05rem;font-weight:700;color:var(--ink)}
.lugares .hoja ul{list-style:none;margin:0;padding:0}
.lugares .hoja li{position:relative;display:flex;flex-direction:column;justify-content:center;gap:.1rem;min-height:60px;
  margin:0;padding:8px 44px 8px var(--sp-4);border-top:1px solid var(--line)}
/* the whole row is the link (the link stays bare: <a href="/qr">Códigos QR</a>) */
.lugares .hoja li a{display:block;min-height:0;margin:0;padding:0;border:none;font-size:1.02rem;font-weight:700;color:var(--ink);text-decoration:none}
.lugares .hoja li a::after{content:"";position:absolute;top:0;right:0;bottom:0;left:0}
.lugares .hoja li small{display:block;font-size:.88rem;line-height:1.3;color:var(--ink-2)}
.lugares .hoja li::after{content:"";position:absolute;right:20px;top:50%;width:8px;height:8px;margin-top:-5px;border:solid var(--ink-3);border-width:2px 2px 0 0;transform:rotate(45deg)}
.lugares .hoja li:active{background:var(--panel)}
.lugares .hoja li a[aria-current="page"]{color:var(--grn-text)}
@media (min-width:600px){
  .admin-nav{padding:0 var(--sp-4)}
  .lugares .ir>a,.lugares .mas>summary{flex:0 0 auto;padding:0 var(--sp-3)}
  .lugares .mas{flex:0 0 auto;position:relative}
  .lugares .hoja{left:0;right:auto;width:380px;max-height:calc(100vh - 140px);padding-bottom:var(--sp-2);
    border:1px solid var(--line-2);border-radius:0 0 var(--r-lg) var(--r-lg)}
}

main.adm{max-width:none;margin:0;padding:var(--sp-5) var(--sp-4) var(--sp-8);border:none;border-radius:0;box-shadow:none}
@media (min-width:600px){
  main.adm{max-width:720px;margin:var(--sp-6) auto;padding:var(--sp-6) var(--sp-7) var(--sp-7);border:1px solid var(--line);border-radius:var(--r-lg);box-shadow:0 1px 2px rgba(15,20,23,.04),0 14px 34px -22px rgba(15,20,23,.22)}
}
.adm h1{margin:0}
.adm .cab{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);flex-wrap:wrap}
.adm .cab .btn{min-height:48px;padding:0 var(--sp-4);font-size:.98rem}
.adm>.nota,.adm .cab+.nota{margin:var(--sp-2) 0 0;color:var(--ink-2)}
.adm .flash-err,.adm .flash-ok{margin:var(--sp-4) 0 0}
.adm .rail>.flash-err{margin:var(--sp-7) 0 0}
@media (min-width:1024px){.adm .avisos,.adm .cab a[href="#nuevo"]{display:none}}
.adm .rail>.flash-err+.bloque{margin-top:var(--sp-4)}
.adm .bloque{margin:var(--sp-7) 0 0}
.adm .bloque>h2:first-child{margin-top:0}
.adm .bloque>.nota{margin:0;color:var(--ink-2)}
.adm form{margin:0}
.adm input.rfc{text-transform:uppercase;letter-spacing:.04em}
.adm small{display:block;margin-top:.4rem;color:var(--ink-3);font-size:.9rem;line-height:1.35}
.adm form>.btn{width:100%;margin-top:var(--sp-5)}
/* "Required": a box and its words on one row, sentence case */
.adm label.check{display:flex;align-items:center;gap:var(--sp-3);min-height:52px;margin:var(--sp-3) 0 0;
  font-size:1rem;font-weight:600;letter-spacing:0;text-transform:none;color:var(--ink);cursor:pointer}
.adm label.check input{flex:0 0 auto;width:24px;height:24px;min-height:0;margin:0;accent-color:var(--grn)}
/* min and max side by side: two small numbers */
.adm .par{display:flex;gap:var(--sp-3)}
.adm .par>div{flex:1 1 0;min-width:0}
.adm .back{display:inline-flex;align-items:center;gap:.5rem;min-height:48px;margin:0 0 var(--sp-2) calc(-1 * var(--sp-2));padding:0 var(--sp-2);font-weight:700;text-decoration:none}
.adm .back::before{content:"";width:8px;height:8px;border:solid currentColor;border-width:0 0 2.5px 2.5px;transform:rotate(45deg)}

/* the lists: a category or group title, then rows on hairlines */
.adm h2.cat{display:flex;flex-wrap:wrap;align-items:baseline;gap:.15rem .6rem;margin:var(--sp-6) 0 0;padding:0 0 var(--sp-2);border-bottom:1.5px solid var(--ink);font-size:1.2rem}
.adm .lista>h2.cat:first-of-type,.adm .lista>input+h2.cat{margin-top:var(--sp-3)}
.adm h2.cat small{font-family:var(--ui);font-size:.9rem;font-weight:600;letter-spacing:0;color:var(--ink-2)}
.adm .fila{display:flex;align-items:center;gap:var(--sp-3);min-height:56px;padding:4px 0;border-bottom:1px solid var(--line)}
.adm .fila .nm{flex:1 1 auto;min-width:0;font-weight:600;line-height:1.25}
.adm .fila .px{flex:0 0 auto;font-weight:700;font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}
.adm .rail>.nota{margin:var(--sp-5) 0 0;color:var(--ink-2)}
.adm .bloque>.ir{width:100%;margin-top:var(--sp-4)}
.adm .lista>.nota{padding:var(--sp-3) 0;color:var(--ink-2);border-bottom:1px solid var(--line)}

/* a product: the name over its IVA (the whole left side opens the product),
   the price, the 86 switch. The price column keeps one right edge, so the
   pesos line up. The markup keeps <span class="nm">..</span><span class="px">
   side by side: the e2e reads it. */
.adm .prod{display:grid;grid-template-columns:minmax(0,1fr) auto auto;grid-template-rows:auto auto;column-gap:var(--sp-3);row-gap:0;min-height:64px;padding:8px 0;scroll-margin-top:30vh}
.adm .prod .nm{grid-column:1;grid-row:1;align-self:end;font-weight:700}
.adm .prod .meta{grid-column:1;grid-row:2;align-self:start;margin-top:.1rem;font-size:.9rem;color:var(--ink-2)}
.adm .prod .px{grid-column:2;grid-row:1/3;align-self:center;min-width:4.6rem;font-size:1.02rem}
.adm .prod .btn{grid-column:3;grid-row:1/3;align-self:center;width:7.6rem;min-height:48px;padding:0 var(--sp-2);font-size:.9rem;line-height:1.15;white-space:normal;text-align:center}
.adm .prod a.abrir{grid-column:1;grid-row:1/3;z-index:1;min-height:48px}
.adm .prod a.abrir:focus-visible{outline-offset:-2px}
.adm .prod .ed{font-weight:700;color:var(--grn-text)}
.adm .prod .agot{font-style:normal;font-weight:800;color:var(--warn)}
.adm .prod.agotado .nm,.adm .prod.agotado .px{color:var(--ink-2)}
.adm .prod.agotado .px{text-decoration:line-through;text-decoration-thickness:1.5px}
.adm .prod.retirado .nm,.adm .prod.retirado .px{color:var(--ink-2)}
.adm .catgest .fila{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2);align-items:center;padding:var(--sp-3) 0}
.adm .catgest .fila input[name=name]{grid-column:1/-1;min-width:0;margin:0}
.adm .catgest .fila .agot{grid-column:1/-1}
.adm .catgest .fila .coc{grid-column:1/-1;display:flex;align-items:center;gap:var(--sp-2);min-height:48px;font-weight:700}
.adm .catgest .fila .coc input{width:24px;height:24px;margin:0}
.adm .catgest .fila .btn{width:100%;min-height:48px;margin:0;padding:0 var(--sp-2);font-size:.9rem}
.adm .catgest .fila.retirado input[name=name]{color:var(--ink-2);background:var(--panel)}
.adm .catgest .agot{font-style:normal;font-weight:800;color:var(--warn)}
/* the row just switched (the page lands on #i<id>) */
.adm .prod:target{background:var(--panel);box-shadow:-12px 0 0 var(--panel),12px 0 0 var(--panel)}
@media (max-width:399px){.adm .prod .btn{width:6.6rem;font-size:.875rem}}
@media (min-width:600px){.adm .prod .btn{width:auto;min-width:9.5rem;padding:0 var(--sp-4);white-space:nowrap}}
.sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

/* a group on the product page: a mark says whether it is on this product */
.adm .grp .nm{display:flex;align-items:center;gap:var(--sp-3)}
.adm .grp .nm::before{content:"";flex:0 0 auto;width:22px;height:22px;border:2px solid var(--ink-3);border-radius:50%;box-sizing:border-box}
.adm .grp.puesto .nm::before{border-color:var(--grn);background:var(--grn) center/14px 14px no-repeat;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M3.5 8.5l3 3 6-7' fill='none' stroke='%23fff' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}
.adm .grp .btn{min-width:6.5rem;min-height:48px;padding:0 var(--sp-4);font-size:.95rem}
.adm .op .px{color:var(--ink-2);font-weight:600}

/* 1024 px and up: the list and, beside it, the forms that add to it */
@media (min-width:1024px){
  main.adm.ancho{max-width:var(--w-admin)}
  .adm .doble{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:var(--sp-8);align-items:start}
  .adm .doble>.rail>.bloque:first-child{margin-top:var(--sp-5)}
  .adm .doble.sola{display:block;max-width:440px}
  .adm .rail .bloque{padding:var(--sp-5);border:1px solid var(--line);border-radius:var(--r-lg);background:var(--panel)}
  .adm .rail .bloque>h2:first-child{font-size:1.2rem}
  .adm .rail input,.adm .rail select{background:var(--bg)}
}

/* ---------- step 3: who sells, Equipo, the PIN pages ---------- */
/* Who sells: the second deck of the header (white). Under 1024 px it is two
   rows of 48 px: the person (a drawn person, the name in ink, "..." when it is
   long) with Cambiar de usuario at the right, then the places in one row that
   scrolls sideways. The name never covers a link. 1024 px and up: one row. */
nav.sub{display:flex;flex-direction:column;border-bottom:1px solid var(--line);background:var(--bg);font-size:.95rem;white-space:nowrap}
nav.sub .yo-fila{display:flex;align-items:center;gap:var(--sp-2);min-height:48px;
  padding:0 var(--sp-1) 0 var(--sp-3);padding-left:max(var(--sp-3),env(safe-area-inset-left));padding-right:max(var(--sp-1),env(safe-area-inset-right));
  border-bottom:1px solid var(--line)}
nav.sub .quien{flex:1 1 auto;min-width:0;display:flex;align-items:center;gap:.45rem;color:var(--ink)}
nav.sub .quien b{min-width:0;overflow:hidden;text-overflow:ellipsis;font-weight:800}
svg.yo{flex:0 0 auto;fill:none;stroke:var(--ink-2);stroke-width:1.8;stroke-linecap:round}
nav.sub{position:relative;z-index:29}
nav.sub .ir{padding:0 var(--sp-1);padding-left:max(var(--sp-1),env(safe-area-inset-left));padding-right:max(var(--sp-1),env(safe-area-inset-right))}
/* every link of the who deck is a 48 px target */
nav.sub .yo-fila a{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;min-width:48px;min-height:48px;margin:0;padding:0 var(--sp-3);color:var(--grn-text);font-weight:700;text-decoration:none}
nav.sub .yo-fila a:active{color:var(--ink)}
@media (max-width:599px){nav.sub .ir>a.pin{display:none}}
@media (min-width:1024px){
  nav.sub{flex-direction:row;align-items:stretch}
  nav.sub .yo-fila{flex:0 1 auto;min-width:0;max-width:22rem;border-bottom:none;padding-left:max(var(--sp-4),env(safe-area-inset-left));border-right:1px solid var(--line)}
  nav.sub .ir{flex:1 1 auto;min-width:0;padding-right:max(var(--sp-3),env(safe-area-inset-right))}
}

/* Equipo: a person is two lines (name; e-mail, role, state) with Apagar or
   Encender at the right, and the role change on one row under them. */
.adm .persona{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"nm act" "meta act" "rol rol";
  column-gap:var(--sp-3);row-gap:.15rem;align-items:center;min-height:0;padding:var(--sp-4) 0;border-bottom:1px solid var(--line)}
.adm .persona .nm{grid-area:nm;align-self:end;font-weight:800;font-size:1.05rem}
.adm .persona .meta{grid-area:meta;align-self:start;color:var(--ink-2);font-size:.9rem;line-height:1.35;overflow-wrap:anywhere}
.adm .persona form{margin:0}
.adm .persona form.act{grid-area:act}
.adm .persona form.rol{grid-area:rol;display:flex;gap:var(--sp-2);margin-top:var(--sp-3)}
.adm .persona form>.btn{width:auto;margin:0;min-height:48px;padding:0 var(--sp-4);font-size:.95rem}
.adm .persona form.rol select{flex:1 1 auto;min-width:0;min-height:48px;padding-top:0;padding-bottom:0}
.adm .persona form.rol .btn{flex:0 0 auto}
.adm .persona.agotado .nm{color:var(--ink-2)}
.adm .persona.agotado .meta{color:var(--ink-2)}
@media (min-width:600px){.adm .persona form.rol{max-width:26rem}}
@media (max-width:599px){
  .admin-nav{padding:0 var(--sp-1)}
  /* a phone: the admin page is one white sheet to the bottom */
  body.admin{background:var(--bg)}
}

/* Mi PIN and Cambiar de usuario: the card of the login. A PIN field reads
   as a PIN (large, centred dots); the name on the pad is the title. */
.card input.pin{min-height:60px;padding-left:calc(.9rem + .45em);font-size:1.6rem;font-weight:800;letter-spacing:.45em;text-align:center}
.card .guardar{margin-top:var(--sp-5)}
.card p.quien-pad{display:flex;align-items:center;gap:.6rem;margin:var(--sp-2) 0 0;color:var(--ink)}
.card p.quien-pad b{min-width:0;font-family:var(--voz);font-size:var(--fs-lg);font-weight:800;line-height:1.15;overflow-wrap:anywhere}
.card .volver+.volver{margin-top:var(--sp-2)}
ul.nombres{list-style:none;margin:var(--sp-3) 0 var(--sp-2);padding:0;display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-2)}
ul.nombres .btn{display:flex;align-items:center;justify-content:center;min-height:64px;width:100%;padding:6px var(--sp-2);text-align:center;line-height:1.2;font-weight:700}
ul.nombres .btn:active{border-color:var(--grn);background:var(--grn-soft)}

/* the picker: the group a refused choice left short. Its words get their own
   line with a warning mark, and its options a red edge; red only warns. */
.elegir h2.cat .falta{order:3;flex:1 0 100%;display:flex;align-items:center;gap:.45rem;margin-top:.2rem;
  font-family:var(--ui);font-size:.95rem;font-weight:800;letter-spacing:0;color:var(--warn)}
.elegir h2.cat .falta::before{content:"!";flex:0 0 auto;display:flex;align-items:center;justify-content:center;width:20px;height:20px;border-radius:50%;background:var(--warn);color:#fff;font-size:.8rem;font-weight:900;line-height:1}
.elegir label.opcion.corta{border-color:var(--warn)}
/* the picker offline (templates/venta.html #off-elegir): a screen over the sale screen, the bar at its foot */
.off-elegir{position:fixed;top:0;right:0;bottom:0;left:0;z-index:40;overflow-y:auto;background:var(--bg);
  padding:var(--sp-5) var(--sp-4) calc(96px + env(safe-area-inset-bottom))}
.off-elegir[hidden]{display:none}
.off-elegir .elegir-barra{position:fixed;left:0;right:0;bottom:0;z-index:41;margin:0;
  padding:10px var(--sp-3) calc(10px + env(safe-area-inset-bottom));
  background:var(--bg);border-top:1px solid var(--line-2)}
@media (min-width:600px){.off-elegir{padding-left:calc(50% - 240px);padding-right:calc(50% - 240px)}}
/* a tile that opens the picker: a "+" after the price */
.tile.abre .mas{margin-left:.3rem;font-style:normal;font-weight:800;color:var(--ink-2)}

/* ========== Step 4: cobrar complete, Caja, the corte, Devolución ==========
   One small set: money rows (label left, amount right, tabular), a segmented
   choice made of radios, chips of 48 px, folded secondary forms, and the red
   outline for an action that takes money back (DESIGN.md: red only warns). */

/* a group label that is not on one field: the look of a field label */
.card .etq{margin:.9rem 0 .35rem;font-weight:700;font-size:.875rem;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-2)}

/* the segmented choice: radios first (hidden, still focusable), then their
   labels in one bordered row. A checked radio fills its label green-soft. */
.card input.forma{position:absolute;width:1px;height:1px;min-height:0;margin:0;padding:0;border:0;opacity:0;pointer-events:none}
.formas{display:flex;border:1.5px solid var(--line-2);border-radius:var(--r-sm);overflow:hidden;background:var(--bg)}
.card .formas label{flex:1 1 auto;min-width:0;display:flex;align-items:center;justify-content:center;min-height:52px;margin:0;padding:0 .55rem;
  font-size:.98rem;font-weight:700;text-transform:none;letter-spacing:0;color:var(--ink);text-align:center;line-height:1.15;cursor:pointer}
.card .formas label+label{border-left:1.5px solid var(--line-2)}
#forma-1:checked~.formas label[for=forma-1],#forma-2:checked~.formas label[for=forma-2],#forma-3:checked~.formas label[for=forma-3]{
  background:var(--grn-soft);color:var(--grn-text);font-weight:800;box-shadow:inset 0 0 0 2px var(--grn)}
#forma-1:focus-visible~.formas label[for=forma-1],#forma-2:focus-visible~.formas label[for=forma-2],#forma-3:focus-visible~.formas label[for=forma-3]{
  outline:2px solid var(--grn);outline-offset:-5px}
/* each tender shows only its own fields */
#forma-2:checked~.solo-efectivo,#forma-3:checked~.solo-efectivo,#forma-1:checked~.solo-ref{display:none}

/* chips: a choice that is a link (the even split), 48 px each */
.chip-n{display:inline-flex;align-items:center;justify-content:center;min-width:48px;min-height:48px;padding:0 .85rem;
  border:1.5px solid var(--line-2);border-radius:var(--r-sm);background:var(--bg);color:var(--ink);
  font-weight:700;font-size:1rem;text-decoration:none;font-variant-numeric:tabular-nums}
.chip-n.on{border-color:var(--grn);background:var(--grn-soft);color:var(--grn-text)}

/* a folded secondary form: a 48 px row that opens in place */
.card details.plegado>summary,.card details.propina>summary,.card details.anular>summary{
  display:flex;align-items:center;gap:.55rem;min-height:48px;list-style:none;cursor:pointer;font-weight:700}
.card details>summary::-webkit-details-marker{display:none}
.card details.propina>summary{margin-top:var(--sp-2);color:var(--grn-text)}
.card details.propina>summary::before{content:"+";display:flex;align-items:center;justify-content:center;width:24px;height:24px;
  border-radius:50%;background:var(--grn-soft);font-size:1.1rem;font-weight:900;line-height:1}
.card details.propina[open]>summary::before{content:"\2212"}
.card details.anular,.card details.plegado{margin-top:var(--sp-5);border-top:1px solid var(--line)}
.card details.anular>summary,.card details.plegado>summary{justify-content:space-between;color:var(--ink-2)}
.card details.anular>summary::after,.card details.plegado>summary::after{content:"";width:8px;height:8px;margin-right:4px;
  border:solid var(--ink-2);border-width:0 2px 2px 0;transform:rotate(45deg)}
.card details.anular[open]>summary::after,.card details.plegado[open]>summary::after{transform:rotate(225deg)}
.card details.anular label:first-of-type{margin-top:var(--sp-1)}

/* the action that takes money back: red outline, red words, never a fill */
.card .btn.btn-peligro{margin-top:var(--sp-4);border-color:var(--warn);color:var(--warn);background:var(--bg);font-weight:800}
.card .btn.btn-peligro:active{background:#FCF3F2}

/* ---------- cobrar ---------- */
.cobrar .pagos h2{margin:var(--sp-4) 0 0;padding-bottom:.4rem;font-size:1.1rem}
.cobrar .pagos td{padding:.55rem 0}
.cobrar .pagos td small{display:block;margin-top:.1rem;font-size:.875rem;color:var(--ink-3);overflow-wrap:anywhere}
.cobrar .pagos .nota{margin:var(--sp-2) 0 0;font-size:.95rem;font-variant-numeric:tabular-nums}
.cobrar .partes{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2);margin:var(--sp-5) 0 0;padding-top:var(--sp-2);border-top:1px solid var(--line)}
.cobrar .partes span,.cobrar .propinas span{flex:1 0 100%;margin:.4rem 0 -.1rem;font-weight:700;font-size:.875rem;text-transform:uppercase;letter-spacing:.04em;color:var(--ink-2)}
.cobrar .partes a{flex:1 1 0;margin-left:0}
.cobrar .partes a:first-of-type{flex:2 1 auto}
.cobrar .partes+details.anular{margin-top:var(--sp-3)}
/* the propina chips (DRAFT), above the one-tap buttons: "Sin propina" at its own width,
   then each percent with the amount the server computed under it */
.cobrar .propinas{display:flex;flex-wrap:wrap;align-items:stretch;gap:var(--sp-2);margin:var(--sp-2) 0 var(--sp-3)}
.cobrar .propinas a{flex:1 1 0;min-width:0;margin-left:0}
/* Sin propina is a chip like the others, the same width: an equal, neutral choice (Michael, 2026-10-08) */
.cobrar .desglose{width:100%;border-collapse:collapse;margin:var(--sp-2) 0 0}
.cobrar .desglose td{padding:.15rem 0}
.cobrar .desglose .amt{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
.chip-tip{flex-direction:column;gap:.05rem;padding:.3rem .5rem;line-height:1.1}
.chip-tip small{font-size:.875rem;font-weight:600;color:var(--ink-2)}
.chip-tip.on small{color:inherit}
.cobrar .parte{display:flex;align-items:baseline;gap:.45rem;margin:var(--sp-2) 0 0;padding:.6rem .8rem;border-radius:var(--r-sm);
  background:var(--grn-soft);color:var(--grn-text);font-weight:700;font-variant-numeric:tabular-nums}
.cobrar .parte span{margin-right:auto}
.cobrar .parte b{font-size:1.3rem;font-weight:900}
.cobrar .cobro-form{margin-top:var(--sp-1)}
.cobrar form.exacto{display:none}
/* the one-tap payment (BUILD.md 4e): Exacto full width, the bills two by two, card and transfer below.
   Each target is 60 px tall: a thumb on a counter, a wet hand. */
.cobrar .rapido{margin-top:var(--sp-3)}
/* the three ways are pay-now buttons, not tabs: one row each, the way at the left and the amount
   it pays at the right ("Tarjeta  $75.00"). Cash exact is the green fill; card and transfer are
   white with a green edge, so none reads as a selected tab. Fixed rows: no button moves when the
   total changes (tools/verify/comal-taps.py). */
.cobrar .formas-rapidas{display:flex;flex-direction:column;gap:var(--sp-2)}
.cobrar .formas-rapidas .btn,.cobrar .formas-rapidas .btn-cobrar{min-height:60px;height:60px;margin:0;width:100%;padding:0 var(--sp-4);display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:.3em;font-size:1.1rem;font-weight:800;line-height:1.15;white-space:nowrap;text-align:left}
.cobrar .formas-rapidas .forma-btn{background:var(--bg);color:var(--grn-text);border:2px solid var(--grn)}
.cobrar .formas-rapidas .forma-btn:active{background:var(--grn-soft)}
.cobrar .formas-rapidas small{display:inline;margin:0;font-size:inherit;font-weight:inherit;line-height:inherit;color:inherit}
.cobrar .formas-rapidas .cuanto{margin-left:auto;padding-left:var(--sp-3);font-size:1.2rem;font-weight:900;font-variant-numeric:tabular-nums}
.cobrar .forma-nota{margin:-.2rem 0 .1rem;padding:0 var(--sp-1);font-size:.9rem;line-height:1.3;color:var(--ink-2)}
.cobrar .billetes-etq{margin:var(--sp-3) 0 var(--sp-1);height:1.3rem;font-size:.9rem;font-weight:700;color:var(--ink-2)}
.cobrar .billetes{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-2)}
.cobrar .billete{height:60px;min-height:60px;font-size:1.35rem;font-weight:800;font-variant-numeric:tabular-nums}
.cobrar .billete:disabled{opacity:.35}
.cobrar details.otro{margin-top:var(--sp-4)}
.cobrar details.otro>summary{cursor:pointer;min-height:48px;display:flex;align-items:center;justify-content:space-between;font-weight:700;color:var(--ink-2);list-style:none}
.cobrar details.otro>summary::-webkit-details-marker{display:none}
/* the fold says it opens: the chevron of the other folds of the card */
.cobrar details.otro>summary::after{content:"";width:8px;height:8px;margin-right:4px;border-right:2px solid var(--ink-2);border-bottom:2px solid var(--ink-2);transform:rotate(45deg)}
.cobrar details.otro[open]>summary::after{transform:rotate(225deg)}
.card .exacto-btn{margin-top:var(--sp-3);gap:.4em}

/* ---------- money rows: a label left, the amount right (corte, devolver) ---------- */
.card .cifras{margin:var(--sp-4) 0 0;border-top:1px solid var(--line)}
.card .cifras .fila{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-3);margin:0;padding:.75rem 0;border-bottom:1px solid var(--line);color:var(--ink)}
.card .cifras .fila span{color:var(--ink-2);font-weight:600}
.card .cifras .fila b{font-size:1.3rem;font-weight:800;font-variant-numeric:tabular-nums;white-space:nowrap}
/* the corte: the difference is the one big number; short is red (red warns) */
.corte .cifras .fila-dif{align-items:center;padding:var(--sp-3) 0;border-bottom:none}
.corte .cifras .fila-dif span{color:var(--ink);font-weight:800}
.corte .cifras .fila-dif b{font-size:var(--fs-money);font-weight:900;letter-spacing:-.02em;line-height:1}
.corte .cifras .fila-dif.falta b{color:var(--warn)}
.corte .cifras .fila-dif.cuadra b{color:var(--grn-text)}
.card .veredicto{display:block;margin:0 0 var(--sp-1);padding:.6rem .8rem;border-radius:var(--r-sm);font-weight:800;font-size:1.05rem;text-align:center;font-variant-numeric:tabular-nums}
.card .veredicto.falta{background:#FCF3F2;color:var(--warn)}
.card .veredicto.cuadra{background:var(--grn-soft);color:var(--grn-text)}
.card .veredicto.sobra{background:var(--panel);color:var(--ink)}
.card .estado{margin:var(--sp-4) 0 0;padding:.8rem .9rem;border-radius:var(--r-sm);background:var(--panel);color:var(--ink);font-weight:600}
.card .flash-ok{margin:var(--sp-4) 0 0}

/* ---------- Caja: the kind of movement as three rows ---------- */
.caja .tipos{margin:0}
/* Corte de caja: the first thing on Caja, a clear way in (green-soft, an arrow), not a link at the foot */
.card.caja a.ir-corte{justify-content:space-between;width:100%;margin:var(--sp-3) 0 var(--sp-2);padding:0 var(--sp-4);background:var(--grn-soft);color:var(--grn-text);border:1.5px solid var(--grn);font-weight:800;font-size:1.1rem}
.card.caja a.ir-corte::after{content:"";flex:0 0 auto;width:9px;height:9px;border:solid currentColor;border-width:2.5px 2.5px 0 0;transform:rotate(45deg)}
.caja label.opcion:first-child{margin-top:0}

/* ---------- the corte ---------- */
.corte .recontar{margin-top:var(--sp-2)}
.corte .recontar .btn{margin-top:var(--sp-3)}
.corte .ventas h2,.corte .movs h2,.corte .audit h2{margin:var(--sp-7) 0 0;font-size:1.3rem}
.corte .audit>.nota{margin:var(--sp-2) 0 0;font-size:.92rem}
.corte .resumen td{padding:.6rem 0}
.corte .resumen tr.forma td{border-bottom-color:var(--line);color:var(--ink-2);font-size:.98rem}
.corte .resumen tr.forma td:first-child{padding-left:var(--sp-3)}
.corte .resumen tr.forma td.amt{font-weight:600}
.corte .resumen tr.vend td{font-weight:800;border-bottom:1px solid var(--line)}
.corte .resumen tr.tot td{padding-top:.75rem;font-size:1.05rem;font-weight:800;border-top:2px solid var(--ink);border-bottom:none}
.corte .resumen tr.tot td.amt b{font-size:1.3rem;font-weight:900}
.corte .ventas .flash-err{margin-top:var(--sp-3)}
/* event rows, stacked at every width (the corte's lists and the Caja's
   "Anotado en este turno"): kind and amount; the item; the reason; who and
   when. A cell left empty takes no room. */
.corte table.eventos,.corte table.eventos tbody,.caja table.eventos,.caja table.eventos tbody{display:block;width:100%}
.corte table.eventos tr,.caja table.eventos tr{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:var(--sp-3);padding:.7rem 0;border-bottom:1px solid var(--line)}
.corte table.eventos td,.caja table.eventos td{display:block;min-width:0;padding:0;border:0;font-size:.95rem;line-height:1.35;overflow-wrap:anywhere}
.corte table.eventos td:empty,.caja table.eventos td:empty{display:none}
.corte .mv-line td:nth-child(3),.caja .mv-line td:nth-child(3),.corte .au-line td:nth-child(3){grid-row:1;grid-column:1;font-weight:800;color:var(--ink)}
.corte .mv-line td.amt,.caja .mv-line td.amt,.corte .au-line td.amt{grid-row:1;grid-column:2;font-size:1.05rem;font-weight:800;font-variant-numeric:tabular-nums;text-align:right}
.corte .mv-line td:nth-child(4),.caja .mv-line td:nth-child(4),.corte .au-line td:nth-child(4){grid-row:2;grid-column:1/3;color:var(--ink)}
.corte .au-line td:nth-child(5){grid-row:3;grid-column:1/3;color:var(--ink-2)}
.corte .mv-line td:nth-child(2),.caja .mv-line td:nth-child(2),.corte .au-line td:nth-child(2){grid-row:4;grid-column:1;margin-top:.15rem;font-size:.9rem;color:var(--ink-3)}
.corte .mv-line td:nth-child(1),.caja .mv-line td:nth-child(1),.corte .au-line td:nth-child(1){grid-row:4;grid-column:2;margin-top:.15rem;font-size:.9rem;color:var(--ink-3);text-align:right;white-space:nowrap}
.caja .movs h2{margin:var(--sp-7) 0 0;font-size:1.3rem}
.caja .movs+.btn.volver{margin-top:var(--sp-6)}
/* the paid sales: folded; each row reaches its refund with a 48 px button */
.corte details.lista{margin-top:var(--sp-6)}
.corte details.lista>summary{font-family:var(--voz);font-size:1.3rem;font-weight:800;color:var(--ink);letter-spacing:-.015em}
.corte .ventas-lista td{padding:.35rem 0;vertical-align:middle}
.corte .ventas-lista td.amt{padding-right:var(--sp-3)}
.corte .ventas-lista td.ir{width:1%;white-space:nowrap}
.corte .ventas-lista td.ir a{display:inline-flex;align-items:center;min-height:48px;padding:0 var(--sp-4);border:1.5px solid var(--line-2);border-radius:var(--r-sm);
  color:var(--ink);font-weight:700;font-size:.95rem;text-decoration:none}
/* Devoluciones del turno: seven cells a line; on a phone each line is a card (it was wider than 360 px and pushed the page wide) */
@media (max-width:599px){
  .corte table.rf-lista,.corte table.rf-lista tbody{display:block;width:100%}
  .corte .rf-line{display:flex;flex-wrap:wrap;align-items:baseline;gap:.15rem .6rem;padding:.75rem 0;border-bottom:1px solid var(--line)}
  .corte .rf-line td{display:block;padding:0;border:0;min-width:0;overflow-wrap:anywhere;order:4}
  .corte .rf-line td:nth-child(1){order:1;font-weight:800}
  .corte .rf-line td.amt{order:2;margin-left:auto;font-weight:800;white-space:nowrap}
  .corte .rf-line td:nth-child(6){order:3;flex-basis:100%}
}
.corte .cerrar-turno{margin-top:var(--sp-6);padding-top:var(--sp-2);border-top:1px solid var(--line)}
.corte .cerrar-turno .nota{margin:var(--sp-3) 0 0}
.corte .cerrar-turno .btn-cobrar{margin-top:var(--sp-3)}
.corte>.btn.volver:first-of-type{margin-top:var(--sp-6)}
/* a laptop: the corte reads wider, the event lists get room */
@media (min-width:768px){main.card.corte{max-width:560px}}

/* ---------- Devolución ---------- */
.devolver form .btn-peligro{min-height:60px;margin-top:var(--sp-5);font-size:1.15rem}

/* ---------- step 4c ---------- */
/* a negative Vendido hoy (refunds of an earlier turno): green is money that
   is right, so the chip turns neutral; the minus leads (-$78.00) */
header.shell .hoy.neg{background:var(--panel);color:var(--ink);box-shadow:inset 0 0 0 1px var(--line-2)}
/* the corte's net total below zero: ink, not the money green */
.corte .resumen tr.tot.neg td.amt{color:var(--ink)}
/* Negocio: the Caja rule sits apart from the four ticket fields */
.adm form h2.parte{margin:var(--sp-7) 0 0}
.adm input[aria-invalid="true"]{border-color:var(--warn);box-shadow:inset 0 0 0 1px var(--warn)}

/* ========== Step 4b: offline para llevar (static/comal-offline.js) ==========
   The state line, the offline cart and the local ticket. Offline, the screen keeps the
   shape the cajero knows: the menu, then the cuenta in the thumb zone with Cobrar where
   Cobrar always is. Only the state line says what changed. */
.off-arriba [hidden],.off-panel[hidden],.off-panel [hidden],.off-ticket[hidden],#unsent-msg[hidden]{display:none}

/* the state line. Online with nothing to send: a quiet line at the foot of the menu.
   Offline: an ink bar under the header (sticky). Online with sales to send: a grey bar. */
.off-arriba{position:sticky;top:60px;z-index:25}
.off-badge{display:flex;align-items:center;flex-wrap:wrap;gap:0 .4rem;min-height:40px;margin:0;padding:0 var(--sp-3);font-size:.92rem;font-weight:700;color:var(--ink-2)}
.off-badge:not([data-state]){display:none}
.off-badge #off-state::before{content:"";display:inline-block;width:9px;height:9px;margin-right:.5rem;border-radius:50%;background:var(--grn);vertical-align:1px}
.off-badge #off-n{font-variant-numeric:tabular-nums}
.off-badge #off-n::before{content:"\00B7";margin-right:.4rem}
.off-pie .off-badge[data-n="0"] #off-n,.off-pie .off-badge[data-n="0"] #off-unsent{display:none}
.off-pie{padding:0 0 var(--sp-2)}
.off-pie .off-badge{font-size:.875rem;font-weight:600}
.off-arriba .off-badge{background:var(--panel);color:var(--ink);border-bottom:1px solid var(--line-2)}
.off-arriba .off-badge[data-state=off]{background:var(--ink);color:#fff;border-bottom-color:var(--ink)}
.off-badge[data-state=off] #off-state::before{background:transparent;box-shadow:inset 0 0 0 2px #fff}
/* sales wait to be sent: "No cierre esta ventana" in the same bar. A phone gives it the second row
   of the bar (no dot leads it); from 600 px it follows the count on one row */
.off-badge #off-cierre{white-space:nowrap}
.off-badge #off-cierre:not([hidden])::before{content:"\00B7";margin-right:.4rem}
@media (max-width:599px){
  .off-arriba .off-badge{padding-top:6px;padding-bottom:6px;line-height:1.3}
  .off-badge #off-cierre{flex-basis:100%;padding-left:calc(9px + .5rem)}
  .off-badge #off-cierre:not([hidden])::before{content:none}
}
.off-arriba .flash-err{margin:0;border-radius:0;border-width:0 0 1.5px;padding:.7rem var(--sp-3);font-size:.95rem;font-weight:600;line-height:1.35}
/* the session ended: calm, not red; the way back is a 48 px button */
.off-aviso{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-2) var(--sp-3);margin:0;padding:.7rem var(--sp-3);background:var(--bg);border-bottom:1.5px solid var(--line-2);color:var(--ink);font-size:.95rem;font-weight:600;line-height:1.35}
.off-aviso .btn{min-height:48px;padding:0 var(--sp-5);text-decoration:none}

/* offline, a product with options needs the connection: it reads as not available here */
body.off .tile.abre{background:var(--panel);color:var(--ink-2);border-color:var(--line)}
body.off .pedido{display:none}

/* the offline cart */
.off-panel{background:var(--bg)}
.off-panel h2{margin:0 0 var(--sp-2);padding:0;border:none;font-size:1.2rem}
.off-panel .vacio:not([hidden]){display:flex;align-items:center;min-height:48px}
#off-vacia:not([hidden])~*{display:none}
.off-orden{display:flex;align-items:center;gap:var(--sp-2)}
.off-pedido{flex:1 1 auto;min-width:0}
/* the cuenta that was open when the connection dropped: one quiet line over its order */
.off-copia{margin:0 0 2px;font-size:.875rem;font-weight:600;line-height:1.3;color:var(--ink-2)}
#off-vaciar{flex:0 0 auto;min-height:48px;padding:0 .8rem;font-size:.92rem}
.off-forma{display:flex;gap:8px;margin-top:8px}
.off-panel label.opcion{position:relative;z-index:0;flex:1 1 0;display:flex;align-items:center;gap:.6rem;min-width:0;min-height:48px;margin:0;padding:0 var(--sp-3);
  border:1.5px solid var(--line-2);border-radius:var(--r-sm);background:var(--bg);
  font-size:1rem;font-weight:700;letter-spacing:0;text-transform:none;color:var(--ink);cursor:pointer}
.off-panel .opcion input{-webkit-appearance:none;appearance:none;flex:0 0 auto;width:22px;height:22px;min-height:0;margin:0;padding:0;border:2px solid var(--ink-3);border-radius:50%;background:var(--bg)}
.off-panel .opcion input:checked{border-color:var(--grn);background:var(--grn);box-shadow:inset 0 0 0 4px var(--bg)}
.off-panel .opcion input:focus-visible{outline:2px solid var(--grn);outline-offset:2px}
.off-panel .opcion input:checked~.nm::before{content:"";position:absolute;z-index:-1;left:-1.5px;top:-1.5px;right:-1.5px;bottom:-1.5px;border:2px solid var(--grn);border-radius:var(--r-sm);background:var(--grn-soft)}
.off-panel .opcion input:checked~.nm{color:var(--grn-text);font-weight:800}
.off-campo{margin-top:8px}
.off-panel .peso input{min-height:52px;font-size:1.35rem}
.off-panel #off-ref{min-height:52px;font-size:1.05rem}
.off-panel input[aria-invalid="true"]{border-color:var(--warn);box-shadow:inset 0 0 0 1px var(--warn)}
.off-panel .cobro{margin-top:8px}
.off-panel .cobro .total{margin:0}

/* a phone: the cart is the bar in the thumb zone. The order reads as one or two lines
   ("3 Taco al pastor · 1 Agua de horchata"); Recibido sits beside its word. */
@media (max-width:1023px){
  body.venta.off{padding-bottom:calc(300px + env(safe-area-inset-bottom))}
  body.off .off-panel{position:fixed;left:0;right:0;bottom:0;z-index:20;max-height:82vh;overflow-y:auto;
    padding:10px var(--sp-3) calc(10px + env(safe-area-inset-bottom));
    border-top:1px solid var(--line-2);border-radius:var(--r-lg) var(--r-lg) 0 0;
    box-shadow:0 -10px 24px -18px rgba(15,20,23,.35)}
  .off-panel>*{max-width:640px;margin-left:auto;margin-right:auto}
  .off-panel h2{display:none}
  .off-panel .lines{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;font-size:.95rem;line-height:22px}
  .off-panel .lines li{display:inline;min-height:0;padding:0;border:none}
  .off-panel .lines li+li::before{content:"\00B7";margin:0 .45em;color:var(--ink-3);font-weight:700}
  .off-panel .lines .q{margin-right:.3em}
  .off-panel .lines .nm{font-size:inherit}
  .off-panel .lines .amt{display:none}
  .off-campo{display:flex;align-items:center;gap:var(--sp-3)}
  .off-campo label{flex:0 0 6.2rem;margin:0;font-size:.95rem;letter-spacing:0;text-transform:none;color:var(--ink-2)}
  .off-campo .peso,.off-campo #off-ref{flex:1 1 auto;min-width:0}
  .off-panel .cobro{min-height:0;padding:0}
}
/* 1024 px and up: the pane beside the menu, where the cuenta sits online */
@media (min-width:1024px){
  body.off .off-panel{flex:0 0 380px;position:sticky;top:116px;display:flex;flex-direction:column;max-height:calc(100vh - 132px);overflow-y:auto;
    border:1px solid var(--line);border-radius:var(--r-md);padding:var(--sp-4)}
  .off-orden{display:contents}
  #off-vaciar{order:9;width:100%;margin-top:var(--sp-3)}
  .off-panel .cobro{margin-top:var(--sp-3)}
}

/* the local ticket: a screen of its own, the receipt and then Imprimir and Nueva venta
   (sticky at the foot, where Cobrar was) */
.off-ticket{position:fixed;left:0;right:0;top:0;bottom:0;z-index:60;display:flex;flex-direction:column;align-items:center;overflow-y:auto;
  padding:var(--sp-4) var(--sp-3) 0;background:var(--bg)}
.off-ticket .ticket{flex:0 0 auto}
.off-ticket .ticket h1{font-size:1rem;font-weight:800;letter-spacing:0;text-transform:none}
.off-ticket .pendiente{margin:.6rem 0 0;padding:.5rem .6rem;border:1.5px dashed var(--ink);font-size:.85rem;font-weight:700;line-height:1.35;text-align:center}
.off-ticket.con-cambio tr.cambio td{font-size:1.45rem;font-weight:900}
.off-ticket.con-cambio tr.cambio td.amt{color:var(--grn-text)}
.off-ticket .acciones{position:sticky;bottom:0;flex:0 0 auto;margin-top:auto;padding:var(--sp-3) 0 calc(var(--sp-3) + env(safe-area-inset-bottom));background:var(--bg)}
.off-ticket .acciones .btn,.off-ticket .acciones .btn-cobrar{min-height:56px}
@media (min-width:600px){.off-ticket{padding-top:var(--sp-6)}.off-ticket .acciones{margin-top:var(--sp-2)}}

/* the corte while this phone holds unsent sales: the field and the buttons rest */
.corte #unsent-msg{margin:var(--sp-3) 0 var(--sp-4)}
.peso input:disabled{background:var(--panel);border-color:var(--line);color:var(--ink-3)}

@media print{
  body.venta{padding:0;background:#fff}
  body.venta>*:not(.off-ticket){display:none}
  .off-ticket:not([hidden]){position:static;display:block;overflow:visible;padding:0;background:#fff}
  .off-ticket .acciones{display:none}
  .off-ticket .ticket h1{font-size:11pt}
  .off-ticket .pendiente{border:1px dashed #000;color:#000;font-size:8.5pt}
  .off-ticket tr.cambio td,.off-ticket.con-cambio tr.cambio td,.off-ticket.con-cambio tr.cambio td.amt{font-size:11pt;color:#000}
}

/* A cuenta the phone copied into an unsent offline sale (step 4d): the server cuenta stays on screen
   to read, but it cannot be charged, added to or changed until that sale lands. */
.off-bloq{margin:0;font-size:.9rem;font-weight:700;line-height:1.3;color:var(--ink)}
.off-bloq[hidden]{display:none}
body.copiada #cuenta .btn-cobrar,body.copiada #cuenta button.x{display:none}
/* the way on (step 4d design, S4D-M1): Nueva venta where Cobrar was, the note one line above it */
#cuenta .nueva-bloq{display:none}
body.copiada #cuenta .nueva-bloq{display:flex}
body.copiada .cobro .off-bloq{font-weight:600}
@media (max-width:1023px){
  body.copiada .pedido .cobro{flex-wrap:wrap;row-gap:6px;padding-top:8px}
  body.copiada .cobro .off-bloq{order:-1;flex:1 1 100%}
  body.copiada .cobro .total,body.copiada .cobro .nueva-bloq{flex:1 1 0}
  body.copiada .cobro .nueva-bloq{min-height:60px;padding:0 .75rem}
}
@media (min-width:1024px){
  body.copiada .cobro .off-bloq{margin:var(--sp-1) 0 var(--sp-3)}
  body.copiada .cobro .nueva-bloq{width:100%;min-height:60px}
}

/* ========== Step 4d design ==========
   The summary per person at the top of the corte audit (corte.html): its rows turn into
   columns. The first column names the kind, then one column a person; a count reads across
   from its kind. The title is the corner cell. With no person row (only kinds the summary
   does not count, as a posible venta doble), the header row is alone and hides. */
.corte table.por-persona{display:grid;grid-template-rows:repeat(7,auto);grid-auto-flow:column;
  grid-template-columns:minmax(6.5rem,1fr);grid-auto-columns:auto;
  width:100%;margin:var(--sp-5) 0 var(--sp-2);
  /* four people or more on a small phone: the people slide under the kind column, which stays */
  overflow-x:auto;overscroll-behavior-x:contain}
.corte table.por-persona tbody,.corte table.por-persona tr{display:contents}
.corte table.por-persona th,.corte table.por-persona td{display:block;margin:0;padding:.55rem 0 .55rem var(--sp-4);
  border-bottom:1px solid var(--line);font-family:var(--ui);font-size:.92rem;font-weight:700;line-height:1.3;letter-spacing:0;
  text-transform:none;text-align:right;font-variant-numeric:tabular-nums;color:var(--ink);white-space:normal;overflow-wrap:normal}
.corte .por-persona .sm-cab th{min-width:0;position:sticky;left:0;z-index:1;padding-left:0;padding-right:var(--sp-2);background:var(--bg);
  text-align:left;font-weight:600;color:var(--ink-2)}
.corte .por-persona .sm-cab th span{display:block}
.corte .por-persona .sm-cab th:first-child,.corte .por-persona .sm-line td:first-child{align-self:stretch;display:flex;align-items:flex-end;justify-content:flex-end;
  border-bottom:2px solid var(--ink);color:var(--ink);font-weight:800}
.corte .por-persona .sm-cab th:first-child{justify-content:flex-start;font-family:var(--voz);font-size:1.05rem;letter-spacing:-.01em}
.corte .por-persona .sm-cab:only-child{display:none}

@media (max-width:1023px){.cobro .off-bloq{flex:1 1 50%}}

/* ========== 4e: one tap, several lines; the common option chosen already ========== */
/* Repetir and the combos sit over the menu; offline the phone has no tile for them */
.menu .atajos{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 8px}
.menu .atajos form{margin:0}
.menu .atajos .repetir .btn{width:auto;min-height:48px;margin:0;padding:0 1.1rem}
/* the combo buttons flow in the same row as Repetir: one or two rows on a phone, not three */
.menu .combo-form{display:contents}
.combo-tile{min-height:48px;padding:0 1rem;border:1.5px solid var(--grn);border-radius:var(--r-sm);background:var(--grn-soft);color:var(--grn-text);font:inherit;font-weight:700;cursor:pointer}
.combo-tile:active{background:var(--grn);color:#fff}
body.off .atajos{display:none}
/* a tile whose tap adds with the default options: the small "opciones" corner opens the picker */
.menu .tile-form .celda{position:relative;display:grid}
.menu .tile-form .celda .tile{width:100%}
/* the options corner: a 48 px target in the top right; the name keeps clear of it */
.tile-form .opc{position:absolute;top:0;right:0;width:48px;height:48px;border:0;border-radius:var(--r-sm);background:transparent;color:var(--ink-2);font-size:22px;line-height:1;cursor:pointer}
.menu .tile-form .celda .tile .nm{display:block;padding-right:30px}
.tile-form .opc:active{background:var(--grn-soft)}
.predet{display:inline;margin:0 0 0 auto}
.predet-btn.on{border-color:var(--grn);color:var(--grn-text)}

/* ---------- final pass (2026-10-07): combos, estaciones ---------- */
/* Combos: the name over what it holds, Quitar at the right (neutral: it deletes) */
.adm .fila.combo{display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-areas:"nm act" "meta act";column-gap:var(--sp-3);row-gap:.15rem;align-items:center;padding:var(--sp-3) 0}
.adm .fila.combo .nm{grid-area:nm;font-weight:800}
.adm .fila.combo .meta{grid-area:meta;color:var(--ink-2);font-size:.92rem;line-height:1.35}
.adm .fila.combo form{grid-area:act;margin:0}
.adm .fila.combo .btn{width:auto;min-height:48px;margin:0;padding:0 var(--sp-4)}
/* Estaciones: the category name in a column, the station field beside it */
.adm .estaciones .fila{display:grid;grid-template-columns:minmax(6rem,9rem) minmax(0,1fr);gap:var(--sp-3);align-items:center;padding:var(--sp-2) 0}
.adm .estaciones .fila .nm{margin:0;font-size:1rem;font-weight:800;letter-spacing:0;text-transform:none;color:var(--ink)}
.adm .estaciones .fila input{margin:0}

/* ---- mesas (copied from comal-mesas.css so the sale screen loads one stylesheet, not two: a second sheet cost about 400 ms a tap on a slow phone, measured 2026-10-07) ---- */
/* Mesas: the plano, the move page, the mesa bar of the sale screen. Tokens come from comal.css. */
.plano-wrap{max-width:72rem;margin:0 auto;padding:var(--sp-3,1rem)}
.plano-cab{display:flex;align-items:center;justify-content:space-between;gap:1rem;margin-bottom:.75rem}
.plano-cab h1{margin:0}
.plano{display:grid;grid-template-columns:repeat(auto-fill,minmax(8.5rem,1fr));gap:.75rem}
.plano .zona{grid-column:1/-1;margin:.75rem 0 0;font-size:1rem;color:var(--ink-2)}
.mesa{display:flex;flex-direction:column;align-items:flex-start;justify-content:space-between;gap:.25rem;min-height:6.5rem;padding:.75rem;border:1.5px solid var(--line-2);border-radius:14px;background:var(--bg);color:var(--ink);font:inherit;text-align:left;cursor:pointer}
.mesa .mn{font-weight:700;font-size:1.1rem}
.mesa .mt{font-weight:700;font-size:1.25rem;color:var(--grn-text)}
.mesa .ma{font-size:.9rem;color:var(--ink-3)}
.mesa.libre{background:var(--panel)}
.mesa.ocupada{background:var(--grn-soft);border-color:var(--grn)}
.mesa.ocupada .ma{color:var(--ink-2)}
.mesa:focus-visible{outline:3px solid var(--grn);outline-offset:2px}
.mesa-barra{position:relative;z-index:2;display:flex;flex-wrap:wrap;gap:.5rem;padding:.4rem var(--sp-3,1rem)}
.mesa-barra form{margin:0}
.mesa-barra .btn{width:auto;min-height:48px;margin:0;padding:0 .9rem;font-size:.95rem}
/* a 360 px phone: the three mesa buttons share one row */
@media (max-width:419px){.mesa-barra{flex-wrap:nowrap;gap:6px}.mesa-barra>*{flex:1 1 auto}.mesa-barra>form{display:flex}
  .mesa-barra form .btn{flex:1 1 auto;width:auto}.mesa-barra .btn{padding:0 .45rem;font-size:.9rem;white-space:nowrap}}
.mover-lineas{list-style:none;padding:0;margin:0 0 1rem}
.mover-lineas li{display:flex;align-items:center;gap:.75rem;padding:.5rem 0;border-bottom:1px solid var(--line)}
.mover-lineas .nm{flex:1}
/* Administrar mesas: one mesa is one row, name and zone, then Guardar and
   Apagar side by side (a phone: the buttons on a second line, half each). */
.pg-mesas-admin .fila{display:block;padding:var(--sp-3) 0;border-bottom:1px solid var(--line)}
.mesa-edit{display:grid;grid-template-columns:1fr 1fr;gap:.5rem;align-items:center;margin:0}
.mesa-edit input{min-width:0;margin:0}
.mesa-edit .btn{width:100%;min-height:48px;margin:0;padding:0 var(--sp-4)}
.pg-mesas-admin .fila.agotado input{color:var(--ink-2);background:var(--panel)}
@media (min-width:700px){.mesa-edit{grid-template-columns:minmax(0,1.2fr) minmax(0,1fr) auto auto}.mesa-edit .btn{width:auto}}
.pide-motivo{display:flex;flex-wrap:wrap;align-items:center;gap:.25rem .5rem;padding:.5rem 0}
.pide-motivo label{margin:0}
.pide-motivo input{flex:1 1 9rem;min-width:0;min-height:48px;margin:0}
.pide-motivo .motivo-guardado{flex:1 1 100%;margin:0;color:var(--grn-text);font-size:.95rem;font-weight:600;white-space:normal}
.pide-motivo .motivo-guardado b{color:var(--ink);font-weight:700}
.pide-motivo .motivo-guardado[hidden]{display:none}
@media (min-width:600px){main.plano-wrap{margin-top:var(--sp-5);margin-bottom:var(--sp-6)}}
@media (min-width:1024px){.plano{grid-template-columns:repeat(auto-fill,minmax(11rem,1fr))}}


/* ---------- demo pass (2026-10-07, 05:30) ---------- */
/* The jump bar (venta.html): one chip a category, one row, sticky under the header (60 px). A chip
   is 48 px to the finger and 40 px to the eye (a clear border is the gap); the row scrolls sideways
   when the names outgrow the phone. A category title lands under the header and the bar. */
.saltos{position:sticky;top:60px;z-index:15;display:flex;flex-wrap:nowrap;overflow-x:auto;overflow-y:hidden;scrollbar-width:none;
  margin:calc(-1 * var(--sp-3)) calc(-1 * var(--sp-3)) var(--sp-2);padding:0 calc(var(--sp-3) - 3px);
  background:
    linear-gradient(90deg,#EDF0EF 40%,rgba(237,240,239,0)) left/20px 100% no-repeat local,
    linear-gradient(270deg,#EDF0EF 40%,rgba(237,240,239,0)) right/20px 100% no-repeat local,
    linear-gradient(90deg,rgba(15,20,23,.14),rgba(15,20,23,0)) left/12px 100% no-repeat scroll,
    linear-gradient(270deg,rgba(15,20,23,.14),rgba(15,20,23,0)) right/12px 100% no-repeat scroll;
  background-color:#EDF0EF;box-shadow:0 1px 0 var(--line-2)}
.saltos::-webkit-scrollbar{display:none}
/* a long name shows its first words ("Gringas…"), so Bebidas fits a 360 px row */
.saltos a{flex:0 0 auto;display:block;max-width:5.6rem;margin:0;padding:0 .6rem;line-height:42px;
  border:3px solid transparent;border-radius:10px;background:var(--bg);background-clip:padding-box;box-shadow:inset 0 0 0 1.5px var(--line-2);
  color:var(--ink);font-size:.9rem;font-weight:700;text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.saltos a:active{background-color:var(--grn-soft);box-shadow:inset 0 0 0 1.5px var(--grn)}
.menu h2.cat{scroll-margin-top:calc(60px + 48px + var(--sp-3))}
@media (min-width:1024px){.saltos{margin:calc(-1 * var(--sp-4)) 0 var(--sp-2);padding:0}}
/* the empty cuenta names itself: "Mesa 3 · Cuenta vacía" */
.vacio b .sep{color:var(--ink-3);font-weight:700}
/* a refused removal: the words sit under the motivo box, the box is marked */
.pide-motivo .motivo-err{flex:1 1 100%;margin:0;color:var(--warn);font-size:.95rem;font-weight:700;line-height:1.3}
.pide-motivo.falta input{border-color:var(--warn);box-shadow:0 0 0 1px var(--warn)}
/* Caja, the corte and the Turno page: the sale screen's top bar and places over the card */
body.con-tabs header.shell{justify-content:space-between}
body.con-tabs main.card{margin-top:var(--sp-4)}
/* the admin pages: the same top bar, then their places; the brand lives in the bar */
header.shell.adm-cab{justify-content:space-between}
a.btn-cobrar[aria-busy="true"]{opacity:.6}   /* Cobrar waits for the taps in flight (static/comal-taps.js) */

/* ---------- owner-UX draft (2026-10-11): buttons, the 86 switch, the own row ----------
   Buttons. The soft green tint of btn-dim read as a disabled button on a phone, and it almost
   vanishes in sun (Michael, 2026-10-08, the /clave exception). The one save of an admin form
   (a form straight in its section) is now the solid green with the press edge; a small
   affirmative in a row keeps the tint and gains a green edge, so it reads as a button. */
.adm .btn-dim{border:1.5px solid var(--grn)}
.adm .bloque>form:not(.fila)>.btn.btn-dim,.adm .cab .btn-cobrar{
  background:var(--grn);color:#fff;border:none;font-weight:800;box-shadow:inset 0 -3px 0 rgba(0,0,0,.18)}
.adm .bloque>form:not(.fila)>.btn.btn-dim:active,.adm .cab .btn-cobrar:active{box-shadow:inset 0 -1px 0 rgba(0,0,0,.18)}
.adm .cab .btn-cobrar{min-height:48px;padding:0 var(--sp-4);font-size:1rem;gap:.35rem}
.adm .cab .btn-cobrar span{font-size:1.3rem;line-height:1;margin-top:-2px}

/* The 86 switch (DESIGN.md: a two-word switch, the person reads a word): a knob that sits right
   and green when the product is for sale, left and grey when it is sold out, with the word of
   the state beside it. Tap flips it; catalogo.html's script turns it at once and asks the
   server; the word comes back with the server's row. */
.adm .prod .sw{grid-column:3;grid-row:1/3;align-self:center;display:flex;align-items:center;gap:.55rem;min-height:48px;min-width:7.4rem;
  margin:0;padding:0 .2rem 0 .5rem;border:none;background:none;color:var(--grn-text);font:inherit;font-weight:800;font-size:.95rem;cursor:pointer;text-align:left}
.adm .prod .sw .perilla{position:relative;flex:0 0 auto;width:46px;height:28px;border-radius:14px;background:var(--grn);transition:background-color .12s}
.adm .prod .sw .perilla::after{content:"";position:absolute;top:3px;left:21px;width:22px;height:22px;border-radius:50%;background:#fff;box-shadow:0 1px 2px rgba(15,20,23,.3);transition:left .12s}
.adm .prod .sw.off{color:var(--warn)}
.adm .prod .sw.off .perilla{background:var(--edge)}
.adm .prod .sw.off .perilla::after{left:3px}
.adm .prod .sw:disabled .est{visibility:hidden}
.adm .prod .sw:focus-visible{outline:2px solid var(--grn);outline-offset:2px;border-radius:7px}
@media (prefers-reduced-motion:reduce){.adm .prod .sw .perilla,.adm .prod .sw .perilla::after{transition:none}}
/* the categories fold: its title reads as the other section titles */
.adm details.catgest{margin-top:var(--sp-7);border-top:none}
.adm details.catgest>summary{min-height:52px;padding:0 0 var(--sp-2);border-bottom:1px solid var(--line)}
.adm details.catgest>summary h2{margin:0;padding:0;border:none;font-size:1.2rem}
.adm details.catgest[open]>summary{margin-bottom:var(--sp-3)}
@media (min-width:1024px){.adm .rail details.catgest{padding:var(--sp-4) var(--sp-5);border:1px solid var(--line);border-radius:var(--r-lg);background:var(--panel)}
  .adm .rail details.catgest>summary{border-bottom:none;padding:0}}

/* Equipo: the person signed in. Usted beside the name; only Cambiar mi contraseña. */
.adm .persona .tu{display:inline-block;margin-left:.4rem;padding:.05rem .5rem;border-radius:var(--r-sm);background:var(--grn-soft);color:var(--grn-text);font-style:normal;font-size:.8rem;font-weight:800;vertical-align:middle}
.adm .persona .mia{grid-area:act}
.adm .persona .mia .btn{min-height:48px;padding:0 var(--sp-3);font-size:.92rem}
@media (max-width:599px){.adm .persona.yo{grid-template-areas:"nm nm" "meta meta" "act act"}
  .adm .persona .mia{margin-top:var(--sp-3)}.adm .persona .mia .btn{width:100%}}
