
  @page { size: A4; margin: 0; }
  /* ===========================================================================
     TOKENS DEL TEMA — FASE 1 (03/09/2026). Una sola definición de cada color de la
     interfaz; las tres paletas históricas (--ui*, --a-*, --d-*) las CONSUMEN y ya no
     declaran hex propios. El oscuro es byte a byte el de siempre (verificado volcando
     los colores computados de ~4.900 elementos antes y después). El claro vive en
     `html[data-theme="claro"]` y sólo cambia estos tokens.
     ⚠️ COBERTURA PARCIAL, A PROPÓSITO: quedan hex literales sueltos en las reglas
     (medidos por `test/tema.test.mjs`, que no deja que el número crezca). Por eso el
     tema claro NO se ofrece en la interfaz todavía: `Tema` lo aplica sólo si se lo
     pide a mano, y el sistema no decide hasta que la cobertura sea completa.
     🔴 Fuera del alcance: las páginas del PDF (--cream/--ink/…), portal.html y
     stock.html tienen su propia paleta y no cambian con el tema. */
  :root{
    --t-scheme:dark;
    --t-bg:#131316; --t-surface:#1b1c20; --t-surface-2:#26272d; --t-input:#101115;
    --t-line:#2b2c32; --t-line-2:#43444c;
    --t-ink:#ededef; --t-muted:#8e909a; --t-dim:#6b6d76;
    --t-accent:#8f7df0; --t-accent-deep:#6a5bd8; --t-focus:var(--t-accent);
    --t-overlay:rgba(0,0,0,.55); --t-sel:rgba(143,125,240,.16); --t-hover:rgba(255,255,255,.06);
    --t-pressed:rgba(255,255,255,.1); --t-disabled:rgba(237,237,239,.38);
    --t-ok:#1ed48c; --t-warn:#ff9500; --t-info:#3f95ff; --t-err:#ff5c42; --t-teal:#4ecdc4; --t-reunion:#f06ac9; --t-personal:#b48cff;
    --t-chart-ok:#00a05a; --t-chart-warn:#a35c00; --t-chart-info:#0064d7;
    --t-panel-bg:#0d0f18; --t-panel-surface:#1a1d2b; --t-panel-surface-2:#14161f;
    --t-panel-line:rgba(255,255,255,0.06); --t-panel-line-2:rgba(255,255,255,0.1);
    --t-panel-ink:#f5f6fa; --t-panel-muted:#8992a8; --t-panel-dim:#c7cbdb; --t-panel-accent:#9a70ff;
    --t-agenda-bg:#141518;
    /* superficie intermedia (módulos, hojas), botón principal, texto sobre acento,
       y la pantalla de entrada (el logo con su aura). */
    --t-surface-1:#17181c; --t-btn-primary-bg:#fff; --t-btn-primary-hover:#e7e8ec; --t-btn-primary-ink:#111216; --t-on-accent:#0f1016;
    --t-intro-bg:#08080a; --t-intro-bg-2:#17181c; --t-logo-filter:none;
    /* Colores que se conservan por SIGNIFICADO (identidad de las pestañas del
       formulario y de las páginas del carrusel), iguales en los dos temas. */
    --t-tab-ev:#ef7d5f; --t-tab-fmt:#5ac8dc; --t-tab-val:#53c98d; --t-tab-eq:#e9b14c; --t-tab-dia:#b48cff;
  }
  html[data-theme="claro"]{
    --t-scheme:light;
    --t-bg:#f4f5f9; --t-surface:#ffffff; --t-surface-2:#eceef4; --t-input:#ffffff;
    --t-line:#d9dce6; --t-line-2:#b9bece;
    --t-ink:#17181d; --t-muted:#5b6170; --t-dim:#6b7180;
    --t-accent:#5f45d8; --t-accent-deep:#4d34c2;
    --t-overlay:rgba(20,22,31,.35); --t-sel:rgba(95,69,216,.14); --t-hover:rgba(20,22,31,.05);
    --t-pressed:rgba(20,22,31,.09); --t-disabled:rgba(23,24,29,.38);
    --t-ok:#0e7a4f; --t-warn:#9c5300; --t-info:#1b5fcf; --t-err:#c22f19; --t-teal:#0b7a73; --t-reunion:#a8248c; --t-personal:#6b3fc9;
    --t-chart-ok:#00804a; --t-chart-warn:#8a4d00; --t-chart-info:#0055b8;
    --t-panel-bg:#eef0f6; --t-panel-surface:#ffffff; --t-panel-surface-2:#f5f6fa;
    --t-panel-line:rgba(20,22,31,0.08); --t-panel-line-2:rgba(20,22,31,0.14);
    --t-panel-ink:#14161f; --t-panel-muted:#586074; --t-panel-dim:#454b5c; --t-panel-accent:#5f45d8;
    --t-agenda-bg:#f4f5f9;
    --t-surface-1:#f9fafc; --t-btn-primary-bg:#17181d; --t-btn-primary-hover:#2c2d36; --t-btn-primary-ink:#ffffff; --t-on-accent:#ffffff;
    --t-intro-bg:#eef0f6; --t-intro-bg-2:#ffffff; --t-logo-filter:invert(1);
  }
  /* 🔴 `color-scheme` TAMBIÉN EN LA RAÍZ (07/09/2026). Medido en el simulador (iOS
     26.1, PWA instalada): la píldora ‹ › ✓ del teclado sigue el `color-scheme` del
     campo enfocado, y las TECLAS siguen la apariencia del SISTEMA (ningún
     color-scheme las cambia en una web app). Con la raíz siguiendo al tema, todo lo
     nativo que sí lo respeta (píldora, pickers, scrollbars, selects) va con la app. */
  html{ color-scheme:var(--t-scheme); --sat:env(safe-area-inset-top, 0px); }
  :root{
    --cream:#F4F1EC; --ink:#161514; --gray:#9b958a; --muted:#b3ada1;
    --hair:#ddd8cd; --panel:#DDD8CD; --badge:#5b574e; --badgeb:#c9c3b6;
    --uibg:var(--t-bg); --uicard:var(--t-surface); --uiline:var(--t-line); --uitext:var(--t-ink); --uimut:var(--t-muted); --acc:var(--t-accent);
    --c-ev:var(--t-tab-ev); --c-fmt:var(--t-tab-fmt); --c-val:var(--t-tab-val); --c-eq:var(--t-tab-eq); --c-dia:var(--t-tab-dia);
  }
  *{ box-sizing:border-box; margin:0; padding:0; }

  /* 🔴 Sin zoom por doble toque, en NINGUNA parte de la app.
     `touch-action:manipulation` le saca al navegador el doble-tap-to-zoom (y de paso
     el retardo de ~300ms que esperaba el segundo toque, así los botones responden al
     toque). Va en html/body y baja a todo el árbol solo: el navegador intersecta el
     valor del elemento tocado con el de sus ancestros, así que un hijo que declara
     `touch-action:none` (por ejemplo #introOverlay) sigue con `none`.
     Acá se saca SOLO el doble toque. El PINCH lo saca un script del index (los
     eventos `gesturestart`/`gesturechange` de iOS, 14/09/2026: Tobi pidió que la app
     no tenga zoom, solo los PDF), con una única excepción: la vista previa del PDF
     (`.stage`). iOS ignora `user-scalable=no` en el navegador, así que el meta
     viewport no es el lugar para esto. Si agregás un documento nuevo (otro iframe
     con `srcdoc`), copiale esta regla: el touch-action no cruza el borde del iframe. */
  html, body{ touch-action:manipulation; }

  /* ===========================================================================
     SISTEMA DE INTERACCION — una sola definicion de "esto responde al dedo".
     ===========================================================================
     🔴 TODO VA CON `:where()`, QUE TIENE ESPECIFICIDAD CERO. Eso es lo que deja
     que cualquier regla de pantalla que ya exista le gane sin pelear, y que esta
     capa se pueda sacar sin tocar nada mas. Es una capa de RESPUESTA, no un
     rediseño: no cambia un color, un tamaño ni una posicion en reposo.

     🔴 `html.puntero` LA PONE EL JS y solo cuando el aparato tiene un mouse de
     verdad (`hover:hover` + `pointer:fine`). Las 67 reglas `:hover` de este
     archivo estan acotadas a esa clase, porque EN TACTIL EL HOVER SE QUEDA
     PEGADO DESPUES DE TOCAR: tocabas una tarjeta, se iba a otra pantalla, y al
     volver seguia resaltada como si el dedo estuviera encima. El proyecto ya lo
     sabia — el hover del #navbar vive adentro del @media de escritorio con ese
     mismo comentario — pero era el unico de los 67 que lo tenia en cuenta.
     ⚠️ Regla `:hover` nueva -> va con el prefijo `:where(html.puntero)`. */
  :root{
    --ix-ms:150ms;                                   /* dentro de los 120-180 pedidos */
    --ix-curva:cubic-bezier(.32,.72,0,1);            /* la misma del resto de la app */
  }

  /* El anillo de foco de teclado, UNO para toda la app. Cada superficie tiene su
     propio acento (--d-* el panel, --a-* la agenda, --acc el presupuestador), asi
     que se pregunta en ese orden y el anillo sale del color de donde estas. */
  :where(button,[role="button"],a[href],summary,select,[tabindex]:not([tabindex="-1"])):focus-visible{
    outline:2px solid var(--d-acc, var(--a-acc, var(--acc)));
    outline-offset:2px;
  }

  /* 🔴 RESPUESTA AL PRESIONAR. La lista es EXPLICITA y no un `*`: un press global
     tocaria tambien celdas y textos que no hacen nada, que es justo lo que el
     pedido prohibe ("si algo parece interactivo, debe ejecutar una accion util").
     Los botones se hunden 1px —el mismo gesto que .btn ya tenia— y las filas y
     tarjetas se achican un pelo. `transform` no re-fluye nada: el contenido de al
     lado no se mueve. */
  @media (prefers-reduced-motion:no-preference){
    :where(button,[role="button"],.pk-d,.pk-h,.ag-act,.ag-st,.dbtn,.dchip,.hbtn,.hchip){
      transition:background-color var(--ix-ms) var(--ix-curva),
                 border-color var(--ix-ms) var(--ix-curva),
                 color var(--ix-ms) var(--ix-curva),
                 opacity var(--ix-ms) var(--ix-curva),
                 transform var(--ix-ms) var(--ix-curva);
    }
    :where(button,[role="button"]):not([disabled]):not([aria-disabled="true"]):active{
      transform:translateY(1px);
    }
    :where(.ag-item,.ag-cell.has,.dev,.hev,.dd-day,.ag-folder-hd):active{
      transform:scale(.99);
    }
  }

  /* ⚠️ El realce gris de iOS al tocar se saca SOLO porque arriba se da uno propio.
     Sacarlo sin reemplazarlo dejaria toques sin ninguna respuesta, que es peor que
     el realce feo. */
  :where(button,[role="button"],a[href],.ag-item,.ag-cell,.dev,.hev,.dd-day){
    -webkit-tap-highlight-color:transparent;
  }

  /* Deshabilitado: se ve distinto Y no ejecuta. `aria-disabled` va incluido porque
     hay controles que no son <button> y no aceptan el atributo `disabled`. */
  :where([disabled],[aria-disabled="true"]){ cursor:default; }
  :where([aria-disabled="true"]){ opacity:.5; }

  body{ font-family:'Helvetica Neue',Helvetica,'Liberation Sans',Arial,sans-serif; color:var(--ink); background:var(--t-surface-2); }
  .mono{ font-family:'SFMono-Regular',Menlo,'Liberation Mono','DejaVu Sans Mono',monospace; }

  /* ===================== REPARTO INTERNO (solo pantalla) =====================
     Compacto a propósito: Valores ya es la pestaña más larga y esto es un resumen
     de tres renglones, no una planilla. Nunca sale en el PDF — vive dentro de
     .controls, que el renderer no mira. */
  .repint{ background:var(--t-surface); border:1px solid var(--t-line); border-radius:11px;
    padding:12px 14px; margin:0 0 12px; color:var(--uitext); }
  .repint .rep-t{ font-size:9.5px; letter-spacing:1.8px; text-transform:uppercase;
    color:var(--uimut); font-weight:700; margin-bottom:9px; }
  .repint .rep-fila{ display:flex; justify-content:space-between; align-items:baseline;
    gap:12px; padding:4px 0; font-size:12.5px; }
  .repint .rep-fila b{ font-family:'SFMono-Regular',Menlo,'Liberation Mono',monospace;
    font-variant-numeric:tabular-nums; font-weight:700; white-space:nowrap; }
  /* La línea que importa: separada por un filete y un poco más grande. */
  .repint .rep-queda{ border-top:1px solid var(--t-line); margin-top:6px; padding-top:9px; font-size:13.5px; }
  .repint .rep-queda b{ font-size:16px; color:var(--c-val); }
  .repint .rep-pc{ font-size:11px; color:var(--uimut); margin-top:3px; }
  .repint .rep-aviso:not(:empty){ margin-top:8px; font-size:11.5px; color:var(--t-err);
    background:color-mix(in srgb, var(--t-err) 9%, transparent); border:1px solid color-mix(in srgb, var(--t-err) 30%, transparent);
    border-radius:8px; padding:7px 9px; }
  /* 🔴 En rojo SOLO el número que se fue a negativo, no la caja entera: teñir todo
     el bloque haría ilegibles los otros dos, que están bien. */
  .repint.mal .rep-queda b{ color:var(--t-err); }
  /* La ayuda debajo de un campo. Apagada y chica: explica, no compite. */
  .fld .fhint{ display:block; margin-top:5px; font-size:10.5px; line-height:1.45; color:var(--uimut); }
  .fld .fhint[hidden]{ display:none; }

  /* ===================== CONTROL PANEL (solo pantalla) ===================== */
  /* `top` sale de --nav-top: en escritorio la barra está arriba y esta columna es
     sticky, así que sin esto se le mete debajo. En mobile resuelve a 0. */
  .controls{ position:sticky; top:var(--nav-top, 0px); z-index:50; background:color-mix(in srgb, var(--t-bg) 86%, transparent); color:var(--uitext);
    border-bottom:1px solid var(--t-line); box-shadow:0 22px 46px -30px rgba(0,0,0,.95);
    font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;
    backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px); }
  /* --- app bar --- */
  .cp-bar{ display:flex; align-items:center; gap:26px; padding:14px 24px 13px; flex-wrap:wrap;
    background:linear-gradient(180deg,color-mix(in srgb, var(--t-bg) 70%, transparent),color-mix(in srgb, var(--t-bg) 50%, transparent)); border-bottom:1px solid var(--t-line); }
  .cp-brand{ min-width:230px; }
  /* "◧ Panel" vive en la barra de arriba, no en la toolbar de abajo: es navegación,
     tiene que estar a la vista. El gap de .cp-bar es 26px, acá se achica. */
  .cp-bar > #btnDash{ flex:none; margin-right:-14px; }
  .controls h1{ font-size:14.5px; letter-spacing:.4px; font-weight:700; }
  .controls h1 span{ color:var(--uimut); font-weight:400; }
  .cp-chips{ display:flex; gap:8px; margin-top:9px; }
  .cp-chips .chip{ display:flex; align-items:center; gap:7px; background:var(--t-surface); border:1px solid var(--t-line);
    border-radius:999px; padding:5px 12px; }
  .cp-chips .chip label{ font-size:9px; letter-spacing:1.6px; text-transform:uppercase; color:var(--uimut); }
  /* 🔴 EL ANCHO VA EN `ch` Y NO EN px (04/09/2026). Con 88px el N° entraba justo y
     la fecha "19 / 09 / 2026" (14 caracteres) medía 97px: se leía "19 / 09 / 202" en
     escritorio y "19 / 09 / 2" en el celu. En `ch` el ancho sigue a la fuente mono,
     que es la que escribe los dos valores: 12ch para el folio (`2026-0904-01`) y
     14ch para la fecha con sus espacios. */
  .cp-chips .chip input{ background:transparent; border:0; color:var(--uitext); outline:none; padding:0; width:12.5ch;
    font-family:'SFMono-Regular',Menlo,'Liberation Mono',monospace; font-size:11.5px; }
  .cp-chips .chip input#c_validez{ width:14.5ch; }
  .cp-spacer{ flex:1; }
  .cp-total{ text-align:right; }
  .cp-total label{ display:block; font-size:9.5px; letter-spacing:2.2px; text-transform:uppercase; color:var(--uimut); margin-bottom:1px; }
  .cp-total input{ background:transparent; border:0; outline:none; text-align:right; color:var(--t-ink); width:270px; padding:0;
    font-family:'SFMono-Regular',Menlo,'Liberation Mono',monospace; font-weight:700; font-size:29px; letter-spacing:-.5px;
    font-variant-numeric:tabular-nums; text-shadow:0 0 26px rgba(83,201,141,.30); }
  .cp-cta{ display:flex; align-items:center; }
  /* --- buttons --- */
  .btn{ border:1px solid var(--t-line); background:var(--t-surface); color:var(--uitext); border-radius:999px;
    padding:10px 18px; font-size:13px; cursor:pointer; font-family:inherit;
    transition:border-color .14s, background .14s, color .14s, transform .08s, box-shadow .14s; }
  :where(html.puntero) .btn:hover{ border-color:var(--t-line-2); background:var(--t-line); }
  .btn:active{ transform:translateY(1px); }
  .btn.primary{ background:var(--t-btn-primary-bg); color:var(--t-btn-primary-ink); border-color:var(--t-btn-primary-bg); font-weight:700; padding:11px 22px;
    box-shadow:0 3px 14px -4px rgba(0,0,0,.7), 0 0 0 1px color-mix(in srgb, var(--t-ink) 5%, transparent); }
  :where(html.puntero) .btn.primary:hover{ background:var(--t-btn-primary-hover); border-color:var(--t-btn-primary-hover); box-shadow:0 6px 20px -6px rgba(0,0,0,.8), 0 0 0 1px color-mix(in srgb, var(--t-ink) 8%, transparent); }
  .btn.primary.eq{ background:var(--c-eq); border-color:var(--c-eq); color:#1a1206;
    box-shadow:0 3px 16px -4px color-mix(in srgb, var(--c-eq) 55%, transparent); }
  :where(html.puntero) .btn.primary.eq:hover{ filter:brightness(1.07); }
  .btn.ghost{ background:transparent; border-color:var(--t-line); color:var(--uimut); font-size:11px;
    letter-spacing:.5px; padding:9px 15px; }
  :where(html.puntero) .btn.ghost:hover{ color:var(--uitext); border-color:var(--t-line-2); background:var(--t-surface); }
  :where(html.puntero) .btn.ghost.danger:hover{ color:#e06a5a; border-color:#59302a; background:rgba(224,106,90,.06); }
  /* Volver al panel: el mismo logo del Dashboard, no la palabra "Panel". El src se
     copia por JS desde la portada del PDF (ponerLogo) para no duplicar el base64. */
  .btn.dashlogo{ display:flex; align-items:center; padding:6px 13px; border-radius:14px; }
  /* El selector de tema: control solo, zona táctil completa; el ☀︎/◐ acompaña al texto. */
  #btnTema{ min-height:44px; }
  .btn.dashlogo img{ height:22px; width:auto; display:block; }
  :where(html.puntero) .btn.dashlogo:hover{ background:var(--t-surface); border-color:var(--t-line-2); }
  /* --- tabs --- */
  .cp-tabs{ display:flex; gap:5px; padding:0 16px; border-bottom:1px solid var(--t-line); overflow-x:auto; scrollbar-width:none; }
  .cp-tabs::-webkit-scrollbar{ display:none; }
  /* En el celu la tira de pestañas se corta ("Día del evento" queda afuera) y nada
     decía que había más: un degradé en el borde derecho lo insinúa (auditoría
     08/09/2026). En escritorio entran todas y no hace falta. */
  @media (max-width:1023px){
    .cp-tabs{ -webkit-mask-image:linear-gradient(to right, #000 calc(100% - 36px), transparent); mask-image:linear-gradient(to right, #000 calc(100% - 36px), transparent); }
  }
  .cp-tab{ --tc:var(--t-muted); position:relative; display:flex; align-items:center; gap:8px; border:0; background:transparent;
    color:var(--uimut); font-family:inherit; font-size:12.5px; font-weight:600; letter-spacing:.3px;
    padding:10px 14px; margin:6px 0 3px; border-radius:999px; cursor:pointer; white-space:nowrap;
    transition:color .14s, background .14s; }
  .cp-tab[data-cptab="evento"]{ --tc:var(--c-ev); }
  .cp-tab[data-cptab="formato"]{ --tc:var(--c-fmt); }
  .cp-tab[data-cptab="valores"]{ --tc:var(--c-val); }
  .cp-tab[data-cptab="equipo"]{ --tc:var(--c-eq); }
  .cp-tab[data-cptab="dia"]{ --tc:var(--c-dia); }
  .cp-tab .dot{ width:7px; height:7px; border-radius:2px; background:var(--tc); opacity:.45; transition:.14s; }
  :where(html.puntero) .cp-tab:hover{ color:var(--uitext); background:color-mix(in srgb, var(--t-ink) 4%, transparent); }
  .cp-tab.on{ color:var(--uitext);
    background:color-mix(in srgb, var(--tc) 16%, transparent);
    box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--tc) 38%, transparent); }
  .cp-tab.on .dot{ opacity:1; box-shadow:0 0 9px var(--tc); }
  /* --- panels --- */
  .cp-body{ padding:16px 24px 14px; }
  .cp-panel{ display:none; --sc:var(--acc); }
  .cp-panel.on{ display:block; animation:cpIn .18s ease; }
  @keyframes cpIn{ from{ opacity:0; transform:translateY(3px); } to{ opacity:1; transform:none; } }
  .cp-panel[data-cpp="evento"]{ --sc:var(--c-ev); }
  .cp-panel[data-cpp="formato"]{ --sc:var(--c-fmt); }
  .cp-panel[data-cpp="valores"]{ --sc:var(--c-val); }
  .cp-panel[data-cpp="equipo"]{ --sc:var(--c-eq); }
  .cp-panel[data-cpp="dia"]{ --sc:var(--c-dia); }
  .cp-sub{ font-size:10.5px; letter-spacing:2px; text-transform:uppercase; color:var(--uimut); margin:18px 0 8px; }
  .cp-sub:first-child{ margin-top:0; }
  .cp-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(215px,1fr)); gap:12px 14px; }
  .cp-grid .fld{ margin:0; }
  /* --- fields --- */
  .fld{ margin-bottom:10px; }
  /* Aviso de fecha (existe / ya pasó): el "ya pasó" es ámbar y no rojo, porque no bloquea. */
  .fld .fld-aviso.es-aviso, .fld [data-aviso].es-aviso{ color:var(--t-warn); }
  /* Franja "Tenés un presupuesto sin guardar" (auditoría 08/09/2026). */
  .cp-borrador{ display:none; align-items:center; gap:10px; flex-wrap:wrap; margin:0 0 10px; padding:9px 14px;
    border:1px solid color-mix(in srgb, var(--t-accent) 55%, transparent); background:var(--t-sel); border-radius:10px; font-size:13px; color:var(--t-ink); }
  .cp-borrador-btns{ margin-left:auto; display:flex; gap:8px; }
  .cp-borrador .btn{ min-height:36px; padding-inline:12px; }
  .fld label{ display:block; font-size:11px; color:var(--uimut); margin-bottom:5px; letter-spacing:.2px; }
  .fld input{ width:100%; background:var(--t-input); border:1px solid var(--t-line); color:var(--uitext);
    border-radius:8px; padding:9px 11px; font-size:13px; font-family:inherit;
    transition:border-color .14s, box-shadow .14s; }
  .fld input:focus{ outline:none; border-color:var(--sc,var(--acc));
    box-shadow:0 0 0 3px color-mix(in srgb, var(--sc,var(--acc)) 18%, transparent); }
  .fld input[readonly]{ color:var(--c-val); font-weight:700; background:var(--t-input); }
  /* mismo look que .fld input; appearance:none para que no aparezca el select nativo del SO */
  .fld select{ width:100%; background:var(--t-input); border:1px solid var(--t-line); color:var(--uitext);
    border-radius:8px; padding:9px 11px; font-size:13px; font-family:inherit; appearance:none; -webkit-appearance:none;
    background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='6'><path d='M0 0l5 6 5-6z' fill='%238c8f98'/></svg>");
    background-repeat:no-repeat; background-position:right 11px center; padding-right:28px;
    transition:border-color .14s, box-shadow .14s; }
  .fld select:focus{ outline:none; border-color:var(--sc,var(--acc));
    box-shadow:0 0 0 3px color-mix(in srgb, var(--sc,var(--acc)) 18%, transparent); }
  .fld textarea{ width:100%; background:var(--t-input); border:1px solid var(--t-line); color:var(--uitext);
    border-radius:8px; padding:9px 11px; font-size:13px; font-family:inherit; resize:vertical; min-height:64px; line-height:1.5;
    transition:border-color .14s, box-shadow .14s; }
  .fld textarea:focus{ outline:none; border-color:var(--sc,var(--acc));
    box-shadow:0 0 0 3px color-mix(in srgb, var(--sc,var(--acc)) 18%, transparent); }
  .two{ display:flex; gap:10px; } .two .fld{ flex:1; }
  /* Campo con selector al costado (fecha y hora). El input se sigue pudiendo tipear:
     el botón abre el picker propio de la app (ver el módulo Pickers). Antes esto era
     un <input type="date"> escondido de 1px + showPicker(), que en iOS no abría nada
     y dejaba el campo como "escribilo a mano". */
  .pick-wrap{ position:relative; }
  .pick-wrap > input{ padding-right:38px; }
  .pick-btn{ position:absolute; top:50%; right:6px; transform:translateY(-50%); width:28px; height:28px;
    border:1px solid var(--t-line); background:var(--t-surface); color:var(--uitext); border-radius:6px;
    font-size:14px; line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center;
    padding:0; transition:border-color .15s; }
  :where(html.puntero) .pick-btn:hover{ border-color:var(--sc,var(--acc)); }
  /* --- modules (Formato & Setup) --- */
  .cp-modules{ display:grid; grid-template-columns:repeat(auto-fit,minmax(255px,1fr)); gap:14px; }
  .module{ position:relative; background:var(--t-surface-1); border:1px solid var(--t-surface-2); border-radius:12px; padding:15px 17px 15px 20px;
    box-shadow:inset 0 1px 0 color-mix(in srgb, var(--t-ink) 3%, transparent); overflow:hidden; }
  .module::before{ content:""; position:absolute; left:0; top:0; bottom:0; width:3px;
    background:var(--sc); box-shadow:0 0 10px color-mix(in srgb, var(--sc) 60%, transparent); }
  .module .mt{ font-size:12.5px; font-weight:700; letter-spacing:.2px; display:flex; align-items:center; gap:8px; }
  .module .mt::before{ content:""; width:7px; height:7px; border-radius:2px; background:var(--sc); box-shadow:0 0 8px var(--sc); flex:none; }
  .module .md{ font-size:11px; color:var(--uimut); margin:4px 0 13px; line-height:1.5; }
  .module .editnote{ margin-top:12px; }
  /* --- toolbar --- */
  .cp-toolbar{ display:flex; align-items:center; gap:8px; padding:10px 24px 12px; border-top:1px solid var(--t-line);
    background:var(--t-input); flex-wrap:wrap; }
  .cp-tbspacer{ flex:1; }
  .cp-note{ font-size:10.5px; color:var(--t-dim); line-height:1.45; max-width:400px; text-align:right; }
  .cp-note b{ color:var(--uimut); }
  .editnote{ font-size:11px; color:var(--uimut); margin-top:10px; line-height:1.5; }
  .editnote b{ color:var(--uitext); }
  .topactions{ display:inline-block; }

  .stage{ padding:30px 0 60px; display:flex; flex-direction:column; align-items:center; gap:24px; }
  .editable{ outline:1px dashed transparent; transition:outline .15s; border-radius:4px; }
  :where(html.puntero) .editable:hover{ outline:1px dashed #b9b3a6; }
  .editable:focus{ outline:1px solid var(--acc); }

  /* ===================== DOCUMENTO ===================== */
  .page{ position:relative; width:210mm; height:297mm; overflow:hidden; background:var(--cream);
    box-shadow:0 10px 40px rgba(0,0,0,.4); }
  .pad{ position:absolute; top:0;right:0;bottom:0;left:0; padding:52px 56px 0 56px; }
  .folio{ position:absolute; top:52px; right:56px; font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:3px; color:var(--muted); }
  .folio.nrofolio{ top:66px; font-size:7px; letter-spacing:2px; }
  .cover .folio.nrofolio{ color:rgba(255,255,255,.5); }
  .brand{ position:absolute; top:50px; left:56px; } .brand img{ height:30px; display:block; }
  .foot{ position:absolute; left:56px; right:56px; bottom:38px; display:flex; justify-content:space-between;
    font-family:'Liberation Mono',Menlo,monospace; font-size:8px; letter-spacing:2px; color:var(--muted); text-transform:uppercase; }
  .dark .foot{ color:rgba(255,255,255,.5); }
  .foot .df{ font-size:7.5px; letter-spacing:1px; text-transform:none; }
  .dark .foot .df, .cover .foot .df{ color:rgba(255,255,255,.45); }
  .eyebrow{ font-family:'Liberation Mono',Menlo,monospace; font-size:10px; letter-spacing:4px; text-transform:uppercase; color:#36332e; }
  .dark .eyebrow{ color:rgba(255,255,255,.72); }
  .h1{ font-size:50px; font-weight:700; letter-spacing:-1.2px; line-height:.96; margin-top:10px; }
  .h1 .it{ font-style:italic; font-weight:400; color:var(--gray); }
  .dark .h1{ color:#fff; } .dark .h1 .it{ color:rgba(255,255,255,.55); }
  .subref{ font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:3px; text-transform:uppercase; color:var(--gray); margin-top:8px; }
  .dark .subref{ color:rgba(255,255,255,.6); }
  .lede{ font-size:21px; font-weight:400; line-height:1.32; letter-spacing:-.3px; margin-top:30px; }
  .lede .it{ font-style:italic; color:var(--gray); }
  .note{ font-size:12.5px; line-height:1.5; color:#5d584f; margin-top:14px; max-width:88%; }
  .rule{ height:1px; background:var(--hair); margin:26px 0 4px; } .dark .rule{ background:rgba(255,255,255,.16); }

  .row{ display:flex; align-items:flex-start; justify-content:space-between; padding:15px 0; border-bottom:1px solid var(--hair); }
  .row .lead{ display:flex; align-items:flex-start; gap:22px; flex:1; padding-right:26px; }
  .row .lead > div:last-child{ flex:1; }
  .row .n{ font-family:'Liberation Mono',Menlo,monospace; font-size:10px; letter-spacing:1px; color:var(--muted); padding-top:5px; min-width:20px; }
  .row .title{ font-size:18px; font-weight:600; letter-spacing:-.3px; }
  .row .desc{ font-size:12px; color:var(--gray); margin-top:3px; }
  .badge{ font-family:'Liberation Mono',Menlo,monospace; font-size:7.5px; letter-spacing:2px; text-transform:uppercase; color:var(--badge);
    border:1px solid var(--badgeb); padding:5px 9px; white-space:nowrap; margin-top:3px; flex-shrink:0; }

  .grp{ margin-top:18px; }
  .grp-h{ display:flex; align-items:center; justify-content:space-between; border-bottom:1px solid var(--hair); padding-bottom:7px; }
  .grp-h .gt{ font-family:'Liberation Mono',Menlo,monospace; font-size:11px; letter-spacing:3px; text-transform:uppercase; color:#36332e; }
  .grp-h .gs{ font-size:11.5px; color:var(--gray); }
  .eq{ display:flex; align-items:baseline; gap:14px; padding:7px 0; border-bottom:1px solid #e7e2d8; }
  .eq > div:last-child{ flex:1; }
  .eq:last-child{ border-bottom:none; }
  .eq .q{ font-family:'Liberation Mono',Menlo,monospace; font-size:11px; color:var(--ink); min-width:30px; }
  .eq .en{ font-size:13.5px; font-weight:600; letter-spacing:-.2px; }
  .eq .ed{ font-size:11.5px; color:var(--gray); }

  .spec .sr{ display:flex; gap:30px; padding:16px 0; border-bottom:1px solid var(--hair); }
  .spec .sk{ font-family:'Liberation Mono',Menlo,monospace; font-size:12px; letter-spacing:1px; min-width:120px; }
  .spec .sv{ font-size:13.5px; color:#4a463f; }
  .panel{ margin-top:30px; height:300px; background:var(--panel); position:relative; display:flex; align-items:center; justify-content:center; }
  .panel img{ width:84%; }
  .panel .cap{ position:absolute; bottom:16px; left:20px; right:20px; display:flex; justify-content:space-between;
    font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:2px; color:#8a8579; }
  .panel .cap .mid{ color:#3c3a35; }

  .cover{ background:#000; }
  .cover .ph{ position:absolute; top:0;right:0;bottom:0;left:0; background-size:cover; background-position:center 38%; }
  .cover .scrim{ position:absolute; top:0;right:0;bottom:0;left:0; background:linear-gradient(180deg, rgba(0,0,0,.25) 0%, rgba(0,0,0,.05) 40%, rgba(0,0,0,.78) 100%); }
  .cover .logo{ position:absolute; top:46%; left:50%; transform:translate(-50%,-50%); width:300px; }
  .cover .logo img{ width:100%; display:block; }
  .cover .meta{ position:absolute; left:56px; bottom:120px; color:#fff; }
  .cover .meta .k{ font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:4px; text-transform:uppercase; color:rgba(255,255,255,.8); }
  .cover .meta .client{ font-size:62px; font-weight:600; letter-spacing:-1.5px; line-height:1; margin:14px 0 22px; }
  .cover .meta .grid{ display:flex; gap:40px; }
  .cover .meta .grid .lab{ font-family:'Liberation Mono',Menlo,monospace; font-size:8px; letter-spacing:2px; color:rgba(255,255,255,.55); text-transform:uppercase; }
  .cover .meta .grid .val{ font-family:'Liberation Mono',Menlo,monospace; font-size:12px; color:#fff; margin-top:5px; white-space:nowrap; }
  .cover .folio{ color:rgba(255,255,255,.7); } .cover .foot{ color:rgba(255,255,255,.55); }

  .dark .ph{ position:absolute; top:0;right:0;bottom:0;left:0; background-size:cover; background-position:center; }
  .dark .scrim{ position:absolute; top:0;right:0;bottom:0;left:0; }
  .breakdown{ margin-top:34px; }
  .bl{ display:flex; justify-content:space-between; align-items:baseline; padding:15px 0; border-bottom:1px solid rgba(255,255,255,.16); }
  .bl .bk{ font-size:16px; color:#fff; }
  .bl .bk small{ display:block; font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:2px; color:rgba(255,255,255,.5); text-transform:uppercase; margin-top:4px; }
  .bl .bv{ font-family:'Liberation Mono',Menlo,monospace; font-size:18px; color:#fff; }
  .total{ margin-top:30px; }
  .total .tl{ font-family:'Liberation Mono',Menlo,monospace; font-size:10px; letter-spacing:3px; text-transform:uppercase; color:rgba(255,255,255,.6); }
  .total .tn{ font-size:108px; font-weight:600; letter-spacing:-4px; color:#fff; line-height:.9; margin-top:6px; }
  .total .tc{ font-size:13px; color:rgba(255,255,255,.7); margin-top:14px; max-width:70%; line-height:1.5; }
  .opt{ display:flex; gap:14px; margin-top:26px; }
  .opt .oc{ flex:1; border:1px solid rgba(255,255,255,.2); padding:16px 18px; }
  .opt .oc .ot{ font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:2px; text-transform:uppercase; color:rgba(255,255,255,.6); }
  .opt .oc .ov{ font-size:24px; font-weight:600; color:#fff; margin-top:8px; }
  .opt .oc .od{ font-size:11px; color:rgba(255,255,255,.55); margin-top:4px; }

  .ocard{ border:1px solid var(--hair); padding:24px 26px; margin-top:18px; position:relative; }
  .ocard .oh{ min-height:60px; padding-right:200px; }   /* reserva lugar para el precio anclado */
  .ocard .otag{ font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:3px; text-transform:uppercase; color:var(--gray); }
  .ocard .oname{ font-size:23px; font-weight:600; letter-spacing:-.5px; margin-top:8px; }
  .ocard .oprice{ position:absolute; top:50%; right:26px; transform:translateY(-50%); text-align:right; }   /* anclado y centrado vertical */
  .ocard .oprice .pl{ font-family:'Liberation Mono',Menlo,monospace; font-size:8px; letter-spacing:2px; text-transform:uppercase; color:var(--gray); line-height:1.4; }
  .ocard .oprice .pv{ font-size:36px; font-weight:600; letter-spacing:-1px; white-space:nowrap; }
  .ocard .olist{ margin-top:16px; }
  .ocard .oli{ font-size:13px; color:#4a463f; padding:6px 0; border-bottom:1px solid #e7e2d8; display:flex; gap:12px; }
  .ocard .oli:last-child{ border-bottom:none; }
  .ocard .oli .q{ font-family:'Liberation Mono',Menlo,monospace; color:var(--ink); min-width:26px; }

  .gracias{ font-size:62px; font-weight:600; letter-spacing:-1.5px; color:#fff; margin-top:30px; }
  .aclar-blk{ margin-top:24px; max-width:94%; }
  .aclar{ font-family:'Liberation Mono',Menlo,monospace; font-size:11.5px; line-height:1.7;
    color:rgba(255,255,255,.62); white-space:pre-wrap; min-height:16px; }
  .contacts{ margin-top:22px; }
  .ct{ display:flex; gap:26px; align-items:baseline; padding:9px 0; }
  .ct .ck{ font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:2px; text-transform:uppercase; color:rgba(255,255,255,.5); min-width:46px; }
  .ct .cv{ font-size:15px; color:#fff; }

  /* total Solo DJ */
  .djtotal{ margin-top:42px; }
  .dt-cur{ font-size:22px; color:rgba(255,255,255,.85); }
  .dt-num{ font-size:150px; font-weight:600; letter-spacing:-5px; color:#fff; line-height:.82; margin:4px 0 22px; }
  .dt-desc{ font-family:'Liberation Mono',Menlo,monospace; font-size:13px; color:rgba(255,255,255,.7); line-height:1.7; }
  .dt-rule{ height:1px; background:rgba(255,255,255,.18); margin:28px 0 24px; max-width:66%; }
  .dt-blk{ margin-bottom:20px; }
  .dt-k{ font-family:'Liberation Mono',Menlo,monospace; font-size:9px; letter-spacing:2px; text-transform:uppercase; color:rgba(255,255,255,.55); }
  .dt-v{ font-size:22px; color:#fff; margin-top:3px; }
  .dt-s{ font-size:13px; color:rgba(255,255,255,.65); margin-top:6px; }

  /* recuadro Productor del evento (adicional opcional, solo DJ) */
  .dt-prod{ position:absolute; left:56px; right:56px; bottom:172px;
    background:rgba(255,255,255,.045); border:1px solid rgba(255,255,255,.14);
    border-radius:14px; padding:24px 28px; backdrop-filter:blur(1px); }
  .dt-prod-top{ display:flex; align-items:center; gap:11px; }
  .dt-prod-ico{ width:26px; height:26px; flex:0 0 auto; opacity:.9; }
  .dt-prod-h{ font-family:'Liberation Mono',Menlo,monospace; font-size:15px; letter-spacing:2px;
    text-transform:uppercase; color:#fff; }
  .dt-prod-tag{ font-family:'Liberation Mono',Menlo,monospace; font-size:7.5px; letter-spacing:2px;
    text-transform:uppercase; color:rgba(255,255,255,.6); padding:3px 9px;
    border:1px solid rgba(255,255,255,.22); border-radius:20px; }
  .dt-prod-body{ font-family:'Liberation Mono',Menlo,monospace; font-size:11px; line-height:1.75;
    color:rgba(255,255,255,.6); margin-top:13px; max-width:78%; }
  .dt-prod-foot{ display:flex; align-items:baseline; gap:8px; margin-top:16px; }
  .dt-prod-k{ font-family:'Liberation Mono',Menlo,monospace; font-size:8px; letter-spacing:1.5px;
    text-transform:uppercase; color:rgba(255,255,255,.5); }
  .dt-prod-price{ font-size:21px; color:#fff; }

  /* selector de formato */
  .modebar{ display:flex; align-items:center; gap:14px; margin-bottom:14px; flex-wrap:wrap; }
  .modebar .ml{ font-size:10.5px; letter-spacing:2px; text-transform:uppercase; color:var(--uimut); }
  .seg{ display:inline-flex; background:var(--t-input); border:1px solid var(--t-line); border-radius:999px; padding:3px;
    box-shadow:inset 0 2px 5px rgba(0,0,0,.4); }
  .seg button{ border:0; background:transparent; color:var(--uimut); font-family:inherit; font-size:13px; font-weight:600;
    padding:8px 18px; border-radius:999px; cursor:pointer; transition:color .13s, background .13s; }
  :where(html.puntero) .seg button:not(.active):hover{ color:var(--uitext); }
  .seg button.active{ background:color-mix(in srgb, var(--sc,var(--acc)) 20%, var(--t-surface-1)); color:var(--sc,var(--acc));
    font-weight:700; box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--sc,var(--acc)) 45%, transparent); }
  .seg.seg-xl button{ padding:12px 24px; font-size:14px; }
  .setup-head{ display:inline-flex; align-items:center; gap:9px; }
  .iswitch{ position:relative; display:inline-block; width:42px; height:25px; flex:0 0 auto; }
  .iswitch input{ position:absolute; opacity:0; width:0; height:0; }
  .islider{ position:absolute; inset:0; background:var(--t-line-2); border-radius:999px; cursor:pointer; transition:.22s; }
  .islider::before{ content:""; position:absolute; width:19px; height:19px; left:3px; top:3px; background:#fff; border-radius:50%; transition:.22s; box-shadow:0 1px 3px rgba(0,0,0,.35); }
  .iswitch input:checked + .islider{ background:#34c759; }
  .iswitch input:checked + .islider::before{ transform:translateX(17px); }
  .seg.disabled{ opacity:.38; pointer-events:none; filter:grayscale(.4); }
  .full-only.hide{ display:none; }
  .dj-only.hide{ display:none; }
  .evt-otro{ display:none; background:var(--t-input); border:1px solid var(--t-line); color:var(--uitext);
    border-radius:8px; padding:8px 12px; font-size:13px; font-family:inherit; transition:border-color .14s, box-shadow .14s; }
  .evt-otro:focus{ outline:none; border-color:var(--sc,var(--acc));
    box-shadow:0 0 0 3px color-mix(in srgb, var(--sc,var(--acc)) 18%, transparent); }
  .evt-otro.show{ display:inline-block; }

  /* ===================== ÍCONOS DE TRAZO (05/09/2026) ===================== */
  /* Los emojis de la interfaz se reemplazaron por símbolos SVG del sprite del
     <head> (ver `ICO()`). Toman el color del texto, miden como una letra y no cambian
     según el sistema. `.fill` es para los pocos que van rellenos (el play). */
  .ico{ width:1.05em; height:1.05em; display:inline-block; vertical-align:-0.18em; flex:none;
    fill:none; stroke:currentColor; stroke-width:1.9; stroke-linecap:round; stroke-linejoin:round; }
  .ico.fill{ fill:currentColor; stroke:none; }
  #navbar .nvi .ico{ width:21px; height:21px; vertical-align:0; stroke-width:1.75; }
  #navbar .nvb-mas .nvi .ico{ width:24px; height:24px; stroke-width:2; }
  .crear-op .ci .ico{ width:22px; height:22px; vertical-align:0; }
  #dash .dnoti .ico{ width:18px; height:18px; vertical-align:-0.25em; }
  #dash .deye .ico{ width:18px; height:18px; }
  /* Ícono seguido de texto en un chip/botón: el espacio del HTML se pierde en flex. */
  .dchip .ico, .btn .ico, .ag-act .ico, .dalact .ico, .dd-todo .ico, .pick-btn .ico{ margin-right:.35em; }
  .pick-btn .ico{ margin-right:0; width:18px; height:18px; }

  /* ===================== MÓVIL / iPhone ===================== */
  .mobile-tip{ display:none; }
  @media screen and (max-width:860px){
    body{ background:var(--t-bg); }
    .controls{ position:static; }
    .stage{ display:none !important; }
    .cp-bar{ padding:calc(12px + env(safe-area-inset-top)) 14px 12px; gap:10px 14px; }
    .cp-brand{ min-width:0; flex:1 1 100%; display:flex; align-items:center; justify-content:space-between; gap:8px 10px; flex-wrap:wrap; }
    .cp-chips{ margin-top:0; }
    /* En el celu los dos pills envuelven a una segunda línea si no entran: nunca se recorta el texto. */
    .cp-chips{ flex-wrap:wrap; }
    .cp-spacer{ display:none; }
    .cp-total{ text-align:left; flex:1 1 100%; padding:6px 0 2px; border-top:1px solid var(--t-line); }
    .cp-total input{ text-align:left; font-size:31px; width:100%; }
    /* Sin el botón del agente (14/09/2026) quedan dos: se reparten la fila, parejos. */
    .cp-cta{ flex:1 1 100%; gap:8px; }
    .cp-cta .btn, .cp-cta .btn.ghost{ flex:1 1 0; width:auto; justify-content:center; text-align:center; padding:14px 10px; font-size:15px; }
    .cp-tabs{ padding:0 8px; }
    .cp-tab{ flex:1 1 auto; justify-content:center; padding:12px 9px 13px; font-size:12px; }
    .cp-body{ padding:14px 14px 12px; }
    .cp-toolbar{ padding:10px 14px calc(12px + env(safe-area-inset-bottom)); }
    .btn.ghost{ flex:1 1 auto; text-align:center; }
    .cp-note{ display:none; }
    .mobile-tip{ display:block; flex:1 1 100%; text-align:left; max-width:none; }
    /* 16px es el mínimo que evita el zoom automático de iOS al enfocar un campo.
       Vale para todo input de formulario, incluidos los que tienen picker al lado. */
    .fld input, .fld textarea, .fld select, .evt-otro{ font-size:16px; padding:12px 12px; }
    .fld select{ padding-right:28px; }
    /* va DESPUÉS de .fld input: el shorthand `padding` de arriba pisa el padding-right
       de .pick-wrap, y el texto quedaría abajo del botón del selector */
    .pick-wrap > input{ padding-right:46px; }
    .pick-btn{ width:34px; height:34px; right:7px; font-size:15px; }
    .fld label{ font-size:12px; }
    .seg{ width:100%; flex-wrap:wrap; }   /* con "Civil" son 5 opciones: se acomodan en dos filas */
    .seg button{ flex:1; padding:11px 8px; font-size:12px; }
    .seg.seg-xl button{ padding:13px 8px; font-size:13px; }
    .modebar{ flex-wrap:wrap; }
    .stage{ padding:16px 0 44px; gap:14px; }
    .page{ zoom: var(--mz, 0.48); box-shadow:0 6px 22px rgba(0,0,0,.5); }
  }

  /* ===================== DESKTOP ANCHO (>=1200px) ===================== */
  @media screen and (min-width:1200px){
    body{ display:flex; align-items:flex-start; }
    .controls{ flex:1; min-width:0; position:sticky; top:var(--nav-top, 0px);
      max-height:calc(100vh - var(--nav-top, 0px)); overflow-y:auto; }
    .stage{ flex:0 0 360px; width:360px; position:sticky; top:var(--nav-top, 0px);
      max-height:calc(100vh - var(--nav-top, 0px)); overflow-y:auto; padding:20px 0 40px; }
    .page{ zoom:0.38; }
  }

  /* ===================== PRINT ===================== */
  @media print{
    body{ background:#fff; }
    .controls{ display:none !important; }
    .stage{ padding:0; gap:0; display:block; }
    .page{ box-shadow:none !important; page-break-after:always; break-after:page; }
    .page:last-child{ page-break-after:auto; }
    .editable{ outline:none !important; }
    *{ -webkit-print-color-adjust:exact !important; print-color-adjust:exact !important; }
  }

  /* refuerzos para exportación PDF (html2canvas) */
  .row .lead{ gap:0; }
  .row .n{ margin-right:22px; }
  .eq{ gap:0; }
  .eq .q{ margin-right:14px; }
  .spec .sr{ gap:0; }
  .spec .sk{ margin-right:30px; }
  .cover .meta .grid{ gap:0; }
  .cover .meta .grid > div{ margin-right:40px; }
  .opt{ gap:0; }
  .opt .oc:first-child{ margin-right:14px; }
  .ocard .oli{ gap:0; }
  .ocard .oli .q{ margin-right:12px; }
  .ct{ gap:0; }
  .ct .ck{ margin-right:26px; }
  .panel img{ margin-left:auto; margin-right:auto; }

  /* ===================== AGENDA · BASE DE DATOS (solo pantalla) ===================== */
  .agenda-ov{ position:fixed; inset:0; background:rgba(0,0,0,.55); backdrop-filter:blur(3px); -webkit-backdrop-filter:blur(3px);
    opacity:0; pointer-events:none; transition:opacity .28s ease; z-index:80; }
  .agenda-ov.open{ opacity:1; pointer-events:auto; }

  .agenda{
    --a-bg:var(--t-agenda-bg); --a-bg2:var(--uibg); --a-card:var(--uicard); --a-card2:var(--t-surface-2); --a-input:var(--t-input);
    --a-line:var(--uiline); --a-line2:var(--t-line-2); --a-ink:var(--uitext); --a-mut:var(--uimut); --a-dim:var(--t-dim);
    /* 🔴 PALETA REFORZADA EL 27/08/2026, y acá el arreglo era PEOR que en el
       Panel: el verde (croma .094) y el azul (.083) estaban POR DEBAJO DEL PISO
       DE CROMA — o sea que se leían literalmente como GRIS. Medido con el
       validador de la skill dataviz contra `--a-bg` (var(--t-agenda-bg)).
       Son los MISMOS hex que usa el Dashboard: antes eran dos paletas distintas
       para los mismos tres estados, así que el mismo dato se veía de un color en
       el Panel y de otro en la Agenda. */
    --a-acc:var(--acc); --a-acc-d:var(--t-accent-deep); --a-green:var(--t-ok); --a-amber:var(--t-warn); --a-blue:var(--t-info); --a-red:var(--t-err);
    --a-mono:'SFMono-Regular',Menlo,'Liberation Mono','DejaVu Sans Mono',monospace; --a-disp:'Helvetica Neue',Helvetica,Arial,sans-serif;
    position:fixed; top:0; right:0; bottom:0; width:min(560px,100vw); z-index:81;
    background:linear-gradient(180deg,var(--a-bg2),var(--a-bg));
    color:var(--a-ink); border-left:1px solid var(--a-line);
    box-shadow:-30px 0 60px -30px rgba(0,0,0,.8);
    transform:translateX(102%); transition:transform .32s cubic-bezier(.4,0,.18,1);
    display:flex; flex-direction:column;
    font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;
  }
  .agenda.open{ transform:translateX(0); }
  /* 🔴 Un cajón cerrado (translateX(102%)) sigue proyectando su sombra hacia adentro del
     viewport: en oscuro era invisible, en claro se veía una franja gris en el borde
     derecho de TODAS las pantallas (medido el 03/09/2026). Sin sombra hasta que abre. */
  .agenda:not(.open){ box-shadow:none; }
  .agenda-hd{ display:flex; align-items:center; justify-content:space-between; gap:12px;
    padding:calc(16px + env(safe-area-inset-top)) 22px 14px; border-bottom:1px solid var(--a-line); flex-shrink:0; }
  .agenda-hd h2{ font-family:var(--a-disp); font-size:15px; font-weight:700; letter-spacing:.5px; }
  .agenda-hd h2 span{ display:block; font-size:11px; letter-spacing:.04em; color:var(--a-mut); font-weight:400; margin-top:4px; }
  .agenda-x{ border:1px solid var(--a-line); background:var(--a-card); color:var(--a-ink); width:34px; height:34px; border-radius:8px; cursor:pointer; font-size:14px; line-height:1; flex-shrink:0; transition:border-color .15s,background .15s; }
  :where(html.puntero) .agenda-x:hover{ border-color:var(--a-acc); }
  .agenda-body{ overflow-y:auto; padding:16px 22px 26px; flex:1; }

  /* ---- Métricas ----
     Paleta de las barras: NO son los mismos hex que los chips/puntitos del calendario.
     Los tonos son idénticos (desvío 0°) pero re-escalados para relleno grande sobre
     fondo oscuro: los de la UI quedaban fuera de la banda de luminosidad y demasiado
     desaturados (leían gris), y verde↔ámbar no separaban para daltonismo.
     Estos pasan los cinco checks contra el fondo var(--t-agenda-bg) — no los cambies a ojo. */
  /* ⚠️ SOLO CAMBIÓ EL ÁMBAR (27/08/2026), de #966900 a #a35c00. Estos tres son la
     paleta de RELLENO GRANDE de las barras de Métricas y siguen siendo distintos
     de los chips a propósito (ver el comentario largo más abajo). Pero al pasar
     el ámbar de la app de amarillo-naranja (H73) a ámbar de verdad (H63), este
     quedaba 16° corrido: las barras seguían amarillentas mientras el resto de la
     app ya no. Ahora está a 1° del de los chips — mismo tono, otra escala, que es
     justamente la relación que estos colores tienen que tener.
     🔴 Revalidado, no elegido a ojo: pasa los cinco checks contra var(--t-agenda-bg)
     (ΔE 8.7 deutan). El verde y el azul NO se tocaron: ya estaban a 4° y 3°. */
  .agenda{ --m-conf:var(--t-chart-ok); --m-esp:var(--t-chart-warn); --m-cons:var(--t-chart-info); }
  .ag-tabs{ display:flex; gap:6px; margin-bottom:16px; }
  .ag-tab{ flex:1; border:1px solid var(--a-line); background:transparent; color:var(--a-mut);
    border-radius:9px; padding:8px 12px; font:inherit; font-size:12.5px; cursor:pointer; transition:.15s; }
  :where(html.puntero) .ag-tab:hover{ border-color:var(--a-line2); color:var(--a-ink); }
  .ag-tab.on{ background:var(--a-card); border-color:var(--a-acc); color:var(--a-ink); font-weight:600; }
  .mt-hd{ display:flex; align-items:center; justify-content:center; gap:14px; margin-bottom:16px; }
  .mt-hd button{ width:28px; height:28px; border-radius:7px; border:1px solid var(--a-line);
    background:transparent; color:var(--a-mut); cursor:pointer; font:inherit; }
  :where(html.puntero) .mt-hd button:hover{ border-color:var(--a-acc); color:var(--a-ink); }
  .mt-year{ font-family:var(--a-mono); font-size:17px; font-weight:700; min-width:64px; text-align:center; }
  .mt-chart{ background:var(--a-card); border:1px solid var(--a-line); border-radius:11px;
    padding:15px 14px 10px; margin-bottom:12px; }
  .mt-title{ font-size:10px; letter-spacing:1.6px; text-transform:uppercase; color:var(--a-mut); margin-bottom:14px; }
  .mt-title > span{ float:right; letter-spacing:0; text-transform:none; color:var(--a-dim); font-family:var(--a-mono); }   /* > : el monto de adentro (ojito) no flota */
  .mt-plot{ display:flex; align-items:flex-end; gap:3px; height:132px; position:relative;
    border-bottom:1px solid var(--a-line); padding-bottom:0; }
  .mt-col{ flex:1; display:flex; flex-direction:column; justify-content:flex-end; align-items:center;
    height:100%; position:relative; cursor:default; border-radius:5px 5px 0 0; transition:background .12s; }
  /* El hover resalta la columna con un fondo, no atenuando la barra: atenuar leía
     como "deshabilitado" justo en el mes que estás mirando. */
  :where(html.puntero) .mt-col:hover{ background:color-mix(in srgb, var(--t-ink) 5%, transparent); }
  .mt-bar{ width:100%; display:flex; flex-direction:column-reverse; gap:2px; /* separador de 2px entre segmentos */
    border-radius:4px 4px 0 0; overflow:hidden; }
  .mt-seg{ width:100%; min-height:2px; }
  .mt-seg.confirmado{ background:var(--m-conf); }
  .mt-seg.espera{ background:var(--m-esp); }
  .mt-seg.consultar{ background:var(--m-cons); }
  .mt-mon{ font-family:var(--a-mono); font-size:8.5px; color:var(--a-dim); margin-top:5px;
    position:absolute; bottom:-15px; left:0; right:0; text-align:center; }
  .mt-col.hoy .mt-mon{ color:var(--a-acc); font-weight:700; }
  .mt-val{ font-family:var(--a-mono); font-size:8.5px; color:var(--a-mut); margin-bottom:3px; white-space:nowrap; }
  .mt-plot{ margin-bottom:20px; }
  /* Franja de detalle bajo el gráfico en vez de tooltip flotante: en un cajón de
     560px el tooltip se escapaba hacia arriba y tapaba las tarjetas de totales. */
  .mt-detail{ margin-top:2px; padding:8px 10px; min-height:34px; background:var(--a-card2);
    border:1px solid var(--a-line); border-radius:9px; font-size:11.5px; color:var(--a-mut);
    display:flex; align-items:center; gap:6px 14px; flex-wrap:wrap; }
  .mt-detail b{ font-family:var(--a-mono); color:var(--a-ink); }
  .mt-detail .mes{ color:var(--a-ink); font-weight:700; }
  .mt-detail i{ width:8px; height:8px; border-radius:2px; display:inline-block; margin-right:5px; }
  .mt-detail .hint{ color:var(--a-dim); }
  .mt-legend{ display:flex; flex-wrap:wrap; gap:8px 16px; margin-bottom:14px; font-size:11.5px; color:var(--a-mut); }
  .mt-legend span{ display:flex; align-items:center; gap:6px; }
  .mt-legend i{ width:9px; height:9px; border-radius:3px; display:block; }
  .mt-table{ font-size:12px; color:var(--a-mut); margin-bottom:8px; }
  .mt-table summary{ cursor:pointer; color:var(--a-dim); font-size:11.5px; padding:4px 0; }
  /* Con la columna Rechazado son SEIS columnas y a 390px no entran: medido, la tabla
     pide 363px contra 357 de caja. El desborde se resuelve adentro de su propia caja
     —scroll horizontal en el contenedor de la tabla— y nunca dejando que empuje el
     ancho del cajón. `white-space:nowrap` para que las cifras no se partan en dos
     renglones al apretarse. */
  .mt-table > div{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .mt-table table{ width:100%; min-width:340px; border-collapse:collapse; margin-top:8px; }
  .mt-table th,.mt-table td{ text-align:right; padding:4px 6px; border-bottom:1px solid var(--a-line);
    font-family:var(--a-mono); font-size:11px; white-space:nowrap; }
  .mt-table th:first-child,.mt-table td:first-child{ text-align:left; }
  .mt-table th{ color:var(--a-dim); font-weight:400; }
  .mt-empty{ color:var(--a-dim); font-size:12.5px; text-align:center; padding:26px 0; }

  .ag-stats{ display:grid; grid-template-columns:repeat(3,1fr); gap:10px; margin-bottom:16px; }
  .ag-stat{ background:var(--a-card); border:1px solid var(--a-line); border-radius:10px; padding:11px 13px; }
  .ag-stat .k{ font-size:10px; letter-spacing:2px; text-transform:uppercase; color:var(--a-mut); }
  .ag-stat .v{ font-family:var(--a-mono); font-weight:700; font-size:19px; margin-top:6px; color:var(--a-acc); font-variant-numeric:tabular-nums; line-height:1; }
  .ag-stat .v small{ font-size:11px; color:var(--a-mut); font-weight:400; }

  .ag-cal{ background:var(--a-card); border:1px solid var(--a-line); border-radius:12px; padding:14px 14px 16px; margin-bottom:16px; }
  .ag-cal-hd{ display:flex; align-items:center; justify-content:space-between; margin-bottom:12px; }
  .ag-cal-hd .mlabel{ font-size:14px; font-weight:700; letter-spacing:.3px; }
  .ag-nav{ display:flex; gap:6px; align-items:center; }
  .ag-nav button{ border:1px solid var(--a-line); background:var(--a-input); color:var(--a-ink); width:30px; height:30px; border-radius:7px; cursor:pointer; font-size:15px; line-height:1; transition:border-color .15s; }
  :where(html.puntero) .ag-nav button:hover{ border-color:var(--a-acc); }
  .ag-nav .today{ width:auto; padding:0 13px; font-size:11px; letter-spacing:1.5px; text-transform:uppercase; }
  .ag-dow{ display:grid; grid-template-columns:repeat(7,1fr); gap:4px; margin-bottom:6px; }
  .ag-dow span{ text-align:center; font-size:9px; letter-spacing:1px; text-transform:uppercase; color:var(--a-dim); }
  .ag-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:4px; }
  /* ⚠ `flex-direction:column` no es decorativo: con `aspect-ratio` y dirección fila,
     la contribución de ancho mínimo de la celda se dispara y las columnas `1fr` de
     .ag-grid dejan de entrar — el panel del Dashboard se va a 850px de ancho y
     aparece scroll horizontal en el celular. En columna, `justify-content:center`
     centra verticalmente el número, que es lo que hace falta ahora que el día
     pintado ya no lleva los puntitos abajo. */
  .ag-cell{ aspect-ratio:1/1; border:1px solid transparent; border-radius:8px; background:var(--a-input); position:relative;
    display:flex; flex-direction:column; align-items:center; justify-content:center; padding:0;
    transition:background .14s, border-color .14s, filter .14s; }
  /* Las celdas de relleno del principio del mes se llamaban `.ag-cell.pad` y chocaban
     con `.pad`, que es de las páginas del PDF y trae `padding:52px 56px 0`. Como la
     regla de .ag-cell venía después, la pisaba y no se notaba — hasta que se le sacó
     el padding y las celdas vacías se comieron 112px cada una, reventando el ancho
     de la grilla. Renombradas a `.vacia`, y .ag-cell lleva su `padding:0` explícito. */
  .ag-cell.vacia{ background:transparent; }
  .ag-cell .dn{ font-family:var(--a-mono); font-size:11px; color:var(--a-mut); }
  .ag-cell.today{ border-color:var(--a-acc); }
  .ag-cell.today .dn{ color:var(--a-acc); font-weight:700; }
  .ag-cell.has{ cursor:pointer; background:var(--a-card2); }
  /* 🔴 TODAS las fechas reales son accionables, asi que TODAS avisan que se pueden
     tocar. Antes solo las que tenian eventos: una fecha libre no daba cursor ni
     hover y parecia muerta — que es exactamente lo que era hasta que se le puso
     accion. `.vacia` (el relleno del principio del mes) no lleva nada: no es una
     fecha. El hover va acotado a `html.puntero` como todo el resto. */
  .ag-cell[data-iso]{ cursor:pointer; }
  :where(html.puntero) .ag-cell[data-iso]:hover{ border-color:var(--a-line2); background:color-mix(in srgb, var(--t-ink) 5%, transparent); }
  :where(html.puntero) .ag-cell.has:hover{ border-color:var(--a-line2); }
  .ag-cell.sel{ border-color:var(--a-acc); background:color-mix(in srgb, var(--t-accent) 16%, transparent); }
  /* ---- día con eventos: el cuadro entero pintado con el color del estado ----
     Antes era un puntito de 6px abajo del número: había que buscarlo con lupa.
     El fondo lo escribe drawCalendar en el style inline (un color, o un gradiente
     en franjas si ese día tiene eventos de más de un estado). Acá va todo lo que
     depende de tener el cuadro pintado: el número pasa a tinta oscura, y el "hoy"
     y el día seleccionado se marcan con anillo en vez de borde, que sobre el color
     lleno no se distinguía. */
  .ag-cell.pintado{ border-color:transparent; }
  .ag-cell.pintado .dn{ color:var(--t-on-accent); font-weight:700; }
  .ag-cell.pintado .cnt{ color:color-mix(in srgb, var(--t-on-accent) 75%, transparent); font-weight:700; }
  :where(html.puntero) .ag-cell.pintado:hover{ filter:brightness(1.09); }
  .ag-cell.pintado.today{ box-shadow:inset 0 0 0 2px var(--a-acc); }
  .ag-cell.pintado.sel{ box-shadow:inset 0 0 0 2px var(--a-ink); }
  .ag-cell .cnt{ position:absolute; top:3px; right:4px; font-family:var(--a-mono); font-size:8px; color:var(--a-dim); }

  .ag-tools{ display:flex; gap:8px; margin-bottom:12px; flex-wrap:wrap; align-items:center; }
  .ag-quick{ flex:1 1 100%; border:1px dashed var(--a-line2); background:transparent; color:var(--a-acc);
    border-radius:10px; padding:9px 14px; font:inherit; font-size:12.5px; font-weight:600; cursor:pointer;
    transition:border-color .15s, background .15s; }
  :where(html.puntero) .ag-quick:hover{ border-color:var(--a-acc); background:color-mix(in srgb, var(--t-accent) 8%, transparent); }
  /* 🔴 LA LUPA, ARRIBA DE LA AGENDA (14/09/2026). Un solo objeto: lupa + campo + ✕.
     El campo va en 16px SIEMPRE: abajo de eso iOS hace zoom al enfocar, y eso era
     el "zoom" de esta sección. Pegado arriba mientras se scrollea la lista. */
  .ag-buscar{ position:sticky; top:-1px; z-index:3; display:flex; align-items:center; gap:10px; margin:0 0 14px;
    padding:0 12px 0 14px; min-height:46px; background:var(--a-input); border:1px solid var(--a-line); border-radius:14px;
    color:var(--a-dim); cursor:text; transition:border-color .15s; }
  .ag-buscar:focus-within{ border-color:var(--a-acc); color:var(--a-acc); }
  .ag-buscar .ico{ width:20px; height:20px; flex:none; }
  .ag-search{ flex:1; min-width:0; background:transparent; border:0; color:var(--a-ink); padding:11px 0; font-size:16px; font-family:inherit;
    -webkit-appearance:none; appearance:none; }
  .ag-search::placeholder{ color:var(--a-dim); }
  .ag-search:focus{ outline:none; }
  .ag-search::-webkit-search-decoration, .ag-search::-webkit-search-cancel-button{ -webkit-appearance:none; appearance:none; }
  .ag-buscar-x{ flex:none; width:32px; height:32px; border-radius:50%; border:0; background:var(--a-card2); color:var(--a-mut); font:inherit; font-size:13px; cursor:pointer; }
  .ag-buscar-x[hidden]{ display:none; }
  :where(html.puntero) .ag-buscar-x:hover{ color:var(--a-ink); }
  /* con una búsqueda escrita, en el teléfono los resultados van pegados a la lupa */
  @media (max-width:1023px){ #agViewAgenda.buscando > .ag-stats, #agViewAgenda.buscando > .ag-cal{ display:none; } }
  .ag-filter{ background:var(--a-input); border:1px solid var(--a-line); color:var(--a-ink); border-radius:999px; padding:9px 14px; font-size:12px; font-family:inherit; cursor:pointer; }
  /* el select también hace zoom en iOS abajo de 16px */
  @media (max-width:860px){ .ag-filter{ font-size:16px; padding:10px 16px; min-height:44px; } }
  .ag-filter:focus{ outline:none; border-color:var(--a-acc); }

  .ag-list{ display:flex; flex-direction:column; gap:14px; }
  .ag-folder{ border:1px solid var(--a-line); border-radius:12px; overflow:hidden; background:var(--a-bg); }
  .ag-folder-hd{ display:flex; align-items:center; gap:10px; width:100%; text-align:left; cursor:pointer;
    background:var(--a-card); border:0; color:var(--a-ink); padding:12px 14px; font-family:inherit;
    transition:background .15s; }
  :where(html.puntero) .ag-folder-hd:hover{ background:var(--a-card2); }
  .ag-folder-hd .chev{ width:14px; flex-shrink:0; color:var(--a-mut); transition:transform .2s; font-size:11px; }
  .ag-folder.collapsed .chev{ transform:rotate(-90deg); }
  .ag-folder-hd .fico{ font-size:15px; flex-shrink:0; }
  .ag-folder-hd .ftit{ font-weight:700; font-size:13.5px; letter-spacing:.2px; flex:1; }
  .ag-folder-hd .fmeta{ font-family:var(--a-mono); font-size:10.5px; color:var(--a-mut); text-align:right; line-height:1.4; flex-shrink:0; }
  .ag-folder-hd .fmeta b{ color:var(--a-acc); font-weight:700; }
  .ag-folder.confirm .ftit{ color:var(--a-green); }
  .ag-folder-hd .fcount{ display:inline-block; min-width:20px; text-align:center; background:var(--a-input);
    border:1px solid var(--a-line); border-radius:20px; padding:1px 7px; font-family:var(--a-mono);
    font-size:10px; color:var(--a-mut); }
  .ag-folder.confirm .fcount{ color:var(--a-green); border-color:color-mix(in srgb, var(--a-green) 40%, transparent); }   /* era un verde pastel fijo (24/09/2026) */
  .ag-folder-bd{ display:flex; flex-direction:column; gap:9px; padding:11px 11px 13px; }
  .ag-folder.collapsed .ag-folder-bd{ display:none; }
  .ag-folder-empty{ text-align:center; color:var(--a-dim); font-size:12px; padding:14px 8px; }
  .ag-item .meta{ display:flex; flex-wrap:wrap; gap:5px 8px; margin-top:7px; }
  .ag-item .chip{ font-family:var(--a-mono); font-size:9.5px; letter-spacing:.3px; color:var(--a-mut);
    background:var(--a-input); border:1px solid var(--a-line); border-radius:999px; padding:3px 9px; }
  .ag-item .chip b{ color:var(--a-ink); font-weight:700; }
  /* Ingreso suelto (cargado desde Números). Teal porque es el hueco de tono que
     quedaba: verde 145° ya es "confirmado", ámbar 37° "en espera", azul 215°
     "consultar", violeta 254° el acento y las anotaciones de agenda. Igual el color
     no carga solo con la identidad — el chip dice "💵 Ingreso" al lado. */
  .agenda{ --a-teal:var(--t-teal); }
  /* Reunión (10/09/2026): el color propio de una reunión en calendarios, puntos y chips. */
  .agenda{ --a-reunion:var(--t-reunion); }
  .bg-reunion{ background:var(--a-reunion, var(--t-reunion)); }
  .ag-item .chip.reunion{ color:var(--a-reunion); border-color:color-mix(in srgb, var(--t-reunion) 42%, transparent); }
  /* Día personal (15/09/2026): el color de los días que son de Tobi, en calendarios, puntos y chips. */
  .agenda{ --a-personal:var(--t-personal); }
  .bg-personal{ background:var(--a-personal, var(--t-personal)); }
  .ag-item .chip.personal{ color:var(--a-personal); border-color:color-mix(in srgb, var(--t-personal) 42%, transparent); }
  .ag-item .chip.ingreso{ color:var(--a-teal); border-color:color-mix(in srgb, var(--t-teal) 42%, transparent);
    background:color-mix(in srgb, var(--t-teal) 10%, transparent); font-weight:700; }
  .ag-empty{ text-align:center; color:var(--a-dim); font-size:12.5px; padding:30px 14px; line-height:1.6; }
  .ag-empty b{ color:var(--a-mut); display:block; margin-bottom:6px; font-size:13.5px; }
  .ag-item{ background:var(--a-card); border:1px solid var(--a-line); border-radius:11px; padding:12px 14px; transition:border-color .15s; }
  :where(html.puntero) .ag-item:hover{ border-color:var(--a-line2); }
  .ag-item .top{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
  /* El nombre es un <button> (es el control con el que el teclado llega a la
     ficha), así que hay que devolverle el aspecto de texto: un botón trae fondo,
     borde, padding y fuente propios del sistema. `text-align:left` porque los
     botones centran, y `width:100%` para que el ellipsis siga cortando igual. */
  .ag-item .nm{ font-weight:700; font-size:14.5px; letter-spacing:.1px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
    display:block; width:100%; text-align:left; background:none; border:0; padding:0;
    font-family:inherit; color:inherit; cursor:pointer; }
  /* La tarjeta entera abre la ficha: el cursor lo tiene que decir. */
  .ag-item{ cursor:pointer; }
  .ag-vacio-acts{ display:flex; gap:8px; justify-content:center; flex-wrap:wrap; margin-top:10px; }
  .ag-item .sub{ font-size:11.5px; color:var(--a-mut); margin-top:3px; line-height:1.45; }
  .ag-item .nro{ font-family:var(--a-mono); font-size:9px; letter-spacing:.4px; color:var(--a-dim); margin-top:6px; }
  .ag-item .amt{ font-family:var(--a-mono); font-weight:700; font-size:15px; color:var(--a-acc); white-space:nowrap; }
  /* Es un <button>: hay que devolverle fondo y tipografía, que el sistema le pone
     los suyos. Y `padding` en vez de alto fijo, para que el texto mande. */
  .ag-st{ display:inline-flex; align-items:center; gap:5px; font-size:9px; letter-spacing:1px; text-transform:uppercase; padding:4px 9px; border-radius:20px; border:1px solid var(--a-line2); cursor:pointer; user-select:none; transition:border-color .15s;
    background:transparent; font-family:inherit; }

  /* ===========================================================================
     ZONAS TACTILES DE LOS CONTROLES AISLADOS
     ===========================================================================
     🔴 LA CAJA CRECE DE VERDAD Y EL ESPACIO SE DEVUELVE CON MARGENES NEGATIVOS.
     Es el mismo patrón que ya usa `#hist .hinfo`, y ahí está escrito por qué NO
     se hace con un `::after` de 44px: el area parece grande pero cualquier
     hermano posterior le pinta encima —un absoluto sin z-index no sube de plano—
     y el toque termina cayendo en el vecino. Agrandando la caja, el hit-test es
     del propio elemento y no depende del orden del DOM.
     ⚠️ Solo los controles AISLADOS. En las filas densas (los cinco botones de
     acción de un item) agrandar cada caja empujaria el layout de toda la lista,
     que es justo lo que el pedido llama "deformar el diseño"; ahí lo que protege
     del error es la separación, no el tamaño. */
  .agenda-x, #numeros .agenda-x, #notis .agenda-x, #chatIA .ch-x{
    min-width:44px; min-height:44px; margin:-5px -5px -5px 0; }
  /* ⚠️ Sin margen negativo HORIZONTAL: ‹ Hoy › son tres hermanos pegados y con -7px
     a los costados se pisaban entre sí (medido en WebKit, 03/09/2026). */
  .ag-nav button{ min-width:44px; min-height:44px; margin:-7px 0; }
  #dash .dd-arrow{ min-width:44px; min-height:44px; }
  #dash .dcur{ min-height:44px; margin-block:-13px; }
  #dash .dchip.dtab{ min-height:38px; margin-block:-9px; }
  /* 🔴 SEGUNDA PASADA (03/09/2026): los controles que se tocan seguido en el celu y
     medían menos de 36px. Crece la CAJA y el layout absorbe el alto: son filas que
     tienen aire (las acciones de las alertas y los filtros van en filas que envuelven)
     o controles solos (la ✕ de la ficha, los chips del Agente). Medido en WebKit
     que ninguna caja agrandada pisa a otra interactiva. `.ag-act` (los cinco botones
     de un item de la Agenda) sube a 36px y no a 44: a 44 empujaba cada item 15px y
     la lista entera dejaba de entrar en pantalla; ahí sigue protegiendo la separación. */
  :is(#dash,#notis) .dalact{ min-height:40px; padding:0 12px; display:inline-flex; align-items:center; }
  :is(#dash,#notis) .dalacts{ gap:8px; }
  #dash .dchip.dnum{ min-height:40px; display:inline-flex; align-items:center; margin-block:-6px; }
  #dashFicha .fx{ min-width:44px; min-height:44px; margin-top:-7px; margin-bottom:-7px; }
  .ag-tab{ min-height:44px; }
  #hist .hchip{ min-height:40px; }
  .ag-act{ min-height:36px; }
  /* Los links de las alertas ("Ver evento →", "Ver tareas →") medían 13px de alto:
     la caja crece y el aire se devuelve, la fila no se mueve. */
  :is(#dash,#notis) .dallink{ min-height:40px; display:inline-flex; align-items:center; }
  /* El toggle de moneda de Números y el "Empezar de cero" del Agente: controles solos. */
  #numeros .nm-cur, .mt-curbar .nm-cur{ min-height:40px; margin-block:-8px; }
  #chatIA .ch-bar .limpiar{ min-height:40px; padding-inline:10px; }
  /* El chip de estado de un item de la Agenda mueve plata y medía 21px. */
  .ag-st{ min-height:32px; }
  #hist .hmas{ min-height:40px; }
  /* El botón del calendario dentro del campo de fecha: se agranda el área de golpe
     con un pseudo PROPIO (está dentro del botón, así que el hit-test es del botón y
     no depende del orden del DOM — el problema del ::after era en hermanos). */
  .pick-btn{ overflow:visible; }
  .pick-btn::before{ content:''; position:absolute; inset:-6px; }
  #dash .dcalhd button{ min-width:40px; min-height:40px; margin:-7px; }
  /* ⚠️ LOS QUE NO SE TOCAN, Y POR QUE. `.ag-act` (29px de alto) son los cinco
     botones de accion de un item y `.hchip` (31px) los filtros del Historial: los
     dos viven en FILAS DENSAS, y ahi agrandar cada caja empuja el layout de la
     lista entera — el borde es visible, asi que el truco del margen negativo no
     los disimula. En una fila densa lo que protege del error no es el tamaño sino
     la separacion, que ya la tienen. Queda anotado a proposito: no es un olvido. */
  :where(html.puntero) .ag-st:hover{ border-color:var(--a-mut); }
  .ag-st::before{ content:""; width:7px; height:7px; border-radius:50%; }
  .ag-st.confirmado{ color:var(--a-green); } .ag-st.confirmado::before{ background:var(--a-green); }
  /* ⚠️ Este era el ÚNICO de los cuatro chips con el color escrito a mano; los otros
     tres ya usaban var(--a-amber). Al reforzar la paleta el 27/08/2026 quedaba del
     tono viejo mientras sus hermanos cambiaban — un ámbar distinto en la misma fila. */
  .ag-st.espera{ color:var(--a-amber); } .ag-st.espera::before{ background:var(--a-amber); }
  .ag-st.consultar{ color:var(--a-blue); } .ag-st.consultar::before{ background:var(--a-blue); }
  /* Rechazado reusa el rojo que la app ya tiene (--a-red), no un tono nuevo. El chip
     siempre lleva la palabra al lado, así que la identidad nunca depende del color —
     que es la condición para poder usar un rojo acá sin pasar por el validador de
     paletas, al revés de lo que pasa en las barras de Métricas, donde el color ES el
     dato y por eso el rechazado NO se apila (ver renderMetrics). */
  .ag-st.rechazado{ color:var(--a-red); } .ag-st.rechazado::before{ background:var(--a-red); }
  .ag-item .acts{ display:flex; gap:6px; margin-top:11px; flex-wrap:wrap; }
  .ag-act{ border:1px solid var(--a-line); background:var(--a-card); color:var(--a-mut); border-radius:7px; padding:6px 11px; font-size:11px; cursor:pointer; font-family:inherit; transition:color .15s, border-color .15s; }
  :where(html.puntero) .ag-act:hover{ color:var(--a-ink); border-color:var(--a-acc); }
  :where(html.puntero) .ag-act.danger:hover{ color:var(--a-red); border-color:var(--a-red); }
  .ag-act.danger.armed{ color:#fff; background:var(--a-red); border-color:var(--a-red); font-weight:700; }
  /* Estado "armado" del patrón de dos toques para los botones que NO son .ag-act.danger
     (Vaciar todo, Importar, Vaciar lista). Tienen que verse igual de rojos: el confirm()
     nativo no aparece en la PWA instalada de iPhone, así que la única confirmación
     posible es la que se dibuja en el propio botón. El fallback del color es porque
     --a-red se define en .agenda y "Vaciar lista" vive afuera, en el módulo #manualEq. */
  button.armed{ color:#fff; background:var(--a-red,#e5484d); border-color:var(--a-red,#e5484d); font-weight:700; }
  .ag-act.cal{ color:var(--a-mut); }
  :where(html.puntero) .ag-act.cal:hover{ color:var(--a-ink); border-color:var(--a-acc); }

  /* --navh ya trae adentro el env(safe-area-inset-bottom): el pie tiene que quedar
     arriba de la tab bar, que le flota encima (barra z-950, cajón z-81).

     El `max()` es red de seguridad: si por lo que sea --navh quedara CORTO, la barra le
     pasa por arriba a los tres botones y quedan cortados abajo de todo — que es
     justamente el bug que se reportó. El piso es la misma estimación que el CSS usa de
     fallback (54px de barra + el safe-area del aparato), así que cuando la medición está
     bien los dos valores coinciden y esto no cambia nada. En escritorio la barra es más
     baja y el piso no aplica: se lo saca el override del media query de 1024px. */
  .ag-foot{ border-top:1px solid var(--a-line);
    padding:13px 22px max(calc(13px + var(--nav-bot, 0px)), calc(13px + 54px + env(safe-area-inset-bottom)));
    display:flex; gap:8px; flex-wrap:wrap; flex-shrink:0; background:var(--a-bg2); }
  .ag-foot button{ border:1px solid var(--a-line); background:var(--a-card); color:var(--a-mut); border-radius:7px; padding:9px 12px; font-size:11.5px; cursor:pointer; font-family:inherit; transition:color .15s,border-color .15s; }
  :where(html.puntero) .ag-foot button:hover{ color:var(--a-ink); border-color:var(--a-acc); }
  /* Estados del botón de Google Calendar: conectado, y "hay cosas sin subir / hay que
     reconectar". Reusa las variables de la paleta de la Agenda, no inventa hex. */
  /* Avisos push en el cajón de notificaciones (#notis hereda --d-*). */
  #notis .push-box{ margin:18px 0 8px; padding:14px 16px; background:var(--d-card); border:1px solid var(--d-line); border-radius:12px; }
  #notis .push-hd{ font-size:10.5px; letter-spacing:2px; text-transform:uppercase; color:var(--d-mut); margin-bottom:8px; }
  #notis .push-txt{ font-size:13px; line-height:1.5; color:var(--d-dim); }
  #notis .push-txt b{ color:var(--d-ink); }
  #notis .push-acts{ display:flex; gap:8px; flex-wrap:wrap; margin-top:12px; }
  #notis .push-acts .push-on{ color:var(--d-ink); border-color:var(--d-acc); }
  #notis .push-msg{ font-size:12px; color:var(--d-mut); margin-top:8px; min-height:1em; }
  #notis .push-msg:empty{ display:none; }
  /* El desplegable "Datos ▸" del pie: el summary se ve como un botón más del pie y
     los tres botones aparecen a su lado al abrirlo. Sin marcador nativo (el ▸ va
     escrito) y con el mismo tamaño táctil que el resto. */
  /* ⚠️ NO `display:contents` en el <details>: en WebKit le saca la caja al elemento y
     los hijos se pintan aunque esté cerrado (medido: "Vaciar todo" visible con
     open=false). Va como flex normal, y el ocultado se escribe explícito además
     del nativo. */
  .ag-foot details.ag-datos{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
  .ag-foot details.ag-datos summary{ list-style:none; cursor:pointer; border:1px solid var(--a-line); background:var(--a-card); color:var(--a-mut);
    border-radius:7px; padding:9px 12px; font-size:11.5px; user-select:none; }
  .ag-foot details.ag-datos summary::-webkit-details-marker{ display:none; }
  .ag-foot details.ag-datos summary::after{ content:" ▸"; opacity:.7; }
  .ag-foot details.ag-datos[open] summary::after{ content:" ▾"; }
  .ag-foot details.ag-datos[open] summary{ color:var(--a-ink); border-color:var(--a-acc); }
  .ag-foot details.ag-datos .ag-datos-b{ display:flex; gap:8px; flex-wrap:wrap; }
  .ag-foot details.ag-datos:not([open]) .ag-datos-b{ display:none; }
  .ag-foot button.gcal-on{ color:var(--a-green); border-color:color-mix(in srgb, var(--a-green) 45%, transparent); }
  .ag-foot button.gcal-warn{ color:var(--a-amber); border-color:rgba(233,177,76,.5); }

  #btnAgenda .agcount{ display:inline-block; min-width:17px; text-align:center; margin-left:7px; background:var(--acc); color:#fff; font-family:var(--mono,'SFMono-Regular',Menlo,monospace); font-size:10px; font-weight:700; border-radius:10px; padding:1px 5px; vertical-align:middle; }

  /* 26px por encima de la tab bar: el toast está en z-90 y la barra en z-950, así que
     sin sumarle --navh el aviso salía tapado por la barra de navegación. */
  .ag-toast{ position:fixed; left:50%; bottom:calc(26px + var(--nav-bot, 0px)); transform:translateX(-50%) translateY(20px); z-index:10100; /* 23/09/2026: en z-90 quedaba DEBAJO del Panel (900), la ficha (10060) y el chat (10070): los errores de guardado y los avisos no se veían */
    background:var(--uicard); border:1px solid var(--acc); color:var(--uitext); padding:11px 18px; border-radius:10px;
    font-size:13px; box-shadow:0 18px 40px -18px rgba(0,0,0,.8); opacity:0; pointer-events:none; transition:opacity .25s, transform .25s;
    display:flex; align-items:center; gap:9px; font-family:'Helvetica Neue',Arial,sans-serif; max-width:88vw; }
  .ag-toast.show{ opacity:1; transform:translateX(-50%) translateY(0); }
  .ag-toast .dot{ width:8px; height:8px; border-radius:50%; background:var(--acc); flex-shrink:0; }

  @media (max-width:560px){
    .ag-stats{ gap:7px; }
    .ag-stat{ padding:9px 10px; }
    .ag-stat .v{ font-size:16px; }
    .agenda-hd{ padding:calc(14px + env(safe-area-inset-top)) 16px 13px; }
    .agenda-body{ padding:14px 16px 22px; }
    .ag-foot{ padding:11px 16px max(calc(11px + var(--nav-bot, 0px)), calc(11px + 54px + env(safe-area-inset-bottom))); }
  }

  /* En escritorio la barra es un pill de 44px y no hay safe-area: el piso de 54px de
     arriba sobraría, así que acá el pie vuelve a ser solo lo que mide la barra. */
  @media (min-width:1024px){
    .ag-foot{ padding-bottom:calc(13px + var(--nav-bot, 0px)); }
  }

  
  #introOverlay{ position:fixed; inset:0; z-index:99999; background:var(--t-intro-bg);
    background:radial-gradient(circle at 50% 34%,var(--t-intro-bg-2) 0%,var(--t-intro-bg) 64%);
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    touch-action:none; will-change:transform; overscroll-behavior:none; }
  /* Acá había `cursor:grab` (más una regla `.grabbing`), resto del "swipe to enter"
     que esta pantalla tuvo alguna vez. La clase no la pone nadie desde hace rato, y
     ahora que lo único que se toca es el logo, una manito de arrastrar sobre el fondo
     dice justo lo que no es. */
  #introOverlay.leaving{ transition:transform .55s cubic-bezier(.7,0,.2,1), opacity .55s ease; }
  #introLogo{ width:100%; height:auto; display:block; position:relative; z-index:2;
    -webkit-user-drag:none; user-select:none; pointer-events:none; filter:brightness(0) invert(1); }

  /* ---------------------------------------------------------------------------
     EL AURA DEL LOGO — el degradé animado siguiendo el CONTORNO DE LAS LETRAS.

     🔴 EL ANILLO NO ES UN RECTÁNGULO: es el propio PNG del logo usado como MÁSCARA.
     La primera versión enmarcaba la caja (como el cajón del Agente Pro, que sí es un
     rectángulo) y quedaba un cuadrado pegado alrededor del logo. Acá el recorte tiene
     que ser la silueta.

     Cómo se engorda la silueta sin filtros: `mask-image` acepta VARIAS capas, así que
     va el mismo PNG ocho veces corrido en ocho direcciones (cada 45°, a `--r` de
     distancia). La unión de las ocho es la silueta dilatada — un halo de --r px
     alrededor de cada letra. El centro lo tapa el propio logo blanco, que va ENCIMA
     (z-index 2): por eso solo se ve el borde.

     ⚠️ A propósito NO se usa `mask-composite` para restar el centro, aunque sería el
     camino "correcto". Las capas de máscara se componen en orden inverso entre el
     `mask-composite` del estándar y el `-webkit-mask-composite` viejo de Safari: si el
     orden se da vuelta, en iOS la resta se convierte en unión y en vez del contorno
     ves la silueta rellena. Tapando el centro con el logo opaco no hay operador que
     pueda salir mal, y de paso el borde antialiaseado del PNG hace que el color se
     funda con la letra en vez de cortar seco.

     🔴 LA TÉCNICA DEL COLOR ES ROTAR UN ELEMENTO, NO ANIMAR EL GRADIENTE. Animar el
     `from` de un conic-gradient con @property se ve igual en la compu pero REPINTA la
     textura en cada frame — y esta es la primera pantalla que se ve al abrir la app,
     con la PWA arrancando en frío. Rotando con `transform` el trabajo lo hace el
     compositor. Mismo criterio (y mismos comentarios) que `#chatIA .ch-aura`.
     ⚠️ Keyframes propios (`introGirar`) y no los del chat: el CSS de keyframes es
     global y compartirlos andaría, pero dejaría esta pantalla dependiendo de que el
     cajón del agente siga existiendo. */
  /* 🔴 `backwards` y NO `forwards`. Con `forwards` la animación de entrada se queda
     "pegada" en su último keyframe (opacity:1, transform:none) y eso le GANA a
     cualquier valor declarado después: los estados de abajo (.entrando con su
     scale, el :active) no tendrían ningún efecto y parecerían rotos. Con
     `backwards` el fill es solo hacia atrás — cubre los .15s de delay para que no
     haya flash — y al terminar mandan los valores declarados acá. Misma razón por la
     que el aura tiene su propio `introAuraIn` con un `from` explícito. */
  #introLogoBox{
    position:relative; width:min(72vw,340px); opacity:1;
    transition:transform .35s cubic-bezier(.2,.7,.2,1);
    animation:introLogoIn 1s cubic-bezier(.2,.7,.2,1) .15s backwards;
    /* La misma paleta "PRO" del agente, con el violeta del medio = var(--acc) de la
       app. Es lo que hace que el efecto se lea como parte del producto. */
    --pro-1:#22d3ee; --pro-2:#3b82f6; --pro-3:#8b6cf5; --pro-4:#ec4899; --pro-5:#f59e0b;
    --r:3px;     /* grosor del contorno */
    --pad:8px;   /* aire alrededor del logo; tiene que ser MAYOR que --r o el halo se corta */
  }
  /* 🔴 El aura vive escondida hasta que el JS copia el logo de la portada y escribe
     `--lg`. Sin esa guarda, `mask-image:var(--lg)` con la variable sin definir es una
     declaración inválida: el navegador la descarta, el elemento queda SIN máscara y
     lo que se ve es el rectángulo de colores entero. */
  #introLogoBox .intro-aura{ display:none; }
  #introLogoBox.conlogo .intro-aura{ display:block; }

  #introLogoBox .intro-aura{
    position:absolute; inset:calc(var(--pad) * -1); z-index:1; pointer-events:none;
    overflow:hidden;
    opacity:1; animation:introAuraIn 1.2s ease .5s backwards;
    /* `paint` y no `strict`: strict incluye contain:size, y con la máscara Safari
       calcula el elemento como si no tuviera dimensiones. */
    contain:layout paint;
    /* El logo dentro de una caja `--pad` más grande de cada lado: la máscara se
       dibuja del tamaño exacto del <img> y centrada, así calza pixel a pixel. */
    --m:var(--lg);
    --sz:calc(100% - var(--pad) * 2);
    --d:calc(var(--r) * .7071);   /* la diagonal del octógono */
    -webkit-mask-image:var(--m),var(--m),var(--m),var(--m),var(--m),var(--m),var(--m),var(--m);
            mask-image:var(--m),var(--m),var(--m),var(--m),var(--m),var(--m),var(--m),var(--m);
    -webkit-mask-repeat:no-repeat,no-repeat,no-repeat,no-repeat,no-repeat,no-repeat,no-repeat,no-repeat;
            mask-repeat:no-repeat,no-repeat,no-repeat,no-repeat,no-repeat,no-repeat,no-repeat,no-repeat;
    -webkit-mask-size:var(--sz) var(--sz),var(--sz) var(--sz),var(--sz) var(--sz),var(--sz) var(--sz),
                      var(--sz) var(--sz),var(--sz) var(--sz),var(--sz) var(--sz),var(--sz) var(--sz);
            mask-size:var(--sz) var(--sz),var(--sz) var(--sz),var(--sz) var(--sz),var(--sz) var(--sz),
                      var(--sz) var(--sz),var(--sz) var(--sz),var(--sz) var(--sz),var(--sz) var(--sz);
    -webkit-mask-position:
      calc(50% + var(--r)) 50%,            calc(50% - var(--r)) 50%,
      50% calc(50% + var(--r)),            50% calc(50% - var(--r)),
      calc(50% + var(--d)) calc(50% + var(--d)), calc(50% - var(--d)) calc(50% + var(--d)),
      calc(50% + var(--d)) calc(50% - var(--d)), calc(50% - var(--d)) calc(50% - var(--d));
            mask-position:
      calc(50% + var(--r)) 50%,            calc(50% - var(--r)) 50%,
      50% calc(50% + var(--r)),            50% calc(50% - var(--r)),
      calc(50% + var(--d)) calc(50% + var(--d)), calc(50% - var(--d)) calc(50% + var(--d)),
      calc(50% + var(--d)) calc(50% - var(--d)), calc(50% - var(--d)) calc(50% - var(--d));
    /* 🔴 El cuadrado que gira tiene que llegar a la DIAGONAL de la caja, y un % en
       `width` se resuelve contra el ANCHO: si queda corto, al rotar los extremos se
       salen del gradiente y el color se pierde en las esquinas. 200% deja margen de
       sobra sin pintar textura al pedo. El margen negativo tiene que ser exactamente
       la mitad, por eso el lado va en variable y no repetido a mano. */
    --aura-lado:min(200%, 150vmax);
  }
  #introLogoBox .intro-aura::before{
    content:''; position:absolute; top:50%; left:50%;
    width:var(--aura-lado); aspect-ratio:1;
    margin:calc(var(--aura-lado) * -0.5) 0 0 calc(var(--aura-lado) * -0.5);
    background:conic-gradient(var(--pro-1),var(--pro-2),var(--pro-3),var(--pro-4),
                              var(--pro-5),var(--pro-4),var(--pro-3),var(--pro-2),var(--pro-1));
    animation:introGirar 8s linear infinite;
    will-change:transform;
  }
  @keyframes introGirar{ to{ transform:rotate(1turn); } }
  /* `from` explícito: introHintIn solo tiene `to`, así que con fill `backwards`
     tomaría como origen el valor declarado (opacity:1) y no se vería entrar. */
  @keyframes introAuraIn{ from{ opacity:0; } to{ opacity:1; } }

  /* ---------------------------------------------------------------------------
     LA PANTALLA DE BLOQUEO NO TIENE BOTONES: EL LOGO ES EL BOTÓN.

     Tocarlo dispara el Face ID. Los estados los lleva `#introOverlay` (y no la caja
     del logo) porque además del contorno tienen que mover el texto de abajo, que es
     hermano. Cada estado habla por el mismo contorno de colores, que en esta pantalla
     es el único elemento vivo:
       · validando -> acelera y el logo late
       · entrando  -> acelera más y el logo crece, justo antes de que el overlay suba
       · nope      -> el contorno se pone rojo
     🔴 `nope` cambia las custom properties de la paleta, NO agrega un keyframe. Un
     keyframe acá reemplazaría al `introLogoIn` del shorthand, y al sacar la clase el
     logo se volvería a desvanecer desde cero en cada reintento. */
  #introOverlay.logo-boton #introLogoBox{ cursor:pointer; -webkit-tap-highlight-color:transparent; }
  #introOverlay.logo-boton #introLogoBox:active{ transform:scale(.97); }
  #introLogoBox:focus-visible{ outline:2px solid var(--pro-3); outline-offset:14px; border-radius:10px; }

  #introOverlay.validando #introLogoBox .intro-aura::before{ animation-duration:2s; }
  #introOverlay.validando #introLogo{ animation:introLatir 1.3s ease-in-out infinite; }
  @keyframes introLatir{ 0%,100%{ opacity:1; } 50%{ opacity:.5; } }

  #introOverlay.entrando #introLogoBox{ transform:scale(1.07); }
  #introOverlay.entrando #introLogoBox .intro-aura::before{ animation-duration:.9s; }

  #introOverlay.nope #introLogoBox{
    --pro-1:#ff7a7a; --pro-2:#ff5f5f; --pro-3:#ff4d6d; --pro-4:#ff8a5c; --pro-5:#ff5f5f; }

  /* 🔴 En las dos pantallas del logo no hay NI UNA palabra: ni instrucción ni pregunta.
     La app es de una sola persona, que ya sabe que el logo se toca. Lo único que puede
     aparecer es el mensaje de error, y solo cuando algo falló — un fallo mudo dejaría
     la pantalla igual que antes de tocar y parecería que el toque no registró.
     `:empty` es lo que hace que, sin error, el bloque no ocupe ni un píxel y el logo
     quede centrado de verdad en vez de corrido hacia arriba por un hueco invisible. */
  #introLock, #introEnrol{ margin-top:0; }
  #introLockErr{ color:#ff8a8a; font-size:12px; margin-top:30px;
    font-family:'SFMono-Regular',Menlo,monospace; letter-spacing:.3px; }
  #introLockErr:empty{ display:none; }
  @media (prefers-reduced-motion:reduce){
    #introLogoBox .intro-aura{ animation:none; }
    #introLogoBox .intro-aura::before{ animation:none; }
    #introLogo{ animation:none; }
  }
  @keyframes introLogoIn{ from{ opacity:0; transform:translateY(14px) scale(.93); } to{ opacity:1; transform:none; } }
  @keyframes introHintIn{ to{ opacity:1; } }
  #introForm{ margin-top:44px; display:flex; flex-direction:column; align-items:center; gap:14px;
    opacity:0; animation:introHintIn .8s ease .95s forwards; }
  #introForm input{ width:min(72vw,260px); padding:12px 16px; border-radius:10px; border:1px solid color-mix(in srgb, var(--t-ink) 18%, transparent);
    background:color-mix(in srgb, var(--t-ink) 6%, transparent); color:var(--t-ink); font-size:16px; text-align:center; outline:none; }
  #introForm input::placeholder{ color:color-mix(in srgb, var(--t-ink) 40%, transparent); }
  #introForm input:focus{ border-color:#8f7dff; }
  #introForm input:disabled{ opacity:.5; }
  #introEnterBtn{ padding:11px 30px; border-radius:10px; border:none; background:#8f7dff; color:#0a0e18;
    font-weight:700; font-size:14px; cursor:pointer; }
  #introEnterBtn:active{ transform:scale(.97); }
  #introErr{ color:#ff8a8a; font-size:12px; font-family:'SFMono-Regular',Menlo,monospace; letter-spacing:.5px; min-height:14px; }
  /* 🔴 POR QUÉ ESTA PANTALLA PIDE LA CONTRASEÑA. El arranque era mudo: para mostrar el
     logo hacen falta TRES cosas (sesión persistida + passkey guardada + WebAuthn) y
     cuando falta una cualquiera se cae al formulario sin decir cuál. El síntoma llega
     un día después de la causa —"hoy me pidió la clave y antes no"— así que sin esto se
     diagnostica adivinando, y encima en la PWA instalada no hay consola ni barra de
     direcciones para mirarlo. Es una línea apagada, para sacarle una foto. */
  #introWhy{ margin-top:18px; max-width:min(84vw,330px); text-align:center;
    color:color-mix(in srgb, var(--t-ink) 34%, transparent); font-size:10.5px; line-height:1.65; white-space:pre-line;
    font-family:'SFMono-Regular',Menlo,monospace; letter-spacing:.3px;
    opacity:0; animation:introHintIn .8s ease 1.15s forwards; }
  /* `hidden` tiene que ganarle al display:flex de los paneles */
  #introOverlay [hidden]{ display:none !important; }
  /* ---- panel de bloqueo (Face ID) y panel de alta de passkey ---- */
  #introLock, #introEnrol{ margin-top:44px; display:flex; flex-direction:column; align-items:center; gap:14px;
    opacity:0; animation:introHintIn .8s ease .5s forwards; text-align:center; }
  /* Acá vivían el candado 🔒, el texto "La app está bloqueada" y los botones grandes
     (#introBio "Desbloquear" y #introEnrolSi "Activar Face ID"). Se fueron con ellos:
     las dos pantallas son el logo y nada más. `.introAlt` se queda porque son las dos
     salidas de emergencia, que siguen apareciendo si el Face ID falla. */
  .introAlt{ display:flex; align-items:center; gap:10px; margin-top:2px; }
  .introAlt button{ background:none; border:0; color:#8f8fa6; font-family:inherit; font-size:12px;
    text-decoration:underline; cursor:pointer; padding:4px; }
  :where(html.puntero) .introAlt button:hover{ color:var(--t-ink); }
  .introAlt span{ color:#4a4c60; font-size:11px; }

  /* #dashFicha (modal de ficha técnica) y #notis (el cajón de notificaciones)
     comparten la base para no duplicar la paleta. Cada uno sobreescribe abajo lo
     único distinto: z-index, fondo y overflow.
     🔴 `#notis` TIENE que estar acá. Vive a nivel de `body`, no adentro de `#dash`
     (si colgara del panel, `unSoloScroll()` le pondría `dash-sin-scroll` y en
     mobile se quedaría sin scroll propio — el mismo motivo por el que `#chatIA`
     está afuera). Y como no es descendiente de `#dash`, sin esta línea no hereda
     una sola de las variables `--d-*` y el panel de alertas se ve como texto plano
     sin tarjetas ni colores. Salió al probarlo. */
  #dash, #dashFicha, #notis, #hist, #desglose{
    /* Paleta del diseño. Validada con el validador de la skill dataviz contra el fondo
       var(--t-panel-bg): pasa piso de croma, separación en daltonismo (ΔE 10.5 protan) y contraste.
       Falla solo la banda de luminosidad, que aplica a rellenos grandes — acá estos tres
       colores se usan en texto, puntitos y la barra de 8px, nunca en relleno grande.
       Las barras de "Eventos por mes" son de un solo tono (acento vs apagado), así que
       no entran en esa categoría. Los --m-* de la pestaña Métricas NO se tocan. */
    --d-canvas:var(--t-panel-bg); --d-card:var(--t-panel-surface); --d-card2:var(--t-panel-surface-2); --d-line:var(--t-panel-line);
    --d-line2:var(--t-panel-line-2);
    --d-ink:var(--t-panel-ink); --d-mut:var(--t-panel-muted); --d-dim:var(--t-panel-dim);
    /* 🔴 REFORZADOS EL 27/08/2026: los anteriores se veían "desgastados" y no era
       una impresión — eran pasteles medidos. Croma OKLCH 0.123 / 0.147 / 0.128 y
       luminosidad 0.72–0.79, o sea claros y sin saturación. La ganancia: verde
       +39%, ámbar +19%, azul +38%, rojo +26% de croma.
       ⚠️ EL ÁMBAR ADEMÁS CAMBIÓ DE TONO, no solo de fuerza: de H73 (amarillo
       anaranjado) a H63, que es ámbar de verdad. Fue un pedido explícito.
       ⚠️ El violeta subió poco de croma pero arregla algo que estaba mal: tenía
       contraste 4.43 sobre la tarjeta, POR DEBAJO del 4.5 que necesita un texto;
       ahora da 4.89.
       🔴 NO LOS CAMBIES A OJO. Validados con el validador de la skill dataviz
       contra la superficie real de la rueda (`--d-card` var(--t-panel-surface)):
         node scripts/validate_palette.js "var(--t-ok),var(--t-warn),var(--t-info)" --mode dark --surface "var(--t-panel-surface)"
       Pasan croma, separación en daltonismo (ΔE 11.3 protan, contra 10.5 de los
       viejos) y contraste. Falla solo la banda de luminosidad, que aplica a
       RELLENOS MACIZOS: acá son texto, puntitos y el anillo de 13px de la rueda,
       que es una marca fina. Es la misma excepción que ya valía antes. */
    --d-green:var(--t-ok); --d-amber:var(--t-warn); --d-blue:var(--t-info); --d-red:var(--t-err); --d-acc:var(--t-panel-accent);
    /* el calendario reusa las clases .ag-* , que dependen de estas variables */
    --a-input:var(--d-card2); --a-card2:var(--d-card2); --a-line:var(--d-line2); --a-line2:var(--d-line2);
    --a-mut:var(--d-mut); --a-dim:var(--d-mut); --a-acc:var(--d-acc);
    --a-green:var(--d-green); --a-amber:var(--d-amber); --a-blue:var(--d-blue); --a-red:var(--d-red);
    --d-reunion:var(--t-reunion); --a-reunion:var(--d-reunion);
    --d-personal:var(--t-personal); --a-personal:var(--d-personal);
    --a-mono:ui-monospace,'SF Mono',Menlo,monospace;
  }

  /* 🔴 EL LAYOUT VA APARTE DE LA PALETA, Y `#notis` NO ENTRA ACÁ. Los dos de arriba
     son overlays a pantalla completa que arrancan en `display:none`; `#notis` es un
     cajón `.agenda`, que es `display:flex` siempre y se esconde con un `transform`.
     Cuando esto era un solo bloque y se le sumó `#notis` para que heredara las
     variables, el cajón se llevó también el `display:none` y **no abría nunca**: el
     JS le ponía la clase `open`, el velo aparecía, y atrás no había nada. Salió al
     probarlo. ⚠️ Si mañana otro overlay necesita la paleta, va arriba (variables) y
     NO acá abajo. */
  #dash, #dashFicha{
    position:fixed; inset:0; z-index:900; overflow-y:auto; display:none;
    background:var(--d-canvas); color:var(--d-ink);
    font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; font-size:12.5px;
  }
  #dash.on{ display:block; }

  #dash::-webkit-scrollbar{ width:8px; height:8px; }
  #dash::-webkit-scrollbar-thumb{ background:color-mix(in srgb, var(--t-ink) 12%, transparent); border-radius:4px; }
  #dash .dwrap{ max-width:1400px; margin:0 auto;
    padding:calc(26px + var(--nav-top, 0px)) 32px calc(52px + var(--nav-bot, 0px)); box-sizing:border-box; }

  /* ---- header ---- */
  #dash .dtop{ display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:16px; margin-bottom:22px; }
  #dash .dtopl{ display:flex; align-items:center; gap:20px; }
  /* La campana y el Agente Pro, juntos. Ver el comentario del HTML: sueltos, el
     `space-between` de .dtop los mandaba a filas distintas en el celu. */
  #dash .dtopr{ display:flex; align-items:center; gap:9px; flex:none; }
  #dash .dlogo{ height:28px; width:auto; display:block; flex:none; }
  /* 🔴 EL LOGO ES UN PNG BLANCO: en claro se invierte con un filter (mismo patrón que
     la Quinta), en los TRES lugares de la interfaz donde aparece. Las páginas del PDF
     (.page .logo) NO: son el papel, no la interfaz. */
  #introLogo, .btn.dashlogo img, #dash .dlogo{ filter:var(--t-logo-filter); }
  #dash .dsep{ width:1px; height:28px; background:var(--d-line2); }
  #dash .dtop h1{ margin:0; font-size:20px; font-weight:700; letter-spacing:-.2px; }
  #dash .dtop h1 span{ color:var(--d-mut); font-weight:400; }
  #dash .dacts{ display:flex; gap:12px; }
  #dash .dbtn{ display:flex; align-items:center; gap:8px; background:var(--d-card); color:var(--d-ink);
    border:1px solid var(--d-line2); border-radius:9px; padding:9px 14px;
    font:inherit; font-size:12.5px; font-weight:600; cursor:pointer; transition:border-color .14s; }
  :where(html.puntero) #dash .dbtn:hover{ border-color:var(--d-acc); }
  #dash .dbtn.primary{ background:var(--d-ink); color:var(--d-canvas); border-color:var(--d-ink); font-weight:700; }
  :where(html.puntero) #dash .dbtn.primary:hover{ filter:brightness(.94); border-color:var(--d-ink); }

  /* ---- layout ---- */
  #dash .dgrid{ display:grid; grid-template-columns:minmax(0,2fr) minmax(0,1fr); gap:18px; align-items:start; }
  #dash .dcol{ display:flex; flex-direction:column; gap:18px; min-width:0; }
  #dash .dpanel{ background:var(--d-card); border:1px solid var(--d-line); border-radius:14px; padding:20px 22px; }
  #dash .dpanel.sm{ padding:18px 20px; }
  #dash .dpanel h2{ margin:0; font-size:10.5px; font-weight:700; letter-spacing:1.5px; text-transform:uppercase; color:var(--d-mut); }
  #dash .dmono{ font-family:var(--a-mono); font-variant-numeric:tabular-nums; }

  /* ---- alertas (notificaciones etapa 1) ----
     Va ARRIBA de .dgrid, o sea lo primero que se ve después del header: la gracia es
     que salte sola a la vista, no tener que ir a buscarla. Sin scroll propio (regla
     "UN SOLO SCROLL" del panel) y sin ocultarse en mobile: es donde más sirve. */
  /* ---- El panel de alertas ----
     🔴 `:is(#dash,#notis)` Y NO `#dash` PELADO, desde el 27/08/2026. Este bloque se
     mudó al cajón de notificaciones, que vive a nivel de `body` y NO es descendiente
     de `#dash`: con el prefijo viejo, adentro del cajón se veía como texto plano —
     sin tarjetas, sin colores y sin espaciado. Se usa `:is()` en vez de duplicar las
     34 reglas justamente para que no puedan divergir, y **no cambia la especificidad**
     (`:is()` toma la del selector más específico del grupo, que acá es un id en los
     dos casos). ⚠️ Regla nueva de alertas → sale con este mismo prefijo. */
  :is(#dash,#notis) .dalert{ background:var(--d-card); border:1px solid var(--d-line); border-radius:14px;
    padding:18px 22px; margin-bottom:18px; border-left:3px solid var(--d-amber); }
  /* Sin nada pendiente se colapsa a una línea discreta en vez de ocupar media
     pantalla para decir que no hay nada. */
  :is(#dash,#notis) .dalert.ok{ border-left-color:var(--d-green); padding:13px 22px; }
  :is(#dash,#notis) .dalert.ok .dalhd{ margin-bottom:0; }
  :is(#dash,#notis) .dalert.ok .dalt{ color:var(--d-mut); font-weight:600; }
  /* Estado "no pude leer": ni alarma ni "todo al día", que sería mentir. */
  :is(#dash,#notis) .dalert.off{ border-left-color:var(--d-mut); }
  :is(#dash,#notis) .dalhd{ display:flex; align-items:center; justify-content:space-between; gap:14px;
    flex-wrap:wrap; margin-bottom:14px; }
  :is(#dash,#notis) .dalt{ display:flex; align-items:center; gap:9px; font-size:13.5px; font-weight:700; }
  :is(#dash,#notis) .dalt .ico{ font-size:14px; line-height:1; }
  :is(#dash,#notis) .dalcfg{ font-size:10.5px; color:var(--d-mut); font-family:var(--a-mono); white-space:nowrap; }
  :is(#dash,#notis) .dalgrp{ margin-top:12px; }
  :is(#dash,#notis) .dalgrp:first-of-type{ margin-top:0; }
  :is(#dash,#notis) .dalgh{ display:flex; align-items:center; justify-content:space-between; gap:12px;
    font-size:11.5px; font-weight:600; color:var(--d-dim); margin-bottom:8px; }
  :is(#dash,#notis) .dalrow{ display:flex; align-items:center; justify-content:space-between; gap:12px;
    padding:9px 12px; background:var(--d-card2); border-radius:9px; margin-bottom:6px; }
  :is(#dash,#notis) .dalrow:last-child{ margin-bottom:0; }
  :is(#dash,#notis) .dalrow .l{ min-width:0; }
  :is(#dash,#notis) .dalrow .nm{ font-weight:600; font-size:12.5px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  :is(#dash,#notis) .dalrow .mt{ font-size:11px; color:var(--d-mut); margin-top:2px; }
  :is(#dash,#notis) .dalrow .r{ display:flex; align-items:center; gap:10px; flex:none; }
  :is(#dash,#notis) .daldias{ font-family:var(--a-mono); font-size:11px; font-weight:700; padding:4px 9px;
    border-radius:20px; white-space:nowrap; background:color-mix(in srgb, var(--t-warn) 14%, transparent); color:var(--d-amber); }
  :is(#dash,#notis) .daldias.mucho{ background:color-mix(in srgb, var(--t-err) 16%, transparent); color:var(--d-red); }
  :is(#dash,#notis) .dallink{ background:none; border:0; color:var(--d-acc); font:inherit; font-size:11.5px;
    font-weight:600; cursor:pointer; padding:0; white-space:nowrap; }
  :where(html.puntero) :is(#dash,#notis) .dallink:hover{ text-decoration:underline; }
  :is(#dash,#notis) .dalmas{ font-size:11px; color:var(--d-mut); margin-top:7px; }

  /* ---- Comparables (Fase 11) ----
     ⚠️ z-index 10055: arriba de la vista previa del PDF (10051) y abajo de la ficha
     (10060). Se abre desde el presupuestador (z-50), así que con el 81 de fábrica de
     `.agenda` quedaría tapado por cualquier overlay — mismo caso que #numeros.
     🔴 Y va en BLOQUEAN del carrusel como `#pricing.open`, CON la clase: el cajón
     vive siempre en el DOM y se esconde con transform, así que el selector pelado
     mataría el gesto desde el arranque. */
  #pricing{ z-index:10055; }
  #pricing [hidden]{ display:none !important; }
  /* 🔴 LOS DOS BLOQUES SE VEN DISTINTOS A PROPÓSITO. El documento pide «separar
     claramente datos históricos de recomendación inferida», y separarlos solo con un
     subtítulo no alcanza: lo inferido va enmarcado y con su fundamento escrito
     adentro, para que no se lea como un dato más. */
  #pricing .pr-sec{ font-size:10px; font-weight:800; letter-spacing:1.6px;
    color:var(--a-mut,var(--t-panel-muted)); margin:22px 0 10px; text-transform:uppercase; }
  #pricing .pr-grid{ display:grid; grid-template-columns:repeat(2,1fr); gap:8px; }
  #pricing .pr-kpi{ background:var(--a-card2,var(--t-panel-surface-2)); border:1px solid var(--a-line2,var(--t-panel-line-2));
    border-radius:11px; padding:11px 12px; }
  #pricing .pr-kpi .k{ font-size:10.5px; color:var(--a-mut,var(--t-panel-muted)); }
  #pricing .pr-kpi .v{ font-family:var(--a-mono,monospace); font-size:17px; font-weight:700; margin-top:3px; }
  #pricing .pr-kpi .n{ font-size:10px; color:var(--a-mut,var(--t-panel-muted)); margin-top:2px; }
  #pricing .pr-rec{ border:1px solid #4a3c1c; background:#1f1a10; border-radius:13px; padding:15px; }
  #pricing .pr-rec .et{ font-size:9.5px; font-weight:800; letter-spacing:1.5px; color:#f2c86b; }
  #pricing .pr-rec .rango{ font-family:var(--a-mono,monospace); font-size:15px; color:#f2c86b; margin-top:8px; }
  #pricing .pr-rec .sug{ font-family:var(--a-mono,monospace); font-size:25px; font-weight:700; color:#f2c86b; margin-top:6px; }
  #pricing .pr-rec .por{ font-size:11.5px; color:#c9b98c; margin-top:9px; line-height:1.5; }
  #pricing .pr-nada{ border:1px solid var(--a-line2,var(--t-panel-line-2)); background:var(--a-card2,var(--t-panel-surface-2));
    border-radius:13px; padding:15px; font-size:12.5px; color:var(--a-mut,var(--t-panel-muted)); line-height:1.55; }
  #pricing .pr-fila{ display:flex; align-items:center; gap:10px; padding:9px 11px;
    background:var(--a-card2,var(--t-panel-surface-2)); border-radius:9px; margin-bottom:6px; font-size:12px; }
  #pricing .pr-fila .l{ flex:1; min-width:0; }
  #pricing .pr-fila .l b{ display:block; font-size:12.5px; overflow:hidden;
    text-overflow:ellipsis; white-space:nowrap; }
  #pricing .pr-fila .l span{ font-size:10.5px; color:var(--a-mut,var(--t-panel-muted)); }
  #pricing .pr-fila .m{ flex:none; font-family:var(--a-mono,monospace); font-size:12.5px; font-weight:700; }
  #pricing .pr-nota{ font-size:11px; color:var(--a-mut,var(--t-panel-muted)); margin-top:8px; line-height:1.5; }

  /* ==================== MODO EVENTO (Fase 10, 26/08/2026) ====================
     «Crear una interfaz especial para usar el día del evento. Botón: INICIAR
      EVENTO. Mostrar solamente información operativa. Diseñar primero para teléfono.»

     🔴 ESTA ES LA ÚNICA PANTALLA DE LA APP QUE SE USA CON EL TELÉFONO EN LA MANO,
     PARADO Y A OSCURAS. Todo lo demás sigue de ahí: tipografía grande, contraste
     alto, botones del tamaño de un pulgar y NADA que no sirva en ese momento.

     🔴 z-index 10080: por encima de TODO lo demás (el chat está en 10070 y el panel
     de stock en 10075). Si quedara debajo, "iniciar evento" abriría una pantalla
     tapada — que es exactamente el bug que ya tuvo el panel de rental.
     ⚠️ Va con `inset:0` y NUNCA con `dvh`: en la PWA instalada `100dvh` resuelve más
     bajo que la pantalla y deja una franja del fondo abajo de todo. Ya probado.
     ========================================================================== */
  #modoEv{ position:fixed; inset:0; z-index:10080; display:none;
    background:#0a0b0f; color:#f2f4f8; overflow-y:auto; -webkit-overflow-scrolling:touch; }
  #modoEv.on{ display:block; }
  #modoEv .me-wrap{ max-width:620px; margin:0 auto;
    padding:calc(14px + env(safe-area-inset-top)) 16px calc(64px + env(safe-area-inset-bottom)); }
  #modoEv .me-hd{ display:flex; align-items:flex-start; gap:12px; margin-bottom:6px; }
  #modoEv .me-vivo{ font-size:10px; font-weight:800; letter-spacing:1.6px;
    color:#0a0b0f; background:var(--d-green,#1ed48c); padding:3px 8px; border-radius:5px; }
  #modoEv .me-cli{ font-size:26px; font-weight:800; line-height:1.15; margin-top:8px; }
  #modoEv .me-sub{ font-size:13px; color:#9aa4b5; margin-top:4px; }
  #modoEv .me-x{ margin-left:auto; flex:none; width:40px; height:40px; border-radius:11px;
    background:#171a22; border:1px solid #262c38; color:#c7cede; font-size:20px; cursor:pointer; }

  /* El bloque de arriba: la hora, en grande. Es lo que se mira de reojo. */
  #modoEv .me-ahora{ margin:16px 0; padding:16px; border-radius:14px;
    background:#12151d; border:1px solid #222836; }
  /* 🔴 Escala con el ancho y NO parte en dos líneas. Es lo que se mira de reojo,
     parado y de lejos: "21:00 → 05:00 (+1)" cortado en dos renglones se lee peor que
     el mismo texto un poco más chico. A 375px queda en 24px, que entra justo. */
  #modoEv .me-hora{ font-family:var(--a-mono,monospace); font-size:clamp(20px,6.4vw,30px);
    font-weight:700; letter-spacing:.5px; white-space:nowrap; }
  #modoEv .me-falta{ font-size:13px; color:#9aa4b5; margin-top:6px; }
  #modoEv .me-falta b{ color:#f2f4f8; }

  #modoEv .me-sec{ font-size:10.5px; font-weight:800; letter-spacing:1.8px;
    color:var(--d-acc,#9a70ff); margin:26px 0 10px; text-transform:uppercase; }
  #modoEv .me-card{ background:#12151d; border:1px solid #222836; border-radius:12px;
    padding:13px 14px; margin-bottom:8px; font-size:14.5px; line-height:1.5; }
  #modoEv .me-k{ font-size:11.5px; color:#8792a5; }

  /* 🔴 Los contactos son BOTONES GRANDES, no texto con un link chiquito: se tocan
     con una mano, apurado y sin mirar. 48px de alto es el mínimo táctil cómodo. */
  #modoEv .me-cont{ display:flex; align-items:center; gap:10px; margin-bottom:8px; }
  #modoEv .me-cont .n{ flex:1; min-width:0; }
  #modoEv .me-cont .n b{ display:block; font-size:14.5px; }
  #modoEv .me-cont .n span{ font-size:11.5px; color:#8792a5; }
  #modoEv .me-btn{ flex:none; min-width:48px; height:48px; padding:0 14px; border-radius:12px;
    display:inline-flex; align-items:center; justify-content:center; gap:6px;
    background:#1b2130; border:1px solid #2c3444; color:#dfe5f0; font-size:17px;
    text-decoration:none; cursor:pointer; }
  #modoEv .me-btn:active{ background:#232b3c; }
  #modoEv .me-btn.maps{ flex:1; font-size:14.5px; font-weight:700;
    background:#1d2b22; border-color:#2f4a38; color:#8fe0ae; }

  /* Checklist: fila entera clickeable, no un checkbox de 14px. */
  #modoEv .me-chk{ display:flex; align-items:center; gap:12px; padding:13px 14px;
    background:#12151d; border:1px solid #222836; border-radius:12px; margin-bottom:7px;
    cursor:pointer; font-size:14.5px; user-select:none; }
  /* ⚠️ El ✓ va TRANSPARENTE hasta que se tilda. Con el color oscuro del fondo se
     veía igual —apenas, pero se veía— y un casillero vacío que ya muestra un tilde
     fantasma se lee como si estuviera a medio marcar. */
  #modoEv .me-chk .box{ flex:none; width:24px; height:24px; border-radius:7px;
    border:2px solid #39425a; display:flex; align-items:center; justify-content:center;
    font-size:14px; color:transparent; }
  #modoEv .me-chk.ok{ opacity:.5; }
  #modoEv .me-chk.ok .box{ background:var(--d-green,#1ed48c); border-color:var(--d-green,#1ed48c); }
  #modoEv .me-chk.ok .t{ text-decoration:line-through; }
  #modoEv .me-chk .t{ flex:1; min-width:0; }

  /* 🔴 EL ÚNICO NÚMERO DE PLATA DE TODA LA PANTALLA. El documento pide esconder las
     métricas y lo financiero «que no sea necesario durante el evento» — y el saldo SÍ
     lo es, porque se cobra ese día. Total, gastos, ganancia, comisión y métricas no
     entran acá: no sirven parado en un salón y son justo lo que no querés que se vea
     si alguien te mira la pantalla por encima del hombro. */
  #modoEv .me-saldo{ background:#1f1a10; border:1px solid #4a3c1c; color:#f2c86b;
    border-radius:14px; padding:16px; text-align:center; }
  #modoEv .me-saldo .v{ font-family:var(--a-mono,monospace); font-size:26px; font-weight:700; }
  #modoEv .me-vacio{ font-size:13px; color:#6f7889; padding:4px 2px 10px; }

  /* El botón que la abre, cuando hay evento hoy. */
  #dash .me-go{ display:flex; align-items:center; justify-content:center; gap:9px;
    width:100%; margin:0 0 14px; padding:15px; border-radius:13px; cursor:pointer;
    font-size:14px; font-weight:800; letter-spacing:1.2px;
    background:linear-gradient(135deg,#1d7a4a,#2aa365); border:0; color:#fff; }
  #dash .me-go:active{ filter:brightness(.92); }
  #dash .me-go .cu{ font-weight:500; letter-spacing:0; opacity:.85; }

  @media (min-width:1024px){
    /* En escritorio no molesta, pero esto está pensado para el celular: se deja
       legible y centrado, sin agrandar más. */
    #modoEv .me-cli{ font-size:30px; }
  }

  /* ---- acciones rápidas de seguimiento (Fase 5) ----
     🔴 La fila pasa a `align-items:flex-start`: con la barra de acciones adentro de
     la columna izquierda, centrar verticalmente dejaba el "N d" y el "Ver evento →"
     flotando a media altura del bloque en vez de alineados con el nombre. */
  :is(#dash,#notis) .dalrow:has(.dalacts){ align-items:flex-start; }
  :is(#dash,#notis) .dalacts{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:7px; }
  :is(#dash,#notis) .dalact{ font:inherit; font-size:10.5px; font-weight:600; cursor:pointer;
    padding:4px 9px; border-radius:7px; white-space:nowrap;
    background:var(--d-card); border:1px solid var(--d-line2); color:var(--d-fg); }
  :where(html.puntero) :is(#dash,#notis) .dalact:hover{ border-color:var(--d-acc); color:var(--d-acc); }
  :is(#dash,#notis) .dalact.mal{ border-color:var(--d-red); color:var(--d-red); }
  :is(#dash,#notis) .dalult{ font-size:10.5px; color:var(--d-mut); }
  /* 🔴 EL FALLO SE DICE EN LA FILA, no por toast: el cajón puede estar scrolleado y
     el toast vive abajo de todo — en el celular no se ve. Cantar "✓" sobre una
     escritura que no entró es la mentira que esta app ya pagó cara. */
  :is(#dash,#notis) .dalult.mal{ color:var(--d-red); font-weight:700; }

  /* ===========================================================================
     TAREAS DEL EVENTO — la sección de la ficha.
     ===========================================================================
     🔴 Los objetivos táctiles llegan a 44px agrandando la caja de verdad y
     devolviendo el espacio con márgenes negativos: es el patrón que ya usa la app
     (ver `#hist .hinfo`), y está documentado por qué NO se hace con un `::after` de
     44px — un absoluto sin z-index no sube de plano y el toque cae en el vecino. */
  #dashFicha .ftar{ display:flex; flex-direction:column; gap:2px; }
  #dashFicha .ftar-row{ position:relative; display:flex; align-items:flex-start; gap:10px;
    padding:7px 2px; border-radius:8px; }
  #dashFicha .ftar-row.hecha .ftar-txt{ opacity:.5; text-decoration:line-through; }
  #dashFicha .ftar-chk{ flex:0 0 auto; width:44px; height:44px; margin:-11px -11px -11px -11px;
    display:flex; align-items:center; justify-content:center;
    background:none; border:0; cursor:pointer; color:var(--d-acc); font-size:15px; font-weight:800;
    -webkit-tap-highlight-color:transparent; }
  #dashFicha .ftar-chk::before{ content:''; width:19px; height:19px; border-radius:6px;
    border:1.5px solid var(--d-line2); position:absolute; }
  #dashFicha .ftar-chk[aria-checked="true"]::before{ border-color:var(--d-acc); background:color-mix(in srgb, var(--t-panel-accent) 16%, transparent); }
  #dashFicha .ftar-txt{ flex:1; min-width:0; padding-top:2px; font-size:13px; color:var(--d-ink);
    word-break:break-word; }
  /* Las dos aclaraciones van chiquitas y apagadas: son contexto, no el dato. */
  #dashFicha .ftar-pend, #dashFicha .ftar-men{ display:block; font-style:normal;
    font-size:10.5px; color:var(--d-mut); margin-top:2px; }
  /* "No se pudo guardar en este dispositivo" no es un estado de espera: es una
     pérdida inminente, y se ve distinto. */
  #dashFicha .ftar-pend.mal{ color:var(--d-red); font-weight:700; }
  #dashFicha .ftar-mas{ flex:0 0 auto; width:44px; height:44px; margin:-11px -11px -11px 0;
    background:none; border:0; color:var(--d-mut); font-size:17px; cursor:pointer;
    -webkit-tap-highlight-color:transparent; }
  #dashFicha .ftar-msg{ position:absolute; right:46px; top:10px; font-size:10.5px; color:var(--d-mut); }
  #dashFicha .ftar-msg.mal{ color:var(--d-red); font-weight:700; }
  /* El menú del ⋯ y el editor: los dos se dibujan sobre la fila. */
  #dashFicha .ftar-pop{ position:absolute; right:0; top:40px; z-index:3;
    display:flex; flex-direction:column; min-width:168px;
    background:var(--d-card); border:1px solid var(--d-line2); border-radius:10px;
    box-shadow:0 10px 30px rgba(0,0,0,.5); overflow:hidden; }
  #dashFicha .ftar-pop button{ min-height:44px; padding:0 14px; text-align:left;
    background:none; border:0; color:var(--d-ink); font:inherit; font-size:12.5px; cursor:pointer; }
  #dashFicha .ftar-pop button.mal{ color:var(--d-red); }
  #dashFicha .ftar-edit{ flex-basis:100%; display:flex; flex-wrap:wrap; gap:7px; margin-top:7px; }
  #dashFicha .ftar-alta{ margin-top:9px; }
  #dashFicha .ftar-add{ min-height:44px; padding:0 14px; border-radius:9px;
    background:none; border:1px dashed var(--d-line2); color:var(--d-dim);
    font:inherit; font-size:12.5px; cursor:pointer; }
  #dashFicha .ftar-form{ display:flex; flex-wrap:wrap; gap:7px; align-items:center; }
  /* 🔴 EL `hidden` PIERDE CONTRA `display:flex`: los dos pesan igual (0,1,0 contra
     0,1,0) y gana el que va después en la hoja, así que el formulario del alta
     aparecía SIEMPRE, al lado del botón que tenía que abrirlo. Es el mismo choque
     que este proyecto ya documentó para `#numeros [hidden]` y para `.warn[hidden]`,
     y no se ve leyendo el archivo: salió en la captura. */
  #dashFicha .ftar-form[hidden]{ display:none !important; }
  /* 🔴 16px: abajo de eso iOS hace zoom al enfocar y, como la ficha es `fixed`, la
     pantalla queda descuadrada encima del contenido. Misma regla que `.fld`. */
  #dashFicha .ftar-form input, #dashFicha .ftar-edit input{
    flex:1; min-width:150px; min-height:44px; padding:0 11px; border-radius:9px;
    background:var(--d-card2); border:1px solid var(--d-line2); color:var(--d-ink);
    font:inherit; font-size:16px; }
  #dashFicha .ftar-ok, #dashFicha .ftar-no{ min-height:44px; padding:0 15px; border-radius:9px;
    border:1px solid var(--d-line2); background:var(--d-card2); color:var(--d-ink);
    font:inherit; font-size:12.5px; font-weight:700; cursor:pointer; }
  #dashFicha .ftar-ok{ border-color:var(--d-acc); color:var(--d-acc); }
  #dashFicha .ftar-ok:disabled{ opacity:.5; cursor:default; }
  :where(html.puntero) #dashFicha .ftar-row:hover{ background:color-mix(in srgb, var(--t-ink) 3%, transparent); }
  :where(html.puntero) #dashFicha .ftar-pop button:hover{ background:color-mix(in srgb, var(--t-ink) 6%, transparent); }
  :where(html.puntero) #dashFicha .ftar-add:hover{ border-color:var(--d-acc); color:var(--d-acc); }

  /* La actividad: cerrada por defecto y con el resumen como control táctil. */
  #dashFicha .ftar-act, #dash .dtar-act{ margin-top:9px; }
  #dashFicha .ftar-act > summary, #dash .dtar-act > summary{
    display:flex; align-items:center; min-height:44px; padding:0 4px;
    color:var(--d-mut); font-size:12px; cursor:pointer; list-style:none;
    -webkit-tap-highlight-color:transparent; }
  #dashFicha .ftar-act > summary::-webkit-details-marker,
  #dash .dtar-act > summary::-webkit-details-marker{ display:none; }
  #dashFicha .ftar-act > summary::before, #dash .dtar-act > summary::before{
    content:'▸'; margin-right:7px; transition:transform .15s ease; }
  #dashFicha .ftar-act[open] > summary::before, #dash .dtar-act[open] > summary::before{
    transform:rotate(90deg); }
  #dashFicha .ftar-act-caja, #dash .dtar-act-caja{ padding:2px 4px 6px; }
  #dashFicha .ftar-act-fila, #dash .dtar-act-caja .ftar-act-fila{
    display:flex; flex-wrap:wrap; gap:6px; align-items:baseline;
    padding:5px 0; border-top:1px solid var(--d-line); font-size:11.5px; }
  #dashFicha .ftar-act-q, #dash .dtar-act-caja .ftar-act-q{ color:var(--d-dim); font-weight:700; }
  #dashFicha .ftar-act-det, #dash .dtar-act-caja .ftar-act-det{
    color:var(--d-mut); flex:1; min-width:0; word-break:break-word; }
  #dashFicha .ftar-act-f, #dash .dtar-act-caja .ftar-act-f{ color:var(--d-mut); opacity:.8; }
  /* 🔴 LA BANDEJA DE CONFLICTOS. Va en rojo y arriba de la lista: es un gesto que la
     persona hizo y que la base rechazó, o sea lo único de este panel que exige una
     decisión. El ✕ descarta a conciencia, no reintenta. */
  #dash .dconf{ border:1px solid var(--d-red); border-radius:9px; padding:8px 10px;
    margin:0 0 9px; background:color-mix(in srgb, var(--t-err) 10%, transparent); font-size:11.5px; }
  #dash .dconf > b{ color:var(--d-red); display:block; margin-bottom:5px; }
  #dash .dconf-i{ display:flex; gap:8px; align-items:flex-start;
    padding:5px 0; border-top:1px solid color-mix(in srgb, var(--t-err) 22%, transparent); }
  #dash .dconf-i:first-of-type{ border-top:0; }
  #dash .dconf-i > span{ flex:1; min-width:0; word-break:break-word; color:var(--d-dim); }
  #dash .dconf-i em{ display:block; color:var(--d-mut); font-style:normal; opacity:.85; }
  #dash .dconf-i > .x{ background:none; border:0; color:var(--d-red); font-size:16px;
    line-height:1; cursor:pointer; padding:4px 6px; margin:-4px -6px; }

  /* Un movimiento que todavía no llegó a la base se ve distinto: no es historia
     confirmada. */
  #dashFicha .ftar-act-fila.pend, #dash .dtar-act-caja .ftar-act-fila.pend{ opacity:.65; font-style:italic; }
  :where(html.puntero) #dashFicha .ftar-act > summary:hover,
  :where(html.puntero) #dash .dtar-act > summary:hover{ color:var(--d-ink); }

  /* ---- ingresos ---- */
  /* El header de este panel lleva el botón de "Números" al lado del título. Se anula
     el margen de .dhd porque .dbig ya trae el suyo (8px) y sumados quedaban 24px. */
  #dash .dhd.numhd{ margin-bottom:0; align-items:center; }
  #dash .dchip.dnum{ background:var(--d-card2); color:var(--d-mut); font-size:10.5px;
    padding:5px 11px; border:1px solid transparent; white-space:nowrap; }
  :where(html.puntero) #dash .dchip.dnum:hover{ color:var(--d-ink); border-color:var(--d-acc); }
  /* ---- el selector de mes (07/09/2026) ----
     ‹ Mes AAAA › + dos <select> + "Mes actual". Los dos <select> van en 16px
     por la regla de siempre: abajo de eso iOS hace zoom al enfocar y el panel,
     que es fixed, queda descuadrado. Los botones de flecha miden 40px. */
  #dash .dper{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin:4px 0 10px; }
  #dash .dper-nav{ border:0; background:var(--d-card2); color:var(--d-mut); width:40px; height:40px;
    border-radius:20px; font:inherit; font-size:18px; line-height:1; cursor:pointer; flex:none; }
  :where(html.puntero) #dash .dper-nav:hover{ color:var(--d-ink); }
  #dash .dper-lab{ display:flex; flex-direction:column; min-width:0; flex:1 1 120px; }
  #dash .dper-lab b{ font-family:var(--a-mono); font-size:14px; color:var(--d-ink); letter-spacing:.02em; }
  #dash .dper-lab small{ font-size:10.5px; color:var(--d-mut); line-height:1.4; }
  #dash .dper-lab small b{ font-family:inherit; font-size:inherit; color:var(--d-amber); }
  #dash .dper-ctl{ display:flex; gap:6px; align-items:center; flex:1 0 100%; }
  @media (min-width:1024px){ #dash .dper-ctl{ flex:0 0 auto; margin-left:auto; } }
  #dash .dper-sel{ display:inline-flex; }
  #dash .dper-sel .vh{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
  #dash .dper-sel select{ font:inherit; font-size:16px; min-height:40px; padding:0 8px; border-radius:10px;
    border:1px solid var(--d-line); background:var(--d-card2); color:var(--d-ink); }
  #dash .dchip.dper-hoy{ min-height:40px; display:inline-flex; align-items:center; font-size:11px; color:var(--d-acc);
    background:color-mix(in srgb, var(--t-panel-accent) 14%, transparent); font-weight:600; }
  #dash .dkpi.estado .k{ color:var(--d-amber); }
  #dash .dw-lrow .dw-mes{ font-style:normal; font-size:10px; color:var(--d-mut); font-weight:400; }
  #dash .dwheel.mesvacio{ display:none; }
  #dash .dmesvacio{ padding:22px 8px; font-size:12.5px; }
  #dash .dmesvacio b{ color:var(--d-ink); font-size:14px; }
  #dash .dmesvacio .dchip{ margin-top:10px; }
  #dash .dmesvacio-saldo{ display:inline-block; margin-top:10px; }
  /* El acceso al asistente. Va con el violeta de acento y más grande que un chip
     común: es la acción principal del header, no un filtro. */

  /* ---- La campana (27/08/2026) ----
     Al lado del Agente Pro y con su mismo alto, para que el header lea como una
     fila de acciones y no como dos cosas sueltas. */
  #dash .dchip.dnoti{ position:relative; flex:none; font-size:16px; line-height:1;
    padding:7px 11px; border-radius:10px; background:var(--d-card2);
    border:1px solid var(--d-line2); }
  :where(html.puntero) #dash .dchip.dnoti:hover{ background:var(--d-line2); }
  /* 🔴 44px de lado mínimo: es el objetivo táctil que hace falta para el pulgar.
     Con el padding solo quedaba en 30px de alto y en el celu se erra. */
  #dash .dchip.dnoti{ min-width:44px; min-height:44px; }

  /* El punto. Arranca invisible con `scale(0)` y NO con `display:none`, para que
     al aparecer pueda animarse — un punto que se materializa de golpe en una
     esquina no se registra, y este es el único aviso que queda en pantalla. */
  #dash .dchip.dnoti .pt{ position:absolute; top:5px; right:6px; width:9px; height:9px;
    border-radius:50%; background:var(--d-red); transform:scale(0); transition:transform .22s cubic-bezier(.34,1.56,.64,1);
    /* El borde del color del header lo despega del emoji que tiene abajo. */
    box-shadow:0 0 0 2px var(--d-bg); }
  /* 🔴 LOS DOS ESTADOS MUESTRAN EL PUNTO, no solo `hay`. La primera versión escalaba
     el punto únicamente con `.hay` y le cambiaba el color con `.duda`: o sea que el
     caso "no pude leer" pintaba de ámbar un punto que seguía en scale(0) y no se veía
     — la campana quedaba idéntica a "no tenés nada", que es justo lo que este estado
     existe para no decir. */
  #dash .dchip.dnoti.hay .pt,
  #dash .dchip.dnoti.duda .pt{ transform:scale(1); }
  /* Ámbar y no rojo cuando NO SE PUDO LEER: "tenés 3 cosas para revisar" y "no sé
     qué tenés" son dos estados distintos y el mismo punto rojo para los dos haría
     que el segundo se leyera como el primero. Es la misma regla que ya cumple el
     panel de adentro, que nunca dice "al día" sin sesión. */
  #dash .dchip.dnoti.duda .pt{ background:var(--d-amber); }
  #dash .dchip.dnoti.hay{ border-color:color-mix(in srgb, var(--t-err) 45%, transparent); }
  #dash .dchip.dnoti.duda{ border-color:color-mix(in srgb, var(--t-warn) 45%, transparent); }
  @media (prefers-reduced-motion:reduce){
    #dash .dchip.dnoti .pt{ transition:none; }
  }
  #dash .dbig{ font-family:var(--a-mono); font-size:34px; font-weight:800; line-height:1.05;
    margin:8px 0 3px; font-variant-numeric:tabular-nums; }
  #dash .dbigrow{ display:flex; align-items:center; justify-content:space-between; margin-bottom:16px; flex-wrap:wrap; gap:8px; }
  #dash .dsub{ font-size:12.5px; color:var(--d-mut); }
  #dash .dsub b{ color:var(--d-ink); font-weight:600; }
  #dash .dcur{ display:flex; align-items:center; gap:8px; font-size:12px; color:var(--d-mut); cursor:pointer;
    background:var(--d-card2); border:1px solid var(--d-line2); border-radius:20px; padding:5px 10px;
    font:inherit; font-size:11px; transition:border-color .14s; }
  :where(html.puntero) #dash .dcur:hover{ border-color:var(--d-acc); }
  #dash .dcur i{ width:6px; height:6px; border-radius:50%; background:var(--d-blue); display:inline-block; flex:none; }
  #dash .dcur b{ font-family:var(--a-mono); color:var(--d-dim); font-weight:600; }
  /* ================= LA RUEDA (27/08/2026) =================
     Reemplaza al número grande suelto + la barra de composición (`.dcompo`, que se
     borró). SVG y CSS nativos, sin librería de gráficos.
     🔴 Escritorio: rueda a la izquierda, leyenda a la derecha. Mobile: rueda
     centrada y leyenda compacta debajo. El breakpoint es el mismo 1024 de toda la
     app; acá se resuelve con `flex-wrap` y un `min-width`, así que no hace falta
     repetirlo. */
  #dash .dwheel{ display:flex; align-items:center; gap:28px; flex-wrap:wrap;
    margin:6px 0 20px; }
  #dash .dw-ring{ position:relative; width:212px; height:212px; flex:none; }
  #dash .dw-svg{ width:100%; height:100%; display:block;
    /* Arranca a las 12 en punto y no a las 3, que es de donde salen los ángulos en
       SVG: una torta que empieza a la derecha se lee torcida. */
    transform:rotate(-90deg); }
  #dash .dw-track{ fill:none; stroke:color-mix(in srgb, var(--t-ink) 5.5%, transparent); stroke-width:13; }
  #dash .dw-seg{ fill:none; stroke-width:13; stroke-linecap:butt;
    /* El dibujado se anima cambiando SOLO `stroke-dasharray`. El `opacity` es para
       el atenuado al elegir un segmento; los dos son propiedades baratas. */
    transition:stroke-dasharray .9s cubic-bezier(.32,.72,0,1), opacity .22s ease;
    cursor:pointer; }
  #dash .dw-seg[data-est="confirmado"]{ stroke:var(--d-green); }
  #dash .dw-seg[data-est="espera"]    { stroke:var(--d-amber); }
  #dash .dw-seg[data-est="consultar"] { stroke:var(--d-blue); }
  /* Un segmento en 0 no puede recibir el toque: sin esto, la franja invisible sigue
     capturando clicks sobre la que está al lado. */
  #dash .dw-seg.vacio{ pointer-events:none; }
  #dash .dw-segs.elegido .dw-seg{ opacity:.28; }
  #dash .dw-segs.elegido .dw-seg.on{ opacity:1; }
  :where(html.puntero) #dash .dw-seg:hover{ opacity:.85; }
  :where(html.puntero) #dash .dw-segs.elegido .dw-seg.on:hover{ opacity:1; }

  /* El centro. Es un botón que ocupa el hueco del donut. */
  #dash .dw-mid{ position:absolute; inset:26px; border:0; background:none; padding:0;
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:2px; color:inherit; font:inherit; text-align:center; border-radius:50%;
    cursor:default; }
  #dash .dw-mid.puedeVolver{ cursor:pointer; }
  #dash .dw-mid .k{ font-size:9.5px; font-weight:700; letter-spacing:1.4px;
    text-transform:uppercase; color:var(--d-mut); }
  #dash .dw-mid .dbig{ margin:0; font-size:25px; }
  #dash .dw-mid .dsub{ font-size:11px; line-height:1.25; max-width:118px; }
  /* El color del centro sigue al segmento elegido: es lo que ata el número a la
     porción que tocaste sin tener que repetir el nombre del estado. */
  #dash .dw-mid.confirmado .dbig{ color:var(--d-green); }
  #dash .dw-mid.espera     .dbig{ color:var(--d-amber); }
  #dash .dw-mid.consultar  .dbig{ color:var(--d-blue); }
  /* El ojito, en el header al lado de "Números". `margin-left:auto` lo empuja a la
     derecha; el chip de Números queda pegado a él. 44px de objetivo táctil. */
  #dash .dw-eye{ margin-left:auto; font-size:15px; padding:0 8px; line-height:1;
    /* 44px de lado: es un botón que se toca con el pulgar, no un adorno del
       encabezado. Se ve más chico de lo que mide porque el emoji no llena la caja. */
    min-width:44px; min-height:44px; opacity:.5; }
  :where(html.puntero) #dash .dw-eye:hover{ opacity:1; }

  /* El skeleton: mientras no hay datos, un anillo apagado con un tramo que gira. */
  #dash .dw-skel{ position:absolute; inset:0; border-radius:50%;
    border:13px solid color-mix(in srgb, var(--t-ink) 5.5%, transparent);
    border-top-color:color-mix(in srgb, var(--t-ink) 16%, transparent);
    animation:dwSpin 1.1s linear infinite; }
  @keyframes dwSpin{ to{ transform:rotate(360deg); } }
  #dash .dwheel.listo .dw-skel{ display:none; }
  /* Sin datos todavía NO se muestran ceros: el centro queda vacío hasta que llegan.
     Un "USD 0" mientras carga se lee como un dato real y es el mismo error que el
     panel ya evita al no mostrar ceros sin sesión. */
  #dash .dwheel:not(.listo) .dw-mid{ opacity:0; }
  #dash .dw-mid{ transition:opacity .25s ease; }

  /* La leyenda. Tres filas, cada una con su punto, nombre, monto y %. */
  #dash .dw-leg{ flex:1; min-width:210px; display:flex; flex-direction:column; gap:2px; }
  #dash .dw-lrow{ display:flex; align-items:center; gap:10px; width:100%;
    background:none; border:0; padding:9px 8px; border-radius:9px; cursor:pointer;
    color:inherit; font:inherit; text-align:left;
    /* 44px de objetivo táctil: es una fila que se toca con el pulgar. */
    min-height:44px;
    transition:background .16s ease, opacity .2s ease; }
  :where(html.puntero) #dash .dw-lrow:hover{ background:color-mix(in srgb, var(--t-ink) 4%, transparent); }
  #dash .dw-leg.elegido .dw-lrow{ opacity:.45; }
  #dash .dw-leg.elegido .dw-lrow.on{ opacity:1; background:color-mix(in srgb, var(--t-ink) 6%, transparent); }
  #dash .dw-lrow .pt{ width:10px; height:10px; border-radius:3px; flex:none; }
  #dash .dw-lrow .nm{ flex:1; min-width:0; font-size:12.5px; font-weight:600; }
  #dash .dw-lrow .nm small{ display:block; font-weight:400; font-size:10.5px;
    color:var(--d-mut); margin-top:1px; }
  #dash .dw-lrow .mo{ font-family:var(--a-mono); font-size:13px; font-weight:700;
    font-variant-numeric:tabular-nums; white-space:nowrap; }
  #dash .dw-lrow .pc{ font-family:var(--a-mono); font-size:11px; color:var(--d-mut);
    min-width:38px; text-align:right; font-variant-numeric:tabular-nums; }
  /* Entrada de la leyenda: fade + 6px hacia arriba, escalonada. El delay lo pone el
     JS con una custom property, para no escribir tres reglas casi iguales. */
  #dash .dw-lrow{ opacity:0; transform:translateY(6px); }
  #dash .dwheel.listo .dw-lrow{ animation:dwLegIn .34s cubic-bezier(.32,.72,0,1) both;
    animation-delay:var(--d,0ms); }
  @keyframes dwLegIn{ from{ opacity:0; transform:translateY(6px); }
                      to{ opacity:1; transform:none; } }
  /* Con un segmento elegido el opacity lo manda `.elegido`, así que el keyframe no
     puede quedar pegado: por eso `both` y no `forwards` en el shorthand de arriba
     sería lo mismo — lo que importa es que la regla de `.elegido` viene después. */

  /* 🔴 prefers-reduced-motion: se muestra el estado final YA. Nada de animaciones,
     ni el giro del skeleton, ni el dibujado, ni el count-up (ese lo corta el JS). */
  @media (prefers-reduced-motion:reduce){
    #dash .dw-seg{ transition:opacity .22s ease; }
    #dash .dw-skel{ animation:none; }
    #dash .dwheel.listo .dw-lrow{ animation:none; opacity:1; transform:none; }
    #dash .dw-mid{ transition:none; }
  }

  /* ================= PRÓXIMOS DÍAS · agenda horizontal (27/08/2026) ================= */
  #dash .dd-nav{ display:flex; gap:6px; }
  /* Las flechas son de escritorio: en táctil se arrastra con el dedo y dos botones
     más ahí serían dos cosas que ocupan lugar y nadie toca. */
  #dash .dd-arrow{ width:30px; height:30px; border-radius:8px; cursor:pointer;
    background:var(--d-card2); border:1px solid var(--d-line2); color:var(--d-mut);
    font-size:15px; line-height:1; font-family:inherit; }
  :where(html.puntero) #dash .dd-arrow:hover{ color:var(--d-ink); border-color:var(--d-acc); }
  #dash .dd-arrow:disabled{ opacity:.3; cursor:default; }

  #dash .dd-row{ display:flex; gap:9px; margin-top:14px;
    /* ⚠️ `overflow-y:hidden` explícito: sin él el navegador computa el eje Y como
       `auto` solo por haber declarado el X, y eso además de habilitar un scroll
       vertical que nadie quiere es lo que hace que `unSoloScroll()` cace esta fila
       (ver el `data-scroll-propio` del HTML). */
    overflow-x:auto; overflow-y:hidden; scroll-snap-type:x mandatory;
    /* El scrollbar se esconde pero el scroll sigue: lo que comunica que hay más es
       el recorte de la tarjeta siguiente, no una barra. */
    scrollbar-width:none; -ms-overflow-style:none;
    /* 🔴 `overscroll-behavior-x:contain` — sin esto, llegar al final de la fila le
       pasa el gesto al carrusel de páginas y te cambia de pantalla mientras estás
       mirando los días. */
    overscroll-behavior-x:contain;
    -webkit-overflow-scrolling:touch;
    /* Aire a los costados para que la primera y la última no queden pegadas al
       borde del panel, sin romper el snap. */
    padding:2px 2px 6px; margin-left:-2px; margin-right:-2px; }
  #dash .dd-row::-webkit-scrollbar{ display:none; }

  #dash .dd-day{ scroll-snap-align:start; flex:none;
    /* 🔴 EL ANCHO ESTÁ CALCULADO PARA QUE ASOME LA SIGUIENTE. A 393px de viewport el
       panel deja ~325px útiles: con 4 tarjetas de 72px + 3 gaps de 9px = 315, queda
       un resto que muestra el borde de la quinta. Ese recorte es lo que dice "esto
       se desliza" sin necesidad de una barra ni de una flecha. */
    width:72px; min-height:78px; padding:10px 6px;
    display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
    background:var(--d-card2); border:1px solid var(--d-line2); border-radius:12px;
    cursor:pointer; color:inherit; font:inherit;
    transition:background .18s ease, border-color .18s ease, transform .18s ease; }
  :where(html.puntero) #dash .dd-day:hover{ border-color:var(--d-line2); background:color-mix(in srgb, var(--t-ink) 5%, transparent); }
  #dash .dd-day .dow{ font-size:9.5px; font-weight:700; letter-spacing:1.1px;
    text-transform:uppercase; color:var(--d-mut); }
  #dash .dd-day .num{ font-family:var(--a-mono); font-size:21px; font-weight:800;
    line-height:1; font-variant-numeric:tabular-nums; }
  #dash .dd-day .pts{ display:flex; gap:3px; align-items:center; height:7px; }
  #dash .dd-day .pts i{ width:5px; height:5px; border-radius:50%; display:block;
    animation:ddPop .26s cubic-bezier(.34,1.56,.64,1) both; animation-delay:var(--d,0ms); }
  @keyframes ddPop{ from{ transform:scale(0); } to{ transform:scale(1); } }
  #dash .dd-day .cn{ font-size:9.5px; color:var(--d-mut); }
  /* HOY: se marca con el color de acento y en negrita. */
  #dash .dd-day.hoy .num{ color:var(--d-acc); }
  #dash .dd-day.hoy .dow{ color:var(--d-acc); }
  /* ELEGIDO: se marca DISTINTO de hoy —fondo lleno y borde— porque los dos pueden
     coincidir en la misma tarjeta y si se marcaran igual no se sabría cuál es cuál. */
  #dash .dd-day.on{ background:color-mix(in srgb, var(--t-panel-accent) 16%, transparent); border-color:var(--d-acc); }
  #dash .dd-day.on .num{ color:var(--d-ink); }

  /* El detalle del día elegido. */
  #dash .dd-det{ margin-top:12px; }
  #dash .dd-det.cambia{ animation:ddDetIn .2s ease both; }
  @keyframes ddDetIn{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }
  #dash .dd-ev{ display:flex; align-items:center; gap:11px; padding:11px 12px;
    background:var(--d-card2); border:1px solid var(--d-line2); border-radius:10px;
    margin-bottom:7px; }
  #dash .dd-ev:last-of-type{ margin-bottom:0; }
  #dash .dd-ev .hr{ font-family:var(--a-mono); font-size:12.5px; font-weight:700;
    flex:none; min-width:44px; font-variant-numeric:tabular-nums; }
  #dash .dd-ev .in{ flex:1; min-width:0; }
  #dash .dd-ev .in b{ display:block; font-size:13px; font-weight:600;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #dash .dd-ev .in span{ font-size:11px; color:var(--d-mut);
    display:block; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #dash .dd-ev .go{ flex:none; background:none; border:0; color:var(--d-acc);
    font:inherit; font-size:11.5px; cursor:pointer; padding:8px 2px; min-height:44px; }
  :where(html.puntero) #dash .dd-ev .go:hover{ text-decoration:underline; }
  #dash .dd-libre{ font-size:12.5px; color:var(--d-mut); padding:14px 2px; }
  #dash .dd-todo{ display:block; width:100%; margin-top:12px; padding:11px;
    background:var(--d-card2); border:1px solid var(--d-line2); border-radius:10px;
    color:var(--d-mut); font:inherit; font-size:12px; cursor:pointer; min-height:44px; }
  :where(html.puntero) #dash .dd-todo:hover{ color:var(--d-ink); border-color:var(--d-acc); }

  /* Entrada de la fila: fade + 12px desde la derecha, con las tarjetas escalonadas. */
  #dash .dd-row.entra .dd-day{ animation:ddDayIn .3s cubic-bezier(.32,.72,0,1) both;
    animation-delay:var(--d,0ms); }
  @keyframes ddDayIn{ from{ opacity:0; transform:translateX(12px); } to{ opacity:1; transform:none; } }

  @media (prefers-reduced-motion:reduce){
    #dash .dd-row.entra .dd-day,
    #dash .dd-day .pts i,
    #dash .dd-det.cambia{ animation:none; }
    #dash .dd-row{ scroll-behavior:auto; }
  }
  /* 3 y no 4: desde la Fase 1 las tarjetas son los seis conceptos del modelo
     financiero (cotizado, pipeline, contratado, cobrado, por cobrar, ganancia
     proyectada), así que van en dos filas de tres. */
  #dash .dkpis{ display:grid; grid-template-columns:repeat(3,1fr); gap:9px; }
  #dash .dkpi{ background:var(--d-card2); border-radius:10px; padding:12px 14px; }
  #dash .dkpi .k{ display:flex; align-items:center; gap:6px; font-size:9.5px; font-weight:700;
    letter-spacing:1px; text-transform:uppercase; color:var(--d-mut); }
  #dash .dkpi .k i{ width:7px; height:7px; border-radius:50%; display:block; flex:none; }
  #dash .dkpi .v{ font-family:var(--a-mono); font-size:18px; font-weight:700; margin:6px 0 2px;
    font-variant-numeric:tabular-nums; }
  #dash .dkpi .n{ font-size:11px; color:var(--d-mut); }
  #dash .c-confirmado{ color:var(--d-green); } #dash .bg-confirmado{ background:var(--d-green); }
  #dash .c-espera{ color:var(--d-amber); }     #dash .bg-espera{ background:var(--d-amber); }
  #dash .c-consultar{ color:var(--d-blue); }   #dash .bg-consultar{ background:var(--d-blue); }
  #dash .c-rechazado{ color:var(--d-red); }    #dash .bg-rechazado{ background:var(--d-red); }
  #dash .c-reunion{ color:var(--d-reunion); }   #dash .bg-reunion{ background:var(--d-reunion); }
  #dash .dchip.on.reunion{ color:var(--d-reunion); }
  #dash .c-personal{ color:var(--d-personal); }   #dash .bg-personal{ background:var(--d-personal); }
  #dash .dchip.on.personal{ color:var(--d-personal); }
  /* Fila de rechazados: ancho completo y apagada, para que no se lea como un cuarto
     estado del embudo de ingresos. Va DENTRO de la grilla de KPI (grid-column:1/-1)
     para que acompañe el mismo ancho sin un contenedor nuevo. */
  #dash .drech{ grid-column:1/-1; display:flex; align-items:center; gap:8px; flex-wrap:wrap;
    margin-top:2px; padding:8px 12px; border:1px solid color-mix(in srgb, var(--t-err) 22%, transparent);
    background:color-mix(in srgb, var(--t-err) 6%, transparent); border-radius:9px; font-size:12px; color:var(--d-mut); }
  #dash .drech i{ width:7px; height:7px; border-radius:50%; display:block; flex:none; }
  #dash .drech b{ color:var(--d-red); font-family:var(--a-mono); font-variant-numeric:tabular-nums; }
  #dash .drech span{ margin-left:auto; font-size:11px; opacity:.75; }
  /* la 4ta tarjeta es la ganancia neta: mismo tamaño, borde para que no se lea
     como un cuarto estado del presupuesto */
  #dash .c-neta{ color:var(--d-green); }       #dash .bg-neta{ background:var(--d-green); }
  #dash .c-neta.neg{ color:var(--d-red); }       /* la regla del signo: Reparto.claseSigno */
  #dash .dkpi.neta{ border:1px solid color-mix(in srgb, var(--t-ok) 28%, transparent); background:color-mix(in srgb, var(--t-ok) 7%, transparent); }
  /* 🔴 LA TARJETA DE OTROS INGRESOS VA EN EL TEAL QUE LA APP YA LES DA: es el mismo
     var(--t-teal) del chip "💵 Ingreso" de la Agenda, así que un ingreso suelto se
     reconoce igual en las dos pantallas. No es un color nuevo. */
  #dash .dkpi.oi{ border:1px solid color-mix(in srgb, var(--t-teal) 34%, transparent); background:color-mix(in srgb, var(--t-teal) 7%, transparent); }
  #dash .dkpi.oi .k{ color:var(--t-teal); }
  /* La de cierre ocupa la fila entera: con siete tarjetas la última quedaba sola y
     media, y es justo la que resume. */
  #dash .dkpi.ancho{ grid-column:1 / -1; }
  /* ==================== LA PRIMERA MIRADA DEL PANEL (21/09/2026) ====================
     Un número grande (lo que entró en el mes, por fecha de cobro), las dos monedas a la vista,
     Eventos / Otros ingresos, seis meses de historia y dos renglones de lo que viene. El detalle
     por fecha del evento queda plegado. Jerarquía por tamaño y peso, no por cajas: una sola
     superficie destacada (el número), el resto son renglones. Todo lo tocable ≥ 44 pt. */
  #dash{ --e-ev:var(--t-accent); --e-oi:var(--t-teal); }
  #dash .vh{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
  /* el mes: ‹ [Septiembre] [2026] › en una fila */
  #dash .dper{ flex-wrap:wrap; gap:6px; margin:2px 0 12px; }
  #dash .dper-ctl{ flex:1 1 auto; justify-content:center; gap:4px; margin:0; }
  #dash .dper-sel select{ font-weight:700; font-size:16px; min-height:44px; border-color:transparent; background-color:transparent; text-align:center; text-align-last:center; }
  #dash .dper-nav{ width:44px; height:44px; flex:none; }
  #dash .dper-extra{ flex:1 0 100%; font-size:11.5px; color:var(--d-amber); text-align:center; }
  #dash .dper-hoy{ flex:1 0 100%; justify-content:center; }
  /* las dos monedas, siempre a la vista */
  #dash .dmon{ display:grid; grid-template-columns:1fr 1fr; gap:4px; padding:4px; border-radius:14px; background:var(--d-card2); margin-bottom:14px; }
  #dash .dmon-s{ display:grid; gap:1px; min-height:52px; padding:7px 12px; border:0; border-radius:10px; background:transparent; color:var(--d-mut); font:inherit; text-align:left; cursor:pointer; -webkit-tap-highlight-color:transparent; }
  #dash .dmon-s span{ font-size:11.5px; font-weight:600; letter-spacing:.02em; }
  #dash .dmon-s b{ font-family:var(--a-mono); font-size:14px; font-weight:700; font-variant-numeric:tabular-nums; color:var(--d-ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  #dash .dmon-s b.cero{ color:var(--d-dim); font-weight:400; }
  #dash .dmon-s.on{ background:var(--d-card); box-shadow:0 0 0 1px color-mix(in srgb, var(--e-ev) 55%, var(--d-line)); color:var(--d-ink); }
  #dash .dmon-s:not(.on) b{ opacity:.75; }
  /* el número */
  #dash .dent{ position:relative; display:block; padding:2px 2px 12px; cursor:pointer; -webkit-tap-highlight-color:transparent; border-radius:12px; }
  #dash .dent:focus-visible, #dash .dent-r:focus-visible, #dash .dsig-r:focus-visible, #dash .dent-col:focus-visible, #dash .dmon-s:focus-visible{ outline:2px solid var(--t-focus); outline-offset:2px; }
  #dash .dent-k{ font-size:14px; font-weight:600; color:var(--d-mut); }
  #dash .dent-v{ font-family:var(--a-mono); font-size:44px; font-weight:700; letter-spacing:-.03em; line-height:1.08; color:var(--d-ink); font-variant-numeric:tabular-nums; margin:4px 0 6px; overflow-wrap:anywhere; }
  #dash .dent-v small{ font-size:17px; font-weight:400; letter-spacing:0; color:var(--d-mut); margin-right:8px; }
  #dash .dent-d{ font-size:13.5px; color:var(--d-mut); min-height:19px; }
  #dash .dent-d i{ font-style:normal; font-size:10px; }
  #dash .dent-d.up{ color:var(--d-green); } #dash .dent-d.down{ color:var(--d-amber); }
  #dash .dent-go{ position:absolute; right:0; top:2px; display:inline-flex; align-items:center; gap:14px; min-height:28px; padding-right:12px; font-size:12.5px; font-weight:600; color:var(--d-acc); }
  #dash .dent-go .dk-go{ position:static; border-color:var(--d-acc); width:7px; height:7px; transform:rotate(-45deg); }
  /* de dónde vino */
  #dash .dent-bar{ display:flex; gap:2px; height:8px; border-radius:999px; overflow:hidden; margin:2px 0 6px; }
  #dash .dent-bar i{ display:block; min-width:5px; }
  #dash i.ev{ background:var(--e-ev); } #dash i.oi{ background:var(--e-oi); }
  #dash .dent-rows{ display:grid; }
  #dash .dent-r{ display:grid; grid-template-columns:10px 1fr auto; align-items:center; gap:10px; min-height:52px; padding:6px 2px; border:0; border-bottom:1px solid var(--d-line); background:transparent; color:var(--d-ink); font:inherit; text-align:left; cursor:pointer; -webkit-tap-highlight-color:transparent; }
  #dash .dent-r:last-child{ border-bottom:0; }
  #dash .dent-r > i{ width:10px; height:10px; border-radius:3px; display:block; }
  #dash .dent-r .k, #dash .dsig-r .k{ display:grid; gap:1px; min-width:0; font-size:15px; font-weight:600; }
  #dash .dent-r em, #dash .dsig-r em{ font-style:normal; font-size:12.5px; font-weight:400; color:var(--d-mut); line-height:1.3; }
  #dash .dent-r b, #dash .dsig-r b{ font-family:var(--a-mono); font-size:15px; font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap; }
  #dash .dent-r.cero{ color:var(--d-mut); } #dash .dent-r.cero b, #dash .dsig-r b.cero{ color:var(--d-dim); font-weight:400; }
  /* seis meses */
  #dash .dent-ch{ margin-top:14px; padding-top:14px; border-top:1px solid var(--d-line); }
  #dash .dent-cht{ display:flex; justify-content:space-between; align-items:baseline; gap:8px; font-size:13px; font-weight:600; color:var(--d-ink); margin-bottom:8px; }
  #dash .dent-cht span{ font-size:11.5px; font-weight:400; color:var(--d-mut); }
  #dash .dent-cols{ display:grid; grid-template-columns:repeat(6, 1fr); gap:6px; align-items:end; }
  #dash .dent-col{ display:grid; grid-template-rows:16px 96px 20px; gap:4px; padding:0; min-width:0; border:0; background:transparent; color:var(--d-mut); font:inherit; cursor:pointer; -webkit-tap-highlight-color:transparent; border-radius:8px; }
  #dash .dent-col .t{ font-family:var(--a-mono); font-size:11px; text-align:center; white-space:nowrap; font-variant-numeric:tabular-nums; align-self:end; }
  #dash .dent-col .b{ display:flex; align-items:flex-end; justify-content:center; border-bottom:1px solid var(--d-line); }
  #dash .dent-col .pila{ display:flex; flex-direction:column; gap:2px; width:72%; max-width:44px; border-radius:6px 6px 0 0; overflow:hidden; opacity:.38; transition:height .35s cubic-bezier(.2,.8,.2,1), opacity .2s; }
  #dash .dent-col .pila i{ display:block; min-height:3px; }
  #dash .dent-col .m{ font-size:12px; text-align:center; align-self:center; }
  #dash .dent-col.on{ color:var(--d-ink); } #dash .dent-col.on .pila{ opacity:1; } #dash .dent-col.on .m{ font-weight:700; } #dash .dent-col.on .t{ font-weight:700; }
  #dash .dent-col:active .pila{ opacity:.8; }
  :where(html.puntero) #dash .dent-col:hover .pila{ opacity:.7; }
  @media (prefers-reduced-motion:reduce){ #dash .dent-col .pila{ transition:none; } }
  /* lo que viene + el detalle plegado: renglones, no tarjetas */
  #dash .dsigue{ margin-top:18px; }
  #dash .dsig-t{ font-size:13px; font-weight:600; color:var(--d-ink); margin-bottom:2px; }
  #dash .dsig-r{ position:relative; display:grid; grid-template-columns:1fr auto 12px; align-items:center; gap:10px; width:100%; min-height:56px; padding:8px 2px; border:0; border-bottom:1px solid var(--d-line); background:transparent; color:var(--d-ink); font:inherit; text-align:left; cursor:pointer; -webkit-tap-highlight-color:transparent; }
  #dash .dsig-r .dk-go{ position:static; transform:rotate(-45deg); width:7px; height:7px; }
  #dash .dsig-r b.amb{ color:var(--d-amber); }
  #dash .dsig-r:active, #dash .dent-r:active{ background:var(--d-card2); }
  #dash .devdet > summary{ list-style:none; border-bottom:0; } #dash .devdet > summary::-webkit-details-marker{ display:none; }
  #dash .devdet > summary .dk-go{ transform:rotate(45deg); transition:transform .2s; margin-top:-4px; }
  #dash .devdet[open] > summary .dk-go{ transform:rotate(-135deg); margin-top:4px; }
  #dash .devdet[open] > summary{ border-bottom:1px solid var(--d-line); margin-bottom:14px; }
  /* el ojito tapa estos montos con cuatro puntos: ver el bloque "ojito" más abajo */
  /* La tarjeta entera abre Números para consultar los ingresos. El ALTA ya no vive
     acá: empieza por el "+" de la barra, que es el único lugar donde se elige qué
     se crea. */
  #dash .dkpi.oi{ cursor:pointer; }
  :where(html.puntero) #dash .dkpi.oi:hover{ border-color:color-mix(in srgb, var(--t-teal) 60%, transparent); }
  #dash .dkpi.oi:active{ transform:scale(.995); }

  /* ---- ganancia neta ---- */
  #dash .dbar{ height:8px; border-radius:4px; background:var(--d-card2); overflow:hidden; margin:18px 0; }
  #dash .dbar i{ height:100%; display:block; background:var(--d-green); }
  #dash h3{ margin:0 0 9px; font-size:9.5px; font-weight:700; letter-spacing:1px;
    text-transform:uppercase; color:var(--d-mut); }

  /* (Las reglas de "Próximos eventos" —#dash .dev, .devlist— se fueron con el panel
     el 04/09/2026. `.dpill` se queda: la usa Próximos días.) */
  #dash .dpill{ font-size:9.5px; font-weight:700; letter-spacing:.5px; padding:5px 10px; border-radius:20px; white-space:nowrap; }
  #dash .dpill.confirmada{ background:color-mix(in srgb, var(--t-ok) 14%, transparent); color:var(--d-green); }
  #dash .dpill.armado{ background:color-mix(in srgb, var(--t-warn) 14%, transparent); color:var(--d-amber); }
  #dash .dpill.pendiente{ background:color-mix(in srgb, var(--t-info) 14%, transparent); color:var(--d-blue); }
  #dash .dpill.agenda{ background:color-mix(in srgb, var(--t-panel-accent) 16%, transparent); color:var(--d-acc); }
  #dash .dlink{ font-size:11px; font-weight:700; color:var(--d-acc); background:none; border:0;
    font-family:inherit; cursor:pointer; padding:0; }
  :where(html.puntero) #dash .dlink:hover{ text-decoration:underline; }

  /* ---- ficha técnica (modal) ----
     z-index 10060: por encima del cajón de Agenda (81) y de la vista previa del PDF
     (10051), por debajo del overlay de contraseña (99999), que siempre tiene que ganar. */
  #dashFicha{ z-index:10060; background:rgba(6,7,12,.78); overflow:hidden;
    padding:4vh 4vw; box-sizing:border-box; }
  #dashFicha.on{ display:flex; align-items:flex-start; justify-content:center; }
  #dashFicha .fbox{ background:var(--d-card); border:1px solid var(--d-line2); border-radius:16px;
    width:100%; max-width:760px; max-height:92vh; display:flex; flex-direction:column; overflow:hidden; }
  #dashFicha .fhd{ display:flex; align-items:flex-start; gap:16px; padding:20px 24px 16px;
    border-bottom:1px solid var(--d-line); flex:none; }
  #dashFicha .fhd .fk{ font-size:9.5px; font-weight:700; letter-spacing:1.5px;
    text-transform:uppercase; color:var(--d-mut); }
  #dashFicha .fhd .ftit{ font-size:19px; font-weight:700; margin-top:5px; }
  #dashFicha .fhd .fsub{ font-size:11.5px; color:var(--d-mut); margin-top:4px; }
  #dashFicha .fx{ margin-left:auto; flex:none; width:30px; height:30px; border-radius:8px;
    background:var(--d-card2); border:1px solid var(--d-line2); color:var(--d-ink);
    font:inherit; font-size:14px; line-height:1; cursor:pointer; }
  :where(html.puntero) #dashFicha .fx:hover{ border-color:var(--d-red); color:var(--d-red); }
  #dashFicha .fbd{ overflow-y:auto; padding:6px 24px 24px; }
  /* ---- pagos en la ficha (Fase 2) ---- */
  #dashFicha .fpg-x{ background:none; border:0; color:var(--d-mut); cursor:pointer;
    font-size:12px; padding:0 2px; margin-left:6px; line-height:1; }
  :where(html.puntero) #dashFicha .fpg-x:hover{ color:var(--d-red); }
  #dashFicha .fpg-x.confirmar{ color:var(--d-red); font-size:10px; letter-spacing:.5px; }
  #dashFicha .fpg-aviso{ background:var(--d-card2); border:1px solid var(--d-line2);
    border-left:3px solid var(--d-amber); border-radius:0 8px 8px 0;
    padding:11px 13px; margin:10px 0; font-size:12px; line-height:1.5; color:var(--d-mut); }
  #dashFicha .fpg-aviso b{ color:var(--d-fg); }
  #dashFicha .fpg-aviso code{ font-size:11px; }
  #dashFicha .fpg-mig{ display:block; margin-top:9px; background:var(--d-card);
    border:1px solid var(--d-line2); color:var(--d-fg); border-radius:7px;
    padding:6px 11px; font-size:11.5px; cursor:pointer; font-family:inherit; }
  :where(html.puntero) #dashFicha .fpg-mig:hover{ border-color:var(--d-acc); }
  #dashFicha .fpg-alta{ display:grid; grid-template-columns:repeat(2,1fr); gap:7px; margin:12px 0 4px; }
  /* 🔴 16px: abajo de eso iOS hace zoom al enfocar y, como la ficha es fixed, la
     pantalla queda descuadrada encima del contenido. Misma regla que .fld y que el
     textarea del agente. */
  #dashFicha .fpg-alta input{ background:var(--d-card2); border:1px solid var(--d-line2);
    color:var(--d-fg); border-radius:8px; padding:9px 10px; font-size:16px;
    font-family:inherit; width:100%; }
  #dashFicha .fpg-alta input:focus{ outline:none; border-color:var(--d-acc); }
  #dashFicha .fpg-alta input#fpgObs{ grid-column:1/-1; }
  #dashFicha .fpg-add{ grid-column:1/-1; background:var(--d-acc); border:0; color:#fff;
    border-radius:8px; padding:10px; font-size:13px; font-weight:600; cursor:pointer;
    font-family:inherit; }
  #dashFicha .fpg-add:disabled{ opacity:.5; cursor:default; }
  #dashFicha .fpg-msg{ grid-column:1/-1; font-size:11.5px; color:var(--d-mut); min-height:0; }
  #dashFicha .fpg-msg.err{ color:var(--d-red); }
  #dashFicha .fpg-msg.ok{ color:var(--d-green); }
  #dashFicha .fpg-msg.mal{ color:var(--d-red); }
  /* WhatsApp y Copiar de la checklist técnica, al lado de su botón (15/09/2026): de a dos y a tamaño de dedo */
  #dashFicha .fchk-acts{ display:grid; grid-template-columns:1fr 1fr; gap:7px; margin-top:7px; }
  #dashFicha .fchk-acts .fpg-mig{ margin-top:0; display:flex; align-items:center; justify-content:center; gap:7px; min-height:40px; font-size:13px; font-weight:600; }
  #dashFicha .fchk-acts img{ width:20px; height:20px; flex:none; }
  #dashFicha .fchk-msg{ margin-top:6px; }
  /* ---- portal del cliente (Fase 13.1) ----
     El mensaje va DENTRO de la sección y no por toast(): la ficha puede estar
     scrolleada a media pantalla y el toast vive abajo de todo — en el celu no se
     ve. Reusa la paleta de .fpg-msg en vez de inventar colores nuevos. */
  #dashFicha .portal-msg{ font-size:11.5px; color:var(--d-mut); margin-top:8px; }
  #dashFicha .portal-msg.err{ color:var(--d-red); }
  #dashFicha .portal-msg.ok{ color:var(--d-green); }
  #dashFicha .fpg-mig.confirmar{ border-color:var(--d-red); color:var(--d-red); }
  #dashFicha .fpg-mig:disabled{ opacity:.55; cursor:default; }
  @media (max-width:560px){ #dashFicha .fpg-alta{ grid-template-columns:1fr; } }
  #dashFicha .fsec{ font-size:9.5px; font-weight:700; letter-spacing:1.5px; text-transform:uppercase;
    color:var(--d-acc); margin:20px 0 8px; padding-bottom:6px; border-bottom:1px solid var(--d-line); }
  #dashFicha .frow{ display:flex; gap:16px; padding:7px 0; font-size:12.5px; align-items:baseline; }
  #dashFicha .frow .fk2{ color:var(--d-mut); flex:none; width:170px; }
  #dashFicha .frow .fv{ color:var(--d-ink); flex:1; min-width:0; font-family:var(--a-mono);
    white-space:pre-wrap; word-break:break-word; }
  /* separador entre grupos de equipos (Sonido / Iluminación / Estructuras…) */
  #dashFicha .frow.gsep{ border-top:1px solid var(--d-line2); margin-top:7px; padding-top:14px; }
  #dashFicha .frow.money .fv{ font-variant-numeric:tabular-nums; }
  #dashFicha .frow.neg .fv{ color:var(--d-red); }
  #dashFicha .frow.ok .fv{ color:var(--d-green); }
  #dashFicha .frow.warn .fv{ color:var(--d-amber); }

  /* ---- pagos pendientes ---- */
  #dash .dhd{ display:flex; justify-content:space-between; align-items:baseline; margin-bottom:16px; gap:10px; flex-wrap:wrap; }
  #dash .dhd .t{ font-family:var(--a-mono); font-size:12.5px; color:var(--d-amber); font-variant-numeric:tabular-nums; }
  #dash .dpago{ display:flex; justify-content:space-between; align-items:center; padding:11px 0;
    border-bottom:1px solid var(--d-line); gap:12px; }
  #dash .dpago:last-child{ border-bottom:0; }
  #dash .dpago .nm{ font-weight:600; font-size:12.5px; }
  #dash .dpago .vc{ font-size:11px; color:var(--d-mut); margin-top:2px; }
  #dash .dpago .r{ display:flex; align-items:center; gap:10px; flex:none; }
  #dash .dpago .amt{ font-family:var(--a-mono); font-weight:700; font-size:13.5px; color:var(--d-amber);
    font-variant-numeric:tabular-nums; }
  #dash .durg{ font-size:9.5px; font-weight:700; padding:4px 9px; border-radius:20px; white-space:nowrap; }
  #dash .durg.urgente{ background:color-mix(in srgb, var(--t-err) 16%, transparent); color:var(--d-red); }
  #dash .durg.proximo{ background:color-mix(in srgb, var(--t-warn) 14%, transparent); color:var(--d-amber); }
  #dash .durg.atiempo{ background:color-mix(in srgb, var(--t-ok) 14%, transparent); color:var(--d-green); }
  #dash .durg.sinfecha{ background:var(--d-card2); color:var(--d-mut); }

  /* ---- calendario ---- */
  #dash .dcalhd{ display:flex; align-items:center; justify-content:space-between; margin:12px 0 14px; }
  #dash .dcalhd .m{ font-size:16px; font-weight:700; }
  #dash .dcalhd .nav{ display:flex; gap:8px; }
  #dash .dcalhd button{ width:26px; height:26px; border-radius:8px; background:var(--d-card2);
    border:1px solid var(--d-line2); color:var(--d-ink); cursor:pointer; font:inherit; }
  :where(html.puntero) #dash .dcalhd button:hover{ border-color:var(--d-acc); }
  #dash .ddow{ display:grid; grid-template-columns:repeat(7,1fr); gap:4px; margin-bottom:6px; }
  #dash .ddow span{ text-align:center; font-size:10px; color:var(--d-mut); }
  #dash .dleg{ display:flex; gap:12px; margin-top:12px; font-size:10px; color:var(--d-mut); flex-wrap:wrap; }
  #dash .dleg div{ display:flex; align-items:center; gap:5px; }
  /* cuadraditos, no puntos: la leyenda tiene que leerse igual que el calendario */
  #dash .dleg i{ width:9px; height:9px; border-radius:3px; display:inline-block; }

  /* ===== toggle Calendario / Tareas del panel del calendario =====
     Las dos vistas se apilan en la MISMA celda de grilla, así el panel mide siempre
     lo que mide la más alta (el calendario) y nada de lo que está abajo salta al
     cambiar. La que no está activa queda con visibility:hidden, que sigue ocupando
     su lugar en el layout (por eso no se usa display:none). */
  #dash .dhd.cal{ margin-bottom:0; }
  #dash .dtab.on{ background:color-mix(in srgb, var(--t-panel-accent) 18%, transparent); color:var(--d-acc); font-weight:600; }
  /* Deshabilitado solo mientras corre el cross-fade (330ms). No se atenúa: a esa
     duración un parpadeo gris se lee como un glitch, no como feedback. */
  #dash .dtab:disabled{ cursor:default; }
  #dash .dswap{ display:grid; }
  /* Cross-fade en dos tiempos: primero se apaga la vista que sale, recién después
     entra la otra. Antes las dos se cruzaban en los mismos 280ms y se veían
     superpuestas (el calendario fantasma abajo de las tareas). El otro problema era
     `visibility .28s`: transicionada con duración, la vista que se va queda pintada
     todo ese rato. Acá visibility cambia de golpe — al entrar en el instante 0, al
     salir cuando el fade ya terminó. */
  #dash .dswap > .dview{ grid-area:1/1; opacity:0; visibility:hidden; transform:translateY(4px);
    pointer-events:none;
    transition:opacity .15s ease, transform .15s ease, visibility 0s linear .15s; }
  #dash .dswap > .dview.on{ opacity:1; visibility:visible; transform:none; pointer-events:auto;
    transition:opacity .2s ease .13s, transform .2s ease .13s, visibility 0s linear 0s; }
  @media (prefers-reduced-motion:reduce){
    #dash .dswap > .dview, #dash .dswap > .dview.on{ transition:none; }
  }

  #dash .dtareaform{ display:flex; gap:8px; margin:14px 0 10px; }
  #dash .dtareaform input{ flex:1; min-width:0; background:var(--d-card2); border:1px solid var(--d-line2);
    border-radius:9px; padding:8px 11px; color:var(--d-ink); font-size:12px; font-family:inherit; }
  #dash .dtareaform input::placeholder{ color:var(--d-mut); }
  #dash .dtareaform input:focus{ outline:none; border-color:var(--d-acc); }
  #dash .dtareaform button{ flex:none; background:var(--d-acc); color:var(--d-canvas); border:0;
    border-radius:9px; padding:0 14px; font-size:11.5px; font-weight:700; cursor:pointer; }
  #dash .dtareas{ max-height:214px; overflow-y:auto; }
  #dash .dtarea{ display:flex; align-items:flex-start; gap:9px; padding:6px 0; font-size:12px;
    border-bottom:1px solid var(--d-line); }
  #dash .dtarea:last-child{ border-bottom:0; }
  #dash .dtarea label{ display:flex; align-items:flex-start; gap:9px; flex:1; min-width:0; cursor:pointer; }
  #dash .dtarea input[type=checkbox]{ accent-color:var(--d-acc); flex:none; margin-top:1px; cursor:pointer; }
  #dash .dtarea span{ word-break:break-word; line-height:1.45; }
  #dash .dtarea.hecha span{ text-decoration:line-through; color:var(--d-mut); opacity:.65; }
  #dash .dtarea .x{ flex:none; background:none; border:0; color:var(--d-mut); cursor:pointer;
    font-size:15px; line-height:1; padding:0 2px; opacity:.55; transition:color .15s, opacity .15s; }
  :where(html.puntero) #dash .dtarea .x:hover{ color:var(--d-red); opacity:1; }

  /* ---- ocupación / tendencia ---- */
  #dash .docup{ display:flex; align-items:baseline; gap:8px; margin:10px 0 6px; }
  #dash .docup .v{ font-family:var(--a-mono); font-size:22px; font-weight:800; font-variant-numeric:tabular-nums; }
  #dash .docup .r{ font-size:11.5px; color:var(--d-mut); }
  #dash .dbar.acc i{ background:var(--d-acc); }
  #dash .dtend{ display:flex; align-items:flex-end; gap:8px; height:70px; }
  #dash .dtend .c{ flex:1; display:flex; flex-direction:column; align-items:center; gap:6px;
    height:100%; justify-content:flex-end; }
  #dash .dtend .b{ width:100%; border-radius:4px 4px 0 0; background:var(--t-panel-line-2); min-height:2px; }
  #dash .dtend .c.on .b{ background:var(--d-acc); }
  #dash .dtend .l{ font-size:9px; color:var(--d-mut); }

  /* ---- próximos presupuestos ---- */
  #dash .dtask{ padding:14px 0; border-bottom:1px solid var(--d-line); }
  #dash .dtask:last-child{ border-bottom:0; }
  #dash .dtask .r1{ display:flex; justify-content:space-between; gap:10px; }
  #dash .dtask .r1 b{ font-weight:700; font-size:13.5px; }
  #dash .dtask .r1 .amt{ font-family:var(--a-mono); font-weight:700; font-variant-numeric:tabular-nums; flex:none; }
  #dash .dtask .sb{ font-size:11px; color:var(--d-mut); margin:4px 0 10px; }
  #dash .dtask .r2{ display:flex; justify-content:space-between; align-items:center; gap:10px; }
  #dash .dchips{ display:flex; gap:8px; flex-wrap:wrap; }
  /* Estado editable en la ficha (auditoría 08/09/2026): los mismos cuatro chips del
     Panel, en tamaño de dedo. `.fest-chip.sug` es el botón "Marcar confirmado" que
     aparece bajo un pago recién cargado. */
  .fest{ display:flex; flex-wrap:wrap; gap:6px; }
  .fest-chip{ border:1px solid var(--t-line); background:transparent; color:var(--t-muted); border-radius:20px;
    padding:6px 12px; font:inherit; font-size:12px; min-height:32px; cursor:pointer; }
  .fest-chip.on{ font-weight:600; color:var(--t-ink); border-color:transparent; background:var(--t-surface-2); }
  .fest-chip.on.confirmado{ background:color-mix(in srgb, var(--t-ok) 18%, transparent); color:var(--t-ok); }
  .fest-chip.on.espera{ background:color-mix(in srgb, var(--t-warn) 18%, transparent); color:var(--t-warn); }
  .fest-chip.on.consultar{ background:color-mix(in srgb, var(--t-info) 18%, transparent); color:var(--t-info); }
  .fest-chip.on.rechazado{ background:color-mix(in srgb, var(--t-err) 16%, transparent); color:var(--t-err); }
  .fest-chip.sug{ margin-top:6px; border-color:var(--t-ok); color:var(--t-ok); }
  .fpg-msg.ok{ color:var(--t-ok); }
  .fpg-sug{ margin-top:6px; color:var(--t-muted); font-weight:400; }
  #dash .dchip{ border:0; background:var(--d-card2); color:var(--d-mut); border-radius:20px;
    padding:4px 9px; font:inherit; font-size:10px; cursor:pointer; transition:.14s; }
  :where(html.puntero) #dash .dchip:hover{ color:var(--d-ink); }
  #dash .dchip.on.confirmado{ background:color-mix(in srgb, var(--t-ok) 18%, transparent); color:var(--d-green); font-weight:600; }
  #dash .dchip.on.espera{ background:color-mix(in srgb, var(--t-warn) 18%, transparent); color:var(--d-amber); font-weight:600; }
  #dash .dchip.on.consultar{ background:color-mix(in srgb, var(--t-info) 18%, transparent); color:var(--d-blue); font-weight:600; }
  #dash .dchip.on.rechazado{ background:color-mix(in srgb, var(--t-err) 18%, transparent); color:var(--d-red); font-weight:600; }
  #dash .dedit{ border:0; background:transparent; color:var(--d-mut); font:inherit; font-size:11px;
    cursor:pointer; text-decoration:underline; padding:0 2px; flex:none; }
  :where(html.puntero) #dash .dedit:hover{ color:var(--d-ink); }

  /* ---- CTA ---- */
  #dash .dcta{ background:linear-gradient(135deg,#7c5cf0,#5b8def); border-radius:14px; padding:17px 19px;
    display:flex; align-items:center; justify-content:space-between; gap:16px; }
  #dash .dcta .l{ display:flex; align-items:center; gap:14px; }
  #dash .dcta .ico{ width:37px; height:37px; border-radius:10px; background:color-mix(in srgb, var(--t-ink) 18%, transparent);
    display:grid; place-items:center; font-size:20px; flex:none; }
  #dash .dcta b{ display:block; font-weight:700; font-size:13.5px; }
  #dash .dcta span{ display:block; font-size:11px; color:color-mix(in srgb, var(--t-ink) 80%, transparent); margin-top:2px; }
  #dash .dcta .dbtn{ background:var(--d-ink); color:var(--d-canvas); border:0; border-radius:10px;
    padding:8px 13px; font-size:12px; font-weight:700; white-space:nowrap; }

  #dash .dempty{ color:var(--d-mut); font-size:11.5px; padding:14px 0; text-align:center; line-height:1.6; }

  /* ===== ojito: los montos se tapan con CUATRO PUNTOS (29/09/2026) =====
     El botón (#dashEye) pone la clase en <html>, así vale en toda la app: Panel, ficha,
     Desglose, Agenda, Métricas, Números, Historial, Valores y las páginas del presupuesto
     en pantalla, el modo evento, el chat y el globo del Agente. Es SOLO visual: no cambia
     ningún dato, ni el PDF, ni lo que se guarda.
     🔴 ANTES ERA UN DESENFOQUE y se fue por dos motivos: se veía mal ("no queda bien") y
     dejaba adivinar el número (el largo y la forma de los dígitos se leían a través del
     blur). Ahora todo monto es "••••", siempre cuatro, mida lo que mida.
     🔴 CÓMO: `font-size-adjust:0` lleva el texto del monto (y el de sus hijos: se hereda)
     a ancho cero SIN tocar `font-size`, así que el `em` sigue valiendo lo mismo y el
     ::before dibuja los cuatro puntos del tamaño del número que tapa. La caja no cambia de
     lugar ni de alineación: un monto a la derecha sigue a la derecha. Medido en WebKit 26
     y Chrome 154 (el texto mide 0 y el `em` queda igual). Los puntos son una máscara SVG
     sobre currentColor: toman el color del monto, en claro y en oscuro.
     🔴 SOLO LOS NÚMEROS QUE SON PLATA: conteos, fechas, porcentajes y rótulos quedan a la
     vista. Un monto metido en una frase ("USD 810 más que en agosto") va envuelto en
     <span class="monto">, que arma window.conMontos() (index.html): se tapa el monto y no
     la frase. Un "—" (no hay dato) lleva .nada y no se tapa: cuatro puntos dirían que hay
     un monto. Lo vacío tampoco.
     ⚠️ Lugar nuevo que muestre plata → sumalo a esta lista, o armá su texto con
     conMontos(). test/ojito.test.mjs lo verifica y test/visual/ojito.mjs recorre la app
     buscando plata a la vista. */
  #dash .deye{ background:none; border:0; padding:0 0 0 12px; cursor:pointer; line-height:1;
    font-size:.42em; opacity:.45; vertical-align:middle; transition:opacity .15s; }
  :where(html.puntero) #dash .deye:hover{ opacity:1; }
  :root{ --puntos:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 42 10'%3E%3Cg fill='black'%3E%3Ccircle cx='5' cy='5' r='3.3'/%3E%3Ccircle cx='16' cy='5' r='3.3'/%3E%3Ccircle cx='27' cy='5' r='3.3'/%3E%3Ccircle cx='38' cy='5' r='3.3'/%3E%3C/g%3E%3C/svg%3E");
         --punto:radial-gradient(circle closest-side, currentColor 84%, transparent 100%); }
  /* imprimir sale siempre con los números (el PDF lo arma jsPDF aparte, no se entera) */
  @media not print{
    html.montos-off #dashSimbolo{ display:none; }   /* el centro de la rueda queda en "••••" solo */
    /* ⚠️ LAS TRES LISTAS DE ABAJO SON LA MISMA (el monto, sus hijos, los puntos). Lugar nuevo →
       sumalo en las tres: test/ojito.test.mjs falla si difieren. */
    html.montos-off :is(
      #dashTotal, #dash .dkpi .v, #dash .dkpi .n b, #dash .dent-v, #dash .dent-r b, #dash .dsig-r b,
      #dash .dmon-s b, #dash .dent-col .t, #dash .dmesvacio-saldo b, #dash .drech b,
      .amt, .monto, #desglose .dg-celdas b,
      .ag-stat .v:has(small), .ag-folder-hd .fmeta b, #mtDetail b, #mtTable td + td, .mt-val, .mt-rech b,
      #numeros .dkpi .v, #numeros .dkpi .n b, #numeros .nm-h-v, #numeros .nm-f b, #numeros .nm-v,
      #numeros .nm-pc .v, #numeros .nm-ev .tot, #numeros :is(.nm-oi, .nm-cobro) .m, #nmDetail b,
      #gastos_sub, #se-sub, #rep_total, #rep_gastos, #rep_queda,
      .pv, [data-f$="_money"], [data-f="total_num"], [data-f="dj_solo_num"],
      #hist .tot, .me-saldo .v
    ):not(:empty):not(.nada){
      font-size-adjust:0 !important; letter-spacing:0 !important; word-spacing:0 !important;
      text-indent:0 !important; text-overflow:clip !important;
      -webkit-user-select:none; user-select:none;
    }
    html.montos-off :is(
      #dashTotal, #dash .dkpi .v, #dash .dkpi .n b, #dash .dent-v, #dash .dent-r b, #dash .dsig-r b,
      #dash .dmon-s b, #dash .dent-col .t, #dash .dmesvacio-saldo b, #dash .drech b,
      .amt, .monto, #desglose .dg-celdas b,
      .ag-stat .v:has(small), .ag-folder-hd .fmeta b, #mtDetail b, #mtTable td + td, .mt-val, .mt-rech b,
      #numeros .dkpi .v, #numeros .dkpi .n b, #numeros .nm-h-v, #numeros .nm-f b, #numeros .nm-v,
      #numeros .nm-pc .v, #numeros .nm-ev .tot, #numeros :is(.nm-oi, .nm-cobro) .m, #nmDetail b,
      #gastos_sub, #se-sub, #rep_total, #rep_gastos, #rep_queda,
      .pv, [data-f$="_money"], [data-f="total_num"], [data-f="dj_solo_num"],
      #hist .tot, .me-saldo .v
    ):not(:empty):not(.nada) > *{ display:none !important; }
    html.montos-off :is(
      #dashTotal, #dash .dkpi .v, #dash .dkpi .n b, #dash .dent-v, #dash .dent-r b, #dash .dsig-r b,
      #dash .dmon-s b, #dash .dent-col .t, #dash .dmesvacio-saldo b, #dash .drech b,
      .amt, .monto, #desglose .dg-celdas b,
      .ag-stat .v:has(small), .ag-folder-hd .fmeta b, #mtDetail b, #mtTable td + td, .mt-val, .mt-rech b,
      #numeros .dkpi .v, #numeros .dkpi .n b, #numeros .nm-h-v, #numeros .nm-f b, #numeros .nm-v,
      #numeros .nm-pc .v, #numeros .nm-ev .tot, #numeros :is(.nm-oi, .nm-cobro) .m, #nmDetail b,
      #gastos_sub, #se-sub, #rep_total, #rep_gastos, #rep_queda,
      .pv, [data-f$="_money"], [data-f="total_num"], [data-f="dj_solo_num"],
      #hist .tot, .me-saldo .v
    ):not(:empty):not(.nada)::before{
      content:''; display:inline-block; flex:none; vertical-align:.02em;
      width:2.1em; height:.5em; margin:0; padding:0; border:0;
      background:currentColor; font-size-adjust:none;
      -webkit-mask:var(--puntos) center / 100% 100% no-repeat;
              mask:var(--puntos) center / 100% 100% no-repeat;
    }
    /* Los campos del presupuesto no tienen ::before: el valor se vuelve transparente (el
       cursor sigue a la vista) y los cuatro puntos son el fondo, en el color del texto.
       Un campo vacío muestra su ayuda y no se tapa ("Opcional" no es un monto)... salvo
       que la ayuda SEA un número: el "0" de los gastos o, en la lista de la técnica, el
       precio del catálogo. Esos van con puntos como cualquier otro monto de la app; solo
       "a cotizar" queda a la vista. */
    html.montos-off :is(#c_dj, #c_tecnica, #c_senia, #c_prod, #c_optA, #c_optB, #c_gtransporte, #c_gequipo,
      #c_gtecnica, #c_gpersonal, #c_gcomision, #c_gmarketing, #c_gotros)[placeholder="0"]::placeholder,
    html.montos-off #se-list input[data-pid]:not([placeholder="a cotizar"])::placeholder{
      color:transparent !important; -webkit-text-fill-color:transparent !important;
    }
    html.montos-off :is(#c_dj, #c_tecnica, #c_senia, #c_prod, #c_optA, #c_optB, #c_gtransporte, #c_gequipo,
      #c_gtecnica, #c_gpersonal, #c_gcomision, #c_gmarketing, #c_gotros):is(:not(:placeholder-shown), [placeholder="0"]),
    html.montos-off #c_total:not(:placeholder-shown),
    html.montos-off #se-list input[data-pid]:is(:not(:placeholder-shown), :not([placeholder="a cotizar"])){
      -webkit-text-fill-color:transparent !important;
      text-shadow:none !important;   /* el total tiene un resplandor: sin esto, el número se adivina por la sombra */
      background-image:var(--punto), var(--punto), var(--punto), var(--punto) !important;
      background-size:.34em .34em !important; background-repeat:no-repeat !important;
      background-origin:content-box !important;
      background-position:0 50%, .58em 50%, 1.16em 50%, 1.74em 50% !important;
      -webkit-user-select:none; user-select:none;
    }
    /* las flechitas del campo numérico (compu) quedaban encima de los puntos, y tapado no sirven */
    html.montos-off #se-list input[data-pid]::-webkit-inner-spin-button,
    html.montos-off #se-list input[data-pid]::-webkit-outer-spin-button{ -webkit-appearance:none; appearance:none; margin:0; }
    /* los que van alineados a la derecha, con los puntos a la derecha */
    html.montos-off #c_total:not(:placeholder-shown),
    html.montos-off #se-list input[data-pid]:is(:not(:placeholder-shown), :not([placeholder="a cotizar"])){
      background-position:right 1.74em center, right 1.16em center, right .58em center, right 0 center !important;
    }
  }
  /* Acá vivía la regla dura que mataba el panel debajo de 1024px
     (#dash, #dashFicha { display:none !important }). Se sacó: ahora el panel
     también existe en el celu, con el skin del <style> de abajo — y además es la
     pantalla de entrada en cualquier ancho. Con la landing en el formulario, y como
     la pestaña abierta se recuerda en `cp_tab`, abrir la app en el celu te dejaba
     mirando "Equipamiento": la pantalla más interna, sin un dato del día a la vista. */

@media (max-width:1023px){

  /* 🔴 LA AGENDA COMO PÁGINA CUBRE EL VIEWPORT, TAMBIÉN ACOSTADO (03/09/2026).
     `.agenda` mide `min(560px,100vw)`: en un teléfono vertical eso es la pantalla
     entera, pero en horizontal (664px) o en una tablet angosta (768px) quedaban 560px
     de Agenda y, a la izquierda, el presupuestador asomando por detrás. Medido en
     WebKit. Esta regla NO es el diseño ancho de escritorio (que vive en ≥1024 con
     dos columnas): es la misma hoja móvil, ocupando lo que hay. El CAJÓN (`.cajon`)
     no cambia: se abre encima del presupuestador y en horizontal sigue en 560. */
  #agenda.pagina{ width:100vw; }

  /* ---- zona muerta 861–1023px ----
     Entre 861 y 1199 no aplicaba ningún bloque de layout: .stage quedaba visible
     con .page en zoom 1 (A4 a 794px de ancho) apilada debajo del formulario.
     El bloque de 860px ya la oculta para el celu; acá se extiende el mismo
     criterio hasta donde arranca el escritorio. Arriba de 1023 no se toca. */
  .stage{ display:none !important; }

  /* ---- alto del panel: NO usar dvh ----
     🔴 Probado en el iPhone de Tobi (app instalada en la pantalla de inicio): con
     `height:100dvh` el panel resuelve MÁS BAJO que la pantalla y queda una franja
     del fondo del body abajo de todo, con el contenido cortado justo en ese borde.
     Así que el panel se queda con el `inset:0` de la regla base y tapa la pantalla
     entera, que es lo único que garantiza que no haya franja.

     Lo que se puede LEER hasta el final no lo decide el alto del panel sino el
     padding de abajo de .dwrap — ahí estaba el problema original: con 24px, el
     último panel quedaba abajo del indicador de inicio (34px de safe-area) y se
     veía cortado. Ahora el padding lo contempla y sobra aire.

     Si algún día volvés a tocar esto: el síntoma "franja abajo" y el síntoma
     "contenido cortado" se arreglan al revés, no los mezcles. */

  /* ---- layout general del panel ---- */
  #dash .dwrap{ padding:calc(14px + env(safe-area-inset-top)) 14px
                        calc(56px + var(--nav-bot, 0px)); }
  #dash .dgrid{ grid-template-columns:1fr; gap:14px; }   /* de 2fr/1fr a una sola columna */
  #dash .dcol{ gap:14px; }
  /* 🔴 EN EL CELU, LO QUE VIENE VA PRIMERO (04/09/2026). Medido a 390px: la rueda,
     la leyenda, el aviso de pesos y ocho tarjetas de plata ocupaban ~1.700px antes
     de "Próximos días" — pantalla y media de cifras antes de saber si hoy hay
     evento. En escritorio las dos columnas ya lo resuelven; acá el orden lo da el
     flex de .dcol. Escritorio no cambia. */
  #dash .dcol > #dashPanelDias{ order:-1; }
  #dash .dpanel{ padding:16px 15px; border-radius:12px; }
  #dash .dpanel.sm{ padding:15px 14px; }

  /* Al colapsar a una columna el orden ya sale bien solo: la .dcol de la izquierda
     (Ingresos → Eventos → Pagos) cae antes que la de la derecha (Calendario).
     No hace falta tocar `order` ni mover nada de markup. */

  /* ---- header pegajoso ----
     "Abrir presupuestador →" es la única salida del panel en mobile, así que no
     puede quedar arriba de todo fuera de pantalla. El margen negativo lo hace
     full-bleed contra el padding de .dwrap. */
  /* Con la barra de estado translúcida, al pegarse arriba tiene que TAPAR la franja
     de la barra con su propio fondo: sube por el margen negativo lo que la .dwrap
     reservó de safe-area y lo devuelve como padding. En reposo queda donde estaba. */
  #dash .dtop{ position:sticky; top:0; z-index:2;
    margin:calc(-1 * env(safe-area-inset-top)) -14px 14px; padding:env(safe-area-inset-top) 14px 12px; gap:12px;
    background:var(--d-canvas); border-bottom:1px solid var(--d-line); }
  #dash .dtopl{ gap:12px; }
  #dash .dtop h1{ font-size:16px; }
  #dash .dtop h1 span{ display:none; }          /* "· DJ & Eventos" no entra */
  /* 🔴 EN EL CELU EL HEADER ENTRA EN UNA SOLA FILA, y para eso se va la palabra
     "Dashboard". Medido a 375px: logo + separador + título + campana + Agente Pro
     dan ~390px contra los 347 disponibles, así que los dos botones caían a un
     segundo renglón y el header se comía 93px de alto — en la pantalla que
     justamente se está tratando de despejar. El título es lo único prescindible:
     el LOGO ya dice qué app es, y la tab bar de abajo ya dice "Panel". Se oculta a
     la vista pero NO al lector de pantalla, que sigue necesitando el h1 para saber
     de qué es esta página. */
  #dash .dtop h1{ position:absolute; width:1px; height:1px; overflow:hidden;
    clip-path:inset(50%); white-space:nowrap; }
  #dash .dsep{ display:none; }                  /* sin título al lado, no separa nada */
  #dash .dtopr{ gap:7px; }
  #dash .dacts{ width:100%; }
  #dash .dacts .dbtn{ flex:1; justify-content:center; padding:12px 10px; }

  /* ---- ingresos ---- */
  #dash .dbig{ font-size:28px; }
  #dash .dkpis{ grid-template-columns:repeat(2,1fr); }   /* 6 tarjetas en 2×3 */

  /* ---- la rueda en el celu ----
     Rueda CENTRADA y leyenda compacta debajo, no al costado: a 393px una columna de
     leyenda al lado dejaría la rueda en ~150px y las tres filas en 130, y las dos
     cosas quedarían ilegibles. El `column` + `center` es todo lo que hace falta —
     el resto ya viene del `flex-wrap` de escritorio. */
  #dash .dwheel{ flex-direction:column; align-items:center; gap:14px; margin-bottom:16px; }
  #dash .dw-ring{ width:196px; height:196px; }
  #dash .dw-mid .dbig{ font-size:23px; }
  #dash .dw-leg{ width:100%; min-width:0; }
  /* La leyenda compacta: se apoya en el ancho completo y baja un poco el padding,
     pero NO baja de 44px de alto — es un objetivo táctil. */
  #dash .dw-lrow{ padding:8px 6px; }

  /* ---- próximos días en el celu ----
     Las flechas se van: en táctil se arrastra con el dedo, y dos botones que nadie
     toca ocupan el lugar del título. */
  #dash .dd-nav{ display:none; }
  /* Un pelo más chicas para que entren 4 enteras + el recorte de la quinta a 393px:
     4×68 + 3×9 = 299 sobre ~325 útiles. Ese resto es el que comunica el deslizable. */
  #dash .dd-day{ width:68px; }

  /* 🔴 LA FILA DEL EVENTO PASA A DOS RENGLONES. Medido a 393px: con hora + cliente +
     chip de estado + "Ver evento" todo en una línea, al nombre del cliente le
     quedaban ~55px y se leía "Fiesta d..." / "Corporativ...". Los datos que el
     pedido pide mostrar (hora, cliente, tipo, lugar, estado y el botón) no entran en
     una fila a este ancho, así que se apilan: arriba la hora y el nombre completo,
     abajo el estado y la acción. Es el mismo tratamiento que ya recibe `.dev .r` en
     Próximos eventos por el mismo motivo. */
  #dash .dd-ev{ display:grid; grid-template-columns:auto 1fr; gap:4px 11px;
    align-items:start; padding:12px; }
  #dash .dd-ev .hr{ grid-row:1; }
  #dash .dd-ev .in{ grid-row:1; }
  /* La segunda fila arranca bajo el nombre, no bajo la hora: alineada con el texto
     se lee como parte del mismo bloque. */
  #dash .dd-ev .dchip{ grid-column:2; grid-row:2; justify-self:start; }
  /* ⚠️ El alto NO baja de 44px aunque la fila apile: es el único control de esta
     tarjeta y se toca con el pulgar. Se le da aire con el padding en vez de
     achicarlo. */
  #dash .dd-ev .go{ grid-column:2; grid-row:2; justify-self:end; min-height:44px;
    padding:10px 0 4px; }

  #dash .dpago{ flex-wrap:wrap; }

  /* ---- UN SOLO SCROLL: nada con scroll propio adentro del panel ----
     🔴 Tercer síntoma de "abajo no se ve", distinto de los otros dos (franja /
     falta de padding), y el que volvió esta vez.

     En escritorio "Próximos eventos" (ya no existe: se fue el 04/09/2026, pero el
     mecanismo sigue valiendo para cualquier lista) tenía scroll propio
     (`max-height:min(52vh,430px)`) para que el panel no se estirara. En el celu ese mismo tope es veneno: la lista
     arranca a media pantalla, así que sus 430px terminan ~100px POR DEBAJO del borde
     de abajo. Resultado: la última tarjeta visible queda cortada contra el borde y,
     peor, como el scroller tiene `overscroll-behavior:contain`, arrastrar el dedo
     adentro de la lista NUNCA mueve la página — parece que abajo no hay nada más.

     Regla para siempre: adentro de #dash, en mobile, el único que scrollea es #dash.
     Si un contenedor de verdad necesita scroll propio, marcalo con
     `data-scroll-propio` en el HTML (ver `unSoloScroll()` en el JS del panel). */
  #dash .dtareas,
  #dash .dash-sin-scroll{ max-height:none !important; overflow:visible !important; }

  /* ---- lo que no entra en una pantalla de 6" ----
     Ocupación y Próximos presupuestos son análisis de escritorio; el CTA es
     redundante con el header pegajoso.
     El calendario y las tareas se quedan.

     El "#dash " de adelante no es decorativo: la regla base del CTA es `#dash .dcta`
     (1 id + 1 clase), que le gana en especificidad a un `#dashPanelCta` pelado y lo
     dejaba visible. Con los tres escritos igual no hay que acordarse de cuál era cuál. */
  #dash #dashPanelOcup, #dash #dashPanelProx, #dash #dashPanelCta{ display:none; }

  /* ---- alertas ----
     Este panel NO se esconde en mobile, y es a propósito: es el único que te dice qué
     hacer hoy, o sea justo lo que venís a mirar cuando abrís la app en el celu.
     Lo único que cambia es la fila, que a 393px no entra en una línea: el nombre del
     cliente comía el "Ver evento →" y lo dejaba cortado contra el borde. */
  :is(#dash,#notis) .dalert{ padding:15px 15px; border-radius:12px; }
  :is(#dash,#notis) .dalert.ok{ padding:12px 15px; }
  :is(#dash,#notis) .dalrow{ flex-direction:column; align-items:stretch; gap:8px; }
  :is(#dash,#notis) .dalrow .r{ justify-content:space-between; }
  :is(#dash,#notis) .dalhd{ gap:8px; margin-bottom:12px; }

  /* ---- ficha técnica a pantalla completa ---- */
  #dashFicha{ padding:0; }
  /* 100vh y no 100dvh: ver el bloque del alto de #dash — dvh deja franja en la app
     instalada. El aire de abajo lo pone el padding con safe-area de .fbd. */
  #dashFicha .fbox{ max-width:none; max-height:100vh; height:100vh;
    border-radius:0; border:0; }
  #dashFicha .fhd{ padding:calc(14px + env(safe-area-inset-top)) 16px 14px; gap:12px; }
  #dashFicha .fhd .ftit{ font-size:17px; }
  #dashFicha .fbd{ padding:6px 16px calc(24px + env(safe-area-inset-bottom)); }
  /* clave/valor apilados: con .fk2 en 170px fijos no queda ancho para el valor */
  #dashFicha .frow{ flex-direction:column; gap:2px; padding:9px 0; }
  #dashFicha .frow .fk2{ width:auto; font-size:11px; }

  /* ---- botón "◧ Panel" ----
     El margin-right:-14px de la base compensa el gap de 26px de .cp-bar en
     escritorio; con el gap de 14px de mobile descuadra. */
  .cp-bar > #btnDash{ margin-right:0; }
}

  /* 🔴 TRES VARIABLES, Y CADA UNA CONTESTA UNA PREGUNTA DISTINTA.
       `--navh`    = cuánto MIDE la franja que ocupa la barra. No dice de qué lado está.
       `--nav-top` = cuánto hay que reservar ARRIBA.  En mobile 0.
       `--nav-bot` = cuánto hay que reservar ABAJO.   En escritorio 0.
     Existen las dos direccionales para que cada consumidor escriba
     `calc(X + var(--nav-top)) ... calc(Y + var(--nav-bot))` UNA sola vez y funcione en
     los dos lados sin repetir el breakpoint en cada regla. El breakpoint vive en un
     único lugar: el @media de acá abajo. Si agregás un consumidor nuevo, usá las
     direccionales — `--navh` pelado es "el alto", y usarlo como reserva de abajo es
     justo el bug que aparece cuando la barra se muda de lado. */
  /* 28/09/2026: --nav-bot suma --mini-h, el reproductor de vidrio de Cabina cuando hay un tema cargado
     (flota arriba de la barra en todas las páginas): todo lo que dejaba aire para la barra deja también para él. */
  :root{ --navh: calc(54px + env(safe-area-inset-bottom)); --nav-top:0px; --nav-bot:calc(var(--navh) + var(--mini-h, 0px)); }

  /* La barra va ABAJO (tab bar tipo iOS): el pulgar la alcanza sin estirar la mano y
     no le come el aire al header de cada página. El env() que la infla es el de abajo
     —el indicador de inicio del iPhone—, no el del notch. */
  /* 🔴 `--nav-lado` NO es decorativo: lo LEE el script que mide --navh, para saber
     desde qué borde tiene que medir. Es la forma de que el breakpoint siga viviendo
     solo en el CSS en vez de estar duplicado en un matchMedia del JS. Si movés la
     barra de lado, cambiá esto en el mismo bloque. */
  #navbar{ --nav-lado:abajo;
    position:fixed; bottom:0; left:0; right:0; z-index:950; display:flex; gap:4px;
    /* 05/09/2026, medido en el simulador del iPhone 17 Pro Max: con `5px +
       safe-area` los pills terminaban a 39pt del borde (a la altura de la barra de
       Safari) y en el tema oscuro, con el fondo de la barra igual al de la página, se
       leían flotando en el vacío. Ahora bajan a ~26pt del borde —lo que deja el dock
       de iOS 26— sin pisar el indicador de inicio (arranca a ~9pt del borde). En
       aparatos sin indicador el safe-area es 0 y manda el piso de 10px. */
    padding:5px 8px max(10px, calc(env(safe-area-inset-bottom) - 8px)); box-sizing:border-box;
    background:var(--t-panel-bg); border-top:1px solid color-mix(in srgb, var(--t-ink) 10%, transparent);
    font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; }

  /* Faldón. Red de seguridad para el mismo síntoma que arregla el meta `black`: si en
     algún aparato la barra igual no queda pegada al borde de abajo, lo que sobre se
     pinta del color de la barra en vez de verse una franja. Cuando la barra SÍ está
     pegada —el caso normal— el faldón cae fuera de pantalla y no se ve nunca. */
  #navbar::after{ content:""; position:absolute; left:0; right:0; top:100%; height:160px;
    background:var(--t-panel-bg); pointer-events:none; }

  #navbar .nvb{ flex:1; min-width:0; display:flex; flex-direction:column; align-items:center;
    justify-content:center; gap:2px; padding:6px 2px; border:0; border-radius:10px;
    background:transparent; color:var(--t-panel-muted); font:inherit; font-size:11px; font-weight:600;
    cursor:pointer; -webkit-tap-highlight-color:transparent;
    transition:color .18s ease, background-color .18s ease; }
  #navbar .nvi{ font-size:17px; line-height:1; }
  #navbar .nvl{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; max-width:100%; }

  /* El indicador: el ítem activo toma el color de SU página sobre un tinte
     translúcido — el mismo patrón que ya usa .dpill en el panel. El color va por
     variable para que el pill y cualquier otro acento salgan de un solo lugar. */
  #navbar .nvb[aria-current="page"]{ color:var(--nvc); background:var(--nvbg); }

  /* 🔴 EL COLOR SALE DEL BOTON, NO DE SU POSICION. Iba por `:nth-child`, o sea
     atado al orden fisico de la barra, y eso ya se rompio una vez: al entrar el "+"
     en el segundo lugar se quedo con el verde que era de "Evento", e Historial —que
     es el quinto— nunca llego a tener color porque las reglas terminaban en el
     cuarto. Es la misma dependencia de la posicion que hacia que `pintarTabs()`
     marcara el "+" como pestaña activa.
     ⚠️ Boton nuevo en la barra → se pinta por su `data-pag`, nunca por donde este. */
  #navbar .nvb[data-pag="0"]{ --nvc:var(--t-panel-accent); --nvbg:color-mix(in srgb, var(--t-panel-accent) 16%, transparent); }  /* Panel     */
  #navbar .nvb[data-pag="2"]{ --nvc:var(--t-info); --nvbg:color-mix(in srgb, var(--t-info) 16%, transparent); }   /* Agenda    */
  #navbar .nvb[data-pag="3"]{ --nvc:var(--t-warn); --nvbg:color-mix(in srgb, var(--t-warn) 16%, transparent); }    /* Presu     */
  /* Historial toma el violeta que YA usa adentro (`--d-acc`: sus chips activos y su
     anillo de foco), asi que no entra un color nuevo a la paleta.
     ⚠️ Va en hex y no como `var(--d-acc)` porque esa variable esta declarada en
     `#dash, #dashFicha, #notis, #hist` y el navbar no es descendiente de ninguno:
     ahi la variable no resuelve y el pill se quedaria sin color, que es exactamente
     el estado del que lo estamos sacando.
     ⚠️ Comparte el violeta con Panel a proposito —es el acento de la app— y no
     molesta porque nunca hay dos pestañas activas a la vez. */
  #navbar .nvb[data-pag="4"]{ --nvc:var(--t-panel-accent); --nvbg:color-mix(in srgb, var(--t-panel-accent) 16%, transparent); }  /* Historial */

  /* 🔴 EL "+" NO ES UNA PAGINA, ASI QUE SU ESTADO NO SALE DE `aria-current` SINO
     DE `aria-expanded`: se prende solo mientras el menu esta abierto y se apaga al
     cerrarlo, elijas o no una opcion. Es el verde ya validado que antes correspondia
     a Evento — no entra ningun color nuevo.
     🔴 EL TINTE ES MAS FLOJO QUE EL DE UNA PESTAÑA ACTIVA (0.10 contra 0.16) A
     PROPOSITO: con el mismo peso se leeria como "estoy en la seccion Crear", que es
     justo lo que no es. La respuesta principal es el menu que aparece; esto solo
     dice de donde salio. Se funde con la transicion que `.nvb` ya tiene. */
  #navbar .nvb[data-crear]{ --nvc:var(--t-ok); --nvbg:color-mix(in srgb, var(--t-ok) 16%, transparent); }
  #navbar .nvb[data-crear][aria-expanded="true"]{
    color:var(--nvc); background:color-mix(in srgb, var(--t-ok) 10%, transparent); }

  /* En escritorio no hay carrusel (el gesto se gatea a ≤1023px), así que la barra es
     solo navegación directa: cuatro pills compactos y centrados en vez de cuatro
     columnas estiradas a lo ancho de 1280px. */
  /* ═══ ESCRITORIO: LA BARRA VA ARRIBA ═══
     La de abajo es una tab bar para el PULGAR. Con mouse esa posición no tiene ningún
     sentido: el recorrido del cursor hasta el borde inferior es el más largo de la
     pantalla, y encima compite con la barra de tareas del sistema. Arriba es donde un
     menú de escritorio se busca. Y como acá no hay carrusel (el gesto está gateado a
     ≤1023px), la barra es navegación directa y nada más.
     🔴 Lo que se mueve es SOLO la barra. La lógica del teclado (`TecladoChat`, todo el
     bloque de `#chatIA.vv`) es un problema de iOS y no se toca ni se replica acá: en
     escritorio el teclado es físico y no achica ningún viewport. */
  @media (min-width:1024px){
    /* La barra es más baja acá. Este valor es solo el fallback por si el script que
       mide la barra no llegó a correr: apenas corre, --navh pasa a ser el alto real. */
    :root{ --navh:44px; --nav-top:var(--navh); --nav-bot:var(--mini-h, 0px); }   /* abajo solo queda el reproductor de Cabina */
    #navbar{ --nav-lado:arriba;
      top:0; bottom:auto;
      border-top:0; border-bottom:1px solid color-mix(in srgb, var(--t-ink) 6%, transparent);
      /* Aire de mouse: los pills se separan de verdad en vez de quedar amontonados
         como en la versión táctil, donde el ancho es un recurso escaso y los cuatro
         ítems tienen que entrar en 375px. Acá sobran 1280. */
      justify-content:center; gap:14px; padding:8px 18px; }
    /* El faldón apunta para el otro lado: es la red por si quedara un hueco entre la
       barra y el borde, y ahora el borde es el de arriba. Cae fuera de pantalla. */
    #navbar::after{ top:auto; bottom:100%; }
    #navbar .nvb{ flex:0 0 auto; flex-direction:row; gap:10px; min-width:132px;
      padding:9px 22px; font-size:12.5px; border-radius:9px; }
    #navbar .nvi{ font-size:15px; }
    /* Hover: existe solo acá porque solo acá hay un cursor que se pueda apoyar sin
       hacer click. En táctil `:hover` se queda pegado después de tocar. */
    /* ⚠️ Se excluye tambien el "+" con el menu abierto: pesa igual que la regla del
       estado abierto y va despues en la hoja, asi que sin esto el gris del hover le
       ganaba al verde justo mientras el menu estaba desplegado. */
    :where(html.puntero) #navbar .nvb:not([aria-current="page"]):not([aria-expanded="true"]):hover{ color:var(--t-panel-dim); background:color-mix(in srgb, var(--t-ink) 5%, transparent); }
    /* El modal de Evento rápido como PÁGINA (z-940) queda debajo de la barra, así que
       su caja arranca más abajo. Como MODAL (z-10065) la tapa y no necesita nada.
       Va adentro del @media: en mobile el bloque de abajo le pone `padding:0`. */
    #qev.carr{ padding-top:calc(4vh + var(--nav-top)); }
    /* ⚠️ El `max-height:92vh` de la caja no sabe nada del padding del contenedor, así
       que con la barra sumada arriba (4vh + 50) el borde de abajo se pasaba de la
       pantalla. Medido: la caja llegaba a 800.3 en un viewport de 800. */
    #qev.carr .qbox{ max-height:calc(92vh - var(--nav-top)); }
  }

  /* 🔴 Las tres páginas fijas NO se recortan con `bottom:var(--navh)`: se quedan con
     el `inset:0` de su regla base y la barra les flota encima. Recortarlas fue
     exactamente el bug de la "franja negra abajo de todo" que ya está documentado
     para `dvh` en el CLAUDE.md — el overlay resuelve más bajo que la pantalla en la
     app instalada y abajo aparece el fondo del body. Tapar la pantalla entera es lo
     único que garantiza que no haya franja.

     El lugar donde se reserva el aire de la barra es el PADDING DE ABAJO DEL
     CONTENIDO, no el alto del overlay: `#dash .dwrap`, `.ag-foot` y `#qev .qft` ya
     traían su `env(safe-area-inset-bottom)` y ahora suman `--navh`, que lo incluye.

     El presupuestador sí está en flujo normal, así que ese va por padding del body. */
  #qev.carr{ z-index:940; }
  /* 🔴 SOLO `#agenda`, no `.agenda`. Los otros tres cajones que comparten esa clase
     viven ARRIBA de la barra (#numeros 10050, #dashFicha 10060, #chatIA 10070), así
     que la tapan y no tienen que reservar nada; `#agenda` está en z-81 y sí queda
     debajo. En mobile `--nav-top` es 0, o sea que esto resuelve al `top:0` de siempre
     y no hace falta un media query. */
  /* ===========================================================================
     EL SELECTOR DE "CREAR"
     ===========================================================================
     Va por encima de la tab bar (950) porque sale de ella, y por debajo de los
     modales de verdad. En mobile aparece pegado a la barra; en escritorio, donde
     la barra esta arriba, baja desde ahi. */
  .crear-ov{ position:fixed; inset:0; z-index:960; background:rgba(0,0,0,.45); }
  .crear-ov[hidden]{ display:none; }
  .crear{ position:fixed; z-index:961; left:50%; transform:translateX(-50%);
    bottom:calc(12px + var(--nav-bot, 0px)); width:min(420px, calc(100vw - 24px));
    background:var(--uicard); border:1px solid var(--uiline); border-radius:16px;
    padding:8px; box-shadow:0 26px 60px -18px rgba(0,0,0,.85);
    display:flex; flex-direction:column; gap:4px; }
  .crear[hidden]{ display:none; }
  .crear-op{ display:flex; align-items:center; gap:12px; width:100%; text-align:left;
    background:none; border:0; border-radius:12px; padding:13px 12px; cursor:pointer;
    color:var(--uitext); font:inherit; min-height:44px; }
  .crear-op .ci{ font-size:20px; line-height:1; flex:0 0 auto; width:34px; text-align:center; }
  .crear-op .ct{ display:flex; flex-direction:column; gap:2px; min-width:0; }
  .crear-op .ct b{ font-size:14px; font-weight:700; }
  .crear-op .ct small{ font-size:11.5px; color:var(--uimut); line-height:1.4; }
  :where(html.puntero) .crear-op:hover{ background:var(--t-surface-2); }
  .crear-op:active{ background:var(--t-surface-2); }
  .crear-op:focus-visible{ outline:2px solid var(--acc); outline-offset:-2px; }
  .crear-x{ background:none; border:0; border-top:1px solid var(--uiline); margin-top:4px;
    color:var(--uimut); font:inherit; font-size:12.5px; padding:12px; min-height:44px;
    cursor:pointer; border-radius:0 0 12px 12px; }
  :where(html.puntero) .crear-x:hover{ color:var(--uitext); }
  /* 🔴 EL "+" MUESTRA SOLO EL SIMBOLO. La etiqueta se esconde a la vista pero NO se
     borra del DOM: sigue ahi para quien no ve el icono, y el boton ademas lleva
     `aria-label="Crear"`. Es el unico de la barra que no es una pestaña, asi que
     tampoco compite con las cuatro que si lo son. */
  #navbar .nvb-mas .nvl{ position:absolute; width:1px; height:1px; overflow:hidden;
    clip-path:inset(50%); white-space:nowrap; }
  #navbar .nvb-mas .nvi{ font-size:22px; }
  #navbar .nvb-mas{ justify-content:center; }

  #agenda{ top:var(--nav-top); }

  /* ===========================================================================
     LA AGENDA COMO PAGINA, SOLO EN ESCRITORIO
     ===========================================================================
     🔴 TODO ESTO VIVE ADENTRO DE `min-width:1024px` Y DE `.pagina`. Las dos
     condiciones hacen falta: en el celular la Agenda no cambia ni un pixel —es la
     misma hoja de siempre— y el CAJON tampoco, porque se abre encima del Panel o
     del presupuestador y ensancharlo taparia lo que quedo atras.
     ⚠️ No hay un calendario nuevo ni una lista nueva: es EL MISMO markup, puesto
     en dos columnas con grid. Cero JS. */
  @media (min-width:1024px){
    #agenda.pagina{
      /* De hoja de 560px a pagina entera. `left:0` es lo que la ensancha: el
         `width` del cajon deja de mandar porque los dos bordes estan anclados. */
      left:0; width:auto;
      border-left:0; box-shadow:none;
      background:linear-gradient(180deg,var(--a-bg2),var(--a-bg));
    }
    /* El header de la pagina no necesita la ✕ del cajon: se sale por la tab bar.
       Se deja igual para no cambiar comportamiento, solo se centra el contenido. */
    #agenda.pagina .agenda-hd,
    #agenda.pagina .ag-foot{ max-width:1320px; margin-left:auto; margin-right:auto; width:100%; }
    #agenda.pagina .agenda-body{ padding:18px 28px 26px; }
    #agenda.pagina .agenda-body > *{ max-width:1320px; margin-left:auto; margin-right:auto; }

    /* 🔴 DOS COLUMNAS CON EL MISMO MARKUP. El calendario a la izquierda —grande,
       pero con techo: sin el `max-width` las celdas se vuelven cuadrados enormes en
       un monitor ancho y el mes se lee peor, no mejor— y a la derecha lo que cambia
       cuando tocás una fecha: los totales, el buscador, los filtros y la lista. */
    #agenda.pagina #agViewAgenda{
      display:grid;
      grid-template-columns:minmax(0,1.05fr) minmax(0,1fr);
      grid-template-areas:
        "buscar buscar"
        "cal stats"
        "cal tools"
        "cal lista";
      grid-template-rows:auto auto auto 1fr;
      gap:0 26px;
      align-items:start;
      max-width:1320px; margin:0 auto;
    }
    #agenda.pagina #agViewAgenda > .ag-buscar{ grid-area:buscar; position:static; max-width:620px; }
    #agenda.pagina #agViewAgenda > .ag-cal  { grid-area:cal;   max-width:620px; margin-bottom:0; }
    #agenda.pagina #agViewAgenda > .ag-stats{ grid-area:stats; }
    #agenda.pagina #agViewAgenda > .ag-tools{ grid-area:tools; }
    #agenda.pagina #agViewAgenda > .ag-list { grid-area:lista; }
    /* El calendario acompaña el scroll de la lista: en una pagina alta, perderlo de
       vista obliga a subir para cambiar de dia. */
    #agenda.pagina #agViewAgenda > .ag-cal{ position:sticky; top:0; }
    /* Las fechas, comodas de leer. `aspect-ratio` sigue mandando: esto solo sube el
       piso para que en una columna ancha no queden como botones diminutos. */
    #agenda.pagina .ag-cell{ min-height:56px; font-size:14px; }
    #agenda.pagina .ag-cell .dn{ font-size:14.5px; }
    #agenda.pagina .ag-cal-hd .mlabel{ font-size:17px; }
    #agenda.pagina .ag-tools .ag-quick{ flex:0 0 auto; }
    /* Métricas no se toca: es una vista de ancho completo y ahi el grid estorba. */
    #agenda.pagina #agViewMetrics{ max-width:1320px; margin:0 auto; }
  }

  body{ padding-top:var(--nav-top); padding-bottom:var(--nav-bot); }

  /* El canvas (lo que se pinta afuera de la caja del body y en cualquier franja que
     el viewport de la app instalada deje sin cubrir) va del color de la barra, no del
     fondo del body: así un pixel de más abajo de la barra se lee como parte de ella
     y no como una franja negra. */
  html{ background:var(--t-panel-bg); }

  /* Mientras el dedo arrastra, las páginas no pueden tener transición propia o
     irían "atrasadas" respecto del dedo. `.agenda` trae una de .32s de fábrica. */
  .carr-drag{ transition:none !important; }
  /* Contexto de apilado para el presupuestador, que es el único que no es fixed. */
  .carr-vista{ position:relative; z-index:901; will-change:transform; }
  .carr-anim{ transition:transform .26s cubic-bezier(.22,.61,.36,1) !important; }

      .fld .acepto{ display:flex; align-items:center; gap:6px; margin-top:6px;
        font-size:11px; letter-spacing:.04em; text-transform:uppercase; opacity:.72; cursor:pointer; }
      .fld .acepto input{ width:auto; margin:0; cursor:pointer; }
      :where(html.puntero) .fld .acepto:hover{ opacity:1; }
    
  /* 🔴 z-index 10075, arriba de #chatIA (10070) y de su velo (10069). Con el 9999 de
     antes, abrir el stock con el agente abierto lo dejaba enterrado abajo del velo
     —que en mobile es OPACO— y se veía una pantalla gris sin un dato. Que el chat se
     cierre al abrir el stock (ver openP) alcanza para el camino normal; esto es la red
     por si algún día aparece otra vía que abra el panel sin pasar por ahí. */
  #sp-overlay{ position:fixed; inset:0; z-index:10075; background:#0E1116; display:none; flex-direction:column; }
  #sp-overlay.open{ display:flex; }
  #sp-bar{ flex:none; display:flex; align-items:center; gap:12px;
    padding:calc(11px + env(safe-area-inset-top)) 16px 11px;
    background:#161A21; border-bottom:1px solid #2A313D; color:#E8EBF0;
    font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; }
  #sp-bar .sp-t{ font-weight:700; font-size:14px; letter-spacing:.4px; }
  #sp-bar .sp-t span{ color:#8B95A5; font-weight:400; }
  #sp-bar .sp-x{ margin-left:auto; background:#26262b; border:1px solid #3a3a42; color:#e9e7e2;
    border-radius:8px; width:40px; height:38px; font-size:18px; line-height:1; cursor:pointer; font-family:inherit; }
  :where(html.puntero) #sp-bar .sp-x:hover{ border-color:#E9B14C; }
  #sp-frame{ flex:1; width:100%; border:0; background:#0E1116; }
  #sp-foot{ flex:none; display:flex; padding:12px 16px calc(12px + env(safe-area-inset-bottom));
    background:#161A21; border-top:1px solid #2A313D; }
  #sp-foot .sp-add{ flex:1; background:#E9B14C; color:#1a1206; border:0; border-radius:10px;
    padding:14px 18px; font-size:15px; font-weight:700; cursor:pointer;
    font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; }
  :where(html.puntero) #sp-foot .sp-add:hover{ filter:brightness(1.06); }
  .topactions{ margin:2px 0 12px; }
  .topactions .btn{ font-size:13.5px; padding:11px 18px; }

  #stockEditor{ display:none; background:transparent; color:var(--uitext);
    border-top:1px solid var(--t-line); margin-top:14px; padding:14px 0 4px;
    font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; }
  #stockEditor.show{ display:block; }
  #stockEditor .se-h{ display:flex; align-items:center; gap:10px; margin-bottom:10px; flex-wrap:wrap; }
  #stockEditor .se-h .t{ font-size:10px; letter-spacing:2px; text-transform:uppercase; color:var(--uimut); }
  #stockEditor .se-h .c{ font-family:'Liberation Mono',Menlo,monospace; color:var(--acc); font-size:12px; }
  #stockEditor .se-h .sp{ margin-left:auto; display:flex; gap:8px; flex-wrap:wrap; }
  #stockEditor .se-list{ display:flex; flex-direction:column; gap:6px; max-height:300px; overflow:auto; }
  #stockEditor .se-row{ display:flex; align-items:center; gap:10px; background:var(--uicard);
    border:1px solid var(--uiline); border-radius:8px; padding:8px 10px; }
  #stockEditor .se-row .q{ font-family:'Liberation Mono',Menlo,monospace; color:var(--uimut); font-size:12px; min-width:34px; }
  #stockEditor .se-row .nm{ flex:1; font-size:12.5px; line-height:1.3; }
  #stockEditor .se-row .nm .kk{ font-size:9px; letter-spacing:1px; color:var(--acc); text-transform:uppercase; margin-right:6px; }
  #stockEditor .se-row .pr{ display:flex; align-items:center; gap:5px; flex:none; }
  #stockEditor .se-row .pr span{ font-size:11px; color:var(--uimut); }
  #stockEditor .se-row .pr input{ width:96px; background:var(--t-input); border:1px solid var(--uiline);
    color:var(--uitext); border-radius:6px; padding:6px 8px; font-size:12.5px; font-family:inherit; text-align:right; }
  #stockEditor .se-row .pr input:focus{ outline:none; border-color:var(--acc); }
  #stockEditor .se-foot{ display:flex; align-items:center; gap:16px; margin-top:12px; flex-wrap:wrap; }
  #stockEditor .se-foot .sub{ font-size:13px; }
  #stockEditor .se-foot .sub b{ font-family:'Liberation Mono',Menlo,monospace; color:var(--acc); font-size:15px; }
  #stockEditor .se-empty{ font-size:11px; color:var(--uimut); line-height:1.5; max-width:560px; }

  #pvOv{ position:fixed; inset:0; z-index:10050; background:rgba(10,10,12,.72); display:none; }
  #pvOv.open{ display:block; }
  #pvBox{ position:fixed; inset:3vh 3vw; z-index:10051; display:none; flex-direction:column;
          background:var(--t-surface); border-radius:12px; overflow:hidden; box-shadow:0 20px 60px rgba(0,0,0,.5); }
  #pvBox.open{ display:flex; }
  #pvBox .pv-hd{ display:flex; align-items:center; gap:12px; padding:11px 14px; background:var(--t-input);
                 border-bottom:1px solid var(--t-line); color:var(--t-ink); font-size:13px; flex-shrink:0; }
  #pvBox .pv-hd b{ font-size:14px; }
  #pvBox .pv-hd .pv-nm{ opacity:.6; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #pvBox .pv-hd .pv-sp{ margin-left:auto; }
  #pvBox .pv-btn{ background:transparent; border:1px solid var(--t-line-2); color:var(--t-ink); border-radius:7px;
                  padding:6px 11px; font:inherit; font-size:12px; cursor:pointer; }
  :where(html.puntero) #pvBox .pv-btn:hover{ background:var(--t-surface-2); }
  #pvFrame{ flex:1; width:100%; border:0; background:var(--t-line-2); }
  #pvFallback{ display:none; padding:26px 20px; text-align:center; color:var(--t-muted); font-size:14px; line-height:1.6; }
  #pvBox.nativo #pvFrame{ display:none; }
  #pvBox.nativo #pvFallback{ display:block; }

  .ptr{ position:absolute; top:0; left:0; right:0; height:0; display:flex; justify-content:center;
    pointer-events:none; z-index:6; }
  .ptr > span{ margin-top:-42px; width:34px; height:34px; border-radius:50%;
    background:var(--t-panel-surface); border:1px solid color-mix(in srgb, var(--t-ink) 16%, transparent); color:var(--t-ink);
    display:grid; place-items:center; font-size:15px; line-height:1; opacity:0;
    box-shadow:0 8px 20px -8px rgba(0,0,0,.8); }
  .ptr.anim > span{ transition:transform .26s cubic-bezier(.2,.7,.2,1), opacity .22s ease; }
  .ptr.load > span{ animation:ptrGira .75s linear infinite; }
  @keyframes ptrGira{ from{ rotate:0deg; } to{ rotate:360deg; } }
  @media (prefers-reduced-motion:reduce){ .ptr.load > span{ animation:none; } }
  /* que el rebote del contenedor no arrastre la página de atrás */
  #dash, .agenda-body{ overscroll-behavior-y:contain; }
  .agenda-body{ position:relative; }

  .pk-ov{ position:fixed; inset:0; z-index:10070; background:transparent; }
  .pk{ position:fixed; background:var(--t-surface-1); border:1px solid var(--t-line-2); border-radius:14px;
    box-shadow:0 26px 60px -18px rgba(0,0,0,.85); padding:12px; width:262px; box-sizing:border-box;
    font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; color:var(--uitext);
    animation:pkIn .13s ease-out; }
  @keyframes pkIn{ from{ opacity:0; transform:translateY(-4px); } to{ opacity:1; transform:none; } }
  .pk-hd{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-bottom:10px; }
  .pk-hd .pk-m{ font-size:13px; font-weight:700; letter-spacing:.2px; }
  .pk-nav{ width:26px; height:26px; border-radius:7px; border:1px solid var(--t-line); background:var(--t-input);
    color:var(--uitext); cursor:pointer; font:inherit; font-size:14px; line-height:1; flex:none; }
  :where(html.puntero) .pk-nav:hover{ border-color:var(--acc); }
  .pk-dow{ display:grid; grid-template-columns:repeat(7,1fr); gap:2px; margin-bottom:4px; }
  .pk-dow span{ text-align:center; font-size:9px; letter-spacing:.6px; text-transform:uppercase; color:var(--uimut); }
  .pk-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:2px; }
  .pk-d{ aspect-ratio:1/1; border:0; background:transparent; color:var(--uitext); border-radius:8px;
    font:inherit; font-size:12px; cursor:pointer; padding:0; font-variant-numeric:tabular-nums; }
  :where(html.puntero) .pk-d:hover{ background:var(--t-surface-2); }
  .pk-d.off{ color:var(--t-dim); }
  .pk-d.hoy{ box-shadow:inset 0 0 0 1px var(--acc); color:var(--acc); font-weight:700; }
  .pk-d.on{ background:var(--acc); color:var(--t-on-accent); font-weight:700; }
  .pk-ft{ display:flex; gap:6px; margin-top:10px; }
  .pk-ft button{ flex:1; border:1px solid var(--t-line); background:var(--t-input); color:var(--uimut);
    border-radius:8px; padding:7px 8px; font:inherit; font-size:11px; cursor:pointer; }
  :where(html.puntero) .pk-ft button:hover{ color:var(--uitext); border-color:var(--t-line-2); }
  /* horas: lista scrolleable, no rueda nativa */
  .pk.time{ width:132px; padding:6px; }
  .pk-list{ max-height:236px; overflow-y:auto; overscroll-behavior:contain; }
  .pk-list::-webkit-scrollbar{ width:6px; }
  .pk-list::-webkit-scrollbar-thumb{ background:var(--t-line-2); border-radius:3px; }
  .pk-h{ display:block; width:100%; text-align:center; border:0; background:transparent; color:var(--uitext);
    border-radius:7px; padding:9px 0; font-family:'SFMono-Regular',Menlo,monospace; font-size:13px; cursor:pointer; }
  :where(html.puntero) .pk-h:hover{ background:var(--t-surface-2); }
  .pk-h.on{ background:var(--acc); color:var(--t-on-accent); font-weight:700; }
  /* En pantallas chicas deja de ser popover y pasa a hoja centrada: pegado al campo
     se salía de la pantalla y encima quedaba abajo del teclado. */
  @media (max-width:560px){
    .pk-ov{ background:rgba(0,0,0,.55); display:flex; align-items:center; justify-content:center; padding:18px; }
    .pk{ position:static; width:min(320px,100%); padding:14px; }
    .pk.time{ width:min(200px,100%); }
    .pk-list{ max-height:min(52vh,320px); }
    .pk-d{ font-size:14px; }
    .pk-h{ font-size:15px; padding:11px 0; }
  }

  #qev{ position:fixed; inset:0; z-index:10065; display:none; background:rgba(6,7,12,.78);
    padding:4vh 4vw; box-sizing:border-box; font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; }
  #qev.on{ display:flex; align-items:flex-start; justify-content:center; }
  #qev .qbox{ background:var(--t-surface-1); border:1px solid var(--t-line-2); border-radius:16px; width:100%; max-width:460px;
    max-height:92vh; display:flex; flex-direction:column; overflow:hidden; color:var(--uitext);
    box-shadow:0 30px 70px -24px rgba(0,0,0,.9); animation:qevIn .16s ease-out; }
  @keyframes qevIn{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }
  #qev .qhd{ display:flex; align-items:flex-start; gap:14px; padding:18px 20px 14px; border-bottom:1px solid var(--t-surface-2); }
  #qev .qhd .k{ font-size:9.5px; font-weight:700; letter-spacing:1.5px; text-transform:uppercase; color:var(--uimut); }
  #qev .qhd .t{ font-size:17px; font-weight:700; margin-top:4px; }
  #qev .qhd .s{ font-size:11.5px; color:var(--uimut); margin-top:4px; line-height:1.5; }
  #qev .qx{ margin-left:auto; flex:none; width:30px; height:30px; border-radius:8px; background:var(--t-input);
    border:1px solid var(--t-line); color:var(--uitext); font:inherit; font-size:14px; line-height:1; cursor:pointer; }
  :where(html.puntero) #qev .qx:hover{ border-color:var(--a-red,var(--t-err)); color:var(--a-red,var(--t-err)); }
  #qev .qbd{ overflow-y:auto; padding:16px 20px 20px; }
  #qev .qgrid{ display:grid; grid-template-columns:1fr 1fr; gap:12px 12px; }
  #qev .qgrid .full{ grid-column:1/-1; }
  #qev .qft{ display:flex; gap:9px; padding:14px 20px calc(16px + env(safe-area-inset-bottom));
    border-top:1px solid var(--t-surface-2); }
  #qev .qft .btn{ flex:1; justify-content:center; text-align:center; }
  #qev .qmsg{ font-size:11.5px; color:var(--a-red,var(--t-err)); min-height:15px; margin-top:10px; }
  @media (max-width:560px){
    #qev{ padding:0; }
    /* 100vh, no dvh: ver el bloque del alto de #dash en el skin mobile del panel */
    #qev .qbox{ max-width:none; max-height:100vh; height:100vh; border-radius:0; border:0; }
    /* Como PÁGINA del carrusel termina arriba de la tab bar, así que el alto es el
       viewport MENOS la barra. Con los 100vh de arriba el pie (Cancelar / Guardar
       en la agenda) quedaba 54px por debajo del borde: se veía cortado y no se
       podía tocar. Como modal sigue siendo 100vh, que ahí sí ocupa todo. */
    #qev.carr .qbox{ max-height:calc(100vh - var(--nav-bot)); height:calc(100vh - var(--nav-bot)); }
    /* El safe-area de arriba lo come el header en los dos casos: con la tab bar
       abajo, la página del carrusel también arranca pegada al notch. */
    #qev .qhd{ padding:calc(14px + env(safe-area-inset-top)) 16px 14px; }
    #qev .qbd{ padding:14px 16px 18px; }
    #qev .qft{ padding:12px 16px calc(14px + env(safe-area-inset-bottom)); }
    #qev .qgrid{ grid-template-columns:1fr; }
    #qev .qgrid .dos{ grid-column:auto; }
  }

  /* Arriba de #dash (900) y abajo de #dashFicha (10060): el cajón se abre DESDE el
     panel, así que con el z-index de fábrica de .agenda (81) quedaba tapado por él. */
  #numeros{ z-index:10050; color-scheme:var(--t-scheme); }
  #numerosOv{ z-index:10049; }

  /* ---- Para revisar · las notificaciones (27/08/2026) ----
     Mismo criterio que #numeros: arriba de #dash (900) porque se abre DESDE el
     panel, y abajo de #dashFicha (10060) porque desde acá se abre la ficha —
     si estuviera por encima, "Ver evento" abriría una pantalla tapada. Es el
     bug que ya tuvo el panel de rental. */
  #notis{ z-index:10052; color-scheme:var(--t-scheme); }
  #notisOv{ z-index:10051; }
  /* El cuerpo ya trae el padding del cajón; el panel de alertas adentro no
     necesita el margen que tenía cuando vivía suelto arriba del dashboard. */
  #notis #dashAlertas{ margin:0; }

  /* Las dos series del gráfico. NO son hex nuevos: son dos de los tres colores de
     Métricas, que ya están validados contra este fondo (ver el comentario largo de
     --m-conf/--m-esp/--m-cons más arriba, "no los cambies a ojo"). Verde = tu plata,
     azul = la de StagePro; ese par es justamente el que separa para daltonismo. */
  /* El `hidden` del HTML lo pone la hoja del navegador con `display:none`, que pierde
     por especificidad contra cualquier `#numeros .x{display:flex}` de acá abajo. Sin
     esta línea, el rango de fechas y el form de alta arrancan visibles. */
  #numeros [hidden]{ display:none !important; }

  /* 🔴 LOS TRES SALEN DE LA PALETA DE METRICAS, QUE YA ESTA VALIDADA. Son los
     mismos tres tonos re-escalados para relleno grande sobre fondo oscuro que usa
     el apilado de Métricas, y pasan los cinco checks del validador de dataviz. No
     inventar un cuarto color a ojo: ver el comentario largo de la paleta. */
  #numeros{ --n-vos:var(--m-conf); --n-mario:var(--m-cons); --n-gastos:var(--m-esp); }
  #numeros .mt-seg.vos{ background:var(--n-vos); }
  #numeros .mt-seg.mario{ background:var(--n-mario); }
  #numeros .mt-seg.gastos{ background:var(--n-gastos); }
  /* Meses que el gráfico muestra pero que caen afuera del período elegido. */
  #numeros .mt-col.fuera{ opacity:.4; }

  /* ---- selector de período ---- */
  #numeros .nm-chips{ margin-bottom:10px; }
  #numeros .nm-chips .ag-tab{ font-size:11.5px; padding:8px 5px; }
  #numeros .nm-rango{ margin-bottom:12px; }
  #numeros .nm-perlab{ display:flex; align-items:center; justify-content:space-between;
    gap:10px; margin-bottom:16px; font-size:12px; color:var(--a-mut); flex-wrap:wrap; }
  #numeros .nm-perlab .lab{ color:var(--a-ink); font-weight:600; }
  /* El botón de moneda se comparte con la pestaña Métricas del cajón de la Agenda:
     el selector estaba scopeado a #numeros y ahí no aplicaba. Mismo control, mismo
     significado, un solo estilo. */
  #numeros .nm-cur, .mt-curbar .nm-cur{ display:flex; align-items:center; gap:7px; background:var(--a-card2);
    border:1px solid var(--a-line); color:var(--a-mut); border-radius:20px; padding:5px 11px;
    font:inherit; font-size:11px; cursor:pointer; transition:border-color .14s; }
  :where(html.puntero) #numeros .nm-cur:hover, :where(html.puntero) .mt-curbar .nm-cur:hover{ border-color:var(--a-acc); }
  #numeros .nm-cur i, .mt-curbar .nm-cur i{ width:6px; height:6px; border-radius:50%; background:var(--a-blue); flex:none; }
  .mt-curbar{ display:flex; align-items:center; gap:10px; margin:0 0 12px; flex-wrap:wrap; }
  .mt-otra{ font-size:11px; color:var(--a-dim); }
  /* Los rechazados NO se apilan con los ingresos y por eso van en su propia franja:
     apilarlos haría que la altura de la barra dijera "esto es lo que facturé" contando
     lo que se cayó. Además, con verde/ámbar/azul ya ocupados no existe un cuarto tono
     que separe bajo daltonismo (medido: cualquier rojo queda en ΔE 3 contra el verde,
     y cualquier violeta en ΔE 2 contra el azul, con un mínimo de 8), así que la serie
     se muestra como número y no como color. */
  .mt-rech{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin-top:10px;
    padding:8px 11px; border:1px solid rgba(207,123,114,.24); background:rgba(207,123,114,.07);
    border-radius:9px; font-size:11.5px; color:var(--a-mut); }
  .mt-rech b{ color:var(--a-red); font-family:var(--a-mono); font-variant-numeric:tabular-nums; }
  .mt-rech .conv{ margin-left:auto; font-size:11px; color:var(--a-dim); }

  /* 🔴 Los campos usan `.fld` del presupuestador tal cual, sin CSS propio. Antes acá
     había un `#numeros input{ font-size:12.5px }` inventado, y abajo de 16px iOS hace
     zoom automático al enfocar: el cajón es position:fixed, así que con el zoom se
     descuadraba encima del contenido y parecía que las cajas se superponían. La regla
     que lo evita ya existía y vive en el media query de 860px:
       .fld input, .fld textarea, .fld select { font-size:16px }
     Si agregás un campo nuevo, envolvelo en .fld y no le pongas font-size. */

  /* ---- KPIs: misma forma que .dkpi del Panel, con la paleta del cajón ----
     Se reescriben en vez de reusar porque las reglas de allá son `#dash .dkpi`. */
  #numeros .nm-kpis{ display:grid; grid-template-columns:repeat(2,1fr); gap:9px; margin-bottom:22px; }
  #numeros .dkpi{ background:var(--a-card); border:1px solid var(--a-line); border-radius:10px; padding:12px 14px; }
  #numeros .dkpi .k{ display:flex; align-items:center; gap:6px; font-size:9.5px; font-weight:700;
    letter-spacing:1px; text-transform:uppercase; color:var(--a-mut); }
  #numeros .dkpi .k i{ width:7px; height:7px; border-radius:50%; display:block; flex:none; }
  #numeros .dkpi .v{ font-family:var(--a-mono); font-size:19px; font-weight:700; margin:7px 0 3px;
    font-variant-numeric:tabular-nums; color:var(--a-ink); line-height:1.05; }
  #numeros .dkpi .v small{ font-size:11px; color:var(--a-mut); font-weight:400; }
  #numeros .dkpi .n{ font-size:10.5px; color:var(--a-mut); line-height:1.45; }
  /* nowrap: sin esto el importe del subtítulo se parte entre la moneda y el número
     ("USD" en una línea, "9.750" en la siguiente) y la tarjeta crece un renglón. */
  #numeros .dkpi .n b{ font-family:var(--a-mono); color:var(--a-ink); font-weight:700; white-space:nowrap; }
  #numeros .dkpi.vos{ border-color:color-mix(in srgb, var(--t-chart-ok) 42%, transparent); background:color-mix(in srgb, var(--t-chart-ok) 7%, transparent); }
  #numeros .dkpi.vos .v{ color:var(--a-green); }
  #numeros .dkpi.mario .v{ color:var(--a-blue); }
  #numeros .nm-aviso{ grid-column:1/-1; background:var(--a-card); border:1px solid var(--a-line2);
    border-radius:10px; padding:14px 15px; font-size:12.5px; color:var(--a-mut); line-height:1.55; }

  /* ---- secciones ---- */
  #numeros .nm-sec{ margin-bottom:24px; }
  #numeros .nm-sect{ font-size:9.5px; font-weight:700; letter-spacing:1.5px; text-transform:uppercase;
    color:var(--a-mut); margin-bottom:10px; display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
  #numeros .nm-sect .esc{ margin-left:auto; letter-spacing:0; text-transform:none; color:var(--a-dim);
    font-family:var(--a-mono); font-size:10px; font-weight:400; }
  #numeros .nm-sect button{ margin-left:auto; }

  /* ---- una fila por evento (caja de .ag-item, contenido propio) ---- */
  #numeros .nm-ev .top{ display:flex; align-items:flex-start; justify-content:space-between; gap:10px; }
  #numeros .nm-ev .cli{ font-weight:700; font-size:13.5px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  #numeros .nm-ev .fch{ font-size:11px; color:var(--a-mut); margin-top:3px; font-family:var(--a-mono); }
  #numeros .nm-ev .tot{ font-family:var(--a-mono); font-weight:700; font-size:14px; color:var(--a-acc); white-space:nowrap; }
  #numeros .nm-grid{ display:grid; grid-template-columns:repeat(4,1fr); gap:6px; margin-top:10px; }
  #numeros .nm-c{ background:var(--a-input); border:1px solid var(--a-line); border-radius:8px; padding:6px 8px; min-width:0; }
  #numeros .nm-c .k{ font-size:8.5px; letter-spacing:.7px; text-transform:uppercase; color:var(--a-dim); white-space:nowrap; }
  #numeros .nm-v{ font-family:var(--a-mono); font-size:12px; font-weight:700; margin-top:3px;
    font-variant-numeric:tabular-nums; color:var(--a-ink); overflow:hidden; text-overflow:ellipsis; }
  #numeros .nm-c.mario .nm-v{ color:var(--a-blue); }
  #numeros .nm-c.com .nm-v{ color:var(--a-green); }
  /* Comisión negativa = la técnica quedó por debajo del costo del stock. Se muestra
     en rojo y NO se recorta a cero: es un dato mal cargado y hay que verlo. */
  #numeros .nm-c.com.neg .nm-v{ color:var(--a-red); }
  /* El KPI grande sigue la misma regla que la fila: negativo = rojo. */
  #numeros .dkpi.vos.neg .v{ color:var(--a-red); }
  @media (max-width:420px){ #numeros .nm-grid{ grid-template-columns:repeat(2,1fr); } }

  /* ---- otros ingresos ---- */
  /* La caja del form es la misma tarjeta que .ag-item; adentro manda .fld, que ya
     trae su propio margin-bottom — por eso el form no pone gap ni flex. */
  #numeros .nm-form{ background:var(--a-card); border:1px solid var(--a-line); border-radius:10px;
    padding:13px 14px 4px; margin-bottom:12px; }
  #numeros .nm-form .a{ display:flex; gap:8px; padding-bottom:9px; }
  #numeros .nm-oi{ display:flex; align-items:center; gap:10px; background:var(--a-card);
    border:1px solid var(--a-line); border-radius:9px; padding:9px 12px; margin-bottom:7px; }
  #numeros .nm-oi .f{ font-family:var(--a-mono); font-size:10.5px; color:var(--a-dim); flex:none; }
  #numeros .nm-oi .d{ flex:1; min-width:0; font-size:12.5px; overflow:hidden; }
  #numeros .nm-oi .d em{ display:block; font-style:normal; font-size:10.5px; color:var(--a-dim);
    margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #numeros .nm-oi .m{ font-family:var(--a-mono); font-weight:700; font-size:13px; color:var(--a-green); flex:none; }
  #numeros .nm-oi .x{ border:1px solid var(--a-line); background:transparent; color:var(--a-dim);
    width:26px; height:26px; border-radius:7px; cursor:pointer; flex:none; font-size:11px; line-height:1;
    transition:color .15s,border-color .15s; }
  :where(html.puntero) #numeros .nm-oi .x:hover{ color:var(--a-red); border-color:var(--a-red); }
  /* Segundo estado del borrado en dos toques (el confirm() nativo no aparece en la
     PWA de iPhone). Mismo look que .ag-act.danger.armed de la Agenda. */
  #numeros .nm-oi .x.armado{ width:auto; padding:0 10px; color:#fff; font-size:10.5px;
    font-weight:700; background:var(--a-red); border-color:var(--a-red); }
  /* El feedback lo muestra el cajón en su propia UI: agToast vive en z-90 y este
     overlay está en 10050, así que un toast del padre queda tapado abajo. */
  #numeros .nm-msg{ font-size:11.5px; color:var(--a-mut); min-height:16px; margin-bottom:10px; line-height:1.5; }
  #numeros .nm-msg.err{ color:var(--a-red); }
  #numeros .nm-msg.ok{ color:var(--a-green); }
  #numeros .nm-empty{ color:var(--a-dim); font-size:12px; text-align:center; padding:18px 8px; line-height:1.6; }

  /* ==================== NÚMEROS MÁS CLARO (21/09/2026) ====================
     Tobi: "toda la parte de números tiene que estar más clara". Dos bloques con su definición en una
     línea: LO QUE ENTRÓ (por fecha de cobro: una seña cuenta el mes que se cobró) y LOS EVENTOS DEL
     PERÍODO (por fecha del evento). El número que importa va grande y solo; el desglose es una barra
     y tres filas que SUMAN el total; abajo, la lista de cobros. Medidas para el iPhone 17 Pro Max:
     todo lo que se toca ≥ 40 pt, texto de lectura ≥ 12 px. Los colores salen del tema. */
  /* saldo en azul y no en verde: en el tema claro el verde y el teal de otros ingresos se confundían */
  #numeros{ --n-senia:var(--a-acc); --n-saldo:var(--a-blue); --n-oi:var(--t-teal); }
  #numeros .mt-seg.senia{ background:var(--n-senia); } #numeros .mt-seg.saldo{ background:var(--n-saldo); } #numeros .mt-seg.oi{ background:var(--n-oi); }
  /* el período: ‹ Septiembre 2026 › */
  #numeros .nm-perlab{ gap:10px; flex-wrap:wrap; }
  #numeros .nm-nav{ display:flex; align-items:center; gap:2px; min-width:0; }
  #numeros .nm-nav .lab{ font-size:17px; font-weight:700; letter-spacing:-.01em; padding:0 4px; white-space:nowrap; }
  #numeros .nm-nav button{ min-width:44px; min-height:44px; border:0; background:transparent; color:var(--a-mut); font:inherit; font-size:24px; line-height:1; border-radius:50%; cursor:pointer; -webkit-tap-highlight-color:transparent; }
  #numeros .nm-nav button:active{ background:var(--a-card); color:var(--a-ink); }
  #numeros .nm-nav button.hoy{ font-size:13px; font-weight:600; min-width:0; padding:0 12px; min-height:34px; border-radius:999px; border:1px solid var(--a-line2); color:var(--a-ink); margin-left:6px; }
  #numeros .nm-chips .ag-tab{ font-size:13.5px; padding:10px 6px; min-height:44px; }
  /* el número que importa */
  #numeros .nm-hero{ background:color-mix(in srgb, var(--a-acc) 9%, var(--a-card)); border:1px solid color-mix(in srgb, var(--a-acc) 34%, var(--a-line)); border-radius:20px; padding:18px 18px 14px; margin-bottom:12px; }
  #numeros .nm-h-k{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; font-size:15px; font-weight:600; color:var(--a-ink); }
  #numeros .nm-h-k span{ font-size:12.5px; font-weight:400; color:var(--a-mut); }
  #numeros .nm-h-v{ font-family:var(--a-mono); font-size:38px; font-weight:700; letter-spacing:-.02em; line-height:1.05; margin:8px 0 14px; font-variant-numeric:tabular-nums; color:var(--a-ink); overflow-wrap:anywhere; }
  #numeros .nm-h-v small{ font-size:15px; font-weight:400; color:var(--a-mut); letter-spacing:0; }
  #numeros .nm-barra{ display:flex; height:10px; border-radius:999px; overflow:hidden; gap:2px; margin-bottom:12px; background:var(--a-line); }
  #numeros .nm-barra i{ display:block; min-width:4px; }
  #numeros .nm-barra i.senia, #numeros .nm-f i.senia, #numeros .nm-cobro em i.senia{ background:var(--n-senia); }
  #numeros .nm-barra i.saldo, #numeros .nm-f i.saldo, #numeros .nm-cobro em i.saldo{ background:var(--n-saldo); }
  #numeros .nm-barra i.otros, #numeros .nm-f i.otros{ background:var(--n-oi); }
  #numeros .nm-filas{ display:grid; gap:2px; }
  #numeros .nm-f{ display:grid; grid-template-columns:10px 1fr auto auto; align-items:center; gap:10px; min-height:32px; font-size:14.5px; color:var(--a-ink); }
  #numeros .nm-f i{ width:10px; height:10px; border-radius:3px; display:block; }
  #numeros .nm-f em{ font-style:normal; font-size:12.5px; color:var(--a-mut); }
  #numeros .nm-f b{ font-family:var(--a-mono); font-weight:700; font-variant-numeric:tabular-nums; min-width:96px; text-align:right; white-space:nowrap; }
  #numeros .nm-f.cero{ color:var(--a-dim); } #numeros .nm-f.cero b{ font-weight:400; color:var(--a-dim); }
  #numeros .nm-h-def{ margin:12px 0 0; padding-top:10px; border-top:1px solid color-mix(in srgb, var(--a-acc) 22%, var(--a-line)); font-size:13px; line-height:1.4; color:var(--a-mut); }
  #numeros .nm-aviso2{ background:color-mix(in srgb, var(--a-amber) 9%, var(--a-card)); border:1px solid color-mix(in srgb, var(--a-amber) 40%, var(--a-line)); border-radius:14px; padding:12px 14px; font-size:13.5px; line-height:1.45; color:var(--a-mut); margin-bottom:20px; }
  #numeros .nm-aviso2 b{ color:var(--a-ink); font-weight:600; }
  #numeros .nm-sc{ display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
  #numeros .nm-sc button{ min-height:40px; padding:0 14px; border-radius:999px; border:1px solid var(--a-line2); background:var(--a-card); color:var(--a-ink); font:inherit; font-size:13.5px; font-weight:600; cursor:pointer; }
  /* la lista de cobros */
  #numeros .nm-cobros{ display:grid; gap:8px; }
  #numeros .nm-cobro{ display:grid; grid-template-columns:48px 1fr auto; align-items:center; gap:10px; width:100%; min-height:60px; padding:10px 14px; text-align:left; background:var(--a-card); border:1px solid var(--a-line); border-radius:14px; color:var(--a-ink); font:inherit; cursor:pointer; -webkit-tap-highlight-color:transparent; transition:transform .12s ease, border-color .18s ease; }
  #numeros .nm-cobro:active{ transform:scale(.985); border-color:var(--a-acc); }
  #numeros .nm-cobro .f{ font-family:var(--a-mono); font-size:13px; color:var(--a-mut); }
  #numeros .nm-cobro .d{ min-width:0; display:grid; gap:2px; }
  #numeros .nm-cobro .d b{ font-size:15px; font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  #numeros .nm-cobro .d em{ font-style:normal; font-size:12.5px; color:var(--a-mut); display:flex; align-items:center; gap:6px; min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  #numeros .nm-cobro .d em i{ width:8px; height:8px; border-radius:2px; flex:none; display:block; }
  #numeros .nm-cobro .m{ font-family:var(--a-mono); font-size:15px; font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap; }
  /* por cobrar */
  #numeros .nm-pcs{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
  #numeros .nm-pc{ background:var(--a-card); border:1px solid var(--a-line); border-radius:14px; padding:13px 14px; min-width:0; }
  #numeros .nm-pc.alerta{ border-color:color-mix(in srgb, var(--a-red) 45%, var(--a-line)); background:color-mix(in srgb, var(--a-red) 7%, var(--a-card)); }
  #numeros .nm-pc .k{ font-size:13px; font-weight:600; color:var(--a-ink); line-height:1.25; }
  #numeros .nm-pc .v{ font-family:var(--a-mono); font-size:21px; font-weight:700; margin:7px 0 4px; font-variant-numeric:tabular-nums; overflow-wrap:anywhere; line-height:1.1; }
  #numeros .nm-pc .v small{ font-size:12px; font-weight:400; color:var(--a-mut); }
  #numeros .nm-pc .v.cero{ color:var(--a-dim); font-weight:400; }
  #numeros .nm-pc.alerta .v{ color:var(--a-red); }
  #numeros .nm-pc .n{ font-size:12px; line-height:1.4; color:var(--a-mut); }
  /* el gráfico: qué muestra */
  #numeros .nm-modo{ display:grid; grid-template-columns:1fr 1fr; gap:4px; padding:4px; border-radius:14px; background:var(--a-card); border:1px solid var(--a-line); margin-bottom:12px; }
  #numeros .nm-modo button{ min-height:40px; border:0; border-radius:10px; background:transparent; color:var(--a-mut); font:inherit; font-size:14px; font-weight:600; cursor:pointer; }
  #numeros .nm-modo button.on{ background:var(--a-bg); color:var(--a-ink); box-shadow:0 0 0 1px var(--a-line2); }
  /* títulos de sección y tarjetas de lo contratado: legibles, sin gritar en mayúsculas */
  #numeros .nm-sect{ font-size:15px; font-weight:700; letter-spacing:-.005em; text-transform:none; color:var(--a-ink); margin-bottom:12px; }
  #numeros .nm-sect .esc{ font-size:12.5px; font-weight:400; }
  #numeros .nm-kpis{ gap:10px; margin-bottom:14px; }
  #numeros .nm-kpis .dkpi:first-child{ grid-column:1/-1; }
  #numeros .dkpi{ border-radius:14px; padding:13px 14px; min-width:0; }
  #numeros .dkpi .k{ font-size:12.5px; font-weight:600; letter-spacing:0; text-transform:none; color:var(--a-ink); }
  #numeros .dkpi .v{ font-size:21px; overflow-wrap:anywhere; }
  #numeros .nm-kpis .dkpi:first-child .v{ font-size:28px; }
  #numeros .dkpi .n{ font-size:12px; }
  #numeros .nm-empty{ font-size:13.5px; line-height:1.5; }
  #numeros .nm-msg:empty{ min-height:0; margin:0; }
  .fpg-cuenta{ margin-top:4px; font-size:12.5px; color:var(--a-mut); } .fpg-cuenta b{ color:var(--a-ink); font-weight:600; }
  @media (max-width:380px){ #numeros .nm-h-v{ font-size:32px; } #numeros .nm-pcs{ grid-template-columns:1fr; } }


  #manualEq{ background:transparent; color:var(--uitext);
    border-top:1px solid var(--t-line); margin-top:14px; padding:14px 0 4px;
    font-family:'Helvetica Neue',Helvetica,Arial,sans-serif; }
  #manualEq[hidden]{ display:none !important; }
  #manualEq .me-h{ display:flex; align-items:center; gap:10px; margin-bottom:10px; flex-wrap:wrap; }
  #manualEq .me-h .t{ font-size:10px; letter-spacing:2px; text-transform:uppercase; color:var(--uimut); }
  #manualEq .me-h .c{ font-family:'Liberation Mono',Menlo,monospace; color:var(--acc); font-size:12px; }
  #manualEq textarea{ width:100%; background:var(--t-input); border:1px solid var(--uiline); color:var(--uitext);
    border-radius:8px; padding:10px 12px; font-size:13px; font-family:inherit; resize:vertical; min-height:120px; line-height:1.55; }
  #manualEq textarea:focus{ outline:none; border-color:var(--acc); }
  #manualEq .me-btns{ display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; align-items:center; }
  #manualEq .me-msg{ font-size:12px; color:var(--acc); margin-left:2px; }
  #manualEq .me-list{ display:flex; flex-direction:column; gap:12px; margin-top:14px; max-height:320px; overflow:auto; }
  #manualEq .me-grp .me-gt{ font-family:'Liberation Mono',Menlo,monospace; font-size:10px; letter-spacing:2px;
    text-transform:uppercase; color:var(--acc); margin-bottom:6px; }
  #manualEq .me-row{ display:flex; align-items:center; gap:10px; background:var(--uicard);
    border:1px solid var(--uiline); border-radius:8px; padding:7px 10px; margin-bottom:5px; }
  #manualEq .me-row .q{ font-family:'Liberation Mono',Menlo,monospace; color:var(--uimut); font-size:12px; min-width:32px; }
  #manualEq .me-row .nm{ flex:1; font-size:12.5px; line-height:1.3; }
  #manualEq .me-row .me-del{ flex:none; background:transparent; border:1px solid var(--uiline); color:var(--uimut);
    border-radius:6px; width:26px; height:26px; cursor:pointer; font-size:12px; }
  :where(html.puntero) #manualEq .me-row .me-del:hover{ border-color:#e05252; color:#e05252; }
  #manualEq .me-empty{ font-size:12px; color:var(--uimut); line-height:1.5; }
  #manualEq .me-note{ font-size:11px; color:var(--uimut); line-height:1.5; margin-top:12px; max-width:620px; }
  #manualEq .me-note b{ color:var(--uitext); }

  /* ===== IA · panel de "cargar desde texto" (presupuestador) ===== */
  /* 🔴 El atributo hidden pierde contra cualquier regla con display: los dos
     selectores pesan igual y gana el que va después. Sin esto, el panel y la
     previsualización arrancan abiertos. Es el mismo choque que ya está
     documentado para #numeros y para .warn/.info de la Quinta. */
  .ia-panel[hidden], .ia-prev[hidden]{ display:none !important; }

  .ia-box{ margin:0 0 14px; }
  .ia-open{ background:transparent; border:1px dashed var(--uiline); color:var(--acc);
    border-radius:9px; padding:9px 13px; font-size:12.5px; cursor:pointer; font-family:inherit;
    transition:border-color .15s, color .15s; }
  :where(html.puntero) .ia-open:hover{ border-color:var(--acc); }
  .ia-panel{ margin-top:10px; background:var(--uicard); border:1px solid var(--uiline);
    border-radius:10px; padding:12px; }
  /* 🔴 16px. Abajo de eso iOS hace zoom solo al enfocar y descuadra la pantalla.
     Misma regla que ya rige en .fld y en la ficha de la Quinta. */
  .ia-panel textarea{ width:100%; box-sizing:border-box; font-family:inherit;
    font-size:16px; line-height:1.45; padding:10px; border-radius:8px; resize:vertical;
    background:var(--uibg,var(--t-input)); border:1px solid var(--uiline); color:var(--uitext); }
  .ia-row{ display:flex; align-items:center; gap:9px; margin-top:9px; flex-wrap:wrap; }
  .ia-go{ background:var(--acc); border:0; color:#fff; border-radius:8px; padding:9px 15px;
    font-size:12.5px; font-weight:600; cursor:pointer; font-family:inherit; }
  .ia-go[disabled]{ opacity:.5; cursor:default; }
  .ia-x{ background:transparent; border:1px solid var(--uiline); color:var(--uimut);
    border-radius:8px; padding:9px 13px; font-size:12.5px; cursor:pointer; font-family:inherit; }
  .ia-msg{ font-size:11.5px; color:var(--uimut); }
  .ia-msg.err{ color:#e05252; }
  .ia-prev{ margin-top:12px; border-top:1px solid var(--uiline); padding-top:11px; }
  .ia-prev .pt{ font-size:11px; letter-spacing:1.5px; text-transform:uppercase;
    color:var(--uimut); margin-bottom:9px; }
  .ia-prev .baja{ font-size:11.5px; color:var(--t-tab-eq); margin-bottom:9px; line-height:1.5; }
  .ia-f{ display:flex; align-items:flex-start; gap:9px; padding:6px 0; font-size:12.5px; line-height:1.45; }
  .ia-f input{ margin-top:3px; flex:none; width:15px; height:15px; accent-color:var(--acc); }
  .ia-f .k{ color:var(--uimut); min-width:112px; flex:none; }
  .ia-f .v{ color:var(--uitext); word-break:break-word; }
  .ia-f .old{ color:var(--uimut); text-decoration:line-through; }
  /* Separador explícito entre lo que había y lo que va a quedar. Sin él los dos textos
     salen pegados ("Salón viejoQuinta en Pilar") y el tachado solo no alcanza para
     entender que son dos valores distintos. */
  .ia-f .arr{ color:var(--uimut); margin:0 7px; }
  .ia-prev .none{ font-size:12px; color:var(--uimut); }

  /* ===================== EL ASISTENTE (#chatIA) =====================
     Es un `.agenda` — reusa el cajón entero (posición, transición, header, cuerpo
     con scroll, la paleta --a-*) igual que hace #numeros. Lo propio es el z-index,
     las burbujas, las tarjetas de acción y el pie con el compositor.

     ⚠️ z-index 10070: arriba de #dash (900), de #numeros (10050) y de #dashFicha
     (10060), porque se abre desde cualquiera de los tres y tiene que quedar
     adelante. Como está por encima de #navbar (950), el pie NO necesita reservar
     --navh — la tab bar queda tapada por el overlay. Esa es la diferencia con
     .ag-foot, que vive en un cajón de z-81 y sí pasa por debajo de la barra. */
  /* ---------------------------------------------------------------------------
     🔴 EL VELO. Tapa TODO el layout viewport, y hace falta por algo que solo se vio
     en el iPhone: con el teclado abierto el cajón se achica hasta el borde del
     teclado, pero entre ese borde y la barra de accesorios de iOS (la de ‹ › ✓ que
     el sistema pone sobre el teclado) queda una franja donde asomaba el
     presupuestador de atrás. El cajón no puede cubrirla —está fuera del viewport
     visual— así que el que la cubre es el velo, que no depende del teclado.

     En mobile es OPACO y del mismo color que el cajón: así esa franja se lee como
     parte del asistente y no como "algo que se coló". En escritorio el cajón es
     lateral y ver el fondo atenuado es lo correcto para un panel, así que ahí va
     semitransparente.

     ⚠️ Es un elemento aparte y no un pseudo de #chatIA: el cajón tiene `transform`
     para entrar y salir, y un pseudo suyo se movería con él, que es justo lo que no
     puede pasar. */
  /* 🔴 EL VELO SE PASA DE LARGO A PROPÓSITO (top/bottom en -100vh), no va a `inset:0`.
     `position:fixed` ancla al LAYOUT viewport, y al enfocar el textarea iOS SCROLLEA ese
     layout para "mostrar" el campo: ahí `visualViewport.offsetTop` se vuelve > 0 y todo
     lo fixed queda corrido hacia arriba respecto de lo que ves. El cajón sobrevive
     porque se reposiciona con --chat-top, pero el velo se quedaba clavado en el tope del
     layout y por abajo aparecía una franja sin tapar — por ahí se veía el presupuestador
     (texto e imágenes de la app) justo al empezar a escribir.
     ⚠️ Desde que el cajón cubre el layout viewport entero (ver #chatIA.vv) el velo ya no
     tiene que atajar esa franja: quedó como segunda línea, y como el fondo de las
     esquinas redondeadas. No lo saques igual — es un color plano y no cuesta nada.
     Estirarlo una pantalla para cada lado lo vuelve inmune a cualquier corrimiento, sin
     depender de medir nada ni de que el scrollTo(0,0) llegue a tiempo. Es un color plano:
     no cuesta nada. El body ya tiene el scroll bloqueado mientras el chat está abierto,
     así que el excedente no genera scroll. */
  #chatIAVelo{
    position:fixed; top:-100vh; bottom:-100vh; left:0; right:0;
    z-index:10069; background:var(--t-agenda-bg);
    opacity:0; pointer-events:none; transition:opacity .3s ease;
  }
  /* 🔴 `pointer-events:auto` cuando está puesto, también en mobile. Taparlo a la vista
     no alcanza: sin esto un toque en la franja que el cajón no cubre le llega al
     presupuestador de atrás y podés apretarle un botón sin verlo. Que CIERRE al tocarlo
     es otra cosa y solo pasa en escritorio — ver el listener del click. */
  #chatIAVelo.on{ opacity:1; pointer-events:auto; }
  @media (min-width:1024px){
    /* En escritorio el cajón es lateral: atenuar el fondo es lo correcto para un panel,
       y además deja ver qué hay detrás mientras el agente te lo modifica. */
    #chatIAVelo{ background:color-mix(in srgb, var(--t-bg) 62%, transparent); }
  }

  #chatIA{
    z-index:10070; color-scheme:var(--t-scheme);
    /* 🔴 EL ENCUADRE VA REDONDEADO, Y ESTO ES LO QUE LO HACE. El aura se recorta con
       `border-radius:inherit`, así que el radio del marco sale de acá y de ningún otro
       lado: tocá este número y el anillo, el fondo y el recorte del contenido se mueven
       juntos. Con 0 (el valor de fábrica de .agenda) el marco terminaba en cuatro
       puntas, que es justo lo que se pidió sacar.
       `overflow:hidden` NO es opcional: `.ch-foot` tiene fondo propio y `.agenda-hd` su
       borde, y sin recortar el contenedor los dos desbordan por las esquinas y las
       vuelven a cuadrar — el redondeo se vería solo en el anillo y no en el cajón.
       En mobile el cajón ocupa la pantalla entera, así que por las esquinas asoma el
       velo, que ahí es OPACO y del mismo color: se lee como una hoja redondeada, no
       como un agujero. En escritorio el velo es translúcido y queda como panel flotante. */
    /* Dos radios (05/09/2026, 11:10). ARRIBA el borde es RECTO: con la barra de estado
       `black` el viewport arranca debajo de la barra (translucent se probó dos veces y
       en iOS 26 deja 62pt muertos abajo — ver el <head>), así que ahí un radio grande
       se vería como una curva contra una franja plana: 22. ABAJO los dos vértices son
       la esquina del iPhone. La cuenta es asimétrica:
       si el radio del marco queda por DEBAJO del de la pantalla, la esquina del
       aparato se lo come; por encima, el marco es más redondo que el vidrio y siempre
       entra. Los iPhone modernos andan entre 55 y 62pt: 60 con 2px de aire cubre
       cualquiera (aire ≥ 0,293·(62−58) ≈ 1,2px). En el diagnóstico se pueden ajustar
       en el aparato. */
    --rt:22px; --rb:60px;
    /* 🔴 SI EL CONTENIDO ESTÁ DEBAJO DE LA BARRA DE ESTADO (07/09/2026), el radio de
       arriba es el del vidrio. Pasa cuando el ícono se instaló con
       `black-translucent` (iOS lee el meta al instalar): `env(safe-area-inset-top)`
       da ~59 y el cajón arranca en el borde del vidrio, donde un radio 22 queda
       cortado por la esquina redonda de la pantalla (captura de Tobi, 20:29). Con
       `black` el inset es 0 y queda 22, recto contra la barra. Es un `min()` puro CSS:
       22 + inset·10, con tope 60 — cualquier inset ≥ 4px ya da 60. */
    /* 🔴 Y CON `black` (inset 0) ARRIBA NO HAY CIERRE (07/09/2026, 20:38): iOS 26 le
       da a la web app 894 de los 956pt — o arriba del notch (translucent, sin los 62
       de abajo) o debajo de la barra (black, sin los 62 de arriba); no hay forma de
       tener las dos puntas (seis páginas de prueba el 05/09). Con black el marco
       cerraba con una línea a 62pt del vidrio y se leía "cortado". Ahora, sin inset,
       el radio de arriba es 0 y el anillo no tiene borde superior (ver `.ch-aura`):
       los dos laterales suben derecho y se meten detrás de la barra de estado. Con
       inset (translucent) es la curva 60.
       ⚠️ CORRECCIÓN (14/09/2026): con `black` iOS 26.6.1 pinta la barra en NEGRO PURO,
       no del color del cajón — la captura del iPhone mostró el escalón. El fundido
       está al final del bloque mobile del chat ("LA BARRA DE ESTADO ES NEGRA"). */
    --rt:min(60px, calc(0px + env(safe-area-inset-top, 0px) * 10));
    border-radius:var(--rt) var(--rt) var(--rb) var(--rb); overflow:hidden;
    /* La paleta "PRO", una sola vez y de acá la leen el aura y el texto: si el borde y
       el título salieran de dos listas distintas, se despegarían al primer retoque.
       🔴 El violeta del medio es el --acc de la app a propósito. Es lo que hace que el
       efecto se lea como "esta app tiene un modo PRO" y no como un gradiente pegado
       encima que podría ser de cualquier producto. */
    --pro-1:#22d3ee;  /* cian     */
    --pro-2:#3b82f6;  /* azul     */
    --pro-3:#8b6cf5;  /* violeta  = var(--acc) */
    --pro-4:#ec4899;  /* rosa     */
    --pro-5:#f59e0b;  /* naranja  */
  }
  #chatIA .agenda-body{ padding:16px calc(18px + env(safe-area-inset-right)) 8px calc(18px + env(safe-area-inset-left)); }
  /* Sin subtítulo: el encabezado es el nombre y la ✕, nada más. Apaisado, el notch
     queda de costado y el contenido lo esquiva; el anillo no (va debajo, como arriba). */
  #chatIA .agenda-hd{ padding-left:calc(18px + env(safe-area-inset-left)); padding-right:calc(14px + env(safe-area-inset-right)); }
  #chatIA .agenda-hd h2 span{ color:var(--a-dim); }

  /* ---------------------------------------------------------------------------
     EL AURA (borde animado, tipo Apple Intelligence)

     🔴 LA TÉCNICA ES ROTAR UN ELEMENTO, NO ANIMAR EL GRADIENTE. Se puede animar el
     `from` de un conic-gradient con @property, y en el escritorio se ve igual — pero
     eso REPINTA la textura en cada frame, y acá la textura es del tamaño de la
     pantalla. En Safari iOS eso traba el scroll del hilo mientras el agente piensa,
     que es exactamente el momento en que lo estás mirando. Rotando un elemento con
     `transform` el trabajo lo hace el compositor y no hay repaint ninguno.
     Si alguna vez te tienta "simplificarlo" a un conic animado: probalo en el celu
     antes, no en la compu.

     Hace falta un elemento real (`<i class="ch-aura">`) y no un pseudo del cajón,
     porque son dos capas: la que gira y la que tapa el centro para dejar solo el
     borde. Un pseudo-elemento no puede tener hijos. */
  /* ⚠️ El aura va POR ENCIMA del contenido (z-index 5), no debajo, y se recorta al
     anillo con `mask-composite`. La primera versión iba debajo con una capa opaca
     tapando el centro, y en el iPhone se vio el problema: `.ch-foot` tiene fondo
     propio y z-index 1, así que le pasaba por arriba al aura — el borde rodeaba el
     hilo pero se cortaba antes del compositor, o sea justo donde estás mirando cuando
     escribís. Con la máscara solo se pinta el anillo de 2px, el centro queda
     transparente de verdad y el marco cierra alrededor del cajón entero.
     El hijo que rota se recorta contra la máscara del padre, así que se sigue
     animando con `transform` y no hay repaint. */
  /* `border-radius:inherit` = el radio sale de #chatIA. La máscara recorta el anillo
     contra ESA forma, así que las esquinas del marco salen curvas sin una sola línea
     extra: el padding de 2px define el grosor y el radio interno se calcula solo. */
  /* 🔴 EL ANILLO SE DESPEGA DEL BORDE DE LA PANTALLA. Pegado al borde (inset:0) su
     lado de abajo es invisible en el celu por dos motivos físicos que no se arreglan
     con color: la pantalla del iPhone tiene las ESQUINAS REDONDEADAS y le recorta los
     vértices al marco, y el INDICADOR DE INICIO se apoya justo encima de esa línea.
     Con aire alrededor el marco se lee como una hoja flotante y cierra completo.
     Los números salen de la geometría, no del gusto: la esquina de la pantalla es un
     arco de ~55px, así que para que un marco de radio 20 no la toque hace falta
     ~0,293·(55−20) ≈ 10px de aire. Abajo se le suma el safe-area del indicador.
     ⚠️ El cajón NO se achica: sigue cubriendo la pantalla entera (ver #chatIA.vv). Lo
     único que entra hacia adentro es el anillo, y lo que queda entre él y el borde es
     el fondo del propio cajón — mismo color, así que se lee como el margen de la hoja.
     Con el teclado abierto el indicador de inicio está TAPADO, así que ahí el aire de
     abajo vuelve a ser el mismo que el de los costados y el marco se apoya en el
     teclado. En escritorio el cajón es un panel lateral con borde propio: aire 0. */
  /* 🔴 UN SOLO NÚMERO, IGUAL EN LOS CUATRO LADOS, Y FIJO. Antes eran dos (`--marco` y
     un `--marco-b` que le sumaba el safe-area) y el de abajo además cambiaba con el
     teclado: el marco terminaba a 44px del borde y encima se movía al escribir. Las
     dos cosas estaban mal. El aire ahora es el mínimo para que el aparato no le
     recorte los vértices, y eso se consigue con radio, no con distancia: si el radio
     del marco se parece al de la pantalla, las dos curvas son casi concéntricas y el
     aire necesario tiende a cero (la cuenta es aire ≥ 0,293·(radio_pantalla − radio_marco);
     con 55 y 44 da 3,2px).
     ⚠️ El indicador de inicio queda APOYADO sobre la línea de abajo, y es a propósito:
     es como se ve el resplandor de Siri. Lo que sí respeta el safe-area es el
     CONTENIDO del pie, que es otra cosa y va por su cuenta. */
  #chatIA{ --marco:2px; }
  /* Cerrado (translateX(102%)) no proyecta su sombra hacia adentro: en claro se veía
     como una franja gris en el borde derecho de toda la app. Mismo criterio que .agenda. */
  #chatIA:not(.open){ box-shadow:none; }
  /* ⚠️ El override de escritorio va ACÁ y no en el bloque del velo, aunque ahí quedaría
     más ordenado: `#chatIA` pesa lo mismo en los dos (1 id), así que gana el que va
     después en la hoja — puesto antes, el 10px de arriba se lo comía y en escritorio
     el anillo quedaba flotando adentro del panel. */
  @media (min-width:1024px){
    /* Acá el cajón es un panel lateral con su propio borde: no toca ninguna esquina
       redondeada de pantalla ni ningún indicador de inicio, así que el aire sobraría. */
    #chatIA{ --marco:0px; --rt:20px; --rb:20px; }
  }
  /* 🔴 EL ANILLO MIDE SIEMPRE LA PANTALLA ENTERA (05/09/2026). El cajón se achica al
     visual viewport cuando sube el teclado (ver #chatIA.vv-mide); el anillo NO: su
     alto es `--pantalla-h` (la altura del layout en reposo, que escribe TecladoChat al
     abrir) y lo que queda debajo del borde del cajón lo recorta el overflow:hidden —
     o sea que el teclado se le SUPERPONE, como el resplandor de Siri. Es lo que hace
     que la animación no "se rompa" al escribir: el rectángulo del anillo, su centro
     de giro y sus esquinas son IDÉNTICOS antes, durante y después del teclado. La
     versión anterior lo abrazaba a lo visible y en cada frame del teclado el gradiente
     se recentraba y las esquinas de abajo (radio 50) se apoyaban en el borde recto del
     teclado: eso era el salto.
     Sin `--pantalla-h` (sin JS) cae a 100%, que es el cajón entero. */
  #chatIA .ch-aura{
    position:absolute; inset:var(--marco); bottom:auto;
    /* Sin inset superior (black) el anillo arranca en el borde del área y no tiene
       línea de arriba: `top` 0 y `padding-top` 0. Con inset (translucent) es el
       marco de siempre (2px de aire y 2px de línea). Es un min() puro CSS. */
    top:min(var(--marco), env(safe-area-inset-top, 0px));
    height:calc(var(--pantalla-h, 100%) - 2 * var(--marco));
    z-index:5; pointer-events:none;
    /* Concéntrico con el cajón: el radio interno es el externo menos el aire. Con
       `border-radius:inherit` las dos curvas quedaban paralelas pero no concéntricas y
       en las esquinas se abría el espacio. */
    border-radius:calc(var(--rt) - var(--marco)) calc(var(--rt) - var(--marco))
                  calc(var(--rb) - var(--marco)) calc(var(--rb) - var(--marco));
    overflow:hidden; padding:2px; padding-top:min(2px, env(safe-area-inset-top, 0px)); box-sizing:border-box;
    -webkit-mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
            mask:linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
    -webkit-mask-composite:xor; mask-composite:exclude;
    /* 🔴 En reposo iba en .42 y era demasiado poco: los tonos oscuros de la paleta
       (azul y violeta) contra un fondo casi negro quedaban por debajo del umbral de
       "se ve algo", y el marco se leía cortado. .78 lo deja presente sin que compita
       con el hilo. Los escalones de escribiendo/pensando se subieron en la misma
       proporción para que se sigan distinguiendo entre sí. */
    opacity:.22; transition:opacity .45s ease;
    /* `paint` y no `strict`: strict incluye contain:size, que con la máscara y el
       inset:0 hace que Safari calcule el elemento como si no tuviera dimensiones. */
    contain:layout paint;
  }
  /* 🔴 Con el cajón cerrado el aura NO EXISTE. El cajón vive siempre en el DOM (se
     esconde con transform, no con display), así que sin esta regla la animación
     seguiría girando en segundo plano toda la sesión, quemando batería por algo que
     nadie está viendo. Es el mismo motivo por el que #chatIA.open va con la clase
     en BLOQUEAN del carrusel. */
  #chatIA:not(.open) .ch-aura{ display:none; }

  /* La capa que gira. Cuadrada y del tamaño de la diagonal (200% del lado mayor),
     centrada: si fuera del tamaño del cajón, al rotar dejaría las esquinas vacías. */
  /* 🔴 EL LADO SE MIDE CONTRA LA DIAGONAL, NO CONTRA EL ANCHO.
     Acá decía `width:220%` con el comentario "del tamaño de la diagonal (200% del lado
     mayor)" — pero un porcentaje en `width` se resuelve contra el ANCHO del cajón, y en
     el celu el lado mayor es el ALTO. Medido a 390×844: el cuadrado que gira quedaba en
     856px contra una diagonal de 930px, o sea 74px de menos. Al rotar, los extremos del
     anillo se salían del gradiente y quedaban transparentes: el borde de colores se
     "perdía" arriba y abajo. En escritorio no se notaba porque ahí el cajón mide 560 de
     ancho y 220% ya alcanzaba.
     `min(300%, 150vmax)` cubre los dos casos: el cajón nunca es más grande que la
     pantalla, y la diagonal de la pantalla es como mucho 1,415·vmax — o sea que 150vmax
     siempre alcanza — mientras que el 300% mantiene el cuadrado chico en escritorio, que
     es donde el cajón es angosto y un lado atado a vmax sería textura al pedo.
     El lado va en una variable porque el margen negativo tiene que ser exactamente la
     mitad, y los dos porcentajes se resuelven contra la misma base (el ancho del cajón),
     así que no se pueden desincronizar. */
  #chatIA .ch-aura{ --aura-lado:min(300%, 150vmax); }
  #chatIA .ch-aura::before{
    content:''; position:absolute; top:50%; left:50%;
    width:var(--aura-lado); aspect-ratio:1;
    margin:calc(var(--aura-lado) * -0.5) 0 0 calc(var(--aura-lado) * -0.5);
    /* 🔴 LA PALETA DA TRES VUELTAS AL CÍRCULO, NO UNA. Con una sola vuelta cada lado
       del marco muestra un tramo de ángulo, y en un celu el cajón es alto y angosto:
       el borde de ARRIBA y el de ABAJO abarcan apenas ~50° cada uno, o sea que en cada
       instante son de UN color casi plano. Cuando a ese tramo le tocaba el azul o el
       violeta —los dos tonos oscuros de la paleta— sobre un fondo casi negro el borde
       de abajo directamente desaparecía y parecía que la animación se cortaba ahí.
       Repitiendo la secuencia, esos mismos 50° contienen siempre varios colores, así
       que los cuatro lados muestran degradé todo el tiempo. Los lados largos no
       cambian: ya abarcaban 130° cada uno.
       La vuelta se alargó de 8s a 11s para compensar: con tres ciclos, el color de un
       punto cambia tres veces más rápido a igual velocidad de giro. */
    background:conic-gradient(var(--pro-1),var(--pro-2),var(--pro-3),var(--pro-4),
                              var(--pro-5),var(--pro-4),var(--pro-3),var(--pro-2),
                              var(--pro-1),var(--pro-2),var(--pro-3),var(--pro-4),
                              var(--pro-5),var(--pro-4),var(--pro-3),var(--pro-2),
                              var(--pro-1),var(--pro-2),var(--pro-3),var(--pro-4),
                              var(--pro-5),var(--pro-4),var(--pro-3),var(--pro-2),
                              var(--pro-1));
    animation:chGirar 24s linear infinite;
    will-change:transform;
  }
  @keyframes chGirar{ to{ transform:rotate(1turn); } }

  /* El "glow" del reposo. Va como box-shadow del CAJÓN y no como una capa del aura,
     porque el aura ahora es solo el anillo recortado. Estático a propósito: un
     filter:blur() sobre un subárbol que rota fuerza repaint por frame y tira abajo
     todo lo que se ganó rotando en vez de repintar. */
  /* 🔴 EL box-shadow SE DECLARA EN REPOSO, NO SOLO EN `.open`, y esto importa:
     cuando solo estaba en `.open`, al abrir el panel el navegador tenía que
     ANIMAR una sombra de 60px de blur sobre un elemento del tamaño de la pantalla
     (de `none` a su valor) al mismo tiempo que el transform lateral. Declarado
     también en reposo, la sombra ya está puesta y en la apertura no cambia: lo
     único que se anima es el `transform`, que es lo pedido.
     ⚠️ Y la transición NO se redeclara acá. Antes esta regla traía su propia
     shorthand con la curva vieja `(.4,0,.18,1)` y, como `#chatIA.open` pesa más
     que `#chatIA`, le ganaba a la curva del panel: el cajón entraba con un easing
     y el resto de la app con otro. La transición vive en UN solo lugar. */
  #chatIA.open{ box-shadow:-30px 0 60px -30px rgba(0,0,0,.8), inset 0 0 40px -22px color-mix(in srgb, var(--t-panel-accent) 65%, transparent); }
  #chatIA.escribiendo{ box-shadow:-30px 0 60px -30px rgba(0,0,0,.8), inset 0 0 46px -20px color-mix(in srgb, var(--t-panel-accent) 78%, transparent); }
  #chatIA.pensando{ box-shadow:-30px 0 60px -30px rgba(0,0,0,.8), inset 0 0 50px -18px color-mix(in srgb, var(--t-panel-accent) 85%, transparent); }

  /* 🔴 CAMBIAR `animation-duration` EN CALIENTE ES UN SALTO, Y ACÁ NO SE PUEDE PAGAR.
     Una animación en curso conserva su tiempo pero recalcula el progreso contra la
     duración nueva: si iba por 5s de 11s (45%) y la duración pasa a 7s, salta a 71%.
     El anillo pega un tirón.
     Eso ya estaba escrito dos líneas más abajo para `pensando`, con la excusa de que
     "dura un turno" — cierta ahí, FALSA acá: `escribiendo` se prende cada vez que
     tocás el campo, o sea decenas de veces por conversación, y encima en el único
     momento en que no hay nada más en pantalla que lo disimule (justo cuando sube el
     teclado y el marco es lo único que se mueve). El tirón quedaba desnudo.
     Por eso al escribir el anillo ahora SOLO cambia de opacidad, que sí interpola por
     el compositor y es lo que la transición de `.ch-aura` ya sabe hacer. El estado se
     sigue leyendo igual: el reposo está en .78 y esto lo lleva a 1.
     ⚠️ Si algún día querés que además acelere, no toques la duración: hace falta una
     SEGUNDA capa que rote y aparezca por opacidad, y eso es otra textura del tamaño de
     la pantalla girando — justo lo que se evitó al no animar el gradiente. */
  #chatIA.escribiendo .ch-aura{ opacity:.55; }

  /* Pensando: más intenso y más rápido. Acá el salto de velocidad SÍ se paga, y por
     eso se queda: pasa una vez por turno y llega junto con tu mensaje apareciendo en
     el hilo y los tres puntitos, así que está tapado por el resto del movimiento. */
  #chatIA.pensando .ch-aura{ opacity:1; }
  /* ⚠️ `pensando` YA NO ACELERA LA ROTACIÓN. Cambiar `animation-duration` en
     caliente hace que el navegador recalcule el progreso contra la duración
     nueva: si iba por 5s de 13s (38%) y pasa a 3.5s, salta a 100% — un tirón
     visible. El estado se distingue solo por opacidad, que sí interpola por el
     compositor. La rotación tiene que ser continua, sin saltos, siempre. */
  #chatIA.pensando .ch-aura::after{ box-shadow:inset 0 0 30px -4px rgba(154,112,255,.7); }

  /* El contenido queda debajo del anillo (z-index 5), que es transparente en el centro
     y no tapa nada. El z-index:1 se mantiene para que el pie siga por encima del hilo. */
  #chatIA .agenda-hd, #chatIA .agenda-body, #chatIA .ch-foot{ position:relative; z-index:1; }

  /* ---------------------------------------------------------------------------
     "AGENTE PRO" — el gradiente fluyendo en el texto.

     Acá SÍ se anima el background-position, al revés que en el aura, y no es una
     contradicción: son diez caracteres, o sea un repaint de unos pocos miles de
     píxeles por frame. El aura pinta la pantalla entera; esto pinta una palabra. */
  .agente-pro{
    /* Stack literal y no var(--a-mono): los botones del Panel y de la barra viven
       FUERA de #chatIA, donde esa variable resuelve a otra cosa según el ancestro, y
       los tres "Agente Pro" de la app tienen que verse idénticos. */
    font-family:'SFMono-Regular',Menlo,'Liberation Mono','DejaVu Sans Mono',monospace;
    font-weight:700; letter-spacing:3px; text-transform:uppercase;
    background:linear-gradient(90deg,var(--pro-1),var(--pro-2),var(--pro-3),var(--pro-4),
                               var(--pro-5),var(--pro-4),var(--pro-3),var(--pro-2),var(--pro-1));
    background-size:200% 100%;
    -webkit-background-clip:text; background-clip:text;
    -webkit-text-fill-color:transparent; color:transparent;
    animation:chFluir 14s linear infinite;
  }
  @keyframes chFluir{ to{ background-position:-200% 0; } }
  /* 🔴 EL ORBE DEL AGENTE PRO (14/09/2026, tercera vuelta). Tobi pidió sacar el logo y
     dejar "la animación de colores que había atrás de Agente Pro, solo esos colores,
     siempre moviéndose". Es la misma técnica del aura del cajón: un conic-gradient de
     la paleta PRO en un pseudo que GIRA con transform (compositor, sin repintar),
     recortado a un círculo, con un poco de desenfoque para que se lea como un
     remolino y no como una rueda. Reemplaza al nombre y al logo en los tres lugares
     (título del cajón, botón del Panel, botón de la barra) y va adentro de la burbuja.
     La paleta la trae de .agente-pro (mismas --pro-*). Con reducción de movimiento
     queda quieto: sigue siendo el remolino, no gira. */
  .agente-orbe{ position:relative; display:inline-block; width:24px; height:24px; border-radius:50%; overflow:hidden; flex:none;
    vertical-align:middle; isolation:isolate; box-shadow:0 0 0 1px color-mix(in srgb, var(--pro-3) 35%, transparent); }
  .agente-orbe::before{ content:''; position:absolute; inset:-40%; border-radius:50%;
    background:conic-gradient(from 0deg, var(--pro-1), var(--pro-2), var(--pro-3), var(--pro-4), var(--pro-5), var(--pro-4), var(--pro-3), var(--pro-2), var(--pro-1));
    filter:blur(3px); animation:orbeGira 5s linear infinite; will-change:transform; }
  .agente-orbe::after{ content:''; position:absolute; inset:0; border-radius:50%;
    background:radial-gradient(circle at 32% 30%, color-mix(in srgb, white 45%, transparent), transparent 58%); }
  @keyframes orbeGira{ to{ transform:rotate(360deg); } }
  #chatIA .agenda-hd h2{ display:flex; align-items:center; min-height:34px; }
  #chatIA .agenda-hd h2 .agente-orbe{ width:30px; height:30px; }

  /* ⚠️ El título del cajón es un <span> adentro del <h2>, y ahí ya vive
     `.agenda-hd h2 span` (0,0,1,2) — la regla del SUBTÍTULO, con font-size:11px,
     weight 400 y letter-spacing .04em. Le gana a `.agente-pro` (0,0,1,0) por
     especificidad, así que sin esta regla el nombre sale con el cuerpo del subtítulo:
     se ve chiquito y sin tracking, que es exactamente lo contrario de lo que se busca.
     Se sube la especificidad en vez de renombrar la clase para no tocar el header de
     la Agenda, que es compartido. */
  #chatIA .agenda-hd h2 span.agente-pro{
    display:block; font-size:15px; font-weight:700;
    letter-spacing:3px; margin:0 0 2px;
  }
  /* Sin background-clip:text el texto quedaría INVISIBLE (color:transparent sobre un
     fondo que no se recorta). El fallback no es cosmético: es que se lea. */
  @supports not ((-webkit-background-clip:text) or (background-clip:text)){
    .agente-pro{ background:none; color:var(--acc); -webkit-text-fill-color:currentColor; }
  }
  /* Los botones que ABREN el agente. La paleta la definen ellos porque viven fuera de
     #chatIA (el Panel, la barra del presupuestador), y las custom properties de arriba
     están declaradas en el cajón. */
  .agente-pro, .ia-chispa, .agente-orbe{
    --pro-1:#22d3ee; --pro-2:#3b82f6; --pro-3:#8b6cf5; --pro-4:#ec4899; --pro-5:#f59e0b;
  }
  /* La chispa que reemplazó al 🧠 en los botones de acción. Mismo gradiente que el
     título, más chica: son acciones del agente, no su nombre. */
  .ia-chispa{
    background:linear-gradient(90deg,var(--pro-1),var(--pro-3),var(--pro-4));
    background-size:200% 100%;
    -webkit-background-clip:text; background-clip:text;
    -webkit-text-fill-color:transparent; color:transparent;
    animation:chFluir 14s linear infinite; font-style:normal;
  }
  @supports not ((-webkit-background-clip:text) or (background-clip:text)){
    .ia-chispa{ background:none; color:var(--acc); -webkit-text-fill-color:currentColor; }
  }

  /* El proyecto ya respeta esto en .ptr y en .ch-pensando. Acá importa más: son dos
     animaciones infinitas y una ocupa toda la pantalla. */
  @media (prefers-reduced-motion:reduce){
    #chatIA .ch-aura::before, .agente-pro, .ia-chispa, .agente-orbe::before{ animation:none; }
    /* 🔴 SIN MOVIMIENTO, PERO CON BORDE ENTERO. El anillo queda ESTÁTICO (el conic
       no gira) y con la MISMA opacidad que en reposo: en .5 los tramos azul y
       violeta sobre fondo casi negro se perdían y el marco se leía cortado, que es
       justo lo que la reducción de movimiento no tiene por qué pagar. */
    #chatIA .ch-aura{ opacity:.22; }
  }

  #chatIA .ch-hilo{ display:flex; flex-direction:column; gap:14px; }

  /* Burbujas. Lo de Tobi a la derecha con el violeta de la app; lo del asistente a
     la izquierda sobre la tarjeta, que es lo que más se lee. */
  #chatIA .ch-msg{ max-width:88%; font-size:13px; line-height:1.6; white-space:pre-wrap;
    word-break:break-word; border-radius:12px; padding:10px 13px; }
  #chatIA .ch-msg.yo{ align-self:flex-end; background:var(--a-acc); color:#fff;
    border-bottom-right-radius:4px; }
  #chatIA .ch-msg.ia{ align-self:flex-start; background:var(--a-card);
    border:1px solid var(--a-line); color:var(--a-ink); border-bottom-left-radius:4px; }
  /* Streaming: el cursor mientras el texto sigue llegando. */
  #chatIA .ch-msg.ia.stream > :last-child::after{ content:''; display:inline-block; width:7px; height:.95em; margin-left:2px; vertical-align:-.15em; border-radius:2px;
    background:var(--a-acc); animation:chCursor .9s steps(2, jump-none) infinite; }
  #chatIA .ch-msg.ia.stream:empty::after{ content:''; display:inline-block; width:7px; height:.95em; border-radius:2px; background:var(--a-acc); animation:chCursor .9s steps(2, jump-none) infinite; }
  @keyframes chCursor{ from{ opacity:1; } to{ opacity:0; } }
  #chatIA .ch-estado.plegado .paso:not(:last-child){ display:none; }
  @media (prefers-reduced-motion:reduce){ #chatIA .ch-msg.ia.stream > :last-child::after, #chatIA .ch-msg.ia.stream:empty::after{ animation:none; } }
  #chatIA .ch-msg.err{ align-self:stretch; max-width:none; background:transparent;
    border:1px solid var(--a-red); color:var(--a-red); font-size:12px; }

  /* Qué herramientas usó. Va chiquito y apagado: no es la respuesta, es la
     trazabilidad de cómo llegó — poder ver que miró el catálogo de verdad. */
  #chatIA .ch-tools{ align-self:flex-start; font-size:10.5px; color:var(--a-dim);
    letter-spacing:.03em; margin-top:-8px; }

  /* Tarjeta de acción. El borde dice el estado: violeta = hecha sola,
     ámbar = esperando que Tobi confirme, verde = confirmada, rojo = falló. */
  #chatIA .ch-acc{ align-self:stretch; background:var(--a-card); border:1px solid var(--a-line);
    border-left:3px solid var(--a-acc); border-radius:10px; padding:11px 13px; }
  #chatIA .ch-acc.pide{ border-left-color:var(--a-amber); }
  #chatIA .ch-acc.hecha{ border-left-color:var(--a-green); }
  #chatIA .ch-acc.fallo{ border-left-color:var(--a-red); }
  #chatIA .ch-acc .t{ font-size:12.5px; font-weight:600; color:var(--a-ink); line-height:1.45; }
  #chatIA .ch-acc .est{ font-size:11px; color:var(--a-dim); margin-top:4px; }
  #chatIA .ch-acc.hecha .est{ color:var(--a-green); }
  #chatIA .ch-acc.fallo .est{ color:var(--a-red); }
  /* Los dos estados honestos entre "hecha" y "fallo": guardada en este dispositivo y
     sin subir (ámbar), y rechazada por la base (rojo, pero no es un error de la app). */
  #chatIA .ch-acc.pendiente{ border-left-color:var(--a-amber); }
  #chatIA .ch-acc.pendiente .est{ color:var(--a-amber); }
  #chatIA .ch-acc.conflicto{ border-left-color:var(--a-red); }
  #chatIA .ch-acc.conflicto .est{ color:var(--a-red); }
  #chatIA .ch-acc.descartada{ opacity:.6; }
  #chatIA .ch-acc .det{ margin-top:9px; font-size:11.5px; color:var(--a-mut); line-height:1.6; }
  #chatIA .ch-acc .det b{ color:var(--a-ink); font-weight:600; }
  #chatIA .ch-acc .det .warn{ color:var(--a-amber); }
  #chatIA .ch-acc ul{ margin:6px 0 0; padding-left:16px; }
  #chatIA .ch-acc li{ margin:3px 0; }
  #chatIA .ch-acc .mono{ font-family:var(--a-mono); color:var(--a-ink); }
  #chatIA .ch-acc .btns{ display:flex; gap:8px; margin-top:11px; flex-wrap:wrap; }
  #chatIA .ch-acc .si{ background:var(--a-acc); border:0; color:#fff; border-radius:8px;
    padding:8px 15px; font:inherit; font-size:12.5px; font-weight:600; cursor:pointer; }
  #chatIA .ch-acc .no{ background:transparent; border:1px solid var(--a-line);
    color:var(--a-mut); border-radius:8px; padding:8px 13px; font:inherit; font-size:12.5px; cursor:pointer; }
  #chatIA .ch-acc .si[disabled], #chatIA .ch-acc .no[disabled]{ opacity:.45; cursor:default; }

  /* Pie: chips de arranque + compositor. Fuera del body para que no scrollee con
     la conversación. */
  /* El respiro de abajo del CONTENIDO va por su cuenta y no atado al marco: son dos
     cosas distintas. El marco es decoración pegada al vidrio y el indicador de inicio
     se le apoya encima sin problema; el contenido, en cambio, no puede quedar abajo
     del indicador. Por eso acá sí manda `env(safe-area-inset-bottom)`.
     Con el teclado abierto el indicador está TAPADO, así que reservarle su franja deja
     un hueco muerto entre el textarea y el teclado — y en una pantalla ya reducida a la
     mitad, ese hueco se nota. La clase la pone y la saca el módulo del teclado. */
  #chatIA .ch-foot{ flex-shrink:0; border-top:1px solid var(--a-line); background:var(--a-bg);
    padding:11px calc(18px + env(safe-area-inset-right)) calc(12px + var(--sab-chat, env(safe-area-inset-bottom))) calc(18px + env(safe-area-inset-left)); }
  #chatIA.teclado .ch-foot{ padding-bottom:8px; padding-top:8px; }
  /* Con el teclado arriba, el campo tiene que ser lo ÚLTIMO antes del teclado: la
     fila de gastos y "Empezar de cero" se va mientras se escribe (vuelve al bajar el
     teclado, tocando el fondo). Pedido del 05/09/2026. */
  #chatIA.teclado .ch-bar{ display:none; }
  /* Con el teclado arriba el cajón termina APOYADO en el teclado, no en la esquina del
     vidrio: ahí un radio de 60 se veía como una hoja redondeada flotando sobre las
     teclas (medido en el simulador del iPhone 17 Pro Max, 05/09/2026). Abajo va recto;
     arriba conserva su curva. El anillo no cambia (su alto es la pantalla y el cajón lo
     recorta), así que solo se enderezan las esquinas del cuerpo del cajón. */
  #chatIA.teclado{ border-bottom-left-radius:0; border-bottom-right-radius:0; }

    /* =========================================================================
     EL CAJÓN Y EL TECLADO DE iOS.

     El problema de fondo: `.agenda` es `position:fixed; top:0; bottom:0`, o sea
     que se ancla al LAYOUT viewport. Cuando iOS abre el teclado el layout NO
     cambia: lo que se achica es el VISUAL viewport. Sin hacer nada, el pie con
     el textarea queda debajo del teclado.

     ⚠️ Las tres pasadas anteriores están resumidas en CLAUDE.md. Lo que sigue es
     la cuarta, que es la que separa los dos movimientos; los comentarios de las
     versiones viejas se borraron porque describían un mecanismo que ya no existe
     y contradecían al código de abajo.
  ========================================================================= */
  /* =========================================================================
     HISTORIA CORTA (la larga está en CLAUDE.md): la cuarta pasada (27/08) sacó el
     `translateY(--chat-off)` del panel y movía SOLO el pie con `--kb`; la quinta dejó
     el anillo fijo; la sexta fijó el body para que el documento no scrollee. Las tres
     asumían que el recorte del teclado era `innerHeight − vv.height − offsetTop`, y
     en el iPhone real ese número es CERO cuando iOS panea por el alto del teclado.
     La séptima (04/09/2026), abajo, dimensiona el cajón con el visual viewport.
     Lo que sigue valiendo de las anteriores: `#chatIA` mueve SOLO lateral (nunca un
     translateY), el body va `position:fixed` mientras el chat está abierto, y no
     hay transición CSS mientras el teclado viaja.
  ========================================================================= */

  /* 🔴 EL TRANSFORM DEL PANEL: SOLO LATERAL, Y EN UNA SOLA REGLA.
     `translate3d` y no `translateX` para forzar capa propia en el compositor.
     `.agenda` trae `translateX(102%)` y `.agenda.open` `translateX(0)`; estas dos
     los pisan con la misma especificidad de id, así que el cajón entra y sale por
     el costado y nada más. */
  #chatIA{ transform:translate3d(100%,0,0);
           /* La sombra en reposo es la MISMA que en `.open`: así la apertura no la
              anima. La transición de `box-shadow` queda solo para los cambios de
              estado del glow (reposo → escribiendo → pensando). */
           box-shadow:-30px 0 60px -30px rgba(0,0,0,.8), inset 0 0 40px -22px color-mix(in srgb, var(--t-panel-accent) 65%, transparent);
           /* 🔴 `height` transiciona SOLO cuando `.kb-anim` le da duración (octava
              pasada, 07/09/2026): en reposo, con paneo de respaldo y al rotar es 0s,
              o sea instantáneo. `top` no transiciona nunca. */
           --kb-dur:0s; --kb-curva:linear;
           transition:transform .32s cubic-bezier(.32,.72,0,1), box-shadow .45s ease, height var(--kb-dur) var(--kb-curva); }
  /* 🔴 LA CURVA DEL TECLADO DE iOS, MEDIDA (07/09/2026): tres grabaciones a 60 fps en
     el simulador del iPhone 17 Pro Max, ajuste por mínimos cuadrados, error medio 3%.
     Sube: 280ms cubic-bezier(.25,.5,.2,1) (arranque rápido, cola larga). Baja: el
     teclado se esconde en ~150ms, casi lineal. `--kb-anim-sube/baja` los escribe
     TecladoChat desde localStorage.pp_kb_anim para ajustarlos en el aparato. */
  #chatIA.kb-anim{ --kb-dur:280ms; --kb-curva:cubic-bezier(.25,.5,.2,1); transition:transform .32s cubic-bezier(.32,.72,0,1), box-shadow .45s ease, height var(--kb-anim-sube, var(--kb-dur) var(--kb-curva)); }
  #chatIA.kb-anim.kb-baja{ --kb-dur:150ms; --kb-curva:cubic-bezier(.3,.3,.2,1); transition:transform .32s cubic-bezier(.32,.72,0,1), box-shadow .45s ease, height var(--kb-anim-baja, var(--kb-dur) var(--kb-curva)); }
  #chatIA.open{ transform:translate3d(0,0,0); }

  /* 🔴 SÉPTIMA PASADA (04/09/2026): EL CAJÓN ES EL VISUAL VIEWPORT.
     El video del iPhone 17 Pro Max mostró el panel entero corrido hacia arriba con el
     teclado abierto: iOS panea el visual viewport por el alto del teclado (offsetTop =
     407) y un `fixed` anclado al layout viewport se va con el paneo. La cuenta
     "innerHeight − vv.height − offsetTop" daba 0 en ese caso, así que ningún `--kb`
     compensaba nada.
     Ahora el JS escribe `--vv-top` (= offsetTop) y `--vv-h` (= vv.height) por frame
     mientras el teclado viaja, y el cajón se dimensiona con eso: ES lo visible. El
     encabezado queda arriba de lo visible, el pie apoyado sobre el teclado sin
     transform, el hilo ocupa lo que hay (flex:1) y conserva scroll, y el anillo
     (inset:--marco) abraza lo visible sin leer nada del teclado.
     `.vv` = el módulo corre; `.vv-mide` = ya escribió las dos variables. Sin `.vv-mide`
     mandan el top:0/bottom:0 de siempre (pantalla entera). Sin teclado las variables
     valen 0 / innerHeight: idéntico a la pantalla entera.
     ⚠️ Nada de `100dvh`: en la PWA instalada resuelve más bajo que la pantalla.
     ⚠️ `top`/`height` NO llevan transición en ningún estado: mientras el teclado se
     mueve cada frame escribe el valor exacto del sistema (sin doble easing). */
  #chatIA.vv{ top:0; bottom:0; height:auto; }
  #chatIA.vv-mide{ top:var(--vv-top, 0px); height:var(--vv-h); bottom:auto; }

  /* 🔴 EL PIE NO SE MUEVE CON transform: está apoyado en el borde de abajo del
     cajón, que ya es el borde visible. (La cuarta pasada lo trasladaba con `--kb`,
     que en el iPhone daba 0 justo cuando hacía falta.) */

  /* El hilo ocupa lo que hay entre encabezado y pie (flex:1 de .agenda-body) y
     conserva su scroll interno. Ya no gana recorrido con `--kb`: la caja se achica
     con el cajón y el último mensaje se sube con alFinal(). */

  /* 🔴🔴 EL ANILLO NO LEE EL TECLADO. NUNCA. DECISIÓN DEFINITIVA (27/08/2026).

     Acá estaba el bug de la grabación. La pasada anterior hacía que el borde de
     abajo del anillo siguiera al área visible:

         #chatIA .ch-aura{ bottom: calc(var(--marco) + var(--kb)); }
         #chatIA.teclado .ch-aura{ border-radius: ... }

     Y eso ES, literalmente, lo que se veía y estaba mal: el marco **reducía su
     altura**, aparecía **una línea horizontal de cierre justo encima del teclado**
     y el conjunto se leía como si Agente Pro se hubiera convertido en una ventana
     chica flotando sobre el dashboard.

     LA REGLA AHORA, y no tiene excepciones: **el marco mide siempre la pantalla
     entera y el teclado se le superpone.** Que la parte de abajo del marco quede
     físicamente detrás del teclado es lo correcto y lo buscado. La geometría del
     anillo es IDÉNTICA antes, durante y después de usar el teclado.

     ⚠️ Por eso acá abajo NO HAY una sola regla de `.ch-aura`: su geometría vive en
     un solo lugar, la declaración de más arriba (`inset:var(--marco)` con su radio
     fijo), y nada la toca. Lo único que puede cambiarle un estado es la OPACIDAD.
     🔴 Si volvés a ver un `--kb`, un `bottom` o un `border-radius` sobre
     `.ch-aura`, es este bug de vuelta. */

  /* ---- transiciones y teclado (octava pasada, 07/09/2026) ----
     Antes había dos escuelas: seguir el viewport por frame sin transición (4ª–7ª) o
     transicionar el pie mientras iOS lo animaba (doble easing). Medido en el
     simulador, iOS informa la altura final casi de golpe (uno o dos eventos) y el
     teclado tarda ~300 ms en subir: seguir "por frame" era un salto. Ahora hay UNA
     animación, la del cajón (`.kb-anim`, arriba), con la curva del teclado. El pie
     no tiene transición propia: se apoya en el borde del cajón.
     ⚠️ El aura solo transiciona OPACIDAD (bottom y border-radius fijos). */

  /* Con el teclado abierto el indicador de inicio está tapado, así que ese
     safe-area es un hueco muerto en una pantalla ya reducida a la mitad. */

  @media (prefers-reduced-motion:reduce){
    #chatIA, #chatIA.kb-anim, #chatIA.kb-anim.kb-baja{ transition:none; }
    #chatIA.anim .ch-foot, #chatIA.anim .ch-aura{ transition:opacity .45s ease; }
  }

  /* Feedback al tocar el campo: el input toma el color de la identidad PRO. Es la
     "animación al escribir" que se pidió, y de paso confirma que el foco entró —
     en el celu, con el teclado tapando media pantalla, eso no es obvio. */
  #chatIA textarea:focus{
    outline:none; border-color:var(--pro-2);
    box-shadow:0 0 0 1px var(--pro-2), 0 0 18px -6px var(--pro-3);
    transition:border-color .2s ease, box-shadow .2s ease;
  }
  #chatIA .ch-row{ display:flex; gap:8px; align-items:flex-end; }
  /* 🔴 16px. Abajo de eso iOS hace zoom al enfocar y, como el cajón es fixed, la
     pantalla queda descuadrada encima del contenido. Misma regla que .fld. */
  #chatIA textarea{ flex:1; min-width:0; box-sizing:border-box; font-family:inherit;
    font-size:16px; line-height:1.45; padding:10px 12px; border-radius:10px; resize:none;
    max-height:120px; background:var(--a-input); border:1px solid var(--a-line); color:var(--a-ink); }
  #chatIA .ch-send{ flex:none; background:var(--a-acc); border:0; color:#fff; border-radius:10px;
    width:44px; height:42px; font-size:16px; line-height:1; cursor:pointer; }
  #chatIA .ch-send[disabled]{ opacity:.45; cursor:default; }
  #chatIA .ch-bar{ display:flex; align-items:center; gap:10px; margin-top:6px; flex-wrap:wrap; opacity:.72; }
  #chatIA .ch-bar label{ display:flex; align-items:center; gap:7px; font-size:11px;
    color:var(--a-dim); cursor:pointer; }
  #chatIA .ch-bar input[type=checkbox]{ width:14px; height:14px; accent-color:var(--a-acc); }
  #chatIA .ch-bar .limpiar{ margin-left:auto; background:transparent; border:0;
    color:var(--a-dim); font:inherit; font-size:11px; cursor:pointer; text-decoration:underline; }
  /* El "pensando" con los tres puntitos. Es la única señal de que sigue trabajando:
     un turno con varias herramientas puede tardar 15 segundos. */
  #chatIA .ch-pensando{ align-self:flex-start; display:flex; gap:4px; padding:12px 13px; }
  #chatIA .ch-pensando i{ width:6px; height:6px; border-radius:50%; background:var(--a-dim);
    animation:chPulso 1.2s infinite ease-in-out; }
  #chatIA .ch-pensando i:nth-child(2){ animation-delay:.15s; }
  #chatIA .ch-pensando i:nth-child(3){ animation-delay:.3s; }
  @keyframes chPulso{ 0%,80%,100%{ opacity:.25; transform:translateY(0); }
                      40%{ opacity:1; transform:translateY(-3px); } }
  @media (prefers-reduced-motion:reduce){ #chatIA .ch-pensando i{ animation:none; opacity:.6; } }

  /* ==================== EL CHAT REDISEÑADO (13/09/2026) ====================
     Documento "Rediseño del Agente Pro". Lo que sigue PISA las reglas de arriba con
     la misma especificidad (van después): el asistente sin burbuja y a ancho de
     lectura, el usuario en burbuja compacta, tarjetas de una sola familia, el
     inicio inteligente, el estado del turno en pasos, el composer en cápsula con
     "+" y ■, conversaciones, y la ficha encima del chat. El marco PRO queda como
     acento: apagado en reposo, encendido mientras trabaja; en claro, apagado.
     🔴 Las reglas del teclado (#chatIA.vv, .vv-mide, .kb-anim, .teclado .ch-foot,
     .teclado .ch-bar) NO se tocan: viven arriba y son las medidas en el iPhone. */
  #chatIA{ --ch-r:12px; --ch-lect:640px; }
  #chatIA .agenda-hd{ gap:10px; }
  #chatIA .agenda-hd h2{ flex:none; }
  #chatIA .agenda-hd h2 span.agente-pro{ font-size:12.5px; letter-spacing:.06em; }
  #chatIA .ch-ctx{ flex:1; min-width:0; font-size:12px; color:var(--a-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
    padding:3px 9px; border:1px solid var(--a-line); border-radius:999px; background:var(--a-card); }
  #chatIA .ch-ctx[hidden]{ display:none; }
  #chatIA .ch-hbs{ display:flex; align-items:center; gap:2px; margin-left:auto; flex:none; }
  #chatIA .ch-hb{ min-width:40px; min-height:40px; border:0; background:transparent; color:var(--a-mut); font:inherit; font-size:18px;
    border-radius:10px; cursor:pointer; display:grid; place-items:center; }
  #chatIA .ch-hb[aria-expanded="true"]{ background:var(--a-card); color:var(--a-ink); }
  #chatIA .ch-hb.dim{ font-size:14px; opacity:.6; }
  #chatIA .agenda-body{ padding-top:12px; }
  #chatIA .ch-hilo{ gap:12px; max-width:var(--ch-lect); margin:0 auto; width:100%; }

  /* Mensajes. El tuyo: burbuja compacta a la derecha. El del asistente: SIN burbuja,
     a ancho completo, 15px: es texto para leer, no un mensaje de WhatsApp. */
  #chatIA .ch-msg{ position:relative; white-space:normal; }
  #chatIA .ch-msg.yo{ white-space:pre-wrap; max-width:85%; font-size:14px; line-height:1.5; padding:9px 13px;
    border-radius:16px 16px 4px 16px; background:var(--a-acc); color:#fff; }
  #chatIA .ch-msg.yo.fallo{ background:color-mix(in srgb, var(--a-red) 22%, var(--a-card)); color:var(--a-ink); border:1px solid color-mix(in srgb, var(--a-red) 50%, transparent); }
  #chatIA .ch-msg.ia{ align-self:stretch; max-width:none; background:transparent; border:0; padding:2px 2px;
    font-size:15px; line-height:1.55; color:var(--a-ink); border-radius:0; }
  #chatIA .ch-msg.ia p{ margin:0 0 9px; }
  #chatIA .ch-msg.ia p:last-of-type{ margin-bottom:0; }
  #chatIA .ch-msg.ia ul, #chatIA .ch-msg.ia ol{ margin:2px 0 9px; padding-left:20px; }
  #chatIA .ch-msg.ia li{ margin:3px 0; }
  #chatIA .ch-msg.ia code{ font-family:var(--a-mono); font-size:.9em; background:var(--a-card); border:1px solid var(--a-line); border-radius:5px; padding:0 5px; }
  #chatIA .ch-msg.ia b{ font-weight:600; }
  #chatIA .ch-msg.err{ align-self:stretch; max-width:none; white-space:pre-wrap; background:color-mix(in srgb, var(--a-red) 10%, transparent);
    border:1px solid color-mix(in srgb, var(--a-red) 45%, transparent); color:var(--a-ink); font-size:13px; padding:9px 12px; border-radius:var(--ch-r); }
  /* Acciones por mensaje: al tocar el mensaje (en escritorio, al pasar). */
  #chatIA .ch-acts{ display:none; gap:12px; margin-top:6px; font-family:var(--a-mono); font-size:11px; letter-spacing:.02em; }
  #chatIA .ch-msg.yo .ch-acts{ justify-content:flex-end; }
  #chatIA .ch-msg.acts-on .ch-acts{ display:flex; }
  #chatIA .ch-acts button{ background:none; border:0; padding:6px 0; color:var(--a-dim); font:inherit; cursor:pointer; min-height:28px; }
  #chatIA .ch-msg.yo .ch-acts button{ color:#fff; opacity:.8; }
  #chatIA .ch-msg.yo.fallo .ch-acts button{ color:var(--a-ink); }
  #chatIA .ch-acts button.fuerte{ font-weight:700; color:var(--a-ink); }
  #chatIA .ch-sep{ align-self:center; font-family:var(--a-mono); font-size:10.5px; letter-spacing:.06em; color:var(--a-dim); margin:2px 0; }
  #chatIA .ch-tools{ margin-top:-6px; font-size:10.5px; }

  /* El estado del turno: pasos reales, punto animado → ✓. */
  #chatIA .ch-estado{ align-self:stretch; display:flex; flex-direction:column; gap:4px; padding:2px 0; }
  #chatIA .ch-estado .paso{ display:flex; align-items:center; gap:9px; font-size:12.5px; color:var(--a-mut); min-height:22px; }
  #chatIA .ch-estado .paso i{ width:7px; height:7px; border-radius:50%; background:var(--a-acc); flex:none; animation:chPulso 1.1s infinite ease-in-out; }
  #chatIA .ch-estado .paso.ok{ color:var(--a-dim); }
  #chatIA .ch-estado .paso.ok i{ animation:none; background:transparent; width:auto; height:auto; border-radius:0; }
  #chatIA .ch-estado .paso.ok i::before{ content:'✓'; color:var(--a-green); font-size:11px; }
  @media (prefers-reduced-motion:reduce){ #chatIA .ch-estado .paso i{ animation:none; opacity:.7; } }

  /* Las tarjetas: UNA familia (fondo tarjeta, borde 1px, radio 12). Sin sombras. */
  #chatIA .ch-card{ align-self:stretch; background:var(--a-card); border:1px solid var(--a-line); border-radius:var(--ch-r); padding:11px 13px; }
  #chatIA .ch-card .k{ font-family:var(--a-mono); font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:var(--a-dim); margin-bottom:4px; }
  #chatIA .ch-card .k2{ margin-top:10px; }
  #chatIA .ch-card .vacio{ font-size:12.5px; color:var(--a-dim); padding:3px 0; }
  #chatIA .ch-card .row{ display:flex; justify-content:space-between; gap:10px; padding:6px 0; border-top:1px solid var(--a-line); font-size:13px; }
  #chatIA .ch-card .row:first-of-type{ border-top:0; }
  #chatIA .ch-card .row .m{ font-family:var(--a-mono); color:var(--a-mut); font-variant-numeric:tabular-nums; white-space:nowrap; }
  #chatIA .ch-card .row .m.amber{ color:var(--a-amber); }
  #chatIA .ch-card .row .m.est-confirmado{ color:var(--a-green); }
  #chatIA .ch-card .row .m.est-espera{ color:var(--a-amber); }
  #chatIA .ch-card .row .m.est-consultar{ color:var(--a-blue); }
  #chatIA .ch-card.ch-fallo{ color:var(--a-amber); font-size:13px; }
  #chatIA .ch-ev{ display:flex; align-items:center; gap:10px; width:100%; text-align:left; background:none; border:0; border-top:1px solid var(--a-line);
    padding:8px 0; font:inherit; font-size:13px; color:var(--a-ink); cursor:pointer; min-height:40px; }
  #chatIA .ch-ev:first-of-type, #chatIA .k + .ch-ev{ border-top:0; }
  #chatIA .ch-ev .h{ font-family:var(--a-mono); color:var(--a-dim); width:44px; flex:none; font-variant-numeric:tabular-nums; }
  #chatIA .ch-ev .c{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #chatIA .ch-ev .m{ font-family:var(--a-mono); color:var(--a-mut); font-variant-numeric:tabular-nums; }
  #chatIA .dot{ display:inline-block; width:7px; height:7px; border-radius:50%; margin-right:7px; vertical-align:middle; background:var(--a-blue); }
  #chatIA .dot.confirmado{ background:var(--a-green); } #chatIA .dot.espera{ background:var(--a-amber); }
  #chatIA .dot.consultar{ background:var(--a-blue); } #chatIA .dot.reunion{ background:var(--a-reunion); } #chatIA .dot.personal{ background:var(--a-personal, var(--t-personal)); }
  #chatIA .dot.off{ background:var(--a-dim); opacity:.6; }
  #chatIA .ch-cal button.d.off{ background:transparent; color:var(--a-dim); font-weight:400; text-decoration:line-through; }
  #chatIA .ch-card .row .m.est-rechazado, #chatIA .ch-ev .m.est-rechazado{ color:var(--a-dim); }
  #chatIA .ch-link{ display:inline-block; background:none; border:0; padding:8px 0 2px; margin-right:16px; font:inherit; font-family:var(--a-mono);
    font-size:11px; letter-spacing:.06em; text-transform:uppercase; color:var(--a-acc); cursor:pointer; min-height:32px; }
  #chatIA .ch-link.dim{ color:var(--a-dim); }

  /* El inicio inteligente. */
  #chatIA .ch-home{ display:flex; flex-direction:column; gap:12px; align-self:stretch; }
  #chatIA .ch-saludo{ font-size:19px; font-weight:600; letter-spacing:-.01em; color:var(--a-ink); padding:2px 2px 0; }
  #chatIA .ch-aviso{ border-color:color-mix(in srgb, var(--a-amber) 45%, var(--a-line)); }
  #chatIA .ch-aviso .txt{ font-size:13.5px; color:var(--a-ink); line-height:1.45; }
  #chatIA .ch-aviso .sub{ font-size:12.5px; color:var(--a-mut); margin-top:2px; font-family:var(--a-mono); }
  #chatIA .ch-aviso .acts{ display:flex; gap:4px 14px; flex-wrap:wrap; }
  /* Hasta tres avisos (fase 1, 14/09/2026): el primero manda; los que siguen van más
     quietos. La acción principal de cada uno ("¿Le escribo?", "Anotar la seña") va en
     el acento; "Ver el evento" y "Hoy no" quedan como estaban. */
  #chatIA .ch-aviso.mas{ border-color:var(--a-line); }
  #chatIA .ch-aviso.mas .txt{ font-size:13px; }
  #chatIA .ch-link.p{ color:var(--pro-2); }
  #chatIA .ch-aviso .acts .ch-link{ margin-right:0; }

  /* Bloques ricos: calendario, cifra, deudores, ficha, catálogo. Misma familia de tarjeta. */
  #chatIA .ch-bloques{ align-self:stretch; display:flex; flex-direction:column; gap:10px; }
  #chatIA .ch-card .tit{ font-size:15px; font-weight:600; color:var(--a-ink); margin:-2px 0 4px; }
  #chatIA .ch-card .row.tot{ border-top:1px solid var(--a-line2); color:var(--a-dim); }
  #chatIA .ch-card .row small{ color:var(--a-dim); font-size:11px; margin-left:6px; }
  #chatIA .ch-card .row .m.green{ color:var(--a-green); }
  #chatIA .ch-cifra .big{ font-family:var(--a-mono); font-size:24px; font-weight:500; color:var(--a-ink); letter-spacing:-.01em; font-variant-numeric:tabular-nums; margin-top:2px; }
  #chatIA .ch-cifra .sub{ font-size:12px; color:var(--a-mut); margin:2px 0 6px; }
  #chatIA .ch-cifra .sub .up{ color:var(--a-green); } #chatIA .ch-cifra .sub .down{ color:var(--a-red); }
  #chatIA .ch-cal{ display:grid; grid-template-columns:repeat(7,1fr); gap:3px; margin:6px 0 8px; font-family:var(--a-mono); font-size:11.5px; text-align:center; }
  #chatIA .ch-cal span, #chatIA .ch-cal button{ display:flex; align-items:center; justify-content:center; gap:2px; min-height:32px; border-radius:7px; color:var(--a-mut); font:inherit; padding:0; border:0; background:none; position:relative; }
  #chatIA .ch-cal .hd{ color:var(--a-dim); font-size:9.5px; min-height:16px; letter-spacing:.06em; }
  #chatIA .ch-cal .x{ visibility:hidden; }
  #chatIA .ch-cal .hoy{ outline:1px solid var(--a-line2); }
  #chatIA .ch-cal button.d{ cursor:pointer; color:var(--a-ink); font-weight:600; }
  #chatIA .ch-cal button.d.confirmado{ background:color-mix(in srgb, var(--a-green) 24%, transparent); }
  #chatIA .ch-cal button.d.espera{ background:color-mix(in srgb, var(--a-amber) 24%, transparent); }
  #chatIA .ch-cal button.d.consultar{ background:color-mix(in srgb, var(--a-blue) 24%, transparent); }
  #chatIA .ch-cal button.d.reunion{ background:color-mix(in srgb, var(--a-reunion) 24%, transparent); }
  #chatIA .ch-cal button.d.personal{ background:color-mix(in srgb, var(--t-personal) 24%, transparent); }
  #chatIA .ch-cal button.d i{ font-style:normal; font-size:9px; color:var(--a-dim); }
  #chatIA .ch-fichaMini .row .m.est-confirmado{ color:var(--a-green); }

  /* Tarjetas de acción (fase 5): verbo, grilla clave/valor, 44pt, transición de estado. */
  #chatIA .ch-acc{ border-left-width:1px; border-left-color:var(--a-line); border-radius:var(--ch-r); padding:12px 13px; }
  #chatIA .ch-acc.pide{ border-color:color-mix(in srgb, var(--a-acc) 45%, var(--a-line)); }
  #chatIA .ch-acc.hecha{ border-color:color-mix(in srgb, var(--a-green) 40%, var(--a-line)); }
  #chatIA .ch-acc.pendiente{ border-color:color-mix(in srgb, var(--a-amber) 45%, var(--a-line)); }
  #chatIA .ch-acc.conflicto, #chatIA .ch-acc.fallo{ border-color:color-mix(in srgb, var(--a-red) 45%, var(--a-line)); }
  #chatIA .ch-acc .t{ font-size:14px; }
  #chatIA .ch-acc .est{ font-size:12px; margin-top:3px; }
  #chatIA .ch-acc .det{ font-size:13px; }
  #chatIA .ch-acc .kv{ display:grid; grid-template-columns:auto 1fr; gap:4px 14px; margin:2px 0 4px; }
  #chatIA .ch-acc .kv span:nth-child(odd){ color:var(--a-dim); }
  #chatIA .ch-acc .kv span:nth-child(even){ color:var(--a-ink); font-weight:500; }
  #chatIA .ch-acc .kv span.mono{ font-family:var(--a-mono); font-variant-numeric:tabular-nums; }
  #chatIA .ch-acc .nota{ margin-top:7px; color:var(--a-dim); font-size:12px; }
  #chatIA .ch-acc .btns{ margin-top:12px; }
  #chatIA .ch-acc .si{ min-height:44px; padding:0 18px; border-radius:11px; font-size:14px; flex:1; max-width:280px; }
  #chatIA .ch-acc .no{ min-height:44px; padding:0 14px; border-radius:11px; font-size:14px; }
  #chatIA .ch-acc .si[disabled]{ opacity:.45; }
  #chatIA .ch-acc .ch-link{ padding-top:10px; }
  /* Flujos: controles adentro de la tarjeta. */
  #chatIA .ch-acc .form{ display:grid; grid-template-columns:1fr 1fr; gap:8px; margin:6px 0 2px; }
  #chatIA .ch-acc .form .f{ display:flex; flex-direction:column; gap:3px; min-width:0; }
  #chatIA .ch-acc .form .f.w{ grid-column:1/-1; }
  #chatIA .ch-acc .form .f[hidden]{ display:none; }
  #chatIA .ch-acc .form small{ font-family:var(--a-mono); font-size:9.5px; letter-spacing:.08em; text-transform:uppercase; color:var(--a-dim); }
  #chatIA .ch-acc .form input, #chatIA .ch-acc .form textarea{ width:100%; box-sizing:border-box; font:inherit; font-size:16px; padding:8px 10px; min-height:40px; border-radius:9px;
    background:var(--a-input); border:1px solid var(--a-line); color:var(--a-ink); color-scheme:inherit; }
  #chatIA .ch-acc .form textarea{ resize:vertical; line-height:1.4; }
  #chatIA .ch-acc .form input:focus, #chatIA .ch-acc .form textarea:focus{ outline:none; border-color:var(--pro-2); }
  #chatIA .ch-acc .form .seg{ display:flex; flex-wrap:wrap; gap:6px; }
  #chatIA .ch-acc .form .seg button{ flex:1 0 auto; min-height:40px; padding:0 12px; border-radius:9px; border:1px solid var(--a-line); background:none; color:var(--a-mut); font:inherit; font-size:13px; cursor:pointer; }
  #chatIA .ch-acc .form .seg button.on{ background:color-mix(in srgb, var(--a-acc) 16%, var(--a-card)); color:var(--a-ink); border-color:transparent; }
  #chatIA .ch-acc .ia-lista{ display:flex; flex-direction:column; gap:2px; margin-top:6px; }
  #chatIA .ch-acc .ia-f{ display:grid; grid-template-columns:auto auto 1fr; gap:10px; align-items:center; min-height:40px; font-size:13px; cursor:pointer; }
  #chatIA .ch-acc .ia-f input{ width:18px; height:18px; accent-color:var(--a-acc); margin:0; }
  #chatIA .ch-acc .ia-f .k{ color:var(--a-dim); }
  #chatIA .ch-acc .ia-f .v{ color:var(--a-ink); }
  #chatIA .ch-acc .ia-f s{ color:var(--a-dim); }

  /* Bloques históricos: la foto de entonces, con su fecha, atenuada; "Ver hoy" la repinta. */
  #chatIA .ch-cuando{ font-family:var(--a-mono); font-size:10.5px; letter-spacing:.06em; text-transform:uppercase; color:var(--a-dim); display:flex; align-items:center; gap:10px; }
  #chatIA .ch-cuando .ch-link{ padding:0; margin:0; min-height:24px; text-transform:none; letter-spacing:0; font-size:11px; }
  #chatIA .ch-bloques.historico .ch-card{ opacity:.82; border-style:dashed; }

  /* Sugerencias y acciones del inicio: chips. Dos a cuatro, nunca genéricas. */
  #chatIA .ch-sug{ display:flex; flex-wrap:wrap; gap:7px; align-self:stretch; }
  #chatIA .ch-chip{ border:1px solid var(--a-line); background:var(--a-card); color:var(--a-mut); border-radius:999px; padding:0 13px;
    min-height:36px; font:inherit; font-size:12.5px; cursor:pointer; text-align:left; }
  #chatIA .ch-chip.p{ border-color:transparent; background:color-mix(in srgb, var(--a-acc) 16%, var(--a-card)); color:var(--a-ink); }

  /* Conversaciones (≡): panel encima del hilo. */
  #chatIA .ch-convs{ position:absolute; left:0; right:0; bottom:0; top:62px; z-index:4; background:var(--a-bg); display:flex; flex-direction:column; overflow:auto;
    padding:0 calc(18px + env(safe-area-inset-right)) 20px calc(18px + env(safe-area-inset-left)); }
  #chatIA .ch-convs-hd{ display:flex; align-items:center; min-height:44px; font-weight:600; font-size:15px; border-bottom:1px solid var(--a-line); margin-bottom:6px; }
  #chatIA .ch-conv{ display:flex; align-items:center; gap:4px; border-bottom:1px solid var(--a-line); }
  #chatIA .ch-conv.actual .t{ color:var(--a-acc); }
  #chatIA .ch-conv-ab{ flex:1; min-width:0; text-align:left; background:none; border:0; padding:11px 2px; font:inherit; color:var(--a-ink); cursor:pointer; min-height:52px; }
  #chatIA .ch-conv-ab .t{ display:block; font-size:14px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #chatIA .ch-conv-ab .s{ display:block; font-family:var(--a-mono); font-size:10.5px; color:var(--a-dim); margin-top:2px; letter-spacing:.04em; }
  #chatIA .ch-convs-vacio{ color:var(--a-dim); font-size:13px; padding:14px 2px; }

  /* El composer: cápsula con "+", campo que crece y ↑ que pasa a ■ mientras trabaja. */
  #chatIA .ch-foot{ padding-top:9px; }
  #chatIA .ch-row{ align-items:flex-end; gap:6px; background:var(--a-input); border:1px solid var(--a-line); border-radius:18px; padding:5px 5px 5px 6px; max-width:var(--ch-lect); margin:0 auto; }
  #chatIA .ch-row:focus-within{ border-color:color-mix(in srgb, var(--pro-2) 70%, var(--a-line)); box-shadow:0 0 0 1px color-mix(in srgb, var(--pro-2) 45%, transparent); }
  #chatIA textarea{ background:transparent; border:0; padding:8px 4px; border-radius:0; max-height:132px; line-height:1.4; }
  #chatIA textarea:focus{ outline:none; border:0; box-shadow:none; }
  #chatIA textarea::placeholder{ color:var(--a-dim); }
  #chatIA .ch-plus, #chatIA .ch-send{ flex:none; width:36px; height:36px; border-radius:50%; font-size:17px; line-height:1; display:grid; place-items:center; padding:0; }
  /* el micrófono (14/09/2026): misma caja que + y ↑ */
  #chatIA .ch-mic{ flex:none; width:36px; height:36px; border-radius:50%; display:grid; place-items:center; padding:0; background:transparent; border:1px solid var(--a-line); color:var(--a-mut); cursor:pointer; }
  #chatIA .ch-mic .ico{ width:18px; height:18px; stroke-width:2; }
  :where(html.puntero) #chatIA .ch-mic:hover{ color:var(--a-ink); border-color:var(--a-acc); }
  #chatIA .ch-plus{ background:transparent; border:1px solid var(--a-line); color:var(--a-mut); font:inherit; font-size:19px; cursor:pointer; position:relative; }
  #chatIA .ch-plus::before{ content:''; position:absolute; inset:-6px; }
  #chatIA .ch-plus[aria-expanded="true"]{ background:var(--a-card); color:var(--a-ink); transform:rotate(45deg); }
  #chatIA .ch-send{ transition:background .18s ease, color .18s ease; }
  #chatIA .ch-send.stop{ background:var(--a-card); border:1px solid var(--a-line2); color:var(--a-ink); font-size:11px; }
  #chatIA .ch-send[disabled]{ opacity:1; }
  #chatIA .ch-bar{ margin:0 auto 6px; max-width:var(--ch-lect); opacity:1; gap:6px; }
  #chatIA .ch-bar[hidden]{ display:none; }
  #chatIA .ch-menu{ position:absolute; left:calc(18px + env(safe-area-inset-left)); right:calc(18px + env(safe-area-inset-right)); bottom:calc(100% - 4px);
    max-width:var(--ch-lect); margin:0 auto; background:var(--a-card); border:1px solid var(--a-line2); border-radius:14px; padding:6px; z-index:6;
    box-shadow:0 14px 34px -18px color-mix(in srgb, var(--a-ink) 35%, transparent); display:flex; flex-direction:column; }
  #chatIA .ch-menu[hidden]{ display:none; }
  #chatIA .ch-foot{ position:relative; }
  #chatIA .ch-mi{ display:flex; align-items:center; gap:9px; flex-wrap:wrap; min-height:44px; padding:8px 10px; border:0; background:none; border-radius:9px;
    font:inherit; font-size:13.5px; color:var(--a-ink); text-align:left; cursor:pointer; }
  #chatIA .ch-mi small{ flex-basis:100%; font-size:11.5px; color:var(--a-dim); margin-top:-4px; padding-left:24px; }
  #chatIA .ch-mi input{ width:15px; height:15px; accent-color:var(--a-acc); margin:0; }
  #chatIA .ch-mi:not(label) small{ padding-left:0; }

  /* :hover SOLO con puntero real (regla de la casa: en el teléfono un hover pegado
     queda encendido después del toque). */
  html.puntero #chatIA .ch-hb:hover{ background:var(--a-card); color:var(--a-ink); }
  html.puntero #chatIA .ch-msg:hover .ch-acts{ display:flex; }
  html.puntero #chatIA .ch-acts button:hover{ color:var(--a-ink); text-decoration:underline; }
  html.puntero #chatIA .ch-ev:hover .c{ color:var(--a-acc); }
  html.puntero #chatIA .ch-chip:hover{ color:var(--a-ink); border-color:var(--a-line2); }
  html.puntero #chatIA .ch-mi:hover{ background:var(--a-input); }
  /* La paleta "/" y "@": encima del composer, filtrada mientras se escribe. */
  #chatIA .ch-palwrap{ position:absolute; left:calc(18px + env(safe-area-inset-left)); right:calc(18px + env(safe-area-inset-right)); bottom:calc(100% - 4px); max-width:var(--ch-lect); margin:0 auto; z-index:6; }
  #chatIA .ch-palwrap[hidden]{ display:none; }
  #chatIA .ch-pal{ background:var(--a-card); border:1px solid var(--a-line2); border-radius:14px; padding:5px; display:flex; flex-direction:column; max-height:264px; overflow:auto;
    box-shadow:0 14px 34px -18px color-mix(in srgb, var(--a-ink) 35%, transparent); }
  #chatIA .ch-pi{ display:flex; align-items:baseline; gap:10px; min-height:44px; padding:8px 10px; border:0; background:none; border-radius:9px; font:inherit; font-size:13.5px; color:var(--a-ink); text-align:left; cursor:pointer; }
  #chatIA .ch-pi b{ font-family:var(--a-mono); font-weight:500; color:var(--a-acc); flex:none; }
  #chatIA .ch-pi span{ color:var(--a-dim); font-size:12px; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #chatIA .ch-pi.sel{ background:color-mix(in srgb, var(--a-acc) 14%, transparent); }
  #chatIA .ch-chip.chico{ min-height:28px; font-size:12px; padding:0 9px; display:inline-flex; align-items:center; gap:5px; }
  #chatIA .ch-chip.chico small{ color:var(--a-dim); font-family:var(--a-mono); font-size:10px; }
  #chatIA .ch-chip.chico button{ background:none; border:0; color:var(--a-dim); font:inherit; padding:0 2px; cursor:pointer; min-width:24px; min-height:24px; }

  /* ↓ nuevo (fase 7): flota sobre el hilo, encima del pie. */
  #chatIA .ch-nuevo{ position:absolute; left:50%; transform:translateX(-50%); bottom:94px; z-index:5;
    min-height:36px; padding:0 14px; border-radius:999px; border:1px solid var(--a-line2); background:var(--a-card); color:var(--a-ink);
    font:inherit; font-size:12.5px; font-weight:600; cursor:pointer; box-shadow:0 8px 24px -14px color-mix(in srgb, var(--a-ink) 40%, transparent); }
  #chatIA .ch-nuevo[hidden]{ display:none; }
  /* Foco visible por teclado, en todo el cajón (accesibilidad). */
  #chatIA :is(button, textarea, input, [tabindex]):focus-visible{ outline:2px solid var(--pro-2); outline-offset:2px; }
  #chatIA textarea:focus-visible{ outline:none; }

  /* La ficha ENCIMA del chat: única excepción al orden de capas, y solo con la clase. */
  #dashFicha.sobre-chat{ z-index:10072; }
  #dashFicha .fvolver{ flex-basis:100%; order:-1; align-self:flex-start; background:none; border:0; padding:0 0 10px; margin:-4px 0 0;
    font:inherit; font-size:13px; font-weight:600; color:var(--d-acc); cursor:pointer; min-height:36px; text-align:left; }
  #dashFicha .fhd{ flex-wrap:wrap; }

  /* El marco PRO en claro: apagado en reposo; solo trabajando. (La raíz SIEMPRE
     lleva data-theme, lo estampa el <head>: no hace falta la media query.) */
  html[data-theme="claro"] #chatIA .ch-aura{ opacity:0; }
  html[data-theme="claro"] #chatIA.escribiendo .ch-aura{ opacity:.35; }
  html[data-theme="claro"] #chatIA.pensando .ch-aura{ opacity:.7; }

  /* Movimiento: corto y con propósito. */
  @media (prefers-reduced-motion:no-preference){
    #chatIA .ch-msg, #chatIA .ch-acc, #chatIA .ch-card, #chatIA .ch-estado, #chatIA .ch-sug{ animation:chEntra .18s ease-out both; }
    #chatIA .ch-sug .ch-chip{ animation:chEntra .18s ease-out both; }
    #chatIA .ch-sug .ch-chip:nth-child(2){ animation-delay:.04s; } #chatIA .ch-sug .ch-chip:nth-child(3){ animation-delay:.08s; } #chatIA .ch-sug .ch-chip:nth-child(4){ animation-delay:.12s; }
    #chatIA .ch-acc{ transition:border-color .2s ease; }
    #chatIA .ch-plus{ transition:transform .18s ease, background .18s ease; }
  }
  @keyframes chEntra{ from{ opacity:0; transform:translateY(6px); } to{ opacity:1; transform:none; } }

  /* ==================== EL CHAT EN EL IPHONE (video del 14/09/2026) ====================
     Ajustes SOLO para mobile (< 1024px): el escritorio no cambia. Lo que el video
     mostró: el anillo de foco azul cuadrado sobre el campo con el teclado abierto,
     el inicio que aparecía de golpe tras un cuadro en blanco al tocar "+", la ✕ con
     caja distinta a ≡ y +, y la ficha que aparecía en seco encima del chat. */
  @media (max-width:1023px){
    /* 🔴 El campo NO lleva anillo de foco propio: la cápsula ya marca el foco con su
       borde (.ch-row:focus-within). La regla general de :focus-visible pesa (1,2,0) por
       el [tabindex] del :is(), así que esta va con más peso todavía. */
    #chatIA .ch-row textarea:focus-visible, #chatIA .ch-row textarea:focus{ outline:none; box-shadow:none; }
    /* Los tres controles del encabezado son la misma pieza: 40pt, sin caja. */
    #chatIA .agenda-x{ background:transparent; border:0; box-shadow:none; color:var(--a-mut); min-width:40px; min-height:40px; width:40px; height:40px;
      margin:0; padding:0; border-radius:10px; font-size:15px; display:grid; place-items:center; }
    #chatIA .ch-hbs{ gap:4px; }
    /* La cápsula del composer: un solo objeto; el foco se nota en su borde, suave. */
    #chatIA .ch-row{ transition:border-color .18s ease, box-shadow .18s ease; }
    #chatIA .ch-row:focus-within{ border-color:color-mix(in srgb, var(--pro-2) 45%, var(--a-line)); box-shadow:none; }
    /* Un poco más de aire alrededor del hilo y entre bloques en pantalla angosta. */
    #chatIA .ch-hilo{ gap:14px; }
    #chatIA .ch-home{ gap:12px; }
    #chatIA .ch-saludo{ padding-top:4px; }
    /* 🔴 EL CORTE DE ARRIBA (video 14/09/2026). Con la barra de estado `black` el
       cajón arranca 62pt abajo del vidrio y las dos líneas laterales del marco
       terminaban en seco contra la barra: se leía como una imagen recortada. Dos
       tiras del color del fondo, del ancho del marco, las FUNDEN en los primeros
       72px. Solo las líneas: el encabezado (título y botones) queda intacto. */
    #chatIA::before, #chatIA::after{ content:''; position:absolute; top:0; width:10px; height:72px; z-index:6; pointer-events:none;
      background:linear-gradient(to bottom, var(--a-bg) 0, var(--a-bg) 34%, transparent 100%); }
    #chatIA::before{ left:0; } #chatIA::after{ right:0; }
    /* `.agenda` trae un `border-left` de 1px para el panel lateral de escritorio. En
       el iPhone el cajón ocupa la pantalla entera y esa línea quedaba pegada al
       borde izquierdo del vidrio, a lo largo de todo el alto (medida en la captura
       WebKit: 3 píxeles de --a-line). El marco acá es el anillo, no un borde. */
    #chatIA{ border-left:0; }
  }
  /* 🔴 LA BARRA DE ESTADO ES NEGRA Y EL CAJÓN NO (captura del iPhone, 14/09/2026,
     iOS 26.6.1). Con `apple-mobile-web-app-status-bar-style=black` iOS pinta la barra
     en NEGRO PURO, no del color de la página (eso lo hace el simulador 26.1 con
     cualquier valor del meta, y engaña): el cajón (--t-agenda-bg) arrancaba 62pt
     abajo con un escalón de color a lo ancho, y se leía como una imagen recortada.
     Por qué no se sube el cajón hasta el vidrio: en iOS 26 `black-translucent` dibuja
     la app debajo de la barra pero le da 894 de los 956pt y deja 62 muertos abajo
     (verificado en el iPhone de Tobi el 05/09; WebKit 301108 sigue abierto). No hay
     forma de tener las dos puntas.
     Lo que sí se puede: que el escalón desaparezca. El encabezado del cajón arranca
     NEGRO (el negro de la barra, la palabra `black`, no un hex: es el color del
     sistema) y se funde en 60px con el fondo del cajón; las dos tiras que funden las
     líneas del marco llevan EL MISMO degradé como fondo y una máscara para el fundido,
     así en cada altura son del color exacto que tienen detrás. Solo en la app
     instalada (display-mode), solo iOS (-webkit-touch-callout) y solo en oscuro: en
     claro la barra negra sobre un cajón claro es otra conversación (`default`
     tintaría la barra desde la página, pero exige reinstalar el ícono y no se pudo
     verificar en el aparato). */
  @media (max-width:1023px) and (display-mode:standalone){
    @supports (-webkit-touch-callout:none){
      html[data-theme="oscuro"] #chatIA .agenda-hd{ background:linear-gradient(to bottom, black 0, var(--a-bg) 60px) no-repeat; }
      html[data-theme="oscuro"] #chatIA::before, html[data-theme="oscuro"] #chatIA::after{
        background:linear-gradient(to bottom, black 0, var(--a-bg) 60px);
        -webkit-mask:linear-gradient(to bottom, black 0, black 34%, transparent 100%);
                mask:linear-gradient(to bottom, black 0, black 34%, transparent 100%); }
    }
  }
  @media (max-width:1023px) and (prefers-reduced-motion:no-preference){
    /* El inicio se ARMA (saludo, tarjeta, aviso, chips) en vez de aparecer de golpe
       tras un cuadro en blanco: cada pieza entra con 50ms de diferencia. */
    #chatIA .ch-home{ animation:none; }
    #chatIA .ch-home > *{ animation:chEntra .26s cubic-bezier(.2,.7,.2,1) both; }
    #chatIA .ch-home > :nth-child(2){ animation-delay:.05s; }
    #chatIA .ch-home > :nth-child(3){ animation-delay:.1s; }
    #chatIA .ch-home > :nth-child(4){ animation-delay:.15s; }
    #chatIA .ch-home .ch-sug .ch-chip{ animation:none; }
    /* Mensajes y bloques: la misma curva del sistema, un toque más larga que en escritorio. */
    #chatIA .ch-msg, #chatIA .ch-bloques, #chatIA .ch-acc{ animation:chEntra .22s cubic-bezier(.2,.7,.2,1) both; }
    /* La ficha encima del chat entra como una hoja: sube y se funde. Solo cuando
       está sobre el chat (sobre-chat); la ficha del Panel no cambia. */
    #dashFicha.sobre-chat .fbox{ animation:chHoja .28s cubic-bezier(.2,.7,.2,1) both; }
  }
  /* ==================== EL CHAT A LA MEDIDA DEL IPHONE 17 PRO MAX (20/09/2026) ====================
     440 × 956 pt, 3x, zona segura 62 arriba / 34 abajo. Tobi: "chequeá todo el diseño del chat…
     cuidá mucho las dimensiones". Medido en WebKit a ese tamaño: los cinco controles del composer y
     del encabezado tenían 36 pt (Apple pide 44), el cuerpo del texto 15 px (iOS usa 17), las acciones
     de los avisos eran texto suelto en mayúsculas, y las sugerencias quedaban arriba de una pantalla de
     casi un metro de pulgar. Referencias: ChatGPT y Claude en iOS (turno anclado arriba, composer en
     cápsula, micrófono cuando está vacío y ↑ cuando hay texto, acciones bajo la última respuesta).
     Solo mobile: el escritorio no cambia. */
  @media (max-width:1023px){
    /* --- el texto: se lee sin esfuerzo a un brazo de distancia --- */
    #chatIA .ch-msg.ia{ font-size:16.5px; line-height:1.55; letter-spacing:-.005em; }
    #chatIA .ch-msg.ia p{ margin:0 0 12px; }
    #chatIA .ch-msg.ia ul, #chatIA .ch-msg.ia ol{ margin:2px 0 12px; padding-left:22px; }
    #chatIA .ch-msg.ia li{ margin:6px 0; }
    #chatIA .ch-msg.yo{ font-size:16px; line-height:1.45; padding:11px 16px; border-radius:22px 22px 6px 22px; max-width:82%; }
    #chatIA .ch-saludo{ font-size:24px; letter-spacing:-.02em; line-height:1.15; }
    #chatIA .ch-card{ padding:14px 16px; border-radius:18px; }
    #chatIA .ch-card .k{ font-size:11px; }
    #chatIA .ch-card .vacio{ font-size:15px; }
    #chatIA .ch-aviso .txt{ font-size:15.5px; line-height:1.4; }
    #chatIA .ch-aviso .sub{ font-size:13px; font-family:inherit; }
    #chatIA .ch-tools{ font-size:12px; }
    #chatIA .ch-sep{ font-size:11.5px; }
    #chatIA .ch-estado .paso{ font-size:15px; min-height:26px; }
    #chatIA .ch-acc .t{ font-size:16px; }
    /* --- todo lo que se toca mide 44 pt --- */
    #chatIA .ch-hb, #chatIA .agenda-x{ min-width:44px; min-height:44px; width:44px; height:44px; border-radius:50%; display:grid; place-items:center; padding:0; }
    #chatIA .ch-hb .ico{ width:22px; height:22px; }
    #chatIA .agenda-x{ font-size:17px; }
    #chatIA .ch-hbs{ gap:2px; }
    #chatIA .ch-plus, #chatIA .ch-send, #chatIA .ch-mic{ width:44px; height:44px; }
    #chatIA .ch-mic .ico{ width:21px; height:21px; }
    #chatIA .ch-plus{ font-size:22px; }
    #chatIA .ch-send{ font-size:20px; }
    #chatIA .ch-row{ border-radius:28px; padding:5px; gap:4px; }
    #chatIA textarea{ font-size:17px; line-height:1.35; padding:10px 6px; max-height:132px; }
    #chatIA .ch-foot{ padding-top:10px; }
    /* 🔴 NOVENA PASADA DEL ALTO (20/09/2026): el encabezado queda pegado debajo del área segura, sin
       aire de más. La base traía 16 + 44 + 14 = 74 pt; con controles de 44 pt alcanza con 6 y 6 (56 pt,
       el alto de una barra de navegación de iOS). Arriba suma `env(safe-area-inset-top)`: 0 con el
       ícono `black` (la app ya vive debajo de la barra) y 62 con el translúcido o en apaisado. */
    #chatIA .agenda-hd{ padding-top:calc(6px + env(safe-area-inset-top, 0px)); padding-bottom:6px; min-height:0; }
    #chatIA .agenda-hd h2{ min-height:44px; }
    /* `.franja`: el área pintable termina antes del vidrio (ícono translúcido en iOS 26). Abajo no hay
       esquina de iPhone que acompañar: el marco cierra con el radio chico, como arriba. */
    #chatIA.franja{ --rb:22px; }
    /* vacío: el micrófono es el protagonista y ↑ está apagado; con texto, ↑ se enciende y el
       micrófono deja el lugar para escribir. Mientras trabaja (■) siempre se ve. */
    #chatIA .ch-row:not(.con-texto) .ch-send:not(.stop){ background:var(--a-card); color:var(--a-dim); border:1px solid var(--a-line); }
    #chatIA .ch-row:not(.con-texto) .ch-mic{ background:var(--a-acc); border-color:transparent; color:#fff; }
    #chatIA .ch-row.con-texto .ch-mic{ display:none; }
    /* --- chips y acciones: botones de verdad, en la zona del pulgar --- */
    #chatIA .ch-sug{ gap:8px; }
    #chatIA .ch-chip{ min-height:44px; padding:0 17px; font-size:15px; }
    #chatIA .ch-aviso .acts{ gap:8px; margin-top:12px; }
    #chatIA .ch-aviso .acts .ch-link{ min-height:40px; padding:0 15px; margin:0; border:1px solid var(--a-line2); border-radius:999px; font-family:inherit; font-size:14px;
      letter-spacing:0; text-transform:none; font-weight:600; color:var(--a-ink); display:inline-flex; align-items:center; }
    #chatIA .ch-aviso .acts .ch-link.p{ background:color-mix(in srgb, var(--a-acc) 22%, var(--a-card)); border-color:transparent; color:var(--a-ink); }
    #chatIA .ch-aviso .acts .ch-link.dim{ border-color:transparent; color:var(--a-dim); font-weight:500; padding:0 8px; }
    /* las acciones del mensaje: a la vista en la última respuesta (en el iPhone no hay "pasar el mouse") */
    #chatIA .ch-msg.ia.ultima .ch-acts{ display:flex; }
    #chatIA .ch-acts{ gap:2px; margin-top:4px; font-family:inherit; font-size:13.5px; letter-spacing:0; }
    #chatIA .ch-acts button{ min-height:40px; padding:0 12px 0 0; border:0; border-radius:10px; color:var(--a-dim); }
    #chatIA .ch-msg.ia .ch-acts button + button{ padding-left:12px; border-left:1px solid var(--a-line); border-radius:0; }
    #chatIA .ch-msg.yo .ch-acts button{ padding:0 10px; }
    #chatIA .ch-msg.err{ font-size:15px; line-height:1.45; padding:13px 15px; border-radius:16px; }
    #chatIA .ch-msg.yo.fallo .ch-acts{ gap:8px; margin-top:10px; }
    #chatIA .ch-msg.yo.fallo .ch-acts button{ min-height:40px; padding:0 16px; font-size:14.5px; border-color:var(--a-line2); }
    #chatIA .ch-msg.yo.fallo .ch-acts button.fuerte{ background:var(--a-ink); color:var(--a-bg); border-color:transparent; }
    #chatIA .ch-acc .btns button{ min-height:48px; font-size:16px; border-radius:14px; }
    #chatIA .ch-nuevo{ min-height:40px; padding:0 16px; font-size:14px; border-radius:999px; }
    /* --- el inicio baja a la zona del pulgar: con el hilo vacío, el saludo y las tarjetas se apoyan
           sobre el composer en vez de colgar del borde de arriba con media pantalla vacía debajo --- */
    #chatIA .agenda-body{ display:flex; flex-direction:column; }
    #chatIA .ch-hilo{ flex:1 0 auto; }
    #chatIA .ch-hilo:has(> .ch-home:only-child){ justify-content:flex-end; padding-bottom:6px; }
    /* y en el espacio de arriba respira la aurora del agente (los colores del orbe, muy difusa): la
       pantalla vacía no se lee como "no cargó". Decorativa; con reducir movimiento queda quieta. */
    #chatIA .ch-hilo:has(> .ch-home:only-child)::before{ content:''; flex:none; align-self:center; margin:auto 0; width:210px; height:210px; border-radius:50%; pointer-events:none;
      background:conic-gradient(from 0deg, var(--pro-1), var(--pro-2), var(--pro-3), var(--pro-4), var(--pro-3), var(--pro-2), var(--pro-1));
      filter:blur(46px); opacity:.30; }
    /* --- el tacto: todo lo que se aprieta cede un poco --- */
    #chatIA .ch-chip, #chatIA .ch-hb, #chatIA .agenda-x, #chatIA .ch-plus, #chatIA .ch-mic, #chatIA .ch-send, #chatIA .ch-acc .btns button,
    #chatIA .ch-aviso .acts .ch-link, #chatIA .ch-acts button, #chatIA .ch-ev{ transition:transform .12s ease, opacity .12s ease, background .18s ease, color .18s ease; -webkit-tap-highlight-color:transparent; }
    #chatIA .ch-chip:active, #chatIA .ch-hb:active, #chatIA .agenda-x:active, #chatIA .ch-plus:active, #chatIA .ch-mic:active, #chatIA .ch-send:active,
    #chatIA .ch-acc .btns button:active, #chatIA .ch-aviso .acts .ch-link:active, #chatIA .ch-acts button:active{ transform:scale(.95); opacity:.85; }
    #chatIA .ch-ev:active{ opacity:.7; }
  }
  @media (max-width:1023px) and (prefers-reduced-motion:no-preference){
    /* "Pensando…" respira: un brillo que cruza el texto del paso en curso (el que todavía no tiene ✓). */
    #chatIA .ch-hilo:has(> .ch-home:only-child)::before{ animation:orbeGira 16s linear infinite; }
    #chatIA .ch-estado .paso:not(.ok) span{ background:linear-gradient(90deg, var(--a-mut) 0%, var(--a-mut) 38%, var(--a-ink) 50%, var(--a-mut) 62%, var(--a-mut) 100%);
      background-size:220% 100%; -webkit-background-clip:text; background-clip:text; color:transparent; animation:chBrillo 1.8s linear infinite; }
  }
  @keyframes chBrillo{ from{ background-position:120% 0; } to{ background-position:-100% 0; } }
  /* Sube casi opaca: si se fundiera desde cero, el chat de abajo se lee a través
     de la ficha durante la entrada (texto sobre texto). */
  @keyframes chHoja{ from{ opacity:.6; transform:translateY(28px); } to{ opacity:1; transform:none; } }

  /* ==================== HISTORIAL (pantalla, 31/08/2026) ====================
     Quinta página del carrusel. Mismo patrón que #dash: overlay fixed con su
     propio scroll, la paleta --d-* heredada del bloque de variables de arriba.
     🔴 z-index 900 igual que #dash y NO más: los cajones y modales (agenda 81 no,
     pero #numeros 10050, ficha 10060, chat 10070, stock 10075, modo evento 10080)
     tienen que poder taparlo, como tapan al panel. */
  #hist{
    position:fixed; inset:0; z-index:900; overflow-y:auto; display:none;
    background:var(--d-canvas); color:var(--d-ink);
    font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
    padding-top:var(--nav-top); padding-bottom:var(--nav-bot);
  }
  #hist.on{ display:block; }
  #hist .hwrap{ max-width:1180px; margin:0 auto; padding:16px 14px calc(56px + env(safe-area-inset-bottom)); }
  #hist h1{ margin:0; font-size:22px; letter-spacing:-.4px; }
  #hist .hsub{ color:var(--d-mut); font-size:13px; margin:3px 0 14px; }
  #hist .hbusca{ position:relative; margin-bottom:11px; }
  #hist .hbusca input{
    width:100%; box-sizing:border-box; padding:11px 13px 11px 36px; border-radius:11px;
    border:1px solid var(--d-line2); background:var(--d-card2); color:var(--d-ink);
    /* 🔴 16px: abajo de eso iOS hace zoom al enfocar y, como el overlay es fixed,
       la pantalla queda descuadrada encima del contenido. Misma regla que .fld. */
    font-size:16px; font-family:inherit;
  }
  #hist .hbusca svg{ position:absolute; left:12px; top:50%; transform:translateY(-50%); opacity:.5; }
  /* 🔴 LOS CHIPS ENVUELVEN, NO SCROLLEAN. Un scroller horizontal deja el último
     chip cortado en reposo, y eso no se lee como "hay más": se lee como un bug de
     layout. Cinco filtros cortos entran en dos renglones. Y de paso no compite
     con el gesto horizontal del carrusel. */
  #hist .hchips{ display:flex; flex-wrap:wrap; gap:7px; margin-bottom:9px; }
  #hist .hchip{
    flex:0 0 auto; border:1px solid var(--d-line2); background:var(--d-card);
    color:var(--d-dim); padding:7px 13px; border-radius:999px; font-size:12.5px;
    cursor:pointer; font-family:inherit; display:inline-flex; gap:6px; align-items:center;
  }
  #hist .hchip .n{ opacity:.6; font-variant-numeric:tabular-nums; }
  #hist .hchip[aria-pressed="true"]{ border-color:var(--d-acc); color:var(--d-ink);
    background:color-mix(in srgb, var(--d-acc) 16%, transparent); }
  #hist .hchip:focus-visible{ outline:2px solid var(--d-acc); outline-offset:2px; }
  #hist .hmas{ background:none; border:0; color:var(--d-mut); font-size:12.5px;
    text-decoration:underline; cursor:pointer; padding:0 0 12px; font-family:inherit; }
  #hist .hmes{ display:flex; align-items:center; gap:10px; margin:16px 0 8px;
    color:var(--d-mut); font-size:11px; letter-spacing:1.4px; text-transform:uppercase; }
  #hist .hmes:after{ content:''; flex:1; height:1px; background:var(--d-line); }
  #hist .hcols{ display:grid; grid-template-columns:1fr; gap:14px; }
  #hist .hev{
    display:block; width:100%; text-align:left; box-sizing:border-box;
    background:var(--d-card); border:1px solid var(--d-line); border-radius:13px;
    padding:13px 14px; margin-bottom:9px; cursor:pointer; color:inherit; font-family:inherit;
  }
  #hist .hev:focus-visible{ outline:2px solid var(--d-acc); outline-offset:2px; }
  /* 23/09/2026: vista previa al costado de cada presupuesto, sin abrir el detalle */
  #hist .hev-fila{ display:flex; gap:8px; align-items:stretch; margin-bottom:9px; }
  #hist .hev-fila .hev{ flex:1; min-width:0; margin-bottom:0; }
  #hist .hev-pv{ flex:none; width:60px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
    background:var(--d-card); border:1px solid var(--d-line); border-radius:13px; color:var(--d-acc); cursor:pointer;
    font:inherit; font-size:11.5px; font-weight:650; min-height:44px; }
  #hist .hev-pv .ico{ width:20px; height:20px; }
  #hist .hev-pv:focus-visible{ outline:2px solid var(--d-acc); outline-offset:2px; }
  #hist .hev-pv:active{ transform:scale(.97); }
  #hist .hev[aria-current="true"]{ border-color:var(--d-acc);
    background:color-mix(in srgb, var(--d-acc) 9%, var(--d-card)); }
  #hist .hev .r1{ display:flex; justify-content:space-between; gap:10px; align-items:baseline; }
  #hist .hev .cli{ font-size:15px; font-weight:650; letter-spacing:-.2px;
    overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  #hist .hev .tot{ font-family:var(--font-display,ui-monospace,Menlo,monospace);
    font-size:14px; font-weight:700; font-variant-numeric:tabular-nums; white-space:nowrap; }
  #hist .hev .r2{ color:var(--d-mut); font-size:12px; margin-top:3px;
    font-family:var(--font-display,ui-monospace,Menlo,monospace); }
  #hist .hev .r3{ display:flex; flex-wrap:wrap; gap:7px; align-items:center; margin-top:9px; }
  #hist .hest{ display:inline-flex; align-items:center; gap:6px; padding:5px 11px;
    border-radius:999px; font-size:12px; font-weight:650; }
  #hist .hest .pt{ width:6px; height:6px; border-radius:50%; background:currentColor; }
  #hist .hult{ color:var(--d-dim); font-size:12px; display:inline-flex; gap:6px; align-items:center; }
  #hist .hmov{ margin-left:auto; font-size:11px; color:var(--d-mut); background:var(--d-card2);
    border:1px solid var(--d-line); border-radius:999px; padding:4px 10px;
    font-family:var(--font-display,ui-monospace,Menlo,monospace); }
  #hist .hpend{ color:var(--d-amber); border:1px solid var(--d-amber); border-radius:999px;
    padding:4px 10px; font-size:11.5px; font-weight:650; }
  #hist .hev.elim .cli{ text-decoration:line-through; opacity:.65; }
  #hist .hvacio{ color:var(--d-mut); text-align:center; padding:40px 20px; font-size:14px; }

  /* ---- detalle ---- */
  #hist .hdet{
    position:fixed; left:0; right:0; bottom:0; max-height:88vh; z-index:2;
    background:var(--d-card); border-top:1px solid var(--d-line2);
    border-radius:16px 16px 0 0; display:none; flex-direction:column;
    transform:translateY(100%); transition:transform .28s cubic-bezier(.32,.72,0,1);
  }
  #hist .hdet.on{ display:flex; transform:translateY(0); }
  #hist .hdvelo{ position:fixed; inset:0; background:rgba(0,0,0,.5); display:none; z-index:1; }
  #hist .hdvelo.on{ display:block; }
  #hist .hdhd{ display:flex; gap:10px; align-items:flex-start; padding:13px 16px 12px;
    border-bottom:1px solid var(--d-line); flex:0 0 auto; }
  #hist .hdhd h2{ margin:0; font-size:18px; letter-spacing:-.3px; }
  #hist .hdhd .s{ color:var(--d-mut); font-size:12.5px; margin-top:3px;
    font-family:var(--font-display,ui-monospace,Menlo,monospace); }
  #hist .hdx{ margin-left:auto; width:34px; height:34px; border-radius:50%; flex:0 0 auto;
    border:1px solid var(--d-line2); background:var(--d-card2); color:var(--d-ink);
    font-size:16px; cursor:pointer; }
  /* 🔴 EL AIRE DE ABAJO LO DA --nav-bot, NO env() PELADO. En móvil el detalle es
     una hoja `position:fixed; bottom:0`, y un fixed NO se posiciona contra un
     ancestro fixed: se ancla al layout viewport, así que el `padding-bottom` que
     #hist ya reserva para la barra NO lo alcanza. Y como #hist está en z-900 y
     #navbar en z-950, la barra le pintaba encima Y SE LLEVABA EL TOQUE — los dos
     botones del final quedaban tapados 23 de sus 44px y eran intocables. Medido a
     390×844 con la barra de un iPhone (93px): botón 730→774, barra desde 751.
     ⚠️ --nav-bot YA TRAE ADENTRO el env(safe-area-inset-bottom): sumárselo otra
     vez sería contarlo dos veces. El max() es la misma red de seguridad que usa
     .ag-foot por si la medición de la barra quedara corta. */
  #hist .hdbd{ overflow-y:auto;
    padding:14px 16px max(calc(24px + var(--nav-bot, 0px)),
                          calc(24px + 54px + env(safe-area-inset-bottom))); }
  #hist .hsec{ color:var(--d-mut); font-size:10.5px; letter-spacing:1.5px;
    text-transform:uppercase; margin:16px 0 8px; }
  #hist .hsec:first-child{ margin-top:0; }
  #hist .hfila{ display:flex; justify-content:space-between; gap:12px; padding:7px 0;
    border-bottom:1px solid var(--d-line); font-size:13px; }
  #hist .hfila .v{ font-family:var(--font-display,ui-monospace,Menlo,monospace); text-align:right; }
  #hist .hcu{ display:flex; gap:10px; padding:9px 0; }
  #hist .hcu .ico{ width:30px; height:30px; border-radius:9px; background:var(--d-card2);
    border:1px solid var(--d-line); display:flex; align-items:center; justify-content:center;
    flex:0 0 auto; font-size:14px; }
  #hist .hcu .tx{ flex:1; min-width:0; }
  #hist .hcu .tt{ font-size:13.5px; font-weight:600; display:flex; gap:7px;
    align-items:center; flex-wrap:wrap; }
  #hist .hcu .cd{ color:var(--d-mut); font-size:12px; margin-top:2px;
    font-family:var(--font-display,ui-monospace,Menlo,monospace); }
  #hist .hvb{ font-size:10.5px; background:color-mix(in srgb, var(--d-acc) 20%, transparent);
    color:var(--d-ink); border-radius:5px; padding:1px 6px;
    font-family:var(--font-display,ui-monospace,Menlo,monospace); }
  /* 🔴 EL BOTÓN MIDE 44×44 DE VERDAD y el espacio se devuelve con márgenes
     negativos. Con un ::after de 44px el área parece grande pero cualquier
     hermano posterior le pinta encima (un absoluto sin z-index no sube de plano)
     y el toque cae en el vecino. Agrandando la caja, el hit-test es del propio
     elemento y no depende del orden del DOM; el glifo sigue leyéndose de 12px. */
  #hist .hinfo{ background:none; border:0; color:var(--d-mut); cursor:pointer;
    font-size:12px; line-height:1; width:44px; height:44px; margin:-16px -14px; padding:0;
    display:inline-flex; align-items:center; justify-content:center; vertical-align:middle; }
  #hist .hinfo:focus-visible{ outline:2px solid var(--d-acc); outline-offset:-6px; border-radius:50%; }
  #hist .hinfo[aria-expanded="true"]{ color:var(--d-ink); }
  #hist .hnota{ background:var(--d-card2); border:1px solid var(--d-line); border-radius:9px;
    padding:9px 11px; margin:7px 0 0; font-size:12px; color:var(--d-dim); line-height:1.5; }
  #hist .hver{ display:flex; justify-content:space-between; gap:10px; padding:9px 11px;
    border-radius:9px; font-size:13px; align-items:center; }
  #hist .hver.act{ background:color-mix(in srgb, var(--d-acc) 14%, transparent); }
  /* El ojito de cada versión. 34px y no 44: vive en una fila densa, y el patrón
     del margen negativo no sirve acá porque la fila tiene fondo propio. */
  #hist .hvpv{ flex:0 0 auto; width:34px; height:34px; margin:-6px -4px -6px 4px;
    border:1px solid var(--d-line2); background:var(--d-card2); color:var(--d-ink);
    border-radius:9px; cursor:pointer; font-size:13px; line-height:1; }
  :where(html.puntero) #hist .hvpv:hover{ border-color:var(--d-acc); }
  #hist .hacc{ display:flex; gap:8px; flex-wrap:wrap; margin-top:14px; }
  #hist .hbtn{ border:1px solid var(--d-line2); background:var(--d-card2); color:var(--d-ink);
    border-radius:10px; padding:10px 14px; font-size:13px; cursor:pointer; font-family:inherit;
    min-height:44px; }
  #hist .hbtn.pri{ border-color:var(--d-acc);
    background:color-mix(in srgb, var(--d-acc) 18%, transparent); }
  #hist .hsolo{ color:var(--d-mut); font-size:12px; margin-top:10px; line-height:1.5; }

  @media (min-width:900px){
    #hist .hcols{ grid-template-columns:minmax(0,1fr) minmax(0,420px); gap:18px; align-items:start; }
    /* 🔴 EN ESCRITORIO EL DETALLE NO ES UN MODAL: es un panel al lado y la lista
       sigue siendo interactiva. Por eso acá el JS le saca aria-modal y le pone
       role="region" — anunciarlo como modal sería mentir sobre lo que se puede
       tocar. El velo tampoco va. */
    #hist .hdet{ position:sticky; top:calc(var(--nav-top) + 14px); max-height:calc(100vh - 130px);
      transform:none; border-radius:13px; border:1px solid var(--d-line); display:flex; }
    /* Acá el panel ya no toca el fondo de la pantalla: el aire de la barra sería
       un hueco muerto al final del scroll. */
    #hist .hdbd{ padding-bottom:22px; }
    #hist .hdvelo{ display:none !important; }
    #hist .hlista{ min-width:0; }
  }


  /* ===========================================================================
     EL DESGLOSE DE UNA CIFRA (10/09/2026) — la página que explica una tarjeta.
     ===========================================================================
     Vive fuera de #dash (colgado del body) pero usa su paleta (está en la lista de
     selectores de las variables --d-*). z-index 920: sobre el Panel (900) y DEBAJO
     de la barra de pestañas (950) —las pestañas siguen tocables y una lo cierra y
     navega—, y bajo Números (10050), la ficha (10060) y el agente (10070), que se
     abren desde acá. Reserva --nav-top/--nav-bot como el Panel.
     Entra desde la derecha como una página (transform), y con movimiento reducido
     aparece en seco con un fundido corto. */
  #desglose{ position:fixed; inset:0; z-index:920; display:none; overflow-y:auto; -webkit-overflow-scrolling:touch;
    background:var(--d-canvas); color:var(--d-ink);
    font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; font-size:12.5px;
    transform:translateX(100%); opacity:.98; overscroll-behavior:contain; }
  #desglose.on{ display:block; }
  #desglose.on.in{ transform:translateX(0); opacity:1; }
  #desglose.on{ transition:transform .3s cubic-bezier(.32,.72,0,1), opacity .2s; }
  @media (prefers-reduced-motion: reduce){
    #desglose{ transform:none; opacity:0; }
    #desglose.on{ transition:opacity .12s; }
    #desglose.on.in{ opacity:1; }
  }
  #desglose .vh{ position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
  #desglose .dg-top{ position:sticky; top:0; z-index:2; display:flex; align-items:center; gap:10px;
    padding:calc(10px + env(safe-area-inset-top) + var(--nav-top, 0px)) 14px 10px;
    background:color-mix(in srgb, var(--d-canvas) 88%, transparent); -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
    border-bottom:1px solid var(--d-line); }
  #desglose .dg-back{ display:inline-flex; align-items:center; gap:2px; min-height:40px; padding:0 12px 0 6px; border:0; border-radius:20px;
    background:var(--d-card2); color:var(--d-ink); font:inherit; font-size:13px; font-weight:600; cursor:pointer; }
  #desglose .dg-back .ico{ width:20px; height:20px; }
  :where(html.puntero) #desglose .dg-back:hover{ background:var(--d-card); }
  #desglose .dg-kicker{ font-size:10px; font-weight:700; letter-spacing:1.5px; text-transform:uppercase; color:var(--d-mut); flex:1; min-width:0; }
  #desglose .dg-acts{ display:flex; gap:6px; }
  #desglose .dg-acts .dchip, #desglose .dg-det .dchip{ border:0; background:var(--d-card2); color:var(--d-ink); border-radius:20px; padding:0 12px; min-height:36px;
    font:inherit; font-size:11.5px; font-weight:600; cursor:pointer; }
  #desglose .dg-wrap{ max-width:900px; margin:0 auto; padding:14px 14px calc(30px + env(safe-area-inset-bottom) + var(--nav-bot, 0px)); box-sizing:border-box; }
  #desglose .dg-hd{ padding:6px 2px 12px; }
  #desglose .dg-tit{ margin:0; font-size:22px; font-weight:700; letter-spacing:-.3px; line-height:1.15; }
  #desglose .dg-alc{ margin-top:5px; font-size:12px; color:var(--d-mut); }
  #desglose .dg-alc b{ color:var(--d-ink); font-family:var(--a-mono); font-weight:600; letter-spacing:.02em; }
  #desglose .dg-def{ margin:10px 0 0; font-size:12.5px; line-height:1.55; color:var(--d-dim); max-width:640px; }
  #desglose .dg-avisos:not(:empty){ margin-top:10px; display:flex; flex-direction:column; gap:6px; }
  #desglose .dg-aviso{ border-radius:10px; padding:9px 12px; font-size:12px; line-height:1.5; border:1px solid var(--d-line2); background:var(--d-card); }
  #desglose .dg-aviso.err{ border-color:color-mix(in srgb, var(--d-red) 45%, transparent); color:var(--d-red); }
  #desglose .dg-aviso.warn{ border-color:color-mix(in srgb, var(--d-amber) 45%, transparent); color:var(--d-amber); }
  #desglose .dg-aviso.info{ color:var(--d-mut); }
  #desglose .dg-hero{ display:flex; align-items:baseline; gap:12px; flex-wrap:wrap; margin-top:14px; }
  #desglose .dg-total{ font-family:var(--a-mono); font-size:30px; font-weight:700; font-variant-numeric:tabular-nums; letter-spacing:-.02em; }
  #desglose .dg-total small{ font-size:14px; color:var(--d-mut); font-weight:600; }
  #desglose .dg-n{ font-size:12.5px; color:var(--d-mut); }
  /* ---- herramientas ---- */
  #desglose .dg-tools{ display:flex; flex-direction:column; gap:10px; padding:10px 0 12px; position:sticky; top:calc(60px + env(safe-area-inset-top) + var(--nav-top, 0px)); z-index:1;
    background:var(--d-canvas); }
  #desglose .dg-buscar input{ width:100%; box-sizing:border-box; font:inherit; font-size:16px; min-height:44px; padding:0 14px; border-radius:12px;
    border:1px solid var(--d-line2); background:var(--d-card); color:var(--d-ink); -webkit-appearance:none; appearance:none; }
  #desglose .dg-buscar input:focus{ outline:none; border-color:var(--d-acc); }
  #desglose .dg-chips{ display:flex; flex-direction:column; gap:6px; }
  #desglose .dg-chipfila{ display:flex; gap:6px; overflow-x:auto; padding-bottom:2px; scrollbar-width:none; -webkit-overflow-scrolling:touch; }
  #desglose .dg-chipfila::-webkit-scrollbar{ display:none; }
  #desglose .dg-chip{ flex:none; display:inline-flex; align-items:center; gap:6px; min-height:36px; padding:0 12px; border-radius:18px;
    border:1px solid var(--d-line2); background:var(--d-card); color:var(--d-mut); font:inherit; font-size:11.5px; font-weight:600; cursor:pointer;
    transition:background .15s, color .15s, border-color .15s; white-space:nowrap; }
  #desglose .dg-chip.on{ background:var(--d-ink); color:var(--d-canvas); border-color:var(--d-ink); }
  #desglose .dg-chipfila.cifra .dg-chip.on{ background:var(--d-acc); border-color:var(--d-acc); color:#fff; }
  #desglose .dg-chip.vacio{ opacity:.5; }
  #desglose .dg-chip .pt{ width:8px; height:8px; border-radius:50%; display:inline-block; }
  #desglose .dg-chip.on .pt{ outline:2px solid color-mix(in srgb, var(--d-canvas) 70%, transparent); }
  #desglose .dg-orden{ display:flex; align-items:center; gap:8px; font-size:11.5px; color:var(--d-mut); }
  #desglose .dg-orden select{ font:inherit; font-size:16px; min-height:40px; padding:0 10px; border-radius:10px; border:1px solid var(--d-line2);
    background:var(--d-card); color:var(--d-ink); }
  #desglose .dg-dir{ width:40px; height:40px; border-radius:10px; border:1px solid var(--d-line2); background:var(--d-card); color:var(--d-ink); font-size:15px; cursor:pointer; }
  #desglose .dg-dir.inv{ background:var(--d-ink); color:var(--d-canvas); }
  /* ---- la lista ---- */
  #desglose .dg-list{ display:flex; flex-direction:column; gap:8px; }
  #desglose .dg-row{ background:var(--d-card); border:1px solid var(--d-line); border-radius:14px; padding:12px 14px; cursor:pointer;
    transition:border-color .15s, transform .12s; -webkit-tap-highlight-color:transparent; }
  #desglose .dg-row:active{ transform:scale(.992); }
  :where(html.puntero) #desglose .dg-row:hover{ border-color:var(--d-acc); }
  #desglose .dg-row:focus-visible{ outline:2px solid var(--d-acc); outline-offset:2px; }
  #desglose .dg-row.nocuenta{ opacity:.62; }
  #desglose .dg-r1{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; }
  #desglose .dg-cli{ font-size:14.5px; font-weight:700; min-width:0; overflow-wrap:anywhere; }
  #desglose .dg-monto{ font-family:var(--a-mono); font-size:15px; font-weight:700; font-variant-numeric:tabular-nums; flex:none; }
  #desglose .dg-r2{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; margin-top:4px; font-size:11.5px; color:var(--d-mut); }
  #desglose .dg-r2 .pt{ width:8px; height:8px; border-radius:50%; display:inline-block; flex:none; }
  #desglose .dg-r3{ display:flex; gap:14px; flex-wrap:wrap; margin-top:9px; }
  #desglose .dg-d{ display:flex; flex-direction:column; font-family:var(--a-mono); font-size:12.5px; font-variant-numeric:tabular-nums; }
  #desglose .dg-d small{ font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; font-size:9.5px; font-weight:700; letter-spacing:1px; text-transform:uppercase; color:var(--d-mut); }
  #desglose .dg-d em{ font-style:normal; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; font-size:10.5px; color:var(--d-mut); }
  #desglose .dg-d.pend{ color:var(--d-amber); }
  #desglose .dg-d.neg{ color:var(--d-red); }
  #desglose .dg-why{ margin-top:8px; font-size:11px; color:var(--d-mut); line-height:1.45; }
  #desglose .dg-det{ display:none; margin-top:10px; padding-top:10px; border-top:1px solid var(--d-line); gap:8px; flex-wrap:wrap; }
  #desglose .dg-row.abierto .dg-det{ display:flex; }
  #desglose .dg-det > div{ display:flex; flex-direction:column; min-width:120px; font-size:12.5px; }
  #desglose .dg-det small{ font-size:9.5px; font-weight:700; letter-spacing:1px; text-transform:uppercase; color:var(--d-mut); }
  #desglose .dg-sep{ margin:12px 2px 2px; font-size:10px; font-weight:700; letter-spacing:1.5px; text-transform:uppercase; color:var(--d-mut); }
  #desglose .dg-sep .dg-sub{ font-weight:600; letter-spacing:.3px; text-transform:none; font-size:11px; }
  #desglose .dg-vacio{ color:var(--d-mut); font-size:12.5px; padding:34px 14px; text-align:center; line-height:1.6; border:1px dashed var(--d-line2); border-radius:14px; }
  #desglose .dg-vacio b{ display:block; color:var(--d-ink); margin-bottom:4px; }
  /* ---- el pie verificable ---- */
  #desglose .dg-foot{ margin-top:14px; border-top:1px solid var(--d-line2); padding-top:12px; }
  #desglose .dg-suma{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; font-size:12px; color:var(--d-mut); }
  #desglose .dg-suma b{ font-family:var(--a-mono); color:var(--d-ink); font-variant-numeric:tabular-nums; }
  #desglose .dg-chk{ font-weight:700; }
  #desglose .dg-suma.ok .dg-chk{ color:var(--d-green); }
  #desglose .dg-suma.dif .dg-chk{ color:var(--d-amber); }
  #desglose .dg-celdas{ display:grid; grid-template-columns:repeat(auto-fit, minmax(130px, 1fr)); gap:8px; margin-top:10px; }
  #desglose .dg-celdas span{ display:flex; flex-direction:column; background:var(--d-card2); border-radius:10px; padding:9px 11px; font-family:var(--a-mono); font-size:12.5px; font-variant-numeric:tabular-nums; }
  #desglose .dg-celdas small{ font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; font-size:9.5px; font-weight:700; letter-spacing:1px; text-transform:uppercase; color:var(--d-mut); margin-bottom:3px; }
  #desglose .dg-celdas b{ font-weight:700; }
  @media (min-width:1024px){
    #desglose .dg-top{ padding-left:32px; padding-right:32px; }
    #desglose .dg-wrap{ padding-left:32px; padding-right:32px; }
    #desglose .dg-tools{ flex-direction:row; align-items:flex-start; flex-wrap:wrap; }
    #desglose .dg-buscar{ flex:1 1 260px; }
    #desglose .dg-chips{ flex:1 1 100%; }
  }
  /* ---- lo que se toca en el Panel para entrar (10/09/2026) ---- */
  #dash .dkpi.abre{ position:relative; cursor:pointer; padding-right:28px; -webkit-tap-highlight-color:transparent;
    transition:transform .12s, background .15s, box-shadow .15s; }
  #dash .dkpi.abre:active{ transform:scale(.985); }
  :where(html.puntero) #dash .dkpi.abre:hover{ background:color-mix(in srgb, var(--d-card2) 70%, var(--d-card)); box-shadow:inset 0 0 0 1px var(--d-line2); }
  #dash .dkpi.abre:focus-visible{ outline:2px solid var(--d-acc); outline-offset:2px; }
  #dash .dk-go{ position:absolute; right:12px; top:14px; width:8px; height:8px; border-right:2px solid var(--d-mut); border-bottom:2px solid var(--d-mut);
    transform:rotate(-45deg); opacity:.7; }
  #dash .dkpi.abre .dk-go{ top:15px; }
  #dash .dk-sub{ border:0; background:none; padding:0; margin:0; font:inherit; color:inherit; cursor:pointer; text-decoration:underline dotted; text-underline-offset:3px; }
  :where(html.puntero) #dash .dk-sub:hover{ color:var(--d-ink); }
  #dash .drech.abre{ position:relative; cursor:pointer; padding-right:28px; border-radius:10px; }
  #dash .drech.abre .dk-go{ top:50%; margin-top:-5px; }
  #dash .dw-lwrap{ display:flex; align-items:stretch; gap:4px; }
  #dash .dw-lwrap .dw-lrow{ flex:1; min-width:0; }
  #dash .dw-lgo{ flex:none; width:40px; border:0; background:none; color:var(--d-mut); cursor:pointer; position:relative; border-radius:8px; }
  #dash .dw-lgo .dk-go{ right:14px; top:50%; margin-top:-5px; }
  :where(html.puntero) #dash .dw-lgo:hover{ background:color-mix(in srgb, var(--t-ink) 6%, transparent); color:var(--d-ink); }
  #dash .dw-leg.elegido .dw-lgo{ opacity:.45; }
  #dash .dw-mid.puedeAbrir{ cursor:pointer; }
  #dash .dw-mid.puedeAbrir::after{ content:'Ver eventos ›'; display:block; margin-top:4px; font-size:10px; font-weight:700; letter-spacing:.6px; text-transform:uppercase; color:var(--d-acc); }
  :where(html.puntero) #dash .dw-mid.puedeAbrir:hover::after{ text-decoration:underline; }
  #numeros .dkpi.abre{ position:relative; cursor:pointer; padding-right:28px; -webkit-tap-highlight-color:transparent; transition:transform .12s; }
  #numeros .dkpi.abre:active{ transform:scale(.985); }
  #numeros .dkpi.abre:focus-visible{ outline:2px solid var(--a-acc); outline-offset:2px; }
  #numeros .dk-go{ position:absolute; right:12px; top:15px; width:8px; height:8px; border-right:2px solid var(--a-mut); border-bottom:2px solid var(--a-mut); transform:rotate(-45deg); opacity:.7; }

  /* ---- Reuniones en la ficha (10/09/2026) ---- */
  #dashFicha .freu{ display:flex; flex-direction:column; gap:8px; }
  #dashFicha .freu-item{ display:flex; align-items:flex-start; gap:10px; padding:10px 12px; border-radius:10px; background:var(--d-card2); border-left:3px solid var(--d-reunion); }
  #dashFicha .freu-item .fecha{ font-family:var(--a-mono); font-size:12.5px; font-weight:700; white-space:nowrap; }
  #dashFicha .freu-item .det{ flex:1; min-width:0; font-size:12.5px; line-height:1.45; }
  #dashFicha .freu-item .det small{ display:block; color:var(--d-mut); font-size:11.5px; }
  #dashFicha .freu-item .ag-act{ flex:none; min-height:36px; }
  #dashFicha .freu-vacio{ color:var(--d-mut); font-size:12px; line-height:1.5; }
  #dashFicha .freu-alta .dlink{ min-height:40px; display:inline-flex; align-items:center; }
  #dashFicha .freu-form{ display:grid; grid-template-columns:1fr 1fr; gap:8px; margin-top:8px; }
  /* 23/09/2026: el display de arriba le ganaba al atributo hidden (el mismo choque que
     .ftar-form): el formulario de reunión estaba SIEMPRE abierto y "Cancelar" no hacía nada. */
  #dashFicha .freu-form[hidden], #dashFicha .freu-alta .dlink[hidden]{ display:none !important; }
  #dashFicha .freu-form label{ display:flex; flex-direction:column; gap:4px; font-size:10.5px; font-weight:700; letter-spacing:1px; text-transform:uppercase; color:var(--d-mut); }
  #dashFicha .freu-form label.full{ grid-column:1/-1; }
  #dashFicha .freu-form input, #dashFicha .freu-form textarea{ font:inherit; font-size:16px; min-height:44px; padding:8px 12px; border-radius:10px; border:1px solid var(--d-line2); background:var(--d-card); color:var(--d-ink); box-sizing:border-box; width:100%; -webkit-appearance:none; appearance:none; }
  #dashFicha .freu-form textarea{ min-height:64px; resize:vertical; }
  #dashFicha .freu-form .btns{ grid-column:1/-1; display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
  #dashFicha .freu-form .btns .fpg-msg{ flex:1 1 100%; }
  #dashFicha .freu-ver{ margin:0 0 12px; }

  /* ===========================================================================
     CHECKLIST TÉCNICA (14/09/2026) — la vista interna que se abre desde la ficha.
     Es una "página adentro de la página" como el Desglose (mismo patrón: entra
     deslizando, Volver por el carrusel, Escape). Va ENCIMA de la ficha (10060) y
     del chat (10070/10072): 10075, debajo del modo evento (10080) y del velo de
     contraseña. La ficha queda abierta debajo: al volver está como estaba.
     Paleta del Panel (--d-*), igual que la ficha de la que sale.
     =========================================================================== */
  #chkVista{
    --d-canvas:var(--t-panel-bg); --d-card:var(--t-panel-surface); --d-card2:var(--t-panel-surface-2); --d-line:var(--t-panel-line);
    --d-line2:var(--t-panel-line-2); --d-ink:var(--t-panel-ink); --d-fg:var(--t-panel-ink); --d-mut:var(--t-panel-muted); --d-dim:var(--t-panel-dim);
    --d-acc:var(--t-panel-accent); --d-red:var(--t-err); --d-amber:var(--t-warn); --d-green:var(--t-ok);
    position:fixed; inset:0; z-index:10075; display:none; overflow-y:auto; -webkit-overflow-scrolling:touch;
    background:var(--d-canvas); color:var(--d-ink);
    font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; font-size:13px;
    transform:translateX(24px); opacity:0; }
  #chkVista.on{ display:block; transition:transform .3s cubic-bezier(.32,.72,0,1), opacity .2s; }
  #chkVista.on.in{ transform:translateX(0); opacity:1; }
  @media (prefers-reduced-motion: reduce){
    #chkVista{ transform:none; opacity:0; }
    #chkVista.on{ transition:opacity .12s; }
    #chkVista.on.in{ opacity:1; }
  }
  #chkVista .chk-top{ position:sticky; top:0; z-index:2; display:flex; align-items:center; gap:10px;
    padding:calc(8px + env(safe-area-inset-top)) 10px 8px; background:color-mix(in srgb, var(--d-canvas) 88%, transparent);
    -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px); border-bottom:1px solid var(--d-line); }
  #chkVista .chk-back{ display:inline-flex; align-items:center; gap:2px; min-height:40px; padding:0 12px 0 6px; border:0; border-radius:20px;
    background:transparent; color:var(--d-acc); font:inherit; font-size:14px; font-weight:600; cursor:pointer; }
  #chkVista .chk-back .ico{ width:20px; height:20px; }
  :where(html.puntero) #chkVista .chk-back:hover{ background:var(--d-card); }
  #chkVista .chk-kicker{ font-size:10px; font-weight:700; letter-spacing:1.5px; text-transform:uppercase; color:var(--d-mut); flex:1; min-width:0; }
  #chkVista .chk-wrap{ max-width:760px; margin:0 auto; padding:14px 16px calc(150px + env(safe-area-inset-bottom)); box-sizing:border-box; }
  #chkVista .chk-tit{ margin:0; font-size:21px; font-weight:700; letter-spacing:-.3px; line-height:1.15; text-wrap:balance; }
  #chkVista .chk-sub{ margin-top:5px; font-size:12px; color:var(--d-mut); }
  #chkVista .chk-aviso{ margin:12px 0 0; border-radius:10px; padding:11px 13px; font-size:12.5px; line-height:1.5;
    border:1px solid color-mix(in srgb, var(--d-amber) 45%, transparent); color:var(--d-amber); background:var(--d-card); }
  #chkVista .chk-meta{ margin:14px 0 0; display:grid; grid-template-columns:auto 1fr; gap:6px 14px; font-size:12.5px; line-height:1.45; }
  #chkVista .chk-meta dt{ color:var(--d-mut); font-size:11px; text-transform:uppercase; letter-spacing:.8px; padding-top:2px; }
  #chkVista .chk-meta dd{ margin:0; color:var(--d-ink); overflow-wrap:anywhere; }
  #chkVista .chk-toggle{ display:flex; align-items:center; gap:10px; margin:16px 0 4px; padding:10px 12px; border-radius:10px;
    background:var(--d-card); border:1px solid var(--d-line2); font-size:12.5px; cursor:pointer; min-height:44px; box-sizing:border-box; }
  #chkVista .chk-toggle input{ width:18px; height:18px; margin:0; accent-color:var(--d-acc); }
  #chkVista .chk-grupo{ margin-top:16px; }
  #chkVista .chk-gname{ font-size:10.5px; font-weight:700; letter-spacing:1.4px; text-transform:uppercase; color:var(--d-mut);
    padding:0 0 6px; border-bottom:1px solid var(--d-line2); }
  #chkVista .chk-row{ display:flex; align-items:center; gap:10px; min-height:46px; padding:6px 4px; border-bottom:1px solid var(--d-line);
    cursor:pointer; font-size:14px; }
  #chkVista .chk-row.sub{ padding-left:34px; min-height:36px; font-size:13px; color:var(--d-dim); cursor:default; }
  #chkVista .chk-row.pack .chk-n{ color:var(--d-ink); }
  #chkVista .chk-row input{ width:22px; height:22px; margin:0; flex:none; accent-color:var(--d-green); }
  #chkVista .chk-row.on .chk-n{ text-decoration:line-through; color:var(--d-mut); }
  #chkVista .chk-q{ flex:none; min-width:38px; text-align:right; font-family:var(--a-mono); font-weight:700; font-variant-numeric:tabular-nums; }
  #chkVista .chk-n{ flex:1; min-width:0; overflow-wrap:anywhere; line-height:1.3; }
  #chkVista .chk-n small{ color:var(--d-mut); font-size:11px; }
  #chkVista .chk-sku{ display:block; font-family:var(--a-mono); letter-spacing:.02em; }
  #chkVista .chk-tag{ display:inline-block; margin-left:8px; padding:1px 7px; border-radius:9px; font-size:10px; letter-spacing:.4px;
    text-transform:uppercase; background:var(--d-card2); color:var(--d-mut); vertical-align:middle; }
  #chkVista .chk-nota{ margin:16px 0 0; font-size:12px; color:var(--d-mut); line-height:1.5; }
  /* la barra de acciones, pegada abajo y encima del indicador de inicio */
  #chkVista .chk-acts{ position:fixed; left:0; right:0; bottom:0; z-index:3; padding:10px 12px calc(12px + env(safe-area-inset-bottom));
    background:color-mix(in srgb, var(--d-canvas) 92%, transparent); -webkit-backdrop-filter:blur(14px); backdrop-filter:blur(14px);
    border-top:1px solid var(--d-line); }
  #chkVista .chk-btns{ display:grid; grid-template-columns:repeat(2, 1fr); gap:8px; max-width:760px; margin:0 auto; }
  #chkVista .chk-btn{ min-height:44px; padding:0 12px; border-radius:12px; border:1px solid var(--d-line2); background:var(--d-card);
    color:var(--d-ink); font:inherit; font-size:13px; font-weight:600; cursor:pointer; }
  #chkVista .chk-btn.p{ grid-column:1 / -1; background:var(--d-acc); border-color:var(--d-acc); color:var(--t-on-accent); font-size:15px; min-height:50px; }
  /* WhatsApp (15/09/2026): el logo en PNG al lado del texto. Sin la hoja de compartir (Copiar pasa
     a ser la principal), WhatsApp ocupa su propia fila para que no quede un botón suelto. */
  #chkVista .chk-btn.wa:not([hidden]){ display:flex; align-items:center; justify-content:center; gap:8px; }
  #chkVista .chk-btn.wa img{ width:22px; height:22px; flex:none; }
  #chkVista .chk-btns:has(#chkCompartir[hidden]) .chk-btn.wa{ grid-column:1 / -1; }
  #chkVista .chk-btn[hidden]{ display:none; }
  #chkVista .chk-btn:disabled{ opacity:.45; cursor:default; }
  :where(html.puntero) #chkVista .chk-btn:not(:disabled):hover{ border-color:var(--d-acc); }
  #chkVista .chk-msg{ max-width:760px; margin:0 auto 8px; font-size:12px; line-height:1.4; min-height:0; color:var(--d-mut); }
  #chkVista .chk-msg:empty{ display:none; }
  #chkVista .chk-msg.ok{ color:var(--d-green); }
  #chkVista .chk-msg.mal{ color:var(--d-red); }
  #chkVista :is(button, input):focus-visible{ outline:2px solid var(--d-acc); outline-offset:2px; }
  @media (min-width:700px){
    #chkVista .chk-btns{ grid-template-columns:2fr 1fr 1fr 1fr 1fr; }
    #chkVista .chk-btn.p{ grid-column:auto; font-size:14px; min-height:44px; }
    #chkVista .chk-btns:has(#chkCompartir[hidden]){ grid-template-columns:repeat(4, 1fr); }
    #chkVista .chk-btns:has(#chkCompartir[hidden]) .chk-btn.wa{ grid-column:auto; }
  }

  /* ---- impresión de la checklist: A4, casilleros grandes, sin fondos, filas enteras ---- */
  #chkPrint{ display:none; }
  @media print{
    html.chk-imprimiendo body > *:not(#chkPrint){ display:none !important; }
    html.chk-imprimiendo #chkPrint{ display:block; color:black; background:white; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; font-size:11pt; }
    html.chk-imprimiendo{ background:white; }
    @page{ size:A4 portrait; margin:14mm 14mm 16mm; }
    #chkPrint .chk-print-hd h1{ margin:0; font-size:16pt; letter-spacing:.06em; }
    #chkPrint .chk-print-hd div{ margin-top:3pt; font-size:10.5pt; color:color-mix(in srgb, black 80%, white); }
    #chkPrint .chk-print-meta{ margin:10pt 0 0; display:grid; grid-template-columns:auto 1fr; gap:2pt 10pt; font-size:10pt; }
    #chkPrint .chk-print-meta dt{ font-weight:700; }
    #chkPrint .chk-print-meta dd{ margin:0; }
    #chkPrint .chk-print-aviso{ font-style:italic; color:color-mix(in srgb, black 75%, white); }
    #chkPrint .chk-print-t{ width:100%; border-collapse:collapse; margin-top:12pt; }
    #chkPrint .chk-print-t thead{ display:table-header-group; }
    #chkPrint .chk-print-t th{ text-align:left; font-size:8pt; letter-spacing:.06em; text-transform:uppercase; border-bottom:1.2pt solid black; padding:4pt 3pt; }
    #chkPrint .chk-print-t th.c, #chkPrint .chk-print-t td.c{ width:34pt; text-align:center; }
    #chkPrint .chk-print-t th.q, #chkPrint .chk-print-t td.q{ width:38pt; text-align:right; font-weight:700; white-space:nowrap; }
    #chkPrint .chk-print-t td{ padding:6pt 3pt; border-bottom:.5pt solid silver; vertical-align:middle; }
    #chkPrint .chk-print-t tr{ break-inside:avoid; page-break-inside:avoid; }
    #chkPrint .chk-print-t tr.g td{ font-weight:700; font-size:9.5pt; letter-spacing:.08em; border-bottom:1pt solid black; padding-top:12pt; break-after:avoid; page-break-after:avoid; }
    #chkPrint .chk-print-t tr.p td{ border-bottom:0; break-after:avoid; page-break-after:avoid; }
    #chkPrint .chk-print-t tr.s td:nth-child(2){ padding-left:14pt; }
    #chkPrint .bx{ display:inline-block; width:13pt; height:13pt; border:1pt solid black; border-radius:2pt; vertical-align:middle; }
    #chkPrint .bx.on{ background:linear-gradient(45deg, transparent 42%, black 42%, black 58%, transparent 58%); }
    #chkPrint .chk-print-h2{ margin:16pt 0 6pt; font-size:10pt; letter-spacing:.08em; border-bottom:1pt solid black; break-after:avoid; page-break-after:avoid; }
    #chkPrint .chk-print-ctrl{ list-style:none; margin:0; padding:0; }
    #chkPrint .chk-print-ctrl li{ display:flex; align-items:center; gap:8pt; padding:5pt 0; break-inside:avoid; }
    #chkPrint .chk-print-cierre{ margin:12pt 0 0; display:grid; grid-template-columns:auto 1fr; gap:10pt 8pt; align-items:end; }
    #chkPrint .chk-print-cierre dt{ font-weight:600; }
    #chkPrint .chk-print-cierre dd{ margin:0; border-bottom:.6pt solid black; min-height:14pt; }
    #chkPrint .chk-print-cierre dd.alta{ min-height:42pt; }
  }

  /* ===========================================================================
     LA BURBUJA DEL AGENTE PRO Y SU GLOBO (fase 2, 14/09/2026). Solo teléfono.
     La burbuja va con transform (la posición la escribe el JS), por encima del
     contenido y de la tab bar, por debajo de las capas que la tapan (ficha 10060,
     chat 10070…): cuando una de esas está abierta el JS la esconde igual.
     =========================================================================== */
  #agBurbuja{
    position:fixed; left:0; top:0; z-index:10030; width:56px; height:56px; border-radius:50%; padding:0; margin:0;
    border:1px solid color-mix(in srgb, var(--t-accent) 45%, var(--t-line-2)); background:var(--t-surface-1);
    box-shadow:0 8px 24px -8px color-mix(in srgb, var(--t-accent) 55%, transparent), 0 2px 8px color-mix(in srgb, black 35%, transparent);
    display:grid; place-items:center; cursor:grab; touch-action:none; -webkit-user-select:none; user-select:none; -webkit-tap-highlight-color:transparent;
    transition:transform .32s cubic-bezier(.32,.72,0,1), opacity .2s; will-change:transform; }
  #agBurbuja[hidden]{ display:none; }
  #agBurbuja.sinanim{ transition:opacity .2s; }
  #agBurbuja.arrastrando{ cursor:grabbing; box-shadow:0 14px 34px -10px color-mix(in srgb, var(--t-accent) 70%, transparent); }
  #agBurbuja .agente-orbe{ width:42px; height:42px; pointer-events:none; }
  /* el muelle: el aro punteado en la esquina del Panel donde se deja la burbuja */
  #dash .ddock{ width:46px; height:46px; border-radius:50%; border:1.5px dashed color-mix(in srgb, var(--d-acc) 55%, transparent);
    background:color-mix(in srgb, var(--d-acc) 8%, transparent); transition:border-color .2s, background .2s, box-shadow .2s, opacity .2s; }
  #dash .ddock.cerca{ border-style:solid; border-color:var(--d-acc); background:color-mix(in srgb, var(--d-acc) 18%, transparent);
    box-shadow:0 0 0 8px color-mix(in srgb, var(--d-acc) 22%, transparent); }
  #dash .ddock.ocupado{ opacity:0; }
  #agBurbuja .pt{ position:absolute; top:3px; right:3px; width:12px; height:12px; border-radius:50%; background:var(--t-warn); border:2px solid var(--t-surface-1); }
  #agBurbuja .pt[hidden]{ display:none; }
  /* el latido: dos pulsos y quieta. Solo cuando hay algo que decir. */
  #agBurbuja.late{ animation:burPulso .8s ease-in-out 2; }
  @keyframes burPulso{ 0%,100%{ box-shadow:0 8px 24px -8px color-mix(in srgb, var(--t-accent) 55%, transparent), 0 0 0 0 color-mix(in srgb, var(--t-accent) 55%, transparent); }
                       50%{ box-shadow:0 8px 24px -8px color-mix(in srgb, var(--t-accent) 55%, transparent), 0 0 0 14px color-mix(in srgb, var(--t-accent) 0%, transparent); } }
  /* hablando: por encima del velo, el logo un poco más grande. ⚠️ Se agranda el LOGO y no la
     burbuja: la propiedad `scale` se compone DESPUÉS de `transform`, así que escalar la burbuja
     multiplicaba también su translate y la corría 30px (medido en WebKit). */
  #agBurbuja.hablando{ z-index:10091; border-color:var(--t-accent); }
  #agBurbuja.hablando .agente-orbe{ scale:1.12; transition:scale .25s ease; }
  /* 🔴 EL DESENFOQUE ES PROGRESIVO (14/09/2026, Tobi: "que la animación del fondo
     desenfocado sea progresiva"). Antes el contenedor hacía un fundido de .22s con el
     velo YA desenfocado a 14px: el blur aparecía de golpe. Ahora el contenedor no se
     funde; el VELO arranca nítido y transparente y crece hasta blur(14px) + tinte en
     .42s, la tarjeta entra un poco después, y al cerrar se deshace igual (el JS saca el
     nodo a los 460ms, cuando ya terminó). Mientras sale no ataja toques. */
  #agGlobo{ position:fixed; inset:0; z-index:10090; }
  #agGlobo:not(.in){ pointer-events:none; }
  #agGlobo .ag-velo{ position:absolute; inset:0; background-color:color-mix(in srgb, var(--t-bg) 0%, transparent); -webkit-backdrop-filter:blur(0px) saturate(1); backdrop-filter:blur(0px) saturate(1);
    transition:background-color .42s cubic-bezier(.3,.6,.2,1), -webkit-backdrop-filter .42s cubic-bezier(.3,.6,.2,1), backdrop-filter .42s cubic-bezier(.3,.6,.2,1); }
  #agGlobo.in .ag-velo{ background-color:color-mix(in srgb, var(--t-bg) 55%, transparent); -webkit-backdrop-filter:blur(14px) saturate(1.1); backdrop-filter:blur(14px) saturate(1.1); }
  #agGlobo .ag-card{ position:absolute; width:min(340px, calc(100vw - 20px)); box-sizing:border-box; padding:16px 16px 12px; border-radius:18px;
    background:var(--t-surface); border:1px solid var(--t-line-2); color:var(--t-ink); box-shadow:0 18px 50px -18px color-mix(in srgb, black 70%, transparent);
    font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; transform:translateY(8px) scale(.98); opacity:0; transition:transform .32s cubic-bezier(.2,.7,.2,1), opacity .24s ease; }
  #agGlobo.in .ag-card{ transform:none; opacity:1; transition-delay:.08s; }
  /* la colita, hacia la burbuja */
  #agGlobo .ag-card::before{ content:''; position:absolute; width:14px; height:14px; background:var(--t-surface); border:1px solid var(--t-line-2); border-right:0; border-bottom:0; transform:rotate(45deg); }
  #agGlobo .ag-card[data-vertical="abajo"]::before{ top:-8px; }
  #agGlobo .ag-card[data-vertical="arriba"]::before{ bottom:-8px; transform:rotate(225deg); }
  #agGlobo .ag-card[data-lado="der"]::before{ right:22px; }
  #agGlobo .ag-card[data-lado="izq"]::before{ left:22px; }
  #agGlobo .ag-txt{ font-size:16px; line-height:1.4; font-weight:600; min-height:22px; text-wrap:balance; }
  #agGlobo .ag-txt.escribiendo::after{ content:''; display:inline-block; width:2px; height:1em; margin-left:2px; background:var(--t-accent); vertical-align:-2px; animation:burCursor .8s steps(2) infinite; }
  @keyframes burCursor{ to{ opacity:0; } }
  #agGlobo .ag-sub{ margin-top:4px; font-size:12.5px; color:var(--t-muted); font-family:'SFMono-Regular',Menlo,monospace; }
  #agGlobo .ag-sub:empty{ display:none; }
  #agGlobo .ag-acts{ display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }
  #agGlobo .ag-chip{ min-height:40px; padding:0 14px; border-radius:20px; border:1px solid var(--t-line-2); background:var(--t-surface-2); color:var(--t-ink); font:inherit; font-size:13.5px; font-weight:600; cursor:pointer; }
  #agGlobo .ag-chip.p{ background:var(--t-accent); border-color:var(--t-accent); color:var(--t-on-accent); }
  #agGlobo .ag-chip.dim{ background:transparent; color:var(--t-muted); }
  #agGlobo .ag-pie{ display:flex; align-items:center; justify-content:space-between; gap:8px; margin-top:12px; padding-top:10px; border-top:1px solid var(--t-line); }
  #agGlobo .ag-n{ font-size:11.5px; color:var(--t-muted); display:flex; align-items:center; gap:6px; }
  #agGlobo .ag-btn{ min-height:36px; padding:0 8px; border:0; background:transparent; color:var(--t-accent); font:inherit; font-size:13.5px; font-weight:600; cursor:pointer; }
  #agGlobo .ag-btn.dim{ color:var(--t-muted); }
  #agGlobo :is(button):focus-visible{ outline:2px solid var(--t-accent); outline-offset:2px; }
  @media (prefers-reduced-motion:reduce){
    #agBurbuja{ transition:none; } #agBurbuja.late{ animation:none; }
    #agGlobo, #agGlobo .ag-velo, #agGlobo .ag-card{ transition:none; } #agGlobo .ag-txt.escribiendo::after{ animation:none; }
  }

  /* ===========================================================================
     EL MODO VOZ (14/09/2026). Pantalla grande y simple encima del chat: el orbe
     late mientras escucha, lo que decís se va escribiendo, la respuesta se lee.
     Por encima del chat (10070) y de la burbuja (10091 hablando), debajo del velo de
     contraseña. Paleta del cajón (--a-*) via #chatIA no aplica acá: usa --t-*.
     =========================================================================== */
  #vozModo{ position:fixed; inset:0; z-index:10095; display:none; flex-direction:column; background:var(--t-panel-bg); color:var(--t-panel-ink);
    font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif; }
  #vozModo.on{ display:flex; }
  #vozModo .vz-top{ display:flex; align-items:center; justify-content:space-between; padding:calc(10px + env(safe-area-inset-top)) 12px 8px 18px; }
  #vozModo .vz-k{ font-size:11px; font-weight:700; letter-spacing:1.6px; text-transform:uppercase; color:var(--t-panel-muted); }
  #vozModo .vz-x{ width:40px; height:40px; border-radius:50%; border:1px solid var(--t-panel-line-2); background:transparent; color:var(--t-panel-ink); font:inherit; font-size:16px; cursor:pointer; }
  #vozModo .vz-centro{ flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:16px; padding:0 22px; text-align:center; min-height:0; }
  #vozModo .vz-orbe{ width:150px; height:150px; border-radius:50%; border:0; background:transparent; padding:0; cursor:pointer; display:grid; place-items:center; -webkit-tap-highlight-color:transparent; }
  #vozModo .vz-orbe .agente-orbe{ width:140px; height:140px; transition:scale .3s ease; }
  /* sin blur en el orbe grande: un blur de 8px girando a 140px es carísimo en el iPhone */
  #vozModo .vz-orbe .agente-orbe::before{ filter:blur(4px); }
  #vozModo.escuchando .vz-orbe .agente-orbe{ animation:vzLate 1.4s ease-in-out infinite; }
  #vozModo.pensando .vz-orbe .agente-orbe{ scale:.85; opacity:.85; }
  #vozModo.hablando .vz-orbe .agente-orbe{ animation:vzHabla .9s ease-in-out infinite; }
  @keyframes vzLate{ 0%,100%{ scale:1; } 50%{ scale:1.1; } }
  @keyframes vzHabla{ 0%,100%{ scale:1; } 30%{ scale:1.06; } 60%{ scale:.97; } }
  #vozModo .vz-estado{ font-size:15px; color:var(--t-panel-muted); min-height:22px; }
  #vozModo .vz-oido{ font-size:22px; font-weight:600; line-height:1.3; text-wrap:balance; min-height:30px; max-width:620px; }
  #vozModo .vz-oido:not(:empty)::before{ content:'“'; color:var(--t-panel-muted); } #vozModo .vz-oido:not(:empty)::after{ content:'”'; color:var(--t-panel-muted); }
  #vozModo .vz-resp{ font-size:18px; line-height:1.45; color:var(--t-panel-dim); max-width:620px; max-height:38vh; overflow-y:auto; white-space:pre-wrap; }
  #vozModo .vz-centro{ padding-bottom:calc(24px + env(safe-area-inset-bottom)); }
  /* La voz elegible (15/09/2026): botón "Voz" arriba y hoja con voz, tono, ritmo y Probar. Solo tokens. */
  #vozModo .vz-top-der{ display:flex; align-items:center; gap:8px; }
  #vozModo .vz-cfg{ height:40px; padding:0 14px; border-radius:20px; border:1px solid var(--t-panel-line-2); background:transparent; color:var(--t-panel-ink); font:inherit; font-size:14px; font-weight:600; cursor:pointer; }
  #vozModo .vz-cfg[aria-expanded="true"]{ background:var(--t-panel-surface-2); }
  #vozModo .vz-aj{ position:absolute; inset:0; z-index:2; display:flex; align-items:flex-end; justify-content:center; background:color-mix(in srgb, var(--t-panel-bg) 55%, transparent); -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); }
  #vozModo .vz-aj[hidden]{ display:none; }
  #vozModo .vz-aj-caja{ width:min(520px, 100%); box-sizing:border-box; background:var(--t-panel-surface); border-top:1px solid var(--t-panel-line-2); border-radius:20px 20px 0 0; padding:14px 18px calc(18px + env(safe-area-inset-bottom)); display:grid; gap:8px; }
  @media (min-width:600px){ #vozModo .vz-aj{ align-items:center; } #vozModo .vz-aj-caja{ border-radius:20px; border:1px solid var(--t-panel-line-2); padding-bottom:18px; } }
  #vozModo .vz-aj-hd{ display:flex; align-items:center; justify-content:space-between; font-size:17px; }
  #vozModo .vz-aj-listo{ min-height:40px; padding:0 10px; border:0; background:transparent; color:var(--t-panel-accent); font:inherit; font-size:16px; font-weight:700; cursor:pointer; }
  #vozModo .vz-aj-l{ font-size:11px; font-weight:700; letter-spacing:1.4px; text-transform:uppercase; color:var(--t-panel-muted); margin-top:6px; }
  #vozModo .vz-sel{ width:100%; min-height:48px; font:inherit; font-size:16px; color:var(--t-panel-ink); background:var(--t-panel-surface-2); border:1px solid var(--t-panel-line-2); border-radius:12px; padding:0 12px; }
  #vozModo .vz-aj-nota{ margin:2px 0 0; font-size:13.5px; line-height:1.4; color:var(--t-panel-muted); }
  /* la voz en vivo (15/09/2026): el panel creció, así que se desplaza si no entra */
  #vozModo .vz-aj-caja{ max-height:calc(100dvh - 40px - env(safe-area-inset-top)); overflow-y:auto; overscroll-behavior:contain; }
  #vozModo.vivo .vz-k{ color:var(--t-panel-accent); }
  #vozModo :is(button):focus-visible{ outline:2px solid var(--t-panel-accent); outline-offset:2px; }
  @media (prefers-reduced-motion:reduce){ #vozModo.escuchando .vz-orbe .agente-orbe, #vozModo.hablando .vz-orbe .agente-orbe{ animation:none; } }

/* ==================== VOLCADO DE REUNIÓN (21/09/2026) ====================
   Una hoja a pantalla completa, por encima de la ficha (10060; 10072 cuando se abrió desde el chat)
   y del chat (10070), y por debajo del modo evento (10080): se abre desde la ficha, esté donde esté.
   Una sola tarea por paso. El botón principal vive ARRIBA, en el encabezado: con el teclado
   abierto es lo único que iOS nunca tapa. Texto de 17 px (sin zoom al enfocar), todo ≥ 44 pt. */
#volcado{ position:fixed; inset:0; z-index:10075; display:flex; flex-direction:column; background:var(--t-bg); color:var(--t-ink);
  transform:translateY(100%); visibility:hidden; transition:transform .28s cubic-bezier(.2,.8,.2,1), visibility 0s .28s; font-family:inherit; }
#volcado.open{ transform:none; visibility:visible; transition:transform .28s cubic-bezier(.2,.8,.2,1); }
@media (prefers-reduced-motion:reduce){ #volcado, #volcado.open{ transition:none; } }
html.vo-abierto{ overflow:hidden; }
#volcado .vo-hd{ display:flex; align-items:center; gap:10px; padding:calc(8px + env(safe-area-inset-top,0px)) 14px 8px; border-bottom:1px solid var(--t-line); flex:none; }
#volcado .vo-x{ width:44px; height:44px; flex:none; border:0; border-radius:50%; background:transparent; color:var(--t-dim); font-size:18px; cursor:pointer; }
#volcado .vo-tt{ min-width:0; flex:1; display:grid; }
#volcado .vo-tt h2{ margin:0; font-size:17px; font-weight:700; letter-spacing:-.01em; }
#volcado .vo-tt span{ font-size:13px; color:var(--t-dim); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#volcado .vo-pri{ min-height:44px; padding:0 18px; border:0; border-radius:999px; background:var(--t-accent); color:var(--t-on-accent); font:inherit; font-size:15px; font-weight:700; cursor:pointer; white-space:nowrap; }
#volcado .vo-pri:disabled{ opacity:.4; cursor:default; }
#volcado .vo-sec{ min-height:44px; padding:0 16px; border:1px solid var(--t-line); border-radius:999px; background:transparent; color:var(--t-ink); font:inherit; font-size:14.5px; font-weight:600; cursor:pointer; }
#volcado .vo-link{ border:0; background:transparent; color:var(--t-accent); font:inherit; font-size:13.5px; font-weight:600; min-height:36px; padding:0 2px; cursor:pointer; }
#volcado .vo-link:disabled{ opacity:.4; }
#volcado .vo-body{ flex:1; min-height:0; overflow-y:auto; -webkit-overflow-scrolling:touch; display:flex; flex-direction:column; gap:10px;
  padding:14px 16px calc(16px + env(safe-area-inset-bottom,0px)); width:100%; max-width:720px; margin:0 auto; box-sizing:border-box; }
#volcado .vo-lab{ font-size:15px; font-weight:600; line-height:1.35; }
#volcado .vo-ta{ flex:1; min-height:220px; width:100%; box-sizing:border-box; resize:none; padding:14px; border-radius:14px; border:1px solid var(--t-line); background:var(--t-input); color:var(--t-ink);
  font:inherit; font-size:17px; line-height:1.5; }
#volcado .vo-ta:focus, #volcado .vo-in:focus{ outline:2px solid var(--t-focus); outline-offset:1px; }
#volcado .vo-in{ width:100%; box-sizing:border-box; min-height:48px; padding:0 14px; border-radius:12px; border:1px solid var(--t-line); background:var(--t-input); color:var(--t-ink); font:inherit; font-size:17px; }
#volcado .vo-pie{ display:flex; justify-content:space-between; align-items:center; gap:10px; flex-wrap:wrap; font-size:12.5px; color:var(--t-dim); }
#volcado .vo-err{ padding:12px 14px; border-radius:12px; font-size:14px; line-height:1.45; background:color-mix(in srgb, var(--t-err) 10%, transparent); border:1px solid color-mix(in srgb, var(--t-err) 40%, transparent); }
#volcado .vo-lista{ display:grid; gap:8px; }
#volcado .vo-ev{ display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%; min-height:60px; padding:10px 14px; text-align:left; border:1px solid var(--t-line); border-radius:14px; background:transparent; color:var(--t-ink); font:inherit; cursor:pointer; }
#volcado .vo-ev:active{ border-color:var(--t-accent); }
#volcado .vo-ev span{ display:grid; gap:2px; min-width:0; } #volcado .vo-ev b{ font-size:15.5px; } #volcado .vo-ev em{ font-style:normal; font-size:13px; color:var(--t-dim); }
#volcado .vo-chip{ font-style:normal; font-size:11.5px; font-weight:700; padding:3px 9px; border-radius:999px; color:var(--t-accent); background:color-mix(in srgb, var(--t-accent) 14%, transparent); flex:none; }
#volcado .vo-vacio{ padding:22px 8px; text-align:center; font-size:14px; color:var(--t-dim); line-height:1.5; }
#volcado .vo-espera, #volcado .vo-listo{ margin:auto; display:grid; justify-items:center; gap:8px; text-align:center; padding:24px 8px; }
#volcado .vo-espera b, #volcado .vo-listo b{ font-size:17px; } #volcado .vo-espera span, #volcado .vo-listo span{ font-size:14px; color:var(--t-dim); line-height:1.45; }
#volcado .vo-espera i{ width:34px; height:34px; border-radius:50%; border:3px solid var(--t-line); border-top-color:var(--t-accent); animation:voGira .9s linear infinite; }
@keyframes voGira{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce){ #volcado .vo-espera i{ animation-duration:3s; } }
#volcado .vo-ok{ width:56px; height:56px; border-radius:50%; display:grid; place-items:center; font-size:26px; font-weight:700; color:var(--t-on-accent); background:var(--t-ok); }
#volcado .vo-ok.mal{ background:var(--t-warn); }
#volcado .vo-bts{ display:flex; gap:10px; flex-wrap:wrap; justify-content:center; margin-top:10px; }
#volcado .vo-res{ padding:14px; border-radius:14px; font-size:15px; line-height:1.5; background:color-mix(in srgb, var(--t-accent) 9%, transparent); border:1px solid color-mix(in srgb, var(--t-accent) 30%, transparent); }
#volcado .vo-ayuda{ margin:0; font-size:13px; color:var(--t-dim); line-height:1.45; }
#volcado .vo-sec-t{ margin-top:8px; font-size:13px; font-weight:700; color:var(--t-dim); }
#volcado .vo-it{ display:grid; grid-template-columns:28px 1fr; gap:8px; align-items:start; padding:11px 0; border-bottom:1px solid var(--t-line); cursor:pointer; }
#volcado .vo-it input{ width:22px; height:22px; margin:2px 0 0; accent-color:var(--t-accent); }
#volcado .vo-itc{ display:grid; gap:3px; min-width:0; }
#volcado .vo-itc b{ font-size:13px; font-weight:700; color:var(--t-dim); } #volcado .vo-itc b i{ font-style:normal; font-weight:400; }
#volcado .vo-nuevo{ font-size:15.5px; line-height:1.45; white-space:pre-wrap; overflow-wrap:anywhere; }
#volcado .vo-antes{ font-size:12.5px; color:var(--t-dim); text-decoration:line-through; overflow-wrap:anywhere; }
#volcado .vo-it:has(input:not(:checked)) .vo-nuevo{ opacity:.45; }
/* el botón en la ficha */
#dashFicha .fvolc{ display:grid; gap:2px; width:100%; min-height:56px; margin:0 0 14px; padding:11px 14px; text-align:left; border-radius:14px; cursor:pointer; font:inherit;
  color:var(--d-ink); background:color-mix(in srgb, var(--t-accent) 10%, transparent); border:1px solid color-mix(in srgb, var(--t-accent) 38%, transparent); }
#dashFicha .fvolc b{ font-size:15px; font-weight:700; } #dashFicha .fvolc span{ font-size:12.5px; color:var(--d-mut); line-height:1.35; }
#dashFicha .fvolc:active{ transform:scale(.99); }

/* ==================== EDITAR EL MENSAJE ANTES DE MANDARLO (21/09/2026) ====================
   Debajo de "Abrir WhatsApp · Copiar · Editar": un cuadro con el texto en 16px (sin zoom de iOS),
   "Usar este" abre WhatsApp con la versión de Tobi y la guarda como ejemplo de estilo. */
#chatIA .ch-wa{ flex-wrap:wrap; }
#chatIA .ch-wa-ed{ flex:1 0 100%; display:grid; gap:8px; margin-top:8px; }
#chatIA .ch-wa-ta{ width:100%; box-sizing:border-box; min-height:120px; resize:none; padding:12px; border-radius:12px; border:1px solid var(--a-line2); background:var(--a-input, var(--a-card)); color:var(--a-ink); font:inherit; font-size:16px; line-height:1.45; }
#chatIA .ch-wa-ta:focus{ outline:2px solid var(--t-focus); outline-offset:1px; }
#chatIA .ch-wa-acts{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
#chatIA .ch-wa-msg{ font-size:12.5px; color:var(--a-mut); }

/* ==================== LO QUE ANOTASTE PARA HOY Y MAÑANA (21/09/2026) ====================
   Arriba de "Próximos días": una fila por recordatorio, con el color personal. */
#dash .dd-rec{ display:grid; gap:6px; margin-bottom:14px; }
#dash .dd-rec-it{ display:grid; grid-template-columns:auto 1fr 12px; align-items:center; gap:12px; width:100%; min-height:52px; padding:9px 12px; text-align:left; border-radius:12px; cursor:pointer; font:inherit; color:var(--d-ink);
  background:color-mix(in srgb, var(--t-personal) 12%, transparent); border:1px solid color-mix(in srgb, var(--t-personal) 40%, transparent); }
#dash .dd-rec-it .c{ font-family:var(--a-mono); font-size:12.5px; font-weight:700; color:var(--t-personal); white-space:nowrap; }
#dash .dd-rec-it .t{ display:grid; gap:1px; min-width:0; } #dash .dd-rec-it .t b{ font-size:14.5px; font-weight:600; } #dash .dd-rec-it .t em{ font-style:normal; font-size:12.5px; color:var(--d-mut); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
#dash .dd-rec-it .dk-go{ position:static; transform:rotate(-45deg); width:7px; height:7px; }
#dash .dd-rec-it:active{ transform:scale(.99); }

/* TÉCNICA COBRADA SIN EQUIPOS (22/09/2026): en la ficha, un aviso que no se puede no ver. */
#dashFicha .ftec-falta{ border-color:color-mix(in srgb, var(--t-err) 55%, transparent); background:color-mix(in srgb, var(--t-err) 10%, transparent); font-size:13px; line-height:1.45; }
#dashFicha .ftec-falta b{ color:var(--d-ink); }

/* ==== chat · composer en escritorio (23/09/2026) ====
   Tobi: "cuando toco donde se escribe se crea un recuadro azul que queda muy feo; la
   flechita violeta cambiala por algo con animación; y el + no está centrado".
   1) El campo no lleva anillo propio (en el celu ya no lo tenía): la cápsula marca el foco
      con un borde apenas más claro y un halo suave, sin azul.
   2) El + se dibuja con dos trazos centrados, no con el carácter "+" (que cae bajo la
      línea de base según la fuente).
   3) Enviar: vacío es un círculo apagado; con texto se enciende con el degradé de la app
      girando despacio y la flecha crece al pasar el mouse. Trabajando (■) late suave.
   El texto del botón sigue siendo ↑ / ■ (lo leen los tests y los lectores de pantalla);
   solo se dibuja distinto. */
#chatIA .ch-row textarea:focus, #chatIA .ch-row textarea:focus-visible{ outline:none; box-shadow:none; }
#chatIA .ch-row{ transition:border-color .2s ease, box-shadow .2s ease; }
#chatIA .ch-row:focus-within{ border-color:color-mix(in srgb, var(--a-ink) 22%, var(--a-line));
  box-shadow:0 0 0 4px color-mix(in srgb, var(--a-ink) 5%, transparent); }

#chatIA .ch-row .ch-plus{ font-size:0; color:var(--a-mut); }
#chatIA .ch-row .ch-plus::after{ content:''; width:14px; height:14px; display:block; position:absolute; inset:0; margin:auto;
  background:linear-gradient(currentColor,currentColor) center/14px 1.8px no-repeat,
             linear-gradient(currentColor,currentColor) center/1.8px 14px no-repeat; border-radius:1px; }

#chatIA .ch-row .ch-send{ font-size:0; position:relative; overflow:hidden; isolation:isolate; border:0;
  background:var(--a-card); color:var(--a-dim); box-shadow:inset 0 0 0 1px var(--a-line);
  transition:color .2s ease, box-shadow .25s ease, transform .15s ease; }
#chatIA .ch-row .ch-send::before{ content:''; position:absolute; inset:-35%; z-index:-1; border-radius:50%;
  background:conic-gradient(from 0deg, var(--pro-1), var(--pro-2), var(--pro-3), var(--pro-4), var(--pro-5), var(--pro-1));
  opacity:0; transition:opacity .25s ease; }
#chatIA .ch-row .ch-send::after{ content:''; width:18px; height:18px; display:block; position:absolute; inset:0; margin:auto;
  background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 19V5M5.5 11.5 12 5l6.5 6.5'/%3E%3C/svg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 19V5M5.5 11.5 12 5l6.5 6.5'/%3E%3C/svg%3E") center/contain no-repeat;
  transition:transform .25s cubic-bezier(.3,1.6,.5,1); }
/* con texto: se enciende */
#chatIA .ch-row.con-texto .ch-send:not(.stop){ color:white; box-shadow:0 6px 18px -6px color-mix(in srgb, var(--pro-3) 70%, transparent); }
#chatIA .ch-row.con-texto .ch-send:not(.stop)::before{ opacity:1; animation:chSendGira 3.2s linear infinite; }
:where(html.puntero) #chatIA .ch-row .ch-plus:hover{ color:var(--a-ink); border-color:color-mix(in srgb, var(--a-ink) 25%, var(--a-line)); }
:where(html.puntero) #chatIA .ch-row.con-texto .ch-send:not(.stop):hover::after{ transform:scale(1.15); }
#chatIA .ch-row.con-texto .ch-send:not(.stop):active{ transform:scale(.92); }
/* trabajando: cuadradito que late */
#chatIA .ch-row .ch-send.stop{ color:var(--a-ink); box-shadow:inset 0 0 0 1px var(--a-line2); }
#chatIA .ch-row .ch-send.stop::after{ width:12px; height:12px; border-radius:3px; -webkit-mask:none; mask:none; animation:chSendLate 1.2s ease-in-out infinite; }
@keyframes chSendGira{ to{ transform:rotate(1turn); } }
@keyframes chSendLate{ 0%,100%{ transform:scale(1); opacity:1; } 50%{ transform:scale(.78); opacity:.6; } }
@media (prefers-reduced-motion: reduce){
  #chatIA .ch-row.con-texto .ch-send:not(.stop)::before, #chatIA .ch-row .ch-send.stop::after{ animation:none; }
}

/* ═══════════════════════ CABINA EN EL CELU (24/09/2026) ═══════════════════════
   La sección de música (assets/cabina-*.js): tu catálogo, tus géneros, tus listas y el
   reproductor. Se abre desde el botón "Cabina" de la barra, ENCIMA de la página en la
   que estabas (z 945: arriba de todas las páginas, abajo de la barra, que sigue a la
   vista para salir). Sin hex nuevos: todo sale de los tokens del tema, así el claro se
   acomoda solo. El logo es el de Cabina en la Mac: la palabra en mono espaciada y la
   rayita de colores, más un disco que gira mientras suena. */
#navbar .nvb[data-cabina]{ --nvc:var(--t-reunion); --nvbg:color-mix(in srgb, var(--t-reunion) 16%, transparent); }
#navbar .nvb[data-cabina][aria-expanded="true"]{ color:var(--nvc); background:var(--nvbg); }
/* Con Cabina abierta, la pestaña de abajo no puede verse "activa": lo que se ve es Cabina. */
#navbar.cb-on .nvb[aria-current="page"]{ color:var(--t-panel-muted); background:transparent; }
#navbar .nvb[data-cabina].sonando .nvi .ico{ animation:cbGira 3.2s linear infinite; }
@keyframes cbGira{ to{ transform:rotate(360deg); } }
/* Con seis botones, en los teléfonos más angostos (320 pt, el SE viejo) "Historial" no entraba: ahí la etiqueta baja un punto. */
@media (max-width:340px){ #navbar .nvb{ font-size:10px; padding-left:0; padding-right:0; } }
@keyframes cbEntra{ from{ opacity:0; transform:translateY(8px); } to{ opacity:1; transform:none; } }

#cabina{ --cb-lado:max(16px, calc((100% - 860px) / 2));
  position:fixed; inset:0; z-index:945; display:flex; flex-direction:column; outline:none;
  padding:calc(var(--nav-top) + env(safe-area-inset-top, 0px)) 0 var(--nav-bot); box-sizing:border-box;
  background:var(--t-bg); color:var(--t-ink);
  font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
  animation:cbEntra .22s cubic-bezier(.2,.7,.3,1) both; }
#cabina[hidden]{ display:none !important; }

/* el encabezado y el logo */
#cabina .cb-hd{ display:flex; align-items:center; gap:12px; padding:12px var(--cb-lado) 10px; }
#cabina .cb-marca{ display:flex; align-items:center; gap:10px; margin:0; flex:none;
  font:700 14px/1 ui-monospace,'SF Mono',SFMono-Regular,Menlo,monospace; letter-spacing:.26em; color:var(--t-ink); }
#cabina .cb-marca i{ width:28px; height:3px; border-radius:3px; background:var(--luz-barra); }
.cb-disco{ position:relative; display:inline-block; width:26px; height:26px; border-radius:50%; flex:none;
  background:repeating-radial-gradient(circle, transparent 0 1.3px, color-mix(in srgb, var(--t-ink) 10%, transparent) 1.3px 1.9px), var(--t-surface-2);
  box-shadow:inset 0 0 0 1px var(--t-line-2); }
.cb-disco::after{ content:''; position:absolute; inset:30%; border-radius:50%;
  background:radial-gradient(circle, var(--t-bg) 0 16%, transparent 22%),
             conic-gradient(from 0deg, var(--t-tab-fmt), var(--t-info), var(--t-personal), var(--t-reunion), var(--t-tab-fmt)); }
#cabina.sonando .cb-disco{ animation:cbGira 2.4s linear infinite; }
#cabina .cb-cuantos{ flex:1; min-width:0; text-align:right; font-size:12px; color:var(--t-muted);
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-variant-numeric:tabular-nums; }
#cabina .cb-x{ width:44px; height:44px; flex:none; margin-right:-8px; border-radius:50%; border:0; background:transparent;
  color:var(--t-muted); font:inherit; font-size:18px; cursor:pointer; }

/* buscar y pestañas (16px en el campo: abajo de eso iOS hace zoom al enfocar) */
#cabina .cb-busca{ position:relative; padding:0 var(--cb-lado) 10px; }
#cabina .cb-busca[hidden]{ display:none; }
#cabina .cb-busca .ico{ position:absolute; left:calc(var(--cb-lado) + 13px); top:13px; width:18px; height:18px; color:var(--t-dim); pointer-events:none; }
#cabina .cb-busca input{ width:100%; height:44px; box-sizing:border-box; padding:0 14px 0 40px; border-radius:12px;
  border:1px solid var(--t-line); background:var(--t-input); color:var(--t-ink); font:inherit; font-size:16px;
  outline:none; -webkit-appearance:none; appearance:none; }
#cabina .cb-busca input:focus{ border-color:transparent; background:linear-gradient(var(--t-input), var(--t-input)) padding-box, var(--luz) border-box; }
#cabina .cb-tabs{ display:flex; gap:6px; padding:0 var(--cb-lado) 10px; }
#cabina .cb-tabs button{ flex:1; min-height:40px; border-radius:11px; border:1px solid var(--t-line); background:transparent;
  color:var(--t-muted); font:inherit; font-size:13.5px; font-weight:600; cursor:pointer; }
#cabina .cb-tabs button[aria-selected="true"]{ color:var(--t-ink); border-color:transparent;
  background:linear-gradient(var(--t-surface), var(--t-surface)) padding-box, var(--luz) border-box; }
#cabina .cb-aviso{ margin:0 var(--cb-lado) 8px; padding:9px 14px; border-radius:10px; font-size:13px; line-height:1.4;
  color:var(--t-ink); background:color-mix(in srgb, var(--t-warn) 13%, transparent); }
#cabina .cb-aviso[hidden]{ display:none; }
#cabina .cb-aviso .cb-link{ min-height:0; padding:0 2px; }

/* el cuerpo: el único que scrollea */
#cabina .cb-cuerpo{ flex:1; min-height:0; overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch;
  padding:0 var(--cb-lado) 20px; }
#cabina .cb-vacio, #cabina .cb-nota{ margin:14px 2px; color:var(--t-muted); font-size:14px; line-height:1.45; }
#cabina .cb-nota{ margin:8px 2px 12px; font-size:12.5px; }
#cabina .cb-error{ margin:4px 0 10px; padding:10px 12px; border-radius:10px; font-size:13.5px; line-height:1.4;
  color:var(--t-ink); background:color-mix(in srgb, var(--t-err) 14%, transparent); }
#cabina .cb-fila-acc{ display:flex; align-items:center; gap:8px; margin:2px 0 6px; }
#cabina .cb-cuenta{ flex:1; font-size:12.5px; color:var(--t-muted); font-variant-numeric:tabular-nums; }
#cabina .cb-bot{ display:inline-flex; align-items:center; gap:6px; min-height:40px; padding:0 14px; border-radius:20px;
  border:1px solid var(--t-line-2); background:transparent; color:var(--t-ink); font:inherit; font-size:13px; font-weight:600; cursor:pointer; }
#cabina .cb-bot .ico{ width:13px; height:13px; }
#cabina .cb-filtro{ display:inline-flex; align-items:center; gap:2px; margin:2px 0 6px; padding-left:13px; border-radius:20px;
  background:color-mix(in srgb, var(--t-reunion) 15%, transparent); color:var(--t-ink); font-size:13px; font-weight:600; }
#cabina .cb-filtro button{ width:40px; height:40px; border:0; background:transparent; color:inherit; font:inherit; font-size:14px; cursor:pointer; }

/* una fila = un tema */
#cabina .cb-lista{ list-style:none; margin:0; padding:0; }
#cabina .cb-t{ display:flex; align-items:center; gap:10px; min-height:58px; padding:4px 0; border-bottom:1px solid var(--t-line); }
#cabina .cb-t-play{ display:grid; place-items:center; width:44px; height:44px; flex:none; border-radius:50%; border:0; cursor:pointer;
  background:color-mix(in srgb, var(--t-ink) 7%, transparent); color:var(--t-ink); }
#cabina .cb-t-play .ico{ width:17px; height:17px; }
#cabina .cb-t.suena .cb-t-play{ background:var(--t-btn-primary-bg); color:var(--t-btn-primary-ink); }
#cabina .cb-t.suena .cb-t-txt b{ color:var(--t-reunion); }
#cabina .cb-t.sin-audio .cb-t-play{ opacity:.35; }
#cabina .cb-t-txt{ flex:1; min-width:0; cursor:pointer; }
#cabina .cb-t-txt b{ display:block; font-size:15px; font-weight:600; line-height:1.25; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#cabina .cb-t-txt .cb-ver{ font-weight:500; color:var(--t-muted); }
#cabina .cb-t-txt > span{ display:block; margin-top:2px; font-size:12.5px; color:var(--t-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#cabina .cb-t-mas{ display:grid; place-items:center; width:44px; height:44px; flex:none; margin-right:-6px; border-radius:50%; border:0;
  background:transparent; color:var(--t-muted); cursor:pointer; }
#cabina .cb-t-mas .ico{ width:20px; height:20px; }
/* 🎨 EL ZÓCALO DE CADA TEMA, DEL COLOR DE SU TONO (28/09/2026), medio vidriado como el reproductor.
   El JS pone --h (el matiz de su número en la rueda de Camelot) y la clase menor/mayor; el color sale
   de acá. Mismo número o números vecinos = colores vecinos = mezclan bien. Sin tono: vidrio neutro. */
#cabina .cb-lista .cb-t{ margin:5px 0; padding:4px 8px 4px 4px; border-bottom:0; border-radius:14px;
  background:color-mix(in srgb, var(--t-ink) 3.5%, transparent);
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 7%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--t-ink) 6%, transparent); }
#cabina .cb-lista .cb-t.tono{ --tl:0.66; --tch:0.15; --tc:oklch(var(--tl) var(--tch) var(--h));
  background:linear-gradient(100deg, color-mix(in oklab, var(--tc) 32%, transparent), color-mix(in oklab, var(--tc) 12%, transparent) 58%,
             color-mix(in oklab, var(--tc) 5%, transparent));
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 16%, transparent), inset 0 0 0 1px color-mix(in oklab, var(--tc) 32%, transparent); }
#cabina .cb-lista .cb-t.tono.mayor{ --tl:0.8; --tch:0.12; }
html[data-theme="claro"] #cabina .cb-lista .cb-t.tono{ --tl:0.6; }
html[data-theme="claro"] #cabina .cb-lista .cb-t.tono.mayor{ --tl:0.72; }
#cabina .cb-tono{ display:inline-block; min-width:26px; margin-right:7px; padding:0 6px; border-radius:7px; font-style:normal;
  font-weight:750; font-size:11.5px; line-height:17px; text-align:center; vertical-align:1px;
  background:var(--tc); color:color-mix(in srgb, black 84%, var(--tc)); }
/* ORDENAR (28/09/2026): un control segmentado de vidrio, de un toque. El activo se levanta con un
   borde de luz; en Tono y BPM una flechita dice para dónde va (tocarlo de nuevo lo da vuelta). */
#cabina .cb-orden{ display:flex; align-items:center; gap:10px; margin:8px 0 6px; }
#cabina .cb-orden-t{ flex:none; font-size:11px; font-weight:700; letter-spacing:.12em; text-transform:uppercase; color:var(--t-muted); }
#cabina .cb-seg{ flex:1; display:flex; gap:4px; padding:4px; border-radius:15px;
  background:color-mix(in srgb, var(--t-ink) 5%, transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--t-ink) 7%, transparent), inset 0 1px 2px color-mix(in srgb, black 18%, transparent); }
#cabina .cb-seg button{ position:relative; flex:1; min-width:0; min-height:40px; display:inline-flex; align-items:center; justify-content:center; gap:5px;
  padding:0 8px; border:0; border-radius:11px; background:transparent; color:var(--t-muted); font:inherit; font-size:14px; font-weight:600;
  cursor:pointer; -webkit-tap-highlight-color:transparent; transition:background .22s ease, color .22s ease, box-shadow .22s ease, transform .2s cubic-bezier(.2,1.4,.4,1); }
#cabina .cb-seg button span{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#cabina .cb-seg button i{ font-style:normal; font-size:13px; opacity:.85; }
#cabina .cb-seg button[aria-pressed="true"]{ color:var(--t-ink);
  background:linear-gradient(180deg, color-mix(in srgb, white 12%, transparent), transparent 70%), color-mix(in srgb, var(--t-ink) 9%, transparent);
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 22%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--t-ink) 10%, transparent),
             0 2px 8px color-mix(in srgb, black 30%, transparent); }
#cabina .cb-seg button:active{ transform:scale(.96); }
:where(html.puntero) #cabina .cb-seg button:not([aria-pressed="true"]):hover{ color:var(--t-ink); background:color-mix(in srgb, var(--t-ink) 5%, transparent); }
#cabina .cb-tono-nota{ margin:0 0 6px; }
#cabina .cb-orden-guardar{ display:flex; align-items:center; flex-wrap:wrap; gap:6px 12px; margin:2px 0 6px; }
#cabina .cb-orden-guardar .cb-nota{ margin:0; }
/* Ordenado por tono: un encabezado por tono, con su color y una línea que se apaga. */
#cabina .cb-grupo{ list-style:none; display:flex; align-items:center; gap:8px; margin:16px 2px 4px; font-size:12.5px; color:var(--t-muted); }
#cabina .cb-grupo:first-child{ margin-top:6px; }
#cabina .cb-grupo b{ font-weight:700; color:var(--t-ink); }
#cabina .cb-grupo.tono{ --tl:0.66; --tch:0.15; --tc:oklch(var(--tl) var(--tch) var(--h)); }
#cabina .cb-grupo.tono.mayor{ --tl:0.8; --tch:0.12; }
html[data-theme="claro"] #cabina .cb-grupo.tono{ --tl:0.6; }
html[data-theme="claro"] #cabina .cb-grupo.tono.mayor{ --tl:0.72; }
#cabina .cb-grupo .cb-tono{ margin:0; font-size:12.5px; line-height:20px; min-width:32px; }
#cabina .cb-grupo::after{ content:""; flex:1; height:1px; margin-left:4px;
  background:linear-gradient(90deg, color-mix(in oklab, var(--tc, var(--t-line)) 55%, transparent), transparent); }
@media (prefers-reduced-motion: reduce){ #cabina .cb-seg button{ transition:none; } }
#cabina .cb-ord{ display:flex; flex:none; }
#cabina .cb-ord button{ width:38px; height:44px; border:0; border-radius:10px; background:transparent; color:var(--t-muted);
  font:inherit; font-size:16px; cursor:pointer; }
#cabina .cb-ord button:disabled{ opacity:.25; cursor:default; }
#cabina .cb-mas{ display:block; width:100%; min-height:44px; margin:12px 0 0; border-radius:12px; border:1px solid var(--t-line);
  background:transparent; color:var(--link); font:inherit; font-size:14px; font-weight:600; cursor:pointer; }

/* géneros */
#cabina .cb-gen{ list-style:none; margin:0; padding:0; }
#cabina .cb-gen > li{ padding:4px 0 10px; border-bottom:1px solid var(--t-line); }
#cabina .cb-fam{ display:flex; align-items:center; width:100%; min-height:44px; padding:0 2px; border:0; background:transparent;
  color:var(--t-ink); font:inherit; text-align:left; cursor:pointer; }
#cabina .cb-fam b{ flex:1; font-size:16px; font-weight:650; }
#cabina .cb-fam span, #cabina .cb-subgen span{ color:var(--t-muted); font-size:12.5px; font-variant-numeric:tabular-nums; }
#cabina .cb-gen > li.tuyas .cb-fam b{ color:var(--t-reunion); }
#cabina .cb-subgen{ display:flex; flex-wrap:wrap; gap:6px; }
#cabina .cb-subgen button{ min-height:38px; padding:0 12px; border-radius:19px; border:1px solid var(--t-line); background:transparent;
  color:var(--t-ink); font:inherit; font-size:13px; cursor:pointer; }

/* listas */
#cabina .cb-nueva, #cabina .cb-hoja form{ display:flex; gap:8px; margin:6px 0 4px; }
#cabina .cb-nueva input, #cabina .cb-hoja input, #cabina .cb-nombre{ flex:1; min-width:0; height:44px; box-sizing:border-box; padding:0 12px;
  border-radius:11px; border:1px solid var(--t-line); background:var(--t-input); color:var(--t-ink); font:inherit; font-size:16px; outline:none; }
#cabina .cb-nueva input:focus, #cabina .cb-hoja input:focus, #cabina .cb-nombre:focus{ border-color:transparent;
  background:linear-gradient(var(--t-input), var(--t-input)) padding-box, var(--luz) border-box; }
#cabina .cb-nueva button, #cabina .cb-hoja form button{ min-height:44px; padding:0 16px; border-radius:11px; border:0;
  background:var(--t-btn-primary-bg); color:var(--t-btn-primary-ink); font:inherit; font-size:14px; font-weight:700; cursor:pointer; white-space:nowrap; }
/* ✦ «Pedile una lista a la IA» (25/09/2026) */
#cabina .cb-ia{ margin:6px 0 12px; padding:12px; border-radius:14px; border:1px solid transparent;
  background:linear-gradient(var(--t-surface), var(--t-surface)) padding-box, var(--luz) border-box; }
#cabina .cb-ia-t{ display:block; margin:0 0 8px; font-size:14px; font-weight:700; color:var(--t-ink); }
#cabina .cb-ia-fila{ display:flex; gap:8px; }
#cabina .cb-ia input{ flex:1; min-width:0; height:44px; box-sizing:border-box; padding:0 12px; border-radius:11px;
  border:1px solid var(--t-line); background:var(--t-input); color:var(--t-ink); font:inherit; font-size:16px; outline:none; }
#cabina .cb-ia input:focus{ border-color:var(--t-reunion); }
#cabina .cb-ia button{ min-height:44px; padding:0 16px; border-radius:11px; border:0; background:var(--t-btn-primary-bg);
  color:var(--t-btn-primary-ink); font:inherit; font-size:14px; font-weight:700; cursor:pointer; white-space:nowrap; }
#cabina .cb-ia.trabajando .cb-ia-t{ margin:0; }
#cabina .cb-ia.trabajando .cb-nota{ margin:4px 0 0; }
@media (prefers-reduced-motion: no-preference){
  #cabina .cb-ia.trabajando .cb-ia-t{ animation:cbIaLate 1.6s ease-in-out infinite; }
}
@keyframes cbIaLate{ 50%{ opacity:.45; } }
#cabina .cb-ia-nota{ margin:0 0 10px; padding:10px 12px; border-radius:10px; font-size:13.5px; line-height:1.45; color:var(--t-ink);
  background:color-mix(in srgb, var(--t-reunion) 10%, transparent); }
#cabina .cb-ls{ list-style:none; margin:0; padding:0; }
#cabina .cb-ls button{ display:flex; flex-direction:column; align-items:flex-start; gap:2px; width:100%; min-height:56px; padding:8px 2px;
  border:0; border-bottom:1px solid var(--t-line); background:transparent; color:var(--t-ink); font:inherit; text-align:left; cursor:pointer; }
#cabina .cb-ls b{ font-size:15.5px; font-weight:600; }
#cabina .cb-ls span{ font-size:12.5px; color:var(--t-muted); }
#cabina .cb-lhd{ display:flex; align-items:center; gap:6px; margin:2px 0 8px; }
/* tus playlists de rekordbox y de Música, con sus carpetas (28/09/2026) */
#cabina .cb-sec{ display:flex; align-items:baseline; gap:8px; margin:18px 2px 6px; font-size:13px; font-weight:700;
  letter-spacing:.04em; text-transform:uppercase; color:var(--t-muted); }
#cabina .cb-sec span{ font-weight:600; letter-spacing:0; font-variant-numeric:tabular-nums; }
#cabina .cb-carps b{ display:flex; align-items:center; gap:8px; }
#cabina .cb-carps b .ico{ width:18px; height:18px; flex:none; color:var(--t-dim); }
#cabina .cb-ruta{ flex:1; min-width:0; font-size:12.5px; color:var(--t-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#cabina .cb-pl-nombre{ margin:2px 2px 0; font-size:20px; font-weight:700; line-height:1.25; color:var(--t-ink); }
#cabina .cb-pl-meta{ margin-top:4px; }
#cabina .cb-copiar{ display:block; margin:0 0 4px -6px; }
#cabina .cb-perfil{ margin:-4px 0 6px; }
#cabina .cb-perfil summary{ min-height:44px; display:flex; align-items:center; padding:0 2px; font-size:13.5px; font-weight:600;
  color:var(--link); cursor:pointer; list-style:none; }
#cabina .cb-perfil summary::-webkit-details-marker{ display:none; }
#cabina .cb-perfil > div{ padding:10px 12px; border-radius:10px; background:color-mix(in srgb, var(--t-ink) 5%, transparent); }
#cabina .cb-perfil p{ margin:0 0 6px; font-size:12.5px; line-height:1.45; color:var(--t-muted); }
#cabina .cb-perfil p:first-child{ color:var(--t-ink); font-weight:600; }
#cabina .cb-link{ min-height:44px; padding:0 6px; border:0; background:transparent; color:var(--link); font:inherit; font-size:14px;
  font-weight:600; cursor:pointer; white-space:nowrap; }
#cabina .cb-borrar{ display:block; width:100%; min-height:44px; margin:18px 0 6px; border-radius:12px; background:transparent;
  border:1px solid color-mix(in srgb, var(--t-err) 45%, transparent); color:var(--t-err); font:inherit; font-size:14px; font-weight:600; cursor:pointer; }

/* la hoja de "Agregar a una lista" (arriba de la barra, que sigue tocable) */
#cabina .cb-capa{ position:fixed; left:0; right:0; top:0; bottom:var(--nav-bot); z-index:2; }
#cabina .cb-capa[hidden]{ display:none; }
#cabina .cb-velo{ position:absolute; inset:0; background:var(--t-overlay); }
#cabina .cb-hoja{ position:absolute; left:50%; bottom:12px; transform:translateX(-50%); box-sizing:border-box;
  width:min(460px, calc(100% - 24px)); max-height:min(72vh, calc(100% - 24px)); overflow-y:auto; overscroll-behavior:contain;
  padding:14px; border-radius:16px; border:1px solid var(--t-line); background:var(--t-surface);
  box-shadow:0 24px 60px -18px color-mix(in srgb, black 70%, transparent); }
#cabina .cb-hoja p{ margin:2px 2px 10px; font-size:14px; line-height:1.4; color:var(--t-muted); }
#cabina .cb-hoja p b{ color:var(--t-ink); }
#cabina .cb-hoja-ls{ display:flex; flex-direction:column; gap:6px; margin-bottom:8px; }
#cabina .cb-hoja-ls button{ min-height:46px; padding:0 14px; border-radius:12px; border:1px solid var(--t-line); background:var(--t-surface-2);
  color:var(--t-ink); font:inherit; font-size:15px; font-weight:600; text-align:left; cursor:pointer; }
#cabina .cb-hoja-ls button:disabled{ opacity:.5; cursor:default; }
#cabina .cb-hoja-ls button span{ font-size:12.5px; font-weight:500; color:var(--t-muted); }
#cabina .cb-hoja > .cb-link{ display:block; margin:6px auto 0; }

/* con mouse (acotado a un puntero real: en el celu el :hover se queda pegado) */
:where(html.puntero) #cabina .cb-t:hover{ background:color-mix(in srgb, var(--t-ink) 4%, transparent); }
:where(html.puntero) #cabina .cb-lista .cb-t.tono:hover{ background:linear-gradient(100deg, color-mix(in oklab, var(--tc) 42%, transparent),
  color-mix(in oklab, var(--tc) 18%, transparent) 58%, color-mix(in oklab, var(--tc) 8%, transparent)); }
:where(html.puntero) #cabina .cb-t-mas:hover, :where(html.puntero) #cabina .cb-x:hover, :where(html.puntero) #cabina .cb-ord button:not(:disabled):hover{ color:var(--t-ink); background:color-mix(in srgb, var(--t-ink) 7%, transparent); }
:where(html.puntero) #cabina .cb-fam:hover b, :where(html.puntero) #cabina .cb-ls button:hover b{ color:var(--link); }
:where(html.puntero) #cabina .cb-subgen button:hover, :where(html.puntero) #cabina .cb-bot:hover, :where(html.puntero) #cabina .cb-tabs button:not([aria-selected="true"]):hover{ border-color:var(--t-line-2); color:var(--t-ink); background:color-mix(in srgb, var(--t-ink) 5%, transparent); }
:where(html.puntero) #cabina .cb-hoja-ls button:not(:disabled):hover{ border-color:var(--t-line-2); }

@media (prefers-reduced-motion: reduce){
  #cabina, #cabina.sonando .cb-disco, #navbar .nvb[data-cabina].sonando .nvi .ico{ animation:none; }
}

/* ✦ «¿Qué le falta?» (28/09/2026): 10 temas que suenan hoy y no tenés, adentro de cada playlist o lista. */
#cabina .cb-sug{ margin:8px 0 14px; }
#cabina .cb-sug-bot{ display:flex; align-items:center; gap:12px; width:100%; min-height:62px; padding:10px 14px; box-sizing:border-box;
  border-radius:16px; border:1px solid transparent; cursor:pointer; text-align:left; color:var(--t-ink); font:inherit;
  background:linear-gradient(var(--t-surface), var(--t-surface)) padding-box, var(--luz) border-box; }
#cabina .cb-sug-bot b{ display:block; font-size:15.5px; font-weight:700; }
#cabina .cb-sug-bot span span{ display:block; margin-top:2px; font-size:12.5px; color:var(--t-muted); }
#cabina .cb-sug-chispa{ display:grid; place-items:center; width:38px; height:38px; flex:none; border-radius:50%; font-size:17px;
  color:var(--t-btn-primary-ink); background:conic-gradient(from 200deg, var(--t-tab-fmt), var(--t-info), var(--t-personal), var(--t-reunion), var(--t-tab-fmt)); }
#cabina .cb-sug-cargando{ display:flex; align-items:center; gap:14px; min-height:62px; padding:10px 14px; box-sizing:border-box; border-radius:16px;
  background:color-mix(in srgb, var(--t-ink) 5%, transparent); }
#cabina .cb-sug-cargando b{ display:block; font-size:15px; }
#cabina .cb-sug-paso{ display:block; margin-top:3px; font-size:12.5px; color:var(--t-muted); }
#cabina .cb-sug-orbe{ width:36px; height:36px; flex:none; border-radius:50%;
  background:conic-gradient(from 0deg, var(--t-tab-fmt), var(--t-info), var(--t-personal), var(--t-reunion), var(--t-tab-fmt));
  -webkit-mask:radial-gradient(circle, transparent 54%, black 56%); mask:radial-gradient(circle, transparent 54%, black 56%);
  animation:cbGira 1.4s linear infinite; }
#cabina .cb-sug-hd{ display:flex; align-items:center; gap:8px; margin:4px 0 4px 2px; }
/* minimizar y cerrar las 10 sugeridas (28/09/2026) */
#cabina .cb-sug-ctrl{ margin-left:auto; display:flex; gap:4px; }
#cabina .cb-sug-ctrl button, #cabina .cb-sug-x{ display:grid; place-items:center; width:40px; height:40px; flex:none; padding:0; border:0; border-radius:50%;
  color:var(--t-muted); background:color-mix(in srgb, var(--t-ink) 6%, transparent); cursor:pointer; -webkit-tap-highlight-color:transparent;
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 10%, transparent); transition:background .2s ease, color .2s ease, transform .2s cubic-bezier(.2,1.4,.4,1); }
#cabina .cb-sug-ctrl .ico, #cabina .cb-sug-x .ico{ width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
#cabina .cb-sug-ctrl button:active, #cabina .cb-sug-x:active{ transform:scale(.92); }
:where(html.puntero) #cabina .cb-sug-ctrl button:hover, :where(html.puntero) #cabina .cb-sug-x:hover{ color:var(--t-ink); background:color-mix(in srgb, var(--t-ink) 11%, transparent); }
#cabina .cb-sug-flecha{ transition:transform .25s ease; }
#cabina .cb-sug-flecha.arriba{ transform:rotate(180deg); }
#cabina .cb-sug-min{ display:flex; align-items:center; gap:8px; padding:6px 6px 6px 0; border-radius:16px; border:1px solid transparent;
  background:linear-gradient(var(--t-surface), var(--t-surface)) padding-box, var(--luz) border-box; animation:cbSugEntra .3s ease both; }
#cabina .cb-sug-min-b{ flex:1; min-width:0; display:flex; align-items:center; gap:12px; min-height:48px; padding:0 4px 0 12px; border:0; background:transparent;
  color:var(--t-ink); font:inherit; text-align:left; cursor:pointer; -webkit-tap-highlight-color:transparent; }
#cabina .cb-sug-min-b .cb-sug-chispa{ width:32px; height:32px; font-size:15px; }
#cabina .cb-sug-min-t{ flex:1; min-width:0; }
#cabina .cb-sug-min-t b{ display:block; font-size:15px; font-weight:700; }
#cabina .cb-sug-min-t span{ display:block; margin-top:1px; font-size:12px; color:var(--t-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#cabina .cb-sug-min-b .cb-sug-flecha{ width:18px; height:18px; flex:none; fill:none; stroke:var(--t-muted); stroke-width:2.2; stroke-linecap:round; stroke-linejoin:round; }
/* volver deslizando: el contenido sigue al dedo, con una sombra al costado como una hoja */
#cabina .cb-cuerpo.cb-volviendo{ will-change:transform; box-shadow:-26px 0 34px -22px color-mix(in srgb, black 60%, transparent); }
@media (prefers-reduced-motion: reduce){ #cabina .cb-sug-flecha, #cabina .cb-sug-ctrl button, #cabina .cb-sug-x{ transition:none; } #cabina .cb-sug-min{ animation:none; } }
#cabina .cb-sug-hd b{ font-size:15px; }
#cabina .cb-sug-hd span{ font-size:12px; color:var(--t-muted); }
#cabina .cb-sug-analisis{ margin:0 2px 6px; font-size:13.5px; line-height:1.45; color:var(--t-ink); }
#cabina .cb-sug-ls{ list-style:none; margin:0; padding:0; }
#cabina .cb-sug-t{ display:grid; grid-template-columns:60px minmax(0, 1fr); column-gap:12px; padding:12px 0; border-bottom:1px solid var(--t-line); }
@media (prefers-reduced-motion: no-preference){
  #cabina .cb-sug-t{ animation:cbSugEntra .45s cubic-bezier(.2,.8,.3,1) both; animation-delay:calc(var(--i, 0) * 45ms); }
}
@keyframes cbSugEntra{ from{ opacity:0; transform:translateY(8px); } }
#cabina .cb-sug-oir{ position:relative; grid-row:span 2; align-self:start; width:60px; height:60px; padding:0; border:0; border-radius:12px;
  overflow:hidden; cursor:pointer; background:var(--t-surface-2); }
#cabina .cb-sug-oir img{ display:block; width:100%; height:100%; object-fit:cover; }
#cabina .cb-sug-oir .cb-disco{ position:absolute; inset:9px; width:auto; height:auto; }
#cabina .cb-sug-play{ position:absolute; right:4px; bottom:4px; display:grid; place-items:center; width:26px; height:26px; border-radius:50%;
  color:white; background:color-mix(in srgb, black 55%, transparent); -webkit-backdrop-filter:blur(6px); backdrop-filter:blur(6px); }
#cabina .cb-sug-play .ico{ width:12px; height:12px; }
#cabina .cb-sug-t.oyendo .cb-sug-oir{ box-shadow:0 0 0 2px var(--t-reunion); }
#cabina .cb-sug-txt{ min-width:0; }
#cabina .cb-sug-txt b{ display:block; font-size:15px; font-weight:650; line-height:1.25; }
#cabina .cb-sug-art{ display:block; margin-top:1px; font-size:13px; color:var(--t-muted); }
#cabina .cb-sug-tags{ display:flex; flex-wrap:wrap; gap:4px; margin-top:6px; }
#cabina .cb-sug-tags i{ font-style:normal; font-size:11px; font-weight:650; line-height:1.2; padding:3px 7px; border-radius:8px;
  color:var(--t-ink); background:color-mix(in srgb, var(--t-ink) 7%, transparent); }
#cabina .cb-sug-tags i.top{ background:color-mix(in srgb, var(--t-info) 16%, transparent); }
#cabina .cb-sug-tags i.nuevo{ background:color-mix(in srgb, var(--t-ok) 18%, transparent); }
#cabina .cb-sug-por{ display:block; margin-top:6px; font-size:13px; line-height:1.4; color:var(--t-ink); }
#cabina .cb-sug-tengo{ display:inline-block; margin-top:6px; font-size:12px; font-weight:650; font-style:normal; color:var(--t-ok); }
#cabina .cb-sug-acc{ grid-column:2; display:flex; flex-wrap:wrap; gap:6px; margin-top:9px; }
#cabina .cb-sug-l{ display:inline-flex; align-items:center; min-height:36px; padding:0 12px; box-sizing:border-box; border-radius:18px;
  border:1px solid var(--t-line-2); background:transparent; color:var(--t-ink); font:inherit; font-size:12.5px; font-weight:600;
  text-decoration:none; cursor:pointer; }
#cabina .cb-sug-no{ color:var(--t-muted); }
#cabina .cb-sug-mas{ display:flex; align-items:center; justify-content:center; gap:6px; width:100%; min-height:48px; margin:12px 0 2px;
  border-radius:14px; border:1px solid transparent; cursor:pointer; color:var(--t-ink); font:inherit; font-size:14.5px; font-weight:700;
  background:linear-gradient(var(--t-surface), var(--t-surface)) padding-box, var(--luz) border-box; }
#cabina .cb-sug-mas span{ font-size:12.5px; font-weight:500; color:var(--t-muted); }
#cabina .cb-sug-miro{ margin-top:10px; }
#cabina .cb-sug-antes{ margin-top:4px; }
#cabina .cb-sug-antes summary{ min-height:44px; display:flex; align-items:center; padding:0 2px; font-size:13.5px; font-weight:600;
  color:var(--link); cursor:pointer; list-style:none; }
#cabina .cb-sug-antes summary::-webkit-details-marker{ display:none; }
#cabina .cb-sug-antes ul{ list-style:none; margin:0; padding:0; }
#cabina .cb-sug-antes li{ display:flex; align-items:center; gap:8px; min-height:44px; border-bottom:1px solid var(--t-line); font-size:13px; }
#cabina .cb-sug-antes li > span{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--t-muted); }
#cabina .cb-sug-antes li b{ color:var(--t-ink); font-weight:600; }
#cabina .cb-sug-antes li.no{ opacity:.55; }
#cabina .cb-sug-antes em{ font-style:normal; font-size:12px; color:var(--t-muted); }
:where(html.puntero) #cabina .cb-sug-l:hover{ border-color:var(--t-ink); }
:where(html.puntero) #cabina .cb-sug-bot:hover, :where(html.puntero) #cabina .cb-sug-mas:hover{ filter:brightness(1.08); }

/* ===========================================================================
   EL REPRODUCTOR DE TODA LA APP, DE VIDRIO (28/09/2026) — #cbMini
   Tobi: "que quede en toda la app: si cambio a Panel, que siga estando abajo. Animalo como lo nuevo de
   Apple, como agua cristalina que se transparenta. En la computadora, si pongo el mouse, que se vea mejor."
   Vive a nivel de body (no adentro de #cabina). El vidrio: el fondo desenfocado y saturado, un tinte
   muy leve del panel, un borde de luz más fuerte arriba (vidrio iluminado desde arriba), un brillo que
   sigue al dedo o al mouse y una luz de colores que corre adentro mientras suena. En la compu, con el
   mouse encima, se aclara (menos blur: más transparente), se levanta y muestra la barra del tema.
   🔴 Lo que se anima es transform u opacity: lo resuelve el compositor, no repinta el vidrio.
   🔴 El aire que ocupa es --mini-h, que suma a --nav-bot (ver la barra): 58 de cápsula + el aire. */
:root{ --mini-h:0px; }
html.cb-mini-on{ --mini-h:70px; }
html.cb-mini-on.cb-abierta{ --mini-h:108px; }   /* con Cabina abierta se agranda (anterior, barra y tiempo) */
#cbMini{ --mx:50%; --my:0%; --p:0; --corre:0;
  position:fixed; z-index:948; left:0; right:0; margin:0 auto; bottom:calc(var(--navh, 60px) + 6px);
  width:min(560px, calc(100% - 16px)); height:58px; box-sizing:border-box; border-radius:29px;
  isolation:isolate; overflow:hidden; color:var(--t-ink); touch-action:pan-y; -webkit-user-select:none; user-select:none;
  -webkit-tap-highlight-color:transparent; font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',system-ui,sans-serif;
  background:linear-gradient(180deg, color-mix(in srgb, white 13%, transparent), transparent 55%),
             color-mix(in srgb, var(--t-panel-bg) 44%, transparent);
  -webkit-backdrop-filter:blur(18px) saturate(185%); backdrop-filter:blur(18px) saturate(185%);
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 34%, transparent),
             inset 0 -1px 1px color-mix(in srgb, white 7%, transparent),
             inset 0 -14px 22px -18px color-mix(in srgb, black 45%, transparent),
             0 16px 36px -14px color-mix(in srgb, black 60%, transparent),
             0 3px 10px -3px color-mix(in srgb, black 25%, transparent);
  transition:height .42s cubic-bezier(.2,1.2,.35,1), border-radius .42s cubic-bezier(.2,1.2,.35,1), transform .34s cubic-bezier(.2,1.3,.4,1),
             background .35s ease, -webkit-backdrop-filter .35s ease, backdrop-filter .35s ease, box-shadow .35s ease; }
#cbMini[hidden]{ display:none !important; }
html[data-theme="claro"] #cbMini{
  background:linear-gradient(180deg, color-mix(in srgb, white 40%, transparent), transparent 60%),
             color-mix(in srgb, var(--t-panel-bg) 52%, transparent);
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 70%, transparent), inset 0 -1px 1px color-mix(in srgb, black 5%, transparent),
             0 14px 34px -14px color-mix(in srgb, black 32%, transparent), 0 2px 8px -3px color-mix(in srgb, black 14%, transparent); }
/* el borde de luz: un aro de 1px, más claro arriba a la izquierda, como el canto de un vidrio */
#cbMini::before{ content:''; position:absolute; inset:0; z-index:3; pointer-events:none; border-radius:inherit; padding:1px;
  background:linear-gradient(160deg, color-mix(in srgb, white 62%, transparent), color-mix(in srgb, white 6%, transparent) 36%,
             transparent 58%, color-mix(in srgb, white 20%, transparent));
  -webkit-mask:linear-gradient(black 0 0) content-box, linear-gradient(black 0 0); -webkit-mask-composite:xor;
  mask:linear-gradient(black 0 0) content-box exclude, linear-gradient(black 0 0); }
/* la luz de colores que corre adentro mientras suena (el agua) */
#cbMini .cbm-luz{ position:absolute; inset:0; z-index:0; overflow:hidden; border-radius:inherit; pointer-events:none;
  opacity:.16; transition:opacity .6s ease; }
#cbMini.sonando .cbm-luz{ opacity:.42; }
#cbMini .cbm-luz i{ position:absolute; top:-80%; bottom:-80%; left:-45%; width:190%; filter:blur(14px);
  background:radial-gradient(28% 42% at 28% 50%, color-mix(in srgb, var(--t-tab-fmt) 70%, transparent), transparent 72%),
             radial-gradient(24% 40% at 56% 46%, color-mix(in srgb, var(--t-personal) 60%, transparent), transparent 72%),
             radial-gradient(26% 44% at 80% 56%, color-mix(in srgb, var(--t-reunion) 62%, transparent), transparent 72%); }
@media (prefers-reduced-motion: no-preference){
  #cbMini .cbm-luz i{ animation:cbmCorre 11s ease-in-out infinite alternate; animation-play-state:paused; }
  #cbMini.sonando .cbm-luz i{ animation-play-state:running; }
  #cbMini .cbm-txt.cambia{ animation:cbmCambia .4s cubic-bezier(.2,.9,.3,1); }
}
@keyframes cbmCorre{ from{ transform:translateX(-14%) rotate(-4deg); } to{ transform:translateX(14%) rotate(4deg); } }
@keyframes cbmCambia{ from{ opacity:0; filter:blur(5px); transform:translateY(7px); } }
/* el brillo: donde apoyás el dedo (celu) o sigue al mouse (compu) */
#cbMini .cbm-brillo{ position:absolute; inset:0; z-index:2; pointer-events:none; border-radius:inherit; opacity:0; transition:opacity .3s ease;
  background:radial-gradient(150px 90px at var(--mx) var(--my), color-mix(in srgb, white 30%, transparent), transparent 70%); }
#cbMini.toca .cbm-brillo{ opacity:1; transition-duration:.08s; }
/* la fila de arriba: lo que suena y los botones */
#cbMini .cbm-fila{ position:relative; z-index:1; display:flex; align-items:center; gap:2px; height:58px; padding:0 6px 0 7px; box-sizing:border-box; }
#cbMini .cbm-info{ flex:1; min-width:0; display:flex; align-items:center; gap:10px; height:100%; padding:0 4px 0 0; border:0;
  background:transparent; color:inherit; font:inherit; text-align:left; cursor:pointer; }
/* La portada: el logo de Tobi (la misma de la pantalla bloqueada), como la tapa de un disco. */
#cbMini .cbm-arte{ position:relative; display:block; width:44px; height:44px; flex:none; border-radius:10px; overflow:hidden;
  box-shadow:0 2px 8px color-mix(in srgb, black 35%, transparent); }
#cbMini .cbm-arte img{ display:block; width:100%; height:100%; object-fit:cover; }
#cbMini .cbm-arte::after{ content:""; position:absolute; inset:0; border-radius:inherit; pointer-events:none;
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 22%, transparent), inset 0 0 0 1px color-mix(in srgb, white 8%, transparent); }
#cbMini .cbm-txt{ min-width:0; display:flex; flex-direction:column; }
#cbMini .cbm-txt b{ font-size:14.5px; font-weight:650; line-height:1.25; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#cbMini .cbm-txt > span{ font-size:12.5px; line-height:1.3; color:var(--t-muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
#cbMini .cbm-b{ display:grid; place-items:center; width:44px; height:44px; flex:none; padding:0; border:0; border-radius:50%;
  background:transparent; color:var(--t-ink); cursor:pointer; transition:transform .25s cubic-bezier(.2,1.5,.4,1), background .2s ease; }
#cbMini .cbm-b .ico{ width:20px; height:20px; }
#cbMini .cbm-pp{ background:color-mix(in srgb, var(--t-ink) 11%, transparent); box-shadow:inset 0 1px 0 color-mix(in srgb, white 24%, transparent); }
#cbMini .cbm-b:active{ transform:scale(.88); }
#cbMini .cbm-ant{ display:none; }
/* la línea del tema, en el borde de abajo del vidrio */
#cbMini .cbm-prog{ position:absolute; left:24px; right:24px; bottom:5px; z-index:1; height:2px; border-radius:2px; overflow:hidden;
  background:color-mix(in srgb, var(--t-ink) 12%, transparent); transition:opacity .3s ease; }
#cbMini .cbm-prog i{ display:block; height:100%; transform-origin:left center; transform:scaleX(var(--p)); background:var(--luz-barra);
  transition:transform .3s linear; }
/* la barra del tema y el tiempo: con Cabina abierta, y en la compu con el mouse encima */
#cbMini .cbm-abajo{ position:absolute; left:18px; right:18px; bottom:8px; z-index:1; display:flex; align-items:center; gap:10px; height:28px;
  opacity:0; transform:translateY(8px); pointer-events:none; transition:opacity .28s ease, transform .38s cubic-bezier(.2,1.2,.35,1); }
#cbMini .cbm-barra{ flex:1; min-width:0; height:28px; margin:0; accent-color:var(--t-reunion); cursor:pointer; }
#cbMini .cbm-tiempo{ flex:none; font-size:11.5px; color:var(--t-muted); font-variant-numeric:tabular-nums; }
html.cb-abierta #cbMini{ height:96px; border-radius:26px; }
html.cb-abierta #cbMini .cbm-ant{ display:grid; }
html.cb-abierta #cbMini .cbm-abajo{ opacity:1; transform:none; pointer-events:auto; }
html.cb-abierta #cbMini .cbm-prog{ opacity:0; }
/* con la barra de arriba (compu): abajo al centro */
@media (min-width:1024px){
  html.cb-mini-on{ --mini-h:88px; }
  html.cb-mini-on.cb-abierta{ --mini-h:126px; }
  #cbMini{ bottom:calc(18px + env(safe-area-inset-bottom, 0px)); width:min(640px, calc(100% - 48px)); }
  #cbMini .cbm-ant{ display:grid; }
}
/* En la compu ancha el presupuestador son dos columnas con scroll PROPIO: ahí el body no scrollea, así
   que el aire del reproductor va adentro de cada columna (lo de abajo pasa por detrás del vidrio y el
   final se alcanza arriba de él). En el body sobraría: agregaría un scroll de la página entera. */
@media screen and (min-width:1200px){
  body{ padding-bottom:0; }
  .controls{ padding-bottom:var(--nav-bot, 0px); }
  .stage{ padding-bottom:calc(40px + var(--nav-bot, 0px)); }
}
/* 🔴 "Si pongo el mouse, que se vea mejor": se aclara (menos blur, más cristalino), se levanta, la luz
   sigue al mouse y aparece la barra del tema. Solo con un puntero de verdad (en el celu :hover se pega). */
:where(html.puntero) #cbMini:hover{ height:96px; border-radius:26px; transform:translateY(-3px);
  background:linear-gradient(180deg, color-mix(in srgb, white 18%, transparent), transparent 60%),
             color-mix(in srgb, var(--t-panel-bg) 26%, transparent);
  -webkit-backdrop-filter:blur(8px) saturate(210%); backdrop-filter:blur(8px) saturate(210%);
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 46%, transparent), inset 0 -1px 1px color-mix(in srgb, white 10%, transparent),
             0 24px 48px -16px color-mix(in srgb, black 60%, transparent), 0 4px 14px -4px color-mix(in srgb, black 25%, transparent); }
:where(html.puntero) #cbMini:hover .cbm-brillo{ opacity:1; }
:where(html.puntero) #cbMini:hover .cbm-abajo{ opacity:1; transform:none; pointer-events:auto; }
:where(html.puntero) #cbMini:hover .cbm-prog{ opacity:0; }
:where(html.puntero) #cbMini:hover .cbm-luz{ opacity:.55; }
:where(html.puntero) #cbMini .cbm-b:hover{ background:color-mix(in srgb, var(--t-ink) 12%, transparent); }
:where(html.puntero) #cbMini .cbm-pp:hover{ background:color-mix(in srgb, var(--t-ink) 18%, transparent); }
@media (prefers-reduced-motion: reduce){
  #cbMini, #cbMini *, #cbMini::before{ transition:none !important; animation:none !important; }
}

/* ==== chat · colores y movimiento (23/09/2026) ====
   Tobi: "el chat está MUY bien, pero quitemos tanto violeta; juguemos con los colores;
   animaciones futuristas sin que pese; el chat tiene que ser el boom de la app".
   Criterio:
   · El violeta deja de ser EL color. La paleta PRO entera (cian → azul → violeta → rosa →
     naranja) aparece como hilo de luz: bordes finos en degradé, no rellenos planos.
   · Tu burbuja: vidrio oscuro con borde en degradé (antes: violeta lleno).
   · Botón principal de las tarjetas: el primario de la app (blanco en oscuro, negro en
     claro) con un destello de luz al aparecer. Links de los avisos: cian.
   · Movimiento liviano: solo opacidad, escala y desenfoque cortos, una sola vez; el
     "pensando" es un brillo que recorre el texto. Nada de translateY (ver teclado-chat)
     y todo quieto con "reducir movimiento". */
html.con-puntero :focus-visible{ outline:none !important; }

#chatIA{
  --ch-hilo-luz:linear-gradient(115deg, color-mix(in srgb, var(--pro-1) 62%, transparent), color-mix(in srgb, var(--pro-3) 48%, transparent) 50%, color-mix(in srgb, var(--pro-4) 55%, transparent));
  --ch-link:var(--t-tab-fmt);   /* el cian de la app (sin hex nuevos) */
  --ch-yo-bg:color-mix(in srgb, var(--a-ink) 8%, var(--a-card));
}
html[data-theme="claro"] #chatIA{ --ch-link:color-mix(in srgb, var(--t-tab-fmt) 50%, var(--a-ink)); --ch-yo-bg:color-mix(in srgb, var(--a-ink) 5%, var(--a-card)); }

/* tu mensaje: vidrio con borde de luz */
#chatIA .ch-msg.yo{ color:var(--a-ink); border:1px solid transparent;
  background:linear-gradient(var(--ch-yo-bg), var(--ch-yo-bg)) padding-box, var(--ch-hilo-luz) border-box; }

/* el cursor del texto que llega y el punto del "pensando" */
#chatIA .ch-msg.ia.stream > :last-child::after, #chatIA .ch-msg.ia.stream:empty::after{ background:linear-gradient(180deg, var(--pro-1), var(--pro-3)); }
#chatIA .ch-estado .paso i{ background:conic-gradient(from 0deg, var(--pro-1), var(--pro-3), var(--pro-4), var(--pro-1)); }
#chatIA .ch-estado .paso:not(.ok) span{
  background:linear-gradient(90deg, var(--a-mut) 0%, var(--a-mut) 35%, var(--a-ink) 50%, var(--a-mut) 65%, var(--a-mut) 100%) 0 0/250% 100%;
  -webkit-background-clip:text; background-clip:text; color:transparent; animation:chBrilloTexto 1.8s linear infinite; }
@keyframes chBrilloTexto{ from{ background-position:100% 0; } to{ background-position:-150% 0; } }

/* tarjetas de acción: la que espera tu OK lleva el borde de luz; el resto, su color de estado */
#chatIA .ch-acc.pide{ border-color:transparent;
  background:linear-gradient(var(--a-card), var(--a-card)) padding-box, var(--ch-hilo-luz) border-box; }
#chatIA .ch-acc .si{ background:var(--t-btn-primary-bg); color:var(--t-btn-primary-ink); position:relative; overflow:hidden; isolation:isolate;
  transition:background .18s ease, box-shadow .25s ease, transform .12s ease; }
#chatIA .ch-acc .si::after{ content:''; position:absolute; inset:0; pointer-events:none; z-index:1;
  background:linear-gradient(100deg, transparent 32%, color-mix(in srgb, var(--pro-1) 38%, transparent) 46%, color-mix(in srgb, var(--pro-4) 32%, transparent) 56%, transparent 70%) 0 0/300% 100% no-repeat;
  background-position:120% 0; animation:chDestello 1.3s cubic-bezier(.3,.7,.2,1) .35s 1 both; }
@keyframes chDestello{ from{ background-position:120% 0; } to{ background-position:-40% 0; } }
:where(html.puntero) #chatIA .ch-acc .si:hover{ background:var(--t-btn-primary-hover); box-shadow:0 8px 22px -10px color-mix(in srgb, var(--pro-2) 75%, transparent); }
#chatIA .ch-acc .si:active{ transform:scale(.97); }

/* avisos y chips: cian en vez de violeta; el chip destacado con borde de luz */
#chatIA .ch-link, #chatIA .ch-link.p{ color:var(--ch-link); }
#chatIA .ch-link.dim{ color:var(--a-dim); }
#chatIA .ch-chip.p{ color:var(--a-ink); border:1px solid transparent;
  background:linear-gradient(var(--a-card), var(--a-card)) padding-box, var(--ch-hilo-luz) border-box; }
:where(html.puntero) #chatIA .ch-chip:not(.p):hover{ border-color:color-mix(in srgb, var(--pro-1) 45%, var(--a-line)); color:var(--a-ink); }
#chatIA .ch-chip:active, #chatIA .ch-aviso .acts .ch-link:active{ transform:scale(.97); }

/* En el celu: el micrófono protagonista (campo vacío) con degradé frío, no violeta pleno,
   y la acción principal de cada aviso (que ahí es una píldora) con el borde de luz. En la
   compu los avisos son links de texto y lo principal es escribir: quedan como están. */
@media (max-width:1023px){
  #chatIA .ch-row:not(.con-texto) .ch-mic{ background:linear-gradient(135deg, var(--pro-1), var(--pro-2) 55%, var(--pro-3)); color:white; border-color:transparent;
    box-shadow:0 8px 20px -10px color-mix(in srgb, var(--pro-2) 80%, transparent); }
  #chatIA .ch-aviso .acts .ch-link.p{ color:var(--a-ink); border:1px solid transparent;
    background:linear-gradient(var(--a-card), var(--a-card)) padding-box, var(--ch-hilo-luz) border-box; }
}

/* el campo: al enfocarlo, el borde se vuelve un hilo de luz y una línea de brillo lo recorre una vez */
#chatIA .ch-row{ position:relative; }
#chatIA .ch-row:focus-within{ border-color:transparent; box-shadow:0 0 26px -14px color-mix(in srgb, var(--pro-2) 70%, transparent);
  background:linear-gradient(var(--a-input), var(--a-input)) padding-box, var(--ch-hilo-luz) border-box; }
#chatIA .ch-row::after{ content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none; opacity:0;
  background:linear-gradient(100deg, transparent 40%, color-mix(in srgb, var(--pro-1) 16%, transparent) 50%, transparent 60%) 0 0/300% 100% no-repeat; }
#chatIA .ch-row:focus-within::after{ animation:chBarrido 1.1s cubic-bezier(.3,.7,.2,1) 1; }
@keyframes chBarrido{ from{ opacity:1; background-position:130% 0; } to{ opacity:1; background-position:-30% 0; } }

/* lo que entra al hilo aparece enfocándose (sin moverse de lugar) */
#chatIA #chatIAHilo > .ch-msg, #chatIA #chatIAHilo > .ch-acc{ animation:chAparece .34s cubic-bezier(.2,.8,.2,1) both; }
@keyframes chAparece{ from{ opacity:0; transform:scale(.985); filter:blur(5px); } to{ opacity:1; transform:none; filter:none; } }

@media (prefers-reduced-motion: reduce){
  #chatIA .ch-estado .paso:not(.ok) span, #chatIA .ch-acc .si::after, #chatIA .ch-row:focus-within::after,
  #chatIA #chatIAHilo > .ch-msg, #chatIA #chatIAHilo > .ch-acc{ animation:none; }
  #chatIA .ch-acc .si::after{ opacity:0; }
}

/* ==== app · capa de diseño, el mismo lenguaje del chat (24/09/2026) ====
   Tobi: "comencemos con el rediseño (sutil) como el chat". Lo mismo que se hizo en el
   chat, llevado al resto: el violeta deja de estar en todo.
   · Números y montos en tinta (blanco/negro), no en violeta: se leen como dato, no adorno.
   · Links en cian. Lo seleccionado (hoy, el día elegido, la pestaña activa, el filtro)
     con un borde de luz en degradé en vez de un borde violeta.
   · Botones principales: el primario de la app (blanco en oscuro, negro en claro).
   · Barras con degradé frío. Panel en la barra de navegación: neutro; Historial: verde
     agua (antes los dos violetas).
   · Movimiento mínimo: el día de hoy respira, los botones se hunden al tocarlos, las
     tarjetas del Panel se iluminan al pasar el mouse. Nada con "reducir movimiento".
   Sin hex nuevos: todo sale de los tokens del tema, así el modo claro se acomoda solo. */
:root{
  --luz:linear-gradient(115deg, color-mix(in srgb, var(--t-tab-fmt) 72%, transparent), color-mix(in srgb, var(--t-info) 58%, transparent) 38%,
        color-mix(in srgb, var(--t-personal) 55%, transparent) 66%, color-mix(in srgb, var(--t-reunion) 62%, transparent));
  --luz-barra:linear-gradient(90deg, var(--t-tab-fmt), var(--t-info) 55%, var(--t-personal));
  --link:var(--t-tab-fmt);
}
html[data-theme="claro"]{ --link:color-mix(in srgb, var(--t-tab-fmt) 50%, var(--t-ink)); }

/* navegación */
#navbar .nvb[data-pag="0"]{ --nvc:var(--t-ink); --nvbg:color-mix(in srgb, var(--t-ink) 10%, transparent); }
#navbar .nvb[data-pag="4"]{ --nvc:var(--t-teal); --nvbg:color-mix(in srgb, var(--t-teal) 16%, transparent); }

/* links */
#dash .dent-go, :is(#dash,#notis) .dallink, .ia-open, #agGlobo .ag-btn, #hist .hev-pv, .ag-quick{ color:var(--link); }
#dash .dent-go .dk-go{ border-color:var(--link); }

/* números y montos: tinta */
.ag-stat .v, .ag-item .amt, .ag-folder-hd .fmeta b, #numeros .nm-ev .tot, .mt-col.hoy .mt-mon{ color:var(--a-ink); }

/* títulos de sección de la ficha: tenues, con un trazo de luz */
#dashFicha .fsec{ color:var(--d-mut); background:var(--luz-barra) left bottom / 28px 2px no-repeat; }

/* lo seleccionado: borde de luz */
#dash .dd-day.hoy .num{ color:var(--d-ink); }
#dash .dd-day.hoy .dow{ color:var(--link); }
#dash .dd-day.on{ border-color:transparent; background:linear-gradient(var(--d-card2), var(--d-card2)) padding-box, var(--luz) border-box; }
.ag-cell.today{ border-color:transparent; background:linear-gradient(var(--a-input), var(--a-input)) padding-box, var(--luz) border-box; }
.ag-cell.today .dn{ color:var(--a-ink); }
.ag-tab.on{ border-color:transparent; background:linear-gradient(var(--a-card), var(--a-card)) padding-box, var(--luz) border-box; }
#hist .hchip[aria-pressed="true"]{ border-color:transparent; background:linear-gradient(var(--d-card), var(--d-card)) padding-box, var(--luz) border-box; }
#dash .dtab.on{ color:var(--d-ink); background:color-mix(in srgb, var(--t-ink) 10%, transparent); }
#dash .dmon-s.on{ box-shadow:none; border:1px solid transparent; background:linear-gradient(var(--d-card), var(--d-card)) padding-box, var(--luz) border-box; }
#dashFicha .fvolc{ border-color:transparent; background:linear-gradient(var(--d-card), var(--d-card)) padding-box, var(--luz) border-box; }

/* botones principales: el primario de la app */
#dashFicha .fpg-add, #dash .dtareaform button, #agGlobo .ag-chip.p, #volcado .vo-pri, #chkVista .chk-btn.p, .ia-go{
  background:var(--t-btn-primary-bg); border-color:transparent; color:var(--t-btn-primary-ink); }
:where(html.puntero) :is(#dashFicha .fpg-add, #dash .dtareaform button, #agGlobo .ag-chip.p, #volcado .vo-pri, #chkVista .chk-btn.p, .ia-go):hover{ background:var(--t-btn-primary-hover); }
:is(#dashFicha .fpg-add, #dash .dtareaform button, #agGlobo .ag-chip.p, #volcado .vo-pri, #chkVista .chk-btn.p, .ia-go, #dash .dbtn, .ag-act, #hist .hev-pv):active{ transform:scale(.97); }

/* insignias y barras */
#btnAgenda .agcount, .ag-toast .dot, .ia-chispa{ background:var(--luz-barra); }
.ag-toast{ border-color:color-mix(in srgb, var(--t-tab-fmt) 45%, var(--uiline)); }
#dash i.ev{ background:linear-gradient(180deg, var(--t-info), var(--t-personal)); }
#dash .dbar.acc i, #dash .dtend .c.on .b{ background:var(--luz-barra); }

/* movimiento mínimo */
#dash .dd-day.hoy{ position:relative; }
#dash .dd-day.hoy::after{ content:''; position:absolute; inset:-1px; border-radius:inherit; pointer-events:none;
  box-shadow:0 0 18px -4px color-mix(in srgb, var(--t-tab-fmt) 55%, transparent); opacity:.25; animation:diaRespira 4.5s ease-in-out infinite; }
@keyframes diaRespira{ 0%,100%{ opacity:.2; } 50%{ opacity:.85; } }
#dash .dpanel{ transition:border-color .25s ease, box-shadow .3s ease; }
:where(html.puntero) #dash .dpanel:hover{ border-color:color-mix(in srgb, var(--t-tab-fmt) 30%, var(--d-line));
  box-shadow:0 18px 40px -30px color-mix(in srgb, var(--t-info) 60%, transparent); }
@media (prefers-reduced-motion: reduce){
  #dash .dd-day.hoy::after{ animation:none; opacity:.4; }
  #dash .dpanel{ transition:none; }
}

/* ==== Beta debajo del logo + "Reportar algo" (24/09/2026) ==== */
#dash .dlogo-caja{ display:flex; flex-direction:column; align-items:flex-start; gap:4px; flex:none; }
#dash .dbeta{ position:relative; font:inherit; font-family:var(--font-display, ui-monospace, Menlo, monospace); font-size:9px; font-weight:700;
  letter-spacing:.2em; text-transform:uppercase; color:var(--d-mut); padding:2px 8px; min-height:18px; border-radius:999px; cursor:pointer;
  border:1px solid transparent; background:linear-gradient(var(--d-canvas, var(--t-bg)), var(--d-canvas, var(--t-bg))) padding-box, var(--luz) border-box; }
/* la zona de toque llega a 44pt aunque la píldora sea chica */
#dash .dbeta::before{ content:''; position:absolute; inset:-13px -8px; }
:where(html.puntero) #dash .dbeta:hover{ color:var(--d-ink); }
#dash .dbeta:active{ transform:scale(.96); }

#reporte{ position:fixed; inset:0; z-index:10110; display:flex; align-items:flex-end; justify-content:center; }
/* 🔴 24/09/2026 (Tobi: "cuando toco beta y cierro, se bugea toda la página"): el display:flex de
   arriba le ganaba al atributo hidden, así que al cerrar la hoja quedaba una capa INVISIBLE
   tapando toda la pantalla y no dejaba tocar ni desplazar nada. Cerrada, no existe; y mientras
   se va (los 220 ms de la animación) ya no ataja toques. */
#reporte[hidden]{ display:none !important; }
#reporte:not(.on){ pointer-events:none; }
#reporte .rp-velo{ position:absolute; inset:0; background:var(--t-overlay); opacity:0; transition:opacity .22s ease; }
#reporte .rp-hoja{ position:relative; width:min(560px, 100%); max-height:88dvh; overflow:auto; box-sizing:border-box;
  padding:18px 18px calc(18px + env(safe-area-inset-bottom, 0px)); border-radius:22px 22px 0 0;
  background:var(--uicard); color:var(--uitext); border:1px solid transparent;
  background:linear-gradient(var(--uicard), var(--uicard)) padding-box, var(--luz) border-box;
  opacity:0; transform:scale(.98); filter:blur(4px); transition:opacity .24s ease, transform .24s cubic-bezier(.2,.8,.2,1), filter .24s ease; }
#reporte.on .rp-velo{ opacity:1; }
#reporte.on .rp-hoja{ opacity:1; transform:none; filter:none; }
@media (min-width:700px){ #reporte{ align-items:center; } #reporte .rp-hoja{ border-radius:22px; } }
#reporte .rp-hd{ display:flex; gap:12px; align-items:flex-start; justify-content:space-between; margin-bottom:12px; }
#reporte h2{ margin:0; font-size:19px; letter-spacing:-.01em; }
#reporte .rp-hd p{ margin:4px 0 0; color:var(--uimut); font-size:13px; }
#reporte .rp-x{ flex:none; width:40px; height:40px; border-radius:12px; border:1px solid var(--uiline); background:transparent; color:var(--uimut); font:inherit; cursor:pointer; }
#reporte textarea{ width:100%; box-sizing:border-box; min-height:120px; resize:vertical; font:inherit; font-size:16px; line-height:1.45; padding:12px 14px;
  border-radius:14px; border:1px solid var(--uiline); background:var(--t-input); color:var(--uitext); }
#reporte textarea:focus{ outline:none; border-color:transparent; background:linear-gradient(var(--t-input), var(--t-input)) padding-box, var(--luz) border-box; }
#reporte .rp-fila{ display:flex; align-items:center; gap:12px; margin-top:10px; }
#reporte .rp-adj span{ display:inline-flex; align-items:center; min-height:40px; padding:0 14px; border-radius:999px; border:1px dashed var(--uiline); color:var(--link); font-size:13.5px; cursor:pointer; }
#reporte #rpMini{ height:56px; width:auto; border-radius:8px; border:1px solid var(--uiline); }
#reporte .rp-ctx{ margin:10px 0 0; font-size:12px; color:var(--uimut); line-height:1.45; }
#reporte .rp-acc{ display:flex; gap:10px; justify-content:flex-end; margin-top:14px; }
#reporte .rp-no, #reporte .rp-si{ min-height:44px; padding:0 18px; border-radius:12px; font:inherit; font-size:15px; font-weight:600; cursor:pointer; }
#reporte .rp-no{ background:transparent; border:1px solid var(--uiline); color:var(--uitext); }
#reporte .rp-si{ background:var(--t-btn-primary-bg); color:var(--t-btn-primary-ink); border:0; }
#reporte .rp-si:disabled{ opacity:.55; }
#reporte .rp-si:active, #reporte .rp-no:active{ transform:scale(.97); }
#reporte .rp-msg{ margin:10px 0 0; min-height:1em; font-size:13px; color:var(--uimut); }
#reporte .rp-lista h3{ margin:18px 0 8px; font-size:11px; letter-spacing:.14em; text-transform:uppercase; color:var(--uimut); }
#reporte .rp-item{ padding:10px 0; border-top:1px solid var(--uiline); }
#reporte .rp-it-hd{ display:flex; gap:8px; align-items:center; justify-content:space-between; }
#reporte .rp-est{ font-size:11px; font-weight:700; padding:2px 8px; border-radius:999px; background:color-mix(in srgb, var(--uitext) 10%, transparent); }
#reporte .rp-est.arreglado{ color:var(--t-ok); background:color-mix(in srgb, var(--t-ok) 15%, transparent); }
#reporte .rp-est.visto{ color:var(--t-info); background:color-mix(in srgb, var(--t-info) 15%, transparent); }
#reporte .rp-est.pendiente{ color:var(--t-warn); background:color-mix(in srgb, var(--t-warn) 15%, transparent); }
#reporte .rp-fe{ font-size:11.5px; color:var(--uimut); font-variant-numeric:tabular-nums; }
#reporte .rp-tx{ margin-top:6px; font-size:13.5px; line-height:1.45; }
#reporte .rp-nota{ margin-top:6px; font-size:12.5px; color:var(--t-ok); }
@media (prefers-reduced-motion: reduce){ #reporte .rp-velo, #reporte .rp-hoja{ transition:none; } }

/* ==== Agenda · calendario y Métricas con el estilo del chat (24/09/2026) ====
   Tobi: "en la agenda, el diseño del chat… sutil. Ponele animaciones al gráfico de la
   agenda. Esos colores pastel así quedan feos, dale más el estilo del chat".
   · El día con eventos ya no se rellena entero con el color del estado (eso era el pastel):
     vidrio oscuro, borde del color, un resplandor que sube desde abajo y una barrita que
     brilla. Con más de un estado la barrita se parte en tramos y el borde es un degradé.
     El color llega en --pc / --pc-borde / --pc-barra desde drawCalendar (Agenda y Panel).
   · Entrada: los días aparecen en cascada y las barritas se encienden, al abrir la Agenda,
     al cambiar de mes o de pestaña. `--ya` (entrada() en agenda.js) hace que un redibujo
     a mitad de camino siga desde donde iba en vez de arrancar de cero.
   · Métricas: las barras crecen desde abajo, tramos separados con brillo propio.
   · Buscador con el hilo de luz del campo del chat; filtro como píldora; carpetas sin emoji.
   Sin hex nuevos y sin translateY. Con "reducir movimiento", todo quieto. */
:root{ --pc-glow:36%; }
html[data-theme="claro"]{ --pc-glow:15%; }   /* en claro el resplandor fuerte se leía otra vez como pastel */
.ag-cell.pintado{ border-color:color-mix(in srgb, var(--pc) 62%, transparent);
  background:radial-gradient(120% 95% at 50% 118%, color-mix(in srgb, var(--pc) var(--pc-glow, 36%), transparent), transparent 70%), var(--a-input); }
.ag-cell.pintado .dn{ color:var(--a-ink); font-weight:700; }
.ag-cell.pintado .cnt{ color:color-mix(in srgb, var(--a-ink) 70%, transparent); }
.ag-cell.pintado::after{ content:''; position:absolute; left:22%; right:22%; bottom:5px; height:3px; border-radius:3px; pointer-events:none;
  background:var(--pc-barra, var(--pc)); box-shadow:0 0 10px color-mix(in srgb, var(--pc) 75%, transparent); }
.ag-cell.pintado.multi{ border-color:transparent;
  background:radial-gradient(120% 95% at 50% 118%, color-mix(in srgb, var(--pc) var(--pc-glow, 36%), transparent), transparent 70%) padding-box,
             linear-gradient(var(--a-input), var(--a-input)) padding-box, var(--pc-borde) border-box; }
.ag-cell.pintado.today{ box-shadow:0 0 16px -3px color-mix(in srgb, var(--t-tab-fmt) 70%, transparent), inset 0 0 0 1px color-mix(in srgb, var(--a-ink) 55%, transparent); }
.ag-cell.pintado.sel{ box-shadow:inset 0 0 0 1.5px var(--a-ink), 0 0 18px -5px color-mix(in srgb, var(--pc) 90%, transparent); }
.ag-cell.sel:not(.pintado){ border-color:transparent;
  background:linear-gradient(color-mix(in srgb, var(--t-ink) 8%, var(--a-input)), color-mix(in srgb, var(--t-ink) 8%, var(--a-input))) padding-box, var(--luz) border-box; }
:where(html.puntero) .ag-cell.pintado:hover{ filter:none; box-shadow:0 0 18px -6px color-mix(in srgb, var(--pc) 85%, transparent); }
.ag-cell.today::before{ content:''; position:absolute; inset:-1px; border-radius:inherit; pointer-events:none;
  box-shadow:0 0 14px -3px color-mix(in srgb, var(--t-tab-fmt) 60%, transparent); opacity:.3; animation:diaRespira 4.5s ease-in-out infinite; }

/* la cascada: 14 ms por día; --ya descuenta lo que ya pasó si el mes se redibujó en el medio */
.entra > .ag-cell:not(.vacia){ animation:celdaEntra .45s cubic-bezier(.2,.8,.2,1) both; animation-delay:calc(var(--i, 0) * 14ms - var(--ya, 0ms)); }
.entra > .ag-cell.pintado::after{ animation:barraEnciende .5s ease-out both; animation-delay:calc(var(--i, 0) * 14ms + 200ms - var(--ya, 0ms)); }
@keyframes celdaEntra{ from{ opacity:0; transform:scale(.9); filter:blur(2px); } to{ opacity:1; transform:none; filter:none; } }
@keyframes barraEnciende{ from{ transform:scaleX(0); opacity:0; } to{ transform:none; opacity:1; } }

/* Métricas: tramos separados que brillan con su color; crecen en cascada, mes por mes */
#agenda .mt-bar{ overflow:visible; transform-origin:bottom; }
#agenda .mt-seg{ border-radius:3px;
  background-image:linear-gradient(180deg, color-mix(in srgb, white 18%, transparent), transparent 45%);
  box-shadow:inset 0 1px 0 color-mix(in srgb, white 30%, transparent), 0 0 14px -4px color-mix(in srgb, currentColor 65%, transparent); }
#agenda .mt-seg.confirmado{ color:var(--m-conf); } #agenda .mt-seg.espera{ color:var(--m-esp); } #agenda .mt-seg.consultar{ color:var(--m-cons); }
html[data-theme="claro"] #agenda .mt-seg{ box-shadow:inset 0 1px 0 color-mix(in srgb, white 30%, transparent), 0 3px 8px -4px color-mix(in srgb, currentColor 55%, transparent); }
#agenda .mt-legend i, #agenda .mt-detail i{ border-radius:50%; }
#agenda .mt-plot.entra .mt-bar{ animation:barraCrece .6s cubic-bezier(.2,.8,.2,1) both; animation-delay:calc(var(--i, 0) * 40ms - var(--ya, 0ms)); }
#agenda .mt-plot.entra .mt-val{ animation:valAparece .35s ease-out both; animation-delay:calc(var(--i, 0) * 40ms + 380ms - var(--ya, 0ms)); }
@keyframes barraCrece{ from{ transform:scaleY(0); } to{ transform:none; } }
@keyframes valAparece{ from{ opacity:0; } to{ opacity:1; } }

/* el buscador, como el campo del chat: al enfocarlo, borde de luz y un brillo que lo recorre una vez */
#agenda .ag-buscar:focus-within{ border-color:transparent; color:var(--a-ink);
  background:linear-gradient(var(--a-input), var(--a-input)) padding-box, var(--luz) border-box;
  box-shadow:0 0 26px -14px color-mix(in srgb, var(--t-tab-fmt) 70%, transparent); }
#agenda .ag-buscar::after{ content:''; position:absolute; inset:0; border-radius:inherit; pointer-events:none; opacity:0;
  background:linear-gradient(100deg, transparent 40%, color-mix(in srgb, var(--t-tab-fmt) 14%, transparent) 50%, transparent 60%) 0 0/300% 100% no-repeat; }
#agenda .ag-buscar:focus-within::after{ animation:chBarrido 1.1s cubic-bezier(.3,.7,.2,1) 1; }

/* el filtro de estados: píldora como las del chat, con su flechita (el select nativo de iOS desentonaba) */
#agenda .ag-filter{ -webkit-appearance:none; appearance:none; padding-right:36px;
  background-image:linear-gradient(45deg, transparent 50%, var(--a-mut) 50%), linear-gradient(135deg, var(--a-mut) 50%, transparent 50%);
  background-position:calc(100% - 20px) calc(50% + 1px), calc(100% - 15px) calc(50% + 1px); background-size:5px 5px, 5px 5px; background-repeat:no-repeat; }
#agenda .ag-filter:focus{ border-color:transparent;
  background:linear-gradient(45deg, transparent 50%, var(--a-mut) 50%) calc(100% - 20px) calc(50% + 1px)/5px 5px no-repeat,
             linear-gradient(135deg, var(--a-mut) 50%, transparent 50%) calc(100% - 15px) calc(50% + 1px)/5px 5px no-repeat,
             linear-gradient(var(--a-input), var(--a-input)) padding-box, var(--luz) border-box; }

/* carpetas: la marca es un punto (Confirmados, con brillo) o un anillo (No confirmados), no un emoji */
.ag-folder-hd .fico{ width:9px; height:9px; border-radius:50%; box-sizing:border-box; border:1.5px solid var(--a-mut); font-size:0; }
.ag-folder.confirm .fico{ border-color:transparent; background:var(--a-green); box-shadow:0 0 10px color-mix(in srgb, var(--a-green) 70%, transparent); }
/* el estado en cada evento: el puntito brilla con su color, como los del chat */
.ag-st::before{ box-shadow:0 0 8px -1px currentColor; }

@media (prefers-reduced-motion: reduce){
  .entra > .ag-cell:not(.vacia), .entra > .ag-cell.pintado::after, .ag-cell.today::before,
  #agenda .mt-plot.entra .mt-bar, #agenda .mt-plot.entra .mt-val, #agenda .ag-buscar:focus-within::after{ animation:none; }
}

/* ==== Voz · el atajo de mantener la pantalla y la pantalla inmersiva (24/09/2026) ====
   Tobi: "cuando mantengo la pantalla, que se abra el círculo del agente de voz y el fondo
   se blurree; que detecte las ondas como cuando hablás con ChatGPT; que no se muestre el
   texto que voy hablando; muy estético". La pantalla de voz deja de ser un fondo liso: es
   vidrio sobre lo que estabas mirando. En el centro, solo el orbe con sus ondas (el
   <canvas> que dibuja voz.js) y abajo una línea de estado. Lo que decís y la respuesta no
   se escriben; lo que el agente hizo aparece un momento en una píldora con el borde de luz.
   Sin hex ni rgba nuevos: todo sale de los tokens, así el vidrio es oscuro en oscuro y claro
   en claro. Con "reducir movimiento" no hay vuelo, ni aro animado, ni ondas. */
#vozModo{ background:color-mix(in srgb, var(--t-panel-bg) 42%, transparent);
  -webkit-backdrop-filter:blur(26px) saturate(150%); backdrop-filter:blur(26px) saturate(150%); }
#vozModo.on{ animation:vzAparece .34s ease-out both; }
#vozModo.sale{ animation:vzSeVa .22s ease-in both; pointer-events:none; }
@keyframes vzAparece{ from{ opacity:0; } to{ opacity:1; } }
@keyframes vzSeVa{ from{ opacity:1; } to{ opacity:0; } }
#vozModo .vz-k, #vozModo.vivo .vz-k{ display:inline-flex; align-items:center; gap:8px; font-size:10.5px; letter-spacing:1.8px; color:var(--t-panel-muted); }
#vozModo.vivo .vz-k::before{ content:''; width:6px; height:6px; border-radius:50%; background:var(--t-tab-fmt); box-shadow:0 0 8px var(--t-tab-fmt); }   /* en vivo: un punto cian, no el violeta */
#vozModo .vz-x, #vozModo .vz-cfg{ border-color:color-mix(in srgb, var(--t-panel-ink) 16%, transparent); background:color-mix(in srgb, var(--t-panel-ink) 7%, transparent); }
#vozModo .vz-x{ width:44px; height:44px; font-size:15px; }
#vozModo .vz-centro{ gap:10px; }
#vozModo .vz-escena{ position:relative; width:min(340px, 86vw); aspect-ratio:1/1; display:grid; place-items:center; flex:none; }
#vozModo .vz-escena.vuela{ animation:vzVuela .62s cubic-bezier(.2,.9,.25,1) both; }
@keyframes vzVuela{ from{ transform:translate(var(--vz-dx, 0px), var(--vz-dy, 0px)) scale(.26); opacity:.4; } to{ transform:none; opacity:1; } }
#vozModo .vz-ondas{ position:absolute; inset:0; width:100%; height:100%; pointer-events:none; }
#vozModo .vz-orbe{ position:relative; width:168px; height:168px; }
#vozModo .vz-orbe .agente-orbe{ width:150px; height:150px; will-change:transform;
  box-shadow:0 0 0 1px color-mix(in srgb, var(--pro-3) 40%, transparent), 0 22px 70px -24px color-mix(in srgb, var(--pro-2) 75%, transparent); }
#vozModo.onda .vz-orbe .agente-orbe{ animation:none; }
#vozModo.pausa .vz-orbe .agente-orbe{ opacity:.5; filter:saturate(.5); }
#vozModo .vz-estado{ font-size:14px; letter-spacing:.2px; min-height:20px; color:color-mix(in srgb, var(--t-panel-ink) 78%, transparent); }
#vozModo .vz-oido{ display:none !important; }
#vozModo .vz-resp{ display:none; }
#vozModo.falla .vz-resp{ display:block; font-size:15px; line-height:1.4; color:var(--t-panel-ink); max-width:420px; text-wrap:balance; }
#vozModo .vz-hecho{ max-width:min(420px, 86vw); padding:9px 16px; border-radius:999px; font-size:14px; font-weight:600; line-height:1.3; text-align:center;
  color:var(--t-panel-ink); border:1px solid transparent;
  background:linear-gradient(color-mix(in srgb, var(--t-panel-bg) 70%, transparent), color-mix(in srgb, var(--t-panel-bg) 70%, transparent)) padding-box, var(--luz) border-box; }
#vozModo .vz-hecho.mal{ background:color-mix(in srgb, var(--t-err) 14%, var(--t-panel-bg)); border-color:color-mix(in srgb, var(--t-err) 55%, transparent); }
#vozModo .vz-hecho:not([hidden]){ animation:vzHecho .32s cubic-bezier(.2,.8,.2,1) both; }
@keyframes vzHecho{ from{ opacity:0; transform:scale(.94); filter:blur(3px); } to{ opacity:1; transform:none; filter:none; } }

/* el aro que crece bajo el dedo mientras se mantiene (lo pone voz.js en el punto del dedo) */
#vzToque{ position:fixed; left:0; top:0; z-index:10096; width:92px; height:92px; margin:-46px 0 0 -46px; pointer-events:none; opacity:0; }
#vzToque::before{ content:''; position:absolute; inset:0; border-radius:50%; background:var(--luz);
  -webkit-mask:radial-gradient(farthest-side, transparent calc(100% - 3px), black calc(100% - 2.5px));
  mask:radial-gradient(farthest-side, transparent calc(100% - 3px), black calc(100% - 2.5px)); }
#vzToque::after{ content:''; position:absolute; inset:-14px; border-radius:50%; background:radial-gradient(circle, color-mix(in srgb, var(--t-tab-fmt) 30%, transparent), transparent 68%); }
#vzToque.carga{ animation:vzCarga .3s cubic-bezier(.3,.7,.3,1) both; }
#vzToque.dispara{ animation:vzDispara .44s ease-out both; }
@keyframes vzCarga{ from{ opacity:0; transform:scale(.4); } to{ opacity:1; transform:scale(1); } }
@keyframes vzDispara{ from{ opacity:1; transform:scale(1); } to{ opacity:0; transform:scale(1.9); } }
/* 🔴 MANTENER NO ES SELECCIONAR (en pantallas táctiles). iOS decide si lo que está bajo el dedo
   es texto seleccionable EN EL MOMENTO de apoyarlo: si lo es, al medio segundo aparece la lupa
   de texto encima del orbe (se vio en el simulador, grabando el gesto). Apagarlo a mitad del
   gesto llega tarde. Así que, como en una app nativa, en el celu las pantallas no seleccionan
   texto al mantener; los campos, el chat y los reportes sí. En la compu (mouse) no cambia nada. */
@media (hover:none) and (pointer:coarse){
  body{ -webkit-user-select:none; user-select:none; -webkit-touch-callout:none; }
  input, textarea, select, [contenteditable]:not([contenteditable="false"]), #chatIA, #reporte, [data-seleccionable]{ -webkit-user-select:text; user-select:text; -webkit-touch-callout:default; }
}
/* mientras se mantiene: sin selección ni menú de iOS en ningún lado (refuerzo, solo durante el gesto) */
html.vz-sostiene, html.vz-sostiene *{ -webkit-user-select:none !important; user-select:none !important; -webkit-touch-callout:none !important; }

/* sin desenfoque (iOS con "Reducir transparencia", o un navegador que no lo tiene): vidrio casi opaco, que se lea igual */
@media (prefers-reduced-transparency: reduce){ #vozModo{ background:color-mix(in srgb, var(--t-panel-bg) 94%, transparent); } }
@supports not ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){ #vozModo{ background:color-mix(in srgb, var(--t-panel-bg) 94%, transparent); } }
@media (prefers-reduced-motion: reduce){
  #vozModo.on, #vozModo.sale, #vozModo .vz-escena.vuela, #vozModo .vz-hecho:not([hidden]), #vzToque.dispara{ animation:none; }
  #vzToque.carga{ animation:none; opacity:1; }
}

/* 🎵 Las tarjetas de música del Agente Pro (28/09/2026): la lista de temas va plegada y se abre con un toque. */
#chatIA .ch-acc details.ch-lista{ margin-top:8px; }
#chatIA .ch-acc details.ch-lista summary{ cursor:pointer; color:var(--ch-link); font-weight:600; font-size:13px; min-height:36px; display:flex; align-items:center; list-style:none; }
#chatIA .ch-acc details.ch-lista summary::-webkit-details-marker{ display:none; }
#chatIA .ch-acc details.ch-lista summary::after{ content:'›'; margin-left:6px; transition:transform .15s ease; }
#chatIA .ch-acc details.ch-lista[open] summary::after{ transform:rotate(90deg); }
#chatIA .ch-acc details.ch-lista ol{ margin:2px 0 0; padding-left:24px; font-size:12.5px; line-height:1.5; color:var(--a-mut); font-variant-numeric:tabular-nums; }
#chatIA .ch-acc .ch-lista-cambios{ list-style:none; padding-left:0; margin:6px 0 0; font-size:12.5px; line-height:1.5; }
@media (prefers-reduced-motion: reduce){ #chatIA .ch-acc details.ch-lista summary::after{ transition:none; } }
