/* ==========================================================================
   panel-vista.css · Mi Asistente · 10/09/2026
   Dirección visual del panel web — las siete vistas.

   QUÉ ES: la capa visual completa del panel. Trae al panel el idioma que
   Matías eligió para la landing — pozos de violeta, trama de puntos, Bebas
   en las cifras, el hover de las cards.

   DÓNDE VA: `public/css/panel-vista.css`, en la rama design/frontend.
   Se linkea ÚLTIMO, después de todas las hojas de panel:

     <link rel="stylesheet" href="/css/panel-vista.css">

   QUÉ REEMPLAZA: las nueve `panel-fixes*.css`. Cuando esto esté aprobado se
   borran las nueve y esta queda sola. Mientras convivan, esta va última y
   gana por cascada — no usa `!important` en ninguna regla.

   LO QUE ABSORBE DE LOS PARCHES (para que no se pierda al borrarlos):
   · fixes    §1 — Bebas fuera del título de vista, ↳ violeta, sin itálicas,
                    un tamaño por rol, tabular-nums en las cifras
   · fixes-2      — accent-color de los checkbox, el ID que partía la tabla,
                    .thead y .trow con la MISMA grilla (van juntas, siempre)
   · fixes-3      — cajones contenidos en el panel, píldoras del pie alineadas
   · fixes-5      — `align-items:start` en las grillas (las cajas estiradas)
   · fixes-6      — el modal centrado, no sólo el cajón lateral
   · fixes-8      — KPI en auto-fit (el C y el E tienen 3, no 4), estrellas a
                    --violet-text, avatar fuera del blanco-sobre-violeta,
                    Documentos con marco de card
   · fixes-9      — `font: inherit` en button/input (caían al Arial 13,33px)

   TODOS los selectores salen de leer la rama: el marcado de
   `public/panel.html` y las clases que emiten sus renderers. Ninguno
   inventado. Los que SÍ son nuevos están marcados «NUEVO» y necesitan que
   Dev toque el JS — están listados aparte en el archivo de ediciones.

   NO toca ningún `<script>`, no saca ni renombra ningún `id`/`data-*`.

   LO QUE TODAVÍA NO LEÍ, y por lo tanto NO está cubierto acá:
   · `renderPorServicio` (panel.html:3426) — no sé qué marcado emite para
     `#rep-por-servicio`. Dejo `.rep-bars-card` y `.rep-mini-bar` estilados
     porque son los componentes reales del panel para eso, pero si el
     renderer emite otra cosa, esa parte de Reportes no toma el diseño.
   · `#agenda-kpis` (5715) — asumo que emite `.kpi`, que sí está confirmado
     en las otras dos grillas. Riesgo bajo, pero es un supuesto.
   · Los cuerpos de `_agCardDia` (5542-5658) y del renderer de clientes
     (5827-5870) los leí sólo por sus nombres de clase, no completos.
   ========================================================================== */


/* ══ 0 · COLORES ═══════════════════════════════════════════════════════════
   No redeclara la paleta: el panel ya la tiene bien (`panel.html:24-92`, con
   los alias a tokens.css y las cuatro tintas de contraste del 10/09). Sólo
   suma lo que la dirección necesita y el panel no define.                   */
:root{
  --panel-pozo-1:rgba(108,99,255,.13);
  --panel-pozo-2:rgba(108,99,255,.09);
  --panel-pozo-3:rgba(108,99,255,.07);
  --panel-pozo-4:rgba(108,99,255,.10);
  --panel-trama:rgba(20,18,16,.05);
  --card-bg:color-mix(in oklab,var(--graphite-900) 78%,transparent);
}
[data-theme="dark"],html.tg-mode{--panel-trama:rgba(245,244,242,.055)}


/* ══ 1 · EL FONDO ══════════════════════════════════════════════════════════
   Lo primero que hace que el panel se sienta del mismo producto que el sitio.
   Cuatro pozos de violeta fijos + trama de puntos de 3px, la receta aprobada
   de la landing. Acá va más apagada: es una herramienta de trabajo, el fondo
   no puede pelearle a los datos. En claro los pozos bajan al 55%.

   Va en ::before/::after de `.panel` con `z-index:-1` + `isolation:isolate`,
   así no se mete adelante de ningún contenido ni pide un nodo nuevo.        */
.panel{position:relative;isolation:isolate}
.panel::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(58% 44% at 18% 8%,var(--panel-pozo-1),transparent 70%),
    radial-gradient(46% 38% at 88% 22%,var(--panel-pozo-2),transparent 72%),
    radial-gradient(52% 40% at 8% 74%,var(--panel-pozo-3),transparent 72%),
    radial-gradient(60% 46% at 82% 94%,var(--panel-pozo-4),transparent 70%);
  opacity:.55}
.panel::after{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:radial-gradient(var(--panel-trama) 1px,transparent 1px);
  background-size:3px 3px}
[data-theme="dark"] .panel::before,html.tg-mode .panel::before{opacity:1}


/* ══ 2 · TÍTULOS ═══════════════════════════════════════════════════════════
   El título de card pasa a Bebas. `.arrow` (el ↳) se queda en el marcado y
   se apaga: no pido cambiar HTML para esto.

   NO lleva rótulo arriba. Se probó con un ojal (guion + rótulo mono violeta,
   como las secciones del sitio) y Matías lo sacó el 10/09: los rótulos se
   leían como comentarios míos y Dev los pegó como si fueran código. Los
   títulos van solos. No reintentar sin que lo pida.                        */
.card-title{margin:0 0 14px;font-family:var(--display);font-size:23px;font-weight:400;
  letter-spacing:.4px;line-height:1.05;color:var(--cloud-100)}
.card-title .arrow{display:none}

/* El título de vista se queda en DM Sans. Bebas es caps-only y «Inicio»
   salía «INICIO» — `panel-fixes.css` §1 se lo sacó a propósito y esta hoja
   reemplaza ese parche, así que tiene que declararlo o lo revierte sola. */
.hdr-view-title{font-family:var(--sans);font-size:20px;font-weight:700;
  letter-spacing:-.3px;line-height:1.1;color:var(--cloud-100);text-transform:none}

/* El rótulo de capa («Todos los rubros», «Lista cronológica») es el ojal
   suelto de las vistas que no tienen card. Mismo tono, mismo tracking. */
.rep-layer-label{font-family:var(--mono);font-size:9.5px;letter-spacing:.15em;
  text-transform:uppercase;color:var(--violet-text);margin:18px 0 10px}


/* ══ 3 · CARDS ═════════════════════════════════════════════════════════════
   Hover de la landing: borde encendido, glow y luz que sigue al puntero.
   `--mx`/`--my` los pone el listener del archivo de ediciones (8 líneas); sin
   él el glow queda centrado y fijo, que también se ve bien.

   El levante de 4px va SÓLO en las clickeables: en una card de datos el
   movimiento al pasar por encima es ruido.                                 */
.card,.rep-card,.table-card,.cfg-card{
  background:var(--card-bg);border:1px solid var(--hairline);border-radius:18px;
  padding:20px;position:relative;overflow:hidden;
  transition:transform 240ms cubic-bezier(.4,0,.2,1),border-color 240ms ease,
             box-shadow 240ms ease}
.card::before,.cfg-card::before{content:'';position:absolute;inset:0;pointer-events:none;
  opacity:0;transition:opacity 260ms ease;
  background:radial-gradient(200px circle at var(--mx,50%) var(--my,50%),
             var(--violet-soft),transparent 65%)}
.card:hover,.rep-card:hover,.table-card:hover,.cfg-card:hover{border-color:var(--violet-border)}
.card:hover::before,.cfg-card:hover::before{opacity:1}
.card[style*="cursor:pointer"]:hover,button.cfg-card:hover,.client-card:hover,.res-card:hover{
  transform:translateY(-4px);box-shadow:0 18px 40px rgba(0,0,0,.28)}

/* `align-items:start` — absorbe panel-fixes-5. Una grilla estira todos sus
   hijos al alto del más alto, y por eso en Configuración el «Guardar» quedaba
   arriba con 200-400px de hueco debajo. */
.main{grid-area:main;padding:22px 28px 30px;min-width:0}
.grid-primary{display:grid;grid-template-columns:320px minmax(0,1fr);gap:14px;
  align-items:start;margin-top:14px}
.grid-secondary{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);
  gap:14px;align-items:start;margin-top:14px}
.cfg-grid,.clientes-grid,.res-grid,.rep-kpis,.agenda-kpis{align-items:start}
@media (max-width:1100px){.grid-primary,.grid-secondary{grid-template-columns:minmax(0,1fr)}}


/* ══ 4 · LAS CIFRAS EN BEBAS ═══════════════════════════════════════════════
   El panel muestra números todo el tiempo y estaban en JetBrains Mono, que es
   la tipografía de los rótulos. Pasan a Bebas y ganan tamaño: la cifra manda
   y el rótulo es el kicker. Es el mismo orden que la landing.

   Clases verbatim de los renderers: la fila de arriba emite `.kpi` con `.v`
   (cifra) y `.l` (rótulo) y modificadores `.violet` `.gold` `.green`; la card
   «Hoy» emite `.metric`, misma forma. `tabular-nums` para que no bailen al
   refrescar. `line-height:1` sin `overflow:hidden`: a .92 recortaba por
   construcción y cualquier glifo con cola perdía la punta.

   `auto-fit` y no `repeat(4,1fr)` — absorbe panel-fixes-8 §1. No es layout,
   es contenido: los KPI salen del campo `kpis` del glosario y no son cuatro
   en todos los flujos. El C y el E tienen TRES, y con 4 fijas quedaba una
   pista de aire descuadrando la fila.                                       */
/* El mínimo es 168 y no 150 porque los montos llevan la moneda adelante
   ("ARS 612.000", como los emite ars()) y a 150 la cifra en Bebas 40 se
   iba a elipsis. */
.rep-kpis,.agenda-kpis,.mes-tira{display:grid;grid-template-columns:repeat(auto-fit,minmax(168px,1fr));gap:12px}
/* Entre 1100 y ~850px hay lugar para tres columnas de 168 pero no para
   cuatro (4×168 + 3×12 = 708 contra los ~633 disponibles), así que el cuarto
   KPI se caía solo a un segundo renglón con 430px de aire al lado — el mismo
   «4+1, la última sola» que ya se había corregido en #rep-specific. En esa
   franja van DOS columnas: cuatro leen 2+2 y tres leen 2+1, las dos
   balanceadas. Es la misma franja donde apila la tabla de Documentos. */
@media (max-width:1100px){
  .rep-kpis,.agenda-kpis,.res-summary,.mes-tira{grid-template-columns:repeat(2,minmax(0,1fr))}
}
@media (max-width:420px){
  .rep-kpis,.agenda-kpis,.res-summary,.mes-tira{grid-template-columns:minmax(0,1fr)}
}
.rep-kpis>:last-child:nth-child(odd),.mes-tira>:last-child:nth-child(odd){grid-column:1/-1}
.kpi{background:var(--card-bg);border:1px solid var(--hairline);border-radius:16px;
  padding:16px 18px;min-width:0;transition:border-color 240ms ease}
.kpi:hover{border-color:var(--violet-border)}
/* `overflow:hidden` es lo que hace que `text-overflow` exista: sin caja que
   recorte, la elipsis no se activa nunca y un monto de 7 cifras —"ARS
   12.480.000", un total mensual normal— se pinta 33px afuera de la card en
   vez de truncar. Con `line-height:1` ya no recorta la cola de ningún glifo
   (a .92 sí lo hacía; por eso estaba sacado). */
.kpi .v,.metric .v{font-family:var(--display);font-weight:400;font-size:40px;
  line-height:1;letter-spacing:.5px;color:var(--cloud-100);
  font-variant-numeric:tabular-nums;white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.kpi .l,.metric .l{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--cloud-500);display:block;margin-top:7px;
  line-height:1.5}
.kpi.violet .v,.metric.violet .v{color:var(--violet-text)}
.kpi.gold .v,.metric.gold .v{color:var(--gold)}
.kpi.green .v,.metric.green .v{color:var(--green-live)}


/* ══ 5 · INICIO ════════════════════════════════════════════════════════════ */

/* Atención requerida es el bloque más importante del panel y se veía como una
   card más. Filo violeta a la izquierda — la única card del panel que lo
   lleva — y el conteo como ojal a la derecha.
   Tipos reales del renderer: urgente · reagenda · confirmado (glifos ! ↺ ✓).
   El color del ícono se deriva del tipo, no de una clase de color. */
.attn-block{border-left:2px solid var(--violet-600)}
.attn-head{display:flex;align-items:flex-start;gap:12px;margin-bottom:14px;flex-wrap:wrap}
.attn-head .card-title{margin:0;flex:1;min-width:0}
.attn-count{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--cloud-500);white-space:nowrap;padding-top:4px}
.attn-list{display:flex;flex-direction:column}
.attn-row{display:flex;align-items:center;gap:14px;padding:13px 0;
  border-top:1px solid var(--hairline)}
.attn-row:first-child{border-top:0;padding-top:2px}
.attn-ic{width:30px;height:30px;flex:none;border-radius:9px;display:grid;
  place-items:center;font-size:14px;background:var(--hover-tint);color:var(--cloud-300)}
.attn--urgente .attn-ic{background:var(--coral-soft);color:var(--coral)}
.attn--reagenda .attn-ic{background:var(--gold-soft);color:var(--gold)}
.attn--confirmado .attn-ic{background:var(--green-soft);color:var(--green-live)}
.attn-tx{flex:1;min-width:0;font-size:13.5px;line-height:1.45;color:var(--cloud-300)}
.attn-tx b{color:var(--cloud-100);font-weight:600}
.attn-act{flex:none;font-family:var(--sans);font-weight:600;font-size:12.5px;
  border:1px solid var(--graphite-700);background:transparent;color:var(--cloud-100);
  padding:7px 14px;border-radius:8px;cursor:pointer;
  transition:background 160ms,border-color 160ms}
.attn-act:hover{background:var(--violet-soft);border-color:var(--violet-border)}

/* La card «Hoy» lleva el gradiente del cierre de la landing. Es la única card
   con fondo propio, así que es lo primero que se mira: la que contesta «¿cómo
   viene el día?». El gap de 26 era para una cifra de 44; con Bebas a 40 va 22.
   (panel-fixes-8 §4 lo había bajado de 36 a 26 por el mismo motivo.) */
.card--hoy{background:linear-gradient(158deg,rgba(108,99,255,.14),
  rgba(108,99,255,.03) 52%,transparent),var(--card-bg);border-color:var(--violet-border)}
.hoy-list{display:flex;flex-direction:column;gap:22px}
.hoy-foot{margin-top:18px;padding-top:14px;border-top:1px solid var(--hairline);
  font-size:12.5px;line-height:1.5;color:var(--cloud-500)}

/* Agenda de hoy. Clases del renderer: `.agenda-row` con `.agenda-time`,
   `.agenda-name` y `.agenda-svc`. El `border-left` de color y el punto de
   estado los escribe el renderer inline — esos dos no los alcanzo desde acá
   (ver el archivo de ediciones, punto A). Los tres hijos sí. */
.agenda-list{display:flex;flex-direction:column}
.agenda-row{display:grid;grid-template-columns:60px minmax(0,1fr) auto;
  align-items:center;gap:6px 14px;padding:12px 0;border-top:1px solid var(--hairline)}
.agenda-row:first-child{border-top:0}
.agenda-time{font-family:var(--mono);font-size:13px;color:var(--cloud-100);
  font-variant-numeric:tabular-nums}
.agenda-name{font-size:14px;font-weight:600;color:var(--cloud-100);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.agenda-svc{grid-column:2;font-size:12.5px;color:var(--cloud-500);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Documentos recientes. `.inicio-ticket-row` trae TODO inline: estas reglas
   están listas y no hacen nada hasta que el renderer suelte los `style=`
   (archivo de ediciones, punto B). Las dejo escritas para que el cambio de JS
   sea sacar atributos, no inventar CSS. */
.tickets-list{display:flex;flex-direction:column}
.inicio-ticket-row{display:grid;grid-template-columns:minmax(0,1fr) auto;
  align-items:baseline;gap:2px 12px;padding:12px 0;border-top:1px solid var(--hairline)}
.inicio-ticket-row:first-child{border-top:0}
.inicio-ticket-cli{font-size:13px;font-weight:600;color:var(--cloud-100);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}          /* NUEVO */
.inicio-ticket-monto{font-family:var(--mono);font-size:12.5px;color:var(--cloud-100);
  font-variant-numeric:tabular-nums;flex:none}                        /* NUEVO */
.inicio-ticket-est{grid-column:1;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.06em;color:var(--cloud-500)}                        /* NUEVO */

/* Reseñas de Inicio. NUEVO: este contenedor no tiene renderer atado todavía. */
.resenas-list{display:flex;flex-direction:column}
.res-item{padding:13px 0;border-top:1px solid var(--hairline)}
.res-item:first-child{border-top:0;padding-top:2px}
.res-top{display:flex;align-items:center;gap:9px;min-width:0}
/* Las reseñas son anónimas (10/09): en el slot del nombre va el trabajo, no
   la persona. .res-name deja de ir alineado a la derecha porque ya no es un
   dato secundario colgado del renglón — es lo que identifica la reseña. */
.res-name{font-size:12.5px;font-weight:600;color:var(--cloud-300);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.res-q{font-size:13px;line-height:1.5;color:var(--cloud-300);margin-top:6px;
  font-style:italic;text-wrap:pretty}

/* Saludo de Mate y recorrido del día — sólo mini-app, pero el estilo es el
   mismo idioma. El avatar sale del blanco sobre violeta (4,32:1). */
.mate-saludo{display:flex;gap:11px;align-items:flex-start;margin-bottom:16px;
  padding:14px 16px;border-radius:16px;background:var(--card-bg);
  border:1px solid var(--hairline)}
.mate-saludo-av{width:30px;height:30px;flex:none;border-radius:50%;display:grid;
  place-items:center;background:var(--violet-soft-2);border:1px solid var(--violet-border);
  color:var(--cloud-100);font-family:var(--display);font-size:15px;line-height:1}
.mate-saludo p{margin:0;font-size:13.5px;line-height:1.45;color:var(--cloud-100);
  padding-top:4px;text-wrap:pretty}
.recorrido-list{display:flex;flex-direction:column;gap:2px}


/* ══ 6 · TOOLBARS Y FILTROS · las siete vistas ═════════════════════════════
   La tira de filtros va en su propia fila, nunca dentro de la card de
   contenido. Deslizable a propósito, con degradado al borde para que se vea
   que se puede arrastrar — eso era lo que faltaba, no que se cortara.      */
.toolbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;margin-bottom:12px}
.pill{min-height:34px;padding:0 12px;border-radius:9px;border:1px solid var(--graphite-700);
  background:transparent;color:var(--cloud-500);font-family:var(--sans);font-size:12.5px;
  font-weight:500;display:inline-flex;align-items:center;gap:7px;cursor:pointer;
  white-space:nowrap;transition:background 170ms,border-color 170ms,color 170ms}
.pill:hover{background:var(--hover-tint);color:var(--cloud-100)}
.pill.is-active{background:var(--violet-soft-2);border-color:var(--violet-border);
  color:var(--cloud-100);font-weight:600}
.pill .n{font-family:var(--mono);font-size:10.5px;opacity:.75}

/* Navegador de rango. El rótulo va en mono y tabular para que las flechas no
   muevan el ancho al cambiar de período. */
.range-nav{display:flex;align-items:center;gap:4px;margin-left:auto}
.range-arrow{width:32px;height:32px;flex:none;border-radius:8px;border:1px solid var(--graphite-700);
  background:transparent;color:var(--cloud-300);cursor:pointer;font-size:15px;line-height:1;
  display:grid;place-items:center;transition:background 170ms,color 170ms}
.range-arrow:hover{background:var(--violet-soft);color:var(--cloud-100);border-color:var(--violet-border)}
.range-label{font-family:var(--mono);font-size:11.5px;letter-spacing:.04em;
  color:var(--cloud-100);min-width:132px;text-align:center;font-variant-numeric:tabular-nums}
.toolbar-meta{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--cloud-500);margin-left:auto;white-space:nowrap}

.input{height:44px;padding:0 13px;border-radius:11px;border:1px solid var(--graphite-700);
  background:var(--graphite-950);color:var(--cloud-100);font-family:var(--sans);
  font-size:13.5px;outline:none;min-width:0}
.input:focus{border-color:var(--violet-border);box-shadow:0 0 0 3px var(--violet-soft)}
.input::placeholder{color:var(--cloud-500)}
.input-search-tickets{width:100%}

/* Vacíos. Ocupan el alto disponible y se centran, en vez de dejar 700-800px
   muertos abajo — en un teléfono eso es scrollear una pantalla de nada. */
.vacio-centrado-wrap{min-height:46vh;display:grid;place-items:center;text-align:center}
.vacio-centrado-wrap>div{max-width:38ch;text-wrap:pretty}


/* ══ 7 · AGENDA ════════════════════════════════════════════════════════════
   El trabajo en curso es el único bloque del panel con pulso: es lo que está
   pasando ahora mismo. Borde verde y el punto latiendo.                    */
.live-job{margin-top:14px;border-color:var(--green-border);
  background:linear-gradient(158deg,rgba(29,185,84,.07),transparent 55%),var(--card-bg)}
.live-job-row{display:flex;align-items:center;gap:16px;flex-wrap:wrap}
.live-job-main{display:flex;align-items:center;gap:12px;flex:1;min-width:0}
/* El <div> sin clase que envuelve al título y al subtítulo (panel.html:2313)
   es un item flex y por defecto lleva min-width:auto, así que no baja de su
   ancho max-content: el título se pasaba 32px de .live-job-main y se metía
   16px debajo de los botones de estado. Con min-width:0 el encogimiento
   propaga y recién ahí el overflow del título hace efecto.
   Va con :not(.live-pulse) por si el marcado cambia el punto de span a div —
   es la misma trampa de especificidad que .client-top>div con el avatar. */
.live-job-main>div:not(.live-pulse){min-width:0;flex:1}
.live-pulse{width:9px;height:9px;flex:none;border-radius:50%;background:var(--green-live);
  animation:ljp 2.4s ease-in-out infinite}
@keyframes ljp{0%,100%{box-shadow:0 0 0 4px var(--green-soft)}
               50%{box-shadow:0 0 0 9px rgba(29,185,84,.04)}}
.live-job-title{font-size:15px;font-weight:600;color:var(--cloud-100);min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:block}
.live-job-sub{font-family:var(--mono);font-size:11px;color:var(--cloud-500);margin-top:3px}
.live-steps{display:flex;gap:6px;flex-wrap:wrap}
.live-step{font-family:var(--sans);font-size:12.5px;font-weight:600;padding:0 12px;
  min-height:34px;display:inline-flex;align-items:center;border-radius:9px;
  border:1px solid var(--graphite-700);background:transparent;color:var(--cloud-500);
  cursor:pointer;white-space:nowrap;transition:background 160ms,color 160ms,border-color 160ms}
.live-step:hover{background:var(--hover-tint);color:var(--cloud-100)}
.live-step.is-active{background:var(--green-soft);border-color:var(--green-border);
  color:var(--green-live)}
.live-actions{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin-top:16px;
  padding-top:14px;border-top:1px solid var(--hairline)}
.live-sync{display:flex;align-items:center;gap:8px;font-family:var(--mono);font-size:10.5px;
  letter-spacing:.06em;color:var(--cloud-500);min-width:0}
.live-sync-dot{width:6px;height:6px;flex:none;border-radius:50%;background:var(--green-live);
  box-shadow:0 0 0 3px var(--green-soft)}
.live-actions-btns{display:flex;gap:8px;margin-left:auto;flex-wrap:wrap}
@media (max-width:1100px){
  .live-actions{flex-direction:column;align-items:stretch}
  .live-actions-btns{margin-left:0;width:100%}
  .live-actions-btns>*{flex:1}
}

/* Las filas de la agenda por rango. `.ag-item` trae el `border-left` de estado
   inline (queda), lo demás es de acá. */
/* LA LISTA CRONOLÓGICA es la superficie más importante del producto: es el
   día operativo, y es lo que abre la mini-app. Así que la fila deja de ser
   una línea de tabla y pasa a ser una CARD con dos renglones —el dato arriba,
   las acciones de su estado abajo— porque lo que se hace acá es cambiar el
   estado de un trabajo, no leerlo.

   La grilla base de producción (120px minmax(0,1fr) auto, panel.html:1532)
   se respeta en el primer renglón; las acciones van en un segundo renglón que
   ocupa el ancho completo, así no pelean 14px con el badge.                */
.ag-list{display:flex;flex-direction:column;gap:10px}
.ag-item{display:grid;grid-template-columns:96px minmax(0,1fr) auto;
  gap:10px 14px;align-items:start;padding:14px 16px;
  border:1px solid var(--hairline);border-radius:16px;background:var(--card-bg);
  border-bottom:1px solid var(--hairline)}
.ag-item:last-child{border-bottom:1px solid var(--hairline)}
/* El trabajo que está pasando ahora se distingue del resto del día. */
.ag-item.is-ahora{border-color:var(--green-border);
  background:linear-gradient(158deg,rgba(29,185,84,.07),transparent 55%),var(--card-bg)}
.ag-item.is-cerrado{opacity:.72}
.ag-item.is-cerrado:hover{opacity:1}
.ag-item .agenda-time{font-family:var(--mono);font-size:14px;color:var(--cloud-100);
  font-variant-numeric:tabular-nums;padding-top:1px}
.ag-item .agenda-time small{display:block;font-size:9.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--cloud-500);margin-top:3px}
.ag-item .agenda-name{font-size:14.5px;font-weight:600;color:var(--cloud-100);min-width:0}
.ag-item .agenda-svc{grid-column:2;font-size:12.5px;line-height:1.5;color:var(--cloud-500);
  min-width:0;text-wrap:pretty}
.ag-item>.badge{justify-self:end}
/* Segundo renglón: las acciones del estado. */
.ag-item .ag-acciones{grid-column:1/-1;padding-top:11px;margin-top:1px;
  border-top:1px solid var(--hairline)}
/* El mensaje que Mia le manda al cliente, textual. Es la única forma de que
   el emprendedor sepa qué se dijo en su nombre antes de apretar. */
.ag-wa{grid-column:1/-1;display:flex;align-items:flex-start;gap:9px;
  padding:9px 11px;border-radius:11px;background:var(--green-soft);
  border:1px solid var(--green-border);font-size:12.5px;line-height:1.45;
  color:var(--cloud-100);text-wrap:pretty}
.ag-wa .k{font-family:var(--mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--green-live);flex:none;padding-top:2px}
.ag-empty{padding:28px;text-align:center;color:var(--cloud-500);font-size:13px}
@media (max-width:560px){
  .ag-item{grid-template-columns:74px minmax(0,1fr);padding:13px 14px}
  .ag-item>.badge{grid-column:2;justify-self:start}
  .ag-item .agenda-svc{grid-column:1/-1}
}
.ag-accion{font-family:var(--sans);font-weight:600;transition:background 160ms,border-color 160ms}
.ag-reag-btn:hover,.ag-accion:hover{background:var(--violet-soft)}
.ag-reag-motivos{display:flex;gap:6px;flex-wrap:wrap}


/* ══ 8 · DOCUMENTOS ════════════════════════════════════════════════════════
   La tabla es una card, no una lista suelta — absorbe panel-fixes-8 §8. Las
   filas tenían divisoria pero el conjunto no tenía contenedor, así que
   flotaba sobre el fondo: era la única superficie de datos del panel sin
   marco. Y con marco la cabecera necesita aire arriba, que era cero.

   `.thead` y `.trow` comparten la grilla en la MISMA regla — absorbe
   panel-fixes-2. Al cambiar las columnas sólo en `.trow` se desalineó
   ID/CLIENTE/RESUMEN/ESTADO/CUÁNDO. Van juntas, siempre.                   */
.table-card{padding:0}
/* Las cinco pistas van todas en minmax, no cuatro fijas + un 1fr. Con
   96+150+130+96 fijos (472) más los gaps (56) y el padding de la fila (44)
   son 572px de costo fijo: en un .main de 689 la única pista flexible
   —RESUMEN, justo la del texto más largo— se quedaba con 59px, envolvía en
   tres líneas y encima desbordaba. La intención quedaba invertida.
   Ahora las otras cuatro ceden hasta su mínimo antes de apretar a RESUMEN,
   que es la que tiene que ser la más ancha. */
.tickets-table .thead,.tickets-table .trow{display:grid;
  grid-template-columns:minmax(64px,96px) minmax(104px,150px) minmax(0,1fr)
                        minmax(92px,130px) minmax(64px,96px);
  column-gap:14px;align-items:center}
.tickets-table .thead{padding:16px 22px;font-family:var(--mono);font-size:10px;
  letter-spacing:.14em;text-transform:uppercase;color:var(--cloud-500);
  border-bottom:1px solid var(--hairline)}
.tickets-table .trow{padding:14px 22px;border-bottom:1px solid var(--hairline);
  font-size:13px;color:var(--cloud-300);cursor:pointer;transition:background 160ms}
.tickets-table .trow:last-child{border-bottom:none}
.tickets-table .trow:hover{background:var(--hover-tint)}
.tickets-table .tid{font-family:var(--mono);font-size:10px;letter-spacing:.06em;
  color:var(--cloud-500);white-space:nowrap}
.tickets-table .ttime{font-family:var(--mono);font-size:11px;color:var(--cloud-500);
  text-align:right;font-variant-numeric:tabular-nums}
/* Apilado. El renderer emite los cinco hijos en este orden y sólo tres
   llevan clase (.tid, .badge, .ttime): Cliente y Resumen son <span> pelados,
   así que hay que colocarlos por POSICIÓN, no por clase.

     1 .tid  ·  2 cliente  ·  3 resumen  ·  4 .badge  ·  5 .ttime

   Se coloca con grid-area explícito en cada hijo. Con `grid-template-areas`
   sola no alcanzaba: sin un `grid-area` en los hijos las áreas no las
   consume nadie, gana la colocación automática en orden del DOM —el #id se
   quedaba el slot ancho y el cliente en 76px— y cada fila armaba su propia
   grilla implícita, así que los badges no compartían línea de columna.     */
@media (max-width:1100px){
  .tickets-table .thead{display:none}
  .tickets-table .trow{grid-template-columns:minmax(0,1fr) auto;
    row-gap:4px;column-gap:10px;padding:14px 18px}
  .tickets-table .trow>*:nth-child(2){grid-area:1/1;font-size:14px;font-weight:600;
    color:var(--cloud-100);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  .tickets-table .trow>*:nth-child(4){grid-area:1/2;justify-self:end}
  .tickets-table .trow>*:nth-child(3){grid-area:2/1/3/3;min-width:0}
  .tickets-table .trow>*:nth-child(1){grid-area:3/1}
  .tickets-table .trow>*:nth-child(5){grid-area:3/2;justify-self:end}
}

/* Badge de estado. Los cuatro tonos del sistema. */
.badge{display:inline-flex;align-items:center;gap:5px;font-family:var(--mono);
  font-weight:600;font-size:9px;letter-spacing:.09em;text-transform:uppercase;
  padding:4px 9px;border-radius:999px;border:1px solid;white-space:nowrap}
.badge i{width:5px;height:5px;border-radius:9px;display:block;background:currentColor}
.b-ok{color:var(--green-live);background:var(--green-soft);border-color:var(--green-border)}
.b-amb{color:var(--gold);background:var(--gold-soft);border-color:rgba(232,184,76,.30)}
.b-vio{color:var(--violet-text);background:var(--violet-soft-2);border-color:var(--violet-border)}
.b-neu{color:var(--cloud-300);background:var(--hover-tint);border-color:var(--graphite-700)}


/* ══ 9 · CLIENTES ══════════════════════════════════════════════════════════
   El avatar era la tercera aparición del blanco sobre violeta: 4,32:1, con dos
   hex a mano (`linear-gradient(135deg,#6C63FF,#4036B5)` + `color:#fff`) fuera
   del sistema. Pasa a tinte violeta con borde y tinta `--cloud-100` → 14,26:1.
   Absorbe panel-fixes-8 §7. La ficha usa la misma clase (`#cd-avatar`), así
   que se arreglan los dos de una.                                          */
.clientes-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}
/* .client-top y .client-name son reales (panel.html:947 y 950) y el renderer
   los emite (5854). El tamaño de .client-name lo fija panel-fixes.css:76:
   14px / 600 — se preserva. */
.client-top{display:flex;align-items:flex-start;gap:12px;min-width:0}
/* :not(.client-avatar) es obligatorio, no cosmético: `.client-top>div` tiene
   más especificidad (0,1,1) que `.client-avatar` (0,1,0), así que sin el
   filtro el avatar toma flex:1, su width:44px pasa a ser sólo la base y el
   círculo se estira a elipse aplastando el nombre. Y el renderer real
   (panel.html:5854) emite sus propios hijos dentro de .client-top, así que un
   selector suelto le pegaría a lo que sea que emita. */
.client-top>div:not(.client-avatar){min-width:0;flex:1}
.client-name{display:flex;align-items:center;gap:7px;font-size:14px;font-weight:600;
  color:var(--cloud-100);min-width:0}
.client-name>span:first-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* La dirección va completa, como la devuelve Google Maps (calle, número,
   código postal, ciudad, país) — decisión de Matías del 10/09, ya pasada a
   Dev. Acá es el mismo dato de `direccion_negocio.formatted`, que es
   justamente el campo que hay que leer para que no salga [object Object]. */
.client-extra{font-size:11px;line-height:1.55;color:var(--cloud-500);margin-top:8px;
  padding-top:8px;border-top:1px dashed var(--hairline);text-wrap:pretty}
.client-card{background:var(--card-bg);border:1px solid var(--hairline);border-radius:18px;
  padding:18px 20px;cursor:pointer;position:relative;overflow:hidden;min-width:0;
  transition:transform 240ms cubic-bezier(.4,0,.2,1),border-color 240ms,box-shadow 240ms}
.client-avatar,#cd-avatar{width:44px;height:44px;flex:none;border-radius:50%;
  display:grid;place-items:center;background:var(--violet-soft-2);
  border:1px solid var(--violet-border);color:var(--cloud-100);font-family:var(--sans);
  font-weight:700;font-size:15px;letter-spacing:-.3px;background-image:none}
.client-tag{font-family:var(--mono);font-size:9px;letter-spacing:.06em;font-weight:600;
  padding:3px 7px;border-radius:5px;flex-shrink:0;text-transform:uppercase}
.client-meta{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:10px 14px;
  border-top:1px solid var(--hairline);padding-top:14px;margin-top:14px}
.client-meta .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.10em;
  text-transform:uppercase;color:var(--cloud-500)}
.client-meta .v{font-family:var(--display);font-size:22px;line-height:1;color:var(--cloud-100);
  font-weight:400;letter-spacing:.3px;margin-top:5px;font-variant-numeric:tabular-nums}
.client-status{display:flex;align-items:center;gap:6px;font-size:11px;color:var(--cloud-300)}
.client-proxima{font-family:var(--mono);font-size:10.5px;letter-spacing:.04em;
  color:var(--cloud-300)}


/* ══ 10 · REPORTES ═════════════════════════════════════════════════════════ */
.rep-card{margin-top:14px}
.rep-card .card-title{margin-bottom:16px}
.rep-row{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:14px;
  align-items:start;margin-top:14px}
.rep-bars-card{background:var(--card-bg);border:1px solid var(--hairline);
  border-radius:18px;padding:20px}
/* La barra de Reportes es .rep-mini-bar con un <i style="width:X%"> adentro
   (panel.html:1527, emitida en 3491). NO son las .neg-bars de Configuración:
   son dos componentes distintos. */
.rep-mini-bar{height:6px;border-radius:4px;background:var(--graphite-700);
  overflow:hidden;margin-top:10px}
.rep-mini-bar i{display:block;height:100%;border-radius:4px;background:var(--violet-600)}
.skel{background:linear-gradient(90deg,var(--hover-tint),var(--violet-soft),var(--hover-tint));
  background-size:220% 100%;animation:skel 1.5s ease-in-out infinite}
@keyframes skel{0%{background-position:120% 0}100%{background-position:-20% 0}}
#rep-pat-tag{color:var(--cloud-100)}


/* ══ 11 · RESEÑAS ══════════════════════════════════════════════════════════
   El promedio es la cifra más grande de la vista: va en Bebas, grande, y las
   estrellas debajo. Las estrellas en `--violet-600` daban 3,95:1 sobre la card
   y el mínimo es 4,5 (a 18px no alcanza la excepción de texto grande, que
   arranca en 18,66). Van a `--violet-text` → 7,55:1, y ese token existe para
   este caso exacto: lo dice su comentario en tokens.css:18. Absorbe fixes-8 §5.

   La itálica de la cita se queda y el tamaño de 17px NO se toca (fixes-8 §6).*/
.res-summary{display:grid;grid-template-columns:repeat(auto-fit,minmax(168px,1fr));
  gap:12px;margin-bottom:14px}
.res-avg,.res-stat{background:var(--card-bg);border:1px solid var(--hairline);
  border-radius:16px;padding:16px 18px;display:flex;flex-direction:column;gap:3px;min-width:0}
.res-avg .n{font-family:var(--display);font-size:44px;font-weight:400;line-height:1;
  letter-spacing:.4px;color:var(--cloud-100);font-variant-numeric:tabular-nums}
.res-avg .s,.res-stars,#res-avg-stars{color:var(--violet-text);letter-spacing:2px;font-size:15px}
.res-avg .l,.res-stat .l{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--cloud-500);margin-top:4px}
.res-stat .v{font-family:var(--display);font-size:32px;font-weight:400;line-height:1;
  letter-spacing:.4px;color:var(--cloud-100);font-variant-numeric:tabular-nums}
.res-stat .v.green{color:var(--green-live)}
.res-filters{display:flex;gap:8px;flex-wrap:wrap}
.res-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px}
.res-card{background:var(--card-bg);border:1px solid var(--hairline);border-radius:18px;
  padding:20px 22px;position:relative;overflow:hidden;min-width:0;
  transition:transform 240ms cubic-bezier(.4,0,.2,1),border-color 240ms,box-shadow 240ms}
.res-card .quote{font-size:17px;line-height:1.5;color:var(--cloud-100);font-style:italic;
  text-wrap:pretty}
.res-card .meta{display:flex;align-items:baseline;gap:9px;margin-top:14px;
  padding-top:12px;border-top:1px solid var(--hairline)}
.res-card .meta .n{font-family:var(--mono);font-size:10px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--cloud-500)}
.res-card .meta .t{font-family:var(--mono);font-size:10px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--cloud-500);margin-left:auto}
.res-photo{height:96px;border-radius:12px;margin-bottom:12px;
  background:linear-gradient(135deg,var(--violet-soft),var(--graphite-800));
  border:1px solid var(--hairline);display:grid;place-items:center;
  font-family:var(--mono);font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--cloud-500)}


/* ══ 12 · CONFIGURACIÓN ════════════════════════════════════════════════════
   Salud del negocio: la cifra cobrada es la más grande del panel después del
   promedio de reseñas. En Bebas, con el rótulo como ojal arriba.           */
.negocio-resumen{display:flex;flex-direction:column;gap:12px;margin-bottom:16px}
.neg-lbl{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--violet-text);margin-bottom:8px}
.neg-cobrado{font-family:var(--display);font-size:46px;font-weight:400;line-height:.95;
  letter-spacing:.4px;color:var(--cloud-100);font-variant-numeric:tabular-nums}
.neg-cobrado-sub{font-family:var(--sans);font-size:12.5px;color:var(--cloud-500);margin-top:4px}
.neg-bars{display:flex;flex-direction:column;gap:11px;padding-top:14px;margin-top:14px;
  border-top:1px solid var(--hairline)}
.neg-bar-row{display:grid;grid-template-columns:90px minmax(0,1fr) 84px;align-items:center;gap:10px}
.neg-bar-track{height:7px;background:var(--graphite-700);border-radius:9px;overflow:hidden}
.neg-bar-fill{display:block;height:100%;border-radius:9px}
/* El estado actual del stepper es un rótulo, no una opción: no se puede
   clickear y se distingue del resto. */
.live-step[disabled]{cursor:default;background:var(--green-soft);
  border-color:var(--green-border);color:var(--green-live);font-weight:700}

.cfg-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:14px;
  align-items:start}
.cfg-card h3{display:flex;flex-direction:column;gap:2px;margin:0 0 14px;
  font-family:var(--display);font-size:20px;font-weight:400;letter-spacing:.4px;
  line-height:1.05;color:var(--cloud-100)}
.cfg-card h3 .arrow{display:none}
.cfg-field{display:flex;flex-direction:column;gap:5px;margin-top:12px;min-width:0}
.cfg-field label{font-family:var(--mono);font-size:9.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--cloud-500)}
.cfg-field .val{font-size:13.5px;color:var(--cloud-100);min-width:0}

/* La lista de Configuración (una card por pantalla, en mini-app). */
.cfg-list-row{display:flex;align-items:center;gap:12px;width:100%;text-align:left;
  min-height:56px;padding:12px 16px;border-radius:14px;border:1px solid var(--hairline);
  background:var(--card-bg);cursor:pointer;transition:background 170ms,border-color 170ms}
.cfg-list-row:hover{background:var(--hover-tint);border-color:var(--violet-border)}
.cfg-list-txt{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.cfg-list-txt .t{font-size:14px;font-weight:600;color:var(--cloud-100)}
.cfg-list-txt .s{font-family:var(--mono);font-size:10.5px;letter-spacing:.04em;
  color:var(--cloud-500);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cfg-list-arrow{flex:none;font-size:18px;color:var(--cloud-500)}
#cfg-back-btn{display:inline-flex;align-items:center;gap:7px;min-height:42px;padding:0 16px;
  border-radius:10px;border:1px solid var(--graphite-700);background:transparent;
  color:var(--cloud-300);font-family:var(--sans);font-size:13px;font-weight:500;
  cursor:pointer;margin-bottom:14px;transition:background 170ms,color 170ms}
#cfg-back-btn:hover{background:var(--violet-soft);color:var(--cloud-100);
  border-color:var(--violet-border)}


/* ══ 13 · CAJONES Y MODALES ════════════════════════════════════════════════
   Los dos van contenidos DENTRO del panel, no del viewport — absorbe
   panel-fixes-3 y -6. El panel tiene DOS componentes de ventana y el parche 3
   arreglaba sólo uno: `.pw-drawer-ov` (el cajón lateral) sí, `.modal-ov` (el
   modal centrado de presupuesto y recibo) no.                              */
/* El cajón se encierra en el panel, pero eso es un límite HORIZONTAL: que no
   se salga del ancho del panel en pantallas anchas. El overlay se queda
   `fixed` —como en producción, panel.html:1620— para que el alto sea el de
   la ventana; con `absolute` se anclaba al .panel, que crece con su
   contenido (1944px), el cajón resolvía `height:100%` a 1944 y el pie con la
   acción principal caía al final del documento, fuera de la pantalla.

   El encierro horizontal lo da la banda: una columna de 1440px centrada —el
   mismo `max-width` del panel— con el cajón pegado a su borde derecho. Sin
   nodos nuevos y sin sticky. */
.pw-drawer-ov{position:fixed;inset:0;z-index:120;display:grid;
  grid-template-columns:minmax(0,1440px);grid-template-rows:minmax(0,1fr);
  justify-content:center;overflow:hidden}
/* 14-sep-2026 (Dev): el background/blur que estaban acá se movieron a
   `.pw-drawer-backdrop` (panel.html) -- ese contenedor se muestra con
   `visibility:hidden→visible` (no animable), así que el fondo aparecía
   de un salto en vez de fundirse; `.pw-drawer-backdrop` ya existe
   específicamente para este fade y antes quedaba invisible, tapado por
   este mismo fondo ya opaco. Mismo color y blur, un solo fundido real. */
/* El cajón se adapta a su contenido en vez de estirarse siempre a toda la
   altura: con `height:auto` + `max-height` mide lo que mide su ficha y sólo
   cuando la pasa, el cuerpo empieza a scrollear. Así la ficha de un cliente
   con dos trabajos no deja media pantalla vacía abajo.

   Al dejar de tocar los bordes se vuelve una hoja apoyada, no una pared:
   separada 18px de arriba, abajo y del borde derecho del panel, con las
   cuatro esquinas redondeadas y la sombra alrededor. `align-self:center` la
   centra vertical mientras sea más baja que la ventana. */
.pw-drawer-ov>.pw-drawer{justify-self:end;align-self:center;
  height:auto;max-height:calc(100% - 36px);margin:18px;
  border:1px solid var(--hairline);border-radius:20px;overflow:hidden;
  box-shadow:0 26px 70px rgba(0,0,0,.45)}
/* El cuerpo deja de absorber el sobrante: crece con su contenido y scrollea
   sólo cuando el cajón llegó a su tope. */
.pw-drawer-ov>.pw-drawer>.pw-drawer-body{flex:0 1 auto}
@media (max-width:560px){
  .pw-drawer-ov>.pw-drawer{margin:0;max-height:100%;height:100%;
    border-radius:0;border:0;align-self:stretch}
}
/* 14-sep-2026 (Dev): backdrop-filter sacado -- Mati confirmó que sacarlo
   del cajón "mejoró mucho" la velocidad real (mismo blur, mismo GPU/
   driver, misma superficie de overlay animado). Mismo arreglo acá por
   consistencia -- ver .pw-drawer-backdrop en panel.html para el detalle
   completo del hallazgo. */
.modal-ov{position:fixed;inset:0;z-index:120;background:rgba(0,0,0,.55)}

/* El cajón es una superficie de la dirección, no una ventana gris: mismo
   fondo de card, la trama de puntos de 3px, y el gradiente de violeta
   entrando por el encabezado — el mismo gesto que la card «Hoy». */
.pw-drawer{background:var(--graphite-900);border-left:1px solid var(--hairline);
  box-shadow:-18px 0 50px rgba(0,0,0,.35);position:relative;isolation:isolate}
.pw-drawer::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:radial-gradient(var(--panel-trama) 1px,transparent 1px);
  background-size:3px 3px}
.pw-drawer-head{background:linear-gradient(160deg,rgba(108,99,255,.16),
  rgba(108,99,255,.03) 60%,transparent);border-bottom:1px solid var(--hairline)}
.pw-drawer-x{border-color:var(--graphite-700);border-radius:9px;
  transition:background 160ms,color 160ms,border-color 160ms}
.pw-drawer-x:hover{background:var(--violet-soft);color:var(--cloud-100);
  border-color:var(--violet-border)}
.pw-drawer-body{gap:14px}
.pw-drawer-foot{border-top:1px solid var(--hairline);
  background:linear-gradient(0deg,var(--violet-soft),transparent)}
/* El modal centrado, el mismo tratamiento. */
.modal{background:var(--graphite-900);border-color:var(--hairline);border-radius:18px;
  position:relative;isolation:isolate}
.modal::before{content:'';position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:radial-gradient(var(--panel-trama) 1px,transparent 1px);
  background-size:3px 3px}
.modal-head{padding-bottom:14px;border-bottom:1px solid var(--hairline)}
.modal-x{border:1px solid var(--graphite-700);border-radius:9px;
  transition:background 160ms,color 160ms,border-color 160ms}
.modal-x:hover{background:var(--violet-soft);color:var(--cloud-100);
  border-color:var(--violet-border)}
.modal-foot{padding-top:14px;border-top:1px solid var(--hairline)}
/* Las cifras de los cajones —el total de un presupuesto, lo facturado de una
   ficha— van en Bebas, como las del panel. */
.pw-drawer .kpi .v,.modal .kpi .v{font-size:30px}
.pw-drawer-total{display:flex;align-items:baseline;justify-content:space-between;
  gap:12px;padding:14px 16px;border-radius:14px;border:1px solid var(--violet-border);
  background:linear-gradient(158deg,rgba(108,99,255,.14),rgba(108,99,255,.03) 52%,transparent)}
.pw-drawer-total .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--cloud-500)}
.pw-drawer-total .v{font-family:var(--display);font-size:34px;font-weight:400;
  line-height:1;letter-spacing:.4px;color:var(--cloud-100);font-variant-numeric:tabular-nums}
/* La bitácora de la ficha del cliente. */
.pw-hist{display:flex;flex-direction:column}
.pw-hist-row{display:grid;grid-template-columns:62px minmax(0,1fr) auto;gap:12px;
  align-items:baseline;padding:11px 0;border-top:1px solid var(--hairline)}
.pw-hist-row:first-child{border-top:0}
.pw-hist-row .f{font-family:var(--mono);font-size:10.5px;color:var(--cloud-500);
  letter-spacing:.04em}
.pw-hist-row .t{min-width:0;font-size:13px;color:var(--cloud-300)}
.pw-hist-row .m{font-family:var(--mono);font-size:12px;color:var(--cloud-100);
  font-variant-numeric:tabular-nums}
/* DM Sans, no Bebas: es la misma razón por la que .hdr-view-title volvió al
   sans — Bebas es caps-only y "Cargar un trabajo" salía "CARGAR UN TRABAJO".
   Bebas se queda en los títulos de card y en las cifras. */
.pw-drawer-title{font-family:var(--sans);font-size:17px;font-weight:700;
  letter-spacing:-.2px;line-height:1.3;color:var(--cloud-100)}
.pw-drawer-sub{font-family:var(--mono);font-size:10.5px;letter-spacing:.07em;
  color:var(--cloud-500);margin-top:5px;display:flex;align-items:center;gap:7px}
.modal-title{font-family:var(--sans);font-size:17px;font-weight:700;letter-spacing:-.2px;
  line-height:1.3;color:var(--cloud-100)}
.modal-sub{display:flex;align-items:center;gap:7px;font-family:var(--mono);font-size:10.5px;
  color:var(--cloud-500);margin-top:5px;line-height:1.4}

/* Los bloques numerados del cajón de alta. El número vivía en 9,5px dentro de
   una caja de 19px, así que el bloque se leía como un cuadrado vacío — y es
   justo la señal que hace legible en qué paso estás. El ✓ va un punto más
   grande porque una tilde lee más chica que un dígito con la misma altura. */
.ctm-num{font-size:11px;font-weight:600;line-height:1}
.ctm-bloque.is-done .ctm-num{font-size:12px}


/* ══ 14 · BOTONES Y CAMPOS ═════════════════════════════════════════════════
   El blanco sobre `--violet-600` da 4,32:1 y falla en los dos temas. No es
   sólo el botón: son tres elementos — el botón, el número de paso del cajón de
   presupuesto y el avatar de Mate. Los tres al 700 (5,44:1), el hover al 800,
   que ya está declarado como `:active`. El 600 sigue siendo el violeta de
   marca para bordes, tintes e íconos.                                      */
.btn-primary{background:var(--violet-700);color:#fff}
.btn-primary:hover{background:var(--violet-800)}

/* `font: inherit` — absorbe panel-fixes-9. `panel.html` no tiene ninguno, así
   que 11 button/input caen al Arial 13,33px del navegador en medio de un panel
   en DM Sans. El más visible es `#ctm-hora`, el campo de hora del cajón de
   alta, en otra tipografía que el resto del formulario. */
/* `:where()` es obligatorio, no cosmético: sin él el selector es clase+tipo
   (0,1,1) y le gana a TODA regla de un solo componente (0,1,0) —`.pill`,
   `.ag-accion`, `.attn-act`, `.live-step`, `.ctm-dia`, `.ctm-input`, la ✕ de
   los cajones— que caían a los 16px del body. Con `:where()` el reset pesa
   cero: rescata a los 11 controles sin estilo del Arial 13,33px del navegador
   (heredan porque nada más los toca) y no le pisa el tamaño a ninguno de los
   que sí tienen regla. */
:where(.panel,.pw-drawer,.modal) :where(button,input,select,textarea){
  font-family:inherit;font-size:inherit;line-height:inherit}
:where(.panel) :where(input[type="checkbox"],input[type="radio"]){accent-color:var(--violet-600)}

/* Cifras tabulares en todo lo que sea número, para que no bailen al refrescar. */
.kpi .v,.metric .v,.res-avg .n,.res-stat .v,.neg-cobrado,.client-meta .v,
.agenda-time,.range-label,.ttime{font-variant-numeric:tabular-nums}

/* Sin itálicas fuera de las citas — absorbe panel-fixes.css §1. La única
   itálica del panel es la cita de una reseña, que es una voz ajena. */
.panel em,.panel i:not([class]){font-style:normal}
.res-card .quote,.res-q{font-style:italic}


/* ══ 15 · PIE ══════════════════════════════════════════════════════════════
   Las dos píldoras del pie ya tenían el mismo alto (28px): lo que estaba
   desalineado era la posición vertical, 14px de desfasaje porque viven en
   cajas distintas. `align-items:center` en la fila lo resuelve.

   El descargo legal va en `--cloud-500`, igual que los links. En un tono de
   borde daba 2,50:1 en oscuro y es el texto obligatorio (Ley 25.326).      */
.footer{grid-area:footer;border-top:1px solid var(--hairline);display:flex;
  align-items:center;padding:0 28px;gap:16px}
.footer-links{display:flex;gap:18px;margin-left:auto;align-items:center}
.footer-links a{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--cloud-500);text-decoration:none}
.footer-links a:hover{color:var(--violet-text)}
.footer-note{font-family:var(--mono);font-size:9.5px;letter-spacing:.11em;
  text-transform:uppercase;color:var(--cloud-500)}


/* ══ 16 · MINI-APP ═════════════════════════════════════════════════════════
   La mini-app es siempre oscura (`html.tg-mode`, decisión del 05/09) y hereda
   todo lo de arriba. Sólo cambia el marco: targets a 44px y la tab bar.     */
html.tg-mode .pill,html.tg-mode .live-step,html.tg-mode .attn-act,
html.tg-mode .btn-outline.sm,html.tg-mode .btn-primary.sm{min-height:44px;padding:0 16px}
html.tg-mode .cfg-list-row{min-height:60px}
.tg-tabbar{display:grid;grid-template-columns:repeat(4,1fr);background:var(--graphite-950);
  border-top:1px solid var(--hairline)}
.tg-tab-btn{min-height:56px;display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:4px;font-family:var(--sans);font-size:10.5px;font-weight:500;
  color:var(--cloud-500);background:transparent;border:0;border-top:2px solid transparent;
  cursor:pointer}
.tg-tab-btn.is-active{color:var(--cloud-100);font-weight:700;border-top-color:var(--violet-600)}


/* ══ 17 · EL CAJÓN DE ALTA ═════════════════════════════════════════════════
   Leído el renderer real (panel.html:3967-3982 el marcado · 4262, 4344-4354,
   4380-4382 lo que emite). Lo que emite es TEXTO PLANO:

     .ctm-sug   → <button class="ctm-sug" data-cid>Nombre · +5491122…</button>
     .ctm-alta  → <button class="ctm-alta" id="ctm-alta-btn">+ Dar de alta a "X"</button>
     el resumen → <span id="ctm-cliente-resumen-txt"> con textContent de UNA
                  línea: "Nombre · +tel · domicilio"
     .ctm-dia / .ctm-hora-slot → <button> con data-dia / data-hora, sin hijos

   Así que esta sección estiliza SÓLO eso. El avatar de iniciales, la columna
   del teléfono, el resumen en dos renglones y el chip `+` de la fila de alta
   NO están acá: necesitan que el renderer emita hijos, y eso vive dentro de
   un <script>. Está pedido en el LEEME como punto F, con el marcado exacto.
   ────────────────────────────────────────────────────────────────────────── */

/* 1 · EL BLOQUE NUMERADO. El número vivía en 9,5px dentro de una caja de
   19px, así que el bloque se leía como un cuadrado vacío — un radio button
   sin elegir. El número dice en qué paso estás y al completarse pasa a ✓
   verde; el ✓ va un punto más grande porque una tilde lee más chica que un
   dígito de la misma altura de x. Y el bloque completo enciende su borde. */
.ctm-bloque{padding:14px 16px;border-radius:14px;background:var(--card-bg);
  border:1px solid var(--hairline);transition:border-color 200ms ease}
.ctm-bloque.is-done{border-color:var(--green-border)}
.ctm-bloque-tit{color:var(--cloud-100)}
.ctm-bloque.is-done .ctm-bloque-tit{color:var(--cloud-300)}

/* 2 · LA LISTA DE LA AGENDA. Texto plano, así que el trabajo es el estado:
   hoy la fila no tiene hover ni foco visible, y es una lista para elegir. */
.ctm-sug{border:1px solid transparent;transition:background 160ms,border-color 160ms}
.ctm-sug:hover,.ctm-sug:focus-visible{background:var(--violet-soft);
  border-color:var(--violet-border);outline:none}

/* 3 · LA FILA DE ALTA. Es la salida cuando el cliente no está en la agenda, y
   es mutuamente excluyente con la lista: la lista se dibuja cuando hay
   coincidencias, esta fila sólo cuando se escribió algo y no hay ninguna.
   El fondo era `rgba(234,179,8,.08)` con borde `rgba(234,179,8,.35)` — un
   ámbar a mano que no está en la paleta. Pasa a los tokens del sistema. */
.ctm-alta{background:var(--gold-soft);border-color:rgba(232,184,76,.32);
  border-radius:11px;align-items:center;font-weight:600;
  transition:background 160ms}
.ctm-alta:hover{background:rgba(232,184,76,.26)}

/* 4 · EL RESUMEN, LOS DÍAS Y LAS HORAS. El resumen pasa de gris neutro a
   tinte violeta: es una elección hecha, no un dato más. */
.ctm-cliente-resumen{background:var(--violet-soft);border-color:var(--violet-border);
  border-radius:11px;line-height:1.5}
.ctm-dia,.ctm-hora-slot{font-family:var(--sans);
  transition:background 160ms,border-color 160ms,color 160ms}
.ctm-hora-slot{font-family:var(--mono);font-variant-numeric:tabular-nums}
.ctm-dia:hover,.ctm-hora-slot:hover{background:var(--hover-tint);color:var(--cloud-100)}
.ctm-dia.is-active,.ctm-hora-slot.is-active{background:var(--violet-soft-2);
  border-color:var(--violet-border);color:var(--cloud-100);font-weight:600}
.ctm-horas{align-content:start}

/* 5 · LA NOTA AL PIE. Dice qué va a pasar al guardar — es lo que evita que
   el usuario dude antes de apretar. El marcado la tiene (#ctm-nota). */
.ctm-nota{border-top:1px solid var(--hairline);padding:12px 4px 0;text-wrap:pretty}

/* El cajón es UNO, no dos. El contenido es idéntico en las dos superficies y
   lo único que cambia es el marco: en la mini-app va a pantalla completa y
   los targets a 44px, que los .ctm-* ya traen declarados de entrada. */
html.tg-mode .ctm-bloque{padding:16px}


/* ══ 18 · EL SLOT DE LA CARD ════════════════════════════════════════════════
   La card entera ya se enciende al pasar por encima, pero adentro cada
   renglón es una cosa clickeable —un documento, un turno, una alerta, una
   reseña— y no daba ninguna señal de cuál estás apuntando. En una lista de
   cinco documentos eso es la diferencia entre elegir y adivinar.

   El realce sangra 12px a cada lado con `margin-inline` negativo + el mismo
   `padding-inline`: así el fondo llega al borde interno de la card en vez de
   quedar flotando en la columna de texto, y no hay que tocar el marcado.
   La divisoria de arriba se apaga en la fila apuntada y en la siguiente —si
   no, queda una línea cruzando el bloque resaltado.                        */
/* El sangrado de 12px es para las filas SIN borde: hace que el realce llegue
   al borde interno de la card en vez de flotar en la columna de texto.
   `.ag-item` NO está en el grupo — desde que la lista cronológica pasó a ser
   una card con borde, fondo y radio propios, el margen negativo la empujaba
   12px afuera de la columna de contenido a cada lado. Su realce lo hace su
   propio borde. */
.inicio-ticket-row,.agenda-row,.attn-row,.res-item,.pw-hist-row{
  margin-inline:-12px;padding-inline:12px;border-radius:10px;
  transition:background 160ms ease,box-shadow 160ms ease}
.inicio-ticket-row:hover,.agenda-row:hover,
.attn-row:hover,.res-item:hover,.pw-hist-row:hover{
  background:var(--violet-soft);box-shadow:inset 0 0 0 1px var(--violet-border);
  border-top-color:transparent}
.inicio-ticket-row:hover+*,.agenda-row:hover+*,
.attn-row:hover+*,.res-item:hover+*,.pw-hist-row:hover+*{border-top-color:transparent}
.ag-item{transition:border-color 200ms ease,background 200ms ease,transform 200ms ease}
.ag-item:hover{border-color:var(--violet-border)}

/* Cursor sólo en las filas que de verdad son clickeables en producción:
   `.attn-row` lo es —el renderer le pone `data-tid` para abrir el detalle
   del ticket (panel.html:5426)— y `.res-item` NO: es una clase nueva y
   `#inicio-resenas-list` todavía no tiene renderer atado, así que un
   `pointer` ahí promete algo que no pasa. */
.inicio-ticket-row,.agenda-row,.ag-item,.attn-row{cursor:pointer}
/* Un día que no es hoy se lee, no se opera: la fila no invita al click ni se
   enciende, porque no hay ficha que abrir de ese día. */
.ag-item.is-lectura{cursor:default}
.ag-item.is-lectura:hover{border-color:var(--hairline)}

/* Y el mismo realce en las filas de la tabla de Documentos y la lista de
   Configuración, que ya tenían fondo al pasar pero sin borde ni radio. */
.tickets-table .trow:hover{background:var(--violet-soft);
  box-shadow:inset 0 0 0 1px var(--violet-border)}
.cfg-list-row:hover{box-shadow:inset 0 0 0 1px var(--violet-border)}


/* ══ 19 · LA VISTA PREVIA DEL DOCUMENTO ════════════════════════════════════
   La vista previa NO es un documento nuevo: es la Pieza 4 en pantalla. Ese
   diseño está CERRADO (06/09) y el marcado se levanta tal cual —`.top`,
   `.emisor`, `.tipo`, `.rule`, `.partes`, `.items`, `.tot`, `.mini`,
   `.legal`, `.pie`— con sus decisiones intactas:

   · Un color por documento: violeta el presupuesto («la marca proponiendo»),
     verde el recibo. Va en `.tipo .t` y en la regla de 3pt.
   · El acento es una REGLA, no un bloque: estos papeles se imprimen en láser
     B/N la mitad de las veces y un encabezado macizo sale como una mancha.
   · El total es un bloque de tinta, no un rectángulo de color: es el número
     por el que se paga y tiene que sobrevivir una fotocopia.
   · La marca se levanta del kit —campo + las dos bandas de halo— no se
     dibuja un círculo a mano.
   · Materiales y mano de obra separados con su subtotal.
   · El descargo no se esconde, y el pie dice MI.ASISTENTE · MIASISTENTEAPP.COM.

   Acá sólo cambia la unidad: la Pieza 4 está en pt y mm para A4, esto en px
   para pantalla, con las mismas proporciones y con 9px de piso —el mismo que
   el resto del sistema. Lo único que se agrega es lo que NO va en el papel:
   la tira de `.doc-prev-luego`, que es información para el emprendedor.

   Si la Pieza 4 cambia, esto cambia: es un solo documento con un solo dueño.
   ────────────────────────────────────────────────────────────────────────── */
.doc-prev{display:flex;flex-direction:column;gap:14px;min-width:0}
.doc-prev-nota{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--cloud-500);display:flex;align-items:center;gap:8px}
.doc-prev-hoja{--ink:#1A1714;--ink2:#4A453F;--mute:#6F6862;--hair:#DDD9D4;
  --violet:#6C63FF;--green:#1DB954;--green-ink:#12703A;
  background:#FFFFFF;color:var(--ink);border-radius:14px;padding:24px 26px 22px;
  box-shadow:0 22px 60px rgba(0,0,0,.45);font-family:var(--sans);min-width:0}
.doc-prev-hoja .top{display:flex;align-items:flex-start;gap:20px;padding-bottom:14px}
.doc-prev-hoja .emisor{display:flex;align-items:flex-start;gap:11px;flex:1;min-width:0}
.doc-prev-hoja .emisor>div{display:flex;flex-direction:column;align-items:flex-start;
  min-width:0;flex:1}
.doc-prev-hoja .emisor .n{font-size:18px;font-weight:700;letter-spacing:-.3px;line-height:1.15}
.doc-prev-hoja .emisor .r{font-family:var(--mono);font-size:9px;line-height:1.5;
  letter-spacing:.09em;text-transform:uppercase;color:var(--mute);margin-top:5px;text-wrap:pretty}
.doc-prev-hoja .emisor .d{font-size:11px;line-height:1.55;color:var(--ink2);margin-top:8px}
.doc-prev-hoja .tipo{text-align:right;flex:none}
.doc-prev-hoja .tipo .t{font-family:var(--display);font-size:26px;line-height:1;letter-spacing:.6px}
.doc-prev-hoja .tipo .nro{font-family:var(--mono);font-size:12.5px;color:var(--ink2);
  margin-top:5px;white-space:nowrap;font-variant-numeric:tabular-nums}
.doc-prev-hoja .tipo .f{font-family:var(--mono);font-size:9.5px;letter-spacing:.06em;
  color:var(--mute);margin-top:4px;white-space:nowrap}
.doc-prev-hoja .rule{height:4px;border-radius:3px}
.doc-prev-hoja .partes{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:20px;
  padding:14px 0 15px;border-bottom:1px solid var(--hair)}
.doc-prev-hoja .lbl{font-family:var(--mono);font-size:9px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--mute)}
.doc-prev-hoja .partes .v{font-size:14px;font-weight:700;letter-spacing:-.2px;margin-top:5px}
.doc-prev-hoja .partes .s{font-size:11px;line-height:1.5;color:var(--ink2);margin-top:4px}
.doc-prev-hoja .items{width:100%;border-collapse:collapse;margin-top:14px}
.doc-prev-hoja .items thead th{font-family:var(--mono);font-size:9px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--mute);font-weight:400;text-align:left;
  padding:0 0 9px;border-bottom:1px solid var(--hair)}
.doc-prev-hoja .items thead th.r{text-align:right}
.doc-prev-hoja .grp td{font-family:var(--mono);font-size:9.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--ink);padding:11px 0 4px}
.doc-prev-hoja .items tbody td{font-size:12px;line-height:1.4;color:var(--ink);
  padding:5px 0;border-bottom:1px solid var(--hair);vertical-align:top}
.doc-prev-hoja .items td.q,.doc-prev-hoja .items td.p,.doc-prev-hoja .items td.s{
  font-family:var(--mono);font-size:11.5px;text-align:right;white-space:nowrap;
  font-variant-numeric:tabular-nums}
.doc-prev-hoja .items td.q{width:44px}
.doc-prev-hoja .items td.p{width:68px}
.doc-prev-hoja .items td.s{width:74px}
.doc-prev-hoja .items .sub td{font-family:var(--mono);font-size:10px;color:var(--mute);
  border-bottom:none;padding:6px 0 0}
.doc-prev-hoja .items .sub td.s{color:var(--ink2)}
/* El total: bloque de tinta, borde de 2px, nada de fondo de color. */
.doc-prev-hoja .tot{display:flex;align-items:flex-end;justify-content:space-between;
  gap:20px;margin-top:15px;padding-top:11px;border-top:2px solid var(--ink);flex-wrap:wrap}
.doc-prev-hoja .tot .k{font-family:var(--mono);font-size:10px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--ink2)}
.doc-prev-hoja .tot .v{font-family:var(--mono);font-size:26px;font-weight:500;
  letter-spacing:-.8px;line-height:1;margin-top:6px;font-variant-numeric:tabular-nums}
.doc-prev-hoja .mini{display:flex;flex-direction:column;gap:5px;text-align:right;
  font-family:var(--mono);font-size:10px;color:var(--mute);font-variant-numeric:tabular-nums}
.doc-prev-hoja .mini b{color:var(--ink2);font-weight:500}
.doc-prev-hoja .nota{margin-top:14px;padding:11px 12px;border-radius:8px;font-size:11px;
  line-height:1.55;color:var(--ink2);text-wrap:pretty}
.doc-prev-hoja .nota.v{background:rgba(108,99,255,.09)}
.doc-prev-hoja .nota.g{background:rgba(29,185,84,.10)}
.doc-prev-hoja .nota b{color:var(--ink)}
.doc-prev-hoja .legal{margin-top:15px;padding-top:13px;border-top:1px solid var(--hair);
  font-size:9.5px;line-height:1.5;color:var(--mute);text-wrap:pretty}
.doc-prev-hoja .pie{display:flex;align-items:center;gap:6px;margin-top:8px;
  font-family:var(--mono);font-size:9px;letter-spacing:.08em;color:var(--mute)}

/* Qué pasa cuando lo mandás. Esto NO va en el papel: es información para el
   emprendedor, así que vive en el escenario oscuro, no en el documento. */
.doc-prev-luego{display:flex;flex-direction:column;gap:7px;padding:14px 16px;
  border-radius:14px;border:1px solid var(--hairline);background:var(--card-bg)}
.doc-prev-luego .k{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--violet-text)}
.doc-prev-luego ol{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;
  gap:6px;counter-reset:p}
.doc-prev-luego li{position:relative;padding-left:22px;font-size:12.5px;line-height:1.5;
  color:var(--cloud-300);text-wrap:pretty}
.doc-prev-luego li::before{counter-increment:p;content:counter(p);position:absolute;left:0;
  top:1px;width:15px;height:15px;border-radius:5px;display:grid;place-items:center;
  background:var(--violet-soft-2);border:1px solid var(--violet-border);
  font-family:var(--mono);font-size:9px;color:var(--cloud-100)}

/* ══ 20 · FILTROS ══════════════════════════════════════════════════════════
   Las filas que el filtro descarta se ocultan; el contador de cada píldora es
   el número real de filas que va a mostrar.                                */
[data-filtrado="no"]{display:none}
:where(.tickets-table,.ag-list,.clientes-grid,.res-grid,.cfg-grid) [data-filtrado="no"],
.tickets-table .trow[data-filtrado="no"],
.clientes-grid .client-card[data-filtrado="no"],
.res-grid .res-card[data-filtrado="no"],
.ag-list .ag-item[data-filtrado="no"]{display:none}
.filtro-vacio{padding:26px 12px;text-align:center;font-size:13px;color:var(--cloud-500)}


/* ══ 21 · LAS ACCIONES DE ESTADO ═══════════════════════════════════════════
   El mismo botón vive en tres lugares —la fila de la agenda, el stepper del
   trabajo en curso y el cajón de detalle— y es el mismo `data-accion`, no
   tres flujos. Hoy los tres traen todo en `style=` inline, así que hasta que
   Dev los suelte (punto A del LEEME) estas reglas no aplican; las dejo
   escritas para que el cambio sea sacar atributos.

   Tres estados, y el tercero es el que importa: cuando la acción ya se
   aplicó, el botón no desaparece —el emprendedor tiene que poder ver qué
   hizo— pasa a ✓ verde y apagado.                                          */
.ag-accion{font-family:var(--sans);font-weight:600;font-size:12px;min-height:34px;
  padding:0 12px;border-radius:8px;border:1px solid var(--graphite-700);
  background:transparent;color:var(--cloud-100);cursor:pointer;white-space:nowrap;
  transition:background 160ms,border-color 160ms,color 160ms}
.ag-accion:hover{background:var(--violet-soft);border-color:var(--violet-border)}
/* La que manda un mensaje al cliente se anuncia: no es lo mismo cambiar un
   estado interno que escribirle a alguien. */
.ag-accion[data-manda-wa="1"]{border-color:var(--green-border);color:var(--green-live)}
.ag-accion[data-manda-wa="1"]:hover{background:var(--green-soft)}
.ag-accion[data-manda-wa="1"]::before{content:'';width:5px;height:5px;flex:none;
  border-radius:50%;background:currentColor;display:inline-block;margin-right:7px;
  vertical-align:1px}
.ag-accion[data-ya-aplicado="1"]{border-color:var(--green-border);
  background:var(--green-soft);color:var(--green-live);cursor:default}
.ag-accion[data-ya-aplicado="1"]::before{content:'✓ ';width:auto;height:auto;
  background:none;border-radius:0;margin-right:2px}
.ag-acciones{display:flex;gap:7px;flex-wrap:wrap;align-items:center}
.ag-reag{padding:0}
.ag-reag-btn{font-family:var(--sans);font-weight:600;font-size:12px;min-height:34px;
  padding:0 12px;border-radius:8px;border:1px solid var(--graphite-700);
  background:transparent;color:var(--cloud-300);cursor:pointer}
.ag-reag-form{gap:7px}
.ag-reag-motivos{border-radius:10px;overflow:hidden;border:1px solid var(--graphite-700)}
.ag-reag-send{font-family:var(--sans);font-weight:600;font-size:12px;min-height:34px;
  padding:0 14px;border-radius:8px;border:0;background:var(--violet-700);color:#fff;cursor:pointer}
.ag-reag-send:hover{background:var(--violet-800)}
.ag-reag-fecha,.ag-reag-hora{font-family:var(--mono);font-size:12px;min-height:34px;
  padding:0 10px;border-radius:8px;border:1px solid var(--graphite-700);
  background:var(--graphite-950);color:var(--cloud-100)}
.ag-reag-msg{font-size:11.5px;color:var(--cloud-500)}

/* ══ 22 · CONFIGURACIÓN · lista ↔ card ═════════════════════════════════════
   No es un cajón: es un cambio de vista. En la mini-app manda «una card por
   pantalla», así que la lista se oculta y aparece la card elegida con el
   botón de volver. En escritorio las cards se ven todas juntas y la lista y
   el botón no hacen falta.                                                 */
.view-configuracion[data-cfg-abierta] #cfg-lista{display:none}
.view-configuracion[data-cfg-abierta] .negocio-resumen{display:none}
.view-configuracion:not([data-cfg-abierta]) #cfg-back-btn{display:none}
.view-configuracion[data-cfg-abierta] .cfg-card[data-cfg]{display:none}
.view-configuracion[data-cfg-abierta] .cfg-card[data-cfg].is-abierta{display:flex}
.cfg-card{display:flex;flex-direction:column;gap:0}
/* El aviso ámbar y el coral del modal de la ficha. */
.aviso-amb,.aviso-cor{font-size:12px;line-height:1.5;border-radius:10px;padding:9px 11px;
  margin-top:6px;text-wrap:pretty}
.aviso-amb{color:var(--gold);background:var(--gold-soft);border:1px solid rgba(232,184,76,.32)}
.aviso-cor{color:var(--coral);background:var(--coral-soft);border:1px solid var(--coral-border)}
.aviso-cor b{color:var(--coral)}


/* ══ 23 · EL CALENDARIO DEL MES ════════════════════════════════════════════
   Producción ya tiene `.cal-dow` y `.cal-cnt` (panel.html:1583, 1588). Faltaba
   la grilla y la celda. Cada número es la cantidad de eventos de ese día, en
   el idioma del rubro — no «tickets».                                      */
.cal{display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:6px}
.cal-dow{font-family:var(--mono);font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--cloud-500);text-align:center;padding:2px 0 6px}
.cal-vacio{min-height:62px}
.cal-dia{min-height:62px;padding:7px 8px;border-radius:11px;border:1px solid var(--hairline);
  background:var(--graphite-950);display:flex;flex-direction:column;gap:5px;cursor:pointer;
  transition:background 160ms,border-color 160ms}
.cal-dia:hover{background:var(--violet-soft);border-color:var(--violet-border)}
.cal-dia.is-hoy{border-color:var(--violet-border);background:var(--violet-soft-2)}
.cal-n{font-family:var(--mono);font-size:11.5px;color:var(--cloud-300);font-variant-numeric:tabular-nums}
.cal-dia.is-hoy .cal-n{color:var(--cloud-100);font-weight:600}
.cal-cnt{font-family:var(--mono);font-size:10px;color:var(--cloud-100);background:var(--violet-soft-2);
  border:1px solid var(--violet-border);border-radius:6px;padding:1px 6px;align-self:flex-start}
@media (max-width:640px){.cal-dia{min-height:48px;padding:5px 6px}}


/* ══ 24 · FILAS DE INTERRUPTOR ═════════════════════════════════════════════
   Configuración es casi toda «esto está prendido o apagado». La fila dice qué
   hace el interruptor, no sólo cómo se llama: el emprendedor está decidiendo
   qué va a hacer Mia en su nombre.                                         */
.cfg-sw{display:flex;align-items:flex-start;gap:12px;padding:12px 0;
  border-top:1px solid var(--hairline)}
.cfg-sw:first-of-type{border-top:0}
.cfg-sw>span{flex:1;min-width:0}
.cfg-sw .t{display:block;font-size:13.5px;font-weight:600;color:var(--cloud-100)}
.cfg-sw .d{display:block;font-size:12px;line-height:1.45;color:var(--cloud-500);
  margin-top:3px;text-wrap:pretty}
.cfg-sw input{flex:none;width:18px;height:18px;margin-top:2px;accent-color:var(--violet-600)}
/* Lista de precios: el importe alineado a la derecha y tabular. */
.cfg-precio{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:4px 12px;
  align-items:baseline;padding:10px 0;border-top:1px solid var(--hairline)}
.cfg-precio:first-of-type{border-top:0}
.cfg-precio .t{font-size:13.5px;color:var(--cloud-100)}
.cfg-precio .m{font-family:var(--mono);font-size:12.5px;color:var(--cloud-100);
  font-variant-numeric:tabular-nums}
.cfg-precio .d{grid-column:1;font-size:11.5px;color:var(--cloud-500)}
.cfg-vacio{padding:26px 16px;text-align:center;font-size:13px;line-height:1.5;
  color:var(--cloud-500);text-wrap:pretty}


/* ══ 25 · LA SEMANA Y EL MES ═══════════════════════════════════════════════
   La vista del día sirve para OPERAR —cambiar estados, avisar, cobrar— y por
   eso es una card por trabajo con sus acciones. La semana y el mes no son eso:
   son para DECIDIR. Dónde tengo lugar, qué día está cargado, cuánto entra.
   Así que su unidad no es el trabajo, es el DÍA: cada día trae su carga contra
   la capacidad configurada, su plata y sus trabajos en una línea.           */

/* ── La semana ─────────────────────────────────────────────────────────── */
.sem-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:12px;align-items:start}
.sem-dia{background:var(--card-bg);border:1px solid var(--hairline);border-radius:16px;
  padding:14px 15px;display:flex;flex-direction:column;gap:10px;min-width:0;
  transition:border-color 200ms ease,transform 200ms ease}
.sem-dia:hover{border-color:var(--violet-border);transform:translateY(-2px);cursor:pointer}
.sem-dia.is-hoy{border-color:var(--violet-border);
  background:linear-gradient(158deg,rgba(108,99,255,.14),rgba(108,99,255,.03) 52%,transparent),var(--card-bg)}
.sem-dia.is-libre{opacity:.72}
.sem-dia.is-libre:hover{opacity:1}
.sem-cab{display:flex;align-items:baseline;gap:8px}
.sem-cab .d{font-family:var(--mono);font-size:9.5px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--cloud-500)}
.sem-cab .n{font-family:var(--display);font-size:26px;line-height:1;letter-spacing:.4px;
  color:var(--cloud-100);font-variant-numeric:tabular-nums}
.sem-cab .hoy{margin-left:auto;font-family:var(--mono);font-size:8.5px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--violet-text);background:var(--violet-soft-2);
  border:1px solid var(--violet-border);border-radius:5px;padding:2px 6px;flex:none}
/* La carga del día contra la capacidad configurada: es lo que contesta
   «¿tengo lugar?» sin abrir el día. */
.sem-carga{display:flex;flex-direction:column;gap:5px}
.sem-carga .t{display:flex;align-items:baseline;gap:6px;font-family:var(--mono);
  font-size:10px;letter-spacing:.06em;color:var(--cloud-500)}
.sem-carga .t b{color:var(--cloud-100);font-weight:500}
.sem-carga .t span{margin-left:auto;color:var(--cloud-300)}
.sem-barra{height:5px;border-radius:4px;background:var(--graphite-700);overflow:hidden;display:flex}
.sem-barra i{display:block;height:100%;background:var(--violet-600)}
.sem-barra i.lleno{background:var(--gold)}
.sem-barra i.pasado{background:var(--green-live)}
.sem-lista{display:flex;flex-direction:column;gap:1px;margin-top:1px}
.sem-fila{display:grid;grid-template-columns:auto minmax(0,1fr) auto;gap:8px;
  align-items:center;padding:6px 0;border-top:1px solid var(--hairline)}
.sem-fila:first-child{border-top:0}
.sem-fila .h{font-family:var(--mono);font-size:10.5px;color:var(--cloud-300);
  font-variant-numeric:tabular-nums}
.sem-fila .c{font-size:12.5px;color:var(--cloud-100);min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.sem-fila .p{width:7px;height:7px;border-radius:50%;flex:none}
.sem-libre{font-size:12px;line-height:1.5;color:var(--cloud-500);text-wrap:pretty}
.sem-plata{margin-top:2px;padding-top:9px;border-top:1px solid var(--hairline);
  display:flex;align-items:baseline;gap:8px}
.sem-plata .k{font-family:var(--mono);font-size:9px;letter-spacing:.13em;
  text-transform:uppercase;color:var(--cloud-500)}
.sem-plata .v{margin-left:auto;font-family:var(--mono);font-size:12.5px;color:var(--cloud-100);
  font-variant-numeric:tabular-nums}

/* ── El mes ────────────────────────────────────────────────────────────── */
/* La celda deja de ser un número con una pastilla: trae la carga del día como
   barra, así el mes se lee de un vistazo — dónde hay lugar y dónde no. */
.cal-dia{justify-content:space-between}
.cal-carga{height:4px;border-radius:3px;background:var(--graphite-700);overflow:hidden}
.cal-carga i{display:block;height:100%;background:var(--violet-600)}
.cal-carga i.lleno{background:var(--gold)}
.cal-dia.is-lleno{border-color:rgba(232,184,76,.32)}
.cal-plata{font-family:var(--mono);font-size:9px;color:var(--cloud-500);
  font-variant-numeric:tabular-nums}
/* La tira de resumen del mes, arriba del calendario. */
.mes-tira{margin-bottom:12px}
.cal-leyenda{display:flex;gap:16px;flex-wrap:wrap;margin-top:12px;padding-top:12px;
  border-top:1px solid var(--hairline);font-family:var(--mono);font-size:9.5px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--cloud-500)}
.cal-leyenda span{display:flex;align-items:center;gap:6px}
.cal-leyenda i{width:9px;height:4px;border-radius:3px;display:block}

/* ══ 26 · LA CARD DEL CLIENTE ══════════════════════════════════════════════
   Un cliente no es una fila de datos: es alguien que vuelve o no vuelve. La
   card ordena por eso — quién es, qué tan confiable, cuánto vale, cuándo lo
   ves — y termina en las dos acciones que se hacen desde acá.              */
.client-card{display:flex;flex-direction:column;gap:12px}
.client-rank{font-family:var(--mono);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--violet-text)}
.client-name .client-tag{flex:none}
/* El semáforo de confianza: verde cumple, ámbar algo pendiente, coral canceló.
   Es derivado y no se puede editar — si se pudiera, no serviría para avisar. */
.client-status{font-size:11.5px}
.client-status.amb{color:var(--gold)}
.client-status.cor{color:var(--coral)}
/* La participación en tu facturación. Contesta «¿cuánto me importa este
   cliente?» mejor que el total suelto. */
.client-share{display:flex;flex-direction:column;gap:5px}
.client-share .t{display:flex;align-items:baseline;font-family:var(--mono);font-size:9px;
  letter-spacing:.13em;text-transform:uppercase;color:var(--cloud-500)}
.client-share .t span{margin-left:auto;color:var(--cloud-300)}
.client-share .b{height:5px;border-radius:4px;background:var(--graphite-700);overflow:hidden}
.client-share .b i{display:block;height:100%;background:var(--violet-600)}
.client-prox{display:flex;align-items:center;gap:7px;padding:8px 10px;border-radius:10px;
  background:var(--violet-soft);border:1px solid var(--violet-border);
  font-family:var(--mono);font-size:10.5px;letter-spacing:.04em;color:var(--cloud-100)}
.client-prox.vacio{background:none;border-color:transparent;color:var(--cloud-500);padding:0 2px}
.client-acc{display:flex;gap:8px;margin-top:auto;padding-top:12px;
  border-top:1px solid var(--hairline)}
.client-acc>*{flex:1}


/* ══ 27 · EL AVISO ═════════════════════════════════════════════════════════
   `#pw-toast` ya existe en producción (panel.html:1625) y es lo que el panel
   usa para confirmar una acción. Acá sólo se le pone el idioma nuevo.       */
#pw-toast{position:fixed;top:56px;right:24px;z-index:200;min-width:260px;max-width:400px;
  padding:13px 18px;border-radius:14px;display:none;pointer-events:none;
  font-family:var(--sans);font-size:13.5px;font-weight:600;line-height:1.45;
  color:var(--cloud-100);background:var(--graphite-900);
  border:1px solid var(--violet-border);box-shadow:0 18px 44px rgba(0,0,0,.45)}
#pw-toast.tono-ok{border-color:var(--green-border)}


/* ══ 27 · EL BANNER DE TELEGRAM ════════════════════════════════════════════
   Es la única cosa del panel que le pide algo al emprendedor para que el
   producto funcione: sin Telegram vinculado, Mia no le puede avisar nada. Así
   que no es un aviso más — va arriba de todo, dentro de `.main`, y se va solo
   cuando ya está vinculado.

   En producción el bloque está insertado FUERA de `.main` (panel.html:4636),
   así que queda arriba del header y pisa la barra. La regla lo reubica sin
   tocar el marcado: `order:-1` dentro del flujo de la vista activa.
   Si Dev lo mueve adentro de `.main`, esta regla sigue siendo correcta.    */
#banner-telegram,.tg-banner{display:flex;align-items:center;gap:14px;
  padding:14px 18px;margin:0 0 14px;border-radius:16px;
  background:linear-gradient(158deg,rgba(108,99,255,.16),rgba(108,99,255,.04) 55%,transparent),var(--card-bg);
  border:1px solid var(--violet-border);order:-1;flex-wrap:wrap}
#banner-telegram[hidden],.tg-banner[hidden]{display:none}
.tg-banner-ic{width:38px;height:38px;flex:none;border-radius:12px;display:grid;
  place-items:center;background:var(--violet-soft-2);border:1px solid var(--violet-border);
  color:var(--violet-text);font-size:17px}
.tg-banner-tx{flex:1;min-width:200px}
.tg-banner-tx b{display:block;font-size:14px;font-weight:600;color:var(--cloud-100)}
.tg-banner-tx span{display:block;font-size:12.5px;line-height:1.5;color:var(--cloud-500);
  margin-top:3px;text-wrap:pretty}
.tg-banner .btn-primary,.tg-banner .btn-outline{flex:none}
/* Vinculado: el banner se convierte en una línea de estado y deja de pedir
   nada. No desaparece del todo porque saber que está conectado es el dato. */
.tg-banner.is-ok{background:var(--card-bg);border-color:var(--green-border)}
.tg-banner.is-ok .tg-banner-ic{background:var(--green-soft);
  border-color:var(--green-border);color:var(--green-live)}

/* ══ 28 · TOAST Y ESTADOS DE CARGA ═════════════════════════════════════════
   El toast es la única confirmación del panel: cuando Mia manda algo en tu
   nombre, esto es lo que te dice que salió. Abajo a la derecha, fuera del
   camino del puntero, y se va solo.                                        */
#pw-toast{position:fixed;right:22px;bottom:22px;z-index:120;max-width:360px;
  padding:13px 16px;border-radius:14px;font-size:13px;line-height:1.45;
  color:var(--cloud-100);background:color-mix(in oklab,var(--graphite-900) 94%,transparent);
  border:1px solid var(--violet-border);box-shadow:0 18px 44px rgba(0,0,0,.42);
  backdrop-filter:blur(8px);text-wrap:pretty;
  opacity:0;transform:translateY(10px);pointer-events:none;
  transition:opacity 240ms ease,transform 240ms cubic-bezier(.4,0,.2,1)}
#pw-toast.is-on{opacity:1;transform:none}
/* El tono dice de qué habla: verde salió, ámbar atención, coral no se pudo. */
#pw-toast.tono-ok{border-color:var(--green-border)}
#pw-toast.tono-amb{border-color:rgba(232,184,76,.32)}
#pw-toast.tono-cor{border-color:var(--coral-border)}
#pw-toast::before{content:'';position:absolute;left:0;top:14px;bottom:14px;width:2px;
  border-radius:2px;background:var(--violet-600)}
#pw-toast.tono-ok::before{background:var(--green-live)}
#pw-toast.tono-amb::before{background:var(--gold)}
#pw-toast.tono-cor::before{background:var(--coral)}
@media (max-width:560px){#pw-toast{left:14px;right:14px;bottom:14px;max-width:none}}

/* El esqueleto de carga: la trama del sistema barriendo, no un gris plano.
   Es el estado que más se ve —el panel recarga cada vez que se abre— y hoy
   es un rectángulo muerto. */
.skel{display:block;border-radius:8px;min-height:14px;
  background:linear-gradient(90deg,var(--graphite-800) 0%,rgba(108,99,255,.16) 50%,var(--graphite-800) 100%);
  background-size:200% 100%;animation:pw-skel 1.4s ease-in-out infinite}
.skel--cifra{height:34px;width:64%;border-radius:10px}
.skel--linea{height:12px;margin-top:8px}
.skel--linea.corta{width:52%}
@keyframes pw-skel{0%{background-position:200% 0}100%{background-position:-200% 0}}
@media (prefers-reduced-motion:reduce){
  .skel{animation:none}
  #pw-toast{transition:none}
}
