/* ══════════════════════════════════════════════════════════════════════════
   Lo que faltaba de MARKUP y ESTILO · Design · 14-09-2026
   ══════════════════════════════════════════════════════════════════════════
   Los siete puntos que Dev marcó como «falta el contenedor, no el cableado».
   Todo cuelga de clases e ids NUEVOS y no pisa ninguna regla existente, con
   una sola excepción a propósito: §6, el estado `:active`, que hoy no existe
   en ningún botón del panel (medido: cero reglas `:active` propias).

   Va junto con `js/panel-design-14sep.js`. La hoja sola dibuja los bloques
   estáticos (§2 banner, §4 motivos, §6 :active); el script engancha los que
   viven sobre nodos que se repintan (§1 mapa, §3 tour, §5 alergias, §7 doble
   toque).
   ══════════════════════════════════════════════════════════════════════════ */


/* ── 1 · «Mapa» al lado de la dirección ─────────────────────────────────────
   Las tres direcciones del panel: la card del trabajo en vivo (`#lj-sub`), el
   cajón del trabajo (`#td-sub`) y la ficha del cliente (`#cd-dir-wrap`).
   Los tres los reescribe el renderer, así que el link lo vuelve a poner un
   observer — no un timeout. El chip es chico y en violeta: es una salida del
   panel, no una acción del flujo, y no tiene que competir con los botones de
   estado que están al lado.
   Ojo `text-transform`: `#lj-sub` y `#td-sub` van en mayúsculas y el chip no
   debe seguirlas. */
.ma-mapa{display:inline-flex;align-items:center;gap:4px;margin-left:8px;
  padding:1px 8px 1px 6px;border-radius:999px;
  border:1px solid var(--violet-border);background:var(--violet-soft);
  font-family:var(--sans);font-size:10.5px;font-weight:600;
  letter-spacing:.02em;line-height:1.75;text-transform:none;
  text-decoration:none;color:var(--violet-text);
  vertical-align:middle;white-space:nowrap;
  transition:background 140ms,border-color 140ms,color 140ms}
.ma-mapa:hover{background:var(--violet-soft-2,rgba(108,99,255,.14));
  border-color:var(--violet-600);color:var(--cloud-100)}
.ma-mapa:focus-visible{outline:2px solid var(--violet-600);outline-offset:2px}
.ma-mapa svg{width:11px;height:11px;flex:none}
/* En la ficha del cliente la dirección es un `.val` de bloque: el chip se
   separa un poco más para que no quede pegado al renglón de abajo. */
#cd-dir-wrap .ma-mapa{margin-left:9px}


/* ── 2 · Banner «Activar mi bot» ────────────────────────────────────────────
   Hermano de `#banner-telegram` y con su misma anatomía (frase + botón, sin
   ícono ni título), pero en CORAL y no en el gris del otro: los dos avisan de
   algo que falta, y sólo uno de los dos significa que hay clientes escribiendo
   y nadie contestando. El tono es la diferencia entre «te falta esto» y «esto
   te está costando plata ahora».
   Nace `hidden`. Lo enciende el dato, no el diseño: `MA.bot({activo:false})`. */
#banner-activar-bot{display:flex;align-items:center;gap:14px;flex-wrap:wrap;
  margin:0 0 14px;padding:11px 14px;border-radius:12px;
  border:1px solid var(--coral-border,rgba(232,106,95,.32));
  background:var(--coral-soft,rgba(232,106,95,.12));
  font-family:var(--sans);font-size:12.5px;line-height:1.55;
  letter-spacing:normal;color:var(--cloud-300);text-wrap:pretty}
#banner-activar-bot > .ic{flex:none;width:22px;height:22px;border-radius:50%;
  display:grid;place-items:center;color:var(--coral);
  border:1px solid var(--coral-border,rgba(232,106,95,.32));
  background:rgba(232,106,95,.10);font-size:12px;font-weight:700;line-height:1}
#banner-activar-bot > span.tx{flex:1 1 0;min-width:0;
  font-size:12.5px;line-height:1.55;color:var(--cloud-300)}
#banner-activar-bot > span.tx b{color:var(--cloud-100);font-weight:700}
#banner-activar-bot > button{flex:none;font-size:12.5px;font-weight:600}
/* El botón en coral, no en violeta: el violeta es «seguí navegando» y esto
   es reparar algo. */
#banner-activar-bot .btn-primary{background:var(--coral);border-color:var(--coral)}
#banner-activar-bot .btn-primary:hover{filter:brightness(1.07)}
/* Mientras el back trabaja. Dev pone la clase; el diseño ya está. */
#banner-activar-bot.is-activando{border-color:var(--violet-border);
  background:var(--violet-soft);color:var(--cloud-300)}
#banner-activar-bot.is-activando > .ic{color:var(--violet-text);
  border-color:var(--violet-border);background:rgba(108,99,255,.10)}
#banner-activar-bot.is-activando .btn-primary{background:var(--violet-600);
  border-color:var(--violet-600);pointer-events:none;opacity:.75}
#banner-activar-bot.is-activando > .ic::after{content:'';width:8px;height:8px;
  border-radius:50%;background:currentColor;animation:ma-late 1.3s ease-in-out infinite}
@keyframes ma-late{0%,100%{opacity:.35;transform:scale(.8)}50%{opacity:1;transform:scale(1)}}


/* ── 3 · Tour guiado de Configuración ───────────────────────────────────────
   Configuración es la pantalla con más cards del panel y ninguna explica para
   qué sirve hasta que la abrís. El tour las recorre en el orden en que hay que
   llenarlas —rubro primero, porque manda sobre el vocabulario de todo lo
   demás— y dice qué hace cada una con el cliente, no qué campo tiene.

   El foco es un recorte: el recuadro no pinta nada, el `box-shadow` de 9999px
   oscurece TODO lo demás. Así el agujero sigue al elemento real sin tener que
   clonarlo ni moverlo de lugar. */
/* 14-09 · el estado final NO puede depender de que una transición termine.
   En un documento que no está visible —pestaña de fondo, iframe de preview—
   las transiciones no avanzan y el tour quedaba abierto en `opacity:0`: en
   pantalla, nada. Es el mismo golpe que la Pieza 5 el 07/09. Se abre y se
   cierra con `display`, sin fundido. */
#ma-tour{position:fixed;inset:0;z-index:130;display:none}
#ma-tour.on{display:block}
#ma-tour .foco{position:absolute;border-radius:14px;pointer-events:none;
  box-shadow:0 0 0 9999px rgba(12,10,8,.68),0 0 0 2px var(--violet-600)}
#ma-tour .globo{position:absolute;box-sizing:border-box;
  width:min(330px,calc(100vw - 28px));padding:15px 16px 13px;
  border-radius:14px;border:1px solid var(--graphite-700);
  background:var(--graphite-900);
  box-shadow:0 18px 44px rgba(0,0,0,.45)}
/* Sin `transition` en el foco ni en el globo, a propósito. Lo mismo que arriba:
   donde el documento no está visible las transiciones no avanzan y el recorte
   se queda clavado en la card anterior mientras el texto ya cambió — medido el
   14-09: seis pasos con el mismo recuadro. Salta, y se entiende. */
#ma-tour .globo .k{display:block;margin:0 0 7px;
  font-family:var(--mono);font-size:9px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--violet-text)}
#ma-tour .globo h4{margin:0 0 6px;font-family:var(--sans);font-size:15px;
  font-weight:600;line-height:1.3;color:var(--cloud-100)}
#ma-tour .globo p{margin:0;font-size:12.5px;line-height:1.6;
  color:var(--cloud-300);text-wrap:pretty}
#ma-tour .pie{display:flex;align-items:center;gap:10px;
  margin-top:14px;padding-top:12px;border-top:1px solid var(--graphite-700)}
#ma-tour .pasos{flex:1 1 auto;display:flex;gap:5px;align-items:center}
#ma-tour .pasos i{width:5px;height:5px;border-radius:50%;
  background:var(--graphite-700);transition:background 160ms,width 160ms}
#ma-tour .pasos i.is{width:15px;border-radius:99px;background:var(--violet-600)}
#ma-tour .pie button{flex:none;font-family:var(--sans);cursor:pointer;
  border-radius:9px;min-height:32px;padding:0 13px;font-size:12.5px}
#ma-tour .salir{border:1px solid transparent;background:transparent;
  color:var(--cloud-500);font-weight:500;padding:0 6px}
#ma-tour .salir:hover{color:var(--cloud-100)}
#ma-tour .sig{border:1px solid var(--violet-600);background:var(--violet-600);
  color:#fff;font-weight:600}
#ma-tour .sig:hover{background:#7d74ff;border-color:#7d74ff}

/* El disparador, arriba de Configuración y al ras derecho: es ayuda, no un
   campo más, así que no entra en la grilla de cards. */
.cfg-tour-lanza{display:flex;justify-content:flex-end;margin:0 0 12px}
.ma-ghost{display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  min-height:32px;padding:0 12px;border-radius:9px;
  border:1px solid var(--graphite-700);background:transparent;
  font-family:var(--sans);font-size:12.5px;font-weight:500;color:var(--cloud-300);
  transition:border-color 140ms,color 140ms,background 140ms}
.ma-ghost:hover{border-color:var(--violet-border);background:var(--violet-soft);
  color:var(--cloud-100)}
.ma-ghost > span{color:var(--violet-text);font-weight:600}


/* ── 4 · Reagendar con motivo ───────────────────────────────────────────────
   Cuatro tarjetas, no un `<select>`: son cuatro y se leen de un vistazo, y
   cada una cambia LO QUE MIA LE DICE AL CLIENTE. Mover una fecha porque se te
   superpuso otro trabajo y moverla porque falta un repuesto no son el mismo
   mensaje, y hoy salían los dos iguales.
   Van como `role="radio"` y NO como `<label>`: en la Pieza 5 el `<label>`
   convertía en disparador a cualquier control que cayera adentro.
   El motivo elegido se copia al `input.ag-reag-motivo` del formulario, al lado
   de la fecha y la hora ocultas — así el envío lo lee igual que a los otros
   dos campos y no hay que ir a buscarlo al DOM. */
.ma-motivos{margin:0 0 12px}
.ma-motivos-lbl{display:block;margin:0 0 8px;
  font-family:var(--mono);font-size:9px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--cloud-500)}
.ma-motivos-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(158px,1fr));gap:8px}
.ma-mot{display:flex;flex-direction:column;align-items:flex-start;gap:3px;
  box-sizing:border-box;width:100%;min-height:56px;padding:9px 11px;
  cursor:pointer;text-align:left;border-radius:11px;
  border:1px solid var(--graphite-700);background:transparent;
  font-family:var(--sans);
  transition:border-color 140ms,background 140ms,transform 120ms}
.ma-mot .t{font-size:13px;font-weight:600;line-height:1.3;color:var(--cloud-100)}
.ma-mot .s{font-size:11.5px;line-height:1.4;color:var(--cloud-500);text-wrap:pretty}
.ma-mot:hover{border-color:var(--violet-border);background:var(--violet-soft)}
.ma-mot[aria-checked="true"]{border-color:var(--violet-600);
  background:var(--violet-soft);box-shadow:0 0 0 1px var(--violet-600)}
.ma-mot[aria-checked="true"] .s{color:var(--cloud-300)}
.ma-mot:focus-visible{outline:2px solid var(--violet-600);outline-offset:2px}
/* Sin motivo no se propone: el pedido se marca en coral una vez, no se
   bloquea el botón —un botón muerto no explica nada—. */
.ma-motivos.falta .ma-motivos-lbl{color:var(--coral)}
.ma-motivos.falta .ma-mot{border-color:var(--coral-border,rgba(232,106,95,.32))}
.ma-motivos-aviso{display:none;margin:8px 0 0;font-size:11.5px;line-height:1.5;
  color:var(--coral)}
.ma-motivos.falta .ma-motivos-aviso{display:block}


/* ── 5 · Alergias en coral (patrón D) ───────────────────────────────────────
   El campo de notas de la ficha es el mismo en los siete flujos y no dice lo
   mismo en ninguno: en A y C es cómo llegar, en G son los datos del equipo, y
   en D —pedidos de comida— es lo único de la ficha que, si se pasa por alto,
   termina en una urgencia médica. El rótulo y el ejemplo los cambia el script
   según el patrón; el coral aparece sólo en D y sólo cuando el texto habla de
   una alergia. No es decoración: es la única línea de la ficha que hay que
   leer antes de salir. */
.ma-alergia{display:flex;align-items:flex-start;gap:8px;
  padding:9px 11px;border-radius:10px;
  border:1px solid var(--coral-border,rgba(232,106,95,.32));
  background:var(--coral-soft,rgba(232,106,95,.12));
  color:var(--cloud-100);font-weight:500;line-height:1.5;text-wrap:pretty}
.ma-alergia::before{content:'!';flex:none;width:17px;height:17px;margin-top:1px;
  border-radius:50%;display:grid;place-items:center;
  background:var(--coral);color:#fff;font-family:var(--sans);
  font-size:11px;font-weight:800;line-height:1}
.ma-alergia-in{border-color:var(--coral-border,rgba(232,106,95,.32))!important;
  background:var(--coral-soft,rgba(232,106,95,.12))!important}
.ma-alergia-in:focus{border-color:var(--coral)!important}


/* ── 6 · Feedback táctil ────────────────────────────────────────────────────
   Medido el 14-09: el panel no tiene UNA sola regla `:active` propia. En
   escritorio se nota poco; en la mini-app, que es donde se usa con el dedo y
   sin hover, no hay ninguna señal de que el toque entró — y eso es lo que hace
   que el emprendedor toque dos veces y mande dos cosas.
   Hundido de 1 px + un punto más oscuro, 60 ms. Nada más: el gesto tiene que
   terminar antes de que el dedo se levante. */
.btn-primary,.btn-outline,.pill,.ag-accion,.ma-mot,.ma-ghost,
.cfg-editar,.cfg-guardar,.cfg-cancelar,.cfg-alta-linea,.cfg-list-row,
.anot-add,.ag-reag-send,.attn-act,.ag-reag-btn,.tab,.nav-item{
  -webkit-tap-highlight-color:transparent;
  transition:transform 60ms ease-out,filter 60ms ease-out,
             background 140ms,border-color 140ms,color 140ms}
.btn-primary:active,.btn-outline:active,.pill:active,.ag-accion:active,
.ma-mot:active,.ma-ghost:active,.cfg-editar:active,.cfg-guardar:active,
.cfg-cancelar:active,.cfg-alta-linea:active,.cfg-list-row:active,
.anot-add:active,.ag-reag-send:active,.attn-act:active,.ag-reag-btn:active,
.tab:active,.nav-item:active{transform:translateY(1px) scale(.988);filter:brightness(.92)}
.btn-primary:disabled:active,.btn-outline:disabled:active,
button[disabled]:active{transform:none;filter:none}
/* Donde no hay puntero el hover nunca se apaga y queda «pegado» después de
   tocar. En táctil manda el `:active` y el hover no pinta. */
@media (hover:none){
  .btn-outline:hover,.pill:hover,.ag-accion:hover,.ma-mot:hover,
  .ma-ghost:hover,.cfg-list-row:hover{background:transparent}
  .btn-primary:active,.btn-outline:active,.pill:active,.ag-accion:active,
  .ma-mot:active,.ma-ghost:active,.cfg-list-row:active{filter:brightness(.86)}
}


/* ── 8 · Los interruptores en la mini-app · 14-09-2026 ──────────────────────
   Matías: «los toggles están mal visualmente».
   Medido en la mini-app a 390: el interruptor sale de **28 × 48**. En
   escritorio es una pastilla de 38 × 22 con el botón adentro; en `tg-mode` lo
   pisan dos reglas de `panel-tg-12sep.css` que no sabían que ese checkbox no
   es un checkbox:

     html.tg-mode input,select,textarea { min-height:48px }   ← lo estira
     html.tg-mode input[type=checkbox]  { width:28px;height:28px }

   El 48 es la regla de área táctil y está bien pensada, pero aplicada al
   gráfico equivocado: el blanco del dedo es **toda la fila** `.cfg-sw`, que
   mide 348 × 73 y ya es enorme. Al interruptor lo dejó más alto que ancho —
   una pastilla parada, que no se lee como un interruptor.

   Acá vuelve a ser un interruptor, y un poco más grande que en escritorio
   porque se toca con el dedo: 48 × 28 con el botón de 22. El `min-height:0`
   es lo que hay que sacarle; el resto es proporción. */
html.tg-mode .cfg-sw input[type="checkbox"]{
  width:48px;height:28px;min-height:0;border-radius:999px;margin:1px 0 0}
html.tg-mode .cfg-sw input[type="checkbox"]::after{
  top:2px;left:2px;width:22px;height:22px}
html.tg-mode .cfg-sw input[type="checkbox"]:checked::after{transform:translateX(20px)}
/* Y los checkboxes de verdad vuelven a ser cuadrados: el mismo `min-height`
   los dejaba en 28 × 48. */
html.tg-mode input[type="checkbox"],
html.tg-mode input[type="radio"]{min-height:0}


/* ── 9 · En la mini-app los cajones son VENTANAS · 14-09-2026 ────────────────
   Matías: «los cajones no aparecen, en realidad acá los cajones son ventanas
   completas, no cajones». Y tiene razón dos veces.

   Medido a 390: `.pw-drawer-ov` quedó en `position:absolute` dentro de un
   contenedor de 3.081 px de alto, y `.pw-drawer` en 390 con `max-width:92%`
   → **359 × 3081**. O sea: un cajón lateral de escritorio, más alto que seis
   pantallas, asomando por el costado. En el teléfono eso no es un cajón: es
   nada.

   La forma correcta es la de la Pieza 3a (`pieza3-miniapp.jsx`): cada detalle
   es una PANTALLA que se empuja desde la derecha, con su barra arriba —flecha
   de volver, título, subtítulo— y el botón principal abajo, pegado al borde.

   El mecanismo de apertura no se toca: el cajón ya entra con
   `translateX(100%)`, y con ancho completo ese mismo gesto pasa a ser el
   empuje de pantalla de siempre. Lo único que cambia es la geometría. */
html.tg-mode .pw-drawer-ov{position:fixed!important;inset:0!important;
  height:100dvh;padding:0!important;margin:0;z-index:140;
  display:flex!important;justify-content:stretch!important;align-items:stretch}
html.tg-mode .pw-drawer-ov > .pw-drawer{place-self:stretch!important;
  width:100%!important;max-width:100%!important;
  height:100dvh!important;max-height:100dvh!important;
  margin:0!important;border:0!important;border-radius:0!important;
  display:flex;flex-direction:column;overflow:hidden}
/* El empuje, declarado acá y con `!important`. La regla de base
   (`.pw-drawer-ov.open .pw-drawer{transform:none}`) es más específica que la
   cerrada y aun así perdía: medido el 14-09, con la ventana ABIERTA el
   `transform` computado seguía siendo `translateX(390px)` — la ventana entera
   quedaba justo afuera del borde derecho. De ahí «los cajones no aparecen»:
   abrían, pero fuera de pantalla.

   Y OJO con cómo entra: **no entra, aparece.** Lo intenté dos veces y las dos
   estrandaron la ventana afuera de la pantalla.

     1 · con `transition` sobre el `transform`: el overlay pasa de
         `visibility:hidden` a visible y cambia de transform en el mismo
         cuadro, así que la transición no arranca y el valor se queda en el
         estado cerrado — una apertura de cada dos, afuera.
     2 · con una `animation` sobre `translate`, creyendo que por ser otra
         propiedad no podía dejarla afuera. Falso: `translate` se COMPONE con
         `transform`, y una animación que no avanza se queda clavada en su
         primer keyframe — `translate:100%` — con la ventana justo afuera del
         borde derecho. Mismo síntoma, menos seguido.

   La conclusión es la del tour, y es general: **si el gesto empieza en un
   lugar donde la pantalla está mal, un reloj que no corre la deja mal para
   siempre.** No importa qué propiedad sea, ni si es `transition` o
   `animation`. En un webview de Telegram que se va a segundo plano eso pasa
   de verdad.

   Así que la ventana no tiene entrada. Aparece en su lugar y se ve.

   ÚLTIMO: estas dos reglas van SIN `html.tg-mode`. El defecto de cascada no
   era de la mini-app — en escritorio el cajón también abría afuera (medido a
   924 de ancho: `left 909` de 924, 15 px visibles de 390). Estaba roto desde
   antes y el arreglo scopeado lo tapaba sólo en el teléfono, que es la peor
   forma de arreglar algo: el bug queda vivo donde nadie lo vuelve a mirar.
   14-09, TARDE · CORREGIDO. Estas dos líneas estaban SIN `html.tg-mode` y el
   comentario que tenían encima decía que así «el escritorio queda como
   siempre». Era falso: apagar la transición sin scope la apaga **también en
   escritorio**, y ahí revierte el ajuste de velocidad y curva del cajón que
   Mati confirmó en vivo. Lo cazó Dev leyendo la hoja, y por eso dejó §8-§11
   afuera de producción — hizo bien.
   El error de fondo no fue el scope: fue escribir un comentario que afirmaba
   lo que yo quería que pasara en vez de lo que la regla hace. Un comentario
   que miente es peor que no tenerlo; el de al lado lo leí yo mismo tres veces
   sin ver el problema, porque decía lo que yo esperaba leer. */
html.tg-mode .pw-drawer-ov > .pw-drawer{transition:none!important;animation:none!important}
html.tg-mode .pw-drawer-ov.open > .pw-drawer{transform:none!important;translate:none!important}
/* El cuerpo es lo único que scrollea: la barra y el botón quedan quietos. */
html.tg-mode .pw-drawer > .pw-drawer-body,
html.tg-mode .pw-drawer > .pw-drawer-cuerpo{flex:1 1 auto;min-height:0;overflow:auto;
  -webkit-overflow-scrolling:touch;overscroll-behavior:contain}

/* La barra de arriba, como la de Telegram: volver a la izquierda, título al
   lado, 52 px. La ✕ pasa a ser ‹ y se muda al principio — es la misma acción
   con el gesto que el teléfono espera. */
html.tg-mode .pw-drawer > .pw-drawer-head{flex:none;position:sticky;top:0;z-index:6;
  display:flex;align-items:center;gap:10px;min-height:52px;padding:0 12px;
  background:var(--graphite-950);border-bottom:1px solid var(--graphite-800,#232020)}
html.tg-mode .pw-drawer > .pw-drawer-head > .pw-drawer-x{order:-1;flex:none;
  width:36px;height:36px;min-height:36px;padding:0;border:0;border-radius:10px;
  background:transparent;color:var(--cloud-100);font-size:0;
  display:grid;place-items:center}
html.tg-mode .pw-drawer > .pw-drawer-head > .pw-drawer-x::before{
  content:'\2039';font-size:30px;line-height:1;font-weight:400;
  color:var(--cloud-100);margin-top:-3px}
html.tg-mode .pw-drawer > .pw-drawer-head > div{flex:1;min-width:0}
html.tg-mode .pw-drawer .pw-drawer-title{font-size:15.5px;line-height:1.25;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
html.tg-mode .pw-drawer .pw-drawer-sub{font-size:11.5px;line-height:1.35;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}

/* El pie es el botón principal. Apilado y a todo el ancho, con el cierre
   ARRIBA de la acción — el orden del marcado ya es «Cancelar, Guardar», así
   que en columna cae solo donde va. De la Pieza 3a: «salir de una pantalla no
   puede depender de una flecha de 20 px arriba a la izquierda: con el teléfono
   en una mano no se llega». La flecha queda, pero no es el único camino. */
html.tg-mode .pw-drawer > .pw-drawer-foot{flex:none;position:sticky;bottom:0;z-index:6;
  display:flex;flex-direction:column;gap:8px;
  padding:10px 12px calc(12px + env(safe-area-inset-bottom,0px));
  background:var(--graphite-950);border-top:1px solid var(--graphite-800,#232020)}
html.tg-mode .pw-drawer > .pw-drawer-foot > button{width:100%;flex:none}
html.tg-mode .pw-drawer > .pw-drawer-foot > .btn-primary{min-height:50px;font-size:15px;
  border-radius:11px;order:2}
html.tg-mode .pw-drawer > .pw-drawer-foot > .btn-outline{min-height:44px;font-size:14px;
  border-radius:11px;order:1}


/* ── 10 · El botón principal de cada pantalla · 14-09-2026 ─────────────────
   Matías: «faltan los botones de agregar trabajo, presupuesto».
   Medido: `#hdr-btn-trabajo` y `#hdr-btn-presupuesto` existen pero están en
   `display:none` en `tg-mode` — o sea que la mini-app **no tenía forma de
   crear nada**.

   No van de vuelta al header: en un teléfono, arriba a la derecha es donde no
   llega el pulgar. La Pieza 3a lo resuelve con **un botón principal por
   pantalla**, abajo, de 50 px, y con la etiqueta que corresponde a dónde
   estás: en Inicio y Agenda agenda, en Documentos arma el comprobante. Ese es
   el patrón, y encima habla el idioma del oficio.

   El botón no inventa ningún flujo: le toca el click al botón real del header,
   que sigue existiendo oculto. Una acción, un dueño. */
.ma-main{display:none}
html.tg-mode .ma-main{position:fixed;left:0;right:0;z-index:90;
  bottom:var(--ma-main-b,56px);
  display:flex;padding:8px 8px 10px;
  background:var(--graphite-950);border-top:1px solid var(--graphite-800,#232020)}
html.tg-mode .ma-main button{width:100%;min-height:50px;border:0;border-radius:11px;
  background:var(--violet-600);color:#fff;
  font-family:var(--sans);font-size:16px;font-weight:600;cursor:pointer;
  display:flex;align-items:center;justify-content:center;gap:8px;
  transition:filter 60ms ease-out,transform 60ms ease-out}
html.tg-mode .ma-main button:active{transform:translateY(1px);filter:brightness(.9)}
/* Con una ventana abierta no hay botón de pantalla: la ventana trae el suyo. */
html.tg-mode .ma-main[hidden]{display:none}


/* ── 11 · Las piezas de la mini-app estaban DOS veces · 14-09-2026 ──────────
   Matías: «arranco jornada y como que se carga la bitácora dos veces».
   Medido después de tocar «Arrancar»: `#view-inicio` tenía `.rec-dia` **y**
   `.ma-rec` — el recorrido del día dibujado dos veces, uno abajo del otro. Lo
   mismo la tarjeta de jornada (`.tg-jornada` + `.ma-jornada`) y la pantalla de
   espera.

   No es un bug de pintado: son **dos implementaciones de la misma pieza**
   corriendo juntas — el bloque inline de `panel.html` (clases `tg-*`, `rec-*`)
   y `js/panel-miniapp.js` (clases `ma-*`). Cada una con su propia variable
   `arrancada`, así que apagar una no apagaba la otra: por eso «arranco y sigue
   ahí».

   Gana `panel-miniapp.js`, que es el archivo suelto que Dev ya tiene y el que
   el LEEME documenta como «las seis piezas de la mini-app». El bloque inline
   se apaga acá, en una línea, sin tocar 9.400 líneas ni pelearse con el
   pintador — que seguiría reinsertando el nodo en cada repintado. */
html.tg-mode #view-inicio .rec-dia,
html.tg-mode #view-inicio .tg-jornada,
html.tg-mode #view-inicio .tg-espera{display:none!important}


/* ── 12 · «¿Qué servicio?» en Cargar un trabajo · 14-09-2026 ───────────────
   Pedido de Dev: el cajón tenía Para quién / Cuándo / Dónde y ningún lugar para
   decir QUÉ. Va como paso propio y ANTES de «Cuándo»: el servicio decide
   cuánto dura, y la duración decide qué horarios quedan libres. Primero qué,
   después cuándo.

   Y no es el mismo campo en los siete flujos — la distinción ya existía en
   `CATALOGO`, no hay que inventar ninguna:
     cerrado  B · D · F   catálogo fijo → selector real
     base     E           se cotiza por teléfono → selector real
     ninguno  C           se sabe por modelo o medidas → selector real
     entrada  A · G       NO se sabe hasta ir → texto libre y OPCIONAL

   En A y G un selector sería mentir: cotizar sin diagnosticar es inventar un
   precio. Ahí el campo pregunta qué te contaron por teléfono y se puede dejar
   vacío; el rótulo genérico que ya usa el panel («Visita agendada») sigue
   siendo el correcto. */
#ctm-bloque-servicio .ctm-serv-wrap{display:flex;flex-direction:column;gap:7px}
#ctm-servicio{width:100%;box-sizing:border-box;min-height:44px;padding:0 11px;
  border-radius:10px;border:1px solid var(--graphite-700,#3E3A37);
  background:var(--graphite-900,#1C1917);color:var(--cloud-100,#F5F4F2);
  font-family:var(--sans);font-size:13.5px;appearance:auto;cursor:pointer}
#ctm-servicio:focus{outline:none;border-color:var(--violet-600,#6C63FF)}
#ctm-servicio option{background:var(--graphite-900,#1C1917);color:var(--cloud-100,#F5F4F2)}
#ctm-bloque-servicio .ctm-serv-precio{font-family:var(--mono);font-size:11.5px;
  letter-spacing:.02em;color:var(--violet-text);min-height:16px}
#ctm-bloque-servicio .ctm-serv-precio em{font-style:normal;color:var(--cloud-500,#8C8C8C)}
#ctm-bloque-servicio .ctm-serv-ayuda{margin:0;font-size:11.5px;line-height:1.55;
  color:var(--cloud-500,#8C8C8C);text-wrap:pretty}
#ctm-bloque-servicio .ctm-serv-ayuda b{color:var(--cloud-300,#C9C9C9);font-weight:600}


/* ── 13 · Tres de la auditoría por flujos · 14-09-2026 ───────────────────

   13a · El interruptor de «Visitas a domicilio» se podía tocar SIN Editar.
   Configuración tiene una regla clara —en lectura los datos no se tocan— y
   una excepción que se la comía entera: una regla del `panel.html` que le
   devolvía `pointer-events: auto` al input de los `.cfg-sw` aunque la card no
   estuviera en edición.
   Medido en todos los flujos: con la card en lectura, un click apagaba el
   domicilio y quedaba así. Es la clase «guarda sin guardar» del 12/09 dada
   vuelta: se guarda algo que nunca se pidió guardar. Un interruptor no es más
   inocente que un campo de texto — es el que decide si Mia ofrece ir a
   domicilio.

   Y no alcanza con el `input`: el control vive adentro de un `<label>` que
   ocupa la fila entera, que es donde de verdad toca el dedo. Bloqueado sólo el
   gráfico de 38×22, el toque caía en el label, el label reenviaba la
   activación y el handler de `panel.html` la tomaba igual. Es la misma trampa
   del registro de la Pieza 5: como label, el control es su descendiente y se
   activa con cualquier click en la fila.
   Se cierra el LABEL, en las siete cards que tienen interruptor. La otra mitad
   va en el JS de `panel.html`: `pointer-events` no cubre el teclado —el input
   sigue siendo enfocable y la barra espaciadora dispara un click—, así que el
   handler también pregunta si la card está en edición. Hacen falta las dos
   mitades; con una sola el dato se sigue cambiando.

   LO QUE ME COSTÓ TRES INTENTOS, y no era CSS raro: había un CIERRE DE
   COMENTARIO de más acá arriba, después de «domicilio». Cerraba antes de tiempo y
   el navegador leía toda esta prosa como si fueran selectores: se perdía,
   descartaba tokens hasta resincronizar, y en el camino **se comía la primera
   regla de abajo**. Por eso la del `<label>` «nunca llegaba al CSSOM» y la de
   su `input` sí: no era la regla, era su posición. Y por eso, cuando dejé una
   sola, desapareció esa también.
   No hubo un solo error en consola. Un comentario mal cerrado en una hoja es
   una mina: se lleva puesta cualquier regla que venga después, en silencio.
   Si algo de este archivo «no aplica» sin explicación, contar las aperturas
   contra los cierres de comentario antes que nada. Y no escribir esos dos
   tokens dentro de un comentario ni entre comillas: al escribir esta misma
   nota volví a partir el bloque en dos.

   Comportamiento verificado: en lectura no cambia ni tocando el label ni el
   input; con Editar apretado, cambia. */
#cfg-grid-real .cfg-card:not(.is-editando) .cfg-sw{pointer-events:none!important;cursor:default}
#cfg-grid-real .cfg-card:not(.is-editando) .cfg-sw input{pointer-events:none!important}

/* 13b · La columna de la hora, en los flujos que no tienen hora.
   En G un equipo entra al taller y no hay hora: la columna de 96 px mostraba
   un «—» arriba y la palabra del evento abajo, tres veces seguidas. El guion
   no informa nada — la pregunta no aplica. Se apaga el guion y la palabra pasa
   a ser el contenido de la columna, que es lo único que ahí significa algo.
   La clase la pone el JS mirando el TEXTO, no el flujo: un trabajo sin hora en
   cualquier flujo tiene el mismo problema. */
.agenda-time.sin-hora{font-size:0;line-height:0}
.agenda-time.sin-hora small{display:block;font-family:var(--mono);font-size:10px;
  line-height:1.5;letter-spacing:.1em;text-transform:uppercase;
  color:var(--cloud-300,#C9C9C9)}

/* 13d · Las cajas redondeadas que se tocan. NO era sólo la agenda.
   La regla es una y vale para todo el panel: **el piso de aire entre dos
   cajas redondeadas es su radio.** Por debajo de eso, las esquinas de dos
   vecinas quedan más cerca entre sí que el propio redondeo, y el redondeo
   deja de separarlas para empezar a juntarlas.

   Medido el 14-09, con todas las cards en radio 16:
     .ag-list       (agenda, hoy)            gap 10  ← se tocaban
     #agenda-kpis   (los 4 KPI de Agenda)    gap 12  ← se tocaban
     #inicio-kpis · .rep-kpis                idem
   La primera vez arreglé sólo la lista y quedó la mitad del problema a la
   vista, que es el mismo error de arreglar donde se miró en vez de donde
   pasa. Van todas juntas y por la regla, no por el síntoma.

   `.rep-kpis` lleva `!important` a propósito: el renderer le escribe estilos
   `.rep-kpis` y `.ag-cola` llevan `!important` a propósito: el renderer les
   escribe estilos inline / sus reglas viven en el `<style>` de `panel.html`,
   que va DESPUÉS de este `<link>` — con la misma especificidad gana el que
   está más abajo, no el más específico.
   Ojo con el nombre: la columna del tablero es `.ag-cola-col`, no `.cola-col`
   — la escribí mal la primera vez y esa mitad del selector no apuntaba a
   nada. */
#agenda-body,#hoy-agenda,#view-inicio .ag-list,
#agenda-kpis,#inicio-kpis{gap:16px}
.rep-kpis{gap:16px!important}
.ag-cola{gap:12px!important}   /* el radio de sus columnas es 12 */
.ag-cola-col{gap:12px!important}   /* sus tarjetas tienen radio 12 */

/* 13c · El resumen de Servicios y precios.
   «4» sobre «servicios con precio»: el número es el dato y la línea de abajo
   es su rótulo. Al ras izquierdo, un número corto queda flotando sobre un
   rótulo el doble de largo y se leen como dos cosas sueltas. Centrado, se leen
   como una. */
#cfg-card-servicios .cfg-resumen > div{align-items:center;text-align:center}


/* 13e · «Trabajo en curso» pegado al primer slot de la lista.
   Medido en A, C, D, E y G: el borde de abajo de `#live-job` y el borde de
   arriba de `#agenda-body` caen **en el mismo píxel**. No los separa nadie:
   son hermanos dentro de `#view-agenda`, que es `display:block` sin gap, y la
   card no tiene margen inferior. Su radio es 18, así que 18 — misma regla que
   las grillas: el piso de aire entre dos cajas redondeadas es su radio. */
#live-job{margin-bottom:18px}

/* ── 14 · «Agenda de hoy» en Inicio · SÓLO EL FLUJO G · 14-09-2026 ─────────
   Matías: «la agenda de hoy estaba bien antes, había que rediseñar el flujo G
   NOMÁS». Tenía razón: la primera versión de este bloque la aplicó a los
   siete y arregló una pantalla rompiendo seis que estaban bien. Queda como
   recordatorio de que «lo mismo pero en todos lados» casi nunca es lo pedido.

   En G no hay horas: un equipo entra al taller y se queda. La columna de hora
   no dice nada, y la lista cronológica —que es la forma correcta en los otros
   seis— acá es una fila de renglones sin ancla, todos iguales, con la cita de
   WhatsApp y los botones de acción de cada uno. Por eso se ve mal SÓLO acá.

   La escala la marca el estado, no la hora. Cada equipo en un renglón, el
   estado adelante, y actuar se hace en Agenda — que es donde lleva la card.
   El marcado y el renderer no se tocan: misma lista, un solo dueño. */
html[data-ma-patron="G"] #view-inicio .ag-list .ag-item{gap:4px 14px;padding:12px 14px}
html[data-ma-patron="G"] #view-inicio .ag-list .ag-wa,
html[data-ma-patron="G"] #view-inicio .ag-list .ag-acciones{display:none}
html[data-ma-patron="G"] #view-inicio .ag-list .agenda-svc{grid-column:2 / -1;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;
  font-size:12.5px;color:var(--cloud-500,#8C8C8C)}
html[data-ma-patron="G"] #view-inicio .ag-list .agenda-name{font-size:14px}
/* Sin pie de «ver la agenda completa»: para eso está la sección Agenda en el
   menú. La card entera ya navega al tocarla — un rótulo que repite lo que la
   barra lateral ya ofrece es ruido, no ayuda. */


/* ── 14b · El tablero de G no se desliza: se acomoda · 14-09-2026 ──────────
   Matías: «hay que resolver para no tener que usar una barra deslizadora».
   Medido en G, Inicio: `.ag-cola` declara **6 columnas fijas de 150 px** y
   vive en una card de 788 → 980 de contenido, `overflow-x:auto`, barra.

   Una barra horizontal adentro de una card de resumen esconde justo lo que la
   card viene a mostrar: las etapas que NO se ven son las que uno se olvida.
   Y en un taller el tablero es la pantalla principal — la cola de equipos ES
   el negocio.

   Las columnas dejan de ser fijas y pasan a repartirse el ancho, con un piso
   de 118 px: en escritorio entran las seis en una fila, y cuando no entran
   bajan de renglón en vez de esconderse. Nunca hay barra, a ningún ancho.
   El gap es 12 porque el radio de las columnas es 12 — misma regla de §13d. */
.ag-cola{grid-template-columns:repeat(auto-fit,minmax(118px,1fr))!important;
  grid-auto-flow:row!important;overflow:visible!important}
/* El detalle que me hizo perder una vuelta: el tablero fluye **por
   columnas** (`grid-auto-flow:column`). Con eso, redefinir
   `grid-template-columns` no alcanza — la grilla usa mis pistas y después
   **se inventa columnas automáticas** para lo que sobra. Medido a 348 de
   ancho útil: «118px 118px 150px 150px 150px 150px», o sea mis dos pistas y
   cuatro columnas auto de 150. Por eso la barra seguía ahí aunque la regla
   ganara la cascada.
   Con `grid-auto-flow:row` los ítems que no entran bajan de renglón, que es
   lo que uno espera de una grilla. Y `min-width:0` en la columna para que la
   pista mande sobre el ancho mínimo de su contenido. */
.ag-cola-col{min-width:0!important}

/* ── 7 · El «¿Seguro?» del doble toque de WhatsApp ──────────────────────────
   Escribirle al cliente es la única acción del panel que sale del panel y no
   se puede deshacer. El primer toque ARMA el botón, el segundo manda.

   El estado armado NO reemplaza el contenido del botón: apaga su color y
   escribe encima con un `::before` absoluto. Si se cambiara el `innerHTML`, el
   nodo sobre el que se hizo click quedaría desconectado y el `closest()` del
   handler real —que corre después— devolvería null: el segundo toque no
   mandaría nada. Es la trampa del 13-09 («el nodo se reemplaza al repintar»),
   acá en versión sincrónica.

   La barra de abajo es el tiempo que queda armado: si no se confirma, vuelve
   solo y no queda nada raro en pantalla. */
.ma-armado{position:relative;overflow:hidden;color:transparent!important;
  background:var(--gold-soft,rgba(232,184,76,.18))!important;
  border-color:var(--gold)!important}
.ma-armado::before{content:attr(data-ma-seguro);position:absolute;inset:0;
  display:grid;place-items:center;
  font-family:var(--sans);font-size:12.5px;font-weight:700;
  letter-spacing:.01em;color:var(--gold)}
.ma-armado::after{content:'';position:absolute;left:0;bottom:0;height:2px;
  width:100%;background:var(--gold);transform-origin:left center;
  animation:ma-cuenta 4.2s linear forwards}
@keyframes ma-cuenta{from{transform:scaleX(1)}to{transform:scaleX(0)}}
.ma-armado:active{transform:none;filter:none}
@media (prefers-reduced-motion:reduce){
  .ma-armado::after{animation:none;width:100%;opacity:.35}
}

/* ── 15 · La tab bar de la mini-app también estaba DOS veces · 18-09-2026 ──
   Mismo bug de fondo que el §11 (arriba): el bloque inline de `panel.html`
   (`.tg-tabbar`, con su propia hoja «Más», `.tg-mas`) y `js/panel-miniapp.js`
   (`.ma-tabbar`/`.ma-mas`) son DOS implementaciones de la misma pieza,
   corriendo juntas -- ninguna sabe de la otra, las dos con
   `position:fixed;bottom:0;z-index:90`. El §11 apagó recorrido/jornada/
   espera pero se olvidó la tab bar (y una insignia chica, ver abajo).

   Gana `panel-miniapp.js`: es la implementación más completa (la misma
   navegación de 4+«Más», pero además resuelve un gap real que la de
   `panel.html` no tiene -- «Cerrar sesión» no era alcanzable desde la
   mini-app antes de que `panel-miniapp.js` le sumara una fila en su hoja
   «Más», ver su propio comentario del 14-sep). El bloque inline se apaga
   acá, mismo patrón que el §11: CSS gateado a `html.tg-mode`, sin tocar el
   JS por si hace falta revertir. */
html.tg-mode .tg-tabbar,
html.tg-mode .tg-mas{display:none!important}

/* Mismo caso, a escala menor: la insignia «lugares libres» de la vista
   Semana. `panel.html` (función `pintar()` de la Agenda) le agrega su
   propio badge `.ag-sem-lug` a cada `.ag-sem-col` en el mismo momento en
   que arma la columna; `panel-miniapp.js` (función `lugar()`) le agrega
   OTRO badge, `.ma-lugar`, al mismo `.ag-sem-col`, con el mismo cálculo
   (tope de 4 por día). Las dos conviven al final de la columna. Gana
   `.ma-lugar` por el mismo criterio de arriba (es la pieza que documenta
   el LEEME de la mini-app); `.ag-sem-lug` se apaga sin tocar el JS que la
   arma. */
html.tg-mode .ag-sem-lug{display:none!important}
