/* Estudio · sistema de diseno (handoff Claude Design, paleta calida arcilla/hueso). */
:root{
  /* ---- Vocabulario de movimiento (2026-08-21) ----
     Antes: 156 transiciones en este archivo y NI UNA con curva propia -- todas caian al
     `ease` por defecto, que es plano y sin caracter. Las duraciones, en cambio, ya estaban
     bien: se agrupaban en .15-.18s. Estos tokens no cambian el ritmo, le ponen curva.
     Definidos para todo el CRM; en esta tanda solo los adopta el panel de galerias. */
  --ease-entra: cubic-bezier(.16, 1, .3, 1);    /* algo que LLEGA: arranca rapido, frena suave */
  --ease-estado: cubic-bezier(.4, 0, .2, 1);    /* algo que CAMBIA estando ya a la vista */
  --dur-1: 120ms;   /* micro: color, hover           */
  --dur-2: 180ms;   /* estandar                       */
  --dur-3: 240ms;   /* paneles y superficies grandes  */
  /* --muted oscurecido de #87847A a #6A675D para alcanzar contraste AA (>=4.5:1) sobre
     paper, bone y deep: se usa en texto pequeno (10-13px) por toda la app (metadatos,
     etiquetas de KPI, estados) que antes quedaba ~3.3:1, ilegible al sol en el celular. */
  --bone:#F3F1EA; --paper:#FCFBF7; --deep:#EFEBE0; --ink:#2B2926; --muted:#6A675D;
  --hair:#E7E3D8; --line2:#DCD7CA; --red:#C96442; --blue:#6E7F63; --yellow:#C79A4E;
  /* --r baja de 11px a 4px con el rediseno minimalista. Vive en :root y no en el bloque
     oscuro a proposito: la GEOMETRIA es la misma en los dos temas, lo que cambia entre
     ellos es la paleta. */
  --accent:#C96442;
  /* --r se mudo a cuarto-oscuro.css: la GEOMETRIA tambien es del sistema de diseno. */
  /* Modo claro: el relleno solido conserva los valores de SIEMPRE (naranja + texto
     blanco). El rediseno minimalista solo redefine estos dos en el bloque oscuro, asi
     que el tema claro queda exactamente como estaba. */
  --accent-solido:#C96442; --accent-tinta:#fff;
  /* Tinte del boton de Xarpie en el nav (mismo RGB que --accent, solo con alpha): se
     redefine junto con --accent en el bloque de tema oscuro de abajo, para que el boton
     no se quede con el tono del tema equivocado si el fotografo cambia de tema en vivo. */
  --tint-xarpie:rgba(201,100,66,.1);
  /* Tinte generico de acento (chips, fondos suaves): mismo criterio que --tint-xarpie
     (RGB de --accent con alpha), pero sin atarlo semanticamente a un solo boton. Se
     redefine junto con --accent en el tema oscuro de abajo, mismo motivo. */
  --tint:rgba(201,100,66,.09);
  /* UNA sola declaracion de la voz tipografica. Antes se declaraba aqui (Newsreader /
     Hanken / Space Mono) y se volvia a declarar 1300 lineas abajo con otras fuentes; la
     segunda ganaba por cascada, asi que lo que se leia aqui no era lo que se veia en
     pantalla. El handoff no usa monospace: las etiquetas van en Instrument Sans en
     mayusculas con letter-spacing. */
  --serif:'Instrument Sans',system-ui,sans-serif;
  /* --sans se mudo a cuarto-oscuro.css (ver la nota de la escala de tipo, abajo). */
  --mono:'Instrument Sans',system-ui,sans-serif;
  /* Escala de tipo cerrada (rediseno minimalista, pase de oficio): cada tamano tiene un trabajo.
     Cambiar la escala entera es tocar estas 7 lineas. --t-campo NO baja de 16px: debajo de eso
     iOS hace zoom al enfocar un campo. Miniaturas de plantillas (gxm-/gxp-/sxm-) quedan fuera. */
  /* La escala de tipo se mudo a cuarto-oscuro.css (2026-09-23): es un token del sistema de
     diseno, y mientras viviera aqui el sistema no se sostenia solo -- usaba 11 tokens que no
     definia. Los tres HTML que cargan este archivo cargan tambien aquel, y aquel va despues. */
}
*{ box-sizing:border-box; }
/* Enlace de salto: oculto hasta enfocarlo con Tab; deja saltar el chat/nav e ir al contenido. */
.skip-link{ position:fixed; left:10px; top:-60px; z-index:100; background:var(--accent,#C96442); color:#fff; padding:10px 16px; border-radius:var(--r); font-size:var(--t-texto); text-decoration:none; box-shadow:0 8px 24px -8px rgba(0,0,0,.4); transition:top .15s ease; }
.skip-link:focus{ top:10px; }
html,body{ margin:0; }
/* Foco visible solo para navegacion por teclado (accesibilidad). */
a:focus-visible,button:focus-visible,input:focus-visible,select:focus-visible,textarea:focus-visible,[tabindex]:focus-visible,.chip:focus-visible,.tab:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
button:disabled{ opacity:.6; cursor:default; }
body{ font-family:var(--sans); background:var(--bone); color:var(--ink); -webkit-font-smoothing:antialiased; font-size:var(--t-texto); }
button,input,select,textarea{ font-family:inherit; color:inherit; }
/* Escala de tipo: sin esto un <button> sin tamano propio cae al 13.33px del navegador, fuera
   de la escala. Solo button: los campos quedan como estaban (su tamano toca el zoom de iOS). */
button{ font-size:inherit; }
::-webkit-scrollbar{ width:10px; height:10px; }
::-webkit-scrollbar-thumb{ background:#d9d1c0; border:3px solid var(--bone); border-radius:var(--r); }
@keyframes rise{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:none; } }
@keyframes pop{ from{ opacity:0; transform:scale(.96); } to{ opacity:1; transform:none; } }

/* utilidades */
.fx{ display:flex; } .f1{ flex:1; min-width:0; } .col{ flex-direction:column; }
.jb{ justify-content:space-between; } .gap10{ gap:10px; }
.gap8{ gap:8px; } .gap14{ gap:14px; }
.fs16{ font-size:var(--t-campo); } .fs20{ font-size:var(--t-sub); } .fw5{ font-weight:500; } .fw6{ font-weight:600; }
.money{ font-variant-numeric:tabular-nums; font-weight:600; }

/* ---------- Login ---------- */
#login{ position:fixed; inset:0; display:none; place-items:center; background:var(--deep); z-index:80; padding:22px; }
#login.show{ display:grid; }
/* Fondo decorativo de pantalla completa (#login/#invitacion-card/#onboarding-quiz, ver
   fondos.css): sin texto encima, asi que el guard de contraste no aplica -- se pide a
   proposito mas marcado que el velo base (pensado para texto), pedido de Daniel 2026-09-03
   viendo el remolino casi apagado detras de la tarjeta. Mismas variables que ya usa
   .fondo::before/::after, solo que con un valor local mas alto/mas bajo en estos tres. */
#login.fondo, #invitacion-card.fondo, #onboarding-quiz.fondo{ --fondo-opacidad:.95; --fondo-velo:.3; }
.login-card{ position:relative; width:min(94vw,380px); background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); padding:40px 38px; text-align:center; box-shadow:0 30px 80px -40px rgba(43,40,36,.4), 0 0 0 1px color-mix(in srgb, var(--paper) 45%, transparent); }
.login-card .mark{ width:44px; height:44px; margin:0 auto 14px; display:block; }
.login-card h1{ font-family:var(--serif); font-weight:400; font-size:var(--t-titulo); margin:0; letter-spacing:-.01em }
.login-card .sub{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.22em; text-transform:uppercase; color:var(--muted); margin:6px 0 26px; }
.login-card input{ width:100%; border:1px solid var(--line2); border-radius:var(--r); background:#FFFDF8; padding:12px 14px; font-size:var(--t-texto); margin-bottom:12px; outline:none; }
.login-card input:focus{ border-color:var(--accent); background:#fff; }
.login-err{ color:#B0533A; font-size:var(--t-texto); min-height:18px; }
.auth-switch{ font-size:var(--t-texto); color:var(--muted); margin-top:6px; }
.auth-switch a{ color:var(--accent); cursor:pointer; text-decoration:underline; }
/* Separador "o" entre el login/registro por password y "Continuar con Google" --
   compartido por #login (index.html) y #pr-form (probar.html). */
.pr-o-divider{ display:flex; align-items:center; gap:10px; margin:14px 0; font-size:var(--t-meta); color:var(--muted); text-transform:uppercase; letter-spacing:.08em; }
.pr-o-divider::before, .pr-o-divider::after{ content:""; flex:1; height:1px; background:var(--line2); }

/* ---------- Aceptar invitacion / recuperar contrasena (mismo peso visual que #login) ---------- */
#invitacion-card{ position:fixed; inset:0; display:none; place-items:center; background:var(--deep); z-index:80; padding:22px; }
#invitacion-card.show{ display:grid; }

/* ---------- Proyectos (public/proyectos.js) ----------
   El color del proyecto entra como --pj y tiñe la barra de avance, el borde de la
   tarjeta y la linea de tiempo: es lo que hace reconocible un proyecto de un vistazo. */
.pj-card{ display:block; text-decoration:none; color:inherit; background:var(--paper); border:1px solid var(--hair);
  border-left:3px solid var(--pj); border-radius:var(--r); padding:16px 18px; transition:.15s; }
@media (hover:hover){ .pj-card:hover{ border-color:var(--pj); box-shadow:0 4px 14px -8px rgba(41,40,36,.3); } }
.pj-card-h{ display:flex; align-items:center; gap:9px; margin-bottom:8px; flex-wrap:wrap; }
.pj-ico{ font-size:var(--t-campo); color:var(--pj); }
.pj-nom{ font-weight:600; font-size:var(--t-texto); flex:1; min-width:0; }
.pj-desc{ font-size:var(--t-texto); color:var(--muted); line-height:1.45; margin-bottom:12px; }
.pj-barra{ height:6px; border-radius:var(--r); background:color-mix(in srgb, var(--ink) 8%, var(--paper)); overflow:hidden; margin:10px 0 8px; }
.pj-barra span{ display:block; height:100%; border-radius:var(--r); transition:width .25s; }
.pj-meta{ display:flex; gap:12px; flex-wrap:wrap; font-size:var(--t-meta); color:var(--muted); }
.pj-vencidas{ color:#B0533A; font-weight:600; }

.pj-resumen{ display:grid; grid-template-columns:repeat(auto-fit,minmax(180px,1fr)); gap:14px;
  border:1px solid var(--hair); border-radius:var(--r); padding:16px 18px; background:var(--paper); }
.pj-r-item{ display:flex; flex-direction:column; gap:3px; }
.pj-r-lbl{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); }
.pj-r-val{ font-family:var(--serif); font-size:var(--t-titulo); font-weight:400; line-height:1.1; letter-spacing:-.01em }

.pj-lista{ border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; }
.pj-fila{ display:flex; align-items:center; gap:12px; padding:11px 14px; border-bottom:1px solid var(--hair); cursor:pointer; transition:.12s; }
.pj-fila:last-child{ border-bottom:0; }
@media (hover:hover){ .pj-fila:hover{ background:var(--deep); } }
.pj-fila.hecha .pj-fila-tit{ text-decoration:line-through; color:var(--muted); }
.pj-fila-tit{ flex:1; min-width:0; font-size:var(--t-texto); }
.pj-fila-meta{ display:flex; align-items:center; gap:10px; font-size:var(--t-meta); white-space:nowrap; }
.pj-check{ flex:0 0 20px; width:20px; height:20px; border-radius:var(--r); border:1.5px solid var(--line2);
  background:transparent; cursor:pointer; color:#fff; font-size:var(--t-meta); line-height:1; }
.pj-check.on{ background:#6E7F63; border-color:#6E7F63; }

/* Linea de tiempo: posiciona por fecha sobre el rango del proyecto. No es un Gantt (no
   dibuja dependencias), es "que cae cuando y que se encima". */
.pj-tl{ border:1px solid var(--hair); border-radius:var(--r); padding:20px 22px 8px; background:var(--paper); overflow-x:auto; }
.pj-tl-eje{ position:relative; height:22px; border-bottom:2px solid var(--hair); margin-bottom:6px; min-width:600px; }
.pj-tl-cabo{ position:absolute; left:0; top:0; font-size:var(--t-meta); color:var(--muted); }
.pj-tl-cabo.der{ left:auto; right:0; }
.pj-tl-hoy{ position:absolute; top:-4px; bottom:-8px; width:2px; background:var(--accent); }
.pj-tl-hoy span{ position:absolute; top:-14px; left:50%; transform:translateX(-50%); font-size:var(--t-eti); color:var(--accent); font-weight:600; }
.pj-tl-pista{ position:relative; min-height:120px; min-width:600px; padding-top:10px; }
.pj-tl-hito{ position:absolute; top:0; transform:translateX(-50%); max-width:190px; }
.pj-tl-punto{ display:block; width:11px; height:11px; border-radius:50%; background:var(--pj); margin:0 auto 8px; }
.pj-tl-punto.hecho{ background:#6E7F63; }
.pj-tl-punto.vencido{ background:#B0533A; }
.pj-tl-caja{ background:var(--deep); border:1px solid var(--hair); border-radius:var(--r); padding:8px 10px; }
.pj-tl-fecha{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); margin-bottom:4px; }
.pj-tl-tarea{ font-size:var(--t-meta); line-height:1.35; cursor:pointer; padding:2px 0; }
@media (hover:hover){ .pj-tl-tarea:hover{ color:var(--accent); } }
.pj-tl-tarea.hecha{ text-decoration:line-through; color:var(--muted); }

/* Caja que contiene al calendario dentro de una pestaña de proyecto: le da el
   position:relative y la altura que .calfull (absolute; inset:0) necesita para no
   desbordarse sobre el resto de la pagina. */
.pj-calbox{ position:relative; height:calc(100vh - 340px); min-height:440px; border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; }
.pj-calbox .calfull{ border-radius:var(--r); }

/* Editor de pasos de una plantilla de proyecto. Clases propias (plt-) y NO .pl-*, que ya
   son del editor de lineas de un paquete con otra rejilla. */
.plt-head,.plt-row{ display:grid; grid-template-columns:1fr 130px 80px 110px 30px; gap:8px; align-items:center; }
.plt-head{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin-bottom:6px; }
.plt-row{ margin-bottom:8px; }
.plt-row .inp,.plt-row .sel{ padding:8px 10px; font-size:var(--t-texto); }
@media (max-width:700px){
  .plt-head{ display:none; }
  .plt-row{ grid-template-columns:1fr 1fr; padding:10px; border:1px solid var(--line2); border-radius:var(--r); }
  .plt-row .inp[data-k="titulo"]{ grid-column:1/3; }
}

.pj-colores{ display:flex; gap:7px; flex-wrap:wrap; padding-top:5px; }
.pj-color{ width:26px; height:26px; border-radius:50%; border:2px solid transparent; cursor:pointer; }
.pj-color.on{ border-color:var(--ink); box-shadow:0 0 0 2px var(--paper) inset; }

/* Etiqueta del proyecto dentro del Calendario general */
.cf-proy{ display:inline-block; padding:1px 6px; border-radius:var(--r); font-size:var(--t-eti); font-weight:600;
  background:color-mix(in srgb, var(--pj) 22%, transparent); color:var(--pj); margin-right:4px; }

@media (max-width:620px){
  .pj-resumen{ grid-template-columns:1fr 1fr; }
  .pj-tl-hito{ max-width:150px; }
}

/* ---------- Barra de sesion de soporte (impersonacion) ----------
   Fija arriba y con color propio: si estas dentro de la cuenta de otra persona, eso no
   se puede confundir con tu propia sesion ni un segundo. */
#imp-barra{ position:fixed; top:0; left:0; right:0; z-index:400; display:flex; align-items:center; justify-content:center;
  gap:14px; flex-wrap:wrap; padding:9px 16px; background:#8A4B2F; color:#FCFBF7; font-size:var(--t-texto); text-align:center;
  box-shadow:0 2px 12px -4px rgba(0,0,0,.4); }
#imp-barra strong{ font-weight:600; }
#imp-barra .btn{ background:rgba(252,251,247,.14); border:1px solid rgba(252,251,247,.4); color:#FCFBF7; }
@media (hover:hover){ #imp-barra .btn:hover{ background:rgba(252,251,247,.24); } }
body.con-imp{ padding-top:38px; }
@media (max-width:620px){ body.con-imp{ padding-top:62px; } }

/* ---------- Cuestionario de bienvenida (mismo peso visual que #login) ---------- */
#onboarding-quiz{ position:fixed; inset:0; display:none; place-items:center; background:var(--deep); z-index:80; padding:22px; overflow-y:auto; }
#onboarding-quiz.show{ display:grid; }
.quiz-card{ width:min(94vw,560px); text-align:left; max-height:92vh; overflow-y:auto; margin:auto; padding:34px 32px 30px; }
.quiz-card .mark{ margin:0 auto 14px; }
.quiz-card h1{ text-align:center; }
.quiz-card .sub{ text-align:center; margin-bottom:16px; }
.quiz-lead{ font-size:var(--t-texto); color:var(--muted); text-align:center; margin:0 0 22px; }
.quiz-lead:empty{ display:none; }
/* Barra de pasos: reusa .al-wsteps/.al-wstep del wizard del album para que el producto
   hable un solo idioma visual. Aqui solo se centra y se separa. */
.quiz-steps{ justify-content:center; margin:0 0 18px; }
.quiz-steps:empty{ display:none; }
.quiz-q{ margin-bottom:20px; }
.quiz-qt{ font-size:var(--t-texto); font-weight:600; margin-bottom:4px; }
.quiz-ayuda{ font-size:var(--t-meta); color:var(--muted); margin-bottom:9px; line-height:1.45; }
.quiz-qt + .quiz-opts, .quiz-qt + .quiz-ops{ margin-top:9px; }
.quiz-opts{ display:flex; flex-wrap:wrap; gap:8px; }
.quiz-opt{ font-size:var(--t-meta); font-weight:500; letter-spacing:.01em; padding:8px 14px; border:1px solid var(--line2); background:transparent; color:var(--ink); border-radius:var(--r); cursor:pointer; transition:.14s; }
@media (hover:hover){ .quiz-opt:hover{ border-color:var(--accent); } }
.quiz-opt.on{ background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); }
/* Opciones con subtitulo (autonomia, tiempo de entrega): tarjetas apiladas, mismo
   patron que .xarpiepreg-op. Un chip de una linea no aguanta explicar un trade-off. */
.quiz-ops{ display:flex; flex-direction:column; gap:8px; }
.quiz-op{ display:flex; flex-direction:column; gap:2px; text-align:left; padding:11px 14px; border:1px solid var(--line2); border-radius:var(--r); background:transparent; color:var(--ink); cursor:pointer; transition:.14s; }
@media (hover:hover){ .quiz-op:hover{ border-color:var(--accent); } }
.quiz-op.on{ border-color:var(--accent); box-shadow:inset 0 0 0 1px var(--accent); background:var(--bone); }
.quiz-op-et{ font-size:var(--t-texto); font-weight:600; }
.quiz-op-det{ font-size:var(--t-meta); color:var(--muted); line-height:1.45; }
.quiz-ta{ width:100%; border:1px solid var(--line2); border-radius:var(--r); background:#FFFDF8; padding:12px 14px; font-size:var(--t-texto); font-family:inherit; resize:vertical; outline:none; }
.quiz-ta:focus{ border-color:var(--accent); background:#fff; }
/* Texto corto de una linea (la ciudad): mismo trazo que el textarea, sin tirador. */
.quiz-in{ resize:none; }
/* Los generos van agrupados por forma de negocio con un rotulo chico: 24 chips sin
   rotulos eran una sopa en la que no se veia que "newborn" y "bodas" son mundos distintos. */
.quiz-grupo{ margin-bottom:12px; }
.quiz-grupo:last-child{ margin-bottom:0; }
.quiz-grupo-t{ font-size:var(--t-meta); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); margin:0 0 7px; }
/* La reaccion de Xarpie a una respuesta: una linea fija (onb.re_*), cero tokens. Con el
   filete a la izquierda se lee como voz de alguien, no como texto de ayuda. */
.quiz-re{ font-size:var(--t-meta); line-height:1.45; color:var(--ink); margin-top:9px; padding-left:10px; border-left:2px solid var(--accent); }
.quiz-re:empty{ display:none; }
/* Miniaturas de la lista de precios subida en el cuestionario (reusa .attach-row del chat). */
.quiz-cat-adj{ margin-top:10px; }
.quiz-cat-adj:empty{ display:none; }
.quiz-cat-adj .attach-nombre{ font-size:var(--t-meta); color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
/* "Lo que ya se de ti": la tarjeta que se llena con cada respuesta. En escritorio va al
   lado del cuestionario; en telefono es una tira fija abajo que se abre con un toque. */
.quiz-sabe[hidden]{ display:none; }
.quiz-sabe-t{ display:flex; justify-content:space-between; align-items:baseline; gap:10px; width:100%; background:transparent; border:0; color:var(--ink); font:inherit; text-align:left; padding:0; cursor:default; }
.quiz-sabe-tt{ font-size:var(--t-meta); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.quiz-sabe-n{ font-size:var(--t-meta); color:var(--muted); white-space:nowrap; }
.quiz-sabe-l{ list-style:none; margin:12px 0 0; padding:0; display:flex; flex-direction:column; gap:9px; }
.quiz-sabe-l li{ font-size:var(--t-texto); line-height:1.45; }
.quiz-sabe-k{ display:block; font-size:var(--t-meta); letter-spacing:.05em; text-transform:uppercase; color:var(--muted); margin-bottom:1px; }
@media (min-width:960px){
  /* UNA columna por defecto. El aside "Lo que ya se de ti" nace oculto y solo aparece
     cuando ya hay respuestas; con las dos columnas declaradas siempre, la rejilla le
     reservaba sus 250px + 22px de hueco aunque estuviera en display:none, y el
     cuestionario quedaba 136px -- (250+22)/2 -- a la izquierda del centro. Se veia
     descuadrado justo en la primera pantalla que ve un fotografo nuevo.
     `:has()` aqui es cosmetico, igual que los otros de este archivo: si faltara, se
     queda la columna sola y el aside baja debajo, que sigue siendo legible. */
  #onboarding-quiz.show{ grid-template-columns:minmax(0,560px); align-items:start; align-content:center; justify-content:center; }
  #onboarding-quiz.show:has(.quiz-sabe:not([hidden])){ grid-template-columns:minmax(0,560px) 250px; column-gap:22px; }
  #onboarding-quiz.show .quiz-card{ width:100%; margin:0; }
  .quiz-sabe{ padding:22px 20px; border:1px solid var(--line2); border-radius:var(--r); background:var(--bone); max-height:92vh; overflow-y:auto; }
}
@media (max-width:959px){
  .quiz-sabe{ position:fixed; left:0; right:0; bottom:0; margin:0; padding:10px 16px calc(10px + env(safe-area-inset-bottom)); background:var(--bone); border-top:1px solid var(--line2); z-index:81; }
  .quiz-sabe-t{ cursor:pointer; }
  .quiz-sabe-l{ display:none; max-height:40vh; overflow-y:auto; }
  .quiz-sabe.abierto .quiz-sabe-l{ display:flex; }
  #onboarding-quiz.show{ padding-bottom:64px; }
}
.quiz-btn{ width:100%; margin-top:14px; }
/* Atras / Saltar: navegacion secundaria, debajo del boton principal y sin competirle. */
.quiz-nav{ display:flex; justify-content:center; gap:10px; margin-top:12px; }
.quiz-nav:empty{ display:none; }
.quiz-espera{ text-align:center; padding:10px 0 4px; }
.quiz-espera p{ font-size:var(--t-texto); color:var(--muted); margin:16px 0 0; }
/* Indeterminada: no sabemos cuanto tarda el modelo, asi que la barra recorre en loop en
   vez de mentir con un porcentaje. */
.quiz-espera-fill{ width:38%; animation:quizEspera 1.4s ease-in-out infinite; }
@keyframes quizEspera{ 0%{ margin-left:0 } 50%{ margin-left:62% } 100%{ margin-left:0 } }
.quiz-saludo p{ font-size:var(--t-texto); line-height:1.62; margin:0 0 12px; }
.quiz-saludo p:last-child{ margin-bottom:0; }
/* La carta de Xarpie. Se lee como una carta y no como una reja de features a proposito:
   parrafos con medida de lectura, sin vinetas, sin iconos. Vive en dos sitios (el ultimo
   paso del cuestionario y el comando /ayuda), asi que no asume el ancho de ninguno. */
.carta-x p{ font-size:var(--t-texto); line-height:1.62; margin:0 0 12px; max-width:62ch; }
.carta-x-pruebame{ font-size:var(--t-texto); color:var(--muted); margin:16px 0 8px !important; }
.carta-x-frases{ display:flex; flex-direction:column; align-items:flex-start; gap:7px; }
/* En columna y alineadas a la izquierda: son FRASES, no etiquetas -- en fila se cortaban
   y se leian como botones sueltos en vez de como ejemplos de algo que se puede decir. */
.carta-x-frases .chip{ text-align:left; white-space:normal; line-height:1.35; }
/* Lo que escribe el modelo, cuando llega. Separado de la carta por una linea: lo de arriba
   es fijo y lo de abajo es sobre ti, y la costura ayuda a que se lea asi. */
.carta-x-personal{ margin-top:18px; padding-top:14px; border-top:1px solid var(--hair); }
.carta-x-personal p{ font-size:var(--t-texto); line-height:1.62; margin:0 0 10px; max-width:62ch; }
.carta-x-personal-tit{ font-size:var(--t-meta); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); margin-bottom:8px; }
/* "Esto ya cambio en tu estudio": una linea por escritura real (cambios[] del POST). */
.carta-x-lista{ margin:0; padding-left:18px; max-width:62ch; }
.carta-x-lista li{ font-size:var(--t-texto); line-height:1.55; margin:0 0 6px; }
.cmd-ayuda-carta{ margin-bottom:16px; padding-bottom:14px; border-bottom:1px solid var(--hair); }
.cmd-ayuda-tit{ font-family:var(--serif,Georgia,serif); font-size:var(--t-sub); margin-bottom:10px; }
:root[data-theme="dark"] .quiz-ta{ background:#262624; border-color:var(--line2); color:var(--ink); }
:root[data-theme="dark"] .quiz-ta:focus{ background:#2C2C2A; }
@media (prefers-reduced-motion:reduce){ .quiz-espera-fill{ animation:none; width:100%; } }

/* ---------- utilidades varias ---------- */
.muted{ color:var(--muted); }
.link-copy{ display:flex; gap:8px; align-items:center; }
.link-copy input{ flex:1; }
.step-row{ display:grid; grid-template-columns:1fr 70px 90px 116px 28px; gap:8px; align-items:center; margin-bottom:8px; }
.step-row input,.step-row select{ padding:8px 10px; font-size:var(--t-texto); }
.badge-inactivo{ opacity:.5; }

/* ---------- Shell ---------- */
/* Ancho del riel de Xarpie. Lo pisa el divisor arrastrable (public/app.js) escribiendo
   --chat-w en linea sobre #app; este calc es el default y el valor al restablecer.
   MITAD Y MITAD (2026-09-20, pedido de Daniel): Xarpie y el CRM van casi siempre juntos, asi que todos arrancan
   50/50 (antes clamp(340px, 30vw, 480px), un chat de columna). El 3px es la mitad del divisor de 6px, para que las
   dos mitades midan igual. En escritorio (861px o mas) nunca baja de los pisos de app.js (chat 300, CRM 380). */
/* --topnav-h: alto de la barra de arriba (Cenital). Vive aqui, en el shell, porque lo usan
   tanto la barra como las alturas de .chatpane/.main que quedan debajo de ella. */
#app{ display:none; min-height:100vh; --chat-w: calc(50% - 3px); }
#app.show{ display:flex; }
/* El carril quedo FUERA de #app (es la barra de arriba), asi que dejo de heredar su
   display:none: sin esto se pintaba encima del login. Lo enciende sincCarrilVisible()
   (public/app.js) junto con #app -- misma clase, mismo momento. */
#cp-riel{ display:none; }
#cp-riel.show{ display:flex; }

.chatpane{ flex:0 0 clamp(320px,34%,460px); background:var(--deep); border-right:1px solid var(--hair); height:100vh; position:sticky; top:0; padding:24px 26px 22px; display:flex; flex-direction:column; min-width:0; }
.cp-brand{ display:flex; align-items:center; gap:12px; padding-bottom:18px; border-bottom:1px solid var(--hair); }
.mark{ width:40px; height:40px; flex:0 0 40px; }
.cp-logout{ margin-left:auto; background:transparent; border:1px solid var(--line2); border-radius:var(--r); width:30px; height:30px; cursor:pointer; color:var(--muted); font-size:var(--t-texto); }
@media (hover:hover){ .cp-logout:hover{ background:#E4DFD2; color:var(--ink); } }

.greet{ margin-top:18px; padding-bottom:16px; border-bottom:1px solid var(--hair); }
.greetkicker{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); }
.greetname{ font-family:var(--serif); font-weight:400; font-size:var(--t-titulo); letter-spacing:-.012em; line-height:1.04; margin-top:8px; }

.chatscroll{ flex:1; min-height:0; overflow-y:auto; overflow-x:hidden; padding:16px 2px 8px; display:flex; flex-direction:column; gap:16px; }
.brow{ display:flex; }
.brow-ai{ justify-content:flex-start; gap:11px; align-items:flex-start; }
.brow-me{ justify-content:flex-end; }
.ava{ width:27px; height:27px; flex:0 0 27px; border-radius:50%; background:var(--accent); position:relative; margin-top:3px; }
.ava:after{ content:''; position:absolute; width:9px; height:9px; border-radius:50%; background:var(--deep); left:6px; top:6px; }
.bubwrap{ min-width:0; max-width:82%; }
.bub{ padding:13px 16px; font-size:var(--t-texto); line-height:1.55; border-radius:var(--r); overflow-wrap:anywhere; white-space:pre-wrap; animation:rise .3s ease both; }
.bub-ai{ background:var(--paper); border:1px solid var(--hair); }
.bub-me{ background:#EAE3D5; color:var(--ink); border:1px solid var(--hair); }
.brow-me .bubwrap{ display:flex; justify-content:flex-end; }
.actnote{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.04em; color:var(--muted); margin-top:8px; display:flex; align-items:center; gap:7px; }
.actnote:before{ content:''; width:8px; height:8px; background:var(--accent); border-radius:50%; display:inline-block; }
/* AREA 2 -- la espera. Ya no es cursiva gris: el texto lleva un brillo que lo RECORRE, asi
   el movimiento no cambia el largo del renglon (antes el texto crecia y encogia con cada
   herramienta y la linea saltaba). El degradado se recorta contra el texto, por eso hace
   falta color:transparent; si el navegador no soporta background-clip:text se ve el color
   plano de respaldo, que es legible igual. */
.esperando{ color:var(--muted); background:linear-gradient(90deg,var(--muted) 22%,var(--ink) 50%,var(--muted) 78%);
  background-size:220% 100%; -webkit-background-clip:text; background-clip:text;
  -webkit-text-fill-color:transparent; animation:xarpieBrillo 1.8s linear infinite; }
@keyframes xarpieBrillo{ from{ background-position:170% 0 } to{ background-position:-70% 0 } }
.bub.typing{ color:var(--muted); }
/* Quien pidio menos movimiento ve el texto quieto y legible, no un degradado congelado a
   medio recorrer (que dejaria medio renglon casi invisible). */
@media (prefers-reduced-motion: reduce){
  .esperando{ animation:none; -webkit-text-fill-color:currentColor; color:var(--ink); }
}

/* ---- Respuesta de Xarpie con formato (public/formato.js) ----
   El markdown del modelo se veia crudo: asteriscos, almohadillas y guiones a la vista.
   Ahora llega como HTML de verdad y estas reglas le dan la jerarquia que pedia el chat.
   `white-space:normal` pisa el pre-wrap de .bub: con bloques reales los saltos ya los
   dan <p>/<li>, y dejarlo en pre-wrap metia una linea en blanco de mas entre cada uno. */
.bub-rico{ white-space:normal; }
.bub-rico > :first-child{ margin-top:0; }
.bub-rico > :last-child{ margin-bottom:0; }
.bub-rico p{ margin:0 0 .62em; }
/* Los titulos son el contraste que faltaba: mas grandes que el cuerpo y en peso alto, con
   aire ARRIBA (separan secciones) y poco abajo (pegados a lo que titulan). */
.bub-rico h3{ font-size:1.16em; font-weight:650; letter-spacing:-.01em; line-height:1.3; margin:1.15em 0 .4em; color:var(--ink); }
.bub-rico h4{ font-size:1.04em; font-weight:650; line-height:1.35; margin:1em 0 .35em; color:var(--ink); }
.bub-rico ul,.bub-rico ol{ margin:.15em 0 .7em; padding-left:1.25em; }
.bub-rico li{ margin:.24em 0; padding-left:.12em; }
/* La vineta en color de acento: la lista se lee como lista de un vistazo, sin que el punto
   compita con el texto. ::marker es lo unico que colorea la vineta sin falsearla con :before
   (que rompe la sangria cuando el renglon envuelve). */
.bub-rico li::marker{ color:var(--accent); }
.bub-rico ol li::marker{ color:var(--muted); font-variant-numeric:tabular-nums; }
.bub-rico strong{ font-weight:650; color:var(--ink); }
/* El fondo del chip se TINE con el color del texto, no con un gris fijo: el tema oscuro es
   el default de la app (theme-init.js) y un rgba(0,0,0,.05) ahi es invisible (medido). Y
   var(--paper) tampoco sirve: en tema claro es exactamente el fondo de la burbuja. El gris
   neutro de la primera linea es el respaldo para navegadores sin color-mix (Safari <16.2). */
.bub-rico code{ font-family:var(--mono); font-size:.88em; background:rgba(128,128,128,.16); background:color-mix(in srgb, var(--ink) 9%, transparent); border:1px solid var(--line2); border-radius:var(--r); padding:.06em .34em; }
.bub-rico a{ color:var(--accent); text-decoration:underline; text-underline-offset:2px; }
.bub-rico hr{ border:none; border-top:1px solid var(--line2); margin:.9em 0; }

/* Una sola fila con scroll horizontal (antes hacia wrap y empujaba todo lo de abajo):
   los chips son sugerencias, no la parte principal de la pantalla. Sin scrollbar visible
   a proposito -- es un gesto de "hay mas", no una barra que competir por espacio. */
.chips{ display:flex; flex-wrap:nowrap; gap:9px; margin:16px 0 12px; overflow-x:auto; padding-bottom:2px; scrollbar-width:none; }
.chips::-webkit-scrollbar{ display:none; }
.chip{ flex:0 0 auto; font-size:var(--t-meta); letter-spacing:.02em; padding:8px 15px; border:1px solid var(--line2); background:var(--paper); border-radius:var(--r); cursor:pointer; color:var(--ink); transition:.14s; }
@media (hover:hover){ .chip:hover{ border-color:#C6C0B0; background:#ECE7DB; } }
/* La pista de "que puede hacer Xarpie aqui" (sincPistaXarpie en app.js). Va justo debajo
   de la .phead, y a proposito NO parece una alerta: es una sugerencia que se puede ignorar
   sin costo, asi que no lleva fondo de color ni icono de aviso. El margen negativo de
   arriba la pega a la cabecera (la .phead ya trae 20px abajo) para que se lea como parte
   de ella y no como el primer elemento del contenido. */
.pista-x{ display:flex; align-items:center; gap:6px; margin:-10px 0 18px; }
.pista-x-chip{ display:inline-flex; align-items:center; gap:8px; font-size:var(--t-meta); padding:7px 14px; border:1px solid var(--line2); background:var(--paper); border-radius:var(--r); cursor:pointer; color:var(--ink); transition:.14s; text-align:left; }
@media (hover:hover){ .pista-x-chip:hover{ border-color:var(--accent); } }
.pista-x-marca{ font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--accent); flex:0 0 auto; }
/* El descarte es deliberadamente discreto: si pesara lo mismo que la sugerencia, la
   pantalla pediria una decision que nadie pidio. Se ve al pasar el raton por la fila. */
.pista-x-no{ flex:0 0 auto; width:24px; height:24px; line-height:1; border:0; background:transparent; color:var(--muted); cursor:pointer; border-radius:50%; font-size:var(--t-campo); opacity:0; transition:.14s; }
@media (hover:hover){ .pista-x:hover .pista-x-no{ opacity:1; } }
@media (hover:hover){ .pista-x-no:hover{ background:var(--line); color:var(--ink); } }
.pista-x-no:focus-visible{ opacity:1; }
/* UNA sola barra (2026-08-28). OJO, esto ya fallo una vez: con todo en una linea el riel es
   angosto, los 4 botones se comian el ancho y el campo se quedaba en 17px, con el texto en
   vertical. Ahora si cabe porque cambiaron las dos causas: el selector de modo se fue AFUERA
   del composer (ver index.html) y "Enviar" dejo de ser un boton de texto (~78px) para ser un
   circulo de 34px. Lo que impide que vuelva a pasar es `min-width:0` en el textarea junto con
   `flex:1 1 auto`: sin el, un flex-item no baja de su ancho de contenido y son los BOTONES
   los que ganan el reparto. MEDIDO el 2026-08-28 sobre este mismo markup: el campo queda en
   239px con el riel a 380 (su ancho minimo), 419px a 560, y no envuelve en ningun punto
   intermedio. Si algun dia agregas otro boton aqui, vuelve a medirlo. */
.composer{ position:relative; display:flex; flex-wrap:nowrap; gap:4px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); padding:7px 7px 7px 15px; align-items:flex-end; }
.composer #chat-send{ margin-left:2px; }
/* El input no muestra outline propio, asi que el foco por teclado se ve en el contenedor. */
.composer:focus-within{ border-color:var(--accent); box-shadow:0 0 0 2px color-mix(in srgb,var(--accent) 30%,transparent); }
/* Textarea, no input: pegar una lista de precios o un prompt largo en un campo de una
   sola linea es inusable. Crece solo hasta 200px y de ahi hace scroll (ver
   autoCrecerChat en app.js). Enter envia, Shift+Enter salta de linea. */
/* min-width:0 es lo que hace posible la barra de una sola linea: sin el, el textarea no baja
   de su ancho de contenido y los botones se quedan con el espacio (ver el comentario de
   .composer arriba). Ya no lleva order ni flex-basis:100%: comparte renglon con los botones. */
.composer textarea#chat-text{ flex:1 1 auto; min-width:0; border:0; background:transparent;
  font-family:inherit; font-size:var(--t-texto); outline:none; padding:8px 2px; resize:none; line-height:1.45;
  max-height:200px; overflow-y:auto; }

/* ---- Xarpie: selector de modo (vive DENTRO del composer, ver index.html) + adjuntar
   imagen (vision) ---- */
/* order:-2 lo pone en su propio renglon arriba de todo (antes que el textarea, que es
   -1): un segmento chico, no dos botones grandes peleando con "Enviar" por el mismo peso
   visual. align-self:flex-start para que no se estire al ancho completo del composer. */
/* Ya no vive dentro del composer, asi que pierde order/flex-basis: ahora es un bloque suelto
   encima de la barra. align-self ya no aplica; el margen de abajo lo separa del composer. */
/* Enviar: el UNICO punto de color de la barra. 34px para que siga siendo tocable con el
   pulgar; el aria-label vive en el HTML (data-i18n-aria) porque adentro solo hay un SVG. */
.chat-enviar{ flex:0 0 auto; width:34px; height:34px; display:grid; place-items:center; border:0;
  border-radius:50%; background:var(--accent-solido); color:var(--accent-tinta); cursor:pointer; transition:.14s var(--ease-estado); }
@media (hover:hover){ .chat-enviar:hover{ filter:brightness(1.08); } }
.chat-enviar:disabled{ opacity:.45; cursor:default; }
.cp-attach{ flex:0 0 auto; width:34px; height:34px; display:grid; place-items:center; border:0; background:transparent; color:var(--muted); cursor:pointer; border-radius:var(--r); transition:.14s; }
@media (hover:hover){ .cp-attach:hover{ background:var(--deep); color:var(--ink); } }
.cp-attach[hidden]{ display:none; }
.cp-attach#chat-mic.listening{ background:var(--red); color:#fff; animation:mic-pulse 1.4s ease-in-out infinite; }
/* Mientras el audio va camino a transcribirse: el boton sigue ocupado pero ya no esta
   escuchando, asi que no puede verse igual que grabando (pulso rojo). Sin animacion: es un
   estado de espera de un par de segundos, no algo que pedir que miren. */
/* El latido de "#chat-voz mientras suena" se fue con el boton (2026-09-23): el interruptor vive
   ahora en el menu «+». No se perdio informacion -- su propio comentario decia que el latido era
   decoracion y que el estado vivia en aria-pressed. Lo que SI se perdio es la forma rapida de
   callarlo con un toque; hoy se calla escribiendo, que es la que ya estaba. */
.cp-attach#chat-mic.working{ background:var(--deep); color:var(--ink); opacity:.75; cursor:progress; }
@media (prefers-reduced-motion: reduce){ .cp-attach#chat-mic.listening{ animation:none; } }
.cp-attach.on{ background:var(--accent-solido); color:var(--accent-tinta); }
body.inspeccionando, body.inspeccionando *{ cursor:crosshair !important; }
.insp-overlay{ position:fixed; z-index:9999; pointer-events:none; border:2px solid var(--accent); border-radius:var(--r); background:color-mix(in srgb, var(--accent) 14%, transparent); }
@keyframes mic-pulse{ 0%,100%{ box-shadow:0 0 0 0 color-mix(in srgb,var(--red) 45%,transparent); } 50%{ box-shadow:0 0 0 7px color-mix(in srgb,var(--red) 0%,transparent); } }

/* Tooltips de ayuda (data-tip, ver wireTooltips en app.js): burbuja propia, no el title
   nativo del navegador -- por eso pointer-events:none (nunca roba el click al elemento
   de abajo) y una transicion de opacidad en vez del retraso/estilo que impone cada SO. */
.tt-pop{ position:fixed; z-index:9200; max-width:230px; background:var(--ink); color:var(--paper); font-size:var(--t-meta); line-height:1.4; padding:7px 11px; border-radius:var(--r); box-shadow:0 10px 26px -12px rgba(0,0,0,.45); opacity:0; transform:translateY(4px); transition:opacity .12s ease, transform .12s ease; pointer-events:none; }
.tt-pop.show{ opacity:1; transform:none; }
.tt-pop.tt-abajo{ transform:translateY(-4px); }
.tt-pop.tt-abajo.show{ transform:none; }

/* Recorrido guiado del Panel (ver TOUR_PANEL en app.js). El backdrop dimido es el box-
   shadow gigante del propio recuadro (recorta un "hueco" en el elemento resaltado sin
   necesitar una mascara aparte); pointer-events:none en el recuadro para que el usuario
   pueda seguir usando la app debajo si decide irse a otra pagina a medio recorrido
   (_tourAbandonar en app.js lo cierra solo). */
.tour-spot{ position:fixed; z-index:9000; pointer-events:none; border:2px solid var(--accent); border-radius:var(--r); background:color-mix(in srgb, var(--accent) 10%, transparent); box-shadow:0 0 0 4000px rgba(20,18,15,.55); transition:left .22s ease, top .22s ease, width .22s ease, height .22s ease; }
.tour-pop{ position:fixed; z-index:9001; width:280px; max-width:calc(100vw - 20px); background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); box-shadow:0 18px 44px -20px rgba(43,40,36,.5); padding:16px; animation:pop .16s ease both; transition:left .22s ease, top .22s ease; }
.tour-pop-kicker{ font-size:var(--t-eti); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); margin-bottom:6px; }
.tour-pop-titulo{ font-size:var(--t-texto); font-weight:600; margin-bottom:6px; }
.tour-pop-texto{ font-size:var(--t-texto); color:var(--muted); line-height:1.5; margin-bottom:14px; }
.tour-pop-acc{ display:flex; justify-content:space-between; align-items:center; gap:8px; }

.tour-fb{ position:fixed; right:22px; bottom:22px; z-index:9001; background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); box-shadow:0 18px 44px -20px rgba(43,40,36,.5); padding:12px 14px; display:flex; align-items:center; gap:10px; animation:pop .16s ease both; }
.tour-fb-texto{ font-size:var(--t-texto); }
.tour-fb-acc{ display:flex; align-items:center; gap:6px; }
.tour-fb-cerrar{ background:none; border:none; color:var(--muted); cursor:pointer; padding:4px; display:flex; border-radius:var(--r); }
@media (hover:hover){ .tour-fb-cerrar:hover{ background:var(--deep); } }
@media (max-width:640px){ .tour-fb{ left:14px; right:14px; bottom:14px; } }

/* Contador de caracteres: oculto casi siempre (ver actualizarContadorChat en app.js),
   solo se enciende cerca de MAX_MENSAJE_CHARS (src/index.js) para avisar ANTES de que
   el servidor rechace el mensaje, no despues. */
.cp-count{ flex:0 0 auto; font-family:var(--mono); font-size:var(--t-eti); color:var(--muted); font-variant-numeric:tabular-nums; margin-right:2px; }
.cp-count.warn{ color:var(--red); font-weight:600; }

/* Arrastrar y soltar un archivo directo sobre el chat: mismo destino y misma validacion
   que el boton de clip (procesarArchivoAdjunto en app.js), un atajo mas, no un camino
   aparte. Oculto por default; drop.js le agrega/quita .dragover al #chat-composer. */
.chat-dropzone{ position:absolute; inset:0; z-index:5; display:none; align-items:center; justify-content:center;
  border:2px dashed var(--accent); border-radius:var(--r); background:color-mix(in srgb, var(--accent) 10%, var(--paper));
  color:var(--accent); font-size:var(--t-texto); font-weight:600; pointer-events:none; }
.composer.dragover .chat-dropzone{ display:flex; }
.attach-prev{ display:flex; flex-wrap:wrap; align-items:center; gap:10px; padding:8px 10px; margin-bottom:8px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); }
.attach-prev[hidden]{ display:none; }
/* Fila ancha: el unico caso posible es un PDF suelto (procesarArchivosAdjuntos nunca
   mezcla PDF con imagenes), asi que ocupa las 100% como antes. */
.attach-row{ display:flex; align-items:center; gap:10px; width:100%; }
.attach-row .attach-doc{ width:40px; height:40px; flex:0 0 40px; display:grid; place-items:center; border-radius:var(--r); background:var(--accent-solido); color:var(--accent-tinta); font-family:var(--mono); font-size:var(--t-eti); font-weight:700; letter-spacing:.04em; }
.attach-name{ flex:1; min-width:0; font-size:var(--t-meta); color:var(--muted); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.attach-x{ flex:0 0 auto; width:24px; height:24px; border:0; background:transparent; color:var(--muted); cursor:pointer; border-radius:var(--r); display:grid; place-items:center; }
@media (hover:hover){ .attach-x:hover{ background:var(--deep); color:var(--ink); } }
/* Miniatura: 1..MAX_IMAGENES_ADJUNTAS por turno, en fila con wrap. Mismo tamano/overlay
   que los thumbs de capturas del modal de reporte (pintarThumbs, app.js). */
.attach-tile{ position:relative; flex:0 0 auto; }
.attach-tile img{ width:56px; height:56px; object-fit:cover; border-radius:var(--r); display:block; }
.attach-tile .attach-x{ position:absolute; top:-7px; right:-7px; width:20px; height:20px; background:var(--ink); color:#fff; border-radius:50%; }
@media (hover:hover){ .attach-tile .attach-x:hover{ background:var(--ink); opacity:.85; } }
.bub-img{ display:block; max-width:100%; width:auto; max-height:280px; border-radius:var(--r); margin-bottom:8px; }
.brow-me .bub-img{ margin-left:auto; }
/* Varias imagenes en la MISMA burbuja enviada (enviarChat, app.js): fila compacta con
   wrap en vez de apilar cada una a 280px de alto. */
.bub-imgs{ display:flex; flex-wrap:wrap; gap:6px; margin-bottom:8px; justify-content:flex-end; }
.bub-img-sm{ display:block; width:64px; height:64px; object-fit:cover; border-radius:var(--r); }

/* ---------- Content (right) ---------- */
.main{ flex:1; min-width:0; height:100vh; overflow-y:auto; }
/* .tab/.tab.on: desde "El Carril" F2 SOLO los usa admin.html para sus propias
   pestañas (Panel/Estudios/Reportes/...) -- la nav del CRM real vive en #cp-riel con
   sus propias clases (.cp-navbtn, mas abajo). No se borran ni se les cambia el estilo:
   admin.html no tiene chat ni carril, y reusa esta clase sin saberlo (sin scope propio,
   asi que un cambio aqui se le nota igual). */
.tab{ position:relative; flex:0 0 auto; white-space:nowrap; font-size:var(--t-texto); font-weight:500; letter-spacing:.01em; padding:6px 12px; border-radius:var(--r); border:1px solid transparent; background:transparent; color:var(--muted); cursor:pointer; transition:.13s; }
@media (hover:hover){ .tab:hover{ background:#ECE7DB; color:var(--ink); } }
.tab.on{ color:var(--ink); }
.tab.on:after{ content:''; position:absolute; left:12px; right:12px; bottom:1px; height:2px; border-radius:2px; background:var(--accent); }

/* Posponer una tarea (activa_desde): ver .posp-menu, definido despues de .usermenu
   porque hereda de esa clase y necesita ganarle el position. */
.posp-wrap{ position:relative; display:inline-flex; }
/* .subbar/.subtab: la subbarra global de nav (#subtabs) se borro en "El Carril" F2 --
   esta clase sigue viva porque proyectos.js la reusa para su propia sub-nav interna
   (public/proyectos.js:411), sin relacion con el carril. */
.subbar{ display:flex; align-items:center; gap:2px; padding:6px 20px; overflow-x:auto; scrollbar-width:none; background:rgba(239,235,224,.92); backdrop-filter:blur(10px); border-bottom:1px solid var(--hair); }
.subbar::-webkit-scrollbar{ display:none; }
.subbar[hidden]{ display:none; }
.subtab{ flex:0 0 auto; white-space:nowrap; font-size:var(--t-meta); font-weight:500; padding:5px 12px; border-radius:var(--r); border:1px solid transparent; background:transparent; color:var(--muted); cursor:pointer; transition:.13s; }
@media (hover:hover){ .subtab:hover{ background:#E4DFD2; color:var(--ink); } }
.subtab.on{ color:var(--accent); background:color-mix(in srgb, var(--accent) 13%, transparent); }
.cp-sess{ font-family:var(--mono); font-size:var(--t-meta); color:var(--muted); }
.wrap{ max-width:1180px; margin:0 auto; padding:28px 32px 80px; overflow-x:auto; }

.phead{ display:flex; align-items:flex-end; justify-content:space-between; border-bottom:1px solid var(--hair); padding-bottom:12px; margin-bottom:20px; gap:16px; flex-wrap:wrap; }
/* margin:0 NO es cosmetico: .ptitle es un <h1> (43 de 45 cabeceras) y el margen
   por defecto del navegador es 0.67em — a 44px eso son 29.5px ARRIBA y ABAJO que
   nadie escribio nunca (no hay reset global de h1 en esta hoja; solo lo tenia
   .login-card). Eran 59px de aire invisible antes del contenido en TODAS las
   secciones. El titulo siempre es el ultimo elemento de su contenedor, asi que
   quitarlo no junta nada con nada. */
.ptitle{ font-family:var(--serif); font-weight:400; font-size:var(--t-saludo); letter-spacing:-.01em; line-height:1; margin:0; }
.peyebrow{ position:relative; padding-left:16px; font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin-bottom:9px; }
.peyebrow:before{ content:''; position:absolute; left:0; top:5px; width:7px; height:7px; border-radius:50%; background:var(--accent); }

/* botones */
.btn{ font-size:var(--t-texto); font-weight:500; letter-spacing:.04em; padding:10px 18px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); cursor:pointer; transition:.14s; }
@media (hover:hover){ .btn:hover{ background:#ECE7DB; color:var(--ink); } }
.btn-p{ background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); }
@media (hover:hover){ .btn-p:hover{ filter:brightness(.94); background:var(--accent-solido); color:var(--accent-tinta); } }
.btn-sm{ padding:7px 13px; font-size:var(--t-meta); }
.btn-gh{ background:transparent; }
.btn-danger{ border-color:#CDA99A; color:#B0533A; background:transparent; }
@media (hover:hover){ .btn-danger:hover{ background:#B0533A; border-color:#B0533A; color:#fff; } }

/* pills */
.pill{ display:inline-flex; align-items:center; font-size:var(--t-meta); font-weight:500; letter-spacing:.01em; padding:3px 11px; border-radius:var(--r); border:1px solid transparent; }
.pill-red{ background:#F1DBD0; color:#A2492B; }
.pill-blue{ background:#E1E7DD; color:#4E6350; }
.pill-yellow{ background:#F0E6CA; color:#836327; }
.pill-ink{ background:#E9E5DA; color:#565349; }
.pill-ghost{ background:transparent; color:var(--muted); border-color:var(--line2); }

/* cards / stats */
.card,.stat,.pblock,.settcard{ background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); box-shadow:0 1px 3px rgba(41,40,36,.04); }
.stat{ padding:16px 18px; position:relative; overflow:hidden; }
.statlabel{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.statnum{ font-family:var(--serif); font-weight:400; font-size:var(--t-titulo); letter-spacing:-.01em; margin-top:6px; line-height:1; font-variant-numeric:tabular-nums; }
.statbar{ position:absolute; right:15px; top:16px; width:13px; height:13px; border-radius:50%; box-shadow:0 0 0 4px color-mix(in srgb,var(--paper) 60%,transparent); }
.grid3{ display:grid; grid-template-columns:repeat(auto-fit,minmax(132px,1fr)); gap:14px; }
.dash{ display:grid; grid-template-columns:1fr 1fr; gap:16px; align-items:start; }

.pblock-h{ display:flex; align-items:center; justify-content:space-between; padding:12px 15px; border-bottom:1px solid var(--hair); }
/* Un nombre de paquete largo envuelve a 2-3 lineas en una columna angosta de movil; con
   align-items:center (arriba) "Editar" quedaba centrado sobre el bloque envuelto, en vez de
   arriba junto a la primera linea. Acotado a movil para no tocar el layout de escritorio. */
@media (max-width:640px){ .pblock-h{ align-items:flex-start; } }
.pblock-t{ font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.1em; text-transform:uppercase; font-weight:600; }
.pblock-t .w-count{ margin-left:8px; vertical-align:1px; }
.pbody{ padding:6px 15px 14px; }
/* Secciones colapsables de la ficha de cliente (preferencia por usuario). */
.evrow{ display:flex; align-items:center; gap:12px; padding:11px 0; border-bottom:1px solid var(--hair); }
.evrow:last-child{ border-bottom:0; }
/* Detalle de una fila (hoy: que fotos se llevo un invitado), en un div HERMANO -- no anidado
   dentro de .evrow -- para que su ancho sea el del panel completo, no el de la columna .f1.
   Le cede el borde de abajo a .evrow (que si no lo duplicaria) y se lo queda solo si el
   detalle termina siendo el ultimo elemento de la lista, mismo criterio que .evrow:last-child
   de arriba. `:has()` es cosmetico (ver #app:has(...) mas abajo en este archivo): si faltara,
   el unico efecto es una raya de mas, nada se rompe. */
.evrow-click{ cursor:pointer; }
.evrow:has(+ .evdet){ border-bottom:0; }
.evdet{ padding:0 0 12px; border-bottom:1px solid var(--hair); }
.evdet:last-child{ border-bottom:0; }
.evdet[hidden]{ display:none; }
/* `.evrow` es el patron de fila mas repetido de la app (leads, tareas, contratos, correos,
   documentos...) y hasta ahora no tenia NINGUN tratamiento para telefono: su columna de texto
   (`.f1`, `min-width:0`) podia encogerse hasta colapsar palabra por palabra igual que le pasaba
   a `.foco-item` (ver el comentario de esa regla, unas lineas mas abajo en este archivo). Mismo
   arreglo, mismo piso de legibilidad: el texto se queda en una linea mientras quepa, y si no
   cabe, la fila completa se envuelve en vez de apretar el texto hasta lo ilegible. */
@media (max-width:640px){
  .evrow{ flex-wrap:wrap; }
  .evrow > .f1{ min-width:160px; }
}
.evtime{ font-family:var(--mono); font-size:var(--t-meta); font-variant-numeric:tabular-nums; width:52px; flex:0 0 52px; color:var(--ink); }
.evname{ font-size:var(--t-texto); line-height:1.2; }
.evmeta{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
.chk{ display:flex; align-items:flex-start; gap:11px; padding:10px 0; border-bottom:1px solid var(--hair); cursor:pointer; }
.chk:last-child{ border-bottom:0; }
.box{ width:18px; height:18px; flex:0 0 18px; border:1.5px solid var(--ink); border-radius:4px; margin-top:1px; display:flex; align-items:center; justify-content:center; transition:.12s; }
.box.done{ background:var(--ink); }
.box.done:after{ content:''; width:9px; height:5px; border-left:2px solid var(--paper); border-bottom:2px solid var(--paper); transform:rotate(-45deg) translateY(-1px); }
.chktext{ font-size:var(--t-texto); line-height:1.35; }
.chktext.done{ text-decoration:line-through; color:var(--muted); }
.empty{ font-size:var(--t-texto); color:var(--muted); padding:10px 0; }

/* ===== Editor de contrato (#/contrato/:id) — recreacion del handoff "Editor de
   Contrato.dc.html", embebido en #view (mismo criterio que .geditor via
   .ge-embebido/.aled/.calfull, ver esa seccion): position:fixed tapaba el chat de
   Xarpie y la barra de navegacion, asi que se ancla al area de contenido y las dos
   medidas salen solas del layout -- ver la regla #view:has(.ced) mas abajo. Paleta
   oscura PROPIA via --ced-*, panel izquierdo (formulario) + panel derecho (documento
   sobre "papel"), sin iframe -- la vista previa es un espejo cliente-side de
   documents.js#contratoBodyV2, hay que mantenerla igual. ===== */
.ced{
  --ced-bg:#262624; --ced-panel:#30302e; --ced-panel2:#3a3a36; --ced-line:rgba(255,255,255,.09); --ced-line2:rgba(255,255,255,.05);
  --ced-ink:#f5f4ee; --ced-ink2:#bdbbb0; --ced-ink3:#84827b; --ced-accent:#d97757; --ced-accent2:#bd5d3a; --ced-ok:#93a986; --ced-gold:#cfa15e; --ced-red:#c9605a;
  --ced-serif:'Instrument Sans',system-ui,sans-serif;
  --ced-paper:#f4efe9; --ced-paperink:#221d19; --ced-papermut:#6a6158; --ced-paperline:rgba(34,29,25,.14);
  position:relative; height:100%; display:flex; flex-direction:column; background:var(--ced-bg);
  font-family:'Instrument Sans',var(--sans); color:var(--ced-ink); -webkit-font-smoothing:antialiased;
}
.ced button{ font-family:inherit; cursor:pointer; border:none; background:none; color:inherit; }
.ced input,.ced textarea{ font-family:inherit; }
.ced .ced-serif{ font-family:var(--ced-serif); font-weight:400; line-height:1; letter-spacing:-.01em }
.ced .ced-label{ text-transform:uppercase; letter-spacing:.16em; font-size:var(--t-eti); font-weight:600; color:var(--ced-ink3); }

/* cabecera */
.ced-top{ display:flex; align-items:center; gap:16px; padding:16px 26px; border-bottom:1px solid var(--ced-line); flex:none; flex-wrap:wrap; }
.ced-iconbtn{ width:38px; height:38px; border-radius:100px; border:1px solid var(--ced-line); display:flex; align-items:center; justify-content:center; color:var(--ced-ink2); transition:.14s; flex:none; font-size:var(--t-campo); }
@media (hover:hover){ .ced-iconbtn:hover{ border-color:var(--ced-ink3); color:var(--ced-ink); } }
.ced-thead{ display:flex; flex-direction:column; gap:3px; }
.ced-tnum{ font-family:var(--ced-serif); font-size:var(--t-titulo); font-weight:400; line-height:1; letter-spacing:-.01em }
.ced-tsub{ font-size:var(--t-meta); color:var(--ced-ink3); }
.ced-stpill{ display:inline-flex; align-items:center; gap:7px; padding:6px 13px; border-radius:var(--r); font-size:var(--t-meta); font-weight:600; white-space:nowrap; }
.ced-st-borrador{ background:rgba(189,187,176,.14); color:var(--ced-ink2); }
.ced-st-enviado{ background:rgba(217,119,87,.16); color:var(--ced-accent); }
.ced-st-falta{ background:rgba(207,161,94,.16); color:var(--ced-gold); }
.ced-st-activo{ background:rgba(147,169,134,.16); color:var(--ced-ok); }
.ced-st-vencido{ background:rgba(201,96,90,.16); color:var(--ced-red); }
.ced-dot{ width:7px; height:7px; border-radius:100px; display:inline-block; background:currentColor; }
.ced-spread{ margin-left:auto; display:flex; align-items:center; gap:10px; flex-wrap:wrap; position:relative; }
.ced-btn{ display:inline-flex; align-items:center; gap:8px; padding:11px 18px; border-radius:var(--r); font-size:var(--t-texto); font-weight:600; transition:.16s; border:1px solid var(--ced-line); color:var(--ced-ink); white-space:nowrap; }
@media (hover:hover){ .ced-btn:hover{ border-color:var(--ced-ink3); } }
.ced-btn:disabled{ opacity:.5; cursor:not-allowed; }
.ced-btn.accent{ background:var(--ced-accent); border-color:var(--ced-accent); color:#fff; }
@media (hover:hover){ .ced-btn.accent:hover{ background:var(--ced-accent2); } }
.ced-btn.sm{ padding:8px 14px; font-size:var(--t-meta); }
.ced-savestate{ font-size:var(--t-meta); color:var(--ced-ink3); white-space:nowrap; }

/* panel flotante (Firmantes/Configuracion/Acciones) -- mismo patron abrir/cerrar/
   click-afuera/Escape que .usermenu, con paleta --ced-* en vez de la del CRM. */
.ced-panel{ position:absolute; top:100%; right:0; margin-top:8px; width:290px; background:var(--ced-panel); border:1px solid var(--ced-line); border-radius:var(--r); padding:16px; box-shadow:0 20px 50px -20px rgba(0,0,0,.5); z-index:5; }
.ced-panel-t{ font-family:var(--ced-serif); font-size:var(--t-texto); font-weight:400; margin:0 0 12px; letter-spacing:-.01em }
.ced-prow{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:9px 0; border-bottom:1px solid var(--ced-line2); font-size:var(--t-texto); }
.ced-prow:last-child{ border-bottom:0; }
.ced-prow .pn{ font-weight:600; }
.ced-prow .ps{ color:var(--ced-ink3); font-size:var(--t-meta); margin-top:2px; }
.ced-prow .ps.ok{ color:var(--ced-ok); }
.ced-pact{ width:100%; text-align:left; padding:9px 4px; font-size:var(--t-texto); border-radius:var(--r); transition:.14s; }
@media (hover:hover){ .ced-pact:hover{ background:var(--ced-panel2); } }
@media (hover:hover){ .ced-pact.danger:hover{ color:var(--ced-red); } }
.ced-psep{ height:1px; background:var(--ced-line2); margin:6px 0; }
.ced-toggle{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:10px 0; }
.ced-toggle .tt{ font-size:var(--t-texto); font-weight:600; }
.ced-toggle .ts{ font-size:var(--t-meta); color:var(--ced-ink3); margin-top:2px; }
.ced-sw2{ width:38px; height:22px; border-radius:var(--r); background:var(--ced-line); position:relative; transition:.2s; flex:none; }
.ced-sw2:after{ content:""; position:absolute; top:2px; left:2px; width:18px; height:18px; border-radius:3px; background:var(--ced-ink); transition:.2s; }
.ced-sw2.on{ background:var(--ced-accent); }
.ced-sw2.on:after{ left:18px; background:#fff; }

/* cuerpo: 2 paneles */
.ced-body{ flex:1; min-height:0; display:flex; }
.ced-editor{ width:46%; max-width:620px; min-width:400px; flex:none; overflow-y:auto; border-right:1px solid var(--ced-line); padding:26px 30px 60px; }
.ced-sec{ margin-bottom:30px; }
.ced-sechd{ display:flex; align-items:center; gap:10px; margin-bottom:16px; }
.ced-sechd .n{ width:22px; height:22px; border-radius:100px; background:var(--ced-panel); border:1px solid var(--ced-line); display:flex; align-items:center; justify-content:center; font-size:var(--t-meta); font-weight:700; color:var(--ced-ink2); flex:none; }
.ced-sechd h3{ font-family:var(--ced-serif); font-size:var(--t-campo); font-weight:400; margin:0; letter-spacing:-.01em }
.ced-grid2{ display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.ced-field{ display:flex; flex-direction:column; gap:7px; margin-bottom:14px; }
.ced-field label{ font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--ced-ink3); font-weight:600; }
.ced-inp{ background:var(--ced-panel); border:1px solid var(--ced-line); border-radius:var(--r); padding:12px 14px; font-size:var(--t-texto); color:var(--ced-ink); outline:none; transition:.14s; width:100%; }
.ced-inp:focus{ border-color:rgba(217,119,87,.55); }
.ced-inp::placeholder{ color:var(--ced-ink3); }
.ced-static{ background:var(--ced-panel); border:1px solid var(--ced-line); border-radius:var(--r); padding:12px 14px; font-size:var(--t-texto); color:var(--ced-ink); }
.ced-static a{ color:var(--ced-accent); text-decoration:none; font-size:var(--t-meta); font-weight:600; }
@media (hover:hover){ .ced-static a:hover{ text-decoration:underline; } }
.ced-money{ position:relative; }
.ced-money .cur{ position:absolute; left:14px; top:50%; transform:translateY(-50%); color:var(--ced-ink3); font-size:var(--t-texto); }
.ced-money .ced-inp{ padding-left:28px; font-family:var(--ced-serif); font-size:var(--t-sub); font-weight:400; letter-spacing:-.01em }

/* plantillas -- boton compacto que abre #ced-tpl-panel (mismo .ced-panel que
   Firmantes/Configuracion/Acciones); .ced-tplgrid/.ced-tpl siguen siendo las mismas
   tarjetas de siempre, solo que ahora a 1 columna porque el popover (320px) es mas
   angosto que el panel del editor donde vivian antes. */
.ced-tplsec{ margin:0 0 20px; }
#ced-tpl-panel .ced-tplgrid{ grid-template-columns:1fr; }
.ced-tplgrid{ display:grid; grid-template-columns:repeat(2,1fr); gap:10px; }
.ced-tpl{ position:relative; text-align:left; background:var(--ced-panel); border:1px solid var(--ced-line); border-radius:var(--r); padding:14px 15px; transition:.14s; cursor:pointer; }
@media (hover:hover){ .ced-tpl:hover{ border-color:var(--ced-ink3); } }
.ced-tpl.on{ border-color:var(--ced-accent); background:rgba(217,119,87,.07); }
.ced-tpl .tn{ font-family:var(--ced-serif); font-size:var(--t-texto); font-weight:400; line-height:1.1; padding-right:20px; letter-spacing:-.01em }
.ced-tpl .td{ font-size:var(--t-meta); color:var(--ced-ink3); margin-top:5px; line-height:1.45; max-height:32px; overflow:hidden; }
.ced-tpl .tmeta{ font-size:var(--t-meta); color:var(--ced-ink2); margin-top:9px; display:flex; gap:10px; }
.ced-tpl .cbadge{ position:absolute; top:12px; right:12px; font-size:8.5px; letter-spacing:.12em; text-transform:uppercase; font-weight:700; color:var(--ced-gold); }
.ced-tpl.on .tick{ position:absolute; top:11px; right:11px; color:var(--ced-accent); }
.ced-tpldel{ position:absolute; bottom:11px; right:11px; color:var(--ced-ink3); opacity:0; transition:.14s; }
@media (hover:hover){ .ced-tpl:hover .ced-tpldel{ opacity:1; } }
@media (hover:hover){ .ced-tpldel:hover{ color:var(--ced-accent); } }
.ced-tplnew{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:8px; border:1px dashed var(--ced-line); border-radius:var(--r); padding:14px; color:var(--ced-ink2); font-size:var(--t-texto); font-weight:600; transition:.14s; min-height:96px; width:100%; }
@media (hover:hover){ .ced-tplnew:hover{ border-color:var(--ced-accent); color:var(--ced-accent); } }
/* Antes vivia a lo ancho del panel del editor (~340-560px), "Guardar"/"Cancelar" a un
   lado del input cabian de sobra. Adentro del popover (320px) esa fila horizontal
   dejaba el input en ~106px -- ilegible. A columna: el input toma el ancho completo,
   Guardar queda de boton principal a lo ancho, Cancelar es solo texto. */
.ced-tplsave{ display:flex; flex-direction:column; gap:8px; margin-top:10px; }
.ced-tplsave .ced-btn.accent{ width:100%; justify-content:center; }
.ced-tplsave .ced-btn:not(.accent){ align-self:center; }
.ced-tplbar{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:12px; padding:12px 14px; background:var(--ced-panel); border:1px solid var(--ced-line); border-radius:var(--r); }
.ced-tplbar .bn{ font-family:var(--ced-serif); font-size:var(--t-texto); font-weight:400; display:flex; align-items:center; gap:9px; letter-spacing:-.01em }
.ced-tplbar .pencil{ color:var(--ced-ink3); }
@media (hover:hover){ .ced-tplbar .pencil:hover{ color:var(--ced-accent); } }
.ced-tpldirty{ display:inline-flex; align-items:center; gap:6px; font-size:var(--t-meta); font-weight:600; color:var(--ced-gold); }
.ced-tplbar .acts{ margin-left:auto; display:flex; gap:8px; }
.ced-chiprow{ display:flex; gap:8px; flex-wrap:wrap; }
.ced-pctchip{ padding:9px 15px; border-radius:var(--r); border:1px solid var(--ced-line); font-size:var(--t-texto); font-weight:600; color:var(--ced-ink2); transition:.14s; }
.ced-pctchip.on{ background:var(--ced-accent); border-color:var(--ced-accent); color:#fff; }
@media (hover:hover){ .ced-pctchip:not(.on):hover{ border-color:var(--ced-ink3); color:var(--ced-ink); } }

/* Control de anticipo (%/monto fijo), compartido entre el modal "Generar contrato"
   (paleta normal de la app) y el editor de pantalla completa (paleta propia --ced-*,
   ver arriba) -- las variables --ced-* llevan fallback al token normal de la app
   para que las MISMAS clases se vean bien en los dos scopes sin duplicar reglas. */
.antmodo{ display:inline-flex; gap:2px; padding:3px; border-radius:var(--r); background:var(--ced-line2, var(--deep)); margin-bottom:10px; }
.antmodobtn{ flex:0 0 auto; font-size:var(--t-meta); font-weight:600; padding:7px 14px; border:0; background:transparent; color:var(--ced-ink3, var(--muted)); border-radius:var(--r); cursor:pointer; transition:.14s; }
.antmodobtn.on{ background:var(--ced-accent, var(--accent)); color:#fff; }
.antpctchip{ padding:9px 15px; border-radius:var(--r); border:1px solid var(--ced-line, var(--line2)); font-size:var(--t-texto); font-weight:600; color:var(--ced-ink2, var(--ink)); background:transparent; cursor:pointer; transition:.14s; }
.antpctchip.on{ background:var(--ced-accent, var(--accent)); border-color:var(--ced-accent, var(--accent)); color:#fff; }
@media (hover:hover){ .antpctchip:not(.on):hover{ border-color:var(--ced-ink3, var(--muted)); } }

/* Fallbacks agregados para que gc-calcbox (modal "Generar contrato", fuera de .ced)
   reuse estas mismas clases -- dentro de .ced el fallback nunca se activa (--ced-*
   siempre esta definida ahi), cero cambio visual en el editor de pantalla completa. */
.ced-calcbox{ background:var(--ced-panel, var(--deep)); border:1px solid var(--ced-line, var(--line2)); border-radius:var(--r); padding:4px 16px; margin-top:14px; }
.ced-calcrow{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:13px 0; border-bottom:1px solid var(--ced-line2, var(--hair)); font-size:var(--t-texto); }
.ced-calcrow:last-child{ border-bottom:none; }
.ced-calcrow .cl{ color:var(--ced-ink2, var(--muted)); }
.ced-calcrow .cv{ font-family:var(--ced-serif, Georgia, serif); font-size:var(--t-sub); font-weight:600; }
.ced-calcrow.tot .cv{ color:var(--ced-accent, var(--accent)); }
.ced-calcrow .cv.neg{ color:var(--ced-red, var(--red)); }

/* servicios */
.ced-svc{ display:flex; align-items:center; gap:10px; margin-bottom:9px; transition:.14s; }
.ced-svc.dragging{ opacity:.4; }
.ced-handle{ color:var(--ced-ink3); cursor:grab; flex:none; display:flex; padding:4px; touch-action:none; }
.ced-chk{ width:22px; height:22px; border-radius:var(--r); border:1.5px solid var(--ced-ink3); flex:none; display:flex; align-items:center; justify-content:center; transition:.14s; color:transparent; font-size:var(--t-texto); }
.ced-chk.on{ background:var(--ced-accent); border-color:var(--ced-accent); color:#fff; }
.ced-svc .ced-inp{ flex:1; }
.ced-svc.off .ced-inp{ color:var(--ced-ink3); text-decoration:line-through; }
.ced-del{ width:34px; height:34px; border-radius:var(--r); border:1px solid var(--ced-line, var(--line2)); display:flex; align-items:center; justify-content:center; color:var(--ced-ink3, var(--muted)); flex:none; transition:.14s; font-size:var(--t-texto); }
@media (hover:hover){ .ced-del:hover{ border-color:var(--ced-accent, var(--accent)); color:var(--ced-accent, var(--accent)); } }
.ced-hint{ font-size:var(--t-meta); color:var(--ced-ink3); margin-top:10px; line-height:1.5; }
/* Detalle del servicio del recibo (recibos inteligentes, fase 1). Solo tokens --ced-*: es el editor oscuro. */
.red-det{ display:flex; flex-direction:column; gap:12px; margin-top:6px; }
.red-chips{ display:flex; flex-wrap:wrap; gap:8px; }
.red-chip{ height:34px; padding:0 14px; border-radius:100px; border:1px solid var(--ced-line); background:transparent; color:var(--ced-ink2); font:inherit; font-size:var(--t-meta); cursor:pointer; transition:.14s; }
@media (hover:hover){ .red-chip:hover{ border-color:var(--ced-ink3); color:var(--ced-ink); } }
.red-chip.on{ background:var(--ced-accent); border-color:var(--ced-accent); }
.red-det-tabla{ border:1px solid var(--ced-line); border-radius:var(--r); overflow:hidden; }
.red-det-cab, .red-det-fila{ display:grid; grid-template-columns:22px minmax(0,1fr) 64px 132px 104px 34px; gap:10px; align-items:center; padding:8px 12px; }
.red-det-cab{ background:var(--ced-line2); font-size:var(--t-eti); font-weight:600; letter-spacing:.1em; text-transform:uppercase; color:var(--ced-ink3); padding-top:10px; padding-bottom:10px; }
.red-det-fila{ border-top:1px solid var(--ced-line2); transition:.14s; }
.red-det-fila.dragging{ opacity:.4; }
.red-det-cab .n, .red-num{ text-align:right; }
.red-det-fila .ced-inp{ padding:9px 10px; min-width:0; }
.red-det-imp{ text-align:right; font-variant-numeric:tabular-nums; font-size:var(--t-texto); }
.red-det-totales{ align-self:flex-end; width:min(380px, 100%); margin-top:2px; }
.red-desc-ctl{ display:flex; align-items:center; gap:8px; }
.red-desc-ctl .ced-inp{ padding:6px 8px; width:64px; font-size:var(--t-meta); }
.red-desc-ctl select.ced-inp{ width:auto; }
.red-det-nota{ font-size:var(--t-meta); line-height:1.5; color:var(--ced-ink3); min-height:0; }
.red-det-nota.ok{ color:var(--ced-ok); }
.red-det-nota.aviso{ color:var(--ced-gold); }
.red-det-nota.mal{ color:var(--ced-red); }
/* Datos y calculos con formulas (recibos inteligentes, fase 2). Solo tokens --ced-*. */
.red-fx{ display:flex; flex-direction:column; gap:22px; margin:6px 0 4px; }
.red-fx-sec{ display:flex; flex-direction:column; gap:10px; }
.red-fx-tit{ display:flex; align-items:baseline; flex-wrap:wrap; gap:4px 12px; }
.red-fx-tit h4{ margin:0; font-size:var(--t-campo); font-weight:500; color:var(--ced-ink); }
.red-fx-tit span{ font-size:var(--t-meta); color:var(--ced-ink3); }
.red-datos{ display:flex; flex-wrap:wrap; gap:10px; }
.red-dato{ display:flex; align-items:center; gap:6px; }
.red-dato .ced-inp{ padding:8px 10px; }
.red-dato [data-role="dato-n"]{ width:130px; }
.red-dato [data-role="dato-v"]{ width:96px; }
.red-calc-tabla{ border:1px solid var(--ced-line); border-radius:var(--r); overflow:hidden; }
.red-calc-fila{ display:grid; grid-template-columns:minmax(90px,170px) minmax(0,1fr); gap:8px 10px; padding:10px 14px; border-top:1px solid var(--ced-line2); }
.red-calc-fila:first-child{ border-top:0; }
.red-calc-fila .ced-inp{ padding:9px 10px; min-width:0; }
.red-calc-l2{ grid-column:1 / -1; display:flex; align-items:center; gap:12px; flex-wrap:wrap; }
.red-calc-l2 select.ced-inp{ width:auto; }
.red-calc-res{ flex:1 1 auto; text-align:right; font-variant-numeric:tabular-nums; font-size:var(--t-texto); }
.red-calc-res.sin{ color:var(--ced-ink3); }
.red-calc-m{ display:inline-flex; align-items:center; gap:6px; font-size:var(--t-meta); color:var(--ced-ink3); cursor:pointer; }
.red-calc-err{ grid-column:1 / -1; font-size:var(--t-meta); line-height:1.5; color:var(--ced-red); display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.red-calc-err.aviso{ color:var(--ced-gold); }
.red-calc-err[hidden]{ display:none; }
.red-det-fila .red-calc-err{ padding:0 0 4px; }
.red-det-fila{ grid-template-rows:auto; }
.red-det-fila .red-calc-err{ grid-column:2 / -1; }
.ced-inp.mal{ border-color:var(--ced-red); }
.ced-inp.aviso{ border-color:var(--ced-gold); }
.red-num.red-fx{ color:var(--ced-accent); text-align:left; font-variant-numeric:tabular-nums; }
.red-fix{ height:28px; padding:0 12px; border:0; border-radius:100px; background:var(--ced-line2); color:var(--ced-ink); font:inherit; font-size:var(--t-meta); cursor:pointer; }
.red-calc-pie{ padding:12px 14px; border-top:1px solid var(--ced-line2); background:var(--ced-line2); display:flex; flex-direction:column; gap:10px; }
.red-insertar{ display:flex; align-items:center; flex-wrap:wrap; gap:6px; }
.red-insertar[hidden]{ display:none; }
.red-nombre{ height:26px; padding:0 10px; border:0; border-radius:100px; background:var(--ced-line2); color:var(--ced-ink2); font:inherit; font-size:var(--t-meta); font-variant-numeric:tabular-nums; cursor:pointer; }
.red-nombre.dato{ color:var(--ced-accent); }
.red-calc-acc{ display:flex; align-items:center; flex-wrap:wrap; gap:10px; position:relative; }
.red-calc-acc .ced-addbtn{ margin-top:0; }
.red-ej-caja{ position:relative; }
.red-ej-btn{ height:34px; padding:0 14px; border:0; border-radius:100px; background:var(--ced-line2); color:var(--ced-ink2); font:inherit; font-size:var(--t-texto); cursor:pointer; }
.red-ej{ position:absolute; z-index:5; left:0; top:calc(100% + 6px); width:min(460px, 80vw); display:flex; flex-direction:column; border-radius:var(--r); background:var(--ced-panel); border:1px solid var(--ced-line); box-shadow:0 20px 50px -20px rgba(0,0,0,.5); overflow:hidden; }
.red-ej[hidden]{ display:none; }
.red-ej-fila{ display:grid; grid-template-columns:1fr; gap:2px; padding:10px 14px; border:0; border-top:1px solid var(--ced-line2); background:transparent; color:var(--ced-ink); font:inherit; text-align:left; cursor:pointer; }
.red-ej-fila:first-child{ border-top:0; }
.red-ej-fila .tit{ font-size:var(--t-texto); }
.red-ej-fila .fx{ font-size:var(--t-meta); color:var(--ced-accent); font-variant-numeric:tabular-nums; }
.red-ej-fila .ef{ font-size:var(--t-meta); color:var(--ced-ink3); }
.red-det-totales .ced-calcrow.info{ font-style:italic; opacity:.8; }
.redp-det-info{ display:flex; justify-content:space-between; gap:18px; padding:3px 0 0; font-size:var(--t-meta); font-style:italic; color:var(--ced-papermut); font-variant-numeric:tabular-nums; }
.red-desglose{ margin-top:18px; }
.red-desglose > summary{ cursor:pointer; color:var(--ced-ink2); font-size:var(--t-texto); padding:6px 0; }
.ced-addbtn{ display:inline-flex; align-items:center; gap:8px; margin-top:12px; padding:10px 16px; border-radius:var(--r); border:1px dashed var(--ced-line); font-size:var(--t-texto); font-weight:600; color:var(--ced-ink2); transition:.14s; }
@media (hover:hover){ .ced-addbtn:hover{ border-color:var(--ced-accent); color:var(--ced-accent); } }
.ced-addrow{ display:flex; gap:10px; flex-wrap:wrap; }
/* Menu de paquete/servicio: se abre bajo los botones, dentro del flujo (no absolute)
   para que empuje el contenido y nunca quede cortado por el scroll del panel. */
.ced-pqmenu{ margin-top:12px; border:1px solid var(--ced-line); border-radius:var(--r); overflow:hidden; }
.ced-pqhd{ padding:10px 14px; font-size:var(--t-meta); letter-spacing:.08em; text-transform:uppercase; color:var(--ced-ink2); border-bottom:1px solid var(--ced-line); }
.ced-pqopt{ display:flex; align-items:center; gap:10px; width:100%; padding:12px 14px; text-align:left; border-bottom:1px solid var(--ced-line); transition:.12s; }
.ced-pqopt:last-child{ border-bottom:0; }
@media (hover:hover){ .ced-pqopt:hover{ background:var(--ced-accent); color:#fff; } }
@media (hover:hover){ .ced-pqopt:hover .pqs, .ced-pqopt:hover .pqp{ color:#fff; } }
.ced-pqopt .pqn{ font-weight:600; font-size:var(--t-texto); }
.ced-pqopt .pqs{ font-size:var(--t-meta); color:var(--ced-ink2); }
.ced-pqopt .pqp{ margin-left:auto; font-weight:600; font-size:var(--t-texto); }
.ced-pqvacio{ padding:14px; font-size:var(--t-texto); color:var(--ced-ink2); }

/* clausulas */
.ced-clause{ display:flex; align-items:flex-start; gap:12px; padding:12px 0; border-bottom:1px solid var(--ced-line2); }
.ced-clause:last-child{ border-bottom:none; }
/* Textarea sin caja de formulario -- sigue leyendose como el parrafo que es, no
   como un campo, pero crece con el texto (autoAlturaClausula) y se puede editar. */
.ced-clause .ct{ flex:1; font-family:inherit; font-size:var(--t-texto); line-height:1.55; color:var(--ced-ink2);
  border:none; background:transparent; padding:0; margin:0; resize:none; overflow:hidden; outline:none; width:100%; display:block; }
.ced-clause .ct:focus{ color:var(--ced-ink); }
.ced-clause.off .ct{ color:var(--ced-ink3); opacity:.6; }
.ced-clause .ced-chk, .ced-clause .ced-del{ margin-top:1px; }
.ced-clause .ced-del{ width:28px; height:28px; }
.ced-addclause{ display:flex; gap:10px; margin-top:14px; }
.ced-addclause .ced-inp{ flex:1; }
.ced-notice{ background:var(--ced-panel); border:1px solid var(--ced-line); border-radius:var(--r); padding:16px; font-size:var(--t-texto); line-height:1.6; color:var(--ced-ink2); }
.ced-notice p{ margin:0 0 12px; }

/* panel derecho: preview */
.ced-preview{ flex:1; min-width:0; overflow-y:auto; background:repeating-linear-gradient(45deg,#211f1d,#211f1d 12px,#232120 12px,#232120 24px); padding:34px; }
.ced-previewbar{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:20px; }
.ced-paper{ max-width:640px; margin:0 auto; background:var(--ced-paper); color:var(--ced-paperink); border-radius:4px; box-shadow:0 30px 80px -30px rgba(0,0,0,.6); padding:56px 58px 50px; }
.ced-pbrand{ display:flex; align-items:center; justify-content:space-between; gap:16px; padding-bottom:20px; border-bottom:1px solid var(--ced-paperline); }
.ced-pbrand .pn{ font-family:var(--ced-serif); font-size:var(--t-sub); font-weight:400; line-height:1.05; letter-spacing:-.01em }
.ced-pbrand img{ display:block; max-height:52px; max-width:220px; }
.ced-pbrand .pmeta{ text-align:right; font-size:var(--t-meta); color:var(--ced-papermut); line-height:1.7; }
.ced-ptitle{ font-family:var(--ced-serif); font-size:var(--t-saludo); font-weight:400; line-height:1.05; margin:30px 0 6px; letter-spacing:-.01em }
.ced-pparties{ font-size:var(--t-texto); line-height:1.7; color:#453e37; }
.ced-pparties b{ color:var(--ced-paperink); font-weight:600; }
.ced-plabel{ font-size:var(--t-eti); letter-spacing:.18em; text-transform:uppercase; color:var(--ced-papermut); font-weight:700; margin:32px 0 12px; }
.ced-psvc{ display:flex; align-items:flex-start; gap:11px; padding:8px 0; font-size:var(--t-texto); border-bottom:1px solid rgba(34,29,25,.07); }
.ced-psvc:last-child{ border-bottom:none; }
.ced-psvc .pc{ color:var(--ced-accent); flex:none; margin-top:2px; }
.ced-ptable{ border:1px solid var(--ced-paperline); border-radius:var(--r); overflow:hidden; }
.ced-ptrow{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:14px 18px; border-bottom:1px solid rgba(34,29,25,.08); font-size:var(--t-texto); }
.ced-ptrow:last-child{ border-bottom:none; }
.ced-ptrow .pl{ color:#453e37; }
.ced-ptrow .pl small{ display:block; color:var(--ced-papermut); font-size:var(--t-meta); margin-top:2px; }
.ced-ptrow .pv{ font-family:var(--ced-serif); font-size:var(--t-campo); font-weight:400; letter-spacing:-.01em }
.ced-ptrow.grand{ background:rgba(217,119,87,.08); }
.ced-ptrow.grand .pv{ color:var(--ced-accent2); font-size:var(--t-titulo); }
.ced-pclause{ font-size:var(--t-meta); line-height:1.75; color:#453e37; margin-bottom:10px; display:flex; gap:9px; }
.ced-pclause .pcn{ font-weight:700; color:var(--ced-paperink); flex:none; }
.ced-psign{ display:grid; grid-template-columns:1fr 1fr; gap:40px; margin-top:44px; }
.ced-psignbox{ border-top:1px solid var(--ced-paperink); padding-top:10px; }
.ced-psignbox img{ display:block; max-height:48px; margin-bottom:4px; }
.ced-psignbox .snm{ font-size:var(--t-texto); font-weight:600; }
.ced-psignbox .sst{ font-size:var(--t-meta); color:var(--ced-papermut); margin-top:2px; }
.ced-psignbox.done .snm{ font-family:var(--ced-serif); font-style:normal; font-size:var(--t-sub); font-weight:400; letter-spacing:-.01em }
.ced-psignbox.done .sst{ color:var(--ced-ok); font-weight:600; }
.ced-pfoot{ text-align:center; font-size:var(--t-meta); color:var(--ced-papermut); margin-top:34px; }

@media (max-width:1080px){
  .ced-body{ flex-direction:column; }
  .ced-editor{ width:100%; max-width:none; min-width:0; border-right:none; border-bottom:1px solid var(--ced-line); }
  .ced-preview{ padding:22px; }
  .ced-paper{ padding:40px 32px; }
}

/* ===== Editor de recibo (#/recibo/:id) — comparte el chrome .ced entero (cabecera,
   paneles, .ced-body/.ced-editor/.ced-sec/.ced-grid2/.ced-field/.ced-static/.ced-money/
   .ced-svc/.ced-del/.ced-calcbox/.ced-preview/.ced-paper, el @media de arriba): la
   raiz del editor es <div class="ced red">, asi que hereda TODO eso sin una linea
   nueva. Solo se aisla: (1) la paleta -- .ced.red redeclara --ced-accent* con mas
   especificidad que .ced, para que un cambio futuro en la paleta del contrato no
   arrastre al recibo sin querer; (2) el papel, porque el LAYOUT del documento (banda
   de anulado, hero de monto+letras, estado de cuenta) es forma-de-recibo, no
   forma-de-contrato -- espejo de RCPT_STYLE en src/documents.js. ===== */
.ced.red{ --ced-accent:#7c9471; --ced-accent2:#647a5b; }

/* Monto protegido (con pago_id): mismo tratamiento tipografico que .ced-money pero
   de solo lectura -- no es un .ced-inp, no debe leerse como editable. */
.red-montofijo{ font-family:var(--ced-serif); font-size:var(--t-sub); font-weight:400; color:var(--ced-accent); letter-spacing:-.01em }
/* Chip "vN - corregido" junto al pill de estado: mismo lenguaje que .ced-tpldirty
   (dorado = "algo distinto de lo emitido de fabrica"), clicable, abre el historial. */
.red-vchip{ display:inline-flex; align-items:center; gap:6px; font-size:var(--t-meta); font-weight:600; color:var(--ced-gold); padding:6px 12px; border-radius:var(--r); background:rgba(207,161,94,.14); border:none; cursor:pointer; }
@media (hover:hover){ .red-vchip:hover{ background:rgba(207,161,94,.22); } }

.redp-head{ text-align:center; padding-bottom:20px; margin-bottom:26px; border-bottom:1px solid var(--ced-paperline); }
.redp-brand{ font-family:var(--ced-serif); font-weight:400; font-size:var(--t-campo); letter-spacing:.02em; }
.redp-logo{ display:block; max-height:52px; max-width:240px; margin:0 auto; }
.redp-fiscal{ font-size:var(--t-meta); color:var(--ced-papermut); line-height:1.6; margin-top:10px; }
.redp-fiscal-cli{ grid-column:1 / -1; }
.red-fisc{ margin-top:18px; padding-top:16px; border-top:1px solid var(--ced-line, currentColor); display:flex; flex-direction:column; gap:12px; }
.red-fisc-hd{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.red-fisc-aviso{ font-size:var(--t-meta); color:var(--urge); margin-top:6px; }
.redp-slogan{ font-size:var(--t-meta); letter-spacing:.1em; text-transform:uppercase; color:var(--ced-papermut); margin-top:8px; }
.redp-titlewrap{ text-align:center; margin-bottom:28px; }
.redp-title{ font-family:var(--ced-serif); font-weight:400; font-size:var(--t-titulo); margin:0; letter-spacing:-.01em }
.redp-num{ font-size:var(--t-meta); letter-spacing:.1em; text-transform:uppercase; color:var(--ced-papermut); margin-top:6px; }
.redp-corregido{ font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--ced-accent2); margin-top:6px; font-weight:600; }
/* Banda de anulado: arriba y en flujo (no marca de agua), mismo criterio que
   RCPT_STYLE -- lo primero que se lee tiene que ser "esto ya no vale". */
.redp-anulado{ border:2px solid var(--ced-red); border-radius:var(--r); padding:12px 16px; margin-bottom:24px; text-align:center; }
.redp-anulado-t{ font-size:var(--t-meta); letter-spacing:.14em; text-transform:uppercase; color:var(--ced-red); font-weight:700; }
.redp-anulado-d{ font-size:var(--t-meta); color:var(--ced-papermut); margin-top:4px; }
.redp-grid2{ display:grid; grid-template-columns:1fr 1fr; gap:16px 28px; margin-bottom:18px; }
.redp-label{ font-size:var(--t-eti); letter-spacing:.1em; text-transform:uppercase; color:var(--ced-papermut); margin-bottom:5px; }
.redp-val{ font-size:var(--t-texto); color:#453e37; }
.redp-concepto{ margin-bottom:22px; }
.redp-hero{ border-left:3px solid var(--ced-accent); background:rgba(0,0,0,.025); padding:16px 20px; margin-bottom:26px; }
.redp-hero .redp-label{ margin-bottom:6px; }
.redp-hero-amt{ font-family:var(--ced-serif); font-weight:400; font-size:var(--t-titulo); color:var(--ced-accent); letter-spacing:-.01em }
.redp-hero-letras{ font-size:var(--t-meta); color:var(--ced-papermut); margin-top:4px; }
.redp-cuenta{ margin-bottom:26px; }
.redp-crow{ display:flex; justify-content:space-between; gap:18px; padding:8px 0; border-bottom:1px solid rgba(34,29,25,.08); font-size:var(--t-texto); color:#453e37; }
.redp-crow.b{ font-weight:600; }
/* Detalle del servicio en la vista previa del papel (espejo de .rcpt-det-* de src/documents.js). */
.redp-det-cols, .redp-det-row{ display:grid; grid-template-columns:minmax(0,1fr) 38px 84px 96px; gap:0 12px; }
.redp-det-cols{ margin-top:8px; padding:0 0 6px; border-bottom:1px solid var(--ced-paperink); font-size:var(--t-eti); letter-spacing:.1em; text-transform:uppercase; color:var(--ced-papermut); }
.redp-det-row{ padding:8px 0; border-bottom:1px solid rgba(34,29,25,.08); font-size:var(--t-texto); color:#453e37; font-variant-numeric:tabular-nums; }
.redp-det-cols .n, .redp-det-row .n{ text-align:right; }
.redp-det-sum{ display:flex; justify-content:space-between; gap:18px; padding:6px 0 0; font-size:var(--t-texto); color:#453e37; font-variant-numeric:tabular-nums; }
.redp-det-tot{ display:flex; justify-content:space-between; gap:18px; padding:9px 0; margin-top:8px; border-top:2px solid var(--ced-paperink); font-weight:600; color:var(--ced-paperink); font-variant-numeric:tabular-nums; }
.redp-incluye{ margin:8px 0 0; padding-left:18px; font-size:var(--t-texto); line-height:1.7; color:#453e37; }
.redp-crow.tot{ border-top:2px solid var(--ced-paperink); border-bottom:2px solid var(--ced-paperink); font-weight:600; padding:9px 0; margin-top:2px; color:var(--ced-paperink); }
.redp-vence{ font-size:var(--t-meta); color:var(--ced-papermut); margin-top:8px; }
.redp-foot{ text-align:center; border-top:1px solid var(--ced-paperline); padding-top:18px; margin-top:8px; }
.redp-foot-note{ font-size:var(--t-meta); color:var(--ced-papermut); line-height:1.6; margin:0 0 18px; }
.redp-sign-cta{ font-family:var(--ced-serif); font-style:normal; font-size:var(--t-texto); margin-bottom:2px; letter-spacing:-.01em }
.redp-sign-name{ font-family:var(--ced-serif); font-size:var(--t-texto); margin-bottom:16px; color:var(--ced-paperink); letter-spacing:-.01em }
.redp-contact{ display:flex; justify-content:center; gap:22px; flex-wrap:wrap; font-size:var(--t-meta); color:var(--ced-papermut); }
@media (max-width:520px){ .redp-grid2{ grid-template-columns:1fr; } .redp-contact{ flex-direction:column; gap:5px; } }

.dz-sw{ width:28px; height:28px; border-radius:50%; border:2px solid transparent; cursor:pointer; padding:0; }
.dz-sw.on{ border-color:var(--ink); box-shadow:0 0 0 2px var(--paper), 0 0 0 3px var(--ink); }
.dz-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; }
.dz-card{ border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); cursor:pointer; padding:0; height:64px; display:flex; align-items:center; justify-content:center; overflow:hidden; font-size:var(--t-meta); color:var(--muted); text-align:center; }
.dz-card.on{ border-color:var(--accent); box-shadow:inset 0 0 0 1px var(--accent); }
.dz-card img{ width:100%; height:100%; object-fit:cover; }
.dz-card-add{ font-size:var(--t-meta); }

/* tables */
.table{ width:100%; border-collapse:collapse; background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; }
.table th{ text-align:left; font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); font-weight:400; padding:13px 16px; border-bottom:1px solid var(--hair); }
.table td{ padding:14px 16px; border-bottom:1px solid var(--hair); font-size:var(--t-texto); vertical-align:middle; }
.trow{ cursor:pointer; transition:.1s; }
@media (hover:hover){ .trow:hover{ background:#F1EEE5; } }
.trow:last-child td{ border-bottom:0; }
.tname{ font-weight:600; }
.tsub{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
.docnum{ font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.14em; text-transform:uppercase; color:var(--accent); }

.toolbar{ display:flex; gap:12px; align-items:center; margin-bottom:18px; flex-wrap:wrap; }
.search{ flex:1; min-width:200px; display:flex; align-items:center; gap:10px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); padding:9px 15px; }
.search input{ border:0; background:transparent; outline:none; font-size:var(--t-texto); flex:1; }
.search .navdot{ width:11px; height:11px; flex:0 0 11px; border:1.5px solid #C6C0B0; border-radius:50%; }
.fchips{ display:flex; gap:8px; flex-wrap:wrap; }
.fchips[hidden]{ display:none; }
.fchip{ font-size:var(--t-meta); letter-spacing:.05em; text-transform:uppercase; padding:8px 14px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); cursor:pointer; color:var(--muted); }
.fchip.on{ background:var(--accent-solido); color:var(--accent-tinta); border-color:var(--accent-solido); }
/* Pestanas de Ajustes. Subrayadas y no .fchips: en esta app las pastillas significan
   "estas filtrando" (ver el comentario de .fed-tab, editor de automatizaciones) y aqui
   son secciones de UNA misma pantalla. Copiadas de .fed-tab y no reusadas por nombre
   porque .fed-barra arrastra reglas propias del editor de flujos (.fl-leyenda,
   max-width 1400). flex-wrap: en telefono las 8 pestanas envuelven en dos filas y
   todas quedan a la vista -- antes la fila hacia scroll horizontal sin pista y la
   ultima quedaba fuera de pantalla. */
.aj-tabs{ display:flex; flex-wrap:wrap; gap:2px; margin-bottom:20px; border-bottom:1px solid var(--hair); }
.aj-tab{ border:none; background:transparent; color:var(--muted); font:inherit; font-size:var(--t-texto); font-weight:600; padding:9px 14px; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; transition:.14s; white-space:nowrap; }
@media (hover:hover){ .aj-tab:hover{ color:var(--ink); } }
.aj-tab.on{ color:var(--ink); border-bottom-color:var(--accent); }
#aj-volver{ display:inline-block; margin-bottom:10px; }
/* Aviso unico de solo lectura (rol que ve pero no edita) y tic de "Guardado" inline:
   autoguardado sin toast para cada clic -- el toast queda para errores. */
.aj-solo-lectura{ font-size:var(--t-meta); color:var(--muted); background:var(--paper2, var(--paper)); border:1px solid var(--hair); border-radius:var(--r); padding:8px 12px; margin:0 0 14px; }
.aj-tick{ display:inline-block; margin-left:10px; font-size:var(--t-meta); color:var(--ok,#2e7d32); opacity:0; transition:opacity .25s; }
.aj-tick.on{ opacity:1; }
@media (max-width:640px){ .aj-tab{ padding:9px 10px; font-size:var(--t-texto); } }

/* modal */
.ov{ position:fixed; inset:0; background:rgba(43,41,38,.42); display:none; align-items:center; justify-content:center; z-index:60; padding:24px; }
.ov.show{ display:flex; animation:pop .18s ease both; }
.modal{ width:520px; max-width:100%; max-height:90vh; overflow-y:auto; background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); animation:pop .2s ease both; }
.modalwide{ width:600px; }
/* Pad de firma del portal (abrirFirma en portal.js): sin touch-action:none el dedo que
   dibuja el trazo tambien le pide al navegador que haga scroll/pan de la pagina detras
   -- la pantalla se corria al firmar en movil. Mismo candado que ya usan los ~10
   elementos de arrastre de este archivo (.ced-handle, .gal-item reordenable, etc.).
   max-width/height:auto: el canvas nace a 600x180 (atributos HTML, no CSS) y sin esto se
   desbordaba del modal en telefono -- pos() en portal.js ya escala el trazo por
   getBoundingClientRect() contra canvas.width/height, asi que achicar el DISPLAY size aqui
   no desalinea el dedo del trazo, solo faltaba permitir que se achicara. */
#firma-pad{ touch-action:none; max-width:100%; height:auto; display:block; }

/* ---------- Editor de paquete: lineas con precio y costo ---------- */
.pl-head,.pl-row{ display:grid; grid-template-columns:1fr 136px 62px 92px 92px 86px 30px; gap:8px; align-items:center; }
.pl-head.nocosto,.pl-row.nocosto{ grid-template-columns:1fr 136px 62px 92px 86px 30px; }
.pl-head{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin-bottom:6px; }
.pl-row{ margin-bottom:8px; }
.pl-row .inp,.pl-row .sel{ padding:8px 10px; font-size:var(--t-texto); }
.pl-sub{ text-align:right; font-size:var(--t-texto); color:var(--muted); font-variant-numeric:tabular-nums; }
.pl-chips{ display:flex; flex-wrap:wrap; gap:6px; margin-bottom:12px; }
.pl-chips .chip{ padding:6px 12px; font-size:var(--t-meta); }
.pl-calc{ margin-top:18px; padding:14px 16px; border:1px solid var(--hair); border-radius:var(--r); background:color-mix(in srgb, var(--ink) 3%, var(--paper)); }
.pl-crow{ display:flex; justify-content:space-between; align-items:center; gap:12px; padding:5px 0; font-size:var(--t-texto); }
/* Sin esto el [hidden] no surte efecto: una regla de autor con display gana contra la
   hoja del navegador, y las filas ocultas se seguian viendo. */
.pl-crow[hidden]{ display:none; }
.pl-crow .money{ font-variant-numeric:tabular-nums; }
.pl-crow.tot{ border-top:1px solid var(--hair); margin-top:8px; padding-top:11px; font-weight:600; font-size:var(--t-texto); }
.pl-crow.tot .v{ color:var(--accent); font-variant-numeric:tabular-nums; }
.pl-money{ position:relative; display:inline-block; }
.pl-money .cur{ position:absolute; left:11px; top:50%; transform:translateY(-50%); color:var(--muted); font-size:var(--t-texto); pointer-events:none; }
.pl-money .inp{ width:150px; padding-left:24px; text-align:right; font-size:var(--t-texto); font-weight:600; }
.pl-derivados{ margin-top:12px; padding:10px 14px; border-radius:var(--r); background:var(--bone); font-size:var(--t-texto); color:var(--muted); }
.pl-derivados .flabel{ display:inline; margin-right:6px; }
@media (max-width:760px){
  .pl-head{ display:none; }
  .pl-row,.pl-row.nocosto{ grid-template-columns:1fr 1fr; gap:6px; padding:10px; border:1px solid var(--line2); border-radius:var(--r); }
  .pl-row .inp[data-k="concepto"]{ grid-column:1/3; }
  .pl-sub{ text-align:left; }
}
/* Editor de paquete: lleva una tabla de elementos (concepto + entregable + 3 numeros)
   que no cabe en 600px sin quedar apretada. (Regla duplicada de mas arriba borrada: esta,
   mas abajo en el archivo, es la que siempre ganaba por especificidad igual + orden.) */
.modalxl{ width:960px; max-width:96vw; }
/* Vista expandida del mapa de la boda: mas ancho que .modalxl a proposito -- es justo
   donde el zoom "detalle" (el que mas separa los pasos apretados) necesita sitio. */
.modal-mapa{ width:1400px; max-width:96vw; }
.mhead{ display:flex; align-items:center; justify-content:space-between; padding:20px 24px; border-bottom:1px solid var(--hair); }
.mtitle{ font-family:var(--serif); font-weight:400; font-size:var(--t-sub); letter-spacing:-.01em }
.x{ width:30px; height:30px; border:1px solid var(--line2); border-radius:var(--r); background:transparent; cursor:pointer; font-size:var(--t-texto); line-height:1; color:var(--ink); }
@media (hover:hover){ .x:hover{ background:#ECE7DB; } }
.mbody{ padding:22px 24px; }
.field{ margin-bottom:16px; }
.flabel{ font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); margin-bottom:6px; display:block; }
.inp,.sel,.ta{ width:100%; font-size:var(--t-texto); padding:10px 12px; border:1px solid var(--line2); border-radius:var(--r); background:#FFFDF8; outline:none; }
.inp:focus,.sel:focus,.ta:focus{ background:#fff; border-color:var(--accent); }
.ta{ resize:vertical; min-height:76px; }
.frow{ display:grid; grid-template-columns:1fr 1fr; gap:14px; }
.mfoot{ display:flex; gap:10px; align-items:center; padding:18px 24px; border-top:1px solid var(--hair); }
.paybox{ background:#F6F3EB; border:1px solid var(--hair); border-radius:var(--r); padding:16px; margin-top:4px; }
.payline{ display:flex; justify-content:space-between; font-size:var(--t-texto); padding:6px 0; border-bottom:1px solid var(--hair); }
.payline:last-child{ border-bottom:0; }
.paybig{ display:flex; justify-content:space-between; align-items:baseline; padding-top:10px; }

/* Fila de pago con su segunda linea de recibo. El borde salta de .payline a .payrow: si se
   queda en .payline, cada pago dibuja una raya ENTRE su monto y su propio recibo, partiendo en
   dos algo que es un solo hecho. */
.payrow{ border-bottom:1px solid var(--hair); padding:2px 0 8px; }
.payrow:last-of-type{ border-bottom:1px solid var(--hair); }
.payrow .payline{ border-bottom:0; padding-bottom:2px; }
.payrec{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.payrec .tsub{ margin-right:auto; }              /* el estado empuja las acciones a la derecha */
.payrec .btn{ padding:4px 9px; font-size:var(--t-meta); line-height:1.35; }
/* Barra de avance del cobro. El fotografo no la tenia: su cliente veia el progreso en el
   portal y el, en su propio CRM, no. Misma lectura que el gauge de Dinero. */
.paygauge{ height:6px; border-radius:var(--r); background:var(--hair); overflow:hidden; margin-top:8px; }
.paygauge-fill{ height:100%; background:var(--accent); border-radius:var(--r); transition:width .35s ease; }
/* Aviso del anticipo escrito en el contrato que nadie registro como pago. */
.payaviso{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-top:12px; padding:10px 12px;
  border:1px solid var(--hair); border-left:3px solid var(--red); border-radius:var(--r); font-size:var(--t-meta); }
/* Casilla "Enviar recibo". En .off no se esconde: se apaga y ENSENA el motivo, porque una
   casilla marcada que en silencio no manda nada es peor que no tener casilla. */
.payenv{ display:flex; align-items:center; gap:8px; font-size:var(--t-meta); cursor:pointer; flex:1; min-width:220px; }
.payenv.off{ color:var(--muted); cursor:default; }
.payenv input{ width:15px; height:15px; accent-color:var(--accent); flex:none; }

.settcard{ padding:28px 30px; max-width:680px; }
/* Va DESPUES de la regla base a proposito: misma especificidad, gana la ultima. En 375px
   los 60px laterales de arriba dejaban ~315px para los campos de Ajustes. */
@media (max-width:640px){ .settcard{ padding:18px 16px; } }

/* toast */
#toast{ position:fixed; left:50%; bottom:34px; transform:translateX(-50%) translateY(14px); background:var(--ink); color:var(--paper); padding:13px 22px; border-radius:var(--r); font-size:var(--t-texto); z-index:90; display:flex; align-items:center; gap:11px; opacity:0; pointer-events:none; transition:.25s; }
#toast.show{ opacity:1; transform:translateX(-50%) translateY(0); }
#toast:before{ content:''; width:9px; height:9px; background:var(--accent); border-radius:50%; }
#toast .toast-accion{ font-size:var(--t-texto); font-weight:600; color:var(--accent); background:none; border:none; cursor:pointer; pointer-events:auto; flex:none; padding:0; }

/* Backdrop del chat de Xarpie en movil: oscurece el CRM detras y cierra al tocar.
   Fuera de movil nunca se muestra (el chat es una columna fija, no un overlay). */
.cp-backdrop{ display:none; }

/* Badge de la campana de notificaciones (#nav-notif-btn, reusa .cp-navcfg). Regla suelta
   y no duplicada dentro de los dos @media de .cp-navcfg (movil/escritorio, mas abajo):
   position:relative no choca con nada que esos bloques ya definan, asi que aplica en los
   dos breakpoints sin repetir el badge dos veces. */
.cp-navcfg{ position:relative; }
.cp-navnotif-badge{
  position:absolute; top:3px; right:3px; min-width:16px; height:16px; padding:0 3px;
  border-radius:var(--r); background:var(--accent-solido); color:var(--accent-tinta); font-size:var(--t-eti); font-weight:700;
  line-height:16px; text-align:center; pointer-events:none; box-shadow:0 0 0 2px var(--deep);
}

/* Piezas que solo existen en telefono (icono de categoria, etiqueta junto a campana/
   engrane): base oculta ANTES del @media que las enciende, misma especificidad. */
.cp-navico, .cp-navcfg-lbl{ display:none; }
@media (max-width:860px){
  /* Antes era min(92vw,420px): dejaba un hueco de ~8vw a la derecha por el que se veia
     (y se podia scrollear, ver abrirChat/cerrarChat en app.js) el CRM de atras a traves
     del backdrop, que es translucido, no un tapon. "En telefono el chat es la pantalla"
     ya era la intencion (ver comentario mas abajo, .chatpane con padding reducido) --
     92vw fue un descuido heredado del calculo de ancho de escritorio. */
  .chatpane{ position:fixed; left:0; top:0; z-index:70; width:100%; height:100vh; transform:translateX(-100%); transition:transform .24s ease; box-shadow:14px 0 40px -20px rgba(0,0,0,.4); }
  .chatpane.open{ transform:translateX(0); }
  #app.show{ display:block; }
  .main{ height:100vh; }
  .dash{ grid-template-columns:1fr; }
  .frow{ grid-template-columns:1fr; }
  .cp-sess{ display:none; }
  .cp-backdrop.show{ display:block; position:fixed; inset:0; z-index:69; background:rgba(43,41,38,.42); animation:pop .18s ease both; }

  /* El cajon movil del carril (lista vertical de categorias, acordeon de subcategorias y el
     boton de Xarpie en fila) se RETIRO con el menu de 4 secciones (2026-09-12): en telefono
     #cp-riel es la cabecera y las secciones viven en #barra-inf (bloque TELEFONO al final). */
  .cp-brand .cp-close{ margin-left:0; }
  .nav-menu .um-item{ font-size:var(--t-meta); padding:8px 10px; }
  .nav-menu .um-sep{ margin:4px 10px 4px 0; }
  .cp-navcfg{
    flex:none; margin:2px 6px; height:auto; border-radius:var(--r); border:0;
    background:transparent; color:var(--muted); display:flex; align-items:center; gap:12px;
    padding:9px 8px; justify-content:flex-start; cursor:pointer; transition:background .13s, color .13s;
    font-family:inherit; font-size:var(--t-texto); font-weight:500; width:100%; text-align:left;
  }
  .cp-navcfg:last-of-type{ margin-bottom:8px; }
  @media (hover:hover){ .cp-navcfg:hover{ background:var(--paper); color:var(--ink); } }
  .cp-navcfg[aria-expanded="true"]{ background:var(--paper); color:var(--ink); }
  /* La etiqueta junto al icono: en escritorio ese mismo boton se queda solo-icono (no era
     parte de este rediseno), asi que el span nace oculto y solo se muestra aqui. */
  .cp-navcfg-lbl{ display:block; flex:1 1 auto; min-width:0; }
}
/* Boton de cerrar el chat de Xarpie (visible en movil, dentro de la cabecera del panel). */
.cp-close{ display:none; }
@media (max-width:860px){
  .cp-close{ display:grid; place-items:center; margin-left:8px; width:30px; height:30px; flex:0 0 30px; border:1px solid var(--line2); border-radius:var(--r); background:transparent; color:var(--muted); cursor:pointer; font-size:var(--t-texto); line-height:1; }
  @media (hover:hover){ .cp-close:hover{ background:#E4DFD2; color:var(--ink); } }
}

/* ---------- Editor de la pagina publica (landing) ---------- */
.lp-editor{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1.05fr); gap:22px; align-items:start; }
.lp-panel{ display:flex; flex-direction:column; gap:16px; min-width:0; }
.lp-card-sec{ max-width:none; padding:20px 22px; }
.lp-status{ font-size:var(--t-texto); color:var(--muted); }
.lp-status .pill{ margin-right:6px; }
.lp-domain{ font-size:var(--t-texto); color:var(--muted); white-space:nowrap; }
.lp-tpls{ display:flex; flex-wrap:wrap; gap:8px; margin-top:6px; }
.lp-tpl{ padding:8px 14px; border:1px solid var(--line2); border-radius:var(--r); background:#FFFDF8; font-size:var(--t-texto); cursor:pointer; }
.lp-tpl.on{ border-color:var(--accent); background:#fff; color:var(--accent); font-weight:600; }
.lp-color{ width:100%; height:38px; padding:2px; border:1px solid var(--line2); border-radius:var(--r); background:#fff; cursor:pointer; }
.lp-blk{ border:1px solid var(--hair); border-radius:var(--r); margin-bottom:12px; overflow:hidden; background:#fff; }
.lp-blk-h{ display:flex; align-items:center; justify-content:space-between; padding:9px 14px; background:var(--bone); border-bottom:1px solid var(--hair); }
.lp-blk-t{ font-weight:600; font-size:var(--t-texto); }
.lp-blk-actions{ display:flex; gap:4px; }
.lp-mini{ width:26px; height:26px; border:1px solid var(--line2); background:#FFFDF8; border-radius:var(--r); cursor:pointer; font-size:var(--t-meta); color:var(--muted); }
.lp-mini:disabled{ opacity:.4; cursor:default; }
@media (hover:hover){ .lp-mini-x:hover{ border-color:var(--red); color:var(--red); } }
.lp-blk-body{ padding:16px 14px; }
.lp-blk-body .field:last-child{ margin-bottom:0; }
.lp-note{ font-size:var(--t-meta); margin:4px 0 0; }
.lp-addwrap{ display:flex; gap:8px; margin-top:6px; }
.lp-addwrap .sel{ flex:1; }
.lp-items{ display:flex; flex-direction:column; gap:8px; }
.lp-item{ display:flex; gap:6px; align-items:center; }
.lp-item .inp{ padding:8px 10px; font-size:var(--t-texto); }
.lp-item-x{ border:0; background:transparent; cursor:pointer; color:var(--muted); font-size:var(--t-texto); padding:4px; }
@media (hover:hover){ .lp-item-x:hover{ color:var(--red); } }
.lp-thumbs{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
.lp-thumb{ position:relative; width:64px; height:64px; border-radius:var(--r); overflow:hidden; border:1px solid var(--hair); }
.lp-thumb.lp-thumb-lg{ width:120px; height:80px; }
.lp-thumb img{ width:100%; height:100%; object-fit:cover; }
.lp-thumb-x{ position:absolute; top:2px; right:2px; background:rgba(0,0,0,.55); color:#fff; width:20px; height:20px; border-radius:50%; border:0; line-height:1; cursor:pointer; font-size:var(--t-meta); }
/* Galeria con texto alternativo (SEO de imagenes): la miniatura crece para dejar
   espacio a un input chico debajo, en vez del cuadrado fijo sin texto. */
.lp-thumbs-alt .lp-thumb{ width:96px; height:auto; overflow:visible; border:0; display:flex; flex-direction:column; gap:4px; }
.lp-thumbs-alt .lp-thumb img{ width:96px; height:64px; border-radius:var(--r); border:1px solid var(--hair); }
.lp-thumb-alt{ width:96px; font-size:var(--t-eti); padding:5px 7px; }
.lp-add-img{ border:1px dashed var(--line2); background:#FFFDF8; border-radius:var(--r); padding:0 14px; height:64px; min-width:70px; cursor:pointer; font-size:var(--t-meta); color:var(--muted); }
@media (hover:hover){ .lp-add-img:hover{ border-color:var(--accent); color:var(--accent); } }
.lp-savebar{ position:sticky; bottom:0; display:flex; align-items:center; justify-content:flex-end; gap:14px; padding:12px 0 4px; background:var(--bone); }
.lp-dirty{ font-size:var(--t-meta); color:var(--yellow); font-weight:600; }
.lp-previewwrap{ position:sticky; top:18px; border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; background:#fff; }
.lp-preview-top{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); padding:10px 14px; border-bottom:1px solid var(--hair); background:var(--paper); }
.lp-preview{ width:100%; height:calc(100vh - 150px); min-height:520px; border:0; display:block; background:#fff; }
@media (max-width:980px){
  .lp-editor{ grid-template-columns:1fr; }
  .lp-previewwrap{ position:static; }
  .lp-preview{ height:70vh; }
}

/* ---------- Disponibilidad semanal (Citas) ---------- */
.ci-day{ display:grid; grid-template-columns:110px 1fr; gap:12px; align-items:start; padding:10px 0; border-bottom:1px solid var(--hair); }
.ci-day:last-child{ border-bottom:0; }
.ci-day-n{ font-weight:600; font-size:var(--t-texto); padding-top:8px; }
.ci-ranges{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; }
.ci-range{ display:flex; align-items:center; gap:6px; background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); padding:5px 8px; }
.ci-range .inp{ width:auto; padding:6px 8px; font-size:var(--t-texto); }
.ci-a{ color:var(--muted); font-size:var(--t-texto); }
.ci-none{ font-size:var(--t-texto); padding-top:8px; }
.ci-add{ white-space:nowrap; }
@media (max-width:560px){ .ci-day{ grid-template-columns:1fr; gap:6px; } .ci-day-n{ padding-top:0; } }

/* ---------- Reservas en linea, pantalla guiada (#/citas) ----------
   La pantalla era una pila de tarjetas de formulario identicas: nada decia cual venia
   primero ni para que servia ninguna. Se reorganizo en 4 pasos con estado, una banda de
   fotos DEL ESTUDIO arriba y una vista previa de lo que ve el cliente al lado, que es lo
   unico que explica el proposito sin una sola linea de texto extra. Namespace .cig-*
   aparte del .ci-* de arriba a proposito: el viejo sigue vivo mientras se migra. */
.cig-layout{ display:grid; grid-template-columns:minmax(0,1fr) 352px; gap:22px; align-items:start; }
.cig-main{ min-width:0; }

/* Banda de fotos: las portadas de las galerias del estudio. Sin galerias queda lisa (fondo --deep);
   ya no cae a fotos de muestra ni en el panel ni en la pagina publica. */
.cig-hero{ position:relative; border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; margin-bottom:18px; min-height:212px; display:flex; align-items:flex-end; }
.cig-hero-fotos{ position:absolute; inset:0; display:grid; grid-auto-flow:column; grid-auto-columns:1fr; gap:2px; background:var(--deep); }
.cig-hero-fotos img{ width:100%; height:100%; object-fit:cover; display:block; }
/* Dos capas, no una: el texto vive abajo a la izquierda y las fotos que trae el fotografo
   pueden ser claras justo ahi (un campo al sol). La vertical sola media ~3:1 sobre la
   foto de campo; la horizontal es la que sostiene el parrafo. */
.cig-hero-velo{ position:absolute; inset:0; background:
  linear-gradient(100deg, rgba(43,41,38,.86) 0%, rgba(43,41,38,.5) 46%, rgba(43,41,38,.16) 100%),
  linear-gradient(180deg, rgba(43,41,38,.14) 0%, rgba(43,41,38,.55) 62%, rgba(43,41,38,.84) 100%); }
.cig-hero-in{ position:relative; width:100%; padding:24px 26px 22px; color:#FCFBF7; }
.cig-hero-eyebrow{ font-size:var(--t-eti); letter-spacing:.22em; text-transform:uppercase; opacity:.82; margin-bottom:6px; }
.cig-hero-t{ font-family:var(--serif); font-weight:400; font-size:var(--t-saludo); line-height:1.05; margin:0; letter-spacing:-.01em }
.cig-hero-d{ font-size:var(--t-texto); opacity:.86; margin:7px 0 0; max-width:46ch; }
.cig-hero-pie{ display:flex; align-items:center; justify-content:space-between; gap:14px; flex-wrap:wrap; margin-top:16px; }
.cig-hero-estado{ display:flex; align-items:center; gap:8px; font-size:var(--t-texto); }
.cig-punto{ width:8px; height:8px; border-radius:50%; background:var(--yellow); flex:0 0 8px; }
.cig-punto.on{ background:#93B08A; }
.cig-hero .btn{ background:rgba(252,251,247,.14); border-color:rgba(252,251,247,.4); color:#FCFBF7; }
@media (hover:hover){ .cig-hero .btn:hover{ background:rgba(252,251,247,.24); } }
.cig-hero .btn-p{ background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); }

/* Riel de pasos: chips horizontales (no columna lateral) porque la vista previa ya se
   lleva una columna; una tercera dejaba el contenido en ~420px. */
.cig-rail{ display:flex; flex-wrap:wrap; gap:8px; margin-bottom:18px; }
.cig-chip{ display:flex; align-items:center; gap:8px; border:1px solid var(--line2); background:var(--paper); border-radius:var(--r); padding:6px 15px 6px 7px; font-size:var(--t-texto); color:var(--ink); cursor:pointer; transition:border-color var(--dur-1) var(--ease-estado), color var(--dur-1) var(--ease-estado); }
@media (hover:hover){ .cig-chip:hover{ border-color:var(--accent); color:var(--accent); } }
.cig-chip-n{ width:21px; height:21px; flex:0 0 21px; border-radius:50%; display:grid; place-items:center; background:var(--deep); color:var(--muted); font-size:var(--t-meta); font-weight:700; }
.cig-chip.on .cig-chip-n{ background:#93B08A; color:#fff; }

.cig-step{ margin-bottom:16px; scroll-margin-top:14px; }
.cig-step-head{ display:flex; align-items:flex-start; gap:13px; margin-bottom:17px; }
.cig-step-num{ width:30px; height:30px; flex:0 0 30px; border-radius:50%; display:grid; place-items:center; background:var(--deep); color:var(--muted); font-size:var(--t-texto); font-weight:700; margin-top:2px; }
.cig-step.done .cig-step-num{ background:#93B08A; color:#fff; }
.cig-step-t{ font-family:var(--serif); font-weight:400; font-size:var(--t-sub); line-height:1.15; letter-spacing:-.01em }
.cig-step-d{ color:var(--muted); font-size:var(--t-texto); margin-top:3px; }
.cig-step-pill{ margin-left:auto; flex:0 0 auto; }
.cig-hint{ font-size:var(--t-meta); color:var(--muted); margin:6px 0 0; }
.cig-acciones{ display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-top:16px; }

/* Servicios como tarjetas: un servicio es un producto, no una fila de tabla. */
.cig-serv-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(220px,1fr)); gap:12px; }
/* var(--paper), NUNCA #fff: el tema oscuro redefine --ink a un hueso claro pero no toca
   un color literal, asi que un fondo blanco fijo dejaba el titulo blanco sobre blanco.
   Medido en la pantalla, no supuesto. (La vista previa .cig-prev SI fija sus colores a
   proposito -- ahi fija fondo Y texto, porque imita una pagina que siempre es clara.) */
.cig-serv{ display:block; width:100%; text-align:left; font:inherit; color:inherit; border:1px solid var(--hair); background:var(--paper); border-radius:var(--r); padding:14px 15px; cursor:pointer; transition:border-color var(--dur-1) var(--ease-estado), transform var(--dur-1) var(--ease-estado); }
@media (hover:hover){ .cig-serv:hover{ border-color:var(--accent); transform:translateY(-1px); } }
.cig-serv.off{ opacity:.55; }
.cig-serv-t{ font-weight:600; font-size:var(--t-texto); line-height:1.25; }
.cig-serv-meta{ display:flex; flex-wrap:wrap; gap:6px; margin-top:9px; }
.cig-tag{ display:inline-flex; align-items:center; gap:4px; font-size:var(--t-meta); color:var(--muted); background:var(--bone); border-radius:var(--r); padding:3px 9px; }
.cig-tag.precio{ color:var(--accent); background:color-mix(in srgb, var(--accent) 10%, var(--paper)); font-weight:600; }
.cig-nuevo{ border:1px dashed var(--line2); background:var(--paper); border-radius:var(--r); padding:14px 15px; min-height:78px; color:var(--muted); font-size:var(--t-texto); cursor:pointer; display:grid; place-items:center; gap:4px; }
@media (hover:hover){ .cig-nuevo:hover{ border-color:var(--accent); color:var(--accent); } }

/* Semana como grilla: se lee de un golpe cuales dias trabajas. auto-fit y no repeat(7)
   para que no reviente cuando la columna de la vista previa se queda con su ancho. */
/* 116px de minimo. Se probo con 88 para meter los 7 dias en una fila, y se midio que un
   <input type=time> en locale de 12 horas pide ~105px de ancho natural: a 88 el navegador
   lo recortaba a 69 y se comia el AM/PM, o sea que "02:00 PM" se leia "02:0". Una semana
   en una sola fila no vale una hora que no se puede leer, asi que auto-fit la envuelve. */
.cig-week{ display:grid; grid-template-columns:repeat(auto-fit, minmax(116px,1fr)); gap:6px; }
.cig-dia{ border:1px solid var(--hair); border-top:2px solid var(--line2); border-radius:var(--r); background:var(--paper); padding:9px 8px 8px; display:flex; flex-direction:column; gap:6px; }
.cig-dia.tiene{ border-top-color:var(--accent); background:var(--deep); }
.cig-dia-n{ font-size:var(--t-eti); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600; }
.cig-dia.tiene .cig-dia-n{ color:var(--ink); }
.cig-rango{ display:flex; flex-direction:column; gap:2px; background:var(--bone); border-radius:var(--r); padding:5px 6px; position:relative; }
.cig-rango .inp{ width:100%; min-width:94px; padding:3px 4px; font-size:var(--t-meta); border-radius:var(--r); }
.cig-rango-a{ font-size:var(--t-eti); color:var(--muted); text-align:center; }
.cig-rango .lp-item-x{ position:absolute; top:1px; right:1px; padding:1px; }
.cig-dia-sin{ font-size:var(--t-meta); color:var(--muted); }
.cig-dia-add{ border:1px dashed var(--line2); background:transparent; border-radius:var(--r); color:var(--muted); font-size:var(--t-meta); padding:4px; cursor:pointer; margin-top:auto; }
@media (hover:hover){ .cig-dia-add:hover{ border-color:var(--accent); color:var(--accent); } }

.cig-share{ display:flex; gap:8px; align-items:center; }
.cig-share .inp{ font-size:var(--t-texto); }
.cig-aviso{ display:flex; gap:9px; align-items:flex-start; font-size:var(--t-texto); background:color-mix(in srgb, var(--yellow) 14%, var(--paper)); border:1px solid color-mix(in srgb, var(--yellow) 34%, var(--paper)); color:#7A5A20; border-radius:var(--r); padding:10px 13px; margin-top:14px; }

/* Estado vacio con imagen: el .empty de la app es una linea de texto gris, que en una
   pantalla que se rediseño para ser visual se lee como un error. */
.cig-vacio{ display:flex; gap:16px; align-items:center; border:1px solid var(--hair); border-radius:var(--r); background:var(--paper); padding:16px; }
.cig-vacio-t{ font-weight:600; font-size:var(--t-texto); }
.cig-vacio-d{ color:var(--muted); font-size:var(--t-texto); margin-top:3px; }

/* Vista previa. Es un mock en HTML plano, no un iframe: el CSS de la pagina publica vive
   inline dentro de src/agenda.js y no se puede importar desde aqui. Todo lo de adentro va
   scopeado bajo .cig-prev para no heredar la tipografia del CRM -- el punto es que se vea
   como OTRA pagina, la del cliente. Si cambias src/agenda.js, actualiza esto. */
.cig-prevwrap{ position:sticky; top:18px; border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; background:var(--paper); }
.cig-prev-top{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:10px 14px; border-bottom:1px solid var(--hair); background:var(--paper); }
.cig-prev-top .lbl{ font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); }
.cig-prev{ background:#F3F1EA; color:#2B2926; font-family:Georgia,'Times New Roman',serif; padding:20px 18px 26px; max-height:calc(100vh - 210px); overflow:auto; }
.cig-prev-portada{ width:100%; height:96px; object-fit:cover; border-radius:var(--r); display:block; margin-bottom:14px; }
.cig-prev-logo{ max-height:34px; max-width:150px; object-fit:contain; display:block; margin:0 auto 10px; }
.cig-prev-top-txt{ text-align:center; margin-bottom:18px; }
.cig-prev-eyebrow{ font-family:var(--sans); font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:#87847A; margin-bottom:6px; }
.cig-prev-estudio{ font-size:var(--t-titulo); font-weight:600; line-height:1.1; }
.cig-prev-titulo{ font-size:var(--t-texto); margin-top:8px; }
.cig-prev-msg{ font-family:var(--sans); font-size:var(--t-meta); color:#87847A; margin-top:6px; line-height:1.5; }
.cig-prev-card{ background:#FCFBF7; border:1px solid #E7E3D8; border-radius:var(--r); padding:13px 14px; margin-bottom:9px; }
.cig-prev-card-t{ font-size:var(--t-texto); font-weight:600; }
.cig-prev-card-m{ font-family:var(--sans); font-size:var(--t-meta); color:#87847A; margin-top:3px; }
.cig-prev-badge{ font-family:var(--sans); font-size:var(--t-eti); font-weight:700; letter-spacing:.04em; text-transform:uppercase; color:#C96442; background:color-mix(in srgb, #C96442 14%, #FCFBF7); border-radius:var(--r); padding:2px 7px; vertical-align:middle; }
.cig-prev-vacio{ font-family:var(--sans); font-size:var(--t-meta); color:#87847A; text-align:center; border:1px dashed #DCD7CA; border-radius:var(--r); padding:20px 14px; }

@media (max-width:980px){
  .cig-layout{ grid-template-columns:1fr; }
  .cig-prevwrap{ position:static; }
  .cig-prev{ max-height:none; }
}
@media (max-width:560px){
  .cig-hero{ min-height:186px; }
  .cig-hero-t{ font-size:var(--t-titulo); }
  .cig-hero-in{ padding:20px 18px 18px; }
  .cig-week{ grid-template-columns:1fr; }
  .cig-dia{ flex-direction:row; flex-wrap:wrap; align-items:center; }
  .cig-dia-n{ flex:0 0 74px; }
  .cig-rango{ flex-direction:row; align-items:center; gap:6px; padding:5px 22px 5px 8px; }
  .cig-rango .inp{ width:auto; }
  .cig-dia-add{ margin-top:0; }
}

/* ---------- Ficha del cliente ---------- */
.lp-back{ display:inline-block; color:var(--muted); text-decoration:none; font-size:var(--t-texto); cursor:pointer; }
@media (hover:hover){ .lp-back:hover{ color:var(--accent); } }
.cl-inforow{ display:flex; justify-content:space-between; gap:12px; padding:9px 0; border-bottom:1px solid var(--hair); font-size:var(--t-texto); }
.cl-inforow:last-child{ border-bottom:0; }
.cl-notas{ padding:10px 0 2px; border-top:1px solid var(--hair); margin-top:2px; }
.cl-notas div:last-child{ white-space:pre-wrap; font-size:var(--t-texto); margin-top:4px; }
.cl-ev{ padding:14px 0; border-bottom:1px solid var(--hair); }
.cl-ev:last-child{ border-bottom:0; }
.cl-ev-money{ display:flex; justify-content:space-between; align-items:baseline; gap:10px; margin-top:8px; font-size:var(--t-texto); }
.cl-entregables{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:10px; }
.cl-addpay{ display:flex; flex-wrap:wrap; gap:8px; align-items:center; margin-top:14px; padding-top:14px; border-top:1px solid var(--hair); }
.cl-addpay[hidden]{ display:none; }
.cl-addpay .inp{ width:110px; } .cl-addpay .sel{ width:auto; flex:1; min-width:120px; }
.cl-addtask{ display:flex; gap:8px; align-items:center; margin-top:12px; padding-top:12px; border-top:1px solid var(--hair); }

/* Checklist de servicios del contrato (Fase 2): activable/editable/reordenable. */
.cd-serv-row{ display:flex; align-items:center; gap:8px; padding:5px 0; }
.cd-serv-row.dragging{ opacity:.4; }
.cd-serv-drag{ cursor:grab; color:var(--muted); font-size:var(--t-texto); line-height:1; flex:0 0 auto; user-select:none; }
.cd-serv-row .cd-serv-activo{ flex:0 0 auto; width:16px; height:16px; }
.cd-serv-row .cd-serv-texto{ flex:1; min-width:0; }
.cd-serv-rm{ flex:0 0 auto; width:26px; height:26px; border:1px solid var(--line2); background:transparent; border-radius:var(--r); color:var(--muted); cursor:pointer; font-size:var(--t-meta); }
@media (hover:hover){ .cd-serv-rm:hover{ border-color:var(--red); color:var(--red); } }
.cl-addtask .inp{ flex:1; }

/* ================= Widget "Habitos diarios" (checklist + racha) ================= */
.hab-rachas{ display:flex; gap:18px; margin-bottom:12px; }
.hab-r{ display:flex; flex-direction:column; }
.hab-r b{ font-family:var(--serif); font-size:var(--t-sub); font-weight:400; line-height:1.1; letter-spacing:-.01em }
.hab-r span{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
.hab-strip{ display:flex; gap:4px; margin-bottom:14px; }
.hab-dot{ width:100%; height:9px; border-radius:3px; background:var(--hair); }
.hab-dot-ok{ background:var(--accent); }
.hab-dot-no{ background:var(--red); opacity:.55; }
.hab-dot-finde{ background:transparent; border:1px dashed var(--hair); }
.hab-dot-na{ background:var(--hair); opacity:.4; }
.hab-lista{ display:flex; flex-direction:column; gap:2px; }
.hab-item{ display:flex; align-items:center; gap:9px; padding:7px 0; cursor:pointer; }
.hab-item input[type="checkbox"]{ width:18px; height:18px; flex:0 0 auto; accent-color:var(--accent); cursor:pointer; }
.hab-t{ flex:1; font-size:var(--t-texto); }
.hab-item:has(input:checked) .hab-t{ color:var(--muted); text-decoration:line-through; }
.hab-badge{ flex:0 0 auto; }
.hab-x{ opacity:0; flex:0 0 auto; width:26px; height:26px; padding:0; }
@media (hover:hover){ .hab-item:hover .hab-x{ opacity:1; } }

/* ================= Menu de usuario (sidebar) ================= */
.cp-brand{ position:relative; }
.cp-menu{ margin-left:auto; background:transparent; border:1px solid var(--line2); border-radius:var(--r); width:30px; height:30px; cursor:pointer; color:var(--muted); font-size:var(--t-texto); line-height:1; }
@media (hover:hover){ .cp-menu:hover{ background:#E4DFD2; color:var(--ink); } }
/* El tope de alto y el scroll propio NO son cosmetica: sin ellos, un menu mas alto que la
   ventana se corta por abajo y sus ultimos botones quedan inalcanzables -- sin barra, sin
   pista y sin manera de llegar a ellos. Daniel reporto el sintoma el 2026-08-18 ("ya no
   esta el panel de acceso"): ahi la causa resulto ser otra, pero al medirlo salio que el
   menu del engrane mide 412px sin tope, y que el atajo al panel es el PENULTIMO de la
   lista -- o sea que en una ventana baja se pierde el mismo boton, ahora por recorte.
   16px = los 8px de arriba y de abajo que respeta el clamp de abrirMenuCfg().
   100dvh y no 100vh: en iOS la barra del navegador hace que 100vh mida de mas (mismo
   motivo ya documentado en .pendw-pop y en el visor de la galeria).
   overflow-x en hidden a proposito: al poner overflow-y en auto el navegador calcula el
   eje X tambien como auto, y aparece una barra horizontal fantasma. Los .um-item son de
   ancho completo, asi que aqui no hay nada que recortar de lado. */
.usermenu{ position:absolute; top:44px; right:0; z-index:75; width:230px; background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); box-shadow:0 18px 44px -20px rgba(43,40,36,.5); padding:6px; animation:pop .16s ease both;
  max-height:calc(100dvh - 16px); overflow-y:auto; overflow-x:hidden; overscroll-behavior:contain; }
.usermenu[hidden]{ display:none; }
.um-head{ padding:10px 12px 12px; border-bottom:1px solid var(--hair); margin-bottom:6px; }
.um-name{ font-weight:600; font-size:var(--t-texto); }
.um-role{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); margin-top:4px; }
.um-item{ display:block; width:100%; text-align:left; background:transparent; border:0; border-radius:var(--r); padding:10px 12px; font-size:var(--t-texto); color:var(--ink); cursor:pointer; }
@media (hover:hover){ .um-item:hover{ background:#ECE7DB; } }
/* Una regla de autor SIEMPRE le gana a la hoja de estilos del navegador, sin importar
   especificidad -- por eso display:block de arriba gana sobre el [hidden] nativo del
   navegador, y un <button class="um-item" hidden> se sigue viendo. Confirmado en vivo
   con el boton "Otra opcion" (compartir nativo) del panel de galeria: aunque el JS ya
   ponia hidden=true quedaba visible. Sin esta regla, CUALQUIER hidden futuro sobre un
   .um-item tiene el mismo bug. */
.um-item[hidden]{ display:none; }
.um-danger{ color:#B0533A; }
@media (hover:hover){ .um-danger:hover{ background:#F1DBD0; } }
.um-sep{ height:1px; background:var(--hair); margin:6px 4px; }

/* Control segmentado (tema en Preferencias) */
.seg{ display:flex; gap:6px; background:var(--bone); border:1px solid var(--line2); border-radius:var(--r); padding:4px; }
.seg-btn{ flex:1; text-align:center; background:transparent; border:0; border-radius:var(--r); padding:9px 8px; font-size:var(--t-texto); color:var(--muted); cursor:pointer; display:flex; align-items:center; justify-content:center; gap:7px; }
.seg-btn.on{ background:var(--paper); color:var(--ink); font-weight:600; box-shadow:0 1px 3px rgba(41,40,36,.12); }
.seg-ico{ width:15px; height:15px; }

/* ================= Tema oscuro (gris neutro, estilo Claude) ================= */
:root{ color-scheme:light; }
/* Gris oscuro casi neutro (apenas tibio), no marron: como el dark de Claude.
   Bloque UNICO del tema oscuro. Antes habia dos (este y otro ~700 lineas abajo) y el
   segundo pisaba ink/muted/blue/yellow: leer este no te decia de que color era la app.
   Los valores de abajo son los que YA se veian (los del bloque que ganaba), fusionados
   aqui sin cambiar un solo pixel. */
/* Rediseno minimalista (2026-09-09, disenado y aprobado en lienzo con Daniel). El acento
   naranja deja de ser el color de la marca y pasa a ser SOLO senal: --red, --ok, --blue y
   --yellow no se tocan, porque ahi el color significa algo (vencido, confirmado, alerta).
   --accent, que era el mismo naranja pero decorativo, se vuelve gris.
   Tres grises y tres superficies, los mismos del lienzo:
     #0F0F0E pagina · #171716 elevada ("maquina") · #2A2A28 accion solida
     #C9C6BF principal · #A6A39C medio · #85827B apagado (5:1 sobre la pagina, el piso
     que este proyecto ya se puso para texto chico al sol). */
:root[data-theme="dark"]{
  color-scheme:dark;
  --bone:#0F0F0E; --paper:#171716; --deep:#141413;
  /* --muted es #A6A39C y no el #85827B del lienzo: ahi lo calcule contra el fondo PLANO
     (#0F0F0E, 5:1), pero la app pinta texturas detras (fondos.css) que son mas claras, y
     paridad-fondos.mjs lo midio en 3.30 sobre "cosecha" y "gota-de-tinta". #A6A39C
     aguanta 4.5 sobre la textura mas clara. El gris de 85827B sigue existiendo donde YO
     controlo el fondo (etiquetas sobre superficie plana), no en el token compartido. */
  --ink:#C9C6BF; --muted:#A6A39C;
  --hair:#1E1E1C; --line2:#2A2A28;
  --red:#D97757;
  /* --accent como TEXTO/BORDE (215 usos): gris claro. Como RELLENO detras de texto blanco
     (24 usos) no funciona ningun gris unico -- claro no aguanta texto blanco encima, y
     oscuro no se lee como texto. Por eso los rellenos van a --accent-solido, que es una
     superficie oscura con tinta clara, igual que el boton de enviar del lienzo. */
  --accent:#C9C6BF;
  --accent-solido:#2A2A28; --accent-tinta:#C9C6BF;
  --tint-xarpie:rgba(201,198,191,.07);
  --tint:rgba(201,198,191,.06);
  --ok:#93a986; --blue:#8fb0d4; --yellow:#cfa15e; --gold:#cfa15e;
}
/* superficies con color fijo (inputs, hovers) que no salen de una variable */
:root[data-theme="dark"] .inp,
:root[data-theme="dark"] .sel,
:root[data-theme="dark"] .ta{ background:#262624; border-color:var(--line2); color:var(--ink); }
:root[data-theme="dark"] .inp:focus,
:root[data-theme="dark"] .sel:focus,
:root[data-theme="dark"] .ta:focus{ background:#2C2C2A; }
:root[data-theme="dark"] .login-card input{ background:#262624; border-color:var(--line2); color:var(--ink); }
:root[data-theme="dark"] .login-card input:focus{ background:#2C2C2A; }
@media (hover:hover){ :root[data-theme="dark"] .btn:hover{ background:#3A3A37; color:var(--ink); } }
@media (hover:hover){ :root[data-theme="dark"] .x:hover, :root[data-theme="dark"] .cp-menu:hover, :root[data-theme="dark"] .um-item:hover{ background:#3A3A37; } }
@media (hover:hover){ :root[data-theme="dark"] .um-danger:hover{ background:#3E2E2A; } }
@media (hover:hover){ :root[data-theme="dark"] .trow:hover{ background:#2C2C2A; } }
:root[data-theme="dark"] .paybox{ background:#2A2A28; }
:root[data-theme="dark"] .search .navdot{ border-color:#5E5E57; }
:root[data-theme="dark"] ::-webkit-scrollbar-thumb{ background:#41413C; border-color:var(--bone); }
/* editor de la landing (usa fondos claros fijos) */
:root[data-theme="dark"] .lp-tpl,
:root[data-theme="dark"] .lp-color,
:root[data-theme="dark"] .lp-mini,
:root[data-theme="dark"] .lp-add-img{ background:#262624; }
:root[data-theme="dark"] .lp-blk,
:root[data-theme="dark"] .lp-previewwrap,
:root[data-theme="dark"] .lp-preview{ background:var(--paper); }
/* pills: fondo tenue del mismo tinte y texto claro */
:root[data-theme="dark"] .pill-red{ background:#3A2A25; color:#E9A385; }
:root[data-theme="dark"] .pill-blue{ background:#29332C; color:#A7C199; }
:root[data-theme="dark"] .pill-yellow{ background:#33311F; color:#E0C589; }
:root[data-theme="dark"] .pill-ink{ background:#34342F; color:#B8B7AF; }
/* superficies claras que faltaban en oscuro (.subbar: ver proyectos.js, no la nav) */
:root[data-theme="dark"] .subbar{ background:rgba(24,23,22,.9); }
@media (hover:hover){ :root[data-theme="dark"] .subtab:hover{ background:#302E2A; } }
:root[data-theme="dark"] .bub-me{ background:#3A3A37; border-color:var(--line2); color:var(--ink); }
@media (hover:hover){ :root[data-theme="dark"] .chip:hover{ background:#3A3A37; border-color:#5A5A52; } }
@media (hover:hover){ :root[data-theme="dark"] .tab:hover{ background:#3A3A37; } }
@media (hover:hover){ :root[data-theme="dark"] .cp-logout:hover{ background:#3A3A37; } }
/* tarjetas KPI enriquecidas del Panel */
.statsub{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.04em; color:var(--muted); margin-top:7px; }
.statsub-alert{ color:var(--red); }
.kpigrid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:12px; }
.nextwed{ display:flex; align-items:center; gap:16px; background:var(--paper); border:1px solid var(--hair); border-left:3px solid var(--accent); border-radius:var(--r); padding:14px 18px; margin-bottom:16px; box-shadow:0 1px 3px rgba(41,40,36,.04); }
.nw-badge{ font-family:var(--serif); font-weight:400; font-size:var(--t-sub); line-height:1; color:var(--accent); min-width:56px; text-align:center; font-variant-numeric:tabular-nums; letter-spacing:-.01em }
.nw-t{ font-family:var(--serif); font-weight:400; font-size:var(--t-campo); letter-spacing:-.01em; }
.nw-m{ font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.03em; color:var(--muted); margin-top:4px; }

/* ================= Onboarding del estudio nuevo ================= */
.onb-grid{ display:grid; grid-template-columns:repeat(auto-fit,minmax(240px,1fr)); gap:12px; }
.onb-step{ display:flex; align-items:center; gap:14px; text-align:left; width:100%; padding:14px 16px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); cursor:pointer; transition:.13s; }
@media (hover:hover){ .onb-step:hover{ border-color:var(--accent); background:#ECE7DB; } }
.onb-ico{ width:38px; height:38px; flex:0 0 38px; display:grid; place-items:center; border-radius:var(--r); background:var(--bone); color:var(--accent); font-size:var(--t-sub); }
.onb-t{ display:block; font-weight:600; font-size:var(--t-texto); }
.onb-d{ display:block; font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
@media (hover:hover){ :root[data-theme="dark"] .onb-step:hover{ background:#3A3A37; } }

/* ================= Panel configurable por widgets ================= */
/* 4 columnas con spans: chico=1 (cuarto), mediano=2 (mitad, el ancho historico de
   w-med), grande=4 (completo, el historico w-full). Cero regresion en los no migrados. */
.wgrid{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px; align-items:start; }
.widget{ background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); box-shadow:0 1px 3px rgba(41,40,36,.04); overflow:hidden; min-width:0; }
.w-ch{ grid-column:span 1; }
.w-med{ grid-column:span 2; }
.w-full{ grid-column:span 4; }
.w-head{ display:flex; align-items:center; gap:8px; padding:12px 15px; border-bottom:1px solid var(--hair); }
.w-title{ font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.1em; text-transform:uppercase; font-weight:600; }
.w-count{ font-family:var(--mono); font-size:var(--t-meta); font-weight:600; color:var(--muted); background:var(--bone); border-radius:var(--r); padding:1px 8px; min-width:20px; text-align:center; }
.w-count:empty{ display:none; }
.w-count.wc-red{ color:#A2492B; background:#F1DBD0; }
.w-body{ padding:6px 15px 14px; }
.w-body .kpigrid{ padding-top:8px; }
/* Controles SIEMPRE visibles pero discretos: tenues en reposo, se acentuan al pasar
   el mouse por la tarjeta o al enfocarlos con teclado. Sin modo edicion. */
.w-drag{ cursor:grab; color:var(--muted); font-size:var(--t-texto); line-height:1; display:inline-block; user-select:none; opacity:.22; transition:opacity .13s; touch-action:none; }
.w-drag:focus-visible{ opacity:.75; }
@media (hover:hover){ .widget:hover .w-drag{ opacity:.75; } }
.w-menu{ width:24px; height:24px; flex:0 0 24px; border:1px solid transparent; background:transparent; border-radius:var(--r); color:var(--muted); cursor:pointer; font-size:var(--t-texto); line-height:1; opacity:.35; transition:.13s; }
.w-quick ~ .w-menu{ margin-left:2px; }
.w-head > .w-menu:first-of-type, .w-count ~ .w-menu{ margin-left:auto; }
.w-menu:focus-visible{ opacity:1; border-color:var(--line2); }
@media (hover:hover){ .widget:hover .w-menu{ opacity:1; border-color:var(--line2); } }
@media (hover:hover){ .w-menu:hover{ color:var(--ink); } }
.widget.dragging{ opacity:.45; }

/* Popover del menu de tarjeta (tamano / configurar / subir-bajar / quitar) */
.w-pop{ position:fixed; z-index:220; min-width:210px; background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); box-shadow:0 10px 30px rgba(20,20,18,.18); padding:8px; }
.w-pop-tams{ display:flex; gap:4px; margin-bottom:6px; }
.w-pop-tam{ flex:1; font-size:var(--t-meta); font-weight:600; padding:7px 6px; border:1px solid var(--line2); background:transparent; color:var(--muted); border-radius:var(--r); cursor:pointer; transition:.13s; }
.w-pop-tam.on{ color:var(--accent); border-color:var(--accent); }
.w-pop-item{ display:block; width:100%; text-align:left; font-size:var(--t-texto); padding:8px 10px; border:0; background:transparent; border-radius:var(--r); color:var(--ink); cursor:pointer; }
@media (hover:hover){ .w-pop-item:hover{ background:var(--bone); } }
@media (hover:hover){ .w-pop-rm:hover{ color:var(--red); } }

/* Tarjeta fantasma "+ Agregar widget" al final de la rejilla */
.w-add-card{ grid-column:span 1; min-height:64px; display:flex; align-items:center; justify-content:center; gap:8px;
  border:1.5px dashed var(--line2); border-radius:var(--r); background:transparent; color:var(--muted);
  font-size:var(--t-texto); cursor:pointer; opacity:.6; transition:.15s; }
@media (hover:hover){ .w-add-card:hover{ opacity:1; border-color:var(--accent); color:var(--accent); } }
.w-add-plus{ font-size:var(--t-sub); line-height:1; }

/* Boton(es) de accion rapida en el encabezado del widget (crear tarea, cita, cotizacion...).
   margin-left:auto en el PRIMERO empuja al grupo entero a la derecha, igual que w-rm; se
   ocultan en modo edicion (mismo espacio que ocupa w-rm ahi) para no duplicar controles. */
.w-quick{ width:24px; height:24px; flex:0 0 24px; display:inline-flex; align-items:center; justify-content:center; border:1px solid var(--line2); background:transparent; border-radius:var(--r); color:var(--muted); cursor:pointer; font-size:var(--t-texto); line-height:1; }
.w-quick:first-of-type{ margin-left:auto; }
.w-quick + .w-quick{ margin-left:2px; }
@media (hover:hover){ .w-quick:hover{ border-color:var(--accent); color:var(--accent); background:color-mix(in srgb, var(--accent) 8%, transparent); } }

/* Clase generica para cualquier fila/tarjeta/barra de widget que navega a su origen al
   hacer clic (ficha de cliente, evento, vista filtrada...). Mismo tratamiento visual que
   ya usaban wed-row/ses-row: se generaliza para todos los widgets nuevos. */
.wed-row, .ses-row, .w-click{ cursor:pointer; border-radius:var(--r); margin:0 -8px; padding-left:8px; padding-right:8px; }
@media (hover:hover){ .wed-row:hover, .ses-row:hover, .w-click:hover{ background:#F1EEE5; } }
@media (hover:hover){ :root[data-theme="dark"] .w-click:hover{ background:#2C2C2A; } }
/* KPI y barras de progreso clicables: mismo hover, pero sin el margen negativo (ya
   tienen su propio padding de tarjeta/fila). */
.stat.w-click{ cursor:pointer; margin:0; transition:.13s; }
@media (hover:hover){ .stat.w-click:hover{ background:#F1EEE5; box-shadow:0 1px 3px rgba(41,40,36,.08); } }
@media (hover:hover){ :root[data-theme="dark"] .stat.w-click:hover{ background:#2C2C2A; } }
.barrow.w-click{ cursor:pointer; margin:0 -8px; padding-left:8px; padding-right:8px; }
@media (hover:hover){ .barrow.w-click:hover{ background:#F1EEE5; } }
@media (hover:hover){ :root[data-theme="dark"] .barrow.w-click:hover{ background:#2C2C2A; } }
.pill.w-click{ cursor:pointer; border:1px solid transparent; }
@media (hover:hover){ .pill.w-click:hover{ filter:brightness(.95); text-decoration:underline; } }

/* selector "agregar widget" */
.wadd-grid{ display:grid; grid-template-columns:1fr; gap:10px; }
.man-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(200px,1fr)); gap:10px; }
a.wadd-item{ color:inherit; text-decoration:none; }
@media (hover:hover){ a.wadd-item:hover{ color:inherit; text-decoration:none; } }
a.wadd-item .wadd-d{ line-height:1.45; }
.wadd-item{ display:flex; align-items:center; gap:14px; text-align:left; width:100%; padding:14px 16px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); cursor:pointer; transition:.13s; }
@media (hover:hover){ .wadd-item:hover{ border-color:var(--accent); background:#ECE7DB; } }
.wadd-ico{ width:38px; height:38px; flex:0 0 38px; display:grid; place-items:center; border-radius:var(--r); background:var(--bone); color:var(--accent); font-size:var(--t-sub); }
.wadd-t{ font-weight:600; font-size:var(--t-texto); }
.wadd-d{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }

/* widget: proximas bodas + sesiones (clickeables) */
.wed-row,.ses-row{ cursor:pointer; border-radius:var(--r); margin:0 -8px; padding-left:8px; padding-right:8px; }
@media (hover:hover){ .wed-row:hover, .ses-row:hover{ background:#F1EEE5; } }
.wed-badge{ font-family:var(--mono); font-size:var(--t-meta); font-weight:700; color:var(--accent); min-width:44px; flex:0 0 44px; text-align:center; }

/* widget: ingresos (grafica estilo bolsa) */
.ing-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; padding:8px 2px 12px; }
.ing-total{ font-family:var(--serif); font-weight:400; font-size:var(--t-titulo); line-height:1; font-variant-numeric:tabular-nums; letter-spacing:-.01em }
.ing-sub{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); margin-top:6px; }
.ing-chg{ font-family:var(--mono); font-size:var(--t-texto); font-weight:700; text-align:right; display:flex; flex-direction:column; align-items:flex-end; }
.ing-chg.up{ color:var(--blue); }
.ing-chg.down{ color:var(--red); }
.ing-chg-sub{ font-weight:400; font-size:var(--t-eti); letter-spacing:.04em; text-transform:uppercase; color:var(--muted); margin-top:3px; }
.ing-chart{ width:100%; }
.ing-svg{ width:100%; height:170px; display:block; }
.ing-base{ stroke:var(--hair); stroke-width:1; stroke-dasharray:2 4; }
.ing-x{ fill:var(--muted); font-family:var(--mono); font-size:var(--t-eti); text-anchor:middle; }
.ing-segs{ display:flex; gap:6px; margin-top:10px; }
.ing-seg{ flex:1; font-size:var(--t-meta); font-weight:600; padding:7px 10px; border:1px solid var(--line2); background:transparent; color:var(--muted); border-radius:var(--r); cursor:pointer; transition:.13s; }
@media (hover:hover){ .ing-seg:hover{ color:var(--ink); } }
.ing-seg.on{ background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); }

/* ---------- widget: Pendientes (unificado, design handoff) ----------
   .pendw vive DENTRO de .w-body (que ya trae padding:6px 15px 14px y .widget ya trae
   fondo/borde/radio/overflow:hidden) -- por eso NO repite card ni titulo (el de .w-head
   ya dice "Pendientes"), y se expande con margen negativo para que sus filas y divisores
   lleguen borde a borde como en el handoff. Los popovers (.pendw-pop) son position:fixed
   posicionados desde JS (igual que wlAbrirMenu en widgets.js): .widget tiene
   overflow:hidden, asi que un popover position:absolute normal se recortaria.
   Tokens propios (--card/--ink2/--line/--acc/--tint/--hov/--sunk/--ok/--warn) resueltos
   desde las variables globales del tema -- sin redeclarar --ink (se hereda tal cual de
   :root, ya coincide pixel a pixel con el handoff en los dos temas). */
.pendw{
  --card:var(--paper); --ink2:var(--muted); --line:var(--hair); --acc:var(--accent); --warn:var(--yellow);
  --tint:rgba(201,100,66,.1); --hov:rgba(0,0,0,.035); --sunk:rgba(0,0,0,.035);
  margin:-6px -15px -14px; display:flex; flex-direction:column; color:var(--ink); position:relative;
  font-family:var(--sans);
}
/* --acc/--warn/--ok crudos no dan 4.5:1 como TEXTO sobre --tint/--sunk (medido: 3.3-3.4:1
   en los dos temas) -- son tonos pensados para fondos solidos grandes (botones), no texto
   chico sobre un tinte. --acctxt/--warntxt/--oktxt son los mismos tonos ajustados que ya
   usa el resto de la app para esto (.pill-red/.pill-yellow/.pill-blue, lineas ~325-328 y
   844-847): texto propio por tema, no el acento crudo. */
:root:not([data-theme="dark"]) .pendw{ --ok:#4E6350; --acctxt:#A2492B; --warntxt:#836327; --oktxt:#4E6350; }
:root[data-theme="dark"] .pendw{
  --ok:#93a986;
  --tint:rgba(217,119,87,.16); --hov:rgba(255,255,255,.05); --sunk:rgba(0,0,0,.22);
  --acctxt:#E9A385; --warntxt:#E0C589; --oktxt:#A7C199;
}
.pendw *{ box-sizing:border-box; }

.pendw-hd{ display:flex; align-items:center; gap:8px; padding:11px 15px 10px; flex-wrap:wrap; }
.widget[data-tam="mediano"] .pendw-hd, .widget[data-tam="grande"] .pendw-hd{ padding:13px 18px 11px; }
.pendw-tot{ font-size:var(--t-meta); font-weight:600; color:var(--ink2); white-space:nowrap; }
.pendw-sp{ flex:1; min-width:0; }
.pendw-ic{ width:28px; height:28px; border-radius:var(--r); display:flex; align-items:center; justify-content:center; color:var(--ink2); border:1px solid transparent; flex:none; transition:.12s; background:none; }
@media (hover:hover){ .pendw-ic:hover{ background:var(--hov); color:var(--ink); } }
.pendw-ic.on{ border-color:var(--line); color:var(--acc); }
.pendw-vs{ display:flex; gap:2px; padding:3px; border-radius:var(--r); background:var(--sunk); flex:none; }
.pendw-vs button{ height:24px; padding:0 8px; border-radius:var(--r); font-size:var(--t-meta); font-weight:600; color:var(--ink2); display:flex; align-items:center; gap:5px; transition:.12s; background:none; border:none; cursor:pointer; }
@media (hover:hover){ .pendw-vs button:hover{ color:var(--ink); } }
.pendw-vs button.on{ background:var(--acc); color:#fff; }
.pendw-src{ display:flex; align-items:center; gap:8px; height:30px; padding:0 11px; border-radius:var(--r); border:1px solid var(--line); background:var(--sunk); color:var(--ink2); flex:1; min-width:0; max-width:210px; }
.pendw-src input{ flex:1; min-width:0; background:none; border:none; outline:none; color:var(--ink); font-size:var(--t-meta); }
.pendw-src input::placeholder{ color:var(--ink2); }
.pendw-pill{ display:inline-flex; align-items:center; gap:4px; height:19px; padding:0 7px; border-radius:var(--r); font-size:var(--t-eti); font-weight:600; background:var(--sunk); color:var(--ink2); flex:none; white-space:nowrap; }
.pendw-pill.red{ background:var(--tint); color:var(--acctxt); }
.pendw-pill.gold{ background:rgba(207,161,94,.16); color:var(--warntxt); }
.pendw-pill.ok{ background:rgba(147,169,134,.16); color:var(--oktxt); }

/* selector: riel (grande) / tabs con scroll (mediano) / desplegable (chico) */
.pendw-sel{ padding:0 15px 11px; }
.widget[data-tam="mediano"] .pendw-sel, .widget[data-tam="grande"] .pendw-sel{ padding:0 18px 12px; }
.pendw-tabs{ display:flex; gap:5px; overflow-x:auto; padding-bottom:2px; scrollbar-width:none; -webkit-mask-image:linear-gradient(to right,#000 90%,transparent); mask-image:linear-gradient(to right,#000 90%,transparent); }
.pendw-tabs::-webkit-scrollbar{ display:none; }
.pendw-tab{ flex:none; height:28px; padding:0 11px; border-radius:var(--r); font-size:var(--t-meta); color:var(--ink2); display:inline-flex; align-items:center; gap:6px; white-space:nowrap; transition:.12s; background:none; border:none; cursor:pointer; }
.pendw-tab .k{ font-size:var(--t-eti); opacity:.7; font-variant-numeric:tabular-nums; }
@media (hover:hover){ .pendw-tab:hover{ color:var(--ink); } }
.pendw-tab.on{ background:var(--tint); color:var(--acctxt); font-weight:600; }
.pendw-tab.on .k{ opacity:1; }
.pendw-nat{ width:100%; height:34px; border-radius:var(--r); border:1px solid var(--line); background:var(--sunk); color:var(--ink); font-size:var(--t-meta); font-weight:600; padding:0 11px; display:flex; align-items:center; gap:8px; cursor:pointer; }
.pendw-nat .cv{ color:var(--ink2); font-weight:400; font-size:var(--t-meta); }
.pendw-2p{ display:grid; grid-template-columns:180px 1fr; border-top:1px solid var(--line); flex:1; min-height:0; }
.pendw-rail{ border-right:1px solid var(--line); padding:8px 8px 12px; }
.pendw-ri{ display:flex; align-items:center; gap:9px; width:100%; padding:9px 10px; border-radius:var(--r); font-size:var(--t-meta); color:var(--ink2); margin-bottom:2px; transition:.12s; background:none; border:none; cursor:pointer; text-align:left; }
.pendw-ri .bar{ width:2px; height:14px; border-radius:2px; background:transparent; flex:none; }
.pendw-ri .n{ flex:1; }
.pendw-ri .k{ font-size:var(--t-meta); font-variant-numeric:tabular-nums; opacity:.8; }
@media (hover:hover){ .pendw-ri:hover{ background:var(--hov); color:var(--ink); } }
.pendw-ri.on{ background:var(--tint); color:var(--acctxt); font-weight:600; }
.pendw-ri.on .bar{ background:var(--acc); }
.pendw-mdiv{ height:1px; background:var(--line); margin:7px 3px; }
.pendw-load{ margin-top:10px; padding:10px; border-radius:var(--r); background:var(--sunk); }
.pendw-load .ll{ font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; font-weight:600; color:var(--ink2); margin-bottom:8px; }
.pendw-lr{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; font-size:var(--t-meta); color:var(--ink2); padding:3px 0; }
.pendw-lr b{ font-family:var(--serif); font-size:var(--t-texto); font-weight:400; color:var(--ink); letter-spacing:-.01em }
.pendw-lr b.hot{ color:var(--acctxt); }

/* filas */
.pendw-body{ flex:1; min-height:0; border-top:1px solid var(--line); }
.pendw-2p .pendw-body{ border-top:none; }
.pendw-gh{ display:flex; align-items:center; gap:9px; padding:9px 15px; background:var(--sunk); font-size:var(--t-eti); letter-spacing:.13em; text-transform:uppercase; font-weight:600; color:var(--ink2); border-bottom:1px solid var(--line); }
.widget[data-tam="mediano"] .pendw-gh, .widget[data-tam="grande"] .pendw-gh{ padding:9px 18px; }
.pendw-gh .gk{ margin-left:auto; letter-spacing:0; text-transform:none; font-size:var(--t-eti); opacity:.8; }
.pendw-r{ display:flex; align-items:center; gap:10px; padding:10px 15px; border-bottom:1px solid var(--line); position:relative; transition:.12s; }
.widget[data-tam="mediano"] .pendw-r, .widget[data-tam="grande"] .pendw-r{ padding:10px 18px; }
@media (hover:hover){ .pendw-r:hover{ background:var(--hov); } }
.pendw-r.pinned{ background:var(--tint); }
.pendw-r.gone{ opacity:.42; }
.pendw.dense .pendw-r{ padding-top:6px; padding-bottom:6px; }
.pendw-rm{ flex:1; min-width:0; }
.pendw-rt{ font-size:var(--t-meta); font-weight:600; line-height:1.3; display:flex; align-items:center; gap:6px; min-width:0; flex-wrap:wrap; row-gap:4px; }
.pendw-rt .tx{ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pendw-rt .pendw-pill{ flex:none; }
.pendw-r.gone .pendw-rt .tx{ text-decoration:line-through; color:var(--ink2); }
.pendw-rt .pin-ic{ color:var(--acc); flex:none; }
.pendw-rs{ font-size:var(--t-meta); color:var(--ink2); margin-top:3px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pendw-cat{ font-size:var(--t-eti); font-weight:600; letter-spacing:.12em; text-transform:uppercase; color:var(--ink2); opacity:.7; flex:none; width:56px; }
.pendw-st{ height:28px; border-radius:var(--r); border:1px solid var(--line); background:var(--sunk); color:var(--ink); font-size:var(--t-meta); padding:0 8px; flex:none; outline:none; }
.pendw-st:focus{ border-color:var(--acc); }
.pendw-go{ height:28px; padding:0 11px; border-radius:var(--r); background:var(--acc); color:#fff; font-size:var(--t-meta); font-weight:600; display:inline-flex; align-items:center; flex:none; transition:.12s; border:none; cursor:pointer; }
@media (hover:hover){ .pendw-go:hover{ filter:brightness(.92); } }
.pendw-go.ghost{ background:transparent; border:1px solid var(--line); color:var(--ink2); }
@media (hover:hover){ .pendw-go.ghost:hover{ border-color:var(--acc); color:var(--acc); } }
.pendw-sla{ width:3px; align-self:stretch; border-radius:2px; flex:none; min-height:24px; }
.pendw-note{ padding:0 15px 11px; display:flex; gap:8px; }
.widget[data-tam="mediano"] .pendw-note, .widget[data-tam="grande"] .pendw-note{ padding:0 18px 11px; }
.pendw-note input{ flex:1; min-width:0; height:30px; border-radius:var(--r); border:1px solid var(--line); background:var(--sunk); color:var(--ink); font-size:var(--t-meta); padding:0 11px; outline:none; }
.pendw-note input:focus{ border-color:var(--acc); }
.pendw-nt{ font-size:var(--t-meta); color:var(--ink2); margin-top:4px; display:flex; gap:6px; align-items:baseline; }
.pendw-nt .q{ color:var(--acc); font-weight:600; flex:none; }

/* popover generico: kebab por fila, filtros ⚙, desplegable de categoria en chico.
   position:fixed + top/left puestos por JS (pendwAbrirPop en app.js) -- .widget tiene
   overflow:hidden y un position:absolute normal se recortaria contra el borde de la
   tarjeta, asi que se monta en document.body: eso lo saca del subarbol de .pendw, y con
   el las variables --card/--line/etc que .pendw resuelve para si mismo. Se resuelven
   otra vez aqui, identicas, para que el popover sea autosuficiente sin importar donde
   cuelgue en el DOM. */
.pendw-pop{
  --card:var(--paper); --ink2:var(--muted); --line:var(--hair); --acc:var(--accent); --warn:var(--yellow);
  --tint:rgba(201,100,66,.1); --hov:rgba(0,0,0,.035); --sunk:rgba(0,0,0,.035);
  /* z-index 76 y no 60: se monta en <body>, asi que compite con los cajones fijos del
     telefono, no con la tarjeta de la que nacio. En 60 quedaba DEBAJO del panel derecho (66),
     del chat (70) y de la hoja del dia (73): el menu de una fila se abria y no se veia. 76 lo
     deja encima de los tres y debajo del modal (78), que es el unico que si debe taparlo. */
  position:fixed; z-index:76; width:206px; background:var(--card); border:1px solid var(--line); border-radius:var(--r); padding:5px; box-shadow:0 18px 44px -14px rgba(0,0,0,.5); color:var(--ink); font-family:var(--sans);
}
:root:not([data-theme="dark"]) .pendw-pop{ --ok:#4E6350; --acctxt:#A2492B; --warntxt:#836327; --oktxt:#4E6350; }
:root[data-theme="dark"] .pendw-pop{
  --ok:#93a986; --acctxt:#E9A385; --warntxt:#E0C589; --oktxt:#A7C199;
  --tint:rgba(217,119,87,.16); --hov:rgba(255,255,255,.05); --sunk:rgba(0,0,0,.22);
}
.pendw-pop-item{ display:flex; align-items:center; gap:9px; width:100%; padding:8px 9px; border-radius:var(--r); font-size:var(--t-meta); color:var(--ink); transition:.12s; background:none; border:none; cursor:pointer; text-align:left; }
@media (hover:hover){ .pendw-pop-item:hover{ background:var(--hov); } }
.pendw-pop-item .n{ flex:1; }
.pendw-pop-item .k{ font-size:var(--t-meta); color:var(--ink2); font-variant-numeric:tabular-nums; }
.pendw-pop-item.on{ background:var(--tint); color:var(--acctxt); }
.pendw-pop-item.on .k{ color:var(--acctxt); }
/* El panel del muelle (el grupo "Documento"): el MISMO popover de arriba, solo mas ancho y
   con la pista en una sola linea. Sin esto "Se manda a una boda" envuelve, esa fila crece a
   43px contra los 31px de sus vecinas y las tres se ven de distinta altura (medido en vivo).
   Con :has() y no con una clase en .pendw-pop porque pendwAbrirPop fija su className el
   mismo; y va sobre el POPOVER y no sobre el wrapper porque .pendw-pop trae width:206px
   fijo, que un min-width de un hijo no puede ensanchar. El ancho se aplica antes de que
   pendwAbrirPop lea offsetWidth (innerHTML y appendChild van primero), asi que el popover
   se sigue posicionando y clampeando bien. Los 206px del resto quedan intactos: ese ancho
   lo comparte el widget de pendientes, que no quiere este. */
.pendw-pop:has(.muelle-popwrap){ width:248px; }
.muelle-popwrap .pendw-pop-item .k{ white-space:nowrap; }
/* Mismos colores que .um-danger (menu de usuario): un solo tono de "esto borra algo" en toda la app. */
.pendw-pop-item.danger{ color:#B0533A; }
@media (hover:hover){ .pendw-pop-item.danger:hover{ background:#F1DBD0; } }

/* Kebab por-tarjeta de Albumes: .alb-card tiene overflow:hidden, asi que el boton vive
   ENCIMA de la portada (position:relative en la raiz de la tarjeta) en vez de ir en la
   franja inferior. Fondo oscuro translucido para leerse parejo sobre portadas claras u
   oscuras (el color de portada lo elige el fotografo, no se puede asumir contraste). */
.alb-kebab{ position:absolute; top:8px; right:8px; width:30px; height:30px; display:flex; align-items:center; justify-content:center; border:none; border-radius:var(--r); background:rgba(0,0,0,.35); color:#fff; cursor:pointer; }
@media (hover:hover){ .alb-kebab:hover{ background:rgba(0,0,0,.55); } }
.pendw-pop-date{ display:flex; gap:6px; padding:5px 4px 3px; }
.pendw-pop-date input{ flex:1; min-width:0; height:30px; border-radius:var(--r); border:1px solid var(--line); background:var(--sunk); color:var(--ink); font-size:var(--t-meta); padding:0 8px; outline:none; }
.pendw-pop-label{ font-size:var(--t-eti); font-weight:600; letter-spacing:.15em; text-transform:uppercase; color:var(--ink2); margin:6px 4px 7px; }
/* En telefono este popover deja de ser un menu de escritorio: lo abre un dedo desde la hoja
   del dia, y el de la lista del dia es el mas largo del repo (11 items + un campo de fecha).
   El max-height NO es cosmetico: pendwAbrirPop coloca con Math.min(innerHeight - offsetHeight
   - 8, ...), y con un menu mas alto que la pantalla eso da un top NEGATIVO que deja los
   primeros items fuera, inalcanzables. El CSS ya se aplico cuando el JS mide offsetHeight (el
   nodo esta en el DOM), asi que acotarlo aqui hace que el clamp vuelva a funcionar solo, sin
   tocar pendwAbrirPop. Los items suben a ~44px de alto, el minimo tactil. */
@media (max-width:860px){
  .pendw-pop{ width:min(264px, calc(100vw - 24px)); max-height:calc(100dvh - 24px); overflow-y:auto; overscroll-behavior:contain; }
  .pendw-pop-item{ padding:12px 11px; font-size:var(--t-texto); }
  .pendw-pop-date input{ height:44px; font-size:var(--t-texto); }
}
.pendw-pop-group{ padding-bottom:9px; margin-bottom:9px; border-bottom:1px solid var(--line); }
.pendw-pop-group:last-child{ border-bottom:none; margin-bottom:0; padding-bottom:0; }
.pendw-pop-step{ display:flex; align-items:center; gap:2px; background:var(--sunk); border-radius:var(--r); padding:3px; margin:0 4px; }
.pendw-pop-step button{ width:26px; height:24px; border-radius:var(--r); display:flex; align-items:center; justify-content:center; color:var(--ink2); font-size:var(--t-texto); font-weight:600; background:none; border:none; cursor:pointer; }
@media (hover:hover){ .pendw-pop-step button:hover{ background:var(--hov); color:var(--ink); } }
.pendw-pop-step .sv{ flex:1; text-align:center; font-size:var(--t-meta); font-weight:600; font-variant-numeric:tabular-nums; }
.pendw-tg{ width:34px; height:20px; border-radius:var(--r); background:var(--sunk); position:relative; flex:none; margin-left:auto; transition:.15s; border:none; cursor:pointer; padding:0; }
.pendw-tg.on{ background:var(--ok); }
.pendw-tg::after{ content:""; position:absolute; top:2px; left:2px; width:16px; height:16px; border-radius:50%; background:#fff; transition:.15s; }
.pendw-tg.on::after{ transform:translateX(14px); }

/* kanban (grande, vista "Tablero", entregas) */
.pendw-kb{ display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:1px; background:var(--line); border-top:1px solid var(--line); }
.pendw-kc{ background:var(--card); padding:11px 11px 14px; min-height:180px; }
.pendw-kh{ display:flex; align-items:center; gap:7px; font-size:var(--t-eti); letter-spacing:.13em; text-transform:uppercase; font-weight:600; color:var(--ink2); margin-bottom:10px; }
.pendw-kh .k{ margin-left:auto; letter-spacing:0; font-size:var(--t-eti); opacity:.8; }
.pendw-kt{ border:1px solid var(--line); border-radius:var(--r); padding:9px 10px; margin-bottom:7px; transition:.12s; width:100%; display:block; background:none; cursor:pointer; text-align:left; }
@media (hover:hover){ .pendw-kt:hover{ border-color:var(--acc); } }
.pendw-kt .t{ font-size:var(--t-meta); font-weight:600; line-height:1.3; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; color:var(--ink); }
.pendw-kt .m{ font-size:var(--t-eti); color:var(--ink2); margin-top:3px; display:flex; align-items:center; gap:6px; }
.pendw-kt .bt{ height:3px; border-radius:2px; background:var(--sunk); margin-top:7px; overflow:hidden; }
.pendw-ke{ font-size:var(--t-meta); color:var(--ink2); opacity:.6; padding:6px 2px; }

/* pie / vacio / deshacer */
.pendw-ft{ display:flex; align-items:center; gap:10px; padding:11px 15px; border-top:1px solid var(--line); }
.widget[data-tam="mediano"] .pendw-ft, .widget[data-tam="grande"] .pendw-ft{ padding:11px 18px; }
.pendw-ft span{ font-size:var(--t-meta); color:var(--ink2); }
.pendw-ft button{ background:none; border:none; cursor:pointer; }
.pendw-ft b{ font-size:var(--t-meta); font-weight:600; color:var(--acc); }
.pendw-empty{ padding:30px 20px; text-align:center; color:var(--ink2); display:flex; flex-direction:column; align-items:center; gap:11px; }
.pendw-empty .ec{ width:44px; height:44px; border-radius:50%; background:rgba(147,169,134,.16); color:var(--ok); display:flex; align-items:center; justify-content:center; }
.pendw-empty .et{ font-family:var(--serif); font-size:var(--t-sub); font-weight:400; color:var(--ink); letter-spacing:-.01em }
.pendw-empty p{ margin:0; font-size:var(--t-meta); line-height:1.55; max-width:260px; }
/* ---- vista Tiempo: linea de hoy (grid de horas en grande, lista+separador en mediano/chico) ---- */
.pendw-tl-stat{ padding:11px 15px; font-size:var(--t-meta); color:var(--ink2); border-bottom:1px solid var(--line); font-variant-numeric:tabular-nums; }
.pendw-tl-mas{ padding:7px 15px; font-size:var(--t-meta); color:var(--ink2); }
.pendw-tl-ahora{ display:flex; align-items:center; gap:8px; padding:4px 15px; }
.pendw-tl-ahora .ln{ flex:1; height:1px; background:var(--acc); opacity:.45; }
.pendw-tl-ahora .lbl{ font-size:var(--t-eti); font-weight:700; letter-spacing:.1em; color:var(--acc); white-space:nowrap; }
.pendw-tl-grid{ display:flex; padding:10px 15px 14px; }
.pendw-tl-times{ width:44px; flex:none; border-right:1px solid var(--line); }
.pendw-tl-hr{ position:relative; }
.pendw-tl-hr span{ position:absolute; top:-6px; right:8px; font-size:var(--t-eti); color:var(--ink2); font-variant-numeric:tabular-nums; }
.pendw-tl-hr:first-child span{ top:1px; }
.pendw-tl-col{ flex:1; min-width:0; position:relative; margin-left:10px; }
.pendw-tl-line{ position:absolute; left:0; right:0; height:1px; background:var(--line); }
.pendw-tl-now{ position:absolute; left:0; right:0; height:2px; background:var(--acc); z-index:3; pointer-events:none; }
.pendw-tl-now::before{ content:""; position:absolute; left:-4px; top:-3px; width:8px; height:8px; border-radius:100px; background:var(--acc); }
.pendw-tl-item{ position:absolute; left:0; right:6px; display:flex; align-items:baseline; gap:7px; padding:5px 9px; border-radius:var(--r); background:var(--tint); border-left:2.5px solid var(--acc); font-size:var(--t-meta); cursor:pointer; transition:.12s; z-index:2; min-height:20px; overflow:hidden; }
@media (hover:hover){ .pendw-tl-item:hover{ filter:brightness(1.06); z-index:4; } }
.pendw-tl-item .hh{ font-weight:700; color:var(--acctxt); flex:none; font-variant-numeric:tabular-nums; }
.pendw-tl-item .tt{ color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pendw-toast{ position:absolute; left:14px; right:14px; bottom:14px; z-index:30; display:flex; align-items:center; gap:10px; padding:10px 12px; border-radius:var(--r); background:var(--card); border:1px solid var(--line); box-shadow:0 16px 36px -12px rgba(0,0,0,.5); }
.pendw-toast .tt{ flex:1; min-width:0; font-size:var(--t-meta); color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pendw-toast button{ font-size:var(--t-meta); font-weight:600; color:var(--acc); flex:none; background:none; border:none; cursor:pointer; }

/* ---------- widget: Flujo de la boda (riel de etapas + linea de tiempo) ----------
   Dos piezas en una tarjeta: arriba por donde va la boda, abajo los pasos con fecha.
   La linea vertical se dibuja con un ::before sobre la LISTA (no un borde por fila):
   asi arranca y termina en el centro del primer y ultimo punto en vez de sobresalir.
   --tardetxt se redeclara aqui (no se hereda de .entw, que es otro subarbol) por la
   misma razon documentada abajo para .pendw-*. */
.evtl{ --tardetxt:#A2492B; }
:root[data-theme="dark"] .evtl{ --tardetxt:#E9A385; }

/* Riel de etapas: fila con scroll horizontal propio, nunca hace scrollear la pagina
   (regla de contenido ancho). flex-wrap:nowrap para que las 5 etapas no se apilen en
   una tarjeta angosta -- prefiero deslizarlas a romper la lectura de izquierda a
   derecha, que es lo que comunica "avance". */
.evtl-riel{ display:flex; gap:0; overflow-x:auto; padding:2px 0 14px; margin-bottom:2px; scrollbar-width:none; }
.evtl-riel::-webkit-scrollbar{ display:none; }
.evtl-etapa{ flex:1 1 0; min-width:72px; display:flex; flex-direction:column; align-items:center; gap:6px; position:relative; }
/* La barra de union va de punto a punto: se dibuja desde el centro de cada etapa hacia
   la izquierda, y la primera no la lleva. */
.evtl-etapa:not(:first-child):before{ content:''; position:absolute; top:5px; right:50%; left:-50%; height:2px; background:var(--hair); }
.evtl-etapa.ya:before, .evtl-etapa.hoy:before{ background:var(--accent); }
.evtl-punto{ width:12px; height:12px; border-radius:50%; background:var(--hair); position:relative; z-index:1; flex:none; }
.evtl-etapa.ya .evtl-punto{ background:var(--accent); }
/* La etapa ACTUAL es la unica con anillo: en escala de grises y en las tres dicromacias
   el halo sigue distinguiendola de las ya pasadas, que un color solo no garantiza. */
.evtl-etapa.hoy .evtl-punto{ background:var(--accent); box-shadow:0 0 0 4px color-mix(in srgb, var(--accent) 28%, transparent); }
.evtl-etiq{ font-size:var(--t-meta); line-height:1.25; text-align:center; color:var(--muted); }
.evtl-etapa.hoy .evtl-etiq{ color:var(--ink); font-weight:600; }

.evtl-lista{ position:relative; padding-left:2px; }
.evtl-fila{ display:flex; align-items:flex-start; gap:10px; padding:9px 0; position:relative; }
.evtl-fila.ya .evtl-t{ color:var(--muted); }
.evtl-t{ font-size:var(--t-texto); line-height:1.35; }
.evtl-t.done{ text-decoration:line-through; color:var(--muted); }
.evtl-cuando{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
.evtl-cuando.tarde{ color:var(--tardetxt); font-weight:600; }
/* El dia de la boda es el ancla de toda la linea: rombo en vez de casilla porque no es
   algo que se palomee -- pasa solo. */
.evtl-boda .evtl-t{ font-weight:600; letter-spacing:.02em; }
.evtl-diamante{ width:14px; height:14px; flex:0 0 14px; margin-top:3px; background:var(--accent); transform:rotate(45deg); border-radius:2px; }
.evtl-mas{ font-size:var(--t-meta); color:var(--muted); padding:8px 0 2px; }

/* Pestanas Pasos/Mapa. max-width y no ancho completo: dos opciones estiradas a 700px se
   leen como una barra de navegacion, no como un interruptor de vista. */
.evtl-tabs{ max-width:220px; margin:0 0 14px; }
.evtl-mapa-head{ display:flex; align-items:flex-start; gap:12px; margin-bottom:10px; }
.evtl-mapa-nom{ font-size:var(--t-texto); font-weight:600; }
.evtl-mapa-sub{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
.evtl-mapa-pie{ font-size:var(--t-meta); color:var(--muted); margin:8px 0 0; max-width:70ch; line-height:1.5; }
.evtl-lnk{ color:var(--accent); }

/* Estado de CADA paso sobre el mapa. Lo pinta el widget despues de armar el SVG, no
   flDiagrama: la receta que ese motor dibuja en Automatizaciones no tiene "hecho" ni
   "vencido" porque todavia no ha corrido. Relleno + tachado + opacidad a la vez, no solo
   color: en escala de grises y en las tres dicromacias tiene que seguir distinguiendose. */
.evtl .fl-nodo.evtl-n-hecho .fl-pt-tarea{ fill:var(--muted); stroke:var(--muted); }
.evtl .fl-nodo.evtl-n-hecho .fl-pt-msj{ fill:var(--muted); }
.evtl .fl-nodo.evtl-n-hecho .fl-pt-cobro{ fill:var(--muted); stroke:var(--muted); }
.evtl .fl-nodo.evtl-n-hecho .fl-lbl{ fill:var(--muted); text-decoration:line-through; }
.evtl .fl-nodo.evtl-n-tarde .fl-pt-tarea{ fill:var(--tardetxt); stroke:var(--tardetxt); }
.evtl .fl-nodo.evtl-n-tarde .fl-pt-cobro{ fill:var(--tardetxt); stroke:var(--tardetxt); }
.evtl .fl-nodo.evtl-n-tarde .fl-lbl{ fill:var(--tardetxt); font-weight:600; }
/* El diagrama trae su propio .fl-diag-scroll; esto solo evita que el SVG empuje la
   tarjeta cuando el flujo es mas ancho que ella. */
.evtl [data-evtl-mapa]{ max-width:100%; overflow:hidden; }
/* En el editor los nodos se arrastran (cursor:grab). Aqui el mapa es de solo lectura y
   todos llevan al editor: el cursor tiene que prometer eso y no un arrastre que no existe. */
.evtl .fl-nodo{ cursor:pointer; }

/* ---------- Barra del mapa: chips de capa (leyenda + interruptor a la vez) ---------- */
.evtl-capas{ display:flex; flex-wrap:wrap; gap:6px; margin:2px 0 10px; }
.evtl-chip{ display:inline-flex; align-items:center; gap:6px; padding:4px 10px 4px 8px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); font:inherit; font-size:var(--t-meta); color:var(--ink); cursor:pointer; }
.evtl-chip .n{ color:var(--muted); font-variant-numeric:tabular-nums; }
.evtl-chip.off{ opacity:.4; }
.evtl-chip .ico{ width:8px; height:8px; flex:none; border-radius:2px; background:var(--ink); }
.evtl-chip[data-capa="cobro"] .ico{ background:var(--accent); transform:rotate(45deg); border-radius:1px; }
.evtl-chip[data-capa="cita"] .ico{ width:0; height:0; background:none; border-radius:0; border-left:4px solid transparent; border-right:4px solid transparent; border-bottom:7px solid var(--ink); }
.evtl-chip[data-capa="entrega"] .ico{ background:var(--muted); }

/* ---------- Banda de hitos (pagos, citas, contrato, entregas) ---------- */
.evtl-hito{ cursor:pointer; }
.evtl-hito path{ fill:var(--paper); stroke:var(--ink); stroke-width:1.4; }
.evtl-hito:focus-visible path{ stroke:var(--accent); stroke-width:2.6; }
.evtl-h-cobro path{ stroke:var(--accent); }
.evtl-h-cobro.evtl-h-pagado path{ fill:var(--accent); }
.evtl-h-cobro.evtl-h-vencido path{ fill:var(--tardetxt); stroke:var(--tardetxt); }
.evtl-h-monto{ fill:var(--muted); font-size:8.5px; font-family:var(--sans); font-variant-numeric:tabular-nums; text-anchor:middle; }
.evtl-h-badge{ fill:var(--ink); }
.evtl-h-badge-n{ fill:var(--paper); font-size:8px; font-weight:700; text-anchor:middle; }

/* Popover de un hito: fixed y anexado a document.body -- .widget tiene overflow:hidden
   (ver mas abajo) y un popover absolute quedaria recortado por el borde de la tarjeta. */
.evtl-pop{ position:fixed; z-index:80; max-width:260px; background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); box-shadow:0 8px 28px rgba(0,0,0,.18); padding:10px 12px; font-size:var(--t-meta); }
.evtl-pop-row + .evtl-pop-row{ margin-top:8px; padding-top:8px; border-top:1px solid var(--hair); }
.evtl-pop-tit{ font-weight:600; }
.evtl-pop-meta{ color:var(--muted); margin-top:2px; }
.evtl-pop-ir{ margin-top:6px; }

/* ---------- widget: Entregas pendientes (fila compacta) ----------
   Geometria copiada a proposito de .pendw-r (~110 lineas mas arriba): los dos widgets
   pintan la MISMA entrega y verlas distintas en el mismo panel se lee como un bug.
   No se reusan las clases .pendw-*: esas resuelven --line/--hov/--sunk/--ink2/--tint
   contra el bloque de tokens que .pendw declara para su subarbol (linea 1248), y :root
   no tiene ninguna de las cinco. Una .pendw-r suelta en .w-body saldria con el borde
   invisible y el hover muerto. Mismo patron que .pendw-pop, que las redeclara para
   sobrevivir colgada de <body>. */
.entw{
  --hov:rgba(0,0,0,.035); --tardetxt:#A2492B;
  margin:-6px -15px -14px;      /* .w-body trae padding 6/15/14: full-bleed como .pendw */
  display:flex; flex-direction:column;
}
:root[data-theme="dark"] .entw{ --hov:rgba(255,255,255,.05); --tardetxt:#E9A385; }
.entw *{ box-sizing:border-box; }

.entw-r{
  display:flex; align-items:center; gap:9px;
  /* padding 5 y no 10: el boton de 44px ya es quien fija el alto de la fila (55px). Con
     10px la fila saltaria a 65px sin ganar ni un pixel de contenido. */
  padding:5px 15px; min-height:55px;
  border-bottom:1px solid var(--hair);
  cursor:pointer; transition:background .12s;
}
.widget[data-tam="grande"] .entw-r{ padding:5px 18px; }
.entw-r:last-of-type{ border-bottom:0; }
@media (hover:hover){ .entw-r:hover{ background:var(--hov); } }
.entw-r.entw-guardando{ opacity:.55; pointer-events:none; }

/* Riel de urgencia. Cambia HUE y LUMINANCIA a la vez: en escala de grises y en las tres
   dicromacias sigue distinguiendose, que es lo que un color solo no garantiza. */
.entw-sla{ width:3px; align-self:stretch; min-height:26px; border-radius:2px; flex:none; background:var(--accent); }
.entw-r.ok .entw-sla{ background:var(--muted); opacity:.28; }

.entw-ic{ flex:none; display:flex; color:var(--muted); }

/* nowrap = la maqueta de una sola linea. El wrap del modo angosto se enciende abajo. */
.entw-m{ flex:1; min-width:0; display:flex; align-items:center; flex-wrap:nowrap; gap:7px; row-gap:3px; }
.entw-t{ flex:1 1 auto; min-width:0; font-size:var(--t-texto); font-weight:600; line-height:1.3;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.entw-k{ flex:0 1 auto; min-width:0; font-size:var(--t-meta); color:var(--muted);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.entw-d{ flex:none; display:inline-flex; align-items:center; gap:3px;
  font-size:var(--t-meta); color:var(--muted); font-variant-numeric:tabular-nums; white-space:nowrap; }
.entw-r.tarde .entw-d{ color:var(--tardetxt); font-weight:600; }

/* Chip de estado: abre .pendw-pop via pendwAbrirPop. 22px de alto visible, 46px de area
   tactil por el ::after -- la fila no puede crecer y 22px seria la mitad del minimo de
   WCAG 2.5.5. El halo es asimetrico a proposito: hacia abajo hay padding vacio de la
   fila, hacia arriba esta el nombre y hay que robarle lo menos posible. */
.entw-est{
  position:relative; flex:none; display:inline-flex; align-items:center; gap:3px;
  height:22px; padding:0 7px; border-radius:var(--r);
  background:var(--deep); color:var(--ink); border:1px solid transparent;
  font-family:inherit; font-size:var(--t-eti); font-weight:600; line-height:1; white-space:nowrap;
  cursor:pointer; transition:.12s;
}
.entw-est::after{ content:""; position:absolute; left:-6px; right:-6px; top:-8px; bottom:-16px; }
@media (hover:hover){ .entw-est:hover{ border-color:var(--line2); } }
.entw-est svg{ opacity:.5; }

/* 44x44 reales de area, con el anillo pintado solo al hover: mismo criterio que el
   minimo tactil de agosto. */
.entw-go{
  flex:none; width:44px; height:44px; border-radius:var(--r);
  display:flex; align-items:center; justify-content:center;
  border:1px solid transparent; background:none; color:var(--muted);
  cursor:pointer; transition:.12s;
}
@media (hover:hover){ .entw-go:hover{ border-color:var(--line2); color:var(--accent); background:var(--hov); } }
.entw-go:disabled{ opacity:.45; cursor:default; }

.entw-ft{ display:flex; justify-content:center; padding:9px 15px; border-top:1px solid var(--hair); }

/* Modo angosto: MISMO DOM, el nombre se lleva su renglon y tipo/cifra/chip envuelven al
   siguiente. No cuesta altura (el boton de 44px ya la fijaba) y le devuelve ~86px al
   nombre, que es lo que hace que "Ivonne & Alexander" entre completo en un telefono.
   640px es el mismo breakpoint que .evrow (linea 411) ya usa. */
@media (max-width:640px){
  .entw-m{ flex-wrap:wrap; }
  .entw-t{ flex:1 0 100%; }
}
.widget[data-tam="chico"] .entw-m{ flex-wrap:wrap; }
.widget[data-tam="chico"] .entw-t{ flex:1 0 100%; }

/* widget: recomendaciones */
.reco{ padding:12px 0; border-bottom:1px solid var(--hair); }
.reco:last-of-type{ border-bottom:0; }
.reco-h{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.reco-t{ font-weight:600; font-size:var(--t-texto); }
.reco-cli{ font-family:var(--mono); font-size:var(--t-meta); color:var(--muted); margin-top:3px; }
.reco-why{ font-size:var(--t-meta); color:var(--ink); line-height:1.45; margin-top:6px; }
.reco-xarpie{ margin-top:8px; }

/* widget: tendencias / noticias */
.trend{ padding:12px 0; border-bottom:1px solid var(--hair); }
.trend-h{ margin-bottom:6px; }
.trend-t{ font-family:var(--serif); font-weight:400; font-size:var(--t-texto); line-height:1.2; letter-spacing:-.01em }
.trend-d{ font-size:var(--t-meta); color:var(--muted); line-height:1.5; margin-top:5px; }

/* widget: barras horizontales (conversion por canal, mix de paquetes) y barra de
   progreso (salud de correos) reusan el mismo componente chico. */
.barrow{ padding:8px 0; border-bottom:1px solid var(--hair); }
.barrow:last-child{ border-bottom:0; }
.barrow-top{ display:flex; justify-content:space-between; align-items:baseline; font-size:var(--t-texto); margin-bottom:5px; gap:10px; }
.barrow-lbl{ font-weight:500; text-transform:capitalize; }
.barrow-val{ color:var(--muted); font-variant-numeric:tabular-nums; white-space:nowrap; }
.barrow-track{ height:6px; border-radius:3px; background:var(--hair); overflow:hidden; }
.barrow-fill{ height:100%; border-radius:3px; background:var(--accent); }

@media (max-width:860px){
  /* Movil: 2 columnas; chico = media pantalla, mediano/grande = completa. */
  .wgrid{ grid-template-columns:repeat(2,minmax(0,1fr)); }
  .w-ch{ grid-column:span 1; }
  .w-med,.w-full{ grid-column:span 2; }
  .w-add-card{ grid-column:span 2; }
  /* Sin drag tactil en v1: el handle se atenua; reordenar = Subir/Bajar del menu ⋯. */
  .w-drag{ opacity:.15; }
}

@media (hover:hover){ :root[data-theme="dark"] .wed-row:hover, :root[data-theme="dark"] .ses-row:hover{ background:#2C2C2A; } }
:root[data-theme="dark"] .w-count{ background:var(--bone); }
:root[data-theme="dark"] .w-count.wc-red{ background:#3A2A25; color:#E9A385; }
@media (hover:hover){ :root[data-theme="dark"] .wadd-item:hover{ background:#3A3A37; } }

/* ---- Bandeja de Xarpie (acciones escenificadas) ---- */
.acc-card{ background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); padding:14px 16px; margin-bottom:12px; box-shadow:0 1px 3px rgba(41,40,36,.04); }
.acc-alto{ border-left:3px solid var(--red); }
.acc-h{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.acc-tipo{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.acc-cuando{ margin-left:auto; font-family:var(--mono); font-size:var(--t-eti); color:var(--muted); }
.acc-t{ font-weight:600; font-size:var(--t-texto); margin-top:9px; }
.acc-cli{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
.acc-brief{ margin-top:10px; padding:9px 12px; background:var(--deep); border-radius:var(--r); }
.acc-brief-t{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); margin-bottom:5px; }
.acc-hecho{ font-size:var(--t-texto); line-height:1.5; }
.acc-cuerpo{ width:100%; margin-top:10px; min-height:74px; font-size:var(--t-texto); line-height:1.5; }
.acc-cuerpo[readonly]{ background:var(--bone); color:var(--ink); border-color:var(--hair); }
.acc-botones{ display:flex; gap:8px; margin-top:10px; align-items:center; flex-wrap:wrap; }
.btn-wa{ background:#1FAF5E; border-color:#1FAF5E; color:#fff !important; text-decoration:none; display:inline-flex; align-items:center; }
@media (hover:hover){ .btn-wa:hover{ background:#188C4B; border-color:#188C4B; color:#fff; } }
:root[data-theme="dark"] .acc-cuerpo[readonly]{ background:#262624; }
:root[data-theme="dark"] .btn-wa{ background:#1FAF5E; border-color:#1FAF5E; }

/* ---- Modo aprendiz: tira "que hice / donde lo encuentras" (Preferencias > xarpie_transparencia) ---- */
/* La tira del modo aprendiz. Desde el inicio-chat vive FUERA del <details> colapsado (era
   ayuda encendida por default pero escondida tras un clic, o sea ayuda para nadie), asi que
   necesita su propio margen: antes lo heredaba del interior del desplegable. El margen
   izquierdo la alinea con el texto de la burbuja, no con el avatar. */
.xarpie-efectos{ display:flex; flex-direction:column; gap:7px; margin-top:9px; }
.brow > .xarpie-efectos{ flex:0 0 100%; min-width:0; margin:9px 0 2px 40px; }
@media (max-width:860px){ .brow > .xarpie-efectos{ margin-left:0; } }
/* align-items:flex-start y no center: con la segunda linea del camino, centrar dejaba la
   palomita flotando a media altura del bloque. */
.xarpie-efecto{ display:flex; align-items:flex-start; gap:8px; font-size:var(--t-meta); line-height:1.4; color:var(--muted); }
/* El camino manual: mono y mas apagado que la linea de arriba -- se lee como una nota al
   pie, no como una segunda instruccion que compita con lo que Xarpie acaba de decir. */
.xarpie-camino{ display:block; margin-top:2px; font-family:var(--mono); font-size:var(--t-meta); opacity:.72; }
.xarpie-efecto-ico{ flex:0 0 auto; color:var(--ok); font-weight:700; }
.xarpie-efecto-txt{ flex:1; min-width:0; }
.xarpie-efecto-txt b{ color:var(--ink); font-weight:600; }
.xarpie-efecto-link{ flex:0 0 auto; font-size:var(--t-meta); padding:5px 13px; border-radius:var(--r); border:1px solid var(--line2); background:var(--paper); color:var(--ink); cursor:pointer; transition:.14s; white-space:nowrap; }
@media (hover:hover){ .xarpie-efecto-link:hover{ border-color:var(--accent); background:var(--deep); } }

/* ---- Diseños: grid de piezas graficas con preview escalada en iframe ---- */
.dzgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(250px,1fr)); gap:18px; }
.dzcard{ border:1px solid var(--line2); border-radius:var(--r); overflow:hidden; background:var(--paper); }
/* El iframe se pinta a tamaño real y se encoge con transform: asi el diseño ve su ancho
   verdadero (1080px) y los px del HTML significan lo que deben. */
.dzcard-prev{ position:relative; overflow:hidden; background:#fff; margin:0 auto; }
.dzv-frame{ border:0; transform-origin:top left; position:absolute; top:0; left:0; pointer-events:none; }
.dzcard-pie{ padding:10px 12px 4px; display:flex; flex-direction:column; gap:2px; font-size:var(--t-texto); }
.dzcard-pie .muted{ font-size:var(--t-meta); }
.dzcard-btns{ display:flex; gap:6px; padding:8px 12px 12px; flex-wrap:wrap; }
.dzv-wrap{ position:relative; overflow:hidden; background:#fff; border-radius:var(--r); border:1px solid var(--line2); margin:0 auto; }

/* ---- Cambios propuestos (Bandeja): el diff antes -> despues de datos de un cliente ---- */
.cpx{ border:1px solid var(--line2); border-radius:var(--r); padding:12px 14px; margin-bottom:10px; background:var(--paper); }
.cpx-head{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; margin-bottom:8px; }
.cpx-motivo{ font-size:var(--t-meta); color:var(--muted); }
.cpx-body{ display:flex; flex-direction:column; gap:5px; }
.cpx-fila{ display:flex; align-items:baseline; gap:8px; font-size:var(--t-texto); flex-wrap:wrap; }
.cpx-campo{ flex:0 0 auto; min-width:104px; color:var(--muted); font-size:var(--t-meta); text-transform:uppercase; letter-spacing:.04em; }
.cpx-antes{ text-decoration:line-through; color:var(--muted); }
.cpx-flecha{ color:var(--muted); }
.cpx-desp{ color:var(--ink); font-weight:600; }
/* notas no reemplaza: se agrega. Se pinta distinto para que no se lea como sustitucion. */
.cpx-add{ color:var(--ink); white-space:pre-wrap; }
.cpx-conflicto{ margin-top:8px; font-size:var(--t-meta); color:var(--warn, #b8860b); line-height:1.45; }
.cpx-btns{ display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; }

/* Progreso en vivo dentro de la burbuja mientras Xarpie trabaja: que herramienta esta
   usando ahora. Desaparece al llegar el render definitivo de la respuesta. */
.xarpie-progreso{ font-size:var(--t-meta); color:var(--muted); margin-bottom:6px; display:flex; align-items:center; gap:6px; }
.xarpie-progreso::before{ content:""; width:6px; height:6px; border-radius:50%; background:var(--accent); flex:0 0 auto; animation:xarpiePulso 1s ease-in-out infinite; }
@keyframes xarpiePulso{ 0%,100%{ opacity:.25; } 50%{ opacity:1; } }

/* ---- Historial de Xarpie: chips de referencia, herramientas de burbuja, modal de historial ---- */
/* Traza/chips/Copiar/WhatsApp colapsados por default (ver burbuja() en app.js): el
   marker nativo de <details> se oculta a proposito porque la flecha de ico("flecha")
   ya cumple ese rol y gira al abrir, en vez de tener dos indicadores redundantes. */
/* El <details> "Opciones" murio (2026-08-28): salia en CADA respuesta, y lo unico util que
   guardaba adentro era a donde habia ido lo que Xarpie acababa de tocar. Eso ahora se ve
   solo (.xarpie-efectos / .bubrefs) y las acciones bajaron a iconos que aparecen al pasar
   el mouse. Sin nada que reportar, debajo del texto no queda nada. */
.bubrefs{ display:flex; flex-wrap:wrap; gap:6px; margin-top:9px; }
.bubrefs .pill{ cursor:pointer; border:1px solid var(--line2); background:var(--paper); transition:.14s; }
@media (hover:hover){ .bubrefs .pill:hover{ background:var(--deep); color:var(--ink); } }
/* Aparecen al pasar el mouse por el turno, o al llegar con el teclado (focus-within): sin
   eso los botones serian inalcanzables sin mouse. En tactil no hay hover, asi que ahi se
   quedan visibles (ver el @media de abajo) -- esconderlos seria quitarlos. */
.bubtools{ display:flex; align-items:center; gap:2px; margin-top:6px; opacity:0; transition:opacity .15s var(--ease-estado); }
.bubtools:focus-within{ opacity:1; }
@media (hover:hover){ .brow:hover .bubtools{ opacity:1; } }
.bubtool,.xarpie-senal-b{ display:grid; place-items:center; width:27px; height:27px; padding:0; border:0;
  border-radius:var(--r); background:transparent; color:var(--muted); cursor:pointer; transition:.14s var(--ease-estado); }
.bubtool:focus-visible, .xarpie-senal-b:focus-visible{
  background:color-mix(in srgb, var(--ink) 9%, transparent); color:var(--ink); outline:none; }
@media (hover:hover){ .bubtool:hover, .xarpie-senal-b:hover{
  background:color-mix(in srgb, var(--ink) 9%, transparent); color:var(--ink); outline:none; } }
/* En una pantalla tactil NO hay hover: sin esto los cuatro botones serian invisibles para
   siempre en el celular, que no es "discretos", es quitados. Ahi se quedan puestos. */
@media (hover: none){
  .bubtools{ opacity:1; }
}
.hist-msg{ padding:10px 0; border-bottom:1px solid var(--hair); }
.hist-msg:last-child{ border-bottom:0; }
.hist-meta{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.03em; color:var(--muted); margin-bottom:4px; }
.hist-user .hist-meta{ color:var(--accent); }
.hist-texto{ font-size:var(--t-texto); line-height:1.55; white-space:pre-wrap; }

/* ---- Calendario (Agenda): navegacion, vista mes, vista semana, drag-and-drop ---- */
.cal-nav{ display:flex; align-items:center; gap:8px; margin-bottom:14px; }
.cal-grid{ border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; background:var(--paper); }
.cal-head{ display:grid; grid-template-columns:repeat(7,1fr); border-bottom:1px solid var(--hair); }
.cal-head-d{ padding:8px 10px; font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); text-align:center; }
.cal-body{ display:grid; grid-template-columns:repeat(7,1fr); }
.cal-celda{ min-height:104px; padding:6px 6px 8px; border-right:1px solid var(--hair); border-bottom:1px solid var(--hair); cursor:pointer; transition:background .12s; }
@media (hover:hover){ .cal-celda:hover{ background:var(--deep); } }
.cal-body .cal-celda:nth-child(7n){ border-right:0; }
.cal-fuera{ opacity:.4; }
@media (hover:hover){ .cal-fuera:hover{ opacity:.7; } }
.cal-hoy{ background:color-mix(in srgb, var(--accent) 9%, var(--paper)); }
.cal-numero{ font-family:var(--mono); font-size:var(--t-meta); color:var(--muted); margin-bottom:5px; }
.cal-hoy .cal-numero{ color:var(--accent); font-weight:700; }
.cal-evs{ display:flex; flex-direction:column; gap:3px; }
.cal-chip{ font-size:var(--t-meta); padding:3px 7px; border-radius:var(--r); background:color-mix(in srgb, var(--cal-c) 16%, var(--paper)); color:var(--ink); border-left:3px solid var(--cal-c); cursor:grab; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cal-chip:active{ cursor:grabbing; }
.cal-chip-h{ font-family:var(--mono); font-size:var(--t-eti); color:var(--muted); }
/* Iconito para distinguir tareas (✓) y sesiones (◈) de los eventos de un vistazo. */
.cal-chip-ic{ font-size:var(--t-eti); margin-right:3px; color:var(--cal-c); }
.cal-chip-sesion{ border-left-style:dashed; }
.cal-chip-tarea{ cursor:grab; }
.cal-chip-sesion{ cursor:pointer; }
/* Punto de color para la leyenda de tipos y el modal de dia. */
.cal-legend-dot{ width:9px; height:9px; border-radius:50%; flex:0 0 9px; display:inline-block; margin-right:2px; }
.cal-legend{ display:flex; flex-wrap:wrap; gap:4px 14px; font-size:var(--t-meta); color:var(--muted); margin-top:8px; align-items:center; }
.cal-legend span.lg{ display:inline-flex; align-items:center; gap:5px; }
.cal-mas{ font-size:var(--t-eti); color:var(--muted); padding:2px 7px; cursor:pointer; }
@media (hover:hover){ .cal-mas:hover{ color:var(--ink); text-decoration:underline; } }
.cal-dragover{ background:color-mix(in srgb, var(--accent) 14%, var(--paper)) !important; }

.cal-sem{ border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; background:var(--paper); }
.cal-sem-head{ display:grid; grid-template-columns:56px repeat(7,1fr); border-bottom:1px solid var(--hair); }
.cal-sem-hcol{ }
.cal-sem-hd{ padding:8px 6px; text-align:center; font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.04em; text-transform:uppercase; color:var(--muted); border-left:1px solid var(--hair); }
.cal-sem-num{ display:block; font-family:var(--serif); font-size:var(--t-texto); color:var(--ink); margin-top:2px; letter-spacing:-.01em }
.cal-sem-hd.cal-hoy{ color:var(--accent); background:color-mix(in srgb, var(--accent) 9%, var(--paper)); }
.cal-sem-hd.cal-hoy .cal-sem-num{ color:var(--accent); }
.cal-sem-body{ display:grid; grid-template-columns:56px repeat(7,1fr); max-height:70vh; overflow-y:auto; }
.cal-sem-horas{ border-right:1px solid var(--hair); }
.cal-sem-hora{ font-family:var(--mono); font-size:var(--t-eti); color:var(--muted); padding:2px 6px; box-sizing:border-box; border-bottom:1px solid var(--hair); }
.cal-sem-col{ position:relative; border-left:1px solid var(--hair); }
.cal-sem-franja{ border-bottom:1px solid var(--hair); box-sizing:border-box; cursor:pointer; }
@media (hover:hover){ .cal-sem-franja:hover{ background:var(--deep); } }
.cal-sem-evs{ position:absolute; inset:0; pointer-events:none; }
.cal-sem-ev{ position:absolute; left:3px; right:3px; padding:3px 6px; border-radius:var(--r); background:color-mix(in srgb, var(--cal-c) 18%, var(--paper)); color:var(--ink); border-left:3px solid var(--cal-c); font-size:var(--t-meta); line-height:1.3; overflow:hidden; cursor:grab; pointer-events:auto; box-shadow:0 1px 3px rgba(41,40,36,.08); }
.cal-sem-ev:active{ cursor:grabbing; }
.cal-sem-ev-h{ font-family:var(--mono); font-size:var(--t-eti); color:var(--muted); display:block; }

@media (hover:hover){ :root[data-theme="dark"] .cal-celda:hover, :root[data-theme="dark"] .cal-sem-franja:hover{ background:#2C2C2A; } }
:root[data-theme="dark"] .cal-hoy,
:root[data-theme="dark"] .cal-sem-hd.cal-hoy{ background:#33291F; }
:root[data-theme="dark"] .cal-dragover{ background:#3A3020 !important; }

/* ---- Calendario: filtro, dias bloqueados, indicador de saldo, resize de duracion ---- */
.cal-saldo{ display:inline-block; width:7px; height:7px; border-radius:50%; background:var(--red); margin-right:5px; vertical-align:middle; flex:0 0 7px; }
.cal-bloq{ font-size:var(--t-eti); padding:2px 7px; border-radius:var(--r); background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--muted) 22%, var(--paper)), color-mix(in srgb, var(--muted) 22%, var(--paper)) 6px, transparent 6px, transparent 12px); color:var(--muted); border:1px solid var(--line2); cursor:pointer; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
@media (hover:hover){ .cal-bloq:hover{ color:var(--ink); } }
.cal-celda.cal-bloqueado{ background:color-mix(in srgb, var(--muted) 7%, var(--paper)); }
.cal-col-bloqueada{ background:repeating-linear-gradient(45deg, color-mix(in srgb, var(--muted) 8%, transparent), color-mix(in srgb, var(--muted) 8%, transparent) 8px, transparent 8px, transparent 16px); }
.cal-hd-bloq{ display:block; font-family:var(--sans); font-size:var(--t-eti); letter-spacing:0; text-transform:none; color:var(--muted); margin-top:2px; cursor:pointer; }
@media (hover:hover){ .cal-hd-bloq:hover{ color:var(--ink); text-decoration:underline; } }
.cal-sem-ev{ display:flex; align-items:baseline; flex-wrap:wrap; }
.cal-resize{ position:absolute; left:0; right:0; bottom:0; height:8px; cursor:ns-resize; touch-action:none; }
@media (hover:hover){ .cal-resize:hover{ background:color-mix(in srgb, var(--cal-c) 55%, transparent); border-radius:0 0 var(--r) var(--r); } }

/* ---- Calendario: carril "sin hora" (eventos sin hora o fuera del rango 6-23) ---- */
.cal-sem-allday{ display:grid; border-bottom:1px solid var(--hair); background:var(--deep); }
.cal-allday-lbl{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.03em; text-transform:uppercase; color:var(--muted); display:flex; align-items:center; justify-content:flex-end; padding:6px; }
.cal-allday-col{ border-left:1px solid var(--hair); padding:5px; display:flex; flex-direction:column; gap:3px; min-height:26px; }
.cal-allday-ev{ font-size:var(--t-meta); padding:3px 7px; border-radius:var(--r); background:color-mix(in srgb, var(--cal-c) 16%, var(--paper)); color:var(--ink); border-left:3px solid var(--cal-c); cursor:grab; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cal-allday-ev:active{ cursor:grabbing; }

/* iOS hace auto-zoom al enfocar un campo con font-size < 16px. En movil subimos los
   controles de formulario a 16px para evitar ese salto molesto (el desktop queda igual). */
@media (max-width:640px){
  .inp, .sel, .ta,
  .login-card input,
  .quiz-ta,
  .search input,
  .composer textarea#chat-text,
  .lp-item .inp,
  .ci-range .inp{ font-size:var(--t-campo); }
}

/* ================= Tablero de Pendientes (Lista / Tabla / Kanban / Calendario) ================= */
/* Controles compactos de la barra (auto-ancho, a diferencia de .inp/.sel que ocupan 100%). */
.sel-sm{ width:auto; padding:7px 11px; font-size:var(--t-meta); }
.inp-sm{ padding:7px 11px; font-size:var(--t-texto); }
.tv-filtros{ gap:8px; }
.tv-filtros .search input{ font-size:var(--t-texto); }
.tv-check{ display:inline-flex; align-items:center; gap:6px; font-size:var(--t-meta); color:var(--muted); white-space:nowrap; cursor:pointer; }
.tv-check input{ accent-color:var(--accent); }

/* Vista LISTA: reutiliza .card + filas .chk. Agrupacion opcional con encabezados. */
.tareas-lista{ padding:2px 20px; }
.tarea-fila{ gap:11px; }
.tgrupo{ margin-bottom:18px; }
.tgrupo-h{ display:flex; align-items:center; gap:8px; font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.07em; text-transform:uppercase; color:var(--muted); font-weight:600; margin:2px 2px 8px; }
.tgrupo-dot{ width:9px; height:9px; border-radius:50%; flex:0 0 9px; }

/* Vista TABLA: cabeceras ordenables, scroll horizontal propio (el body nunca scrollea). */
.tabla-scroll{ overflow-x:auto; padding:0; }
.ttabla{ width:100%; border-collapse:collapse; min-width:660px; }
.ttabla th{ text-align:left; font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); font-weight:400; padding:12px 14px; border-bottom:1px solid var(--hair); white-space:nowrap; }
.ttabla td{ padding:10px 14px; border-bottom:1px solid var(--hair); font-size:var(--t-texto); vertical-align:middle; white-space:nowrap; }
.ttabla tbody tr:last-child td{ border-bottom:0; }
.ttabla .trow{ cursor:default; }
/* .table (la generica, distinta de .ttabla de arriba) nace con overflow:hidden -- pensada
   para recortar esquinas redondeadas, no para tablas anchas -- y sin min-width/nowrap el
   navegador la encoge en vez de scrollear: envolverla en .tabla-scroll sola no bastaba.
   Acotado a movil y al combo con .tabla-scroll para no tocar .table en ningun otro lado. */
@media (max-width:640px){
  .tabla-scroll .table{ min-width:480px; }
  .tabla-scroll .table th, .tabla-scroll .table td{ white-space:nowrap; }
}
.tsort{ cursor:pointer; user-select:none; }
@media (hover:hover){ .tsort:hover{ color:var(--ink); } }
.tcell-tit{ cursor:pointer; font-weight:500; white-space:normal; min-width:180px; }
@media (hover:hover){ .tcell-tit:hover{ color:var(--accent); } }
.trow-done .tcell-tit{ text-decoration:line-through; color:var(--muted); }
.tlink{ cursor:pointer; color:var(--accent); }
@media (hover:hover){ .tlink:hover{ text-decoration:underline; } }
.tnota{ color:var(--muted); font-weight:700; }
.ttabla .box{ cursor:pointer; }

/* Vista KANBAN: columnas en fila (scroll-x), tarjetas arrastrables. */
.kanban{ display:flex; gap:14px; overflow-x:auto; padding-bottom:10px; align-items:flex-start; }
.kcol{ flex:0 0 284px; max-width:300px; background:var(--deep); border:1px solid var(--hair); border-radius:var(--r); display:flex; flex-direction:column; max-height:calc(100vh - 250px); }
.kcol-h{ display:flex; align-items:center; gap:8px; padding:12px 14px; font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.05em; text-transform:uppercase; font-weight:600; color:var(--ink); border-bottom:1px solid var(--hair); }
.kcol-dot{ width:9px; height:9px; border-radius:50%; flex:0 0 9px; }
.kcol-body{ padding:10px; display:flex; flex-direction:column; gap:8px; overflow-y:auto; min-height:70px; }
.kcol-body.kdrop{ background:color-mix(in srgb, var(--accent) 9%, transparent); outline:2px dashed var(--accent); outline-offset:-5px; border-radius:var(--r); }
.ktarj{ background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); padding:10px 11px; cursor:grab; box-shadow:0 1px 2px rgba(41,40,36,.05); }
.ktarj:active{ cursor:grabbing; }
.ktarj.dragging{ opacity:.45; }
.ktarj-tit{ font-size:var(--t-texto); line-height:1.3; margin-bottom:7px; }
.ktarj-done .ktarj-tit{ text-decoration:line-through; color:var(--muted); }
.ktarj-meta{ display:flex; gap:6px; flex-wrap:wrap; }
.ktarj-sub{ font-size:var(--t-meta); color:var(--muted); margin-top:7px; }
.kvacio{ color:var(--muted); font-size:var(--t-meta); text-align:center; padding:8px 0; opacity:.45; }
.kadd{ border:1px dashed var(--line2); background:transparent; color:var(--muted); border-radius:var(--r); padding:8px 10px; font-size:var(--t-meta); cursor:pointer; text-align:left; width:100%; }
@media (hover:hover){ .kadd:hover{ border-color:var(--accent); color:var(--accent); } }
.kadd-box{ background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); padding:8px; }

/* Vista CALENDARIO: reutiliza .cal-grid; chip de tarea completada se atenua. */
.tareas-view .cal-chip-tarea.chip-done{ opacity:.5; text-decoration:line-through; }
.tsinfecha{ margin-top:16px; }

/* Densidad compacta (toggle). Reduce el aire en filas, celdas y tarjetas. */
.dens-compacto .chk{ padding:6px 0; }
.dens-compacto .ttabla td{ padding:6px 14px; }
.dens-compacto .ktarj{ padding:7px 9px; }
.dens-compacto .ktarj-tit{ margin-bottom:5px; }
.dens-compacto .ktarj-sub{ margin-top:5px; }

/* Overrides de tema oscuro para las superficies con color propio del tablero. */
:root[data-theme="dark"] .ktarj{ background:#2C2C2A; }
:root[data-theme="dark"] .kadd-box{ background:#2C2C2A; }
:root[data-theme="dark"] .kcol-body.kdrop{ background:color-mix(in srgb, var(--accent) 16%, transparent); }

/* ================= Galería de entrega (estudio + portal comparten el lightbox) ================= */
/* Lightbox inmersivo */
.lbx{ position:fixed; inset:0; z-index:200; background:rgba(18,17,15,.95); display:flex; flex-direction:column; animation:lbxIn .16s ease; }
@keyframes lbxIn{ from{ opacity:0; } to{ opacity:1; } }
.lbx-stage{ flex:1; display:flex; align-items:center; justify-content:center; position:relative; min-height:0; padding:14px; }
.lbx-img{ max-width:100%; max-height:100%; object-fit:contain; border-radius:4px; box-shadow:0 12px 48px rgba(0,0,0,.55); user-select:none; -webkit-user-drag:none; transition:transform .2s ease; }
.lbx-img.zoomed{ transform:scale(2.5); }
.lbx-x{ position:absolute; top:14px; right:16px; z-index:2; width:44px; height:44px; border:0; border-radius:50%; background:rgba(255,255,255,.12); color:#fff; font-size:var(--t-titulo); cursor:pointer; }
@media (hover:hover){ .lbx-x:hover{ background:rgba(255,255,255,.24); } }
.lbx-nav{ position:absolute; top:50%; transform:translateY(-50%); width:52px; height:52px; border:0; border-radius:50%; background:rgba(255,255,255,.1); color:#fff; font-size:var(--t-saludo); line-height:1; cursor:pointer; display:flex; align-items:center; justify-content:center; }
@media (hover:hover){ .lbx-nav:hover{ background:rgba(255,255,255,.24); } }
.lbx-prev{ left:14px; } .lbx-next{ right:14px; }
.lbx-bar{ display:flex; align-items:center; justify-content:space-between; padding:12px 18px 16px; color:#fff; }
.lbx-count{ font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.06em; opacity:.85; }
.lbx-actions{ display:flex; gap:8px; }
.lbx-btn{ width:40px; height:40px; border:0; border-radius:50%; background:rgba(255,255,255,.12); color:#fff; font-size:var(--t-sub); cursor:pointer; display:flex; align-items:center; justify-content:center; }
@media (hover:hover){ .lbx-btn:hover{ background:rgba(255,255,255,.24); } }
.lbx-btn.on, .lbx-fav.on{ background:var(--accent); }
@media(max-width:640px){ .lbx-nav{ width:42px; height:42px; font-size:var(--t-titulo); } }

/* Resumen de galería en el detalle del evento */
.gal-resumen{ display:flex; align-items:center; gap:14px; }
.gal-resumen-cover{ width:64px; height:64px; flex:0 0 64px; border-radius:var(--r); background-size:cover; background-position:center; border:1px solid var(--hair); }
.gal-resumen-vacia{ display:flex; align-items:center; justify-content:center; color:var(--muted); font-size:var(--t-titulo); background:var(--deep); }

/* Panel de galería del estudio: dropzone, progreso, grid masonry */
.gal-drop{ border:2px dashed var(--line2); border-radius:var(--r); padding:26px 20px; text-align:center; cursor:pointer; transition:.14s; background:var(--paper); }
.gal-drop:focus-visible{ border-color:var(--accent); outline:none; }
@media (hover:hover){ .gal-drop:hover{ border-color:var(--accent); outline:none; } }
.gal-drop.drag{ border-color:var(--accent); background:color-mix(in srgb, var(--accent) 7%, var(--paper)); }
.gal-drop-ico{ font-size:var(--t-titulo); color:var(--accent); }
.gal-drop-t{ margin-top:6px; font-size:var(--t-texto); }
.gal-drop-link{ color:var(--accent); text-decoration:underline; }
.gal-prog{ margin-top:12px; }
.gal-prog-bar{ height:6px; border-radius:var(--r); background:var(--deep); overflow:hidden; }
.gal-prog-fill{ height:100%; background:var(--accent); transition:width .2s; }
/* Lista persistente de errores de subida (subirLoteGaleria). max-height + scroll: son pocos
   GRUPOS casi siempre (2-3 razones distintas), pero por si un lote real cae en muchas. */
.gal-prog-errores{ margin-top:10px; max-height:220px; overflow-y:auto; display:flex; flex-direction:column; gap:8px; }
.gal-prog-error-grupo{ padding:8px 10px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); }
.gal-prog-error-msg{ font-size:var(--t-meta); font-weight:600; color:var(--ink); }
.gal-prog-error-archivos{ font-size:var(--t-meta); color:var(--muted); margin-top:3px; line-height:1.4; }
/* display:grid y NO columns (el masonry de antes): con `columns`, el navegador llena hacia
   ABAJO por cada columna antes de pasar a la siguiente -- el orden real (el que se guarda,
   el que ordena por fecha de captura) queda correcto en el DOM, pero a simple vista, leyendo
   fila por fila como se lee cualquier otra cuadrícula, parecía salteado (reportado como
   "las fotos no se subieron en orden" cuando el EXIF y el sort SI estaban bien). Con grid,
   la fila 1 son las primeras N fotos, la fila 2 las siguientes N: leer de izquierda a
   derecha y de arriba hacia abajo ES el orden real. align-items:start evita que una foto
   corta se estire para llenar el alto de su fila (cada una conserva su aspect-ratio inline). */
.gal-masonry{ display:grid; grid-template-columns:repeat(2,1fr); gap:8px; align-items:start; }
@media(min-width:600px){ .gal-masonry{ grid-template-columns:repeat(3,1fr); } }
@media(min-width:900px){ .gal-masonry{ grid-template-columns:repeat(4,1fr); } }
@media(min-width:1300px){ .gal-masonry{ grid-template-columns:repeat(5,1fr); } }
.gal-item{ position:relative; border-radius:var(--r); overflow:hidden; border:1px solid var(--hair); cursor:zoom-in; background:var(--deep); }
.gal-item img{ width:100%; display:block; }
.gal-fav-badge{ position:absolute; top:8px; left:9px; color:#fff; font-size:var(--t-texto); text-shadow:0 1px 3px rgba(0,0,0,.55); }
.gal-item-acts{ position:absolute; top:6px; right:6px; display:flex; gap:5px; opacity:0; transition:.14s; }
@media (hover:hover){ .gal-item:hover .gal-item-acts{ opacity:1; } }
.gal-act{ width:28px; height:28px; border:0; border-radius:var(--r); background:rgba(0,0,0,.52); color:#fff; font-size:var(--t-texto); cursor:pointer; display:flex; align-items:center; justify-content:center; }
@media (hover:hover){ .gal-act:hover{ background:rgba(0,0,0,.78); } }
@media (hover:hover){ .gal-act-del:hover{ background:var(--red); } }
.gal-oculta img{ opacity:.38; }
.gal-oculta-badge{ position:absolute; top:8px; left:9px; background:rgba(0,0,0,.6); color:#fff; font-size:var(--t-eti); letter-spacing:.06em; text-transform:uppercase; padding:3px 7px; border-radius:var(--r); z-index:3; }
.gal-sec-sel{ position:absolute; left:6px; bottom:6px; z-index:3; font-size:var(--t-meta); padding:3px 6px; border-radius:var(--r); border:0; background:rgba(0,0,0,.55); color:#fff; opacity:0; transition:.14s; max-width:calc(100% - 12px); }
.gal-sec-sel:focus{ opacity:1; }
@media (hover:hover){ .gal-item:hover .gal-sec-sel{ opacity:1; } }
/* Seleccion multiple: la palomita solo aparece al pasar el mouse, PERO una foto ya
   seleccionada la muestra siempre — si no, al mover el cursor no queda ni rastro de que
   fotos estan marcadas y el "mover a seccion" se vuelve a ciegas. */
.gal-check{ position:absolute; right:6px; bottom:6px; z-index:3; width:24px; height:24px; padding:0; border:1.5px solid rgba(255,255,255,.85); border-radius:50%; background:rgba(0,0,0,.42); color:transparent; font-size:var(--t-meta); line-height:1; cursor:pointer; opacity:0; transition:.14s; display:flex; align-items:center; justify-content:center; }
.gal-check:focus-visible{ opacity:1; }
@media (hover:hover){ .gal-item:hover .gal-check{ opacity:1; } }
.gal-item.gal-sel .gal-check{ opacity:1; background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); }
.gal-item.gal-sel{ border-color:var(--accent); box-shadow:0 0 0 2px var(--accent); }
/* Bloque de texto entre fotos (diseno.bloques): una tarjeta mas del grid, arrastrable
   como una foto, con una APROXIMACION del estilo publico (el CRM no carga
   galeria-temas.css). Clic = editar (no lightbox); la etiqueta de arriba dice el tipo. */
.gal-bloque{ cursor:pointer; background:var(--paper); padding:34px 20px 20px; min-height:120px; display:flex; flex-direction:column; justify-content:center; gap:8px; }
@media (hover:hover){ .gal-bloque:hover{ border-color:var(--accent); } }
.gal-blq-tag{ position:absolute; top:8px; left:9px; display:inline-flex; align-items:center; gap:5px; font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.gal-blq-t{ font-family:var(--serif); font-size:var(--t-sub); line-height:1.2; letter-spacing:-.01em }
.gal-blq-x{ font-size:var(--t-meta); line-height:1.6; color:var(--muted); display:-webkit-box; -webkit-line-clamp:6; -webkit-box-orient:vertical; overflow:hidden; }
.gal-blq-cita{ font-family:var(--serif); font-style:normal; font-size:var(--t-campo); line-height:1.35; letter-spacing:-.01em }
.gal-blq-autor, .gal-blq-firma{ font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); }
.gal-bloque-separador{ align-items:center; text-align:center; }
.gal-blq-palabra{ font-family:var(--serif); font-size:clamp(23px,3vw,38.5px); line-height:1; overflow-wrap:anywhere; letter-spacing:-.01em }
/* El fantasma del arrastre de un bloque: clon visual de la tarjeta (no hay <img> que
   pintar de fondo). Hereda posicion/sombra de .gal-fantasma. */
.gal-fantasma-bloque{ background:var(--paper); padding:34px 20px 20px; overflow:hidden; display:flex; flex-direction:column; justify-content:center; gap:8px; }
.gal-fantasma-bloque .gal-item-acts{ display:none; }
/* "+" para inventar una seccion: mismo chip pero de borde punteado, para que se lea como
   "hueco por llenar" y no como un filtro mas de la fila. */
.fchip-mas{ border-style:dashed; padding-left:12px; padding-right:12px; font-size:var(--t-texto); line-height:1; }
@media (hover:hover){ .fchip-mas:hover{ border-color:var(--accent); color:var(--accent); } }
/* Barra de la pestana Fotos, en bandas: "Ver" (Todas/Favoritas/Sin seccion) arriba, la
   SECUENCIA de secciones abajo con su rotulo y consecuencia, acciones (ordenar/descargar)
   aparte en su propio .toolbar. Antes las 4 cosas compartian la misma fila de chips y
   nada distinguia lo que se arrastra de lo que solo filtra -- se desplego el arrastre y
   Daniel no vio ninguna senal de que existiera. */
.g-barra{ display:flex; flex-direction:column; gap:12px; }
.g-barra-sep{ height:1px; background:var(--line2); }
.g-sec-cab{ display:flex; align-items:center; justify-content:space-between; gap:10px; }
.g-sec-rotulo{ font-size:var(--t-meta); font-weight:500; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
.g-sec-rotulo-hint{ font-weight:400; letter-spacing:0; text-transform:none; color:var(--accent); }
.g-sec-consecuencia{ margin:0; }
/* Chip de seccion arrastrable (cablearArrastreSecciones, app.js): mismo tratamiento de
   opacidad que .gal-item.gal-arrastrando, la version para fotos. */
.fchip.dragging{ opacity:.4; }
/* Agarradera del chip de seccion: mismo glifo y touch-action que .ced-handle (contrato) --
   el arrastre arranca AQUI, no en el chip completo, para no bloquear el scroll tactil de
   toda la fila. Siempre visible y tenue, no solo al pasar el mouse: es la UNICA senal de
   que el chip se puede mover, y sin ella no se descubre (mismo defecto que tenia esto
   antes de este cambio). */
.g-sec-grip{ display:inline-flex; align-items:center; margin-right:6px; opacity:.4; cursor:grab; touch-action:none; }
@media (hover:hover){ .fchip:hover .g-sec-grip{ opacity:.9; } }
body.g-sec-arrastrando-activo{ cursor:grabbing !important; }
/* Barra de acciones de la seleccion: pegajosa arriba del grid para que siga a la vista
   cuando el fotografo lleva 200 fotos scrolleadas. */
#g-bulk.on{ position:sticky; top:8px; z-index:6; display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin-bottom:12px; padding:9px 13px; border:1px solid var(--accent); border-radius:var(--r); background:var(--paper); box-shadow:0 2px 10px rgba(41,40,36,.09); }
/* ===== Galería · pestaña Actividad — qué pasa DESPUÉS de entregar =====
   Recrea la pantalla "Actividad" del handoff (Panel del Fotografo) con el vocabulario que
   ya existe en el CRM: .kpigrid+.stat para las tarjetas, .dash para las dos columnas y
   .pblock para los paneles. Solo se añade aquí lo que el sistema no tenía: las barras de
   visitas por día y las filas con miniatura. Prefijo gact- (gal-act ya son los botones
   del tile de la cuadrícula). */
.gact-seg{ width:max-content; max-width:100%; margin:-10px 0 18px; }
.gact-aviso{ font-size:var(--t-meta); color:var(--muted); background:var(--bone); border:1px solid var(--hair); border-radius:var(--r); padding:11px 14px; margin-bottom:16px; }
.gact-spark{ display:flex; align-items:flex-end; gap:4px; height:78px; }
.gact-spark-col{ flex:1; height:100%; display:flex; align-items:flex-end; }
.gact-spark-bar{ width:100%; border-radius:4px 4px 2px 2px; background:var(--accent); min-height:3px; }
/* Un día sin visitas se dibuja como pista completa muy tenue, no como barra de altura
   cero: así se lee "ese día no entró nadie" y no "falta el dato". Tiene que quedar MUY por
   debajo del acento o los días vacíos parecen los que más tráfico tuvieron. */
.gact-spark-bar.vacio{ background:var(--hair); opacity:.28; border-radius:4px; }
.gact-row{ display:flex; align-items:center; gap:12px; padding:9px 0; border-bottom:1px solid var(--hair); }
.gact-row:last-child{ border-bottom:0; }
.gact-th{ width:44px; height:44px; flex:0 0 44px; object-fit:cover; border-radius:var(--r); background:var(--deep); }
.gact-n{ flex:0 0 auto; font-family:var(--serif); font-weight:400; font-size:var(--t-campo); font-variant-numeric:tabular-nums; letter-spacing:-.01em }
/* Miniaturas de tamaño fijo (no grid con 1fr): con dos o tres favoritas, una rejilla
   elástica las estira hasta que parecen otra cosa. */
.gact-favs{ display:flex; flex-wrap:wrap; gap:8px; }
.gact-fav{ width:84px; height:84px; object-fit:cover; border-radius:var(--r); background:var(--deep); }

/* Tarjetas de galería en la ficha del cliente */
.cl-gal-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(148px,1fr)); gap:12px; }
.cl-gal-card{ text-align:left; border:1px solid var(--hair); border-radius:var(--r); overflow:hidden; background:var(--paper); cursor:pointer; padding:0; }
@media (hover:hover){ .cl-gal-card:hover{ border-color:var(--accent); } }
.cl-gal-cover{ aspect-ratio:4/3; background-size:cover; background-position:center; background-color:var(--deep); display:flex; align-items:center; justify-content:center; color:var(--muted); font-size:var(--t-titulo); }
.cl-gal-info{ padding:9px 11px; }
.cl-gal-t{ font-size:var(--t-texto); font-weight:500; }

/* ================= Dashboard CEO (sección Dinero) ================= */
.ceo-bar{ align-items:center; }
.ceo-kpis{ display:grid; grid-template-columns:repeat(6,1fr); gap:10px; margin-bottom:16px; }
@media(max-width:1100px){ .ceo-kpis{ grid-template-columns:repeat(3,1fr); } }
@media(max-width:560px){ .ceo-kpis{ grid-template-columns:repeat(2,1fr); } }
.ceo-kpi{ position:relative; background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); padding:14px 15px 15px; overflow:hidden; box-shadow:0 1px 3px rgba(41,40,36,.04); }
.ceo-kpi-bar{ position:absolute; left:0; top:0; bottom:0; width:3px; }
.ceo-kpi-l{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); }
.ceo-kpi-n{ font-family:var(--serif); font-size:var(--t-titulo); font-weight:400; margin-top:7px; line-height:1; letter-spacing:-.01em }
.ceo-kpi-s{ font-size:var(--t-meta); color:var(--muted); margin-top:8px; line-height:1.3; }
.ceo-kpi.alerta{ background:color-mix(in srgb, var(--red) 5%, var(--paper)); }
.ceo-d{ font-family:var(--mono); font-weight:700; font-size:var(--t-meta); }
.ceo-d.up{ color:var(--blue); } .ceo-d.down{ color:var(--red); }
.ceo-gauge{ height:10px; border-radius:var(--r); background:var(--deep); overflow:hidden; }
.ceo-gauge-fill{ height:100%; background:linear-gradient(90deg,var(--yellow),var(--blue)); border-radius:var(--r); transition:width .35s; }
.ceo-minis{ display:grid; grid-template-columns:1fr 1fr; gap:10px; }
.ceo-mini{ text-align:center; padding:13px 8px; border:1px solid var(--hair); border-radius:var(--r); }
.ceo-mini-n{ font-family:var(--serif); font-size:var(--t-sub); font-weight:400; letter-spacing:-.01em }
.ceo-estac{ display:flex; align-items:flex-end; gap:4px; height:82px; padding-top:8px; }
.ceo-estac-col{ flex:1; display:flex; flex-direction:column; align-items:center; gap:5px; justify-content:flex-end; }
.ceo-estac-bar{ width:100%; max-width:15px; background:var(--blue); border-radius:3px 3px 0 0; }
.ceo-estac-l{ font-size:var(--t-eti); color:var(--muted); }
.ceo-alerta{ display:flex; gap:10px; align-items:flex-start; padding:10px 0; border-bottom:1px solid var(--hair); font-size:var(--t-texto); line-height:1.4; }
.ceo-alerta:last-child{ border-bottom:0; }
.ceo-alerta-dot{ width:7px; height:7px; border-radius:50%; background:var(--yellow); margin-top:6px; flex:0 0 7px; }
.ceo-link{ cursor:pointer; border-radius:var(--r); margin:0 -8px; padding-left:8px; padding-right:8px; }
@media (hover:hover){ .ceo-link:hover{ background:#F1EEE5; } }
@media (hover:hover){ :root[data-theme="dark"] .ceo-link:hover{ background:#2C2C2A; } }

/* ===== Editor de diseño de la galería (#/galeria-diseno/:id) — recreación del handoff
   "Editor de Galeria.dc.html": rail de 392px con tarjetas visuales + canvas con mockup
   de navegador/teléfono mostrando la vista previa real en vivo. Paleta propia (fija,
   estilo herramienta de diseño), con un ajuste minimo para modo oscuro del CRM. ===== */
.geditor{
  --ge-bg:#faf9f6; --ge-canvas:#e7e4dd; --ge-ink:#191714; --ge-ink2:#7a736a; --ge-ink3:#a89f93;
  --ge-line:rgba(25,23,20,.12); --ge-line2:rgba(25,23,20,.06); --ge-accent:#a85d3e;
  --ge-serif:'Instrument Sans',system-ui,sans-serif;
  position:fixed; inset:0; z-index:40; display:flex; background:var(--ge-canvas);
  font-family:'Instrument Sans',var(--sans); color:var(--ge-ink); -webkit-font-smoothing:antialiased;
}
:root[data-theme="dark"] .geditor{ --ge-bg:#232220; --ge-canvas:#18171533; --ge-ink:#f0ece4; --ge-ink2:#a49c90; --ge-ink3:#6f675c; --ge-line:rgba(240,236,228,.14); --ge-line2:rgba(240,236,228,.07); --ge-canvas:#161513; }
.geditor button{ font-family:inherit; cursor:pointer; border:none; background:none; color:inherit; }
.geditor input,.geditor textarea{ font-family:inherit; }
.geditor .ge-serif{ font-family:var(--ge-serif); font-weight:400; line-height:1; letter-spacing:-.01em }

/* rail */
.ge-rail{ width:392px; flex:none; background:var(--ge-bg); border-right:1px solid var(--ge-line2); display:flex; flex-direction:column; height:100%; }
.ge-railtop{ padding:22px 26px 20px; border-bottom:1px solid var(--ge-line2); }
.ge-crumb{ display:flex; align-items:center; gap:8px; color:var(--ge-ink2); font-size:var(--t-meta); font-weight:500; margin-bottom:16px; background:none; padding:0; }
@media (hover:hover){ .ge-crumb:hover{ color:var(--ge-ink); } }
.ge-crumb .ge-bk{ width:28px; height:28px; border-radius:var(--r); border:1px solid var(--ge-line); display:flex; align-items:center; justify-content:center; font-size:var(--t-texto); flex:none; }
.ge-galname{ font-family:var(--ge-serif); font-size:var(--t-titulo); font-weight:400; line-height:1.08; margin:0 0 12px; color:var(--ge-ink); letter-spacing:-.01em }
.ge-rbtn{ flex:1; padding:11px; border-radius:var(--r); font-size:var(--t-texto); font-weight:600; border:1px solid var(--ge-line); transition:color var(--d-toque) var(--curva-cambia), border-color var(--d-toque) var(--curva-cambia), background-color var(--d-toque) var(--curva-cambia), opacity var(--d-toque) var(--curva-cambia); text-align:center; color:var(--ge-ink); }
@media (hover:hover){ .ge-rbtn:hover{ border-color:var(--ge-ink); } }
.ge-rbtn:disabled{ opacity:.5; cursor:not-allowed; }
.ge-rbtn.primary{ background:var(--ge-ink); color:var(--ge-bg); border-color:var(--ge-ink); }
@media (hover:hover){ .ge-rbtn.primary:hover{ opacity:.88; } }
.ge-savestate{ font-size:var(--t-meta); color:var(--ge-ink3); margin-top:10px; text-align:center; height:14px; }
.ge-railscroll{ flex:1; overflow-y:auto; padding:6px 26px 40px; }
.ge-sec{ padding:22px 0; border-bottom:1px solid var(--ge-line2); }
.ge-sec:last-child{ border-bottom:0; }
.ge-sechd{ display:flex; align-items:center; gap:9px; margin-bottom:16px; }
.ge-sechd .ge-n{ font-family:var(--ge-serif); font-size:var(--t-campo); font-weight:400; letter-spacing:-.01em }
.ge-sechd .ge-ix{ width:20px; height:20px; border-radius:var(--r); background:rgba(25,23,20,.05); display:flex; align-items:center; justify-content:center; font-size:var(--t-meta); font-weight:600; color:var(--ge-ink2); flex:none; }
.ge-field{ margin-bottom:16px; border-radius:var(--r); transition:box-shadow var(--d-toque) var(--curva-cambia), background-color var(--d-toque) var(--curva-cambia); }
.ge-field:last-child{ margin-bottom:0; }
/* Clic en el lienzo sobre un texto instrumentado (ver galeria.js/galeria-temas.js):
   pulso breve en el acento del CRM para marcar a donde llego el scroll -- es una
   señal del editor, no del acento de la galeria que se esta editando. */
.ge-field.ge-flash{ box-shadow:0 0 0 2px var(--accent); background-color:color-mix(in oklab, var(--accent) 8%, transparent); }
.ge-flabel{ font-size:var(--t-meta); font-weight:600; color:var(--ge-ink2); margin-bottom:9px; display:flex; justify-content:space-between; }
.ge-flabel .ge-v{ color:var(--ge-ink); font-weight:600; }
.ge-seg{ display:flex; gap:3px; background:rgba(25,23,20,.05); border-radius:var(--r); padding:3px; }
.ge-segbtn{ flex:1; padding:9px 6px; border-radius:var(--r); font-size:var(--t-meta); font-weight:600; color:var(--ge-ink2); transition:color var(--d-toque) var(--curva-cambia), background-color var(--d-toque) var(--curva-cambia), box-shadow var(--d-toque) var(--curva-cambia); text-align:center; white-space:nowrap; }
@media (hover:hover){ .ge-segbtn:hover{ color:var(--ge-ink); } }
.ge-segbtn.on{ background:var(--ge-bg); color:var(--ge-ink); box-shadow:0 1px 3px rgba(0,0,0,.1); }
.ge-swrow{ display:flex; gap:10px; flex-wrap:wrap; align-items:center; }
.ge-sw{ width:34px; height:34px; border-radius:100px; position:relative; transition:box-shadow var(--d-toque) var(--curva-cambia); border:2px solid transparent; flex:none; }
@media (hover:hover){ .ge-sw:hover{ box-shadow:0 0 0 2px var(--ge-bg),0 0 0 3px var(--ge-ink3); } }
.ge-sw.on{ box-shadow:0 0 0 2px var(--ge-bg),0 0 0 4px var(--ge-ink); }
.ge-swcustom{ width:30px; height:30px; border-radius:100px; border:1px solid var(--ge-line); padding:0; }
/* "La de la plantilla" dentro de la paleta de fondo: no es un color, es la AUSENCIA de
   eleccion (fondoTema "auto"). Vive en la misma fila y no como boton aparte porque el
   fondo se elige en un solo lugar; se dibuja partido en diagonal claro/oscuro para que se
   lea como "lo que traiga la plantilla" y no como un tono concreto. El nombre viaja en la
   etiqueta de la fila (#ge-fondolabel), que es donde el resto del panel pone su valor. */
.ge-sw-auto{ background:linear-gradient(135deg,#faf9f6 0 50%,#1b1a17 50% 100%); box-shadow:inset 0 0 0 1px var(--ge-line); }
.ge-cards{ display:grid; grid-template-columns:repeat(3,1fr); gap:8px; }
.ge-card{ border:1px solid var(--ge-line); border-radius:var(--r); padding:13px 11px; cursor:pointer; transition:border-color var(--d-toque) var(--curva-cambia), background-color var(--d-toque) var(--curva-cambia), box-shadow var(--d-toque) var(--curva-cambia); text-align:left; background:none; display:block; width:100%; }
@media (hover:hover){ .ge-card:hover{ border-color:var(--ge-ink3); } }
.ge-card.on{ border-color:var(--ge-ink); background:rgba(25,23,20,.02); box-shadow:inset 0 0 0 1px var(--ge-ink); }
.ge-card .ge-ct{ font-size:var(--t-texto); font-weight:600; margin-bottom:2px; color:var(--ge-ink); }
.ge-card .ge-cs{ font-size:var(--t-meta); color:var(--ge-ink2); }
.ge-card .ge-prev{ height:30px; border-radius:var(--r); margin-bottom:9px; display:flex; align-items:center; justify-content:center; font-size:var(--t-texto); overflow:hidden; background:linear-gradient(150deg,#2a2620,#151310); color:#efe9df; }
/* "La de la plantilla": la muestra no es una letra concreta porque no HAY una letra concreta
   -- depende de la plantilla. Se pinta en la del CRM y se distingue por el tono. */
.ge-card .ge-prev.ge-pf-auto{font-family:var(--serif);opacity:.6; letter-spacing:-.01em}
.ge-card .ge-prev.ge-pf-editorial{ font-family:'Cormorant Garamond',serif; font-style:italic; }
.ge-card .ge-prev.ge-pf-modern{ font-family:'Instrument Sans',sans-serif; font-weight:700; letter-spacing:-.02em; }
.ge-card .ge-prev.ge-pf-romantic{ font-family:'Newsreader',serif; font-style:italic; }
.ge-card .ge-prev.ge-pf-portal-moderna{ font-family:'Playfair Display',Georgia,serif; font-weight:600; }
/* "De la plantilla": las 16 plantillas titulan con Instrument Serif, asi que la muestra
   ensena eso. La clasica no tiene fuente propia -- ahi "auto" resuelve al par elegido. */
.ge-card .ge-prev.ge-pf-plantilla{ font-family:'Instrument Serif',Georgia,serif; }
.ge-card .ge-prev.ge-pf-display{ font-family:'Instrument Serif',Georgia,serif; }
.ge-card .ge-prev.ge-pf-mono{ font-family:'JetBrains Mono',monospace; font-weight:500; letter-spacing:-.04em; }
.ge-card .ge-prev.ge-pf-script{ font-family:'Alex Brush',cursive; font-size:var(--t-titulo); }
.ge-card .ge-prev.ge-pf-bold{ font-family:'Fraunces',Georgia,serif; font-weight:600; }
.ge-card .ge-prev.ge-pf-geometric{ font-family:'Space Grotesk',sans-serif; font-weight:600; letter-spacing:-.01em; }
.ge-card .ge-prev.ge-pf-elegante{ font-family:'Playfair Display',Georgia,serif; font-weight:600; }
/* Tarjetas del selector de VISTA DE FOTOS (.gxc): solo el acomodo, sin portada. El
   hijo principal llena la tarjeta; los que traen flex inline (rails, tiras) lo respetan. */
.gxc.gxm>*{flex:1 1 auto;min-height:0}
.gxc .gxm-rev-cap{flex:0 0 auto}
.gxc .gxm-pag-nav,.gxc .gxm-pila-tira,.gxc .gxm-idx-hd{flex:0 0 auto}
.gxc .gxm-dia-rail,.gxc .gxm-can-rail,.gxc .gxm-riel-idx{flex:0 0 auto}
/* Boton-enlace chico dentro de un .ge-cs (el "Volver al automatico" del slider) */
.ge-link{ background:none; border:0; padding:0; font:inherit; color:var(--accent); cursor:pointer; text-decoration:underline; }
.ge-toggle{ display:flex; align-items:center; justify-content:space-between; padding:13px 0; gap:12px; }
.ge-toggle+.ge-toggle{ border-top:1px solid var(--ge-line2); }
.ge-toggle .ge-tt{ font-size:var(--t-texto); font-weight:600; }
.ge-toggle .ge-ts{ font-size:var(--t-meta); color:var(--ge-ink2); margin-top:1px; }
.ge-sw2{ width:42px; height:25px; border-radius:var(--r-pildora,100px); background:rgba(25,23,20,.15); position:relative; transition:background-color var(--d-toque) var(--curva-cambia); flex:none; }
.ge-sw2:after{ content:""; position:absolute; top:3px; left:3px; width:19px; height:19px; border-radius:100px; background:var(--boton-t,#fff); transition:transform var(--d-toque) var(--curva-cambia); box-shadow:0 1px 3px rgba(0,0,0,.2); }
.ge-sw2.on{ background:var(--ge-ink); }
.ge-sw2.on:after{ transform:translateX(17px); }
/* Un bloque de texto (un capitulo / la cita / el cierre), pagina Textos. Caja propia para
   que se lea como una unidad entre hasta 10 bloques (8 capitulos + cita + cierre) -- sin
   ella, la pagina era un solo choclo de campos sin ninguna pausa visual. El header (rotulo
   + interruptor) lleva su propia raya para separarlo del cuerpo; el cuerpo se atenua (NO
   se deshabilita) cuando el bloque esta oculto -- sigue siendo un borrador editable. */
.ge-embebido .ge-rail .ge-txblock{ border:1px solid var(--ge-line); border-radius:var(--r); padding:2px 16px 16px; margin-bottom:12px; }
.ge-embebido .ge-rail .ge-txblock .ge-toggle{ border-bottom:1px solid var(--ge-line2); margin-bottom:14px; }
.ge-embebido .ge-rail .ge-txblock-body{ transition:opacity .15s; }
/* Encabezado de sesion en el riel de Textos: cada sesion tiene sus propios capitulos, y sin
   este rotulo dos "Ceremonia" seguidas (la de la boda y la del civil) eran indistinguibles. */
.ge-embebido .ge-rail .ge-txses{ font-size:var(--t-meta); font-weight:600; letter-spacing:.12em; text-transform:uppercase; color:var(--ge-ink2); margin:18px 0 8px; padding-top:12px; border-top:1px solid var(--ge-line2); }
.ge-embebido .ge-rail .ge-txses:first-of-type{ margin-top:6px; padding-top:0; border-top:0; }
.ge-embebido .ge-rail .ge-txblock.ge-txblock-oculto .ge-txblock-body{ opacity:.5; }
/* Mismo patron para los interruptores de frase/fecha/lugar/nota (Portada): el cuerpo se
   atenua, el interruptor mismo se queda a opacidad completa para que se siga viendo bien
   incluso apagado. */
.ge-embebido .ge-rail .ge-campo-body{ transition:opacity .15s; }
.ge-embebido .ge-rail .ge-field.ge-campo-oculto .ge-campo-body{ opacity:.5; }
/* Fila de botones "Estilo del titulo/texto" de capitulos: viven UNA vez arriba de la lista
   de capitulos, no repetidos por capitulo -- el rol de estilo es compartido por todos. */
.ge-embebido .ge-rail .ge-txestilos{ display:flex; gap:8px; margin-bottom:18px; flex-wrap:wrap; }
.ge-sub{ margin-top:10px; padding-left:2px; }
.ge-note{ width:100%; border:1px solid var(--ge-line); border-radius:var(--r); padding:13px; font-size:var(--t-campo); line-height:1.55; color:var(--ge-ink); resize:vertical; min-height:82px; outline:none; font-family:'Cormorant Garamond',serif; font-style:italic; background:var(--ge-bg); box-sizing:border-box; }
.ge-note:focus{ border-color:var(--ge-ink); }
.ge-txt{ width:100%; border:1px solid var(--ge-line); border-radius:var(--r); padding:11px 13px; font-size:var(--t-texto); outline:none; background:var(--ge-bg); color:var(--ge-ink); box-sizing:border-box; }
.ge-txt:focus{ border-color:var(--ge-ink); }

/* ===== Riel del editor de galeria (panel izquierdo) — repintado 2026-08-17 sobre el
   handoff "Editor de Galeria · Riel v2": paleta neutra oscura fija (no sigue el tema
   claro/oscuro del CRM, para no competir con los colores reales de la galeria que se
   esta editando), controles de TEXTO en vez de pildoras/tarjetas con caja. Cero cambios
   de funcionalidad: mismos ids, mismas clases delegadas (.ge-card[data-grupo],
   .ge-seg .ge-segbtn[data-grupo]), mismo dispatch en pintarDisenoGaleria (app.js).

   Todo bajo `.ge-embebido .ge-rail` (mas especifico que las reglas base de arriba).

   OJO, ESTO YA NO ES CIERTO: aqui decia que estas reglas NO alcanzaban a portal-diseno
   "porque renderiza sin la clase .ge-embebido". Desde el rediseño del portal (2026-08-28)
   ese editor monta como `.geditor.ge-embebido.ge-portal` y SI las recibe todas. Confiar en
   esta linea costo 4 de sus 5 paginas en blanco en produccion. Al tocar cualquier regla de
   esta seccion, asumir DOS consumidores; lo que sea propio del portal va en el bloque
   `.ge-embebido.ge-portal` (busca "PORTAL-DISEÑO"). El canvas/preview
   (.ge-canvas) y los selectores a pantalla completa (abrirSelectorEstilos y companeros,
   galeria-estilos.js) quedan fuera a proposito: no son parte de este rediseño. */
/* 2026-08-21: el riel PASA A SEGUIR EL TEMA del CRM. Antes era oscuro fijo, con la razon
   escrita arriba (no competir con los colores de la galeria que se edita). La razon
   seguia siendo buena pero el efecto no: en modo claro el CRM entero es claro y el riel
   quedaba como un bloque negro pegado, reportado como "no se cambia a light view".
   El espiritu de aquella decision se conserva de otra forma: el riel NO usa el mismo
   --ge-bg que el resto del editor, usa un neutro propio que lo separa del lienzo y de la
   galeria; sigue leyendose como herramienta, no como papel.
   --ge-prev/--ge-focus/--ge-warn nacen aqui porque 7 reglas de mas abajo tenian el color
   pegado dando por hecho el fondo oscuro (#fff, #242424, rgba(255,255,255,...)): en un
   riel claro eso era texto blanco sobre casi blanco. */
.ge-embebido .ge-rail{
  --ge-bg:#f4f2ee; --ge-ink:#191714; --ge-ink2:#6f6a63; --ge-ink3:#6f695f;
  --ge-line:rgba(25,23,20,.16); --ge-line2:rgba(25,23,20,.08);
  --ge-prev:#e6e2da; --ge-focus:rgba(25,23,20,.45); --ge-warn:#8a4b12;
  /* Texto secundario DENTRO de una caja --ge-prev (la etiqueta de .ge-row). No
     alcanza con --ge-ink2: medido, da 4.15 sobre #e6e2da, bajo el minimo AA de
     4.5. Nace por la misma razon que --ge-prev arriba: la caja cambio el fondo
     bajo un texto que antes iba sobre el riel. */
  --ge-ink2-caja:#635e57;
  width:400px;
}
:root[data-theme="dark"] .ge-embebido .ge-rail{
  --ge-bg:#1a1a1a; --ge-ink:#ededed; --ge-ink2:#8a8a8a; --ge-ink3:#6e6e6e;
  --ge-line:rgba(255,255,255,.1); --ge-line2:rgba(255,255,255,.06);
  --ge-ink3:#8f8f8f;   /* preexistente: #6e6e6e daba 3.41:1 en las opciones inactivas del
                          segmento, bajo el minimo de 4.5. Son botones, no adorno. */
  --ge-prev:#242424; --ge-focus:rgba(255,255,255,.45); --ge-warn:#e0a878;
  --ge-ink2-caja:#949494;   /* #8a8a8a daba 4.50 justo; esto deja margen */
}
/* ===== NAVEGACION POR PAGINAS (2026-08-22) =========================================
   Antes: 9 secciones apiladas en un scroll con nav scroll-spy. El resultado en movil
   (reportado con captura) era un chorizo: el nav envolvia a 2 filas, la ultima seccion
   quedaba a 8 pantallas, y nada distinguia de un vistazo que era clickeable y que era
   rotulo. Ahora se ve UNA pagina a la vez; el nav manda en vez de observar el scroll.

   REGLA DE AFFORDANCE, que es el corazon del rediseño -- tres niveles, sin ambiguedad:
     1. ACCION (.ge-row, .ge-rbtn-caja)  -> caja con borde + fondo --ge-prev + chevron
     2. OPCION (.ge-navbtn, chips, sw)   -> pildora con borde; activa = rellena --ge-ink
     3. ROTULO (.ge-flabel, .ge-secsub)  -> solo color y tamaño, JAMAS caja ni cursor
   Antes .ge-row y .ge-rbtn eran texto pelado ("sin pildora ni borde", decia el comentario
   de abajo) y por eso no se leian como botones. Un radio unico (10px cajas / 999px
   pildoras) y un solo acento (--ge-ink), sin colores decorativos nuevos. */
.ge-embebido .ge-railtop{ display:flex; align-items:center; gap:12px; padding:16px 24px 12px; border-bottom:1px solid var(--ge-line2); }
.ge-embebido .ge-railtop .ge-row{ margin-bottom:0; flex:1; min-width:0; }
.ge-embebido .ge-railtop .ge-savestate{ margin:0; height:auto; text-align:right; white-space:nowrap; flex:none; }
/* El nav no envuelve: se desliza. Con 8 chips en 400px envolver a 2-3 filas se come el
   riel; el scroll lateral mantiene UNA fila pase lo que pase. */
.ge-embebido .ge-nav{ display:flex; align-items:center; gap:6px; padding:12px 24px; border-bottom:1px solid var(--ge-line2); overflow-x:auto; scrollbar-width:none; -webkit-overflow-scrolling:touch; }
.ge-embebido .ge-nav::-webkit-scrollbar{ display:none; }
.ge-embebido .ge-navbtn{ flex:none; font-size:var(--t-meta); font-weight:500; color:var(--ge-ink2); padding:7px 13px; border-radius:var(--r); border:1px solid transparent; background:none; white-space:nowrap; transition:color var(--d-toque) var(--curva-cambia), background-color var(--d-toque) var(--curva-cambia), border-color var(--d-toque) var(--curva-cambia); }
@media (hover:hover){ .ge-embebido .ge-navbtn:hover{ color:var(--ge-ink); border-color:var(--ge-line); } }
.ge-embebido .ge-navbtn.on{ background:var(--ge-ink); border-color:var(--ge-ink); color:var(--ge-bg); font-weight:600; }
.ge-embebido .ge-railscroll{ padding:0 24px 48px; }
/* Una pagina a la vez. El resto de las secciones SIGUE en el DOM (solo oculta): las ~30
   funciones que repintan pedazos del riel escriben por id y no leen geometria. */
/* HIJO DIRECTO, no descendiente: "pagina" es solo un .ge-sec colgado del riel. El editor
   del portal ANIDA .ge-sec dentro de cada pagina (sus sub-bloques numerados), y con el
   selector descendiente esos hijos tambien caian en display:none -- 4 de sus 5 paginas se
   veian VACIAS en produccion (la unica sana era Secciones, la unica que no anida). Galeria
   no cambia: sus 8 secciones son hijas directas de .ge-railscroll, el match es identico. */
.ge-embebido .ge-railscroll > .ge-sec{ padding:24px 0; border-bottom:0; display:none; }
.ge-embebido .ge-railscroll > .ge-sec.activa{ display:block; }
.ge-embebido .ge-h2{ font-family:var(--ge-serif); font-size:var(--t-sub); font-weight:400; line-height:1.15; color:var(--ge-ink); margin:0 0 4px; letter-spacing:-.01em }
.ge-embebido .ge-secsub{ font-size:var(--t-meta); line-height:1.5; color:var(--ge-ink2); margin:0 0 22px; }
/* Cambiar de pagina del riel NO se anima: es la subpestana del panel, se toca decenas de
   veces por sesion y tambien con el teclado (dos motivos por los que el sistema la pone en
   la lista de lo que no se mueve). Video y la Puerta, con el mismo componente, ya no animaban. */
/* Fila-resumen (Plantilla / Diseño de portada / Acomodo): miniatura + valor + accion.
   AHORA con caja: es un boton, y antes no lo parecia. */
.ge-embebido .ge-row{ display:flex; align-items:center; gap:13px; width:100%; text-align:left; padding:10px 12px; margin-bottom:10px; cursor:pointer; background:var(--ge-prev); border:1px solid var(--ge-line); border-radius:var(--r); transition:border-color .15s, background-color .15s; }
.ge-embebido .ge-row:last-child{ margin-bottom:0; }
@media (hover:hover){ .ge-embebido .ge-row:hover{ border-color:var(--ge-ink3); } }
@media (hover:hover){ .ge-embebido .ge-row:hover .ge-rowval{ color:var(--ge-ink); } }
/* El chevron dice "esto abre algo" sin gastar una palabra. Va por CSS y no en el markup
   para no repetirlo en cada fila (y para que no lo lea un lector de pantalla). */
/* content con texto alternativo VACIO ("/ \"\"") : el chevron es decoracion, y sin
   eso algunos lectores de pantalla lo anuncian ("comilla angular simple derecha")
   despues de "Cambiar". No se puede poner aria-hidden en un pseudo-elemento. */
.ge-embebido .ge-row .ge-rbtn::after{ content:"\203A" / ""; margin-left:6px; opacity:.55; }
.ge-embebido .ge-thumb{ width:34px; height:34px; border-radius:var(--r); background-color:var(--ge-prev); background-position:center; background-size:cover; box-shadow:inset 0 0 0 1px var(--ge-line); flex:none; }
.ge-embebido .ge-thumb-lg{ width:40px; height:40px; border-radius:var(--r); }
.ge-embebido .ge-thumb-mosaico{ display:grid; grid-template-columns:1fr 1fr; grid-template-rows:1fr 1fr; gap:2px; padding:5px; box-sizing:border-box; }
.ge-embebido .ge-thumb-mosaico i{ background:var(--ge-ink3); border-radius:1px; opacity:.55; }
.ge-embebido .ge-thumb-mosaico i:first-child{ grid-row:span 2; }
.ge-embebido .ge-rowtext{ flex:1; min-width:0; }
.ge-embebido .ge-rowtext .ge-flabel{ margin-bottom:3px; }
.ge-embebido .ge-rowval{ font-size:var(--t-texto); color:var(--ge-ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; transition:color var(--d-toque) var(--curva-cambia); }
/* Botones/acciones del riel: texto, sin pildora ni borde. */
.ge-embebido .ge-rail .ge-rbtn{ flex:none; padding:0; border:0; border-radius:0; font-size:var(--t-meta); font-weight:500; color:var(--ge-ink2); background:none; }
@media (hover:hover){ .ge-embebido .ge-rail .ge-rbtn:hover{ color:var(--ge-ink); text-decoration:underline; text-underline-offset:2px; } }
@media (hover:hover){ .ge-embebido .ge-rail .ge-row .ge-rbtn:hover{ text-decoration:none; color:var(--ge-ink); } }
/* Accion suelta con caja (nivel 1 de la regla de affordance): "Xarpie, redactá" y
   compania, que viven fuera de una .ge-row y por eso necesitan su propia caja. */
.ge-embebido .ge-rail .ge-rbtn-caja{ padding:7px 13px; min-height:44px; box-sizing:border-box; display:inline-flex; align-items:center; border:1px solid var(--ge-line); border-radius:var(--r); background:var(--ge-prev); color:var(--ge-ink); transition:border-color .15s; }
@media (hover:hover){ .ge-embebido .ge-rail .ge-rbtn-caja:hover{ border-color:var(--ge-ink3); text-decoration:none; } }
.ge-embebido .ge-rail .ge-v{ font-size:var(--t-meta); color:var(--ge-ink); font-weight:500; }
.ge-embebido .ge-rail .ge-flabel-row{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-bottom:9px; }
.ge-embebido .ge-rail .ge-flabel-row .ge-flabel{ margin-bottom:0; }
/* Segmentos (posicion del texto / tamaño / marco / esquinas). El texto-plano-sin-caja del
   handoff original (2026-08-17) se reporto como "no parecen botones" -- una fila de
   palabras con un cambio de peso no lee como control. Cada opcion pasa a su propia
   pildora con borde: misma gramatica visual que .chip/.fchip del resto del CRM (borde +
   radio 100%), pero SIN el --accent del CRM -- eso seguia siendo la razon correcta del
   riel v2, con neutros propios (--ge-*) para no competir con los colores de la galeria
   que se esta editando. .ge-segdark del canvas (dispositivo/modo del preview) no se toca. */
.ge-embebido .ge-rail .ge-seg{ background:none; border-radius:0; padding:0; gap:8px; flex-wrap:wrap; justify-content:flex-start; }
.ge-embebido .ge-rail .ge-segbtn{ flex:none; padding:7px 13px; border-radius:var(--r); border:1px solid var(--ge-line); font-size:var(--t-meta); color:var(--ge-ink2); background:var(--ge-prev); }
@media (hover:hover){ .ge-embebido .ge-rail .ge-segbtn:hover{ border-color:var(--ge-ink3); color:var(--ge-ink); } }
.ge-embebido .ge-rail .ge-segbtn.on{ background:var(--ge-ink); border-color:var(--ge-ink); color:var(--ge-bg); font-weight:600; }
/* Swatches: 26px, aro blanco fino en vez de doble aro. El "+" libre es un circulo con un
   input[type=color] invisible encima (el <label> ya delega el click, sin JS nuevo). */
.ge-embebido .ge-rail .ge-swrow{ gap:10px; }
.ge-embebido .ge-rail .ge-sw{ width:26px; height:26px; box-shadow:inset 0 0 0 1px var(--ge-line); }
.ge-embebido .ge-rail .ge-sw.on,
.ge-embebido .ge-rail .ge-sw-auto.on{ box-shadow:0 0 0 2px var(--ge-bg),0 0 0 3.5px var(--ge-ink); }
.ge-embebido .ge-rail .ge-swcustom-wrap{ width:26px; height:26px; border-radius:100px; box-shadow:inset 0 0 0 1px var(--ge-line); display:flex; align-items:center; justify-content:center; font-size:var(--t-texto); line-height:1; color:var(--ge-ink2); cursor:pointer; position:relative; overflow:hidden; flex:none; transition:box-shadow .15s; }
@media (hover:hover){ .ge-embebido .ge-rail .ge-swcustom-wrap:hover{ box-shadow:inset 0 0 0 1px var(--ge-ink3); } }
.ge-embebido .ge-rail .ge-swcustom-wrap::before{ content:"+"; pointer-events:none; }
.ge-embebido .ge-rail .ge-swcustom{ position:absolute; inset:0; width:100%; height:100%; opacity:0; cursor:pointer; border:0; padding:0; }
/* Especimenes de tipografia: sin caja de tarjeta, solo el "Aa" con aro de seleccion y el
   nombre debajo. El subtitulo (ge-cs) que traia cada tarjeta se oculta -- el nombre solo
   ("Editorial", "Moderna"...) ya alcanza en una grilla de 6, y sin el se lee mas limpio. */
.ge-embebido .ge-rail .ge-cards{ gap:10px; }
.ge-embebido .ge-rail .ge-card{ border:0; border-radius:0; padding:0; background:none; box-shadow:none; }
@media (hover:hover){ .ge-embebido .ge-rail .ge-card:hover{ border-color:transparent; } }
.ge-embebido .ge-rail .ge-card.on{ background:none; box-shadow:none; }
.ge-embebido .ge-rail .ge-card .ge-prev{ height:44px; border-radius:var(--r); margin-bottom:8px; background:var(--ge-prev); color:var(--ge-ink3); box-shadow:inset 0 0 0 1px var(--ge-line); font-size:var(--t-sub); transition:box-shadow .15s,color .15s; }
@media (hover:hover){ .ge-embebido .ge-rail .ge-card:hover .ge-prev{ box-shadow:inset 0 0 0 1px var(--ge-ink3); } }
.ge-embebido .ge-rail .ge-card.on .ge-prev{ box-shadow:inset 0 0 0 1.5px var(--ge-ink); color:var(--ge-ink); }
.ge-embebido .ge-rail .ge-card .ge-ct{ font-size:var(--t-meta); font-weight:500; color:var(--ge-ink2); }
.ge-embebido .ge-rail .ge-card.on .ge-ct{ color:var(--ge-ink); }
.ge-embebido .ge-rail .ge-card .ge-cs{ display:none; }
/* Campos de texto: linea subrayada, nunca caja. La nota/cierre pierde el serif-cursiva
   del chrome (una sola familia tipografica fuera de la vista previa, por diseño) pero
   sigue siendo el mismo <textarea> con el mismo id -- el serif de la galeria real vive
   en la vista previa, no en el editor. */
.ge-embebido .ge-rail .inp,
.ge-embebido .ge-rail .ge-note,
.ge-embebido .ge-rail .ge-txt{ background:none; border:0; border-bottom:1px solid var(--ge-line); border-radius:0; padding:8px 0; font-size:var(--t-texto); line-height:1.6; color:var(--ge-ink); }
.ge-embebido .ge-rail .inp:focus,
.ge-embebido .ge-rail .ge-note:focus,
.ge-embebido .ge-rail .ge-txt:focus{ border-bottom-color:var(--ge-focus); }
.ge-embebido .ge-rail .ge-note{ font-family:inherit; font-style:normal; font-size:var(--t-texto); min-height:60px; }
.ge-embebido .ge-rail .ge-inp-sub{ margin-top:8px; font-size:var(--t-meta); color:var(--ge-ink2); }
.ge-embebido .ge-rail .ge-tx-titulo{ margin-bottom:4px; }
/* Destello de campo enfocado (clic en un texto de la vista previa -> geIrACampo en
   app.js): aro blanco en vez del acento azul del CRM, para no romper la paleta neutra. */
.ge-embebido .ge-rail .ge-field.ge-flash{ box-shadow:0 0 0 2px var(--ge-focus); background-color:color-mix(in srgb, var(--ge-ink) 6%, transparent); }
/* Aviso de legibilidad medida (contraste real contra el fondo de la plantilla). Ambar y
   no rojo: no es un error del fotografo ni algo que le impida seguir -- es un dato que
   antes no tenia. El unico color con croma del riel, justamente para que se note. */
.ge-embebido .ge-rail .ge-aviso:not([hidden]){ margin-top:8px; color:var(--ge-warn); }
.ge-embebido .ge-rail .ge-aviso .ge-link{ color:inherit; }
/* Muestra de tinta que no contrasta con el fondo REAL de la plantilla activa: se apaga y
   se le cruza una diagonal. Sigue siendo clickeable a proposito (el fotografo puede estar
   por cambiar tambien el fondo); solo deja de verse como una opcion equivalente. */
.ge-embebido .ge-rail .ge-sw-ilegible{ opacity:.3; }
.ge-embebido .ge-rail .ge-sw-ilegible::after{
  content:""; position:absolute; inset:0; border-radius:inherit;
  background:linear-gradient(to bottom right, transparent 45%, currentColor 45%, currentColor 55%, transparent 55%);
  color:var(--ge-ink2);
}
@media (hover:hover){ .ge-embebido .ge-rail .ge-sw-ilegible:hover{ opacity:.6; } }
/* Nivel 3 de la regla de affordance: el rotulo NO tiene caja, NO tiene cursor, y es
   visiblemente mas chico que el valor que rotula. Con las cajas nuevas de arriba, un
   .ge-flabel a 12px/600 competia con ellas y volvia a mezclar "titulo" con "boton". */
.ge-embebido .ge-rail .ge-flabel{ font-size:var(--t-meta); font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--ge-ink2); }
/* La fila-resumen es la excepcion: ahi el .ge-flabel es la etiqueta DENTRO del boton
   ("Plantilla"), no un rotulo de grupo, y en versalitas se leia como otro chip. */
.ge-embebido .ge-rail .ge-rowtext .ge-flabel{ font-size:var(--t-meta); text-transform:none; letter-spacing:0; font-weight:500; color:var(--ge-ink2-caja); }
@media (max-width:768px){
  .ge-embebido .ge-railtop{ padding:14px 20px 10px; }
  .ge-embebido .ge-nav{ padding:10px 20px; }
  .ge-embebido .ge-railscroll{ padding:0 20px 40px; }
  /* Objetivos tactiles: los chips y las filas se tocan con el pulgar, no con un mouse. */
  .ge-embebido .ge-navbtn{ min-height:40px; padding:9px 14px; }
  .ge-embebido .ge-row{ min-height:56px; }
}

/* canvas */
.ge-canvas{ flex:1; background:var(--ge-canvas); display:flex; flex-direction:column; min-width:0; height:100%; }
/* Boton "pantalla completa" del canvas (#ge-canvasfull): requestFullscreen() sobre
   #ge-canvas mismo criterio que .aled en el editor de album (ver esa nota) -- promueve el
   elemento entero sin moverlo de padre, asi que el iframe de la vista previa no se recarga.
   El ::backdrop que el navegador pinta detras es NEGRO por default para cualquier
   elemento; sin esto se veria un marco negro en vez del --ge-canvas de siempre. */
.ge-canvas:fullscreen{ background:var(--ge-canvas); }
.ge-canvas:fullscreen::backdrop{ background:var(--ge-canvas); }
.ge-canvastop{ display:flex; align-items:center; justify-content:space-between; padding:16px 26px; gap:16px; flex-wrap:wrap; }
.ge-ctlabel{ display:flex; align-items:center; gap:9px; color:var(--ge-ink2); font-size:var(--t-meta); font-weight:600; }
.ge-ctlabel .ge-lv{ width:7px; height:7px; border-radius:100px; background:#4a6e50; box-shadow:0 0 0 3px rgba(74,110,80,.2); flex:none; }
.ge-segdark{ display:flex; gap:3px; background:rgba(25,23,20,.07); border-radius:var(--r); padding:3px; }
.ge-segdark .ge-segbtn{ padding:8px 16px; flex:none; }
.ge-stagewrap{ flex:1; display:flex; align-items:center; justify-content:center; padding:6px 26px 30px; min-height:0; }
/* Panel de estilo por texto (Motor v2): hermano de .ge-browser dentro de .ge-stagewrap,
   nunca un popover flotando sobre el nodo -- anclar algo DENTRO de un iframe que se
   reconstruye entero en cada cambio (post()) es perseguir un blanco movil; un panel fijo
   al lado del lienzo no tiene ese problema. */
.ge-txpanel{ width:264px; flex:none; align-self:stretch; max-height:100%; overflow-y:auto; background:var(--ge-bg); border-radius:var(--r); border:1px solid var(--ge-line2); padding:18px; margin-left:18px; box-shadow:0 20px 50px -30px rgba(0,0,0,.35); }
.ge-txhd{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:16px; padding-bottom:14px; border-bottom:1px solid var(--ge-line2); }
.ge-txhd span{ font-size:var(--t-texto); font-weight:700; color:var(--ge-ink); }
.ge-txclose{ width:26px; height:26px; border-radius:100px; display:flex; align-items:center; justify-content:center; color:var(--ge-ink2); font-size:var(--t-meta); flex:none; transition:background-color var(--d-toque) var(--curva-cambia), color var(--d-toque) var(--curva-cambia); }
@media (hover:hover){ .ge-txclose:hover{ background:var(--ge-line2); color:var(--ge-ink); } }
/* Panel cuando lo seleccionado es una FOTO y no un texto. Mismo contenedor (.ge-txpanel),
   otro contenido: el panel es "lo que tocaste", no "los ejes del texto". */
/* La caja de encuadre vive AQUI, en el panel, y ya no en el riel: la foto se toca en la
   vista previa y se ajusta al lado. Lleva la proporcion REAL de su hueco (inline, medida
   del DOM del preview), asi que no hay tamano fijo. */
/* LA caja de encuadre del riel, una sola. La usan la portada (proporcion del hueco, que
   viaja inline porque se mide del preview) y el icono de la app (cuadrado fijo, ver el
   modificador). Antes eran dos bloques casi identicos, uno para el panel de la derecha y
   otro para el icono -- el panel ya no encuadra fotos, asi que ese se fue con el. */
.ge-embebido .ge-rail .ge-cajafoco{ border-radius:var(--r); background-size:cover; background-position:50% 50%; cursor:grab; touch-action:none; display:block; box-shadow:inset 0 0 0 1px var(--ge-line); }
.ge-embebido .ge-rail .ge-cajafoco.arrastrando{ cursor:grabbing; }
.ge-embebido .ge-rail .ge-cajafoco:focus-visible{ outline:2px solid var(--ge-accent); outline-offset:2px; }
/* El icono SIEMPRE es cuadrado, asi que su tamano es fijo en vez de heredar la proporcion. */
.ge-embebido .ge-rail .ge-cajafoco-icono{ width:160px; height:160px; border-radius:var(--r); margin:2px 0 10px; }
/* Fila de miniaturas de las portadas de varias fotos (collage 4, triptico 3, marco 2). El
   numero va encima: sin el, elegir "la tercera" obliga a contar cada vez. */
.ge-embebido .ge-rail .ge-pfrow{ display:flex; gap:8px; margin:0 0 10px; flex-wrap:wrap; }
.ge-embebido .ge-rail .ge-pfmini{ width:52px; height:52px; border-radius:var(--r); background-size:cover; background-position:center; background-color:var(--ge-prev); border:1px solid var(--ge-line); position:relative; padding:0; flex:none; transition:border-color var(--d-toque) var(--curva-cambia), box-shadow var(--d-toque) var(--curva-cambia); }
@media (hover:hover){ .ge-embebido .ge-rail .ge-pfmini:hover{ border-color:var(--ge-ink3); } }
.ge-embebido .ge-rail .ge-pfmini.on{ box-shadow:0 0 0 2px var(--ge-bg),0 0 0 4px var(--ge-ink); border-color:transparent; }
.ge-embebido .ge-rail .ge-pfmini span{ position:absolute; left:3px; top:3px; min-width:16px; height:16px; border-radius:var(--r); background:rgba(0,0,0,.62); color:#fff; font-size:var(--t-eti); font-weight:600; line-height:16px; text-align:center; }
/* Acciones del bloque: CON caja, no enlaces de texto -- en el riel `.ge-rbtn` es un enlace
   a proposito, y estas dos son acciones de verdad que tienen que verse tocables. */
.ge-embebido .ge-rail .ge-pfacc{ display:flex; gap:8px; margin-bottom:10px; }
.ge-embebido .ge-rail .ge-pfbtn{ flex:1; padding:12px; min-height:44px; border-radius:var(--r); border:1px solid var(--ge-line); background:var(--ge-prev); color:var(--ge-ink); font-size:var(--t-meta); font-weight:600; text-align:center; transition:border-color var(--d-toque) var(--curva-cambia), color var(--d-toque) var(--curva-cambia); }
@media (hover:hover){ .ge-embebido .ge-rail .ge-pfbtn:hover{ border-color:var(--ge-ink3); } }
.ge-embebido .ge-rail .ge-pfbtn-ink{ background:var(--ge-ink); color:var(--ge-bg); border-color:var(--ge-ink); }
@media (hover:hover){ .ge-embebido .ge-rail .ge-pfbtn-ink:hover{ opacity:.88; } }
/* Rasgado sin arrastre de mouse (el punto de clic vive DENTRO del iframe, la escritura
   pasa por el padre): el nudge cruza esa frontera con un click a la vez, en vez de
   perseguir coordenadas de un frame ajeno. */
.ge-nudgepad{ display:grid; grid-template-columns:repeat(3,34px); grid-template-rows:repeat(3,34px); gap:4px; justify-content:center; margin:6px 0 2px; }
.ge-nudgebtn{ background:var(--ge-line2); border-radius:var(--r); display:flex; align-items:center; justify-content:center; color:var(--ge-ink); font-size:var(--t-texto); transition:background-color var(--d-toque) var(--curva-cambia), color var(--d-toque) var(--curva-cambia); }
@media (hover:hover){ .ge-nudgebtn:hover{ background:var(--ge-line); } }
.ge-nudge-arriba{ grid-column:2; grid-row:1; }
.ge-nudge-izq{ grid-column:1; grid-row:2; }
.ge-nudge-centro{ grid-column:2; grid-row:2; color:var(--ge-accent); }
.ge-nudge-der{ grid-column:3; grid-row:2; }
.ge-nudge-abajo{ grid-column:2; grid-row:3; }
.ge-browser{ width:100%; max-width:1120px; height:100%; background:#fff; border-radius:var(--r) var(--r) var(--r) var(--r); box-shadow:0 40px 90px -40px rgba(0,0,0,.4); display:flex; flex-direction:column; overflow:hidden; border:1px solid rgba(0,0,0,.08); }
.ge-bbar{ height:44px; flex:none; display:flex; align-items:center; gap:14px; padding:0 16px; background:#f2efe9; border-bottom:1px solid var(--ge-line2); }
.ge-dots{ display:flex; gap:7px; }
.ge-dots i{ width:11px; height:11px; border-radius:100px; background:#d6d0c6; display:block; }
.ge-url{ flex:1; background:#fff; border-radius:var(--r); height:26px; display:flex; align-items:center; padding:0 12px; font-size:var(--t-meta); color:var(--ge-ink2); gap:7px; overflow:hidden; white-space:nowrap; text-overflow:ellipsis; }
.ge-bbody{ flex:1; min-height:0; overflow:hidden; position:relative; }
.ge-bbody iframe{ position:absolute; inset:0; width:100%; height:100%; border:0; }
@media (max-width:1000px){
  .geditor{ flex-direction:column; }
  .ge-rail{ width:100%; height:auto; max-height:56vh; border-right:0; border-bottom:1px solid var(--ge-line2); }
  .ge-canvas{ height:auto; flex:1; }
  .ge-stagewrap{ flex-wrap:wrap; overflow-y:auto; }
  .ge-txpanel{ width:100%; margin-left:0; margin-top:14px; align-self:auto; max-height:none; }
}

/* ---------- PORTAL-DISEÑO (#/portal-diseno): divergencias sobre el editor embebido ----
   Todo lleva .ge-embebido.ge-portal (galeria monta sin .ge-portal, no puede matchear).
   Existe porque el riel del portal NO tiene la forma para la que se escribieron las
   reglas compartidas de arriba: su railtop lleva 5 hijos apilables (miga, titulo,
   ambito, quitar personalizacion, savestate) donde galeria lleva 2 en fila. Con el flex
   heredado, el ambito desbordaba ~366px medidos y el editor entero se volvia un scroller
   horizontal que #view recortaba -- eso era el "preview cortado" que se veia. */
.ge-embebido.ge-portal .ge-railtop{ display:block; }
.ge-embebido.ge-portal .ge-railtop .ge-crumb{ margin-bottom:10px; }
.ge-embebido.ge-portal .ge-railtop .ge-galname{ margin:0 0 10px; }
/* El ambito ocupa el ancho del riel y sus pastillas truncan: el nombre del cliente entra
   en el texto ("Solo {nombre}") y no se puede acotar en el origen. */
.ge-embebido.ge-portal .ge-railtop .ge-segdark{ display:flex; width:100%; box-sizing:border-box; }
.ge-embebido.ge-portal .ge-railtop .ge-segdark .ge-segbtn{ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; text-align:center; }
.ge-embebido.ge-portal .ge-railtop .ge-savestate{ margin-top:6px; text-align:left; }
/* Sin esto, "Movil" heredaba height:100% de .ge-browser y pintaba una losa negra a toda
   la altura del lienzo en vez de un telefono. Misma geometria que tenia el .ge-phoneframe
   que este editor dejo muerto al reescribirse; la regla compartida .ge-w-mobile no se toca. */
.ge-embebido.ge-portal .ge-browser.ge-w-mobile{ height:min(100%,780px); }
/* Las ayudas del riel: .ge-cs solo tiene regla dentro de .ge-card, y aqui se usan sueltas. */
.ge-embebido.ge-portal .ge-rail .ge-cs{ font-size:var(--t-meta); line-height:1.5; color:var(--ge-ink2); }
/* Los fondos rgba(25,23,20,...) de estos dos desaparecen sobre el riel oscuro. */
:root[data-theme="dark"] .ge-portal .ge-sechd .ge-ix{ background:rgba(255,255,255,.08); }
:root[data-theme="dark"] .ge-portal .ge-segdark{ background:rgba(255,255,255,.07); }

/* ============================================================================
   CALENDARIO (rediseño, handoff design_handoff_calendario) — overlay de pantalla
   completa, mismo patron que .ced/.geditor (position:fixed;inset:0;z-index:40,
   namespace propio de variables). Oscuro FIJO como .ced (no cambia con el tema
   claro/oscuro de la app: es el mismo patron editorial oscuro en los 3 handoffs).
   Todo clase estructural va prefijada cf- para no chocar con .btn/.modal/.label/
   .inp/.detail/.scrim/etc que ya son clases globales de esta app; los modificadores
   de estado cortos (on/off/today/wknd/blocked/sel/done/dragging/conflict/short/out/
   hasSel/danger/accent/ico/warn) se quedan sin prefijo pero SIEMPRE compuestos con
   una clase cf- (nunca sueltos), igual que .ced-prow.ok / .ced-pact.danger.
   ============================================================================ */
/* .calfull sigue el mismo patron que .aled (editor de albumes, ver esa nota mas abajo):
   position:absolute;inset:0 anclado a #view (no position:fixed a la ventana completa),
   asi el chat de Xarpie -que vive a la izquierda de #view, no debajo- nunca queda tapado.
   Las reglas compartidas (.main columna flex, #view:has(...) sin max-width/padding,
   .main:has(...) sin scroll propio) estan declaradas UNA vez junto a .aled y las
   extienden ambos selectores. */
.calfull{
  /* Tokens en modo CLARO por default (mismo criterio que :root de arriba: sin atributo
     de tema = claro). La mayoria son alias de los tokens reales de la app (--bone/--paper/
     --ink/--accent/--deep) para que un retoque de paleta futuro los alcance solo; los que
     no tienen equivalente (ink3, accent2, ok/gold/warn) llevan su propio hex, elegido para
     >=4.5:1 sobre --paper (mismo criterio AA que --muted, ver la nota de arriba en :root).
     --cal-mix es el truco de las rgba(var(--cal-mix),X) de mas abajo: "255,255,255" en
     oscuro (aclarar hacia blanco) y "0,0,0" en claro (oscurecer hacia tinta) -- shared por
     TODOS los estados hover/realce que antes eran rgba(255,255,255,X) fijo y se volvian
     invisibles sobre un panel claro. */
  --cal-bg:var(--bone); --cal-panel:var(--paper); --cal-panel2:#e8e2d4;
  --cal-line:var(--line2); --cal-line2:var(--hair); --cal-mix:0,0,0;
  --cal-ink:var(--ink); --cal-ink2:var(--muted); --cal-ink3:#8a8577;
  --cal-accent:var(--accent); --cal-accent2:#a8532e; --cal-ok:#4f7a45; --cal-gold:#a67a2e; --cal-warn:#b8503a;
  --cal-warnbg:rgba(184,80,58,.1); --cal-warnbd:rgba(184,80,58,.28); --cal-warntx:#7a3826;
  --cal-serif:'Instrument Sans',system-ui,sans-serif;
  position:absolute; inset:0; z-index:40; display:flex; flex-direction:column;
  background:var(--cal-bg); color:var(--cal-ink); font-family:'Instrument Sans',var(--sans);
  -webkit-font-smoothing:antialiased; overflow:hidden; padding:20px 22px 0;
  container-type:inline-size; /* los breakpoints del calendario son por su propio ancho, no el de la ventana -- el chat de Xarpie se lo puede comer */
}
/* Modo oscuro: los valores ORIGINALES del handoff, sin cambiar un pixel para quien ya
   usaba oscuro (que es casi todo el mundo hoy) -- ver la nota de arriba de por que esto
   antes estaba fijo aqui mismo sin la condicion de tema. */
:root[data-theme="dark"] .calfull{
  --cal-bg:#262624; --cal-panel:#30302e; --cal-panel2:#383835;
  --cal-line:rgba(255,255,255,.09); --cal-line2:rgba(255,255,255,.05); --cal-mix:255,255,255;
  --cal-ink:#f5f4ee; --cal-ink2:#bdbbb0; --cal-ink3:#84827b;
  --cal-accent:#d97757; --cal-accent2:#bd5d3a; --cal-ok:#93a986; --cal-gold:#cfa15e; --cal-warn:#d2694f;
  --cal-warnbg:rgba(210,105,79,.12); --cal-warnbd:rgba(210,105,79,.3); --cal-warntx:#f0cfc4;
}
.calfull button{ font-family:inherit; cursor:pointer; border:none; background:none; color:inherit; text-align:left; }
.calfull input,.calfull textarea,.calfull select{ font-family:inherit; }
.calfull select.cf-inp{ appearance:none; background-image:linear-gradient(45deg,transparent 50%,var(--cal-ink3) 50%),linear-gradient(135deg,var(--cal-ink3) 50%,transparent 50%); background-position:calc(100% - 15px) 50%,calc(100% - 10px) 50%; background-size:5px 5px,5px 5px; background-repeat:no-repeat; padding-right:30px; }
.cf-label{ text-transform:uppercase; letter-spacing:.2em; font-size:var(--t-eti); font-weight:600; color:var(--cal-ink3); }

/* ---- header / alta rapida / filtros ---- */
.cf-hd{ display:flex; align-items:flex-end; justify-content:space-between; gap:18px; flex-wrap:wrap; flex:none; padding-bottom:14px; }
.cf-eyebrow{ text-transform:uppercase; letter-spacing:.2em; font-size:var(--t-eti); font-weight:600; color:var(--cal-accent); }
.cf-htitle{ font-family:var(--cal-serif); font-size:var(--t-saludo); font-weight:400; letter-spacing:-.01em; line-height:1; margin:8px 0 0; }
.cf-hsub{ font-size:var(--t-meta); color:var(--cal-ink3); margin-top:6px; display:flex; align-items:center; gap:9px; flex-wrap:wrap; }
.cf-warnpill{ color:var(--cal-warn); font-weight:600; display:inline-flex; align-items:center; gap:5px; }
.cf-hright{ display:flex; align-items:center; gap:7px; flex-wrap:wrap; }
.cf-nav{ display:inline-flex; align-items:center; gap:2px; border:1px solid var(--cal-line); border-radius:var(--r); padding:3px; }
.cf-nav button{ height:29px; padding:0 10px; border-radius:var(--r); color:var(--cal-ink2); display:inline-flex; align-items:center; justify-content:center; font-size:var(--t-meta); font-weight:600; transition:.14s; }
@media (hover:hover){ .cf-nav button:hover{ background:rgba(var(--cal-mix),.07); color:var(--cal-ink); } }
.cf-seg{ display:inline-flex; background:var(--cal-panel); border:1px solid var(--cal-line); border-radius:var(--r); padding:3px; gap:2px; }
.cf-seg button{ height:29px; padding:0 14px; border-radius:var(--r); font-size:var(--t-meta); font-weight:600; color:var(--cal-ink3); transition:.14s; }
@media (hover:hover){ .cf-seg button:hover{ color:var(--cal-ink); } }
.cf-seg button.on{ background:var(--cal-accent); color:#fff; }
.cf-btn{ display:inline-flex; align-items:center; gap:7px; height:35px; padding:0 15px; border-radius:var(--r); border:1px solid var(--cal-line); font-size:var(--t-meta); font-weight:600; color:var(--cal-ink); transition:.14s; white-space:nowrap; }
@media (hover:hover){ .cf-btn:hover{ border-color:var(--cal-ink3); } }
.cf-btn.accent{ background:var(--cal-accent); border-color:var(--cal-accent); color:#fff; }
@media (hover:hover){ .cf-btn.accent:hover{ background:var(--cal-accent2); } }
.cf-btn.ico{ width:35px; padding:0; justify-content:center; }
.cf-btn.sm{ height:28px; padding:0 11px; font-size:var(--t-meta); }
.cf-search{ display:inline-flex; align-items:center; gap:8px; height:35px; padding:0 13px; border-radius:var(--r); border:1px solid var(--cal-line); background:var(--cal-panel); color:var(--cal-ink3); transition:.14s; min-width:180px; }
.cf-search:focus-within{ border-color:var(--cal-accent); }
.cf-search input{ background:none; border:none; outline:none; color:var(--cal-ink); font-size:var(--t-meta); width:100%; }
.cf-search input::placeholder{ color:var(--cal-ink3); }
.cf-search button{ color:var(--cal-ink3); display:flex; }
.cf-qadd{ display:flex; align-items:center; gap:9px; flex:none; margin-bottom:12px; background:var(--cal-panel); border:1px solid var(--cal-line); border-radius:var(--r); padding:0 6px 0 15px; height:40px; transition:.14s; }
.cf-qadd:focus-within{ border-color:var(--cal-accent); }
.cf-qadd input{ flex:1; background:none; border:none; outline:none; color:var(--cal-ink); font-size:var(--t-texto); }
.cf-qadd input::placeholder{ color:var(--cal-ink3); }
.cf-qhint{ font-size:var(--t-eti); color:var(--cal-ink3); white-space:nowrap; }
.cf-filters{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; flex:none; padding-bottom:12px; border-bottom:1px solid var(--cal-line); }
.cf-fchip{ display:inline-flex; align-items:center; gap:7px; height:28px; padding:0 11px; border-radius:var(--r); border:1px solid var(--cal-line); font-size:var(--t-meta); font-weight:600; color:var(--cal-ink3); transition:.14s; }
@media (hover:hover){ .cf-fchip:hover{ color:var(--cal-ink); border-color:var(--cal-ink3); } }
.cf-fchip.on{ color:var(--cal-ink); border-color:transparent; background:rgba(var(--cal-mix),.07); }
.cf-fchip.warn{ color:var(--cal-warn); border-color:rgba(210,105,79,.4); }
.cf-fdot{ width:8px; height:8px; border-radius:100px; flex:none; }
.cf-fn{ font-variant-numeric:tabular-nums; opacity:.6; font-size:var(--t-meta); }
.cf-fsep{ width:1px; height:19px; background:var(--cal-line); margin:0 3px; }

/* ---- body: riel / grid principal / detalle ---- */
.cf-body{ flex:1; min-height:0; display:flex; gap:14px; padding:14px 0 18px; }
.cf-rail{ width:214px; flex:none; display:flex; flex-direction:column; gap:12px; overflow-y:auto; }
.cf-rcard{ background:var(--cal-panel); border:1px solid var(--cal-line); border-radius:var(--r); padding:13px; }
.cf-rtitle{ font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--cal-ink3); font-weight:600; margin-bottom:11px; display:flex; align-items:center; justify-content:space-between; }
.cf-rtitle button{ color:var(--cal-ink3); display:flex; }
@media (hover:hover){ .cf-rtitle button:hover{ color:var(--cal-ink); } }
.cf-mini{ display:grid; grid-template-columns:repeat(7,1fr); gap:1px; }
.cf-mh{ font-size:8.5px; color:var(--cal-ink3); text-align:center; font-weight:600; padding-bottom:5px; }
.cf-mid{ aspect-ratio:1; border-radius:var(--r); display:flex; flex-direction:column; align-items:center; justify-content:center; font-size:var(--t-eti); font-variant-numeric:tabular-nums; color:var(--cal-ink2); transition:.12s; gap:1px; position:relative; }
@media (hover:hover){ .cf-mid:hover{ background:rgba(var(--cal-mix),.08); color:var(--cal-ink); } }
.cf-mid.out{ color:var(--cal-ink3); opacity:.45; }
.cf-mid.today{ background:var(--cal-accent); color:#fff; font-weight:700; }
.cf-mid.inview{ background:rgba(var(--cal-mix),.07); }
.cf-mdd{ width:3px; height:3px; border-radius:100px; background:var(--cal-accent); }
.cf-mid.today .cf-mdd{ background:#fff; }
.cf-callist{ display:flex; flex-direction:column; gap:2px; }
.cf-calrow{ display:flex; align-items:center; gap:9px; padding:7px 6px; border-radius:var(--r); font-size:var(--t-meta); transition:.12s; width:100%; }
@media (hover:hover){ .cf-calrow:hover{ background:rgba(var(--cal-mix),.05); } }
.cf-cbox{ width:14px; height:14px; border-radius:4px; flex:none; border:1.5px solid; display:flex; align-items:center; justify-content:center; color:#221f1c; }
.cf-cnm{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cf-calrow.off{ color:var(--cal-ink3); }
.cf-cn{ font-size:var(--t-eti); color:var(--cal-ink3); font-variant-numeric:tabular-nums; }
.cf-avrow{ display:flex; align-items:baseline; justify-content:space-between; gap:8px; padding:6px 0; font-size:var(--t-meta); color:var(--cal-ink2); border-bottom:1px solid var(--cal-line2); }
.cf-avrow:last-child{ border-bottom:none; }
.cf-avrow b{ font-family:var(--cal-serif); font-size:var(--t-texto); font-weight:400; color:var(--cal-ink); letter-spacing:-.01em }
.cf-freelist{ display:flex; flex-wrap:wrap; gap:5px; margin-top:9px; }
.cf-freechip{ font-size:var(--t-meta); font-weight:600; color:var(--cal-ok); border:1px solid rgba(147,169,134,.35); border-radius:var(--r); padding:4px 9px; transition:.12s; }
@media (hover:hover){ .cf-freechip:hover{ background:rgba(147,169,134,.14); } }
.cf-main{ flex:1; min-width:0; display:flex; flex-direction:column; background:var(--cal-panel); border:1px solid var(--cal-line); border-radius:var(--r); overflow:hidden; }

/* ---- mes ---- */
.cf-mhead{ display:grid; grid-template-columns:var(--mc,repeat(7,1fr)); flex:none; border-bottom:1px solid var(--cal-line); }
.cf-mhead div{ padding:11px; font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--cal-ink3); font-weight:600; text-align:center; }
.cf-mcells{ flex:1; min-height:0; display:grid; grid-template-columns:var(--mc,repeat(7,1fr)); grid-auto-rows:1fr; overflow-y:auto; }
.cf-mcell{ min-height:98px; padding:6px; border-top:1px solid var(--cal-line2); border-right:1px solid var(--cal-line2); display:flex; flex-direction:column; gap:3px; overflow:hidden; transition:.12s; }
.cf-mcell.lastcol{ border-right:none; }
.cf-mcell.firstrow{ border-top:none; }
@media (hover:hover){ .cf-mcell:hover{ background:rgba(var(--cal-mix),.022); } }
.cf-mcell.out{ background:var(--deep); }
.cf-mcell.out .cf-mnum{ color:var(--cal-ink3); opacity:.6; }
.cf-mcell.wknd{ background:rgba(207,161,94,.03); }
.cf-mcell.blocked{ background:repeating-linear-gradient(45deg,rgba(210,105,79,.09) 0 7px,transparent 7px 14px); }
.cf-mctop{ display:flex; align-items:center; justify-content:space-between; gap:6px; }
.cf-mnum{ width:24px; height:24px; border-radius:100px; display:flex; align-items:center; justify-content:center; font-size:var(--t-meta); font-weight:600; color:var(--cal-ink2); font-variant-numeric:tabular-nums; transition:.12s; }
@media (hover:hover){ .cf-mnum:hover{ background:rgba(var(--cal-mix),.09); color:var(--cal-ink); } }
.cf-mnum.today{ background:var(--cal-accent); color:#fff; }
.cf-mdots{ display:flex; gap:3px; }
.cf-mchip{ display:flex; align-items:center; gap:5px; padding:3px 6px; border-radius:var(--r); font-size:var(--t-meta); line-height:1.25; border-left:2.5px solid; overflow:hidden; white-space:nowrap; transition:.12s; width:100%; }
@media (hover:hover){ .cf-mchip:hover{ filter:brightness(1.35); } }
.cf-mchip.done{ opacity:.5; }
.cf-ctime{ font-size:var(--t-eti); font-variant-numeric:tabular-nums; opacity:.75; flex:none; }
.cf-ctxt{ overflow:hidden; text-overflow:ellipsis; }
.cf-mmore{ font-size:var(--t-eti); color:var(--cal-ink3); font-weight:600; padding:1px 6px; }
@media (hover:hover){ .cf-mmore:hover{ color:var(--cal-accent); } }

/* ---- semana / dia ---- */
.cf-wwrap{ flex:1; min-height:0; display:flex; flex-direction:column; }
.cf-wbody{ flex:1; min-height:0; overflow-y:auto; }
.cf-wtop{ position:sticky; top:0; z-index:12; background:var(--cal-panel); }
.cf-wrow{ display:grid; grid-template-columns:var(--wc); }
.cf-whead{ border-bottom:1px solid var(--cal-line); background:var(--cal-panel); }
.cf-wgut{ border-right:1px solid var(--cal-line2); }
.cf-wdh{ padding:9px 6px 10px; text-align:center; border-right:1px solid var(--cal-line2); display:flex; flex-direction:column; gap:2px; align-items:center; transition:.12s; position:relative; }
.cf-wdh:last-child{ border-right:none; }
@media (hover:hover){ .cf-wdh:hover{ background:rgba(var(--cal-mix),.03); } }
.cf-wdn{ font-size:var(--t-eti); letter-spacing:.15em; text-transform:uppercase; color:var(--cal-ink3); font-weight:600; }
.cf-wdd{ font-family:var(--cal-serif); font-size:var(--t-sub); font-weight:400; line-height:1; width:30px; height:30px; border-radius:100px; display:flex; align-items:center; justify-content:center; letter-spacing:-.01em }
.cf-wdh.today .cf-wdn{ color:var(--cal-accent); }
.cf-wdh.today .cf-wdd{ background:var(--cal-accent); color:#fff; font-size:var(--t-sub); }
.cf-wdh.wknd{ background:rgba(207,161,94,.03); }
.cf-bmark{ position:absolute; top:5px; right:6px; font-size:8.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--cal-warn); font-weight:700; }
.cf-wad{ border-bottom:1px solid var(--cal-line); background:var(--deep); }
.cf-wadlbl{ padding:8px 7px; border-right:1px solid var(--cal-line2); display:flex; flex-direction:column; gap:3px; align-items:flex-start; }
.cf-l1{ font-size:8.5px; letter-spacing:.1em; text-transform:uppercase; color:var(--cal-ink3); font-weight:600; white-space:nowrap; }
.cf-wadlbl button{ font-size:var(--t-eti); color:var(--cal-accent); font-weight:600; white-space:nowrap; }
.cf-wadc{ padding:5px; border-right:1px solid var(--cal-line2); display:flex; flex-direction:column; gap:3px; min-width:0; }
.cf-wadc:last-child{ border-right:none; }
.cf-adchip{ display:flex; align-items:center; gap:5px; padding:3px 6px; border-radius:var(--r); font-size:var(--t-meta); line-height:1.25; border-left:2.5px solid; white-space:nowrap; overflow:hidden; transition:.12s; width:100%; }
@media (hover:hover){ .cf-adchip:hover{ filter:brightness(1.35); } }
.cf-adchip.done{ opacity:.5; }
.cf-adchip span{ overflow:hidden; text-overflow:ellipsis; }
.cf-wtimed{ position:relative; min-height:100%; }
.cf-wtimes{ border-right:1px solid var(--cal-line2); }
.cf-thr{ height:var(--hh); position:relative; }
.cf-thr span{ position:absolute; top:-7px; right:8px; font-size:var(--t-eti); color:var(--cal-ink3); font-variant-numeric:tabular-nums; letter-spacing:.03em; }
.cf-thr:first-child span{ top:2px; }
.cf-wcol{ position:relative; border-right:1px solid var(--cal-line2); background-image:linear-gradient(to bottom,var(--cal-line2) 1px,transparent 1px); background-size:100% var(--hh); }
.cf-wcol:last-child{ border-right:none; }
.cf-wcol.wknd{ background-color:rgba(207,161,94,.025); }
.cf-wcol.today{ background-color:rgba(217,119,87,.045); }
.cf-wcol.blocked{ background-image:repeating-linear-gradient(45deg,rgba(210,105,79,.07) 0 8px,transparent 8px 16px),linear-gradient(to bottom,var(--cal-line2) 1px,transparent 1px); }
.cf-ev{ position:absolute; border-radius:var(--r); padding:4px 7px; font-size:var(--t-meta); line-height:1.25; overflow:hidden; border-left:2.5px solid; display:flex; flex-direction:column; gap:1px; transition:filter .12s; min-height:19px; cursor:grab; user-select:none; z-index:3; }
@media (hover:hover){ .cf-ev:hover{ filter:brightness(1.35); z-index:6; } }
.cf-ev.sel{ outline:1.5px solid var(--cal-ink); outline-offset:-1px; z-index:7; }
.cf-ev.conflict{ box-shadow:inset 0 0 0 1.5px var(--cal-warn); }
.cf-ev.dragging{ cursor:grabbing; opacity:.85; z-index:20; box-shadow:0 10px 26px -8px rgba(0,0,0,.7); }
.cf-evt{ font-size:var(--t-eti); font-variant-numeric:tabular-nums; opacity:.8; display:flex; align-items:center; gap:4px; }
.cf-evn{ font-weight:600; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cf-ev.short{ flex-direction:row; align-items:center; gap:6px; padding:2px 7px; }
.cf-evrz{ position:absolute; left:0; right:0; bottom:0; height:7px; cursor:ns-resize; }
.cf-evrz::after{ content:""; position:absolute; left:50%; transform:translateX(-50%); bottom:2px; width:16px; height:2px; border-radius:2px; background:rgba(255,255,255,.3); opacity:0; transition:.12s; }
@media (hover:hover){ .cf-ev:hover .cf-evrz::after{ opacity:1; } }
.cf-buf{ position:absolute; border-radius:var(--r); background:repeating-linear-gradient(45deg,rgba(var(--cal-mix),.09) 0 5px,transparent 5px 10px); pointer-events:none; z-index:1; }
.cf-nowl{ position:absolute; left:0; right:0; height:1.5px; background:var(--cal-accent); z-index:9; pointer-events:none; }
.cf-nowl::before{ content:""; position:absolute; left:-4px; top:-3px; width:8px; height:8px; border-radius:100px; background:var(--cal-accent); }

/* ---- lista lateral de vista Dia ---- */
.cf-dayview{ flex:1; min-height:0; display:grid; grid-template-columns:1fr 248px; }
.cf-daylist{ border-left:1px solid var(--cal-line); display:flex; flex-direction:column; min-height:0; background:var(--deep); }
.cf-dlhd{ padding:13px 15px 11px; border-bottom:1px solid var(--cal-line2); flex:none; }
.cf-dlt{ font-family:var(--cal-serif); font-size:var(--t-campo); font-weight:400; margin-top:4px; letter-spacing:-.01em }
.cf-dlbody{ flex:1; min-height:0; overflow-y:auto; padding:11px; }
.cf-dlgroup{ margin-bottom:14px; }
.cf-dlgl{ font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--cal-ink3); font-weight:600; margin:0 4px 8px; }
.cf-dli{ display:flex; align-items:flex-start; gap:8px; padding:8px 9px; border-radius:var(--r); border:1px solid var(--cal-line); margin-bottom:6px; transition:.12s; width:100%; }
@media (hover:hover){ .cf-dli:hover{ border-color:var(--cal-ink3); } }
.cf-dli.sel{ border-color:var(--cal-accent); background:rgba(217,119,87,.07); }
.cf-dli.done .cf-dlin{ text-decoration:line-through; color:var(--cal-ink3); }
.cf-dlb{ width:3px; align-self:stretch; border-radius:var(--r); flex:none; min-height:24px; }
.cf-dlm{ flex:1; min-width:0; }
.cf-dlin{ font-size:var(--t-meta); font-weight:600; line-height:1.35; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cf-dlmeta{ font-size:var(--t-eti); color:var(--cal-ink3); margin-top:2px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cf-dlchk{ width:18px; height:18px; border-radius:100px; border:1.5px solid var(--cal-line); display:flex; align-items:center; justify-content:center; color:transparent; flex:none; transition:.12s; margin-top:1px; }
@media (hover:hover){ .cf-dlchk:hover{ border-color:var(--cal-ok); color:var(--cal-ok); } }
.cf-dli.done .cf-dlchk{ background:var(--cal-ok); border-color:var(--cal-ok); color:#1d1b17; }
.cf-dlempty{ font-size:var(--t-meta); color:var(--cal-ink3); padding:8px 4px; line-height:1.5; }

/* ---- panel de detalle ---- */
.cf-detail{ width:290px; flex:none; background:var(--cal-panel); border:1px solid var(--cal-line); border-radius:var(--r); display:flex; flex-direction:column; overflow:hidden; }
.cf-dhd{ padding:15px 16px 14px; border-bottom:1px solid var(--cal-line2); display:flex; align-items:flex-start; gap:10px; flex:none; }
.cf-dbar{ width:3px; align-self:stretch; border-radius:var(--r); flex:none; }
.cf-dm{ flex:1; min-width:0; }
.cf-dt{ font-family:var(--cal-serif); font-size:var(--t-campo); font-weight:400; line-height:1.15; margin-top:3px; letter-spacing:-.01em }
.cf-xb{ width:28px; height:28px; border-radius:var(--r); border:1px solid var(--cal-line); display:flex; align-items:center; justify-content:center; color:var(--cal-ink2); flex:none; }
@media (hover:hover){ .cf-xb:hover{ border-color:var(--cal-ink3); color:var(--cal-ink); } }
.cf-dbody{ flex:1; min-height:0; overflow-y:auto; padding:15px 16px 20px; }
.cf-fgrp{ margin-bottom:14px; }
.cf-flbl{ display:block; font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--cal-ink3); font-weight:600; margin-bottom:6px; }
.cf-inp{ width:100%; background:var(--deep); border:1px solid var(--cal-line); border-radius:var(--r); padding:8px 11px; font-size:var(--t-meta); color:var(--cal-ink); outline:none; transition:.14s; }
.cf-inp:focus{ border-color:var(--cal-accent); }
.cf-inp:disabled{ opacity:.55; cursor:not-allowed; }
textarea.cf-inp{ resize:vertical; min-height:54px; line-height:1.5; }
.cf-two{ display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.cf-typegrid{ display:flex; flex-wrap:wrap; gap:5px; }
.cf-tpill{ display:inline-flex; align-items:center; gap:6px; padding:5px 9px; border-radius:var(--r); border:1px solid var(--cal-line); font-size:var(--t-meta); font-weight:600; color:var(--cal-ink3); transition:.12s; }
@media (hover:hover){ .cf-tpill:hover{ color:var(--cal-ink); } }
.cf-tpill.on{ color:var(--cal-ink); border-color:transparent; }
.cf-tgl{ width:37px; height:21px; border-radius:var(--r); background:rgba(var(--cal-mix),.16); position:relative; transition:.16s; flex:none; }
.cf-tgl.on{ background:var(--cal-ok); }
.cf-tgl::after{ content:""; position:absolute; top:2.5px; left:2.5px; width:16px; height:16px; border-radius:3px; background:#fff; transition:.16s; }
.cf-tgl.on::after{ transform:translateX(16px); }
.cf-trow{ display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:var(--t-meta); padding:2px 0; }
.cf-warnbox{ display:flex; gap:9px; padding:11px 12px; border-radius:var(--r); background:var(--cal-warnbg); border:1px solid var(--cal-warnbd); margin-bottom:14px; font-size:var(--t-meta); line-height:1.5; color:var(--cal-warntx); }
.cf-warnbox b{ color:var(--cal-ink); display:block; margin-bottom:2px; font-size:var(--t-meta); }
.cf-dacts{ display:flex; flex-wrap:wrap; gap:6px; padding-top:6px; border-top:1px solid var(--cal-line2); margin-top:4px; }
.cf-dact{ flex:1; min-width:calc(50% - 3px); justify-content:center; height:32px; padding:0 9px; border-radius:var(--r); border:1px solid var(--cal-line); font-size:var(--t-meta); font-weight:600; color:var(--cal-ink2); display:inline-flex; align-items:center; gap:5px; transition:.12s; }
@media (hover:hover){ .cf-dact:hover{ border-color:var(--cal-ink3); color:var(--cal-ink); } }
@media (hover:hover){ .cf-dact.danger:hover{ border-color:var(--cal-accent); color:var(--cal-accent); } }
.cf-dnone{ flex:1; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; padding:26px 20px; color:var(--cal-ink3); gap:12px; overflow-y:auto; }
.cf-di{ width:44px; height:44px; border-radius:100px; border:1px dashed var(--cal-line); display:flex; align-items:center; justify-content:center; }
.cf-dnone p{ font-size:var(--t-meta); line-height:1.55; margin:0; }
.cf-dnstats{ width:100%; display:flex; flex-direction:column; gap:6px; margin-top:4px; }
.cf-dnstat{ display:flex; align-items:center; justify-content:space-between; gap:10px; padding:8px 11px; border:1px solid var(--cal-line); border-radius:var(--r); font-size:var(--t-meta); color:var(--cal-ink2); }
.cf-dnstat b{ font-family:var(--cal-serif); font-size:var(--t-texto); font-weight:400; color:var(--cal-ink); letter-spacing:-.01em }
.cf-kbd{ display:inline-flex; align-items:center; justify-content:center; min-width:18px; height:18px; padding:0 5px; border-radius:var(--r); border:1px solid var(--cal-line); background:var(--deep); font-size:var(--t-eti); font-weight:700; color:var(--cal-ink2); font-family:ui-monospace,monospace; }

/* ---- modal de ajustes ---- */
.cf-scrim{ position:fixed; inset:0; background:rgba(0,0,0,.62); backdrop-filter:blur(3px); display:flex; align-items:center; justify-content:center; z-index:61; padding:26px; }
.cf-modal{ width:600px; max-width:100%; max-height:88vh; overflow-y:auto; background:var(--cal-panel); border:1px solid var(--cal-line); border-radius:var(--r); box-shadow:0 40px 100px -30px rgba(0,0,0,.8); }
.cf-mhd{ display:flex; align-items:flex-start; justify-content:space-between; gap:16px; padding:22px 24px 16px; border-bottom:1px solid var(--cal-line2); position:sticky; top:0; background:var(--cal-panel); z-index:2; }
.cf-mhd h3{ font-family:var(--cal-serif); font-size:var(--t-titulo); font-weight:400; margin:5px 0 0; letter-spacing:-.01em }
.cf-mbody{ padding:20px 24px 24px; }
.cf-sgroup{ padding-bottom:18px; margin-bottom:18px; border-bottom:1px solid var(--cal-line2); }
.cf-sgroup:last-child{ border-bottom:none; margin-bottom:0; padding-bottom:0; }
.cf-sgl{ font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--cal-accent); font-weight:600; margin-bottom:14px; }
.cf-srow{ display:flex; align-items:center; justify-content:space-between; gap:16px; padding:9px 0; }
.cf-sinfo{ min-width:0; }
.cf-sinfo b{ font-size:var(--t-texto); font-weight:600; display:block; }
.cf-sinfo span{ font-size:var(--t-meta); color:var(--cal-ink3); line-height:1.45; display:block; margin-top:2px; }
.cf-sctl{ flex:none; }
.cf-seg2{ display:inline-flex; background:var(--deep); border:1px solid var(--cal-line); border-radius:var(--r); padding:3px; gap:2px; }
.cf-seg2 button{ padding:6px 11px; border-radius:var(--r); font-size:var(--t-meta); font-weight:600; color:var(--cal-ink3); transition:.12s; white-space:nowrap; }
.cf-seg2 button.on{ background:var(--cal-accent); color:#fff; }
.cf-stepper{ display:inline-flex; align-items:center; gap:2px; background:var(--deep); border:1px solid var(--cal-line); border-radius:var(--r); padding:3px; }
.cf-stepper button{ width:27px; height:26px; border-radius:var(--r); display:flex; align-items:center; justify-content:center; color:var(--cal-ink2); font-size:var(--t-texto); font-weight:600; }
@media (hover:hover){ .cf-stepper button:hover{ background:rgba(var(--cal-mix),.08); color:var(--cal-ink); } }
.cf-sv{ min-width:54px; text-align:center; font-size:var(--t-meta); font-weight:600; font-variant-numeric:tabular-nums; }
.cf-calcfg{ display:flex; align-items:center; gap:11px; padding:10px 12px; border:1px solid var(--cal-line); border-radius:var(--r); margin-bottom:8px; }
.cf-swatches{ display:flex; gap:5px; }
.cf-csw{ width:19px; height:19px; border-radius:100px; border:2px solid transparent; transition:.12s; }
.cf-csw.on{ border-color:var(--cal-ink); }
.cf-cname2{ flex:1; min-width:0; font-size:var(--t-meta); font-weight:600; }
.cf-mono{ font-family:ui-monospace,'SF Mono',Menlo,monospace; font-size:var(--t-meta); color:var(--cal-ink2); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cf-urlrow{ display:flex; align-items:center; gap:10px; padding:11px 13px; border:1px solid var(--cal-line); border-radius:var(--r); background:var(--deep); }
.cf-copyb{ padding:6px 11px; border-radius:var(--r); border:1px solid var(--cal-line); font-size:var(--t-meta); font-weight:600; color:var(--cal-ink2); flex:none; }
@media (hover:hover){ .cf-copyb:hover{ border-color:var(--cal-accent); color:var(--cal-accent); } }
.cf-klist{ display:grid; grid-template-columns:1fr 1fr; gap:7px 18px; }
.cf-krow{ display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:var(--t-meta); color:var(--cal-ink2); padding:3px 0; }
.cf-loading{ display:flex; align-items:center; justify-content:center; height:100%; color:var(--cal-ink3); font-size:var(--t-texto); }

/* @container y no @media: el ancho real del calendario es el de #view, que ahora
   comparte la ventana con el chat de Xarpie (clamp(380px,40%,560px), ajustable arrastrando
   #cp-resize) -- el ancho de LA VENTANA ya no predice el espacio que le queda al calendario. */
@container (max-width:1320px){ .cf-rail{ display:none; } }
@container (max-width:1120px){
  .cf-dayview{ grid-template-columns:1fr; }
  .cf-daylist{ display:none; }
  .cf-body{ position:relative; }
  .cf-detail{ position:absolute; right:0; bottom:0; top:auto; width:min(340px,100%); max-height:78%; z-index:30; box-shadow:0 24px 60px -18px rgba(0,0,0,.8); }
  .cf-detail:not(.hasSel){ display:none; }
}
/* Telefono: monta en Dia por default (ver montarCalendarioFull), pero Semana/Mes se
   pueden elegir a mano y tienen que seguir siendo usables -- en vez de aplastar 7
   columnas a ~45px de ancho, se vuelven scrolleables horizontalmente con un ancho de
   columna minimo legible. El header dejaba una fila con anchos dispares (buscador,
   nav, segmentado, Nuevo) y una fila de filtros con salto irregular; aqui se ordenan
   en filas predecibles de ancho completo. */
@container (max-width:640px){
  .calfull{ padding:14px 14px 0; }
  .cf-hd{ gap:10px; padding-bottom:12px; }
  .cf-htitle{ font-size:var(--t-titulo); }
  .cf-hright{ width:100%; gap:8px; }
  .cf-search{ width:100%; min-width:0; order:1; }
  .cf-nav{ order:2; }
  .cf-seg{ order:3; flex:1; }
  .cf-seg button{ flex:1; }
  .cf-btn.ico{ order:4; }
  .cf-btn.accent{ order:5; flex:1; justify-content:center; }
  .cf-qadd{ height:auto; padding:8px 6px 8px 13px; }
  .cf-qhint{ display:none; } /* redundante con el placeholder del input a este ancho */
  .cf-filters{ flex-wrap:nowrap; overflow-x:auto; padding-bottom:14px; -webkit-overflow-scrolling:touch; }
  .cf-fsep{ flex:none; }

  /* Mes: .cf-mhead y .cf-mcells son hermanos dentro de .cf-main (que por default trae
     overflow:hidden) -- :has() los distingue de Semana/Dia, que tambien usan .cf-main,
     sin que este bloque les toque el overflow a ellos (Semana ya scrollea horizontal
     via .cf-wbody, ver abajo; si .cf-main TAMBIEN scrolleara ahi quedarian dos scrolls
     horizontales anidados). */
  .cf-main:has(.cf-mhead){ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .cf-mhead,.cf-mcells{ min-width:560px; }
  /* Semana: .cf-wbody ya es el scroll vertical (position:sticky del header depende de
     el); se le agrega el horizontal para que header+grilla se muevan juntos -- son
     hermanos dentro del MISMO contenedor, no hace falta sincronizarlos a mano. */
  .cf-wbody{ overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .cf-wrow{ min-width:480px; }
}

/* ============================================================================
   REDISEÑO "PANEL DEL ESTUDIO" (Claude Design) — PARTE 1: CARCASA
   Refina el shell (riel de Xarpie + navegación + tipografía) a la paleta Claude
   oscura y a Cormorant Garamond / Instrument Sans. Todo por tokens, así que
   respeta el toggle claro/oscuro. Los CUERPOS de cada sección se rediseñan en
   la Parte 2 (tiles/hero/KPIs/tablas); acá sólo la carcasa.

   Los tokens que esta parte redefinía (tipografía y paleta oscura) se subieron a su
   declaración única del principio del archivo: se veían igual, pero había que leer dos
   sitios lejanos para saber de qué color y con qué letra era la app.
   ============================================================================ */
/* (Rediseno minimalista 2026-09-10: aqui vivia un radial-gradient de fondo en tema oscuro.
   Quitado a pedido de Daniel: el fondo es plano, el unico relieve es el grano.) */

/* ---- Riel de Xarpie (permanente, más ancho, sobre el degradado) ---- */
.chatpane{ flex:0 0 clamp(380px,40%,560px); background:transparent; padding:30px 34px 26px; }
.cp-brand{ align-items:flex-start; gap:15px; border-bottom:none; padding-bottom:0; }
.cp-menu{ width:40px; height:40px; border-radius:var(--r); border:1px solid var(--line2); font-size:var(--t-campo); }

.greet{ margin-top:30px; padding-bottom:0; border-bottom:none; }
/* Fondo decorativo segun la hora (fondoPorHora, ver ficha.js/app.js cargarBriefing): una
   BANDA, no una tarjeta -- se disuelve hacia la derecha en vez de cortar en seco, para que
   siga leyendose como parte del saludo y no como un widget mas encima de el. */
.greet.fondo{ margin:30px -12px 0; padding:18px 14px 20px; border-radius:var(--r); }
.greet.fondo::before{ -webkit-mask-image:radial-gradient(120% 100% at 0% 50%, #000 40%, transparent 100%); mask-image:radial-gradient(120% 100% at 0% 50%, #000 40%, transparent 100%); }
.greetkicker{ font-family:var(--sans); text-transform:uppercase; letter-spacing:.2em; font-size:var(--t-eti); font-weight:600; color:var(--muted); }
.greetname{ font-family:var(--serif); font-size:var(--t-saludo); font-weight:400; letter-spacing:-.01em; line-height:1.02; margin-top:8px; }

/* AREA 3 -- el ritmo. El gap base ahora es el de DENTRO de un turno (dos respuestas
   seguidas de Xarpie se leen como un bloque) y el aire grande se agrega solo cuando cambia
   quien habla. Antes todo estaba a 16px y no se veia donde terminaba un turno. */
.chatscroll{ margin-top:22px; gap:13px; }
.chatscroll .brow-me + .brow-ai,
.chatscroll .brow-ai + .brow-me{ margin-top:19px; }
/* Xarpie responde en texto plano con avatar (como Claude); tú, en burbuja. */
.ava{ width:30px; height:30px; flex:0 0 30px; background:#2b241d; border:1px solid var(--line2); }
.ava:after{ width:11px; height:11px; left:7px; top:7px; background:var(--accent); }
.bub{ font-size:var(--t-texto); line-height:1.64; border-radius:var(--r); }
.bub-ai{ background:transparent; border:none; padding:3px 2px 0 0; }
/* Tu propio mensaje pierde el relleno: es el apunte al margen, no lo que viniste a leer.
   Va AQUI y no arriba porque esta regla es la ultima que toca .bub-me -- una copia mas
   arriba la pisaba esta y el cambio no se veia (medido). --muted esta calculado para AA
   sobre estas superficies (ver el comentario del token), asi que baja de peso sin dejar de
   ser legible. */
.bub-me{ background:transparent; border:1px solid var(--line2); border-top-right-radius:var(--r); color:var(--muted); font-size:var(--t-texto); }

.chips{ gap:8px; margin:16px 0 12px; }
.chip{ background:transparent; border:1px solid var(--line2); border-radius:var(--r); padding:9px 15px; font-size:var(--t-meta); }
@media (hover:hover){ .chip:hover{ border-color:var(--accent); background:transparent; color:var(--ink); } }

/* Esta regla es POSTERIOR a la base, asi que manda: tiene que repetir el padding izquierdo
   grande de la barra de una linea o el cursor queda pegado al borde. */
.composer{ border-radius:var(--r); padding:7px 7px 7px 16px; }

/* ---- .tab/.subbar/.subtab: reusadas por admin.html y proyectos.js, no por la nav del
   CRM (que vive en #cp-riel desde "El Carril" F2, con su propio estilo mas abajo) ---- */
.tab{ padding:8px 16px; border-radius:var(--r); font-size:var(--t-texto); }
@media (hover:hover){ .tab:hover{ background:transparent; color:var(--ink); } }
.tab.on:after{ left:50%; right:auto; transform:translateX(-50%); width:20px; bottom:-19px; }
.subbar{ padding:11px 40px; gap:4px; background:var(--bone); backdrop-filter:none; }
.subtab{ padding:7px 15px; border-radius:var(--r); font-size:var(--t-texto); }

/* ---- Contenido: ancho completo con aire (como el diseño), título serif grande ---- */
/* padding-top de 34 a 20: la cabecera de cada seccion se comia ~197px (22% de una
   pantalla de 900) antes del primer dato util. Con el margen fantasma del h1 corregido,
   esto deja el contenido de todas las secciones ~85px mas arriba sin tocar la
   tipografia. Verificar en vivo tras "El Carril" F2: #view ya no tiene una barra de nav
   arriba (se mudo al carril de la izquierda), asi que este padding paso a ser TODA la
   separacion del borde superior, no un extra sobre la nav -- si se ve apretado, subir
   este numero es el ajuste, no revertir el de abajo. */
.wrap{ max-width:none; padding:20px 40px 70px; margin:0; }
.phead{ margin-bottom:20px; }
.ptitle{ font-size:44px; }
.peyebrow{ font-family:var(--sans); font-weight:600; letter-spacing:.14em; }

@media (max-width:900px){
  .chatpane{ flex-basis:auto; }
  .subbar,.wrap{ padding-left:20px; padding-right:20px; }
}

/* ============================================================================
   REDISEÑO "PANEL DEL ESTUDIO" (Claude Design) — PARTE 2: CUERPOS DE SECCIÓN
   Refina el vocabulario de componentes COMPARTIDO que usan las 8 secciones
   (KPIs, tarjetas, botones, pills, chips, segmentos, buscador). Como cada
   cuerpo se arma con estos mismos bloques, esto rediseña todas las secciones a
   la vez, sin reescribir la lógica de cada vista. Todo por tokens → respeta el
   toggle claro/oscuro.
   ============================================================================ */

/* --- Tile de KPI: el punto de la esquina pasa a ser BORDE SUPERIOR de color
       (= estado), que es la firma del handoff. Toca Panel, Bodas, Dinero,
       fichas de cliente y todo kpiCard() de una sola vez. --- */
.stat{ padding:17px 18px 15px; border-radius:var(--r); }
.statbar{ left:0; right:0; top:0; width:auto; height:3px; border-radius:var(--r) var(--r) 0 0; box-shadow:none; }
.statlabel{ letter-spacing:.14em; }
.statnum{ font-size:var(--t-saludo); margin-top:9px; }

/* --- Tarjetas y paneles: radio más suave, dentro del rango 14–20px del handoff. --- */
.card,.pblock,.widget,.settcard,.acc-card{ border-radius:var(--r); }
.wadd-item,.paybox{ border-radius:var(--r); }

/* --- Todo lo "botón / chip / control" es cápsula (border-radius:100px),
       otra firma del handoff. --- */
.btn,.btn-sm,.btn-wa{ border-radius:var(--r); }
.fchip{ border-radius:var(--r); }
.search{ border-radius:var(--r); padding-left:18px; padding-right:18px; }
.seg,.seg-btn{ border-radius:var(--r); }
.ing-seg{ border-radius:var(--r); }
.x{ border-radius:var(--r); }

/* --- El buscador y los inputs de filtro heredan la cápsula sin perder foco. --- */
.search:focus-within{ border-color:var(--accent); }

/* ============================================================================
   "EL FOCO" — hero fijo arriba del Panel del dia. Ranking priorizado (tareas,
   leads, entregas, oportunidades, bandeja, cobros) de un motor de reglas
   determinista (sin IA). No es parte de la grilla de widgets reordenable.
   ============================================================================ */
.foco-hero{ background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); padding:22px 24px 6px; margin-bottom:26px; box-shadow:0 1px 3px rgba(41,40,36,.04); }
/* --ok ya es global en tema oscuro (~linea 915) pero en claro solo vivia dentro de
   .pendw -- mismo valor extendido aqui, para el color por categoria de los iconos. */
:root:not([data-theme="dark"]) .foco-hero{ --ok:#4E6350; }
.foco-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:12px; }
/* Fondo decorativo SOLO en la cabecera (misma hora que .greet, ver renderFocoHero): la
   lista de abajo se queda limpia. Margen negativo = las mismas medidas del padding de
   .foco-hero (arriba), asi la banda sangra hasta el borde de la tarjeta redondeada. */
.foco-head.fondo{ margin:-22px -24px 14px; padding:22px 24px 16px; border-radius:var(--r) var(--r) 0 0; overflow:hidden; }
.foco-head.fondo::before{ -webkit-mask-image:linear-gradient(to bottom, #000 45%, transparent); mask-image:linear-gradient(to bottom, #000 45%, transparent); }
.foco-eyebrow{ display:block; font-family:var(--sans); font-weight:600; font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--accent); margin-bottom:4px; }
.foco-title{ font-family:var(--serif); font-weight:400; font-size:var(--t-titulo); letter-spacing:-.01em; }
.foco-list{ display:flex; flex-direction:column; }
.foco-item{ display:flex; align-items:center; gap:14px; padding:14px 0; border-bottom:1px solid var(--hair); }
.foco-item:last-child{ border-bottom:0; }
.foco-ico{ flex:0 0 34px; width:34px; height:34px; display:grid; place-items:center; border-radius:50%; background:var(--bone); font-size:var(--t-texto); color:var(--accent); }
.foco-body{ flex:1; min-width:0; }
.foco-titulo{ font-weight:600; font-size:var(--t-texto); line-height:1.3; }
.foco-porque{ font-size:var(--t-meta); color:var(--muted); margin-top:3px; line-height:1.4; }
/* Fila de perfil (una pregunta de Xarpie): las opciones van DEBAJO del texto y no en la
   columna de acciones, donde cabe un boton pero no cuatro. La fila se alinea arriba
   porque con los chips deja de ser de una sola linea. */
.foco-item:has(.foco-ops){ align-items:flex-start; }
.foco-item:has(.foco-ops) .foco-ico{ margin-top:2px; }
.foco-ops{ display:flex; flex-wrap:wrap; gap:7px; margin-top:10px; }
.foco-op{ font-size:var(--t-meta); font-weight:500; padding:7px 13px; border:1px solid var(--line2); border-radius:var(--r); background:transparent; color:var(--ink); cursor:pointer; transition:.14s; }
@media (hover:hover){ .foco-op:hover:not(:disabled){ border-color:var(--accent); color:var(--accent); } }
.foco-op:disabled{ opacity:.5; cursor:default; }
.foco-op.on{ background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); opacity:1; }
.foco-ico-perfil{ color:var(--blue); }
/* Color por categoria, agrupado por familia (la paleta calida solo tiene 4 tonos no
   neutros): accion inmediata (dinero/mensaje por aprobar), crecimiento (negocio
   nuevo), en-proceso (entrega/espera del cliente). tarea/reconciliar van a --muted a
   proposito (el default de .foco-ico de arriba ES --accent, asi que sin esto se verian
   IGUAL que cobro/bandeja y le quitarian fuerza a esa señal de "accion inmediata"). */
.foco-ico-tarea, .foco-ico-reconciliar{ color:var(--muted); }
.foco-ico-cobro, .foco-ico-bandeja{ color:var(--accent); }
.foco-ico-lead, .foco-ico-oportunidad{ color:var(--yellow); }
.foco-ico-entrega, .foco-ico-galeria{ color:var(--ok); }
/* Coincide con el default de .foco-ico, pero explicito: si el default cambia algun dia,
   esta tarjeta (buena noticia, no una tarea) debe seguir siendo --accent a proposito. */
.foco-ico-seleccion{ color:var(--accent); }
.foco-monto{ flex:0 0 auto; font-family:var(--serif); font-weight:400; font-size:var(--t-texto); font-variant-numeric:tabular-nums; letter-spacing:-.01em }
.foco-btn{ flex:0 0 auto; font-size:var(--t-meta); padding:8px 16px; border-radius:var(--r); border:1px solid var(--line2); background:var(--paper); color:var(--ink); cursor:pointer; transition:.14s; white-space:nowrap; text-decoration:none; display:inline-flex; align-items:center; }
@media (hover:hover){ .foco-btn:hover{ border-color:var(--accent); background:var(--deep); } }
.foco-btn:disabled{ opacity:.55; cursor:default; }
.foco-btn-resolver{ border-color:color-mix(in srgb, var(--ok) 55%, var(--line2)); color:var(--ok); }
@media (hover:hover){ .foco-btn-resolver:hover{ border-color:var(--ok); background:color-mix(in srgb, var(--ok) 12%, var(--paper)); } }
.foco-acciones{ flex:0 0 auto; display:flex; align-items:center; gap:7px; }
.foco-ayuda{ flex:0 0 auto; width:30px; height:30px; display:grid; place-items:center; border-radius:100px; border:1px solid var(--line2); background:transparent; color:var(--muted); cursor:pointer; transition:.14s; }
@media (hover:hover){ .foco-ayuda:hover{ border-color:var(--accent); color:var(--accent); background:var(--deep); } }
/* Menu de "mas acciones": reusa por completo .usermenu/.um-item/.um-danger
   (mismo fondo/borde/sombra/animacion/foco de teclado que el menu de usuario) --
   solo se ajusta la posicion para colgar del boton circular en vez del avatar. */
.foco-menu-wrap{ position:relative; flex:0 0 auto; }
.foco-menu{ top:36px; right:0; width:190px; }

/* Botones "Compartir link..." del panel de galeria (junto a Publicar/Despublicar).
   Mismo patron que .foco-menu-wrap de arriba: el .usermenu adentro no necesita clase
   propia, sus defaults (top:44px, right:0, width:230px) ya calzan con un boton .btn
   normal en vez del circulo chico de El Foco. */
.gshare-wrap{ position:relative; flex:0 0 auto; }
/* "Despublicar" y "Compartir link de la galeria" deben quedar en la MISMA fila (pedido
   explicito). Antes flex-wrap:wrap vivia INLINE en el propio div (`style="..."`) -- un
   estilo inline le gana a CUALQUIER regla externa sin importar especificidad, asi que ni
   !important hacia falta para el bug, ya ganaba solo. Se paso a esta clase para que el
   media query de abajo si pueda pisarlo.
   En un telefono real (375px) los dos botones juntos piden ~340px contra ~325px
   disponibles -- 15px de sobra que con wrap mandaba el segundo boton a su propia fila,
   o sea abajo, no al lado. nowrap + min-width:0 en los botones: en vez de envolver la
   FILA, el texto del boton mas largo envuelve a una segunda linea DENTRO de su propio
   boton (los botones no tienen white-space:nowrap por default) -- se quedan en la misma
   fila sin inventar un texto mas corto que el que se pidio. */
.g-phead-acts{ flex-wrap:wrap; align-items:flex-start; }
@media (max-width:640px){
  .g-phead-acts{ flex-wrap:nowrap; }
  .g-phead-acts .btn{ min-width:0; flex:1 1 auto; text-align:center; }
}

/* La causa real de que el titulo se parta palabra por palabra en un telefono real no era
   "falta flex-wrap" -- .foco-item ya lo tenia y aun asi se rompio en un iPhone real (Chrome
   emulado a 375px lo mostraba bien, WebKit no). La causa es `min-width:0` en .foco-body: eso
   le dice al motor "puedes encoger esto hasta cero antes de envolver la fila", y distintos
   motores deciden en momentos distintos cuando de verdad envolver vs. seguir apretando. El
   arreglo real es un PISO de legibilidad: con min-width fijo, el texto se queda comodo en una
   linea mientras quepa, y en cuanto no cabe, envuelve a su propia linea completa en vez de
   colapsar caracter por caracter. */
@media (max-width:640px){
  .foco-item{ flex-wrap:wrap; }
  .foco-body{ min-width:180px; }
  /* flex:0 0 auto (arriba) hace que la fila mida lo que miden sus botones juntos, asi que el
     wrap nunca pasaba: con tres botones largos ("Que lo haga Xarpie", "Ver todo lo que falta",
     "Ver mi liga de bio") media ~540px y la pagina entera se deslizaba de lado en el telefono
     (captura de Daniel, 2026-09-16). Con el ancho de su renglon, los botones bajan de linea. */
  .foco-acciones{ margin-left:48px; flex-wrap:wrap; flex:1 1 calc(100% - 48px); min-width:0; }
}

/* Selector de cliente con busqueda en vivo + alta rapida (Generar contrato / Generar recibo) */
.cp-drop{ position:absolute; top:100%; left:0; right:0; margin-top:6px; z-index:40; background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); box-shadow:0 18px 44px -20px rgba(43,40,36,.5); padding:6px; max-height:280px; overflow-y:auto; animation:pop .16s ease both; }
.cp-drop[hidden]{ display:none; }
/* Nace para <div> (el picker de arriba) pero los candidatos de los comandos "/" del chat
   la reusan en <button> (mejor foco de teclado que un div con onclick). Estas 6 lineas
   solo pisan chrome nativo de boton -- un <div> no tiene nada de eso, asi que no le
   cambian un pixel al picker de siempre. */
.cp-opt{ display:block; width:100%; padding:9px 12px; border-radius:var(--r); cursor:pointer;
  background:none; border:0; text-align:left; font:inherit; color:inherit; }
@media (hover:hover){ .cp-opt:hover{ background:#ECE7DB; } }
.cp-opt-nuevo{ color:var(--accent); font-weight:600; border-bottom:1px solid var(--hair); margin-bottom:4px; padding-bottom:10px; }
.cp-opt-sub{ font-size:var(--t-meta); color:var(--muted); margin-top:1px; }
@media (hover:hover){ :root[data-theme="dark"] .cp-opt:hover{ background:#33322D; } }

/* Menu de autocomplete de comandos "/" del chat -- mismo patron que .cp-drop de arriba,
   pero ABRE HACIA ARRIBA (bottom:100%): el composer vive al fondo del riel, asi que un
   dropdown que abriera hacia abajo saldria de la pantalla. */
.cmd-menu{ position:absolute; bottom:100%; left:0; right:0; margin-bottom:8px; z-index:40; background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); box-shadow:0 -18px 44px -20px rgba(43,40,36,.5); padding:6px; max-height:min(300px,40vh); overflow-y:auto; animation:pop .16s ease both; }
.cmd-menu[hidden]{ display:none; }
.cmd-opt{ display:flex; align-items:center; gap:9px; padding:8px 10px; border-radius:var(--r); cursor:pointer; }
.cmd-opt.on{ background:#ECE7DB; }
@media (hover:hover){ .cmd-opt:hover{ background:#ECE7DB; } }
.cmd-opt-nombre{ font-weight:600; flex:0 0 auto; }
.cmd-opt-desc{ color:var(--muted); font-size:var(--t-meta); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
:root[data-theme="dark"] .cmd-opt.on{ background:#33322D; }
@media (hover:hover){ :root[data-theme="dark"] .cmd-opt:hover{ background:#33322D; } }

/* ---- Mini calendario del panel (widget) ----
   Rejilla compacta: cada dia se representa con puntos de color (mismos colores que la
   Agenda via calColor), no con chips, para que quepa en el ancho de un widget. Tres
   tamanos: mini (solo rejilla), mediano (rejilla + lista) y grande (2 columnas). */
.mc-head{ display:flex; align-items:center; justify-content:space-between; gap:10px; margin-bottom:10px; }
.mc-nav{ display:flex; gap:4px; flex:0 0 auto; }
.mc-title{ font-weight:600; font-size:var(--t-texto); text-transform:capitalize; text-align:right; }

.mc-wrap.grande{ display:grid; grid-template-columns:minmax(240px,340px) 1fr; gap:18px; align-items:start; }

.mc-dow{ display:grid; grid-template-columns:repeat(7,1fr); gap:2px; margin-bottom:4px; }
.mc-dow span{ text-align:center; font-size:var(--t-eti); font-weight:600; letter-spacing:.06em; color:var(--muted); }
.mc-grid{ display:grid; grid-template-columns:repeat(7,1fr); gap:2px; }
.mc-strip{ display:grid; grid-template-columns:repeat(7,1fr); gap:3px; }

.mc-day{ position:relative; min-height:36px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:2px;
  border:1px solid transparent; background:transparent; border-radius:var(--r); cursor:pointer; padding:3px 2px; transition:.12s; }
.mc-strip .mc-day{ min-height:48px; }
@media (hover:hover){ .mc-day:hover{ background:var(--hair); } }
.mc-day:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }
.mc-day .mc-dw{ font-size:var(--t-eti); font-weight:600; letter-spacing:.05em; color:var(--muted); line-height:1; }
.mc-day .mc-n{ font-size:var(--t-meta); font-variant-numeric:tabular-nums; color:var(--ink); line-height:1; }
.mc-day.out .mc-n{ opacity:.3; }
.mc-day.hoy{ border-color:var(--accent); }
.mc-day.hoy .mc-n{ font-weight:700; color:var(--accent); }
.mc-day.mc-sel{ background:var(--accent); border-color:var(--accent); }
.mc-day.mc-sel .mc-n,.mc-day.mc-sel .mc-dw{ color:#fff; opacity:1; }
.mc-day.bloq{ background-image:repeating-linear-gradient(45deg, transparent, transparent 3px, var(--hair) 3px, var(--hair) 6px); }
/* Hasta 4 "marcas": puntos llanos (tarea/sesion, sin cambios) o iconos (evento, ver
   calMarcas() en app.js). flex-wrap por si un dia raro cae con las 4 marcas siendo iconos
   (9px x4 + gaps ya no caben en una sola linea de ~32px utiles): en vez de desbordar hacia
   el dia vecino, pasan a una segunda linea. */
.mc-dots{ display:flex; flex-wrap:wrap; gap:2px; min-height:9px; align-items:center; justify-content:center; }
.mc-dots i{ width:4px; height:4px; border-radius:50%; display:block; flex:none; }
/* Marca de evento: icono en vez de circulo, mas grande que el punto de tarea/sesion (9px
   vs 4px) para que ademas de la forma, el TAMANO ya diga "esto es distinto". El color
   llega inline por style (igual que los puntos): aqui solo se resetea la geometria de
   circulo que .mc-dots i ya trae. */
.mc-dots i.mc-mark-ico{ width:auto; height:auto; border-radius:0; background:none; flex:none; }
.mc-dots i.mc-mark-ico svg{ display:block; }
/* El aro blanco de seleccionado es para CIRCULOS -- sobre un icono se veria como un marco
   cuadrado torcido. Los iconos quedan fuera de esta regla; celda() resuelve el color a
   blanco en JS cuando el dia esta seleccionado -- necesario porque var(--red) (boda) y
   var(--accent) son EL MISMO color en los dos temas (ver :root arriba en este archivo):
   sin el cambio a blanco, el icono de una boda desaparece el dia que lo seleccionas. */
.mc-day.mc-sel .mc-dots i:not(.mc-mark-ico){ box-shadow:0 0 0 1px rgba(255,255,255,.6); }

.mc-listwrap{ margin-top:12px; }
.mc-wrap.grande .mc-listwrap{ margin-top:0; }
.mc-listhead{ display:flex; align-items:center; justify-content:space-between; gap:8px;
  font-size:var(--t-meta); font-weight:600; letter-spacing:.05em; text-transform:uppercase; color:var(--muted);
  padding-bottom:6px; border-bottom:1px solid var(--hair); margin-bottom:2px; }
.mc-clear{ border:0; background:transparent; color:var(--muted); cursor:pointer; font-size:var(--t-meta); line-height:1; padding:2px 5px; border-radius:var(--r); }
@media (hover:hover){ .mc-clear:hover{ background:var(--hair); color:var(--ink); } }
/* Scroll dentro de la lista: el widget NO crece, la lista se desplaza. */
.mc-list{ overflow-y:auto; overscroll-behavior:contain; }
.mc-list.mediano{ max-height:158px; }
.mc-list.grande{ max-height:300px; }
.mc-item{ padding:6px 2px; }

.mc-foot{ display:flex; align-items:center; gap:8px; margin-top:12px; }
.mc-foot .mc-segs{ flex:1; margin-top:0; }
.mc-tams{ display:flex; gap:2px; flex:0 0 auto; }
.mc-tam{ border:1px solid var(--line2); background:transparent; color:var(--muted); cursor:pointer;
  width:26px; height:26px; border-radius:var(--r); font-size:var(--t-meta); line-height:1; transition:.13s; }
@media (hover:hover){ .mc-tam:hover{ color:var(--ink); } }
.mc-tam.on{ color:var(--accent); border-color:var(--accent); }
@media (max-width:760px){ .mc-wrap.grande{ grid-template-columns:1fr; gap:12px; } }

/* ==================================================================
   BASES DE DATOS DEL USUARIO (bases.js)
   ================================================================== */
.db-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 14px; }
.db-card { display: flex; gap: 12px; align-items: center; text-align: left; padding: 16px; border: 1px solid var(--hair); border-radius: var(--r); background: var(--paper); cursor: pointer; transition: border-color .15s ease, transform .15s ease; }
@media (hover:hover){ .db-card:hover{ border-color: var(--accent); transform: translateY(-1px); } }
.db-card-ico { font-size: var(--t-titulo); width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--accent) 8%, var(--paper)); border-radius: var(--r); flex: none; }
.db-card-t { font-weight: 600; }

.db-mini-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 4px 0 10px; }
.db-chips { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.db-chip-union { font-size: var(--t-eti); color: var(--muted); text-transform: uppercase; }
.db-vista-body { min-width: 0; }
.db-meta .pill { font-size: var(--t-eti); }

.db-tabla-wrap { overflow-x: auto; }
.db-tabla th { white-space: nowrap; }

/* ---- Vista calendario: rejilla de 7 columnas con las filas del mes ---- */
.db-cal-head { font-size:var(--t-meta); color:var(--muted); margin-bottom:8px; text-transform:capitalize; }
.db-cal { display:grid; grid-template-columns:repeat(7,1fr); gap:3px; }
.db-cal-dow { font-size:var(--t-eti); color:var(--muted); text-align:center; padding:3px 0; text-transform:uppercase; letter-spacing:.06em; }
.db-cal-dia { min-height:70px; border:1px solid var(--line2); border-radius:var(--r); padding:4px; overflow:hidden; }
.db-cal-vacio { border-color:transparent; }
.db-cal-n { font-size:var(--t-meta); color:var(--muted); margin-bottom:3px; }
.db-cal-item { font-size:var(--t-meta); background:var(--deep); border-radius:4px; padding:2px 5px; margin-bottom:2px; cursor:pointer; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
@media (hover:hover){ .db-cal-item:hover{ background:var(--accent-solido); color:var(--accent-tinta); } }
.db-cal-mas { font-size:var(--t-eti); color:var(--muted); padding-left:4px; }

/* ---- Vista galeria: tarjetas con portada desde una columna de archivos ---- */
.db-gal { display:grid; grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); gap:12px; }
.db-gal-card { border:1px solid var(--line2); border-radius:var(--r); overflow:hidden; cursor:pointer; background:var(--paper); }
@media (hover:hover){ .db-gal-card:hover{ border-color:var(--accent); } }
.db-gal-img { aspect-ratio:4/3; background:var(--deep); display:flex; align-items:center; justify-content:center; overflow:hidden; }
.db-gal-img img { width:100%; height:100%; object-fit:cover; }
.db-gal-sin { font-size:var(--t-saludo); opacity:.35; }
.db-gal-pie { padding:8px 10px; display:flex; flex-direction:column; gap:2px; font-size:var(--t-meta); }
.db-gal-pie .muted { font-size:var(--t-meta); }

/* ---- Vista linea de tiempo: una barra por fila entre su inicio y su fin ---- */
.db-lt-head { display:flex; font-size:var(--t-meta); color:var(--muted); margin-bottom:6px; }
.db-lt-fila { display:flex; align-items:center; gap:10px; padding:3px 0; cursor:pointer; }
@media (hover:hover){ .db-lt-fila:hover .db-lt-barra{ background:var(--accent); } }
.db-lt-et { flex:0 0 34%; max-width:34%; font-size:var(--t-meta); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.db-lt-pista { position:relative; flex:1; height:16px; background:var(--deep); border-radius:var(--r); }
.db-lt-barra { position:absolute; top:3px; height:10px; min-width:6px; border-radius:var(--r); background:var(--line2); }

/* ---- Opciones de presentacion de la tabla (config.tabla de la vista) ---- */
/* Alto de fila: compacta / normal / alta. Aplica al contenido, no al padding del th. */
.db-tabla.db-alto-compacta td { height:30px; padding-top:2px; padding-bottom:2px; }
.db-tabla.db-alto-normal td { height:40px; }
.db-tabla.db-alto-alta td { height:64px; vertical-align:top; padding-top:9px; }
/* Por default una celda no envuelve (una tabla con textos largos se vuelve ilegible);
   con wrap activo el texto fluye en varias lineas. */
.db-tabla td { white-space:nowrap; overflow:hidden; text-overflow:ellipsis; max-width:420px; }
.db-tabla.db-wrap td { white-space:normal; overflow:visible; text-overflow:clip; }
/* Columnas congeladas: se quedan fijas al hacer scroll lateral. El fondo es obligatorio
   o el contenido de las columnas de atras se transparenta encima al desplazar. */
.db-tabla .db-sticky { position:sticky; z-index:2; background:var(--paper); }
.db-tabla thead .db-sticky { z-index:3; }
.db-tabla .db-sticky::after { content:""; position:absolute; top:0; right:0; bottom:0; width:1px; background:var(--line2); }
/* Pie con los contadores por columna. */
.db-tabla tfoot .db-pie td { font-size:var(--t-meta); color:var(--ink); border-top:1px solid var(--line2); white-space:nowrap; }
.db-pie-et { color:var(--muted); font-size:var(--t-meta); text-transform:uppercase; letter-spacing:.04em; margin-right:5px; }
.db-celda { cursor: pointer; min-width: 90px; }
@media (hover:hover){ .db-celda:hover{ background: color-mix(in srgb, var(--accent) 6%, transparent); } }
.db-celda-titulo { cursor: pointer; }
@media (hover:hover){ .db-celda-titulo:hover .tname{ color: var(--accent); } }
.db-inp-celda { width: 100%; min-width: 90px; }

.db-pop-op { position: fixed; z-index: 260; max-height: 260px; overflow: auto; }
.db-pop-buscar { position: fixed; z-index: 260; width: 320px; padding: 10px; }
.db-buscar-res { max-height: 260px; overflow: auto; margin-top: 8px; }

.db-multi { display: flex; flex-wrap: wrap; gap: 8px 14px; }
.db-multi-op { display: inline-flex; align-items: center; gap: 6px; font-size: var(--t-texto); cursor: pointer; }
.db-rel-x { border: 0; background: none; cursor: pointer; color: var(--muted); font-size: var(--t-eti); padding: 0 2px; }
@media (hover:hover){ .db-rel-x:hover{ color: var(--red); } }
.db-rel-box { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.db-ro { padding: 8px 0; }

.db-esq-row { display: flex; gap: 8px; align-items: center; margin: 8px 0; flex-wrap: wrap; }
.db-picker-base { padding: 12px 0; border-bottom: 1px solid var(--hair); }
.db-picker-base:last-of-type { border-bottom: 0; }
.db-tablero .kcol { min-width: 190px; }
@media (max-width: 860px) {
  .db-cards { grid-template-columns: 1fr 1fr; }
  .db-pop-buscar { width: calc(100vw - 32px); left: 16px !important; }
}
.db-sys-cols { display: flex; flex-wrap: wrap; gap: 6px; padding: 6px 0; }
.db-sys-cols .pill { font-size: var(--t-meta); opacity: .8; }

/* --- Config visual de columnas (iconos por tipo, colores/emojis por opcion) estilo Notion --- */
.db-th-cfg { cursor: pointer; user-select: none; }
@media (hover:hover){ .db-th-cfg:hover{ color: var(--accent); } }
.db-th-ico { opacity: .7; font-size: var(--t-meta); margin-right: 1px; }
.db-th-add { cursor: pointer; color: var(--muted); font-weight: 700; text-align: center; width: 32px; }
@media (hover:hover){ .db-th-add:hover{ color: var(--accent); } }
.db-op-dot { display: inline-block; width: 7px; height: 7px; border-radius: 50%; margin-right: 5px; vertical-align: middle; }
.db-cfg-pop { width: 300px; padding: 12px; z-index: 250; }
.db-cfg-top { display: flex; gap: 8px; align-items: center; margin-bottom: 12px; }
.db-cfg-ico { width: 34px; height: 34px; flex: none; border: 1px solid var(--line2); border-radius: var(--r); background: transparent; font-size: var(--t-campo); cursor: pointer; color: var(--ink); }
@media (hover:hover){ .db-cfg-ico:hover{ border-color: var(--accent); } }
.db-cfg-f { margin-bottom: 11px; }
.db-cfg-f > label { display: block; font-size: var(--t-eti); color: var(--muted); margin-bottom: 4px; text-transform: uppercase; letter-spacing: .05em; }
.db-cfg-f select.sel-sm { width: 100%; }
.db-cfg-acts { display: flex; align-items: center; gap: 6px; margin-top: 14px; }
/* Panel "Opciones de tabla" del configurador de vista. */
.db-cv-det { border: 1px solid var(--line2); border-radius: var(--r); padding: 10px 12px; margin-top: 4px; }
.db-cv-det > summary { cursor: pointer; font-size: var(--t-meta); color: var(--muted); font-weight: 600; }
.db-cv-cols { display: flex; flex-direction: column; gap: 5px; max-height: 240px; overflow-y: auto; margin-top: 6px; }
.db-cv-col { display: flex; align-items: center; gap: 6px; font-size: var(--t-meta); }
/* Editor de formula: chips de columnas + chuleta de sintaxis. */
.db-form-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.db-form-chips .pill { cursor: pointer; font-size: var(--t-meta); padding: 2px 7px; }
@media (hover:hover){ .db-form-chips .pill:hover{ border-color: var(--accent); color: var(--accent); } }
.db-form-ayuda { margin: 8px 0 0; padding: 7px 8px; background: var(--paper2, rgba(0, 0, 0, .03)); border-radius: var(--r); font-size: var(--t-eti); line-height: 1.55; color: var(--muted); white-space: pre-wrap; font-family: ui-monospace, Menlo, monospace; }
/* Valor calculado (rollup / formula) dentro del panel de fila: se ve, no se edita. */
.db-calc-val { padding: 8px 10px; border: 1px dashed var(--line2); border-radius: var(--r); color: var(--muted); }
.db-op-row { display: flex; gap: 6px; align-items: center; margin: 6px 0; }
.db-op-emoji { width: 30px; height: 30px; flex: none; border: 1px solid var(--line2); border-radius: var(--r); background: transparent; cursor: pointer; font-size: var(--t-texto); color: var(--muted); }
@media (hover:hover){ .db-op-emoji:hover{ border-color: var(--accent); color: var(--ink); } }
.db-op-sw { width: 22px; height: 22px; flex: none; border: 1px solid rgba(0, 0, 0, .18); border-radius: 50%; cursor: pointer; padding: 0; }
.db-op-x { border: 0; background: none; color: var(--muted); cursor: pointer; font-size: var(--t-meta); padding: 2px 4px; }
@media (hover:hover){ .db-op-x:hover{ color: var(--red); } }
.db-emoji-pop { width: 288px; padding: 10px; z-index: 400; }
.db-emoji-grid { display: grid; grid-template-columns: repeat(8, 1fr); gap: 2px; max-height: 196px; overflow: auto; }
.db-emoji-b { font-size: var(--t-sub); border: 0; background: none; cursor: pointer; border-radius: var(--r); padding: 4px 0; line-height: 1; }
@media (hover:hover){ .db-emoji-b:hover{ background: var(--bone); } }
.db-emoji-foot { display: flex; gap: 6px; margin-top: 8px; align-items: center; }
.db-color-pop { width: 186px; padding: 12px; z-index: 400; }
.db-sw-row { display: flex; flex-wrap: wrap; gap: 7px; }
.db-sw { width: 24px; height: 24px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; }
.db-sw.on { box-shadow: 0 0 0 2px var(--paper), 0 0 0 4px var(--ink); }
.db-sw-custom { display: flex; align-items: center; gap: 8px; font-size: var(--t-meta); color: var(--muted); margin-top: 12px; cursor: pointer; }
.db-sw-custom input[type=color] { width: 28px; height: 24px; padding: 0; border: 1px solid var(--line2); border-radius: var(--r); background: none; cursor: pointer; }

/* --- Fase 2: icono (page icon) por fila + icono/color por base --- */
.db-fila-ico { margin-right: 6px; font-size: .95em; line-height: 1; display: inline-block; }
.db-fila-ico.editable { cursor: pointer; border-radius: var(--r); padding: 0 2px; margin-right: 4px; }
@media (hover:hover){ .db-fila-ico.editable:hover{ background: var(--bone); } }
.db-fila-ico.vacio { color: var(--muted); opacity: 0; transition: opacity .12s; }
@media (hover:hover){ tr:hover .db-fila-ico.vacio, .db-fila:hover .db-fila-ico.vacio, .db-ktarj:hover .db-fila-ico.vacio{ opacity: .45; } }
/* Icono de fila en la cabecera del panel de fila */
.db-fila-ico-btn { width: 44px; height: 44px; flex: none; border: 1px solid var(--line2); border-radius: var(--r); background: transparent; font-size: var(--t-titulo); cursor: pointer; color: var(--ink); display: flex; align-items: center; justify-content: center; }
@media (hover:hover){ .db-fila-ico-btn.editable:hover{ border-color: var(--accent); } }
.db-fila-ico-btn.vacio { color: var(--muted); }
.db-fila-ico-btn[disabled] { cursor: default; opacity: .6; }
/* Icono/color de base en el modal de creacion */
.db-base-ico-btn, .db-base-color-btn { width: 100%; height: 40px; border: 1px solid var(--line2); border-radius: var(--r); background: transparent; cursor: pointer; font-size: var(--t-sub); color: var(--ink); display: flex; align-items: center; justify-content: center; }
@media (hover:hover){ .db-base-ico-btn:hover, .db-base-color-btn:hover{ border-color: var(--accent); } }
.db-base-color-btn { color: var(--muted); font-size: var(--t-texto); }
/* Icono/color de base en el encabezado de la pagina de la base */
.db-base-ico-h { border: 0; background: none; cursor: pointer; font: inherit; padding: 0 2px; color: inherit; border-radius: var(--r); }
@media (hover:hover){ .db-base-ico-h:hover{ background: var(--bone); } }
.db-base-color-h { font-size: var(--t-texto); }
/* Fase 3: tipo persona (avatar con iniciales) */
.db-persona { display: inline-flex; align-items: center; gap: 6px; }
.db-persona-av { width: 20px; height: 20px; border-radius: 50%; background: color-mix(in srgb, var(--accent) 22%, var(--paper)); color: var(--accent); font-size: var(--t-eti); font-weight: 700; letter-spacing: .02em; display: inline-flex; align-items: center; justify-content: center; flex: none; }
/* Fase 3: fecha con rango (dos date inputs) + checkbox de config */
.db-rango-fechas { display: flex; align-items: center; gap: 8px; }
.db-rango-fechas .inp { flex: 1; min-width: 0; }
.db-cfg-check { display: flex; align-items: center; gap: 7px; font-size: var(--t-meta); color: var(--ink); cursor: pointer; }
/* Fase 3: tipo archivos/foto (miniaturas en celda + editor en el panel de fila) */
.db-arch-thumbs { display: inline-flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.db-arch-thumb { width: 30px; height: 30px; object-fit: cover; border-radius: var(--r); border: 1px solid var(--line2); flex: none; }
.db-arch-mas { font-size: var(--t-meta); color: var(--muted); }
.db-arch-edit { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.db-arch-cell { position: relative; width: 68px; height: 68px; }
.db-arch-cell img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--r); border: 1px solid var(--line2); }
.db-arch-x { position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; border-radius: 50%; border: 0; background: var(--ink); color: var(--paper); font-size: var(--t-meta); cursor: pointer; line-height: 1; }
.db-arch-add { border: 1px dashed var(--line2); background: transparent; color: var(--muted); border-radius: var(--r); height: 68px; min-width: 68px; padding: 0 12px; cursor: pointer; font-size: var(--t-meta); }
@media (hover:hover){ .db-arch-add:hover{ border-color: var(--accent); color: var(--accent); } }
.db-arch-add[disabled] { opacity: .6; cursor: default; }

/* ==================================================================
   DISENADOR DE ALBUM (album-engine.js + vista album-diseno)
   ================================================================== */
.aeng-cell{ box-sizing:border-box; }
.aeng-cell.aeng-empty .aeng-drop{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  border:1px dashed var(--hair); color:var(--muted); font-size:var(--t-meta); background:color-mix(in srgb,var(--accent) 4%,transparent); }
.aeng-cell.aeng-sel{ outline:2px solid var(--accent); outline-offset:-2px; z-index:5; }
.aeng-cell.al-over{ outline:2px solid var(--blue); outline-offset:-2px; }
.aeng-img{ pointer-events:none; }

/* Riel de acomodos alternativos: las miniaturas nunca traen fotoUrl (siempre geometria
   pura, ver pintarRiel en app.js), asi que .aeng-empty nunca pinta su .aeng-drop interno
   (eso solo pasa con opts.interactivo). Regla propia y aislada -- no toca el editor real. */
.al-riel-panel .aeng-cell.aeng-empty{ border:1px dashed var(--hair); background:color-mix(in srgb,var(--accent) 4%,transparent); }
.al-riel-panel{ border-top:1px solid var(--hair); background:var(--paper); padding:12px 20px 14px; flex:none; }
.al-riel-panel[hidden]{ display:none; }

/* Se ancla a .main (la columna del CRM), NO al viewport. Antes era
   `position:fixed; inset:56px 0 0 0`, que daba por hechas dos cosas falsas: que la barra
   de navegacion mide 56px (mide 74 cuando las pestanas se van a dos renglones, asi que el
   editor se le montaba encima y la recortaba) y que a la izquierda no hay nada (hay 432px
   de chat de Xarpie, que quedaba tapado). Anclado a .main las dos medidas salen solas del
   layout y no hay numero que mantener.
   Para que quede DEBAJO de la nav sin escribir su alto, .main pasa a columna flex y el
   editor va en el hueco que sobra (.main > #view crece). Se probo antes midiendo la nav
   desde JS y publicandola en una variable, pero eso obliga a acertarle a cada momento en
   que la nav cambia de alto (breakpoint, menu personalizable, fuentes que cargan tarde) y
   cualquier aviso que se escape deja al editor tapando la nav otra vez. */
.aled{ position:absolute; inset:0; display:flex; background:var(--bone); z-index:40; }
/* requestFullscreen() promueve .aled entero (no viola la regla de overlays absolute-no-
   fixed de arriba: la API cambia el elemento a pantalla completa, no le pone position:
   fixed). El ::backdrop que el navegador pinta detras es NEGRO por default para
   cualquier elemento, no solo video -- sin esto se veria un marco negro en vez del
   bone/paper del editor. */
.aled:fullscreen{ background:var(--bone); }
.aled:fullscreen::backdrop{ background:var(--bone); }
.main{ display:flex; flex-direction:column; }
/* flex:1 0 auto y no 1 1 auto: crecer para llenar la columna SI, pero encogerse no —
   con shrink activo una pagina larga se comprimiria y se cortaria por dentro en vez de
   dejar scrollear a .main, que es como se ha comportado siempre. */
.main > #view{ flex:1 0 auto; position:relative; }
/* Con el editor montado, #view deja de ser el contenedor de pagina (ancho maximo y
   margenes) y se vuelve el marco del editor: si no, el album quedaria en una caja de
   1180px con franjas a los lados. */
.main > #view:has(.aled), .main > #view:has(.calfull), .main > #view:has(.pp-editor){ max-width:none; padding:0; overflow:visible; }
/* Mientras el editor esta montado la columna no scrollea: es de alto completo y lo unico
   que quedaria por debajo es el padding vacio de .wrap. */
.main:has(.aled), .main:has(.calfull), .main:has(.pp-editor){ overflow:hidden; }
.al-railtoggle{ display:none; }
.al-railbg{ display:none; }
@media (max-width:900px){
  /* En telefono si se come la nav: la pantalla no alcanza para las dos cosas. */
  .aled{ inset:0; }
  /* El rail pasa a drawer lateral (el apilado en columna dejaba el canvas fuera de pantalla). */
  .al-rail{ position:fixed; left:0; top:0; bottom:0; z-index:60; transform:translateX(-100%); transition:transform .22s ease; box-shadow:12px 0 34px -18px rgba(0,0,0,.4); width:min(88vw,360px); }
  .al-rail.open{ transform:translateX(0); }
  .al-railtoggle{ display:inline-block; }
  .al-railbg.show{ display:block; position:fixed; inset:0; z-index:55; background:rgba(43,41,38,.42); }
  .al-spreadbar{ gap:10px; }
  .al-cellbar.on{ flex-wrap:wrap; padding:8px 12px; gap:8px; }
}
.al-rail{ width:360px; flex:none; border-right:1px solid var(--hair); background:var(--paper); display:flex; flex-direction:column; }
.al-railtop{ padding:16px 18px 12px; border-bottom:1px solid var(--hair); }
.al-crumb{ border:0; background:none; color:var(--muted); font-size:var(--t-texto); cursor:pointer; padding:0; display:flex; align-items:center; gap:4px; }
@media (hover:hover){ .al-crumb:hover{ color:var(--ink); } }
.al-bk{ font-size:var(--t-sub); }
.al-title{ width:100%; border:0; background:none; font-family:var(--serif,Newsreader,Georgia,serif); font-size:var(--t-titulo); color:var(--ink); margin:8px 0 4px; padding:2px 0; }
.al-title:focus{ outline:0; border-bottom:1px solid var(--accent); }
.al-statusrow{ display:flex; gap:8px; }
.al-pill{ font-size:var(--t-meta); color:var(--muted); }
.al-save{ font-size:var(--t-meta); color:var(--sage,#6E7F63); margin-top:6px; min-height:16px; }
.al-railscroll{ flex:1; overflow-y:auto; padding:6px 18px 40px; }
.al-sec{ padding:16px 0; border-bottom:1px solid var(--hair); }
.al-sec:last-child{ border-bottom:0; }
.al-sechd{ display:flex; align-items:center; gap:9px; margin-bottom:12px; }
.al-ix{ width:20px; height:20px; border-radius:50%; background:var(--bone); border:1px solid var(--hair); color:var(--muted); font-size:var(--t-meta); display:flex; align-items:center; justify-content:center; }
.al-n{ font-family:var(--serif,Newsreader,Georgia,serif); font-size:var(--t-texto); }
.al-hint{ font-size:var(--t-meta); color:var(--muted); margin-top:8px; }
/* ---- Panel de Auto-diseño ampliado (Forma / Que fotos / Ritmo / Estilo / Vista previa) ---- */
.al-adsec{ margin:16px 0; padding-top:14px; border-top:1px solid var(--hair); }
.al-adsec:first-of-type{ margin-top:14px; padding-top:0; border-top:none; }
.al-adsec-h{ font-size:var(--t-meta); font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--muted); margin-bottom:9px; }
.al-adforma{ display:flex; align-items:center; gap:10px; width:100%; text-align:left; padding:10px 12px; border:1px solid var(--hair); border-radius:var(--r); background:var(--paper); cursor:pointer; font-size:var(--t-texto); color:var(--ink); }
@media (hover:hover){ .al-adforma:hover{ border-color:var(--accent); } }
.al-adforma svg{ flex:none; color:var(--muted); }
.al-adforma span:nth-child(2){ flex:1; }
.al-adforma-cambiar{ font-size:var(--t-meta); color:var(--accent); }
.al-adchecks{ display:flex; flex-wrap:wrap; gap:6px 14px; }
.al-adcheck{ display:flex; align-items:center; gap:6px; font-size:var(--t-meta); color:var(--ink); cursor:pointer; }
.al-adcheck.off{ color:var(--muted); cursor:default; }
.al-adcheck input{ margin:0; }
.al-adnodisp{ font-weight:400; text-transform:none; letter-spacing:0; font-size:var(--t-meta); color:var(--muted); }
.al-adprev{ margin-top:16px; padding:12px; border-radius:var(--r); background:var(--bone); }
.al-adprev #al-ad-overview{ margin-top:0; }
.al-adprev-vacio{ font-size:var(--t-meta); color:var(--muted); margin-top:8px; }
.al-adprev-resumen{ font-size:var(--t-texto); font-weight:600; margin-top:10px; }
.al-adprev-muestra{ display:flex; flex-direction:column; gap:4px; margin-top:8px; }
.al-adprev-item{ display:flex; justify-content:space-between; font-size:var(--t-meta); color:var(--muted); padding:4px 8px; background:var(--paper); border-radius:var(--r); }
.al-adprev-mom{ color:var(--ink); }
/* El layout de .al-pool (carrusel de una fila) vive mas abajo, junto a .al-poolzone: es
   el unico lugar donde esta franja se dibuja. Aqui solo queda el aspecto de CADA foto. */
.al-poto{ position:relative; aspect-ratio:1; border-radius:var(--r); overflow:hidden; cursor:grab; border:1px solid var(--hair); }
.al-poto img{ width:100%; height:100%; object-fit:cover; display:block; }
.al-poto.usada{ opacity:.5; }
/* Poolbar Fundy: acciones, filtro, orden, vista. */
.al-poolactions{ display:flex; gap:6px; margin-bottom:8px; flex-wrap:wrap; }
/* Progreso de la subida dentro del rail: reusa .gal-prog-* de la galeria, para que subir
   fotos se vea igual en los dos lados. */
.al-addprog{ margin:0 0 10px; }
.al-tb-sm{ font-size:var(--t-meta); padding:4px 9px; }
/* "Armar con Xarpie" es la accion principal del rail: da el mejor resultado (mira las fotos)
   y por eso se distingue del auto-diseño determinista, que queda como la alternativa rapida. */
.al-tb-xarpie{ background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); }
@media (hover:hover){ .al-tb-xarpie:hover:not(:disabled){ filter:brightness(1.08); } }
.al-poolbar{ display:flex; gap:6px; align-items:center; margin-bottom:8px; }
.al-select-sm{ padding:5px 8px; font-size:var(--t-meta); flex:1; min-width:0; }
.al-ib-sm{ width:26px; height:26px; font-size:var(--t-texto); flex:none; }
.al-ib-sm.on{ color:var(--accent); border-color:var(--accent); }
.al-fbadge{ display:inline-flex; align-items:center; justify-content:center; min-width:15px; height:15px; margin-left:5px; border-radius:var(--r); background:var(--accent-solido); color:var(--accent-tinta); font-size:var(--t-eti); padding:0 3px; }
.al-fbadge[hidden]{ display:none; }
.al-filterpanel{ border:1px solid var(--hair); border-radius:var(--r); padding:10px; margin-bottom:10px; background:var(--paper); }
.al-frow{ display:flex; align-items:center; gap:10px; margin-bottom:8px; }
.al-fheart{ border:1px solid var(--hair); background:var(--bone); color:var(--muted); border-radius:var(--r); width:30px; height:26px; cursor:pointer; font-size:var(--t-texto); }
.al-fheart.on{ color:var(--accent-tinta); background:var(--accent-solido); border-color:var(--accent-solido); }
.al-fstars{ display:flex; gap:2px; }
.al-fstar{ border:0; background:none; color:var(--line2); font-size:var(--t-sub); cursor:pointer; padding:0 2px; }
.al-fstar.on{ color:var(--yellow); }
/* Estrellas y corazon sobre el thumbnail (hover). */
.al-poto-meta{ position:absolute; left:0; right:0; bottom:0; display:none; align-items:center; justify-content:space-between; gap:4px; padding:3px 5px; background:linear-gradient(transparent, rgba(21,19,16,.75)); }
@media (hover:hover){ .al-poto:hover .al-poto-meta{ display:flex; } }
.al-pheart{ border:0; background:none; color:rgba(255,255,255,.55); font-size:var(--t-texto); cursor:pointer; padding:0; }
.al-pheart.on{ color:var(--accent); }
.al-pstars{ display:flex; }
.al-pstar{ border:0; background:none; color:rgba(255,255,255,.45); font-size:var(--t-meta); cursor:pointer; padding:0 1px; }
.al-pstar.on{ color:var(--yellow); }
/* Spreadbar: configuracion del spread actual bajo la toolbar. */
.al-spreadbar{ display:flex; align-items:center; gap:14px; padding:9px 20px; border-bottom:1px solid var(--hair); background:var(--paper); flex-wrap:wrap; }
.al-spreadbar[hidden]{ display:none; }
/* Empuja el grupo de zoom a la derecha de la barra sin tocar el resto de sus gaps. */
.al-sbgap{ flex:1; min-width:8px; }
/* min-width fijo + tabular-nums: el % cambia con cada muesca de rueda; sin ancho fijo
   los botones de al lado bailarian en cada frame. */
.al-zpct{ font-size:var(--t-meta); color:var(--muted); min-width:44px; text-align:center; font-variant-numeric:tabular-nums; }
.al-sblbl{ font-size:var(--t-meta); color:var(--muted); }
.al-sw-sm{ width:20px; height:20px; }
.al-swcustom{ width:24px; height:24px; padding:0; border:1px solid var(--hair); border-radius:50%; background:none; cursor:pointer; }
.al-swcustom::-webkit-color-swatch-wrapper{ padding:2px; }
.al-swcustom::-webkit-color-swatch{ border:0; border-radius:50%; }
.al-sldr{ display:flex; align-items:center; gap:7px; font-size:var(--t-meta); color:var(--muted); }
.al-sldr input[type=range]{ width:90px; accent-color:var(--accent); }
/* Slider sin efecto en este pliego (el margen de un pliego "bandas" lo elige el acomodo,
   ver pintarSpreadbar): se ve apagado pero NO se esconde -- esconderlo haria brincar la
   barra entera cada vez que se pasa de un pliego del catalogo a uno de tu estilo. */
.al-sldr-off{ opacity:.45; }
.al-sldr-off input[type=range]{ cursor:not-allowed; }
.al-txtedit{ z-index:9; border:2px solid var(--accent); border-radius:2px; background:rgba(252,251,247,.92); padding:1%; resize:none; outline:none; white-space:pre-wrap; box-sizing:border-box; }
/* Edicion libre de celda: overlay con handles de resize + pill de mover (en el host, no
   recortado por el overflow de la celda). */
.aeng-editov{ outline:2px solid var(--accent); outline-offset:-1px; }
.aeng-handle{ position:absolute; width:12px; height:12px; background:#fff; border:2px solid var(--accent); border-radius:2px; transform:translate(-50%,-50%); z-index:8; }
.aeng-h-nw,.aeng-h-se{ cursor:nwse-resize; }
.aeng-h-ne,.aeng-h-sw{ cursor:nesw-resize; }
.aeng-h-n,.aeng-h-s{ cursor:ns-resize; }
.aeng-h-e,.aeng-h-w{ cursor:ew-resize; }
.aeng-move{ position:absolute; left:50%; top:0; transform:translate(-50%,-150%); background:var(--accent-solido); color:var(--accent-tinta); border-radius:var(--r); padding:3px 10px; font-size:var(--t-meta); cursor:move; z-index:9; white-space:nowrap; box-shadow:0 2px 8px rgba(43,41,38,.3); user-select:none; }
/* Guia de imantado: aparece solo mientras se arrastra y solo cuando engancho. Es una
   linea de 1px sin sombra a proposito -- tiene que leerse como una regla de alineacion,
   no como parte del diseno del album. */
.aeng-guiaiman{ position:absolute; background:var(--accent); opacity:.85; pointer-events:none; z-index:10; }
/* Popover de configuracion de guias. */
.al-guias-pop{ position:absolute; top:calc(100% + 6px); right:0; z-index:60; width:250px; background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); box-shadow:0 14px 40px rgba(43,41,38,.22); padding:12px 14px; }
.al-gph{ font-family:var(--serif,Newsreader,Georgia,serif); font-size:var(--t-texto); margin-bottom:10px; }
.al-grow{ display:flex; align-items:center; gap:7px; font-size:var(--t-texto); padding:5px 0; color:var(--ink); }
.al-grow input[type=checkbox]{ flex:none; }
.al-gnum{ width:52px; margin-left:auto; padding:3px 6px; border:1px solid var(--hair); border-radius:var(--r); background:var(--bone); font-size:var(--t-texto); text-align:right; }
.al-gph2{ font-size:var(--t-meta); color:var(--muted); margin-top:8px; line-height:1.4; }
.al-fitseg{ display:inline-flex; gap:4px; }
.al-locked{ position:absolute; inset:0; z-index:8; display:flex; align-items:flex-start; justify-content:flex-end; padding:10px; background:rgba(43,41,38,.06); pointer-events:auto; cursor:not-allowed; }
.al-locked span{ font-size:var(--t-meta); background:rgba(43,41,38,.75); color:#fff; padding:4px 10px; border-radius:var(--r); }
.al-lockbadge{ position:absolute; top:4px; right:6px; font-size:var(--t-meta); }
/* Seccion Album del rail: resumen con mini portada. */
.al-rescover{ aspect-ratio:16/10; border-radius:var(--r); display:flex; align-items:center; justify-content:center; padding:14px; text-align:center; }
.al-rescover span{ font-family:var(--serif,Newsreader,Georgia,serif); font-size:var(--t-texto); line-height:1.3; }
/* Wizard "Opciones del album" (3 pasos). */
.al-wsteps{ display:flex; gap:14px; margin-bottom:16px; flex-wrap:wrap; }
.al-wstep{ display:flex; align-items:center; gap:7px; font-size:var(--t-texto); color:var(--muted); }
.al-wstep i{ font-style:normal; width:22px; height:22px; border-radius:50%; border:1px solid var(--hair); display:flex; align-items:center; justify-content:center; font-size:var(--t-meta); background:var(--bone); }
.al-wstep.on{ color:var(--ink); font-weight:600; }
.al-wstep.on i{ background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); }
.al-wstep.done i{ background:var(--blue); border-color:var(--blue); color:#fff; }
.alw-presets{ display:grid; grid-template-columns:repeat(auto-fill,minmax(170px,1fr)); gap:8px; }
.alw-preset{ text-align:left; border:1px solid var(--hair); border-radius:var(--r); background:var(--paper); padding:11px 13px; cursor:pointer; display:flex; flex-direction:column; gap:3px; }
.alw-preset b{ font-size:var(--t-texto); font-weight:600; }
.alw-preset span{ font-size:var(--t-meta); color:var(--muted); }
.alw-preset.on{ border-color:var(--accent); box-shadow:0 0 0 1px var(--accent); }
/* Vive DENTRO de .alw-preset (que ya es clickeable para elegir el tamano); su propio
   listener hace stopPropagation para no disparar tambien la seleccion del preset. */
.alw-preset-def{ font-size:var(--t-eti); color:var(--muted); margin-top:1px; }
@media (hover:hover){ .alw-preset-def:hover{ color:var(--ink); text-decoration:underline; } }
.alw-preset-def.on{ color:var(--accent); font-weight:600; }
/* ---- Guia de contrato por pasos (public/contrato-guia.js) ----
   Reusa .al-wsteps/.al-wstep de arriba (el wizard del album) y .alw-preset para las
   tarjetas de "elegir o crear": son componentes genericos, no exclusivos del album.

   El overflow:visible NO es cosmetico. .widget tiene overflow:hidden y el dropdown
   del buscador de clientes (.cp-drop) es position:absolute con max-height:280px --
   sin esto queda CORTADO en el borde de la tarjeta, y el buscador es lo primero que
   toca el fotografo. wlCardSuelta pone data-wid, asi que el selector pega justo. */
.widget[data-wid="contrato_guia"]{ overflow:visible; }
.widget[data-wid="contrato_guia"] .w-body{ overflow:visible; }
.cg-steps{ margin-bottom:14px; }
.cg-tit{ font-size:var(--t-texto); font-weight:600; margin:0 0 3px; }
.cg-ayuda{ font-size:var(--t-meta); color:var(--muted); margin:0 0 14px; line-height:1.5; }
/* min-height para que la tarjeta no salte de alto entre pasos: en el chat eso
   dispara el ResizeObserver que re-ancla el scroll y se siente a brinco. */
.cg-body{ min-height:184px; }
.cg-foot{ display:flex; gap:10px; align-items:center; margin-top:16px; padding-top:14px; border-top:1px solid var(--hair); }
.cg-nota{ font-size:var(--t-meta); color:var(--muted); margin:8px 0 0; line-height:1.5; }
.cg-aviso{ font-size:var(--t-meta); color:var(--muted); background:var(--bone); border-radius:var(--r); padding:8px 10px; margin-top:8px; line-height:1.5; }
.cg-ok{ text-align:center; padding:14px 0 6px; }
.cg-ok-tit{ font-size:var(--t-campo); font-weight:600; margin:0 0 4px; }
.cg-ok-sub{ font-size:var(--t-texto); color:var(--muted); margin:0 0 16px; }
/* La tarjeta vive en el chat, que puede quedar en ~270px de ancho util. .frow es una
   rejilla de 2 columnas que solo colapsa por ancho de VENTANA, inutil aqui. .wsuelto
   ya trae container-type:inline-size, asi que se puede consultar el contenedor. */
@container (max-width: 430px){
  .cg .frow{ grid-template-columns:1fr; }
  .cg-steps{ gap:8px; font-size:var(--t-meta); }
  .cg-steps .al-wstep i{ width:19px; height:19px; font-size:var(--t-eti); }
}
.alw-cpool{ display:flex; gap:6px; flex-wrap:wrap; max-height:120px; overflow-y:auto; }
.alw-cfoto{ width:46px; height:46px; border-radius:var(--r); overflow:hidden; border:2px solid transparent; padding:0; background:var(--bone); cursor:pointer; font-size:var(--t-eti); color:var(--muted); }
.alw-cfoto img{ width:100%; height:100%; object-fit:cover; display:block; }
.alw-cfoto.on{ border-color:var(--accent); }
.alw-cover-preview{ flex:0 0 190px; }
.alw-cpv{ width:190px; aspect-ratio:1; border-radius:var(--r); display:flex; align-items:center; justify-content:center; padding:14px; text-align:center; position:relative; overflow:hidden; box-shadow:0 6px 22px rgba(43,41,38,.18); }
.alw-cpv img{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; opacity:.85; }
.alw-cpv span{ position:relative; font-family:var(--serif,Newsreader,Georgia,serif); font-size:var(--t-texto); line-height:1.3; text-shadow:0 1px 8px rgba(0,0,0,.25); }
.alw-rev .payline{ display:flex; justify-content:space-between; padding:7px 0; border-bottom:1px solid var(--hair); font-size:var(--t-texto); }
.al-poto .al-badge{ position:absolute; top:3px; right:3px; background:var(--blue); color:#fff; font-size:var(--t-eti); width:15px; height:15px; border-radius:50%; display:flex; align-items:center; justify-content:center; }
.al-segs{ display:flex; gap:6px; flex-wrap:wrap; margin-bottom:10px; }
.al-seg{ font-size:var(--t-meta); padding:3px 10px; border-radius:var(--r); border:1px solid var(--hair); background:var(--bone); color:var(--muted); cursor:pointer; }
.al-seg.on{ color:var(--accent); border-color:var(--accent); }
.al-tpls{ display:grid; grid-template-columns:repeat(4,1fr); gap:7px; }
.al-tpl{ aspect-ratio:2/1; border:1px solid var(--hair); border-radius:var(--r); background:var(--bone); cursor:pointer; padding:3px; position:relative; }
.al-tpl.on{ border-color:var(--accent); box-shadow:0 0 0 1px var(--accent); }
.al-tplprev{ position:absolute; inset:3px; }
.al-tplprev i{ position:absolute; background:color-mix(in srgb,var(--sage) 45%,var(--paper)); border-radius:1px; }
.al-select,.al-txt{ width:100%; padding:9px 11px; border:1px solid var(--hair); border-radius:var(--r); background:var(--paper); color:var(--ink); font-size:var(--t-texto); }
.al-swrow{ display:flex; gap:8px; margin-top:8px; }
.al-sw{ width:26px; height:26px; border-radius:50%; border:2px solid var(--hair); cursor:pointer; }
.al-sw.on{ border-color:var(--accent); box-shadow:0 0 0 2px var(--paper),0 0 0 3px var(--accent); }

.al-main{ flex:1; display:flex; flex-direction:column; min-width:0; }
.al-canvastop{ display:flex; align-items:center; justify-content:space-between; gap:16px; padding:10px 20px; border-bottom:1px solid var(--hair); flex-wrap:wrap; }
.al-ctleft{ display:flex; align-items:center; gap:14px; min-width:0; }
.al-navspread{ display:flex; align-items:center; gap:6px; font-size:var(--t-texto); }
#al-spreadn{ min-width:88px; text-align:center; color:var(--muted); font-size:var(--t-texto); white-space:nowrap; }
.al-undogrp{ display:flex; gap:4px; padding-left:14px; border-left:1px solid var(--hair); }
.al-ib:disabled{ opacity:.32; cursor:default; }
@media (hover:hover){ .al-ib:disabled:hover{ border-color:var(--hair); color:inherit; } }
/* Botones agrupados (Guías + config) y CTA primaria. Se cualifican con .al-toolbar para
   ganarle a .al-tb (declarado despues en el archivo). */
.al-guiaswrap{ display:inline-flex; position:relative; }
.al-toolbar .al-tb-split{ border-top-right-radius:0; border-bottom-right-radius:0; }
.al-toolbar .al-tb-caret{ border-top-left-radius:0; border-bottom-left-radius:0; border-left:0; padding:6px 8px; font-size:var(--t-eti); }
.al-toolbar .al-tb-p{ background:var(--accent-solido); border-color:var(--accent-solido); color:var(--accent-tinta); }
@media (hover:hover){ .al-toolbar .al-tb-p:hover{ border-color:var(--accent-solido); filter:brightness(1.05); } }
.al-ib{ width:30px; height:30px; border-radius:var(--r); border:1px solid var(--hair); background:var(--paper); cursor:pointer; font-size:var(--t-campo); color:var(--ink); }
@media (hover:hover){ .al-ib:hover{ border-color:var(--accent); } }
.al-toolbar{ display:flex; gap:8px; align-items:center; flex-wrap:wrap; }
/* Sin esto el grupo de proporcion se comprime hasta dejar el select en "1∨" y parte
   "Enviar al cliente" en dos renglones: un control que no deja leer su propio valor no
   sirve de nada. No encoge, y si no cabe la barra baja de renglon. */
.al-toolbar .al-prop{ flex:none; gap:6px; }
.al-toolbar .al-prop .al-select{ width:auto; min-width:74px; }
.al-toolbar .al-tb{ white-space:nowrap; }
.al-tb{ font-size:var(--t-texto); padding:6px 12px; border-radius:var(--r); border:1px solid var(--hair); background:var(--paper); color:var(--ink); cursor:pointer; }
.al-tb.on{ color:var(--accent); border-color:var(--accent); }
@media (hover:hover){ .al-tb:hover{ border-color:var(--accent); } }
/* overflow:auto + centrado por margin:auto del HIJO (no por align/justify del padre):
   con el pliego mas grande que el stage (zoom > fit), los margenes auto colapsan a 0 y
   el scroll arranca en la esquina superior izquierda -- centrarlo con flex recortaba el
   inicio del pliego por los 4 lados, invisible e inalcanzable con scroll. Con el pliego
   mas chico que el stage (fit normal) se ve identico a como se veia con flex centrado. */
.al-stage{ flex:1; display:flex; padding:20px; overflow:auto; background:color-mix(in srgb,var(--ink) 4%,var(--bone)); }
.al-stage-zoom, .al-stage-pan{ cursor:grab; }
.al-stage-zoom:active, .al-stage-pan:active{ cursor:grabbing; }
.al-spread{ box-shadow:0 10px 40px rgba(43,41,38,.18); margin:auto; flex:none; }
.al-cellbar{ min-height:0; display:none; align-items:center; gap:14px; padding:0 20px; }
.al-cellbar.on{ display:flex; min-height:48px; border-top:1px solid var(--hair); }
.al-zoom{ font-size:var(--t-texto); color:var(--muted); display:flex; align-items:center; gap:8px; }
/* Mismo peso visual que .al-zoom: son los dos controles con etiqueta de la barra. */
.al-prop{ font-size:var(--t-texto); color:var(--muted); display:flex; align-items:center; gap:8px; }
.al-strip{ display:flex; gap:10px; align-items:center; padding:14px 20px; border-top:1px solid var(--hair); overflow-x:auto; background:var(--paper); }
/* ---------- Editor de albumes sin rail: fotos abajo, vistas a pantalla completa ---------- */
/* La cabecera pasa de columna (en el rail) a fila: el titulo ya no puede ocupar el 100%. */
.al-ctleft .al-title{ width:auto; max-width:230px; margin:0; font-size:var(--t-sub); }
.al-ctleft .al-crumb{ white-space:nowrap; max-width:170px; overflow:hidden; text-overflow:ellipsis; display:block; }
.al-ctleft .al-save{ margin-top:0; }
.al-ctleft{ flex-wrap:wrap; gap:10px; }

/* Envuelve stage+cellbar+poolzone. position:relative para que .al-vistasfull (absoluta,
   inset:0) cubra EXACTAMENTE esta zona sin depender del alto de al-canvastop (que
   cambia con el ancho de la ventana: ya nos mordio medirlo a mano una vez). */
.al-editarea{ flex:1; display:flex; flex-direction:column; min-height:0; position:relative; }

/* Segunda vuelta: la primera version de esta franja era una REJILLA que envolvia a
   varias filas -- con muchas fotos del evento eso las amontonaba visualmente (el reporte
   con la captura). Ahora es un CARRUSEL de una sola fila: no hay "muchas filas" que
   puedan amontonarse, hay una que se desplaza a los lados. Por eso .al-poolzone ya no
   necesita el tope fijo de la version anterior (max-height:38vh): con una sola fila su
   alto ya esta acotado por diseno, sin importar cuantas fotos tenga el evento. */
.al-poolzone{ border-top:1px solid var(--hair); background:var(--paper); padding:12px 20px 14px; display:flex; flex-direction:column; gap:8px; flex:0 0 auto; }
.al-poolzone .al-poolbar{ margin-bottom:0; flex-wrap:wrap; }
.al-poolgap{ flex:1; }
/* Contenedor del carrusel: las flechas se superponen a los bordes de la tira, no ocupan
   su propio espacio -- asi no le restan ancho a las fotos. */
.al-poolstrip{ position:relative; }
.al-poolnav{ position:absolute; top:0; bottom:0; z-index:5; width:34px; border:0; cursor:pointer; display:flex; align-items:center; justify-content:center; font-size:var(--t-sub); color:var(--ink); background:linear-gradient(var(--dir,to right), var(--paper) 30%, transparent); }
.al-poolnav-l{ left:0; --dir:to right; }
.al-poolnav-r{ right:0; --dir:to left; }
@media (hover:hover){ .al-poolnav:hover{ color:var(--accent); } }
/* Una sola fila que se desplaza a los lados (scroll horizontal), NO una rejilla que
   envuelve. El tamano lo elige el usuario en el toolbar del pool, y como es una sola
   fila, cambiar --poto cambia el alto del carrusel Y el de las fotos con el mismo
   control: no hace falta uno aparte para cada cosa. */
.al-poolzone .al-pool{ display:flex; flex-wrap:nowrap; align-items:flex-start; gap:8px; overflow-x:auto; overflow-y:hidden; padding-bottom:2px; }
.al-poto{ flex:none; width:var(--poto,130px); height:var(--poto,130px); }
.al-pool.tam-s{ --poto:86px; }
.al-pool.tam-m{ --poto:130px; }
.al-pool.tam-l{ --poto:190px; }
/* Con las fotos grandes las estrellas dejan de esconderse tras el hover: calificar es
   justo lo que se viene a hacer aqui, y un control invisible no se usa. */
.al-pool.tam-l .al-poto-meta{ display:flex; }
/* "Ver proporcion real" (▤): cada foto conserva SU aspecto en vez del recorte cuadrado.
   Antes esto era un mosaico de 2 columnas (columns:2) que no tenia sentido dentro de un
   carrusel de una fila. Aqui el alto queda fijo (=--poto, igual que el modo recortado) y
   el ANCHO lo decide la imagen: object-fit:contain dentro de una caja cuadrada, asi la
   foto no se deforma y el carrusel no pierde su alineacion de una sola fila. */
.al-pool.prop .al-poto img{ object-fit:contain; background:color-mix(in srgb, var(--ink) 5%, transparent); }

/* Popover chico que sigue quedando: ⚙ Álbum. Mismo molde que .al-guias-pop. */
.al-pop-wrap{ position:relative; display:inline-flex; }
.al-pop{ position:absolute; top:calc(100% + 6px); left:0; z-index:60; width:330px; max-height:min(70vh,560px); overflow-y:auto; background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); box-shadow:0 14px 40px rgba(43,41,38,.22); padding:14px; }
.al-pop[hidden]{ display:none; }
/* #al-exportpop vive mas a la derecha del toolbar que #al-albumpop (justo antes de
   "Enviar al cliente"): con el left:0 de arriba se salia del viewport a 1280px. Mismo
   ajuste que ya usa .al-guias-pop para su boton, tambien cerca del borde derecho. */
#al-exportpop{ left:auto; right:0; }

/* ---------- Vistas: pantalla completa, NO un popover ---------- */
/* Cubre .al-editarea entera (stage+cellbar+poolzone), dejando la barra de arriba
   (al-canvastop) visible y usable -- el boton que la cierra vive ahi mismo. */
.al-vistasfull{ position:absolute; inset:0; z-index:50; background:var(--bone); display:flex; flex-direction:column; }
.al-vistasfull[hidden]{ display:none; }
.al-vf-head{ display:flex; align-items:center; justify-content:space-between; gap:16px; padding:14px 20px; border-bottom:1px solid var(--hair); flex:none; }
.al-vf-body{ flex:1; min-height:0; overflow-y:auto; padding:20px; }
/* Familias (Clasica/Con principal/...) dentro de la pantalla de plantillas. */
.al-vf-body .al-segs{ flex-wrap:wrap; margin-bottom:16px; }
/* Galeria de plantillas GRANDE: cada tarjeta trae un renderThumb de 300px con las fotos
   REALES de este pliego ya puestas (ver pintarTplsGrande) -- comparar de verdad, no
   adivinar por un icono abstracto. */
.al-tplgrid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:20px; }
.al-tplcard{ display:flex; flex-direction:column; gap:8px; align-items:center; background:none; border:2px solid transparent; border-radius:var(--r); padding:10px; cursor:pointer; }
@media (hover:hover){ .al-tplcard:hover{ border-color:var(--line2); } }
.al-tplcard.on{ border-color:var(--accent); }
.al-tplcardprev{ border-radius:var(--r); overflow:hidden; box-shadow:0 2px 10px rgba(43,41,38,.14); }
.al-tplcardname{ font-size:var(--t-meta); color:var(--muted); }
/* Panel "Tu estilo": casilla del lomo y marca de las variantes que no lo tocan. El verde
   es informativo (no es un estado de exito), por eso va solo en el texto, sin fondo. */
.al-lomochk{ display:inline-flex; align-items:center; gap:6px; cursor:pointer; }
.al-lomochk input{ margin:0; }
.al-hint-sm{ font-size:var(--t-meta); color:var(--muted); }
.al-oklomo{ color:var(--ok,#4b7f52); }
/* "Ajustado a las fotos": columna angosta para elegir fotos (izquierda) + resultados a la
   derecha, con mas aire (columnas anchas: son pocas variantes, no 22 plantillas). */
.al-ajust{ display:grid; grid-template-columns:280px 1fr; gap:24px; align-items:start; height:100%; }
.al-ajust-side{ position:sticky; top:0; }
.al-ajust-resumen{ font-size:var(--t-texto); color:var(--muted); margin-bottom:12px; line-height:1.5; }
.al-ajust-resumen b{ color:var(--ink); }
.al-ajust-grid{ display:grid; grid-template-columns:repeat(3,1fr); gap:6px; max-height:60vh; overflow-y:auto; }
.al-ajustfoto{ position:relative; aspect-ratio:1; border-radius:var(--r); overflow:hidden; border:2px solid transparent; padding:0; cursor:pointer; background:none; }
.al-ajustfoto img{ width:100%; height:100%; object-fit:cover; display:block; }
.al-ajustfoto.on{ border-color:var(--accent); }
.al-ajustfoto.on img{ opacity:.55; }
.al-ajustcheck{ position:absolute; inset:0; display:flex; align-items:center; justify-content:center; color:#fff; font-size:var(--t-titulo); text-shadow:0 1px 4px rgba(0,0,0,.5); }
.al-ajust-resultados{ display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:20px; align-content:start; }
.al-ajust-resultados .al-tplcardprev{ background:var(--paper); }
@media (max-width:900px){ .al-ajust{ grid-template-columns:1fr; } .al-ajust-side{ position:static; } }
/* Mosaico de "Todos los pliegos": reusa .al-strip (el mismo motor de dibujo de siempre),
   solo que en rejilla grande y llenando la pantalla en vez de tira horizontal chica. */
.al-strip.grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); align-items:start; align-content:start; gap:20px; padding:0; border-top:0; background:transparent; }
.al-strip.grid .al-sthumb{ width:100%; }
.al-sthumb{ position:relative; flex:none; cursor:pointer; border:2px solid transparent; border-radius:4px; padding:2px; }
.al-sthumb.on{ border-color:var(--accent); }
.al-sthost{ box-shadow:0 1px 3px rgba(43,41,38,.15); border-radius:2px; overflow:hidden; }
.al-sn{ position:absolute; bottom:4px; left:6px; font-size:var(--t-eti); color:#fff; background:rgba(43,41,38,.6); padding:1px 5px; border-radius:var(--r); }
.al-addspread{ flex:none; height:58px; padding:0 16px; border:1px dashed var(--hair); border-radius:var(--r); background:var(--bone); color:var(--muted); cursor:pointer; font-size:var(--t-texto); }
@media (hover:hover){ .al-addspread:hover{ border-color:var(--accent); color:var(--accent); } }

/* ============================================================================
   CHAT COMO SUPERFICIE PRINCIPAL (F1)
   El chat deja de ser una columna lateral y pasa a ser la parte ancha; el CRM
   queda a la derecha con un ancho de trabajo real. Va al FINAL del archivo a
   proposito: .chatpane esta definida dos veces (lineas 57 y 1233) y gana la
   ultima, asi que editar el bloque base no se veria.
   Todo lo de escritorio va dentro de min-width:861px para NO pisar el cajon
   movil (@media max-width:860px, linea 441), que se declara antes y perderia.
   ============================================================================ */
@media (min-width:861px){
  /* INVERTIDO (2026-08-03): antes el chat crecia para llenar todo lo que sobrara y el CRM
     tomaba un ancho fijo. En una pantalla de 1512px eso dejaba el chat en ~900px: una
     columna de conversacion mas ancha que el CRM entero. Ahora el chat tiene un ancho
     PROPIO (arrastrable, --chat-w) y el CRM es el que crece.
     El ancho vive en una variable de #app para que el divisor lo mueva sin tocar reglas. */
  .chatpane{ flex:0 0 var(--chat-w); min-width:0; border-right:none; }
  .main{ flex:1 1 auto; min-width:0; }

  /* El carril ("El Carril", antes "El Riel"): PRIMER hijo de #app (ver el comentario en
     index.html) y con ancho FIJO, para que nunca se mueva entre los 3 modos -- antes
     vivia entre el chat y el CRM, y solo quedaba pegado a la izquierda real en modo
     "Solo CRM"; en "Ambos" quedaba en medio, y en "Solo Xarpie" quedaba a la DERECHA
     del chat.
     Fase 2 de 4: crece de 52px y la navegacion (antes .navbar > .topbar#tabs
     horizontal, ver la Fase 1) se muda aqui debajo del mando -- columna flex de 3
     zonas: #cp-modo (altura fija, arriba), #tabs (flex:1 1 auto + overflow-y:auto, el
     UNICO que scrollea), #nav-cfg-btn (altura fija, al fondo). El scroll no es
     opcional: modos + 8 categorias + un dropdown de Estudio abierto (10 sub-items +
     separadores de grupo) + el engrane suman ~870px, mas que un viewport de 800px.
     border-RIGHT y no left: separa al carril de .chatpane, que quedo a su derecha
     (antes separaba a .cp-riel de .main, que estaba a su derecha).
     120px (200 -> 140 -> 120, dos rondas de feedback en vivo de Daniel: seguia
     sobrando aire incluso en 140). A este ancho "Calendario" (la categoria mas larga
     del carril -- los dropdowns tienen su propio ancho fijo de 200px, aparte) puede
     rozar el limite y truncarse con el ellipsis de .cp-navtxt ("Calendari…"): fallback
     aceptado a proposito, no un bug -- se ve, no rompe el layout, y es mas facil de
     ajustar despues que quedarse corto en el pedido de "mas angosto". */
  /* CENITAL: la misma barra, acostada. flex-direction:row y borde ABAJO en vez de a la
     derecha; el alto lo fija --topnav-h, del que cuelgan las alturas de .chatpane/.main
     de mas abajo (si cambia aqui, cambian solas). El ancho de 120px se va: horizontal, la
     categoria mas larga ya no compite contra una columna angosta, asi que "Calendario"
     deja de truncarse -- el fallback de ellipsis que documentaba el comentario de arriba
     queda sin usarse en escritorio. */
  :root{ --topnav-h:48px; }
  /* Grid de 3 columnas (no flex): con flex, el isotipo centrado quedaria donde sobre
     espacio entre el isotipo y #tabs -- variable segun cuantas categorias haya. Logo a la
     IZQUIERDA (2026-08-31, pedido de Daniel): antes era grid de 3 columnas (1fr/auto/1fr)
     para centrar el isotipo entre el mando de 3 vistas y #tabs; sin mando ya no hay nada
     que centrar contra, asi que baja a 2 columnas -- auto (el isotipo, a su ancho natural)
     + 1fr (todo lo demas, empezando por #tabs).
     Selector #cp-riel.show y no .cp-riel: #cp-riel.show{display:flex} (linea 230, fuera
     de este @media) es un ID+clase, mas especifico que una clase sola -- con .cp-riel a
     secas display:grid nunca gana, el carril se queda en flex. Aqui se iguala la
     especificidad para que gane por ir despues. */
  /* gap:20px, no los 4px del flex original: reportado en vivo por Daniel, el isotipo
     quedaba pegado al primer tab (Galerias, pill blanco solido cuando esta activo) con
     casi nada de aire entre los dos. Es gap del GRID, no padding del isotipo -- un padding
     en .cp-riel-logo no separa nada, porque su columna es `auto` y solo crece con el. */
  /* Menu de 4 secciones (2026-09-12): vuelve a 3 columnas, logo / secciones / iconos, para
     que las 4 secciones queden centradas en la VENTANA sin importar cuanto midan los lados. */
  #cp-riel.show{
    display:grid; grid-template-columns:1fr auto 1fr; flex:none; align-items:stretch; height:var(--topnav-h);
    background:var(--deep); border-right:0; border-bottom:1px solid var(--hair);
    padding:0 10px; gap:20px;
  }
  /* La copia compacta del isotipo (index.html) vive en la primera columna. La original
     de .cp-brand se apaga aqui: en escritorio el carril de arriba ya la reemplaza, y
     dejarlas las dos habria mostrado la marca dos veces a la vez. */
  .chatpane .cp-brand .xarpen-logo{ display:none; }
  .cp-riel-logo{ align-self:center; justify-self:start; }
  /* Columna derecha: mismo contenido de siempre (.cp-nav-central + campana/engrane/
     instalar), agrupado para poder ser SU PROPIA columna 1fr -- .cp-nav-central sigue
     comiendose el espacio sobrante con su flex:1 1 auto de mas abajo, solo que ahora es
     sobrante DENTRO de esta columna, no de todo el carril. */
  .cp-riel-der{ display:flex; flex-direction:row; align-items:center; justify-content:flex-end; justify-self:end; min-width:0; gap:4px; }
  /* La barra ya no scrollea: en horizontal caben las 8 categorias. Si algun dia no
     cupieran, scrollea ELLA (overflow-x) y no la pagina. */
  #app.show{ height:calc(100vh - var(--topnav-h)); min-height:0; }
  /* position:relative y NO static: .diaria es absolute DENTRO de .chatpane y depende de
     que sea contenedor de posicionamiento (lo era por el sticky que ya no hace falta con
     la barra arriba). Con static se iria a posicionarse contra el viewport. */
  .chatpane{ height:100%; position:relative; top:auto; }
  .main{ height:100%; }

  /* La navegacion (pintarNav, NAV en app.js). .cp-navbtn NO es .tab: esa clase la reusa
     admin.html sin scope, y tocarla cambiaria el look de un panel que no tiene carril. */
  /* Menu de 4 secciones (2026-09-12): un solo host (#tabs) en la columna central del grid de
     #cp-riel.show. Reemplaza al grid izq / Xarpie / der de 2026-08-31. */
  .cp-nav-central{ display:flex; align-items:center; justify-content:center; min-width:0; }
  #tabs{ display:flex; flex-direction:row; align-items:center; gap:6px; }
  /* Horizontal: el boton se encoge a su texto (width:auto + flex:none) en vez de llenar
     una columna, y no se parte en dos lineas. */
  .cp-navbtn{
    display:flex; align-items:center; justify-content:center; gap:5px;
    flex:none; width:auto; text-align:center; padding:7px 11px; border-radius:var(--r); border:0;
    background:transparent; color:var(--muted); font-family:inherit; font-size:var(--t-texto);
    font-weight:500; cursor:pointer; transition:background .13s, color .13s; white-space:nowrap;
  }
  @media (hover:hover){ .cp-navbtn:hover{ background:var(--paper); color:var(--ink); } }
  .cp-navbtn.on{ background:var(--ink); color:var(--paper); }
  .cp-navbtn:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
  /* En horizontal ya no hay columna que desbordar: el texto va entero (el ellipsis vertical
     que documentaba el comentario anterior era por los 120px del carril, que ya no existen). */
  .cp-navtxt{ flex:none; min-width:0; white-space:nowrap; }

  /* Campana, engrane e instalar: HTML estatico (index.html), no los crea pintarNav. En
     horizontal quedan al FINAL de la barra (a la derecha) porque #tabs (flex:1 1 auto)
     se come el espacio sobrante -- misma mecanica de antes, girada. Siguen FUERA de
     #tabs, que es lo unico que puede scrollear. */
  .cp-navcfg{
    flex:none; margin:0; width:38px; height:38px; align-self:center; border-radius:var(--r); border:0;
    background:transparent; color:var(--muted); display:flex; align-items:center;
    justify-content:center; cursor:pointer; transition:background .13s, color .13s;
  }
  @media (hover:hover){ .cp-navcfg:hover{ background:var(--paper); color:var(--ink); } }
  .cp-navcfg[aria-expanded="true"]{ background:var(--paper); color:var(--ink); }

  /* El divisor de arrastre, ahora HERMANO de .cp-riel y .chatpane (antes vivia dentro
     del carril, debajo del mando) -- ver el comentario de #cp-resize en index.html.
     flex:0 0 6px y no 1 1 auto: ya no comparte columna con nada que le robe alto, es su
     propio elemento de ancho fijo entre el chat y el CRM (el ancho original, previo a
     "El Riel"). ::before extiende la zona agarrable a los lados -- un objetivo de 6px
     se falla al primer intento sin eso. */
  .cp-resize{ flex:0 0 6px; position:relative; cursor:col-resize; background:transparent; touch-action:none; }
  .cp-resize::before{ content:""; position:absolute; inset:0 -3px; }
  /* El agarre es PERMANENTE, no opacity:0 hasta el hover: la unica pista de que el
     carril se arrastra no puede ser invisible hasta que ya se sabia que estaba
     ahi -- ese era exactamente el defecto del divisor viejo. Cambia de color, no
     de presencia. */
  .cp-grip{ position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
            width:3px; height:38px; border-radius:3px; background:var(--line2);
            transition:background .15s; }
  .cp-resize:focus-visible .cp-grip, .cp-resize.arrastrando .cp-grip{ background:var(--accent); }
@media (hover:hover){ .cp-resize:hover .cp-grip{ background:var(--accent); } }
  .cp-resize:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
  /* Durante el arrastre: sin seleccion de texto accidental y el cursor no cambia al pasar
     sobre el contenido. */
  #app.redimensionando{ user-select:none; cursor:col-resize; }
  #app.redimensionando iframe{ pointer-events:none; }

  /* El bloque colapsado se va a flex-basis 0 (y padding/borde a 0, para que no le quede
     un pixel de aire); el otro pasa a ocupar todo. .cp-riel NUNCA cambia de tamano entre
     los 3 estados -- se queda pegado al borde IZQUIERDO de la ventana SIEMPRE (antes era
     "el borde que corresponda": este es justo el problema que resuelve la Fase 1). Ancho
     efectivo infinito por la ley de Fitts (se lanza el cursor a la pared y se llega),
     justo lo contrario del boton viejo pre-Riel, que en un estado quedaba 12px FUERA
     del viewport (medido con getBoundingClientRect en produccion). Sin nada que
     arrastrar, el cursor vuelve a default y el agarre se esconde: el cursor no debe
     prometer un arrastre que el pointerdown de montarDivisorChat ya rechaza en codigo. */
  #app.chat-colapsado .chatpane{ flex:0 0 0; min-width:0; padding:0; border:0; overflow:hidden; }
  #app.crm-colapsado .chatpane{ flex:1 1 auto; }
  #app.crm-colapsado .main{ flex:0 0 0; min-width:0; overflow:hidden; }
  #app.chat-colapsado .cp-resize, #app.crm-colapsado .cp-resize{ cursor:default; }
  #app.chat-colapsado .cp-grip, #app.crm-colapsado .cp-grip{ display:none; }

  /* FE DE ERRATAS (queda a proposito, para quien busque .cp-collapse en el historial):
     el control viejo era `.cp-collapse` -- dos botones circulares de 30px, position:
     absolute, opacity:.72, flotando sobre el divisor de 5px. Se borro completo el
     2026-08-16 junto con #cp-collapse-chat/#cp-collapse-crm en index.html. */

  /* Riel de lectura: el texto no se estira a 900px aunque el chat sea ancho (modo
     solo-chat, CRM colapsado). Se hace con padding y no tocando el HTML, para no mover
     el DOM del chat. greet/chatscroll/chips no tienen padding horizontal propio, asi
     que 0px de piso no les cambia nada a ancho normal, y con piso 0px se lo comia
     entero apenas el chat bajaba de 780px (el ancho normal, casi siempre) -- sumar el
     propio como piso deja eso intacto y solo crece pasado el riel. */
  .chatpane .greet,
  .chatpane .chatscroll,
  .chatpane .chips{ padding-inline: max(0px, calc((100% - 780px) / 2)); }
  /* El composer y el adjunto SI tienen caja propia (borde, fondo, esquinas redondeadas):
     con padding-inline el borde se quedaba estirado de pared a pared del ancho colapsado
     y solo el TEXTO de adentro se acomodaba al riel -- una franja blanca de punta a
     punta con la letra flotando en medio (asi se veia el modo solo-chat). max-width +
     margin:auto encoge la caja ENTERA al riel, como cualquier bloque de lectura
     centrado. El padding de 10px que cada uno ya trae (declarado arriba) sigue siendo el
     que evita que su contenido toque su propio borde -- eso no cambio.
     xarpiemode ya NO va adentro del composer (cambio del 2026-08-28), asi que dejo de
     heredar este ancho y necesita alinearse solo: no puede llevar max-width+margin:auto
     como los de abajo porque es una pastilla chica y se estiraria a 780px de fondo. Se
     empuja con el mismo calc que .chatpane .chips de arriba, que ya resolvia justo esto. */
  .chatpane .attach-prev,
  .chatpane .composer{ width:100%; max-width:780px; margin-inline:auto; }
  /* La marca sigue pegada al borde: es cabecera, no lectura. */
}

/* ---- Lista del dia (modo solo-chat) ----
   Ver "LISTA DEL DIA" en public/app.js. Vive en el margen que deja el riel de lectura de
   780px, NO en una columna propia: asi no toca el layout del chat ni el del CRM y no hay
   que rehacer el flex de #app. Por eso es absolute dentro de .chatpane, que ya es
   position:sticky (o sea, contenedor de posicionamiento) desde antes.
   El min-width tiene que seguir igual a DIARIA_MIN_ANCHO en app.js: por debajo de eso el
   margen no da para una columna legible y la lista no se muestra (lo decide el JS; esto es
   la red de seguridad para que un bug no la deje flotando encima de la conversacion). */
.diaria{ display:none; }
/* Desde los RIELES, la lista del dia ya no flota en el margen del carril de lectura: vive
   dentro de #riel-izq, que es una columna de verdad del flex de #app. Se acabaron el
   position:absolute, el left/top a mano y el ancho calculado contra el hueco -- la columna
   le da su ancho y la lista simplemente fluye. 1188 y no 1308 desde "Cenital" (el carril
   se fue arriba y devolvio 120px); pareado con DIARIA_MIN_ANCHO en public/app.js. */
@media (min-width:1188px){
  #app.crm-colapsado .diaria:not([hidden]){ display:block; animation:rise .3s ease both; }
}

/* ---- Rieles laterales ----
   Columnas hermanas del chat y del CRM dentro de #app. Los esconde/muestra sincRieles()
   (public/app.js): un riel sin contenido no ocupa ancho, se lo devuelve al chat. */
.riel-lat{ display:none; }
@media (min-width:1188px){
  #app .riel-lat:not([hidden]){
    display:flex; flex-direction:column; gap:14px;
    flex:0 0 296px; min-width:0; height:100%; overflow-y:auto;
    padding:22px 16px; background:var(--deep);
  }
  .riel-izq{ border-right:1px solid var(--hair); }
  .riel-der{ border-left:1px solid var(--hair); }
  /* Las tarjetas fijadas ocupan la columna entera (antes eran una franja horizontal
     apretada encima del chat, donde una tabla no cabia). La forma de columna ya vive en
     .wpins, que hoy no tiene otro hogar; aqui solo queda lo que depende del riel. */
  .riel-der .wpins .widget{ width:100%; }
}
/* El muelle: botones fantasma de ancho completo. Es un mueble, no una tarjeta -- sin
   sombra, sin borde, sin fondo propio: lo que se ve es la accion, no el contenedor.
   Filas de 3 (pedido real de Daniel viendo la lista de 8 en produccion: "abarcan menos
   espacio a lo largo y solo a lo ancho"). .riel-ritual (2 acciones, ver mas abajo) tiene
   su propia rejilla de 2 columnas por el mismo motivo -- ahorrar espacio vertical. */
.muelle{ display:grid; grid-template-columns:repeat(3,1fr); gap:2px; flex:none; }
.muelle-tit{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.13em; text-transform:uppercase; color:var(--muted); margin-bottom:7px; grid-column:1/-1; }
.muelle-btn{
  display:flex; align-items:center; gap:9px; width:100%; text-align:left;
  padding:8px 9px; border:0; border-radius:var(--r); background:transparent; color:var(--muted);
  font-family:inherit; font-size:var(--t-texto); cursor:pointer; transition:background .13s, color .13s;
}
@media (hover:hover){ .muelle-btn:hover{ background:var(--paper); color:var(--ink); } }
.muelle-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
/* La variante en rejilla: icono arriba, etiqueta abajo, centrado -- el .muelle-btn de arriba
   sigue siendo el renglon horizontal de siempre para quien lo use fuera de #muelle
   (.riel-ritual). Especificidad ".muelle .muelle-btn" (2 clases) gana sobre ".muelle-btn"
   (1 clase) sin pelear con el orden de las reglas. .ag-fila la comparte (panel "Agregar" en
   telefono, ver mas abajo): mismo boton fantasma, contenedor distinto. */
.muelle .muelle-btn,
.ag-fila .muelle-btn{
  flex-direction:column; justify-content:center; text-align:center; gap:6px;
  padding:11px 4px; font-size:var(--t-eti); line-height:1.25;
}
.muelle .muelle-btn svg,
.ag-fila .muelle-btn svg{ flex:none; }
/* El ritual del riel (Ver El Foco / Cerrar el dia): mismo boton fantasma que .muelle-btn
   (se reusa esa clase en el HTML), el contenedor es lo unico nuevo. Sin gap propio contra
   #muelle/#diaria -- lo pone .riel-lat (gap:14px, ver arriba) por ser un hijo flex mas.
   Rejilla de 2 columnas (pedido de Daniel, 2026-09-08: lado a lado ahorra mas espacio
   vertical que la lista apilada de antes) -- grid y no flex-row para que las dos ocupen
   el mismo ancho sin tocar el width:100% que .muelle-btn ya trae. */
.riel-ritual{ display:grid; grid-template-columns:repeat(2,1fr); gap:1px; flex:none; }
/* riel-cal: mueble, no tarjeta -- mismo trato que .muelle/.riel-ritual. La rejilla reusa
   .mc-dow/.mc-grid/.mc-day/.mc-dots tal cual (son chrome-agnosticas, ver "Mini calendario
   del panel" abajo). El encabezado (‹ mes ›) usa una clase PROPIA (.rielcal-head, no
   .diaria-head) para no chocar con el $(".diaria-head") de montarDiaria() (app.js), que
   asume un solo resultado en la pagina -- pero comparte la regla visual con .diaria-head
   para verse identico. Los botones internos SI reusan .diaria-nav/.diaria-fecha (sin id):
   nada los busca por clase, solo por id (#diaria-prev/#diaria-fecha/#diaria-next), asi que
   no hay colision ahi. */
.riel-cal{ flex:none; }
.diaria-head, .rielcal-head{ display:flex; align-items:center; gap:2px; margin-bottom:9px; }
.diaria-fecha{ flex:1; min-width:0; text-align:left; border:0; background:transparent; padding:0; cursor:pointer;
  font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.13em; text-transform:uppercase; color:var(--muted); transition:color .14s; }
@media (hover:hover){ .diaria-fecha:hover{ color:var(--ink); } }
.diaria-nav{ flex:0 0 auto; width:22px; height:22px; display:grid; place-items:center; border:0; background:transparent;
  color:var(--muted); border-radius:var(--r); cursor:pointer; font-size:var(--t-texto); line-height:1; opacity:.6; transition:opacity .14s, background .14s; }
@media (hover:hover){ .diaria-nav:hover{ opacity:1; color:var(--ink); background:var(--bone); } }
/* El "+" pegado a la flecha de "manana" seria un tercer paso de navegacion: un poco de
   aire lo separa en lo que es, una accion. */
.diaria-mas{ margin-left:4px; font-size:var(--t-campo); }
.diaria-fila{ display:flex; align-items:flex-start; gap:9px; padding:6px 0; }
/* Palomita dibujada con un borde girado en vez de un SVG: es el unico check de la app que
   se pinta en cada renglon de una lista que se repinta al cambiar de dia. */
.diaria-box{ flex:0 0 15px; width:15px; height:15px; margin-top:2px; padding:0; position:relative;
  border:1.5px solid var(--line2); border-radius:4px; background:transparent; cursor:pointer; transition:border-color .14s, background .14s; }
@media (hover:hover){ .diaria-box:hover{ border-color:var(--accent); } }
.diaria-fila.hecha .diaria-box{ background:var(--accent); border-color:var(--accent); }
.diaria-fila.hecha .diaria-box::after{ content:""; position:absolute; left:4px; top:1px; width:4px; height:8px;
  border:solid #fff; border-width:0 1.6px 1.6px 0; transform:rotate(42deg); }
/* Hora de la tarea (tarea.hora, "HH:MM" opcional). Columna de ANCHO FIJO y SIEMPRE en el
   DOM (vacia si no hay hora, ver diariaFila en app.js) para que el titulo arranque en la
   MISMA x en toda la lista tenga o no hora la fila de al lado. Mismo patron que .evtime
   (.evrow) pero mas angosto (32px vs 52px): ese ancho nacio para columnas mas anchas que
   este riel de 296px. */
.diaria-hora{ flex:0 0 32px; width:32px; align-self:flex-start; margin-top:2px;
  font-family:var(--mono); font-size:var(--t-meta); font-variant-numeric:tabular-nums;
  color:var(--muted); line-height:1.45; white-space:nowrap; }
/* Marca de tipo de un EVENTO en la lista de HOY (diariaFilaEvento, app.js): reusa el slot
   de .diaria-box (mismo ancho/alto que la palomita de una tarea, para que la fila de un
   evento alinee con las de arriba/abajo) pero sin su chrome de checkbox -- el color e
   icono los pone el propio elemento inline (mismo CAL_TIPO_COLOR/CAL_TIPO_ICONO que ya usa
   el calendario del riel), aqui solo se centra y se le quita borde/cursor. */
.diaria-marca-evento{ border:0; background:transparent; cursor:default; display:flex; align-items:center; justify-content:center; }
.diaria-marca-evento svg{ display:block; }
/* --ink y no --muted: el titulo de la tarea es el CONTENIDO de la lista, no un dato
   secundario. En --muted (que pasa AA justo, 5:1) se leia como una nota al pie y habia
   que acercarse -- justo lo contrario de "lo esencial a la vista". El aire alrededor es
   lo que la mantiene discreta, no lo apagado del color. */
.diaria-txt{ flex:1 1 auto; min-width:0; font-size:var(--t-texto); line-height:1.45; color:var(--ink); cursor:pointer; overflow-wrap:anywhere; transition:opacity .14s; }
@media (hover:hover){ .diaria-txt:hover{ opacity:.65; } }
/* De quien es la tarea, A UN LADO y no debajo: es lo unico que distingue tres "Solicitar
   resena al cliente" seguidas, y sumarle un renglon a cada tarea saturaria la columna.
   Se encoge y se corta con puntos suspensivos antes que empujar al titulo (que si envuelve),
   y el nombre completo queda en el title. */
.diaria-quien{ flex:0 1 auto; max-width:42%; align-self:flex-start; margin-top:1px;
  font-size:var(--t-eti); line-height:1.5; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.diaria-fila.hecha .diaria-txt{ text-decoration:line-through; opacity:.5; }
.diaria-vacio{ font-size:var(--t-meta); color:var(--muted); opacity:.6; }
/* Fijada arriba/abajo: mismo glifo (PENDW_ICONOS.pin) que ya usa Pendientes para el
   mismo significado en el resto de la app; arriba vs abajo se lee por la POSICION en
   la lista, no por un segundo icono. */
.diaria-pin{ flex:0 0 auto; align-self:flex-start; margin-top:2px; color:var(--accent); display:flex; }
.diaria-pin svg{ display:block; }
/* Agarre de arrastre: oculto en reposo y revelado al pasar el mouse sobre LA FILA (no
   solo el propio grip), para que se note que existe sin sumar ruido permanente a una
   lista que ya tiene su propia palomita, texto y nombre en cada renglon. */
.diaria-grip{ flex:0 0 14px; align-self:center; display:flex; align-items:center; justify-content:center;
  color:var(--muted); opacity:0; cursor:grab; transition:opacity .12s, color .12s; }
@media (hover:hover){ .diaria-fila:hover .diaria-grip{ opacity:.55; } }
@media (hover:hover){ .diaria-grip:hover{ opacity:1; color:var(--ink); } }
@media (pointer:fine){ .diaria-grip{ touch-action:none; } }
/* Mismo tratamiento que .gal-item.gal-arrastrando (galeria): opacidad reducida + contorno
   de acento, para que la fila que se mueve se distinga de las que se van a correr. */
.diaria-fila.diaria-arrastrando{ opacity:.55; cursor:grabbing; outline:2px solid var(--accent); outline-offset:1px; border-radius:var(--r); }
/* Menu ⋯ de la fila. Se comporta como el grip (aparece al pasar el mouse) para no sumar
   ruido permanente a una lista que ya tiene palomita, texto y nombre por renglon. Lo que
   gana el escritorio con el es que el menu de click derecho POR FIN se anuncia: hasta hoy
   no habia forma de saber que existia. */
.diaria-kebab{ flex:0 0 22px; height:22px; align-self:center; display:grid; place-items:center; padding:0;
  border:0; background:transparent; color:var(--muted); border-radius:var(--r); cursor:pointer;
  opacity:0; transition:opacity .12s, background .12s, color .12s; }
.diaria-kebab svg{ display:block; }
@media (hover:hover){ .diaria-fila:hover .diaria-kebab{ opacity:.55; } }
@media (hover:hover){ .diaria-kebab:hover{ opacity:1; color:var(--ink); background:var(--bone); } }
.diaria-kebab:focus-visible{ opacity:1; outline:2px solid var(--accent); outline-offset:1px; }
/* Sin cursor no hay hover que lo revele, y en tactil este boton es la UNICA puerta a las 9
   acciones de la tarea. */
@media (hover:none){ .diaria-kebab{ opacity:.7; } }
/* Fuera de la hoja el boton de cerrar no existe: en escritorio la lista no se cierra, se
   sale del modo solo-chat. */
.diaria-cerrar{ display:none; }

/* ---- Riel: plegar, proxima boda, notas fijadas ----
   Hijos nuevos de #riel-izq (ver index.html y el bloque "RIEL: plegar, proxima boda y
   notas fijadas" en app.js). Heredan el gate de siempre (.riel-lat, @media min-width:1188px
   mas arriba): en movil #riel-izq entero sigue oculto, nada de esto necesita su propio
   breakpoint. */
.riel-cab{ display:flex; justify-content:flex-end; margin:-6px -6px 2px 0; }
/* Boton icono chico generico (26px, fantasma) -- no habia uno sin prefijo de otra pantalla
   (.al-ib-sm es del editor de album). Sirve al plegar del riel y al engrane del panel de
   notas, los dos nuevos aqui. */
.riel-ib{ width:26px; height:26px; display:grid; place-items:center; border:0; background:transparent; color:var(--muted); border-radius:var(--r); cursor:pointer; flex:none; }
@media (hover:hover){ .riel-ib:hover{ background:var(--hair); color:var(--ink); } }
.riel-ib:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }
/* Estado del negocio (riel, plan 2026-09-08): franja de hasta 4 columnas, separadas por
   una linea fina -- mismo mueble fantasma que #muelle (sin fondo, sin sombra), cada
   columna es su PROPIO boton porque cada una navega a un lugar distinto (tareas vs
   finanzas). border-bottom cierra el grupo antes de #muelle, igual que un widget
   terminaria una seccion. */
.riel-negocio{ display:flex; align-items:stretch; margin-bottom:14px; padding-bottom:12px; border-bottom:1px solid var(--hair); }
.riel-negocio-col{ flex:1; min-width:0; display:flex; flex-direction:column; align-items:center; gap:3px; padding:2px; border:0; background:transparent; cursor:pointer; font-family:inherit; border-radius:var(--r); }
@media (hover:hover){ .riel-negocio-col:hover{ background:var(--paper); } }
.riel-negocio-col:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }
.riel-negocio-n{ font-size:var(--t-texto); font-weight:600; font-variant-numeric:tabular-nums; color:var(--ink); white-space:nowrap; }
.riel-negocio-n.mal{ color:#d64545; }
.riel-negocio-l{ font-size:8.5px; color:var(--muted); text-transform:uppercase; letter-spacing:.05em; white-space:nowrap; }
.riel-negocio-sep{ flex:none; width:1px; background:var(--hair); margin:2px 0; }
.riel-izq.plegado .riel-negocio{ display:none; }

/* El "+" de #diaria-mas/#notas-nueva: un circulo tintado en vez del "+" de texto plano que
   se perdia contra las flechitas de navegacion vecinas (mismo acento que ya usan los chips
   "conectar con" del modal de nota -- no es un motivo nuevo). */
.btn-add{ flex:0 0 auto; width:22px; height:22px; margin-left:6px; display:grid; place-items:center;
  border:0; border-radius:50%; background:var(--tint); color:var(--accent); cursor:pointer; transition:background .13s, color .13s, transform .1s; }
.btn-add svg{ display:block; }
@media (hover:hover){ .btn-add:hover{ background:var(--accent-solido); color:var(--accent-tinta); } }
.btn-add:active{ transform:scale(.92); }

.riel-notas{ flex:none; }
.notas-head{ display:flex; align-items:center; gap:2px; margin-bottom:7px; }
.eyebrow-btn{ flex:1; min-width:0; display:flex; align-items:center; gap:4px; border:0; background:transparent; padding:0; cursor:pointer;
  font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.13em; text-transform:uppercase; color:var(--muted); }
@media (hover:hover){ .eyebrow-btn:hover{ color:var(--ink); } }
.eyebrow-btn svg{ flex:none; opacity:.55; }
@media (hover:hover){ .eyebrow-btn:hover svg{ opacity:1; } }
.notas-nav{ display:flex; align-items:center; gap:2px; margin-bottom:6px; }
.notas-cont{ font-family:var(--mono); font-size:var(--t-eti); color:var(--muted); font-variant-numeric:tabular-nums; margin-right:2px; }
.pila{ display:flex; flex-direction:column; align-items:center; }
.nota{ width:100%; background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); padding:11px 12px 10px; position:relative; z-index:2; }
.nota-txt{ font-size:var(--t-texto); line-height:1.45; color:var(--ink); white-space:pre-line; overflow-wrap:anywhere; }
.nota-pie{ display:flex; align-items:center; gap:6px; margin-top:8px; }
.nota-vinc{ display:inline-flex; align-items:center; gap:5px; padding:3px 8px; border-radius:var(--r); background:var(--tint); color:var(--accent); font-size:var(--t-meta); max-width:100%; overflow:hidden; }
.nota-vinc span{ overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.nota-vinc svg{ flex:none; display:block; }
.nota-x{ margin-left:auto; flex:none; width:22px; height:22px; border:0; background:transparent; color:var(--muted); cursor:pointer; border-radius:var(--r); font-size:var(--t-texto); line-height:1; }
@media (hover:hover){ .nota-x:hover{ background:var(--hair); color:var(--ink); } }
.peek{ height:4px; border:1px solid var(--hair); border-top:0; border-radius:0 0 var(--r) var(--r); background:var(--paper); }
.peek.p1{ width:calc(100% - 14px); }
.peek.p2{ width:calc(100% - 28px); }
.notas-lista{ display:flex; flex-direction:column; gap:6px; }
.notas-lista .nota{ margin-bottom:0; }
.nota-fila{ display:flex; align-items:center; gap:8px; padding:7px 10px; background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); }
.nota-fila .p{ flex:none; color:var(--accent); display:flex; }
.nota-fila .t{ flex:1; min-width:0; font-size:var(--t-meta); color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* Plegado: SOLO icon-only -- .muelle-btn/.riel-ritual siguen siendo los MISMOS botones
   (pintarMuelle/pintarRielRitual no se repintan), esto solo esconde su texto por CSS.
   sincRieles()/sincDiaria() (cuando se muestra u oculta el riel entero) no se tocan. */
/* !important en las 2 reglas de abajo: #app .riel-lat:not([hidden]) (mas arriba, con ID)
   pone flex:0 0 296px, y #app.crm-colapsado .diaria:not([hidden]) (ID + 2 clases) pone
   display:block -- las dos ganan por especificidad a un simple ".riel-izq.plegado" sin ID,
   sin importar el orden. Con !important no hay que perseguir esos selectores si cambian. */
.riel-izq.plegado{ flex-basis:60px !important; padding-left:10px; padding-right:10px; align-items:center; }
.riel-izq.plegado .riel-cab{ justify-content:center; margin-right:0; }
.riel-izq.plegado .muelle-tit{ display:none; }
/* Las 3 columnas no caben en los 60px plegados -- vuelve a una sola, igual que antes de
   que el muelle pasara a rejilla. */
.riel-izq.plegado .muelle,
.riel-izq.plegado .riel-ritual{ grid-template-columns:1fr; }
.riel-izq.plegado .muelle-btn,
.riel-izq.plegado .riel-ritual .muelle-btn{ justify-content:center; padding:8px; }
.riel-izq.plegado .muelle-btn span,
.riel-izq.plegado .riel-ritual .muelle-btn span{ display:none; }
.riel-izq.plegado #riel-cal,
.riel-izq.plegado #diaria{ display:none !important; }
/* Solo el titulo+flecha de "Notas fijadas" ("eyebrow-btn") se esconde -- el "+" (#notas-nueva,
   un .btn-add hermano dentro del mismo .notas-head) tiene que seguir con su icono, igual que
   el "+" de #diaria-mas: crear sigue siendo util plegado, ver el panel completo no tanto. Un
   selector "'.notas-head svg'" a secas apagaba los DOS, incluido el unico contenido del "+". */
.riel-izq.plegado .eyebrow-btn span,
.riel-izq.plegado .eyebrow-btn svg,
.riel-izq.plegado .notas-nav,
.riel-izq.plegado .peek{ display:none; }
.riel-izq.plegado .notas-head{ justify-content:center; }
.riel-izq.plegado .nota{ padding:6px; }
.riel-izq.plegado .nota-txt{ display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; font-size:var(--t-meta); }
.riel-izq.plegado .nota-pie{ display:none; }

/* ---- El panel "Agregar" (Opcion B de "chat como superficie", 2026-09-09; llevado a
   escritorio 2026-09-10) ----
   #chat-plus (el "+" del composer) reemplaza clip/hablar/comentario/que-es-esto Y trae la
   rejilla de crear del muelle, EN CUALQUIER ANCHO. Nacio solo para telefono, donde
   #riel-izq (el que tiene #muelle) se oculta bajo 1188px -- pero ese mismo hueco existe
   entre 861 y 1187px (.riel-lat tambien exige 1188px, ver mas arriba): dejar el "+" nada
   mas en telefono habria dejado esa banda intermedia sin forma de crear sin comando "/",
   igual que telefono antes de este panel. Por eso el boton y el contenido son los MISMOS
   para los tres anchos -- lo unico que cambia es la PRESENTACION del panel, en los dos
   @media de abajo: hoja de abajo con telon en telefono, popover angosto anclado al boton
   (mismo patron que abrirMenuCfg/abrirNotifPanel en app.js) de 861px para arriba.
   ".muelle"/".muelle-btn"/".muelle-tit" se REUSAN tal cual para la rejilla de crear de
   adentro (pintarAgregarSheet, app.js): es la misma lista (muelleAcciones()) y el mismo
   look, asi que no hace falta CSS nuevo para eso -- solo el ".ag-fila" de 4 columnas para
   adjuntar/hablar/comentar/que-es-esto, que comparte el boton fantasma de .muelle-btn via
   el selector agregado arriba. */
#chat-plus{ display:flex; }
#chat-attach, #chat-mic, #chat-feedback, #chat-inspect{ display:none; }
/* padding-left a la par del derecho (7px, como .cp-attach/.chat-enviar): con el "+" de
   primero ya no hace falta el aire de 15/16px que existia para que el placeholder del
   textarea no arrancara pegado al borde. */
#chat-composer.composer{ padding-left:7px; }
#chat-plus svg{ transition:transform .18s ease; }
#chat-plus.abierto svg{ transform:rotate(45deg); }
.agregar-backdrop{ display:none; }
.agregar-sheet{ display:none; }
.ag-head{ display:flex; align-items:center; justify-content:space-between; margin-bottom:10px; flex:none; }
.ag-cuerpo{ overflow-y:auto; -webkit-overflow-scrolling:touch; }
.ag-fila{ display:grid; grid-template-columns:repeat(4,1fr); gap:2px; margin-bottom:10px; }
.ag-sep{ height:1px; background:var(--hair); margin:0 0 10px; }
@media (max-width:860px){
  /* Telefono: hoja fija abajo con telon oscuro detras, mismo patron que #hojadia. */
  .agregar-backdrop:not([hidden]){
    display:block; position:fixed; inset:0; z-index:74;
    background:rgba(20,18,16,.55); animation:pop .18s ease both;
  }
  /* 82vh y no 82% -- a diferencia de #hojadia (que vive DENTRO de un contenedor con alto
     fijo), este panel es hijo directo del documento: un % de alto ahi resolveria contra un
     ancestro sin alto declarado, que es "auto" y no sirve de referencia. */
  .agregar-sheet:not([hidden]){
    display:flex; flex-direction:column; max-height:82vh;
    position:fixed; left:0; right:0; bottom:0; z-index:74;
    background:var(--deep); border-radius:var(--r) var(--r) 0 0;
    padding:10px 20px calc(16px + env(safe-area-inset-bottom));
    box-shadow:0 -20px 50px -20px rgba(0,0,0,.5);
    animation:rise .22s ease both;
  }
  .ag-grabber{ width:36px; height:4px; border-radius:4px; background:var(--line2); margin:2px auto 14px; flex:none; }
}
@media (min-width:861px){
  /* Escritorio (y la banda 861-1187 sin riel): sin telon ni hoja -- popover que
     agregarAbrir() ancla arriba del "+" con getBoundingClientRect(). Cierra por click
     afuera con el listener nuevo de mas abajo (mismo patron que #usermenu/#notif-panel),
     no con el telon: por eso .agregar-backdrop se queda oculto en este ancho. Fondo
     --paper (no --deep, el que usa la hoja de telefono): sin telon detras que lo separe
     de la pagina, necesita su propio contraste -- mismo token que usa .usermenu. */
  .agregar-sheet:not([hidden]){
    display:flex; flex-direction:column; width:320px; max-height:min(72vh,560px);
    position:fixed; z-index:80;
    background:var(--paper); border:1px solid var(--line2); border-radius:var(--r);
    padding:10px 14px 14px; box-shadow:0 18px 44px -20px rgba(43,40,36,.5);
    animation:pop .16s ease both;
  }
  .ag-grabber{ display:none; }
}

/* ---- Expandir una tarjeta suelta (chat o fijados) ----
   ADOPTA el nodo real de la tarjeta (wlExpandirCard, public/widgets.js) -- ".wexp-cuerpo"
   solo necesita centrar lo que le llega, la tarjeta trae su propio fondo/borde/radio
   (.widget). z-index 74, igual que .agregar-backdrop/.agregar-sheet y por la misma razon
   (queda por debajo de .ov en 78: un modal abierto DESDE una tarjeta expandida sigue
   viendose encima). */
.wexp-backdrop{ display:none; }
.wexp{ display:none; }
.wexp-backdrop:not([hidden]){
  display:block; position:fixed; inset:0; z-index:74;
  background:rgba(20,18,16,.55); animation:pop .18s ease both;
}
.wexp:not([hidden]){
  display:flex; flex-direction:column; gap:8px;
  position:fixed; top:4vh; left:3vw; width:94vw; height:92vh;
  z-index:74; background:var(--bone); border:1px solid var(--line2); border-radius:var(--r);
  padding:10px; box-shadow:0 30px 70px -20px rgba(0,0,0,.5);
  animation:pop .18s ease both;
}
.wexp-barra{ display:flex; justify-content:flex-end; flex:none; }
/* min-height:0 en el eje flex: sin esto un hijo con su propio scroll interno (la tarjeta
   suelta puede traer overflow-y en .w-body) no se encoge y empuja el alto del contenedor
   en vez de scrollear adentro -- mismo gotcha de siempre con flex + scroll. */
.wexp-cuerpo{ flex:1 1 auto; min-height:0; overflow:auto; display:flex; }
.wexp-cuerpo > .widget{ width:100%; }
/* La tarjeta expandida no necesita su propio limite de alto (el widget grid normal si lo
   pone via .w-body con su max-height en algunos tipos) -- ver w-expandida por widget si
   alguno lo necesita mas adelante. */
@media (max-width:860px){
  /* Sin margen que mostrar en un telefono: ocupa TODO, como #hojadia. */
  .wexp{ top:0; left:0; width:100vw; height:100vh; height:100dvh; border-radius:0; padding:8px calc(8px + env(safe-area-inset-right)) calc(8px + env(safe-area-inset-bottom)) calc(8px + env(safe-area-inset-left)); }
}

/* ---- Panel de notas (modal) ----
   Reusa .mhead/.mbody/.mfoot/openModal como cualquier otro modal (ver rielNotasAbrirPanel en
   app.js) -- estas clases son solo el contenido de adentro. */
.buscar{ display:flex; align-items:center; gap:7px; border:1px solid var(--line2); border-radius:var(--r); padding:7px 9px; margin-bottom:10px; }
.buscar svg{ flex:none; color:var(--muted); }
.buscar input{ flex:1; min-width:0; border:0; background:transparent; font-family:inherit; font-size:var(--t-meta); color:var(--ink); outline:0; }
.buscar input::placeholder{ color:var(--muted); opacity:.75; }
.filtros{ display:flex; gap:5px; margin-bottom:11px; }
.filtro{ border:1px solid var(--line2); background:transparent; color:var(--muted); border-radius:var(--r); padding:4px 9px; font-family:inherit; font-size:var(--t-meta); cursor:pointer; white-space:nowrap; }
.filtro.on{ border-color:var(--accent); color:var(--accent); background:var(--tint); }
.pn-lista{ display:flex; flex-direction:column; gap:7px; }
.pn-fila{ display:flex; align-items:flex-start; gap:8px; padding:9px 10px; border:1px solid var(--hair); border-radius:var(--r); background:var(--bone); }
.pn-cuerpo{ flex:1; min-width:0; }
.pn-txt{ font-size:var(--t-meta); line-height:1.4; color:var(--ink); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }
.pn-meta{ display:flex; align-items:center; gap:6px; margin-top:6px; flex-wrap:wrap; }
.pn-fecha{ font-size:var(--t-eti); color:var(--muted); font-variant-numeric:tabular-nums; }
.pn-acc{ display:flex; flex-direction:column; gap:2px; flex:none; }
.pn-pin{ width:24px; height:24px; display:grid; place-items:center; border:0; background:transparent; border-radius:var(--r); cursor:pointer; color:var(--muted); }
.pn-pin.on{ color:var(--accent); }
@media (hover:hover){ .pn-pin:hover{ background:var(--hair); } }
.pn-vacio{ font-size:var(--t-meta); color:var(--muted); padding:14px 2px; line-height:1.45; }
.pn-nueva{ width:100%; display:flex; align-items:center; justify-content:center; gap:7px; border:0; border-radius:var(--r);
  background:var(--ink); color:var(--paper); padding:10px; font-family:inherit; font-size:var(--t-texto); cursor:pointer; }
.aj-grupo{ margin-bottom:16px; }
.aj-grupo:last-child{ margin-bottom:0; }
.opt-label{ font-size:var(--t-meta); font-weight:600; color:var(--ink); margin:0 0 7px; }
.opt-nota{ font-size:var(--t-meta); color:var(--muted); margin:-8px 0 0; line-height:1.4; }

/* ---- Hoja del dia (la lista del dia en telefono, a pantalla completa) ----
   Ver "HOJA DEL DIA" en public/app.js. Solo existe por debajo de 861px: ahi .chatpane ya es
   un cajon superpuesto y la hoja hereda ese contrato (pantalla completa, y el scroll del
   body ya bloqueado por abrirChat, que es por lo que esta hoja NO vuelve a bloquearlo --
   dos candados sobre la misma puerta significan que cerrar la hoja soltaria el scroll con
   el chat todavia encima). En la banda 861-1307, donde la columna del escritorio tampoco
   cabe, .chatpane sigue siendo una COLUMNA y una hoja de borde a borde taparia el CRM que
   esta al lado: hueco conocido y deliberado. */
.hojadia{ display:none; }
@media (max-width:860px){
  /* z-index 73: exactamente el hueco que dejo libre el ☰ al bajar al muelle. Encima del chat
     (70) y del carril (72); por debajo de .ov (78), porque desde la hoja se abren modalTarea
     (Editar) y la nota rapida, y esos tienen que salir ENCIMA. El toast (90) tambien queda
     arriba, que es lo correcto: "Orden guardado" y el Deshacer de posponer nacen de aqui. */
  .hojadia:not([hidden]){
    display:flex; flex-direction:column;
    position:fixed; inset:0; z-index:73;
    /* 100dvh y no 100vh, mismo motivo ya documentado en .viewer de galeria.html: con vh, iOS
       resuelve el fijo contra el viewport GRANDE y la ultima fila de la lista queda debajo de
       la barra de Safari. Sin soporte, la declaracion se descarta y queda el inset:0. */
    height:100dvh;
    background:var(--deep);
    animation:rise .2s ease both;
  }
  .hojadia-cuerpo{ display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
  /* Dentro de la hoja, #diaria deja de ser la columnita del margen: ES la pantalla. Se apaga
     explicitamente todo lo que le puso el bloque de escritorio (position, width, max-height)
     para que no quede un resto si algun dia esas reglas se solapan. */
  .hojadia .diaria:not([hidden]){
    display:flex; flex-direction:column; flex:1 1 auto; min-height:0;
    position:static; left:auto; top:auto; width:auto; max-height:none; overflow:visible;
    padding:calc(10px + env(safe-area-inset-top)) 16px 0;
    animation:none;   /* la hoja ya trae su propia entrada; dos a la vez se pelean */
  }
  .hojadia .diaria-head{
    flex:0 0 auto; gap:4px; margin-bottom:6px;
    padding-bottom:10px; border-bottom:1px solid var(--hair);
  }
  /* Las flechas de escritorio miden 22px: la mitad del minimo tactil. */
  .hojadia .diaria-nav{ width:40px; height:40px; font-size:var(--t-sub); opacity:.8; }
  /* #diaria-mas dejo de llevar .diaria-nav (paso a .btn-add, el circulo tintado del "+" --
     ver riel-plegar-boda-notas), asi que la regla de arriba ya no lo alcanza. Mismo tamano
     tactil, sin heredar el opacity/font-size de .diaria-nav (que son de OTRO lenguaje visual,
     el de las flechitas fantasma, no el del circulo solido). */
  .hojadia .diaria-mas.btn-add{ width:40px; height:40px; }
  /* La fecha deja de ser flex:1. En la columna de 300px del escritorio, estirarla mantenia
     "‹ fecha ›" pegado; a lo ancho de un telefono empujaba la flecha de "manana" hasta el
     otro extremo y las dos flechas dejaban de leerse como un par. Aqui el grupo de navegar
     se queda junto a la izquierda y el margen automatico manda "+ ×" a la derecha, que es
     donde deben estar: son acciones, no navegacion. */
  .hojadia .diaria-fecha{ flex:0 1 auto; font-size:var(--t-meta); }
  .hojadia .diaria-mas{ margin-left:auto; }
  .hojadia .diaria-cerrar{ display:grid; }
  /* El unico bloque con scroll. overscroll-behavior:contain para que el rebote al llegar al
     final no se encadene al documento de atras. */
  .hojadia .diaria-body{
    flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain;
    -webkit-overflow-scrolling:touch;
    padding-bottom:calc(20px + env(safe-area-inset-bottom));
  }
  /* align-items:center y no flex-start: en la columna del escritorio la palomita se alinea
     con la primera linea del titulo porque a 300px de ancho y 13px de letra los titulos casi
     no envuelven. En 375px envuelven casi siempre, y con flex-start la palomita quedaba
     pegada al techo de una fila de tres renglones. */
  .hojadia .diaria-fila{ align-items:center; gap:11px; padding:8px 0; min-height:52px; }
  /* flex-basis 0 y no auto. Con basis:auto los dos (titulo y nombre) se encogen en
     proporcion a su contenido, asi que un titulo largo que envuelve arrastraba al nombre
     hacia abajo con el: "Chandru" salia como "Chan…" al lado de una tarea de dos renglones,
     mientras que al lado de una de un renglon salia entero. Con basis 0 el titulo se queda
     con lo que sobre y el nombre conserva su ancho natural hasta su tope -- que es la regla
     que ya vale en escritorio ("se encoge y se corta ANTES que empujar al titulo"), solo que
     ahora se aplica sobre el ancho real y no sobre el reparto del sobrante. */
  .hojadia .diaria-txt{ flex:1 1 0; font-size:var(--t-texto); line-height:1.4; }
  .hojadia .diaria-pin{ align-self:center; margin-top:2px; }
  /* La casilla crece de 15 a 20px (15 en un telefono es una mota), pero el BLANCO TACTIL se
     separa de lo que se ve: un ::before invisible de 44x44 centrado. Subir la casilla a 44 la
     habria dejado del tamano de la letra que acompana -- y el dedo no toca pixeles pintados,
     toca area. .diaria-box ya es position:relative por el ::after de la palomita. */
  .hojadia .diaria-box{ flex:0 0 20px; width:20px; height:20px; margin-top:0; border-radius:var(--r); }
  .hojadia .diaria-box::before{ content:""; position:absolute; inset:-12px; }
  .hojadia .diaria-fila.hecha .diaria-box::after{ left:6px; top:2px; width:5px; height:10px; }
  /* El cliente sigue AL LADO y no debajo (es lo unico que distingue tres "Solicitar resena al
     cliente" seguidas, y un renglon extra por tarea saturaria la hoja). Lo que cambia es el
     TECHO: 42% se resuelve contra la fila entera, y en 375px eso son ~144px -- al titulo le
     quedaban ~125px, o sea 13 caracteres por renglon y titulos de cuatro lineas. 14ch se mide
     en caracteres del propio nombre y no en un porcentaje de la pantalla, asi que da lo mismo
     en un telefono angosto que en uno ancho. Nombres mas largos siguen cortando con puntos
     suspensivos, completos en el title. */
  .hojadia .diaria-quien{ max-width:min(38%, 14ch); font-size:var(--t-meta); align-self:center; margin-top:0; }
  .hojadia .diaria-kebab{ flex:0 0 32px; height:44px; opacity:.7; }
  /* El arrastre no se habilita en dedo: su touch-action:none vive dentro de
     @media (pointer:fine), o sea que hoy NO funciona ahi -- y quitar ese gate haria que el
     dedo que aterriza en el grip no pueda scrollear, que es el gesto principal de una lista a
     pantalla completa. No se pierde nada: "Mover arriba/abajo" del menu ⋯ escribe
     tareas.orden con la misma persistencia. De paso le devuelve 14px + gap al titulo. */
  .hojadia .diaria-grip{ display:none; }
}

/* Linea viva del dia: la puerta a la hoja. Mismo par de reglas que .diaria (apagada por
   defecto, encendida por su @media) para que un bug de JS no la deje colgada donde no toca.
   Ancho completo del cajon: el blanco tactil mas facil que existe. */
.dialinea{ display:none; }
@media (max-width:860px){
  .dialinea:not([hidden]){
    display:flex; align-items:center; gap:10px;
    width:100%; margin-top:16px; min-height:48px; padding:11px 13px;
    border:1px solid var(--hair); border-radius:var(--r); background:transparent;
    color:var(--ink); font-family:inherit; font-size:var(--t-texto); text-align:left; cursor:pointer;
  }
  .dialinea:active{ background:var(--paper); }
  .dialinea:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
  .dialinea-txt{ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .dialinea-ir{ flex:0 0 auto; color:var(--muted); font-size:var(--t-sub); line-height:1; }
}

/* El modal vivia en z-index 60, POR DEBAJO del cajon del chat (70) y del menu
   de usuario (75): en telefono, el boton WhatsApp de una burbuja abria un modal
   invisible detras del chat. 78 lo deja encima de ambos y debajo del login (80)
   y del toast (90). */
.ov{ z-index:78; }

/* La banda 861-900 estaba rota: el bloque de 900px dejaba .chatpane con
   flex-basis:auto mientras el cajon movil solo entra a 860. Se alinea a 860
   para que solo haya dos estados, escritorio y telefono.
   (2026-09-20: aqui se volvia a poner flex-basis:auto solo para 861-900, y eso anulaba --chat-w: el chat quedaba
   del ancho de su contenido y el CRM por debajo de su piso de 380 px, no mitad y mitad. Ya no: esa banda es
   escritorio y usa el ancho de siempre.) */

@media (max-width:860px){
  /* En telefono el chat es un cajon superpuesto, no una columna: no hay nada que
     redimensionar. .cp-resize (el divisor de arrastre, hermano de .cp-riel desde la
     Fase 1) se oculta sin condicion -- montarDivisorChat ya lo ignora en codigo bajo
     860px, esto es solo la pista visual a juego. .cp-riel YA NO se oculta aqui desde
     la Fase 2: paso a ser el cajon de navegacion movil (position:fixed, ver el bloque
     de arriba "Cajon movil del carril"), asi que su display normal se queda. */
  .cp-resize{ display:none; }
  /* En telefono el chat es la pantalla: mas aire util para el texto. */
  .chatpane{ padding:18px 16px 14px; }
  /* Separacion de la fila de marca, AQUI y no en el bloque movil de arriba: el .cp-brand del
     "Riel de Xarpie" (mas arriba en este archivo, sin @media) pone gap:15px con la misma
     especificidad y, al ir despues, ganaba -- la regla de alla se aplicaba y no hacia nada.
     Es el mismo tropiezo que ya documenta el comentario del cajon movil: cada bloque trae su
     copia, y el orden decide.
     Por que 10 y no 15: el ☰ entra en esta fila y se lleva 44px mas su separacion. Medido a
     430px (un iPhone Pro Max, el telefono real), con 15 el nombre del estudio pasaba de UNA
     linea a dos y la fila crecia de 52 a 65px. Con 10 -- mas el margen de la × que se quita
     junto al ☰ arriba -- vuelven los 16px justos que faltaban. */
  .cp-brand{ gap:10px; }
  /* Y OPACO. La linea 1233 lo dejo en background:transparent, que en escritorio esta bien
     (el degradado de #app.show se ve detras) pero como cajon superpuesto dejaba leer el
     CRM POR DEBAJO del chat, con los dos textos encimados. Se veia solo al abrirlo a mano;
     ahora que el chat abre al arrancar, se veria siempre. */
  .chatpane{ background:var(--deep); }
}

/* El parche de nav en 2 filas (.topbar{flex-wrap:wrap}, para cuando 12 categorias no
   cabian en una linea de 566px) se borro completo en "El Carril" F2: la nav vertical
   no tiene ese limite de ancho -- ver #tabs mas arriba, que scrollea en vez de apretarse
   o envolver. Queda el nombre aqui para quien busque "flex-wrap" en el historial. */

/* ---- Widgets fuera de su rejilla (los fijados, y los que Xarpie pinta en el chat) ----
   .wgrid es un grid y .w-ch/.w-med/.w-full son `grid-column: span N`: fuera de esa rejilla
   quedan en no-op, asi que aqui se usa columna simple y se anula el span.
   .wpins vivio hasta E3 como una franja apretada ENCIMA del chat, y de ahi traia
   `max-height:46vh; overflow-y:auto; margin`. Hoy su unico hogar es #riel-der, que ya es
   una columna alta con su propio scroll: dejar el tope puesto recortaba las tarjetas a
   media columna y metia una segunda barra de scroll dentro de la primera. */
.wpins{ display:flex; flex-direction:column; gap:12px; }
.wpins .widget, .wsuelto{ grid-column:auto; width:100%; }
/* Consultas por CONTENEDOR y no por viewport: la tarjeta puede vivir en una columna
   angosta aunque la pantalla sea ancha. */
.wsuelto{ container-type:inline-size; }
.wsuelto .w-head{ cursor:default; }
.wsuelto-btn{ font-size:var(--t-meta); padding:2px 8px; width:auto; height:auto; border-radius:var(--r); }
/* Tarjetas que Xarpie pinta dentro de su respuesta.
   OJO CON LA CAJA: .brow es un flex en FILA (ava + bubwrap). Al colgar aqui un tercer hijo
   sin mas, se convertia en una COLUMNA de 2px de ancho y 1300 de alto: una astilla
   invisible que ademas inflaba el scroll y hacia parecer que el chat estaba vacio.
   flex-basis:100% + flex-wrap en el .brow lo bajan a su propio renglon, a lo ancho. */
.brow-conwidgets{ flex-wrap:wrap; }
.browwidgets{ flex:0 0 100%; min-width:0; display:flex; flex-direction:column; gap:10px; margin:10px 0 2px 40px; }
.browwidgets .widget{ grid-column:auto; width:auto; max-width:100%; }
@media (max-width:860px){ .browwidgets{ margin-left:0; } }

/* Fila LOCAL de un comando "/" (ver "COMANDOS DEL CHAT" en app.js): no viene del agente,
   asi que se distingue apenas -- sin avatar, solo una etiqueta chica con lo que se
   tecleo y una X para quitarla. Reusa .browwidgets/.brow-conwidgets para el host de la
   tarjeta: es la MISMA caja que usa mostrar_widget de Xarpie. */
.brow-local{ margin:2px 0; }
.brow-local-tag{ flex:0 0 100%; display:flex; align-items:center; gap:8px; margin-left:40px; font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.02em; color:var(--muted); }
.brow-local-x{ border:0; background:transparent; color:var(--muted); cursor:pointer; padding:2px 5px; border-radius:var(--r); font-size:var(--t-texto); line-height:1; }
@media (hover:hover){ .brow-local-x:hover{ background:#ECE7DB; color:var(--ink); } }
.brow-local-chips{ display:flex; flex-wrap:wrap; gap:8px; margin-top:2px; }

/* LA REPISA (Fase 4, "chat como superficie"): tira fija ENCIMA de #chat-msgs, hermana suya
   -- nunca dentro (#chat-msgs es role=log con aria-live, ver el comentario junto a
   #chat-msgs en index.html). Una sola a la vez, sin pila que gestionar: mostrarEnRepisa()
   reemplaza el contenido en vez de apilar. Tokens y clases portados del Design canvas
   aprobado (Repisa.dc.html) -- son los mismos --bone/--paper/--accent/--serif de siempre,
   no un tema aparte. */
/* "Viendo:" (Tramo B2): una linea discreta, no una tarjeta; solo dice que ficha viaja. */
.chat-viendo{ flex:none; display:flex; align-items:center; gap:6px; padding:5px 20px;
  font-size:var(--t-meta); color:var(--muted); border-bottom:1px solid var(--line2); min-width:0; }
.chat-viendo .cv-nombre{ color:var(--ink); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; min-width:0; }
.chat-viendo .cv-btn{ flex:none; border:0; background:none; color:var(--muted); cursor:pointer;
  width:22px; height:22px; border-radius:6px; font-size:12px; line-height:1; }
.chat-viendo .cv-fijar.on{ color:var(--ink); background:var(--line2); }
@media (hover:hover){ .chat-viendo .cv-btn:hover{ color:var(--ink); background:var(--line2); } }
.chat-viendo .cv-fijar{ margin-left:auto; }
.repisa{ flex:none; background:var(--paper); border-bottom:1px solid var(--line2);
         box-shadow:0 8px 22px -16px rgba(0,0,0,.4); }
.rtop{ display:flex; align-items:flex-start; gap:9px; padding:11px 20px 9px; }
.rkick{ font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); font-weight:600; }
.rtit{ font-family:var(--serif); font-size:var(--t-campo); font-weight:400; line-height:1.15; margin-top:1px; letter-spacing:-.01em }
.rcifras{ display:flex; gap:22px; padding:2px 20px 12px; flex-wrap:wrap; }
.cif-k{ font-size:var(--t-eti); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); font-weight:600; display:block; }
.cif-v{ font-family:var(--serif); font-size:var(--t-sub); font-weight:400; line-height:1.05; margin-top:2px; display:block; letter-spacing:-.01em }
.cif-s{ font-size:var(--t-meta); color:var(--muted); margin-top:1px; }
.racc{ display:flex; flex-wrap:wrap; gap:7px; padding:0 20px 14px; }
/* Los chips del turno cuelgan DIRECTO de .brow (no de .browwidgets, que ahi no existe),
   asi que tienen que repetir su geometria: sin `flex:0 0 100%` .brow los acomoda como una
   tercera columna al lado de la burbuja, y sin el margen quedan 40px a la izquierda de
   ella, debajo del avatar. Medido con un mensaje corto: los chips salian a la derecha de
   la burbuja en vez de abajo. */
.turno-chips{ flex:0 0 100%; margin:8px 0 2px 40px; }
@media (max-width:860px){ .turno-chips{ margin-left:0; } }
.cmd-candidatos{ display:flex; flex-direction:column; gap:2px; }
.cmd-ayuda{ display:flex; flex-direction:column; gap:2px; }
.cmd-ayuda-fila{ display:flex; align-items:center; gap:9px; padding:7px 2px; border-bottom:1px solid var(--hair); font-size:var(--t-texto); }
.cmd-ayuda-fila:last-child{ border-bottom:0; }
@media (max-width:860px){ .brow-local-tag{ margin-left:0; } }

/* ---- "/cierre": el espejo del ritual (filaLocalCierre en app.js) ----
   Deliberadamente mas sobrio que la tarjeta de la manana: la manana tiene que llamar la
   atencion y proponer, la noche solo cuenta lo que paso y ofrece soltar. */
.cierre{ display:flex; flex-direction:column; gap:10px; }
.cierre-marcador{ font-size:var(--t-texto); color:var(--ink); }
.cierre-pregunta{ font-size:var(--t-meta); color:var(--muted); }
.cierre-lista{ display:flex; flex-direction:column; gap:2px; }
.cierre-fila{ display:flex; align-items:center; gap:10px; padding:6px 2px; border-bottom:1px solid var(--hair); font-size:var(--t-texto); }
.cierre-fila:last-child{ border-bottom:0; }
.cierre-txt{ flex:1 1 auto; min-width:0; overflow-wrap:anywhere; }
.cierre-manana{ flex:0 0 auto; }
/* Ya movida: se apaga en vez de desaparecer -- que la fila siga ahi es la confirmacion
   de que ESA era la que se solto, y evita que la lista salte bajo el dedo. */
.cierre-fila-ida{ opacity:.5; }
.cierre-limpio{ font-size:var(--t-texto); color:var(--ok); }

/* ---- El ritual de la manana (ritualManana en app.js) ----
   Una sola tarjeta: saludo + "que fijas para hoy" + las filas de El Foco. Reusa .foco-list
   y .foco-item tal cual (mismo markup que el hero del Panel via focoItemHTML), asi que aqui
   solo va el envoltorio y lo propio del ritual. */
#ritual-manana .ritual{ background:var(--paper); border:1px solid var(--hair); border-radius:var(--r); padding:18px 20px 8px; box-shadow:0 1px 3px rgba(41,40,36,.04); }
#ritual-manana .ritual-saludo .bub{ background:transparent; border:0; padding:0; margin:0; }
.ritual-pregunta{ display:flex; align-items:baseline; justify-content:space-between; gap:12px; margin:16px 0 2px; padding-top:14px; border-top:1px solid var(--hair); }
.ritual-q{ font-family:var(--serif,Georgia,serif); font-size:var(--t-texto); color:var(--ink); }
.ritual-contador{ font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.02em; color:var(--muted); white-space:nowrap; }
.ritual-despejado{ margin:14px 0 10px; padding-top:14px; border-top:1px solid var(--hair); font-size:var(--t-texto); color:var(--muted); }
/* Con "/foco" no hay saludo (es un repintado, no un briefing nuevo): sin esto la linea
   divisoria quedaba flotando en el borde de arriba de la tarjeta, separando de nada. */
.ritual > .ritual-pregunta:first-child, .ritual > .ritual-despejado:first-child{ margin-top:2px; padding-top:0; border-top:0; }
/* La racha a la izquierda y el boton a la derecha: son cosas distintas (una constata, el
   otro acciona) y juntarlas las haria parecer una sola. El <span> va PRIMERO en el DOM y
   sin row-reverse, para que cuando no hay boton (no-dueno) la racha quede a la izquierda
   de verdad y no saltando al borde derecho. */
.ritual-pie{ display:flex; justify-content:space-between; align-items:center; gap:10px; padding:10px 0 4px; }
.ritual-racha{ font-size:var(--t-meta); color:var(--muted); }
/* Sin boton y sin racha el pie no tiene nada que decir: sus 14px de padding dejarian un
   hueco al final de la tarjeta. Se colapsa en vez de condicionar el render, para que el
   <span> exista SIEMPRE y ritualPintarRacha pueda llenarlo en el momento en que la racha
   llega a 2 fijando hoy (si no, ese dia no se veria y aparecia hasta el siguiente). */
.ritual-pie:not(:has(button)):has(.ritual-racha:empty){ display:none; }
/* El chip de fijar: primario visualmente, porque es LA decision de la manana. */
.foco-btn-fijar{ border-color:var(--accent); color:var(--accent); }
@media (hover:hover){ .foco-btn-fijar:hover:not(:disabled){ background:var(--accent-solido); color:var(--accent-tinta); } }
.foco-btn-fijar.fijada, .foco-btn-fijar:disabled{ border-color:var(--line2); color:var(--muted); background:var(--bone); cursor:default; }
/* La mitad conversacional de la bifurcacion de "preparar". Deliberadamente mas callado que
   el boton primario ("Crear mi primer paquete"): configurarlo uno mismo sigue siendo el
   camino recomendado -- este es el atajo para quien no quiere salir del chat. */
.foco-btn-xarpie{ border-style:dashed; color:var(--muted); }
@media (hover:hover){ .foco-btn-xarpie:hover{ border-style:solid; color:var(--accent); } }
/* Con la cuota llena, los chips que quedan se apagan: dejan de invitar sin desaparecer
   (que confundiria mas que ayudar). El aviso de por que llega por toast al intentarlo. */
.ritual-lleno .foco-btn-fijar:not(.fijada){ opacity:.45; }

/* ---- Panel derecho apilable ----
   En escritorio va EN EL FLUJO: no tapa nada, empuja. Por eso no es un dialogo y no
   atrapa el foco. En telefono se superpone y ahi si (ver panelSync). */
.wpanel{ display:flex; flex-direction:column; background:var(--paper); border-left:1px solid var(--hair); height:100vh; overflow:hidden; }
.wpanel[hidden]{ display:none; }
.wpanel-head{ display:flex; align-items:center; gap:8px; padding:12px 14px; border-bottom:1px solid var(--hair); flex:0 0 auto; }
.wpanel-title{ font-family:var(--serif); font-size:var(--t-campo); font-weight:400; margin:0; flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; letter-spacing:-.01em }
.wpanel-title:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; border-radius:4px; }
.wpanel-btn{ flex:0 0 30px; width:30px; height:30px; display:grid; place-items:center; border:1px solid var(--line2); border-radius:var(--r); background:transparent; color:var(--muted); cursor:pointer; font-size:var(--t-texto); }
@media (hover:hover){ .wpanel-btn:hover{ background:var(--bone); color:var(--ink); } }
.wpanel-btn[hidden]{ display:none; }
.wpanel-body{ flex:1; overflow-y:auto; padding:14px; }
.wpanel-body .widget{ grid-column:auto; width:auto; }
.wpanel-backdrop{ display:none; }

@media (min-width:861px){
  .wpanel{ flex:0 0 clamp(360px,28%,520px); min-width:0; }
}
@media (max-width:860px){
  /* Se superpone. z-index 66: por encima del contenido y por DEBAJO del cajon del chat
     (70) y su backdrop (69), para no romper el chat cuando los dos estan abiertos. */
  .wpanel{ position:fixed; inset:0 0 0 auto; width:min(94vw,460px); z-index:66; box-shadow:-14px 0 40px -20px rgba(0,0,0,.5); }
  .wpanel-backdrop:not([hidden]){ display:block; position:fixed; inset:0; z-index:65; background:rgba(43,41,38,.42); }
}

/* ---- Pregunta de Xarpie con opciones ---- */
/* El boton de saltar a una pantalla (tool abrir_pantalla). Mismo margen izquierdo que la
   pregunta para que se alinee con el texto de la burbuja, pero SIN tarjeta: es una accion
   al pie de la respuesta, no un bloque que compita con ella. */
/* Aviso de trabajo terminado en el chat (Tramo B7c): una linea de sistema, no una burbuja de
   Xarpie (no la escribio el modelo). Mismo sangrado que .xtarjeta para alinear con el hilo. */
.xaviso{ display:flex; align-items:center; gap:10px; margin:10px 0 2px 40px; max-width:520px; padding:8px 12px;
  border:1px dashed var(--line2); border-radius:var(--r); font-size:var(--t-meta); color:var(--muted); }
.xaviso-eti{ flex:none; text-transform:uppercase; letter-spacing:.12em; font-weight:600; font-size:var(--t-eti); color:var(--ink); }
.xaviso-txt{ display:flex; flex-direction:column; gap:1px; min-width:0; flex:1; }
.xaviso-tit{ color:var(--ink); overflow-wrap:anywhere; }
.xaviso-det{ overflow-wrap:anywhere; }
.xaviso-ir{ flex:none; }
/* Interruptor "propone / solo lo que pida" del "+" (Tramo B6). */
.ag-toggle{ display:flex; align-items:center; gap:12px; width:100%; padding:8px 4px; border:0; background:none;
  color:inherit; font:inherit; text-align:left; cursor:pointer; border-radius:var(--r); }
@media (hover:hover){ .ag-toggle:hover{ background:var(--line2); } }
.ag-toggle-txt{ display:flex; flex-direction:column; gap:2px; min-width:0; flex:1; }
.ag-toggle-tit{ color:var(--ink); }
.ag-toggle-pista{ font-size:var(--t-meta); color:var(--muted); }
.ag-toggle-val{ flex:none; font-size:var(--t-meta); padding:3px 9px; border:1px solid var(--line2); border-radius:999px; color:var(--ink); }
.ag-toggle[aria-checked="false"] .ag-toggle-val{ color:var(--muted); }
/* Senalar en pantalla (Tramo B5): un contorno que aparece y se apaga, sin mover el layout
   (outline no ocupa espacio). Sin animacion para quien pide menos movimiento. */
@keyframes xarpie-resalte { 0%, 70% { outline-color:var(--ink); } 100% { outline-color:transparent; } }
.fsec.xarpie-resalte{ outline:2px solid var(--ink); outline-offset:4px; border-radius:var(--r); animation:xarpie-resalte 4s ease-out forwards; }
@media (prefers-reduced-motion: reduce){ .fsec.xarpie-resalte{ animation:none; } }
/* Tarjeta de accion (Tramo B3): mismo sangrado que .xarpieabrir para alinear con la burbuja. */
.xtarjeta{ flex:0 0 100%; min-width:0; max-width:520px; margin:10px 0 2px 40px; padding:12px 14px;
  border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); display:flex; flex-direction:column; gap:8px; }
.xtarjeta-titulo{ font-weight:600; color:var(--ink); }
.xtarjeta-resumen{ font-size:var(--t-meta); color:var(--muted); }
.xtarjeta-campos{ margin:0; display:grid; grid-template-columns:auto 1fr; gap:3px 12px; font-size:var(--t-meta); }
.xtarjeta-campos dt{ color:var(--muted); }
.xtarjeta-campos dd{ margin:0; color:var(--ink); overflow-wrap:anywhere; }
.xtarjeta-pie{ display:flex; flex-wrap:wrap; gap:6px; }
.xtarjeta-estado{ font-size:var(--t-meta); color:var(--muted); }
.xtarjeta-estado.ok{ color:var(--ink); }
.xarpieabrir{ flex:0 0 100%; min-width:0; margin:10px 0 2px 40px; display:flex; flex-direction:column; align-items:flex-start; gap:6px; }
.xarpieabrir-motivo{ font-size:var(--t-meta); color:var(--muted); }
.xarpieabrir-btn{ display:inline-flex; align-items:center; gap:7px; padding:8px 15px; border:1px solid var(--line2); border-radius:var(--r);
  background:var(--paper); color:var(--ink); font-family:inherit; font-size:var(--t-texto); cursor:pointer; transition:.13s; }
@media (hover:hover){ .xarpieabrir-btn:hover{ border-color:var(--accent); color:var(--accent); } }
.xarpieabrir-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:2px; }
@media (max-width:860px){ .xarpieabrir{ margin-left:0; } }

.xarpiepreg{ flex:0 0 100%; min-width:0; margin:12px 0 2px 40px; border:1px solid var(--line2); border-radius:var(--r); padding:14px 16px; background:var(--paper); }
.xarpiepreg-q{ font-size:var(--t-texto); font-weight:500; margin-bottom:12px; }
.xarpiepreg-ops{ display:flex; flex-direction:column; gap:8px; }
.xarpiepreg-op{ display:flex; flex-direction:column; gap:2px; text-align:left; padding:10px 13px; border:1px solid var(--line2); border-radius:var(--r); background:transparent; color:var(--ink); cursor:pointer; transition:.13s; }
@media (hover:hover){ .xarpiepreg-op:hover:not(:disabled){ border-color:var(--accent); background:var(--bone); } }
.xarpiepreg-op:disabled{ cursor:default; opacity:.55; }
.xarpiepreg-op.elegida{ border-color:var(--accent); background:var(--bone); opacity:1; }
.xarpiepreg-et{ font-size:var(--t-texto); font-weight:500; }
.xarpiepreg-det{ font-size:var(--t-meta); color:var(--muted); }
.xarpiepreg-pie{ font-size:var(--t-meta); color:var(--muted); margin-top:10px; }
@media (max-width:860px){ .xarpiepreg{ margin-left:0; } }

/* Pulgar arriba/abajo al pie de una respuesta de Xarpie. Discretos a proposito: se ven al
   pasar el mouse por la burbuja, no compiten con el contenido. */
/* Cuelgan de .bubtools (ver pintarSenalDeXarpie), asi que ya NO manejan su propia opacidad
   ni su propio hover: los hereda la fila. El estilo del boton lo comparten con .bubtool
   arriba. Antes usaban var(--paper2), un token que NO EXISTE: el respaldo era un negro al
   4% invisible en tema oscuro, que es el default de la app. */
.xarpie-senal{ display:flex; align-items:center; gap:2px; }
.xarpie-senal .tsub{ font-size:var(--t-meta); color:var(--muted); padding:0 4px; }
.xs-mal .ico{ transform:rotate(180deg); }
/* Menus flotantes del nav (el "Mas" de la fila de sub-pestanas): viven en <body> con
   coordenadas que calcula pintarSubtabs. Van DESPUES de .usermenu (misma especificidad). */
.nav-menu{ position:fixed; top:auto; right:auto; width:200px; }
.nav-menu .um-item.on{ color:var(--accent); font-weight:600; }
/* Galerias: rejilla con portada grande. Columnas anchas (260px min) para que la
   foto se lea como foto y no como miniatura de lista. */
.gal-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); gap:20px; }
.gal-card{ text-align:left; border:0; background:transparent; padding:0; cursor:pointer; color:inherit; font:inherit; }
.gal-cover{ position:relative; aspect-ratio:4/3; border-radius:var(--r); overflow:hidden; background:var(--deep); border:1px solid var(--line2); }
.gal-cover img{ width:100%; height:100%; object-fit:cover; display:block; transition:transform .3s ease; }
@media (hover:hover){ .gal-card:hover .gal-cover img{ transform:scale(1.04); } }
.gal-cover-vacia{ width:100%; height:100%; display:grid; place-items:center; color:var(--muted); font-size:var(--t-meta); }
.gal-badge{ position:absolute; top:10px; left:10px; }
.gal-info{ padding:10px 2px 0; }
.gal-nombre{ font-size:var(--t-texto); font-weight:600; line-height:1.25; }
.gal-meta{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
.gal-card-s{ font-size:var(--t-meta); color:var(--muted); }
.gal-nums{ display:flex; flex-wrap:wrap; gap:10px; font-size:var(--t-meta); color:var(--muted); margin-top:6px; }

/* Galerias: la tarjeta dejo de ser <button> (no se pueden anidar botones): la
   portada es el boton de abrir y las acciones van aparte, debajo. */
.gal-abrir{ display:block; width:100%; text-align:left; border:0; background:transparent; padding:0; cursor:pointer; color:inherit; font:inherit; }
.gal-acc{ display:flex; align-items:center; gap:8px; margin-top:10px; padding:0 2px; }
.gal-menu-wrap{ position:relative; display:inline-flex; margin-left:auto; }
.gal-mas{ line-height:1; padding:6px 10px; }
/* Igual que .posp-menu y .nav-menu: va despues de .usermenu (misma especificidad,
   gana la ultima) y en fixed, porque la tarjeta lo recortaria. */
.gal-menu{ position:fixed; top:auto; right:auto; width:190px; }

/* Armador de filtros con grupos (2 niveles) y orden multinivel. */
.db-fgrupo{ margin-bottom:6px; }
.db-fgrupo-caja{ border:1px solid var(--hair); border-radius:var(--r); padding:8px 9px; }
/* El nexo ("donde" / el selector Y-O) va en columna fija: sin ancho comun las filas
   quedan escalonadas y cuesta leer que condicion pertenece a que grupo. */
.db-fc-nexo{ flex:0 0 68px; font-size:var(--t-meta); color:var(--muted); }
.db-fc-nexo .sel-sm{ width:100%; }
.db-fc-entre{ padding:5px 0 5px 2px; font-size:var(--t-meta); color:var(--muted); }
.db-fc-entre .sel-sm{ width:68px; }

/* ================= Configurar vista de base (panel de dos columnas) =================
   El modal viejo era un scroll plano de 600px: 8 secciones apiladas, las que no aplicaban
   al tipo se ocultaban con display:none (saltos sin explicacion) y las columnas se
   controlaban en dos lugares distintos. Aqui: riel de secciones con contadores, un pane a
   la vez, columnas unificadas y una tira de vista previa fija arriba del pie.
   --cvp-tint / --cvp-alerta son locales porque en tema oscuro --red y --accent son el
   MISMO color (#D97757): un aviso pintado con --red seria invisible sobre el acento. */
:root{ --cvp-tint:rgba(201,100,66,.09); --cvp-sup:rgba(43,40,36,.035); --cvp-alerta:#B3492A; }
:root[data-theme="dark"]{ --cvp-tint:rgba(217,119,87,.15); --cvp-sup:rgba(255,255,255,.045); --cvp-alerta:#E8A48C; }

.cvp-modal{ width:940px; max-width:96vw; }
.cvp{ display:grid; grid-template-columns:216px minmax(0,1fr); min-height:400px; }
.cvp-riel{ display:flex; flex-direction:column; gap:2px; padding:14px 10px; border-right:1px solid var(--hair); background:var(--cvp-sup); }
.cvp-tab{ display:grid; grid-template-columns:1fr auto; align-items:center; gap:2px 8px; text-align:left; width:100%;
  border:0; border-radius:var(--r); background:transparent; padding:9px 11px; cursor:pointer; color:var(--ink); }
@media (hover:hover){ .cvp-tab:hover{ background:var(--cvp-tint); } }
.cvp-tab.on{ background:var(--cvp-tint); box-shadow:inset 2px 0 0 var(--accent); }
.cvp-tab-nom{ font-size:var(--t-texto); font-weight:600; }
.cvp-tab-sub{ grid-column:1; font-size:var(--t-meta); color:var(--muted); line-height:1.35; }
.cvp-tab-b{ grid-row:1; grid-column:2; font-family:var(--mono); font-size:var(--t-eti); color:var(--muted);
  background:var(--paper); border:1px solid var(--line2); border-radius:var(--r); padding:1px 7px; white-space:nowrap; }
.cvp-tab.on .cvp-tab-b{ color:var(--accent); border-color:var(--accent); }
.cvp-alerta{ display:inline-grid; place-items:center; width:15px; height:15px; border-radius:50%;
  background:var(--cvp-alerta); color:var(--paper); font-size:var(--t-eti); font-weight:700; vertical-align:1px; }

.cvp-pane{ padding:20px 24px; max-height:min(58vh,520px); overflow-y:auto; }

/* --- selector de tipo de vista --- */
.cvp-tipos{ display:grid; grid-template-columns:repeat(auto-fill,minmax(158px,1fr)); gap:8px; margin-top:8px; }
.cvp-tipo{ display:flex; flex-direction:column; gap:3px; text-align:left; padding:11px 12px; cursor:pointer;
  border:1px solid var(--line2); border-radius:var(--r); background:transparent; color:var(--ink); }
@media (hover:hover){ .cvp-tipo:hover{ border-color:var(--accent); } }
.cvp-tipo.on{ border-color:var(--accent); background:var(--cvp-tint); }
.cvp-tipo-ic{ font-size:var(--t-texto); line-height:1.1; color:var(--accent); }
.cvp-tipo-nom{ font-size:var(--t-texto); font-weight:600; }
.cvp-tipo-desc{ font-size:var(--t-meta); color:var(--muted); line-height:1.4; }

.cvp-aviso{ margin-top:14px; padding:10px 12px; border-radius:var(--r); font-size:var(--t-meta); line-height:1.5;
  border:1px solid var(--cvp-alerta); color:var(--cvp-alerta); background:var(--cvp-sup); }
.cvp-req{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase;
  color:var(--cvp-alerta); border:1px solid currentColor; border-radius:var(--r); padding:0 5px; margin-left:4px; }
.cvp-vacio{ padding:16px; border:1px dashed var(--line2); border-radius:var(--r); font-size:var(--t-texto); color:var(--muted); text-align:center; }

/* --- filtros y orden --- */
.cvp-grupo{ border:1px solid var(--line2); border-radius:var(--r); padding:10px 11px; background:var(--cvp-sup); }
.cvp-entre{ padding:7px 0 7px 4px; }
.cvp-cond{ display:flex; gap:7px; align-items:center; flex-wrap:wrap; margin:6px 0; }
.cvp-nexo{ flex:0 0 78px; }
.cvp-nexo-fijo{ font-size:var(--t-meta); color:var(--muted); }
.cvp-conj{ width:100%; }
.cvp-entre .cvp-conj{ width:78px; }
.cvp-x{ margin-left:auto; color:var(--muted); }
@media (hover:hover){ .cvp-x:hover{ color:var(--cvp-alerta); } }

/* --- columnas unificadas (ver + orden + ancho + pie) --- */
.cvp-colhead{ display:flex; gap:8px; align-items:center; padding:0 2px 7px; border-bottom:1px solid var(--hair);
  font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.09em; text-transform:uppercase; color:var(--muted); }
.cvp-colhead-ver{ width:26px; }
.cvp-cols{ display:flex; flex-direction:column; }
.cvp-col{ display:flex; gap:8px; align-items:center; padding:7px 2px; border-bottom:1px solid var(--hair); }
.cvp-col:last-child{ border-bottom:0; }
.cvp-col.es-titulo{ background:var(--cvp-tint); border-radius:var(--r) var(--r) 0 0; padding-left:6px; padding-right:6px; }
.cvp-col-ver{ width:26px; display:grid; place-items:center; }
.cvp-col-ver input[type="checkbox"]{ width:16px; height:16px; accent-color:var(--accent); cursor:pointer; }
.cvp-fijo{ color:var(--accent); font-size:var(--t-meta); cursor:help; }
.cvp-col-nom{ display:flex; align-items:center; gap:7px; font-size:var(--t-texto); }
.cvp-col-ic{ color:var(--muted); font-size:var(--t-meta); width:15px; text-align:center; }
.cvp-col-mov{ width:56px; display:flex; gap:2px; justify-content:flex-end; }
.cvp-col-mov .btn{ padding:2px 6px; }

/* --- tira de vista previa (corre la consulta de verdad mientras configuras) --- */
.cvp-prev{ display:flex; align-items:center; gap:10px; padding:10px 24px;
  border-top:1px solid var(--hair); background:var(--cvp-sup); }
.cvp-prev-et{ flex:0 0 auto; font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.09em;
  text-transform:uppercase; color:var(--muted); }
.cvp-prev-txt{ flex:1; min-width:0; font-size:var(--t-meta); color:var(--ink);
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.cvp-prev-txt.es-vacio{ color:var(--muted); }
.cvp-prev-txt.es-error{ color:var(--cvp-alerta); }

@media (max-width:760px){
  .cvp{ grid-template-columns:1fr; }
  .cvp-riel{ flex-direction:row; overflow-x:auto; border-right:0; border-bottom:1px solid var(--hair); padding:10px; }
  .cvp-tab{ flex:0 0 auto; grid-template-columns:auto; }
  .cvp-tab-sub{ display:none; }
  .cvp-tab-b{ grid-row:auto; grid-column:auto; }
  .cvp-pane{ padding:16px; }
  .cvp-prev{ padding:10px 16px; }
}

/* Selector de tamano dentro del panel de configuracion de una tarjeta */
.wcfg-tams{ display:flex; gap:6px; }
.wcfg-tam{ flex:1; padding:9px 10px; font-size:var(--t-texto); cursor:pointer; color:var(--ink);
  border:1px solid var(--line2); border-radius:var(--r); background:transparent; }
@media (hover:hover){ .wcfg-tam:hover{ border-color:var(--accent); } }
.wcfg-tam.on{ border-color:var(--accent); background:var(--cvp-tint); color:var(--accent); font-weight:600; }

/* ---------- Proyectos: equipo (etapas, notas, conversacion, archivos) ---------- */
/* Editor de columnas del tablero. Rejilla propia y no .plt-row: ese es el editor de
   pasos de plantilla y tiene 5 columnas, no 3. */
.et-row{ display:grid; grid-template-columns:1fr auto 30px; gap:8px; align-items:center; margin-bottom:8px; }
.et-row .inp{ padding:8px 10px; font-size:var(--t-texto); }

.pj-notas{ display:grid; gap:14px; }
.pj-nota{ border:1px solid var(--line2); border-radius:var(--r); padding:12px 14px; background:var(--paper); }
.pj-nota-h{ display:flex; gap:8px; align-items:center; }
.pj-nota-tit{ flex:1; border:0; background:transparent; font:inherit; font-weight:600; font-size:var(--t-texto); color:var(--ink); padding:2px 0; }
.pj-nota-tit:focus{ outline:none; }
.pj-nota-txt{ width:100%; border:0; background:transparent; font:inherit; font-size:var(--t-texto); line-height:1.55; color:var(--ink);
  resize:vertical; min-height:90px; padding:6px 0; }
.pj-nota-txt:focus{ outline:none; }
.pj-nota-pie{ font-size:var(--t-meta); border-top:1px solid var(--line2); padding-top:8px; margin-top:4px; }

/* Conversacion */
.pj-comp{ display:flex; gap:8px; align-items:flex-end; margin-bottom:16px; }
.pj-comp .ta{ flex:1; min-height:56px; }
.pj-hilo{ display:grid; gap:12px; }
.pj-com{ border-left:2px solid var(--line2); padding:2px 0 2px 12px; }
.pj-com-h{ display:flex; gap:8px; align-items:center; font-size:var(--t-meta); flex-wrap:wrap; }
.pj-com-txt{ font-size:var(--t-texto); line-height:1.55; white-space:pre-wrap; margin-top:3px; }

/* Archivos y enlaces */
.pj-arch{ display:grid; gap:2px; }
.pj-arch-item{ display:flex; gap:10px; align-items:center; padding:9px 4px; border-bottom:1px solid var(--line2); }
.pj-arch-ico{ font-size:var(--t-texto); }
.pj-arch-nom{ color:var(--ink); text-decoration:none; font-size:var(--t-texto); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
@media (hover:hover){ .pj-arch-nom:hover{ text-decoration:underline; } }
.pj-arch-meta{ margin-left:auto; font-size:var(--t-meta); white-space:nowrap; }

/* Hilo dentro del modal de tarea */
.tarea-hilo{ border-top:1px solid var(--line2); margin-top:16px; padding-top:14px; }
.tarea-hilo-h{ font-family:var(--mono); font-size:var(--t-eti); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); margin-bottom:8px; }

@media (max-width:640px){
  .et-row{ grid-template-columns:1fr 30px; }
  .et-row label{ grid-column:1/3; }
  .pj-arch-meta{ display:none; }
}

/* ---------- Pestana "Ajustes" de la galeria ---------- */
/* Reusa los controles del editor de diseno (.ge-toggle / .ge-sw2 / .ge-sub) en vez de
   inventar un switch nuevo, pero mapeando las variables --ge-* a la paleta del CRM: aqui
   estamos DENTRO del panel, no en el editor de pantalla completa, y con los colores del
   editor se veria como un injerto. Cuando el editor entre como pestana (fase 4) los dos
   bloques van a compartir el mismo aspecto sin tocar nada. */
.gset{ max-width:640px; --ge-ink:var(--ink); --ge-ink2:var(--muted); --ge-ink3:var(--muted); --ge-line:var(--line2); --ge-line2:var(--hair); --ge-bg:var(--paper); }
.gset .ge-toggle+.ge-toggle{ border-top:1px solid var(--hair); }
/* El off del switch esta hardcodeado a un alfa de tinta oscura, que en tema oscuro
   desaparece contra el fondo. Aqui se le da un valor que funciona en los dos. */
:root[data-theme="dark"] .gset .ge-sw2{ background:rgba(240,236,228,.18); }
.gset .ge-sw2[disabled]{ opacity:.5; cursor:default; }

/* ---------- Editores de alto fijo anclados a #view ---------- */
/* `.main > #view` es `flex:1 0 auto` (shrink 0) a proposito: las paginas largas crecen y scrollea
   `.main`. En un editor manda lo contrario -- tiene que CABER para que sus columnas scrolleen
   por dentro. Sin `flex-shrink:1` + `min-height:0`, #view crecia a 1881px dentro de un .main de
   900px con overflow:hidden: nada scrolleaba y el resto quedaba recortado sin aviso.
   (El editor de galeria usaba aqui la clase .gal-full; desde el cascaron compartido de
   entregas lo hace `.main > #view:has(> .edg)`, en el bloque EDITOR-UNIFICADO.) */
/* El editor de contrato (ver la seccion de .ced): #/contrato/:id nunca convive con pestanas,
   .ced siempre es el UNICO contenido de #view en esa ruta, asi que :has() basta solo. */
.main > #view:has(.ced){ max-width:none; padding:0; overflow:hidden; display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.main:has(#view:has(.ced)){ overflow:hidden; }
/* SIN wrapper propio a proposito (a diferencia de un primer intento con #pd-cq): .ge-rail
   y .ge-canvas van DIRECTOS bajo .geditor.ge-embebido, igual que en galeria-diseno, porque
   las reglas @container de mas abajo (galeria-diseno) buscan .ge-embebido .ge-rail /
   .ge-embebido .ge-canvas como DESCENDIENTES del contenedor de consulta -- meter un div
   intermedio con su propio container-type rompe esa cadena (el rail se iba a 100% de ancho
   por la regla movil, pero .ge-embebido no recibia el flex-direction:column que la
   acompana, y el canvas quedaba en 0px). El contenedor de consulta va en #view, un
   ANCESTRO real de .geditor, exactamente el mismo criterio que #g-tabbody documenta abajo.
   Bug real encontrado probando en navegador, node --check nunca lo iba a atrapar. */
.main > #view:has(.ge-portal){ container-type:inline-size; max-width:none; padding:0; overflow:hidden; display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.main:has(#view:has(.ge-portal)){ overflow:hidden; }
/* El contenedor de consulta va en el PADRE, no en .ge-embebido: una container query no
   puede estilizar a su propio contenedor, asi que con container-type aqui abajo la regla
   de apilado de @container (max-width:900px) nunca aplicaba y, entre 0 y 900px de panel,
   el rail se llevaba el 100% del ancho y la vista previa quedaba en 0px -- desaparecia.
   Las reglas sobre .ge-rail/.ge-canvas si funcionaban (son descendientes), que es
   justamente lo que colapsaba el canvas. */
#g-tabbody{ container-type:inline-size; }
.geditor.ge-embebido{ position:relative; inset:auto; z-index:auto; height:100%; }

/* El ancho util aqui es menor que la ventana (el chat se lleva su parte), asi que el rail
   adelgaza y, si aun asi no cabe, se apila. Por @container y no @media a proposito: lo que
   manda es el ancho del PANEL, no el de la pantalla.

   OJO, ESTO YA NO ES CIERTO: aqui decia que estas reglas no alcanzaban a #/portal-diseno
   "que no declara contenedor". Desde el rediseño del portal, #view:has(.ge-portal) SI
   declara `container-type:inline-size` (a proposito, unas lineas arriba), asi que estas
   reglas aplican a LOS DOS editores embebidos. */
@container (max-width:1120px){ .ge-embebido .ge-rail{ width:340px; } }
@container (max-width:900px){
  .ge-embebido{ flex-direction:column; overflow:auto; }
  .ge-embebido .ge-rail{ width:100%; height:auto; border-right:0; border-bottom:1px solid var(--ge-line2); }
  .ge-embebido .ge-canvas{ min-height:60vh; }
}

/* Selector de portada */
.portada-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(120px,1fr)); gap:10px; }
.portada-op{ position:relative; padding:0; border:2px solid transparent; border-radius:var(--r); overflow:hidden; background:none; cursor:pointer; aspect-ratio:1; }
.portada-op img{ width:100%; height:100%; object-fit:cover; display:block; }
.portada-op.on{ border-color:var(--accent); }
.portada-op-tag{ position:absolute; left:6px; bottom:6px; background:var(--accent-solido); color:var(--accent-tinta); font-size:var(--t-eti); padding:2px 7px; border-radius:var(--r); }

/* Que foto es la portada, visible SIEMPRE en el grid (no solo en hover, que en tablet ni
   siquiera existe). Mismo tratamiento que .gal-oculta-badge. */
.gal-portada-badge{ position:absolute; left:8px; bottom:8px; background:var(--accent-solido); color:var(--accent-tinta); font-size:var(--t-eti); padding:2px 8px; border-radius:var(--r); }
@media (hover:none){ .gal-item-acts{ opacity:1 !important; } }

/* Ordenar la galeria y arrastrar para reordenar. */
.gal-orden{ display:flex; align-items:center; gap:8px; }
.gal-orden .inp-sm{ height:32px; padding:0 26px 0 10px; font-size:var(--t-texto); width:auto; }
.gal-orden-hint{ margin:2px 0 12px; }
/* Para arrastrar hace falta `touch-action:none`, o el navegador se queda el gesto para hacer
   scroll y el pointermove nunca llega. Pero en una pantalla tactil el grid ES casi todo
   fotos: ponerlo ahi dejaria la galeria sin forma de scrollear. Asi que el arrastre es de
   raton/lapiz, y en tactil se reordena con los criterios y el boton de aleatorio, que no
   necesitan gesto. Un long-press dedicado seria lo correcto el dia que alguien lo pida. */
@media (pointer:fine){ .gal-masonry.gal-reordenable .gal-item{ touch-action:none; } }
/* La tarjeta que sueltas se convierte en el hueco vacio de destino (imagen oculta, contorno
   punteado) -- quien lleva la foto en pantalla ahora es el fantasma que sigue al cursor
   (.gal-fantasma), asi que mostrar la misma foto dos veces (aqui dimeada y en el fantasma)
   solo confundia cual de las dos se iba a mover de verdad. */
.gal-item.gal-arrastrando{ opacity:.4; outline:2px dashed var(--acc); outline-offset:-2px; background:transparent; }
.gal-item.gal-arrastrando img{ visibility:hidden; }
body.gal-arrastrando-activo{ cursor:grabbing !important; }
/* Fantasma del arrastre: clon fijo (position:fixed, ajeno al flujo) que sigue al cursor.
   Sin el, arrastrar una foto se sentia desconectado de la mano -- la tarjeta original se
   quedaba en su sitio hasta cruzar a una vecina, sin nada "pegado" al mouse mientras tanto. */
.gal-fantasma{ position:fixed; z-index:95; pointer-events:none; border-radius:var(--r); background-size:cover; background-position:center; background-color:var(--deep); box-shadow:0 16px 34px -12px rgba(0,0,0,.55); outline:2px solid var(--acc); transform:scale(1.03); }
.ga-peligro .ge-tt{ color:#B0533A; }

/* El menu unico de configuracion, colgado del engrane de la nav. Vive como hijo de <body>
   y se posiciona con coordenadas de viewport, igual que .nav-menu: dentro de .navbar
   quedaria recortado por su overflow-x y por debajo de cualquier editor a pantalla
   completa. Va DESPUES de .usermenu (misma especificidad, gana el ultimo) para poder
   cambiar position sin subir el selector, como ya hacen .posp-menu y .nav-menu. */
.usermenu.cfg-menu{ position:fixed; top:auto; right:auto; width:230px; z-index:80; }
/* El panel de la campana es mas ancho que el menu del engrane (lleva icono + 2-3 lineas
   de texto por fila, no una sola etiqueta) -- misma especificidad que la regla de arriba,
   la gana por venir despues. */
.notif-panel{ width:320px; }
.notif-fila{ display:flex; align-items:flex-start; gap:10px; position:relative; padding-right:22px; }
.notif-fila .notif-ico{ flex:none; color:var(--muted); margin-top:1px; }
.notif-fila .notif-cuerpo{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.notif-fila .notif-titulo{ font-weight:600; white-space:normal; }
.notif-fila .notif-detalle{ color:var(--muted); font-size:var(--t-meta); white-space:normal; overflow:hidden; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; }
.notif-fila .notif-fecha{ color:var(--muted); font-size:var(--t-meta); }
/* El punto de "sin leer": mismo tono que --accent (ya lo usa el badge de la campana),
   asi que la fila y el contador cuentan la misma historia con el mismo color. */
.notif-fila .notif-dot{ position:absolute; top:14px; right:8px; width:7px; height:7px; border-radius:999px; background:var(--accent); }
.notif-fila.notif-no-leida .notif-titulo{ font-weight:700; }

/* Iconos (design_handoff_iconos). `vertical-align:-.14em` alinea el trazo con la linea base
   del texto que lo acompaña: sin esto, un icono a la izquierda de una etiqueta se ve
   flotando alto. `flex:none` evita que un icono se aplaste dentro de un boton flex cuando
   la etiqueta es larga. */
.ico{ display:inline-block; vertical-align:-.14em; flex:none; }

/* ===== Marca Xarpen (design_handoff_marca) =====
   Los tokens del handoff vienen con :root = OSCURO; aqui :root es CLARO y el oscuro va bajo
   [data-theme="dark"], asi que estan invertidos a proposito. No es una variacion de la marca:
   son los mismos dos valores de su tabla, colgados del interruptor que este proyecto ya usa.
   El punto del isotipo ya no es terracota (rediseno minimalista, decision de Daniel 2026-09-10):
   toma la misma tinta que el trazo. Los SVG de public/brand/ conservan su color: son el kit
   descargable, no la interfaz. */
:root{
  --xarpen-ink:#2a2520; --xarpen-ink-2:#6a6158;
  --xarpen-accent:var(--xarpen-ink); --xarpen-surface:#f4efe9;
}
:root[data-theme="dark"]{
  --xarpen-ink:#f5f4ee; --xarpen-ink-2:#bdbbb0;
  --xarpen-accent:var(--xarpen-ink); --xarpen-surface:#262624;
}
/* Sobre fotografia: todo blanco, SIN acento (el punto terracota se pierde contra piel y
   vestido) y velo obligatorio debajo. */
.xarpen-on-photo{ --xarpen-ink:#ffffff; --xarpen-accent:#ffffff; position:relative; }
.xarpen-on-photo::before{ content:""; position:absolute; inset:0; background:rgba(38,38,36,.42); }

/* El logo no define color propio: hereda la tinta de la marca. El padding ES el area de
   respeto (Ø/8) y no se recorta aunque apriete -- lo pone xarpenLockup() en linea junto con
   el hueco, porque los dos se derivan de Ø. */
.xarpen-logo{ display:inline-flex; align-items:center; color:var(--xarpen-ink); }
.xarpen-logo__txt{ display:flex; flex-direction:column; justify-content:center; min-width:0; }
.xarpen-logo__name{ font-family:var(--sans), "Instrument Sans", system-ui, sans-serif; font-weight:600; letter-spacing:-.045em; line-height:1; }
.xarpen-logo__slogan{ font-family:var(--sans), "Instrument Sans", system-ui, sans-serif; font-weight:500; letter-spacing:.24em; text-transform:uppercase; color:var(--xarpen-ink-2); margin-top:.5em; }
/* La linea del propio estudio bajo el nombre. No es parte de la marca: por eso va en ink-2,
   con el tracking del CRM y no el del wordmark. */
.xarpen-logo__sub{ font-family:var(--sans), system-ui, sans-serif; font-size:var(--t-eti); font-weight:500; letter-spacing:.12em; text-transform:uppercase; color:var(--xarpen-ink-2); margin-top:4px; line-height:1.25; overflow:hidden; text-overflow:ellipsis; }
.xarpen-logo--apilado{ flex-direction:column; text-align:center; }
.xarpen-logo--apilado .xarpen-logo__txt{ align-items:center; }
.xarpen-mark{ flex:none; display:block; }

/* Estado "procesando": gira SOLO la variante abierta, nunca la maestra. */
@keyframes xarpen-spin{ to{ transform:rotate(360deg); } }
.xarpen-mark--procesando circle:nth-child(1){ animation:xarpen-spin 6s linear infinite; transform-origin:50% 50%; }
.xarpen-mark--procesando circle:nth-child(2){ animation:xarpen-spin 4s linear infinite reverse; transform-origin:50% 50%; }
@media (prefers-reduced-motion: reduce){ .xarpen-mark--procesando circle{ animation:none; } }

/* ===== Xarpen · pulso de enfoque =====
   El parpadeo viaja del centro hacia afuera: punto, anillo de foco, medio y ruido. Es lo que
   el isotipo YA significa segun su handoff ("el desenfoque resolviendose"), puesto en el
   tiempo.

   NO se usa `filter: blur()` aunque el efecto se llame enfoque: el handoff lista los
   desenfoques (y las sombras, los degradados y rotar la maestra) entre "lo que rompe el
   sistema". El enfoque se consigue con el propio vocabulario de la marca -- opacidad y una
   escala minima -- y cada anillo vuelve EXACTAMENTE a su opacidad de especificacion (.3/.6/1),
   que es lo que hace `--op`.

   Los anillos se eligen por su radio y no por :nth-child a proposito: asi la misma regla vale
   para la maestra (4 formas) y para la compacta (3), sin contar hijos. */
/* Cada forma ARRANCA apagada y sube hasta su destello, en vez de partir de su opacidad
   final: el punto y el anillo de foco ya valen 1, asi que un pulso 1 -> 1 -> 1 no se ve y el
   parpadeo empezaba invisible justo en el centro, que es donde tiene que empezar. Medido con
   la Web Animations API antes de corregirlo. El fotograma final vuelve a `--op`, la opacidad
   de especificacion, para no dejar la marca fuera de norma cuando termina. */
@keyframes xarpen-pulso{
  0%   { opacity:calc(var(--op) * .18); transform:scale(.9); }
  45%  { opacity:1; transform:scale(1.04); }
  100% { opacity:var(--op); transform:scale(1); }
}
.xarpen-mark--enfoque circle{
  /* transform-box:fill-box hace que el origen sea el centro de CADA circulo y no el del SVG;
     sin el, la escala los desplaza en diagonal. */
  transform-box:fill-box; transform-origin:center;
  /* `backwards` y NO `both`: durante el retardo aplica el fotograma 0 (apagado, que es lo
     que hace que la onda arranque en el centro), y AL TERMINAR devuelve el mando al
     atributo `opacity` del propio SVG. Con `both` el ultimo fotograma se queda pegado, y
     si la animacion no llega a correr -- pestaña en segundo plano -- la marca se queda al
     18%, casi invisible. Asi la opacidad de especificacion vive en un solo sitio. */
  animation:xarpen-pulso .62s cubic-bezier(.22,.61,.36,1) backwards;
}
.xarpen-mark--enfoque circle[r="3"] { --op:1;  animation-delay:0ms; }
.xarpen-mark--enfoque circle[r="9"] { --op:1;  animation-delay:70ms; }
.xarpen-mark--enfoque circle[r="15"]{ --op:.6; animation-delay:140ms; }
.xarpen-mark--enfoque circle[r="21"]{ --op:.3; animation-delay:210ms; }
/* Una sola pasada por evento. Un logo latiendo sin parar en un CRM es ruido, no marca; el
   unico estado que si es continuo es "procesando", y para eso el handoff ya tiene su propia
   variante (la abierta, que gira). */
@media (prefers-reduced-motion: reduce){
  .xarpen-mark--enfoque circle{ animation:none; }
}

/* El avatar de cada respuesta del agente: el isotipo, en lugar del circulo con punto que
   habia. Se limpian el fondo y el ::after del blob viejo; el SVG hereda la tinta. */
.ava{ background:none; border:0; border-radius:0; color:var(--xarpen-ink); display:flex; align-items:center; justify-content:center; }
.ava::after{ content:none !important; }

/* ============ Selector de disenos de galeria (galeria-estilos.js) ============
   Overlay a pantalla completa que aparece ANTES del modal de "Nueva galeria": primero
   se elige el diseno viendolo en grande, despues se llenan los datos. Namespace .gx-
   (reservado al selector y sus mockups); los mockups .gxm-* dibujan cada tema con divs,
   sin imagenes -- fieles a la geometria del tema, no capturas que envejecen. */
.gx-sel{position:fixed;inset:0;z-index:320;background:color-mix(in srgb,var(--bone) 88%,transparent);backdrop-filter:blur(14px);-webkit-backdrop-filter:blur(14px)}
.gx-selscroll{height:100%;overflow-y:auto;padding:48px clamp(20px,5vw,72px) 60px}
.gx-selhd{display:flex;align-items:flex-start;justify-content:space-between;gap:20px;max-width:1060px;margin:0 auto 30px}
.gx-selsub{color:var(--muted);font-size:var(--t-texto);margin-top:8px;max-width:520px}
.gx-x{background:var(--paper);border:1px solid var(--hair);border-radius:50%;width:42px;height:42px;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--ink);flex:none}
@media (hover:hover){ .gx-x:hover{border-color:var(--ink)} }
.gx-selgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(380px,100%),1fr));gap:26px;max-width:1060px;margin:0 auto}
.gx-card{display:flex;flex-direction:column;text-align:left;padding:0;background:var(--paper);border:1px solid var(--hair);border-radius:var(--r);overflow:hidden;cursor:pointer;font:inherit;color:inherit;transition:transform .18s ease,box-shadow .18s ease,border-color .18s ease}
@media (hover:hover){ .gx-card:hover{transform:translateY(-3px);box-shadow:0 14px 34px rgba(43,41,38,.13);border-color:var(--line2)} }
.gx-card.on{border-color:var(--accent);box-shadow:0 0 0 1px var(--accent)}
/* Mas ALTA que ancha (4/5), en dos pasos del 2026-09-22 y los dos pedidos por Daniel: primero
   de 16/11 a cuadrada ("solo se ve una parte de la portada"), y luego a 4/5 ("mas largos de
   arriba hacia abajo, asi se ven portada Y acomodo").
   La caja es la PAGINA. Su alto se reparte entre la portada y el cuerpo, asi que las dos
   medidas van juntas: con 16/11 la portada quedaba en una franja de 2.35:1 y una foto con
   background-size:cover se recortaba a las caras (medido: 315x134), cuando el demo real en
   escritorio es 1440x900 = 1.6:1. Hoy la portada mide 50 % de 4/5, o sea 315x197 = 1.60:1
   clavado, y TODO el alto que se gano al alargar la caja va al cuerpo: el acomodo de fotos
   pasa de 38 % a 62 % del ancho.
   Si vuelves a mover esta proporcion, mueve tambien el 50 % de .gxm-cover (y el 37 % de
   revista) en sentido contrario, o la portada deja de tener forma de pantalla; y mira los
   mockups con reticula, que centran su composicion en el alto que sobra. */
.gx-mockwrap{aspect-ratio:4/5;background:var(--deep);overflow:hidden}
.gx-cardfoot{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:15px 18px;border-top:1px solid var(--hair)}
.gx-cardn{font-family:var(--serif);font-size:var(--t-campo);font-weight:400; letter-spacing:-.01em}
.gx-cards{color:var(--muted);font-size:var(--t-meta);margin-top:3px;line-height:1.45}
.gx-usar{flex:none;font-size:var(--t-meta);font-weight:600;color:var(--accent);white-space:nowrap;opacity:0;transform:translateX(-4px);transition:opacity .18s,transform .18s}
.gx-card:focus-visible .gx-usar{opacity:1;transform:none}
@media (hover:hover){ .gx-card:hover .gx-usar{opacity:1;transform:none} }
.gx-tag{display:inline-block;font-family:var(--sans);font-size:var(--t-eti);font-weight:600;color:var(--accent);border:1px solid currentColor;border-radius:var(--r);padding:1px 8px;vertical-align:2px;margin-left:4px}
.gx-tag-mov{color:var(--blue)}
.gx-soon{max-width:1060px;margin:34px auto 0}
.gx-soonlbl{font-size:var(--t-meta);letter-spacing:.14em;text-transform:uppercase;color:var(--muted);margin-bottom:10px}
.gx-soonchips{display:flex;flex-wrap:wrap;gap:8px}
.gx-soonchip{font-size:var(--t-meta);color:var(--muted);border:1px dashed var(--line2);border-radius:var(--r);padding:4px 12px}
/* Fila "plantilla actual + Cambiar" (modal de nueva galeria y pestana Diseno) */
.gx-actualrow{display:flex;align-items:center;justify-content:space-between;gap:12px}
.gx-actualn{font-family:var(--serif);font-size:var(--t-texto);font-weight:400; letter-spacing:-.01em}

/* --- Mockups. Base comun: una "pantalla" vertical con cover + grid. --- */
.gxm{width:100%;height:100%;display:flex;flex-direction:column;background:#FCFBF7}
/* 50 % de una caja 4/5 = la forma de una pantalla de escritorio (ver .gx-mockwrap). */
.gxm-cover{flex:0 0 50%;position:relative;display:flex;background:#1d1a16;color:#f3efe8}
.gxm-eyebrow{width:54px;height:4px;border-radius:2px;background:currentColor;opacity:.42}
.gxm-eyebrow.gxm-corta{width:34px}
.gxm-titulo{font-family:var(--serif);font-size:clamp(16.5px,2.4vw,23px);line-height:1.1;margin:9px 0; letter-spacing:-.01em}
.gxm-titulo i{font-style:italic;opacity:.75}
.gxm-grid{flex:1;display:grid;grid-template-columns:repeat(4,1fr);gap:5px;padding:8px}
.gxm-tile{background:linear-gradient(150deg,#DCD7CA,#C8C1B0);border-radius:2px}
/* Clasico: cover a todo lo ancho con texto centrado sobre un degradado de foto. */
.gxm-clasico .gxm-cover{align-items:center;justify-content:center;flex-direction:column;background:linear-gradient(160deg,#4a4034,#1a1712 75%)}
/* Papel: cover partida -- foto a la izquierda, titulo en la mitad oscura; el grid
   escalona sus tiles como guinio al movimiento de scroll del tema real. */
.gxm-papel .gxm-cover{background:#151310}
.gxm-papel .gxm-foto{width:44%;flex:none;background:linear-gradient(150deg,#6b5c48,#2e2820)}
.gxm-papel .gxm-lado{flex:1;display:flex;flex-direction:column;justify-content:center;padding:0 14px}
.gxm-papel .gxm-tile:nth-child(odd){transform:translateY(4px)}

/* Modo oscuro: el overlay hereda los tokens; solo el velo y los mockups claros
   necesitan ajuste fino. */
:root[data-theme="dark"] .gx-sel{background:color-mix(in srgb,#1F1E1D 88%,transparent)}
:root[data-theme="dark"] .gxm{background:#262624}
:root[data-theme="dark"] .gxm-tile{background:linear-gradient(150deg,#4a463f,#38352f)}

/* Mockups de Revista y Diario en el selector (F3) */
/* 37 %: la misma portada de antes en alto absoluto, ajustada a la caja 4/5 (era 46 % de una
   cuadrada). Revista la lleva mas baja que las demas a proposito: debajo va el capitulo. */
.gxm-revista .gxm-cover{flex:0 0 37%;align-items:center;justify-content:center;flex-direction:column;background:linear-gradient(165deg,#5a4c3c,#191714 78%)}
.gxm-rev-cap{display:flex;align-items:center;gap:8px;padding:10px 12px 0}
.gxm-rev-num{font-family:var(--mono,monospace);font-size:8.5px;letter-spacing:.14em;color:#a85d3e;white-space:nowrap}
.gxm-rev-rule{height:1px;flex:1;background:rgba(25,23,20,.18)}
.gxm-revista{background:#f5f2ea}
.gxm-rev-par{flex:1;display:grid;grid-template-columns:1.35fr 1fr;gap:6px;padding:8px 12px 10px;min-height:0}
.gxm-rev-a{height:100%}
.gxm-rev-col{display:grid;grid-template-rows:1fr 1fr;gap:6px;min-height:0}
.gxm-diario{flex-direction:row;background:#faf9f6}
.gxm-dia-rail{flex:none;width:52px;border-right:1px solid rgba(25,23,20,.1);display:flex;flex-direction:column;gap:12px;align-items:flex-end;padding:16px 8px 0 0}
.gxm-dia-h{font-family:var(--serif);font-size:12px;color:#c4bcb0; letter-spacing:-.01em}
.gxm-dia-h.on{color:#191714}
.gxm-dia-main{flex:1;display:flex;flex-direction:column;padding:12px 12px 10px;min-height:0}
.gxm-dia-t{font-size:15px;color:#191714;margin:0 0 4px}
.gxm-dia-grid{flex:1;display:grid;grid-template-columns:2fr 1fr;gap:6px;margin-top:8px;min-height:0}
.gxm-dia-a{height:100%}
:root[data-theme="dark"] .gxm-revista{background:#2b2925}
:root[data-theme="dark"] .gxm-diario{background:#262624}
:root[data-theme="dark"] .gxm-dia-t{color:#EDEBE6}
:root[data-theme="dark"] .gxm-dia-h.on{color:#EDEBE6}
:root[data-theme="dark"] .gxm-rev-rule{background:rgba(237,235,230,.15)}

/* ============================================================================
   SELECTOR DE PLANTILLAS DE LA PAGINA PUBLICA (#/pagina/plantillas, pagina.js)
   Paso 1 del flujo del handoff (galeria de 13 -> editor). Las miniaturas se
   pintan con estilos inline calculados del preset (ppMiniPagina) — el CSS de
   aqui es solo el marco de las tarjetas, con los tokens del tema de la app
   para que funcione en claro y oscuro sin reglas duplicadas.
   ============================================================================ */
/* Composicion de arranque (bio vs pagina completa). Va ARRIBA de las plantillas
   en el mismo Paso 1: son dos decisiones distintas — que secciones traes y con
   que estilo — y mezclarlas en una sola rejilla las confundia. */
.pp-arr{ display:grid; grid-template-columns:repeat(auto-fit, minmax(280px, 1fr)); gap:14px; margin:0 0 22px; }
.pp-arrcard{ border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); padding:16px 18px 18px; display:flex; flex-direction:column; }
@media (hover:hover){ .pp-arrcard:hover{ border-color:var(--accent); } }
.pp-arrnom{ font-size:var(--t-texto); font-weight:600; }
.pp-arrpitch{ font-size:var(--t-texto); line-height:1.6; color:var(--muted); margin:6px 0 0; }
.pp-arrsec{ font-size:var(--t-meta); line-height:1.7; color:var(--muted2, var(--muted)); margin:9px 0 14px; }
.pp-arrcard .btn{ margin-top:auto; align-self:flex-start; }
.pp-barra{ display:flex; align-items:center; gap:14px; flex-wrap:wrap; margin:0 0 18px; }
.pp-barra[hidden]{ display:none; }
.pp-barra #pp-cuenta{ margin-left:auto; }
.pp-grid{ display:grid; gap:22px; }
.pp-tcard{ border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); overflow:hidden; transition:border-color .16s; display:flex; flex-direction:column; }
@media (hover:hover){ .pp-tcard:hover{ border-color:var(--accent); } }
.pp-tcard.on{ border-color:var(--accent); box-shadow:0 0 0 1px var(--accent); }
/* La miniatura entera es un boton (elegir con un click en la vista previa). */
.pp-tprev{ display:block; width:100%; border:0; padding:0; background:none; cursor:pointer; text-align:inherit; border-radius:var(--r) var(--r) 0 0; overflow:hidden; }
.pp-mini{ pointer-events:none; }
.pp-tinfo{ padding:14px 16px 16px; display:flex; flex-direction:column; flex:1; }
.pp-tfila{ display:flex; align-items:baseline; gap:9px; flex-wrap:wrap; }
.pp-tnombre{ font-family:var(--serif); font-size:var(--t-campo); letter-spacing:-.01em }
.pp-ttag{ font-size:var(--t-meta); letter-spacing:.14em; text-transform:uppercase; color:var(--muted); }
.pp-tdesc{ font-size:var(--t-meta); line-height:1.6; color:var(--muted); margin:5px 0 0; }
.pp-tswatches{ display:flex; gap:5px; align-items:center; margin-top:12px; }
.pp-tswatches > span:not(.pp-tmeta){ width:20px; height:20px; border-radius:var(--r); border:1px solid var(--hair); }
.pp-tmeta{ margin-left:auto; font-family:var(--mono); font-size:var(--t-eti); color:var(--muted); }
.pp-tfuentes{ font-size:var(--t-meta); line-height:1.6; color:var(--muted); margin:10px 0 0; }
.pp-tusar{ margin-top:14px; width:100%; }

/* ===== Editor de la pagina publica: 3 columnas (panel · lienzo · inspector).
   Anclado a #view como .aled (position:absolute, no fixed: el codebase ya
   revirtio fixed una vez porque se comia la nav). Las reglas :has() de arriba
   le quitan a #view su caja de pagina cuando este editor esta montado. ===== */
.pp-editor{
  position:absolute; inset:0; z-index:40; background:var(--bone);
  display:grid; grid-template-columns:306px 1fr 334px; grid-template-rows:auto 1fr;
  grid-template-areas:"top top top" "panel canvas insp";
  container-type:inline-size;
}
.pp-top{ grid-area:top; display:flex; align-items:center; gap:14px; padding:10px 16px; border-bottom:1px solid var(--hair); background:var(--paper); }
.pp-top-t{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.pp-tplname{ font-family:var(--serif); font-size:var(--t-texto); color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; letter-spacing:-.01em }
.pp-cambiar-tpl{ font-size:var(--t-meta); color:var(--accent); white-space:nowrap; text-decoration:none; }
@media (hover:hover){ .pp-cambiar-tpl:hover{ text-decoration:underline; } }
.pp-top-acts{ display:flex; align-items:center; gap:8px; margin-left:auto; }
.pp-savestate{ font-size:var(--t-meta); color:var(--muted); font-family:var(--mono); white-space:nowrap; }

.pp-panel{ grid-area:panel; border-right:1px solid var(--hair); background:var(--paper); display:flex; flex-direction:column; min-height:0; }
.pp-tabs{ display:flex; border-bottom:1px solid var(--hair); flex:none; }
.pp-tab{ flex:1; padding:11px 4px; background:none; border:0; border-bottom:2px solid transparent; cursor:pointer; font:inherit; font-size:var(--t-meta); color:var(--muted); }
@media (hover:hover){ .pp-tab:hover{ color:var(--ink); } }
.pp-tab.on{ color:var(--ink); border-bottom-color:var(--accent); font-weight:600; }
.pp-panel-in{ flex:1; overflow-y:auto; padding:14px; min-height:0; }
.pp-hint{ font-size:var(--t-meta); line-height:1.6; color:var(--muted); margin:0 0 12px; }
.pp-sub{ font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); font-weight:600; margin:16px 0 8px; }
.pp-panel-in > .pp-sub:first-child, .pp-insp-in > .pp-sub:first-child{ margin-top:0; }

/* Modo bio del editor de pagina: los controles finos de diseno no desaparecen,
   se pliegan aqui para no ser lo primero que ve quien solo quiere una liga de
   enlaces. La summary imita a .pp-sub para que abierto o cerrado se sienta como
   una seccion mas del panel, no como un <details> de navegador por defecto. */
.pp-avanzado{ margin-top:16px; }
.pp-avanzado summary{ font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); font-weight:600; cursor:pointer; list-style:none; }
.pp-avanzado summary::-webkit-details-marker{ display:none; }
.pp-avanzado summary::before{ content:"▸ "; }
.pp-avanzado[open] summary::before{ content:"▾ "; }
.pp-avanzado[open] summary{ margin-bottom:8px; }

.pp-chipgrid{ display:grid; grid-template-columns:1fr 1fr; gap:8px; }
.pp-chip{ display:flex; flex-direction:column; gap:4px; align-items:flex-start; padding:9px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); cursor:pointer; font:inherit; text-align:left; }
@media (hover:hover){ .pp-chip:hover{ border-color:var(--accent); } }
.pp-chip-n{ font-size:var(--t-meta); color:var(--ink); font-weight:600; }
.pp-chip-g{ font-size:var(--t-eti); color:var(--muted); line-height:1.35; }

.pp-capa{ display:flex; align-items:center; gap:2px; padding:5px 6px; border:1px solid var(--hair); border-radius:var(--r); margin-bottom:6px; background:var(--paper); }
.pp-capa.on{ border-color:var(--accent); box-shadow:0 0 0 1px var(--accent) inset; }
.pp-capa.oculta .pp-capa-t{ opacity:.5; }
.pp-capa.dragging{ opacity:.4; }
.pp-capa-drag{ flex:none; cursor:grab; color:var(--muted); font-size:var(--t-meta); padding:0 3px; opacity:.6; user-select:none; }
@media (hover:hover){ .pp-capa:hover .pp-capa-drag{ opacity:1; } }
.pp-capa-t{ flex:1; min-width:0; display:flex; flex-direction:column; gap:1px; align-items:flex-start; background:none; border:0; cursor:pointer; font:inherit; text-align:left; padding:2px 4px; }
.pp-capa-n{ font-size:var(--t-meta); color:var(--ink); }
.pp-capa-h{ font-size:var(--t-eti); color:var(--muted); max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pp-ico{ width:24px; height:24px; flex:none; border:0; background:none; border-radius:var(--r); cursor:pointer; color:var(--muted); font-size:var(--t-meta); line-height:1; }
@media (hover:hover){ .pp-ico:hover:not(:disabled){ background:var(--deep); color:var(--ink); } }
.pp-ico:disabled{ opacity:.3; cursor:default; }
@media (hover:hover){ .pp-ico-del:hover{ color:var(--accent); } }
.pd-panel{ padding:10px 6px 14px 30px; margin:-4px 0 8px; }
.pp-capa[data-capa="inicio"] .pp-capa-drag{ cursor:default; opacity:.3; }
/* Mismo destello que .ge-field.ge-flash (click en el preview -> salta a su capa en
   Secciones), pero sobre .pp-capa: esa clase no es un .ge-field. */
.pp-capa.ge-flash{ box-shadow:0 0 0 2px var(--accent); border-radius:var(--r); }

.pp-token{ margin-bottom:14px; }
.pp-token-fila{ display:flex; align-items:center; gap:9px; }
.pp-token-fila input[type=color]{ width:34px; height:34px; flex:none; padding:0; border:1px solid var(--line2); border-radius:var(--r); background:none; cursor:pointer; }
.pp-token-tx{ flex:1; min-width:0; display:flex; flex-direction:column; }
.pp-token-tx b{ font-size:var(--t-meta); color:var(--ink); font-weight:600; }
.pp-token-tx span{ font-size:var(--t-eti); color:var(--muted); }
.pp-hex{ width:84px; flex:none; font-family:var(--mono); font-size:var(--t-meta); text-transform:uppercase; }
.pp-sw{ display:flex; flex-wrap:wrap; gap:5px; margin-top:7px; }
.pp-swb{ width:20px; height:20px; border-radius:var(--r); border:1px solid var(--line2); cursor:pointer; padding:0; }
.pp-swb.on{ box-shadow:0 0 0 2px var(--paper), 0 0 0 3px var(--accent); }
.pp-aviso-contraste{ font-size:var(--t-meta); line-height:1.55; color:var(--ink); background:color-mix(in oklab, var(--yellow) 16%, var(--paper)); border:1px solid color-mix(in oklab, var(--yellow) 40%, var(--paper)); border-radius:var(--r); padding:9px 11px; margin:2px 0 12px; }
/* Puede traer varios avisos (acento, texto, titulos, cuerpo): el pie "es tu
   decision" se dice UNA vez al final, no una por linea. */
.pp-aviso-contraste p{ margin:0 0 5px; }
.pp-aviso-contraste p:last-child{ margin-bottom:0; }
.pp-aviso-contraste .pp-aviso-pie{ opacity:.75; }

.pp-parejas{ display:grid; gap:6px; }
.pp-par{ display:flex; flex-direction:column; gap:1px; align-items:flex-start; padding:7px 10px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); cursor:pointer; font:inherit; color:var(--ink); text-align:left; }
@media (hover:hover){ .pp-par:hover{ border-color:var(--accent); } }
.pp-par.on{ border-color:var(--accent); box-shadow:0 0 0 1px var(--accent) inset; }

.pp-seg{ display:flex; border:1px solid var(--line2); border-radius:var(--r); overflow:hidden; }
.pp-seg button{ flex:1; padding:7px 4px; border:0; background:var(--paper); cursor:pointer; font:inherit; font-size:var(--t-meta); color:var(--muted); border-right:1px solid var(--hair); }
.pp-seg button:last-child{ border-right:0; }
@media (hover:hover){ .pp-seg button:hover{ color:var(--ink); } }
.pp-seg button.on{ background:var(--ink); color:var(--paper); }
.pp-seg-mini button{ font-size:var(--t-eti); padding:5px 3px; }

.pp-flag{ display:flex; align-items:center; justify-content:space-between; gap:10px; width:100%; padding:8px 11px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); cursor:pointer; font:inherit; font-size:var(--t-meta); color:var(--ink); margin-bottom:6px; }
.pp-flag i, .pp-toggle i{ width:30px; height:17px; border-radius:var(--r); background:var(--line2); position:relative; flex:none; transition:background .15s; }
.pp-flag i::after, .pp-toggle i::after{ content:""; position:absolute; top:2px; left:2px; width:13px; height:13px; border-radius:3px; background:var(--paper); transition:transform .15s; }
.pp-flag.on i, .pp-toggle.on i{ background:var(--accent); }
.pp-flag.on i::after, .pp-toggle.on i::after{ transform:translateX(13px); }
.pp-toggle{ border:0; background:none; padding:0; cursor:pointer; display:flex; }

.pp-canvas{ grid-area:canvas; overflow:auto; display:flex; justify-content:center; padding:22px 18px 40px; background:var(--bone); min-height:0; }
.pp-pagina{ flex:none; align-self:flex-start; height:min(100%, 1400px); min-height:560px; background:#fff; border-radius:var(--r); overflow:hidden; box-shadow:0 18px 44px -22px rgba(0,0,0,.4); border:1px solid var(--line2); transition:width .18s ease; }
.pp-pagina iframe{ width:100%; height:100%; border:0; display:block; background:#fff; }

.pp-inspector{ grid-area:insp; border-left:1px solid var(--hair); background:var(--paper); display:flex; flex-direction:column; min-height:0; overflow:hidden; }
.pp-insp-head{ display:flex; align-items:center; gap:6px; padding:10px 12px; border-bottom:1px solid var(--hair); flex:none; }
.pp-insp-t{ font-family:var(--serif); font-size:var(--t-texto); color:var(--ink); letter-spacing:-.01em }
.pp-insp-in{ flex:1; overflow-y:auto; padding:14px; min-height:0; }
.pp-insp-vis{ display:flex; align-items:center; justify-content:space-between; gap:10px; font-size:var(--t-meta); color:var(--ink); border-top:1px solid var(--hair); margin-top:16px; padding-top:12px; }
.pp-item{ display:flex; flex-direction:column; gap:6px; padding:10px; border:1px solid var(--hair); border-radius:var(--r); margin-bottom:8px; background:var(--bone); }
.pp-item.dragging{ opacity:.4; }
.pp-quitar{ align-self:flex-start; background:none; border:0; padding:0; cursor:pointer; font:inherit; font-size:var(--t-meta); color:var(--muted); text-decoration:underline; }
@media (hover:hover){ .pp-quitar:hover{ color:var(--accent); } }
.pp-anadir{ width:100%; }
.pp-vacio{ padding:34px 20px; text-align:center; color:var(--muted); }
.pp-vacio-ico{ font-size:var(--t-titulo); opacity:.4; margin-bottom:8px; }
.pp-vacio b{ font-size:var(--t-texto); color:var(--ink); }
.pp-visitas{ padding:0 16px 18px; }
.pp-kpis{ display:flex; gap:8px; }
.pp-kpis > div{ flex:1; border:1px solid var(--hair); border-radius:var(--r); padding:9px 4px; text-align:center; }
.pp-kpis b{ display:block; font-family:var(--serif); font-size:var(--t-campo); color:var(--ink); letter-spacing:-.01em }
.pp-kpis span{ font-size:var(--t-eti); color:var(--muted); }

/* Angosto: el CRM tiene nav + a veces el chat de Xarpie abierto. Container
   queries y no media queries porque lo que manda es el ancho de #view. */
@container (max-width: 1280px){
  .pp-editor{ grid-template-columns:272px 1fr 300px; }
}
@container (max-width: 1080px){
  .pp-editor{ grid-template-columns:262px 1fr; grid-template-areas:"top top" "panel canvas"; }
  .pp-inspector{ position:absolute; top:0; right:0; bottom:0; width:min(90%, 330px); z-index:6; box-shadow:-14px 0 34px -20px rgba(0,0,0,.45); transform:translateX(100%); transition:transform .2s ease; }
  .pp-editor.insp-open .pp-inspector{ transform:translateX(0); }
}
@container (max-width: 820px){
  .pp-editor{ grid-template-columns:1fr; grid-template-areas:"top" "canvas"; }
  .pp-panel{ position:absolute; top:0; left:0; bottom:0; width:min(90%, 300px); z-index:6; box-shadow:14px 0 34px -20px rgba(0,0,0,.45); transform:translateX(-100%); transition:transform .2s ease; }
  .pp-editor.panel-open .pp-panel{ transform:translateX(0); }
  .pp-canvas{ padding:14px 10px 30px; }
  .pp-pagina{ width:100% !important; }
}
.pp-drawer-t{ display:none; }
@container (max-width: 1080px){ .pp-drawer-i{ display:inline-block; } }
@container (max-width: 820px){ .pp-drawer-p{ display:inline-block; } }

/* Mockups de Mosaico, Rubor y Fuera de eje en el selector (F4) */
.gxm-mosaico{background:#f0ece4;position:relative}
.gxm-mos-grid{flex:1;display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:1fr;grid-auto-flow:dense;gap:5px;padding:8px}
.gxm-mos-w2{grid-column:span 2}
.gxm-mos-h2{grid-row:span 2}
.gxm-mos-say{grid-column:span 2;background:#191714;color:#f0ece4;display:flex;align-items:center;padding:0 10px;font-family:var(--serif);font-size:13px; letter-spacing:-.01em}
.gxm-mos-dock{position:absolute;left:50%;bottom:10px;transform:translateX(-50%);display:flex;align-items:center;gap:8px;background:#191714;color:rgba(243,239,232,.75);border-radius:var(--r);padding:5px 6px;font-size:8px;white-space:nowrap}
.gxm-mos-on{background:#f3efe8;color:#191714;border-radius:var(--r);padding:3px 8px}
.gxm-rubor{background:#f7efe9}
.gxm-rub-cover{flex:0 0 30%;align-items:center;justify-content:center;background:linear-gradient(160deg,#8a6a5f,#3c2f2a 80%)}
.gxm-rub-b{flex:1;display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px;padding:8px 10px;align-items:center}
.gxm-rub-b0{background:#f9e9e4}
.gxm-rub-b1{background:#eef0e6}
.gxm-rub-tx{display:flex;flex-direction:column;gap:4px}
.gxm-rub-e{height:3px;width:26px;border-radius:2px;background:#c0705f}
.gxm-rub-h{height:7px;width:54px;border-radius:2px;background:rgba(60,47,42,.45)}
.gxm-rub-b1 .gxm-rub-e{background:#7d8a63}
.gxm-rub-baja{margin-top:10px}
/* Sin proporcion propia las fotos del mockup colapsan a 0 de alto: la banda es un grid
   con align-items:center y .gxm-tile no trae altura por si solo (en los otros mockups la
   hereda de la fila del grid). Anchas y bajas para que QUEPAN LAS DOS BANDAS: la tarjeta
   recorta a 16/11, y con fotos verticales la segunda banda se salia -- justo la que
   demuestra que cada capitulo cambia de color. */
.gxm-rubor .gxm-tile{aspect-ratio:5/3}
.gxm-margen{background:#eceae5}
.gxm-mar-hd{display:flex;justify-content:space-between;padding:10px 12px 4px;font-size:7px;letter-spacing:.16em;text-transform:uppercase;color:#8d8a82}
.gxm-mar-grid{flex:1;display:grid;grid-template-columns:repeat(3,1fr);gap:8px;padding:4px 12px 12px;align-items:start;overflow:hidden}
.gxm-margen .gxm-tile{aspect-ratio:3/4;margin-top:var(--dy,0);transform:translateX(var(--dx,0)) rotate(var(--rot,0deg))}
:root[data-theme="dark"] .gxm-mosaico{background:#2b2925}
:root[data-theme="dark"] .gxm-rubor,:root[data-theme="dark"] .gxm-margen{background:#262624}

/* Mockups de Cinta, Vacio, Canto y Deriva en el selector (F6-T2) */
.gxm-cinta{background:#0f0f0e;color:#f0ede6}
.gxm-cin-tira{flex:0 0 26%;display:flex;gap:3px;overflow:hidden;border-bottom:1px solid rgba(240,237,230,.12)}
.gxm-cin-m{flex:0 0 15%;background:linear-gradient(150deg,#4a4238,#2b2620)}
.gxm-cin-t{font-family:var(--serif);font-size:21px;line-height:.9;padding:12px 12px 8px; letter-spacing:-.01em}
.gxm-cin-t i{font-style:italic;color:#c8814f}
.gxm-cin-grid{flex:1;display:grid;grid-template-columns:repeat(12,1fr);gap:5px;padding:0 12px 12px;align-items:start}
.gxm-cin-s5{grid-column:span 5;aspect-ratio:4/5}
.gxm-cin-s4{grid-column:span 4;aspect-ratio:3/4;margin-top:10px}
.gxm-cin-s3{grid-column:span 3;aspect-ratio:2/3}
.gxm-cinta .gxm-tile{background:linear-gradient(150deg,#4a4238,#332d26)}
.gxm-vacio{background:#fbfbf9}
.gxm-vac-cover{flex:1;position:relative}
.gxm-vac-n{position:absolute;left:14px;top:14px;font-size:9px;color:#1a1a18;display:flex;flex-direction:column;gap:3px}
.gxm-vac-n span{font-size:7px;letter-spacing:.2em;text-transform:uppercase;color:#a5a29a}
.gxm-vac-f{position:absolute;right:16%;bottom:16%;width:34%;aspect-ratio:5/6;transform:rotate(2deg)}
.gxm-vac-c{position:absolute;left:14px;bottom:12px;font-size:7px;letter-spacing:.2em;color:#c1beb6}
.gxm-canto{flex-direction:row;background:#f7f6f4}
.gxm-can-rail{flex:none;width:34px;border-right:1px solid rgba(25,25,24,.1);display:flex;align-items:flex-start;justify-content:center;padding-top:14px}
.gxm-can-rail span{writing-mode:vertical-rl;font-size:7px;letter-spacing:.26em;text-transform:uppercase;color:#191918}
.gxm-can-main{flex:1;display:flex;flex-direction:column;gap:8px;padding:14px 0 14px 12px}
.gxm-can-p0{width:64%;margin-left:auto;aspect-ratio:9/8}
.gxm-can-p1{width:32%;aspect-ratio:4/3}
.gxm-can-p2{width:44%;margin-left:auto;margin-right:14%;aspect-ratio:4/5}
.gxm-deriva{background:#f0ece9}
.gxm-der-c{flex:1;position:relative}
.gxm-der-0{position:absolute;left:0;top:28%;width:38%;aspect-ratio:16/10}
.gxm-der-1{position:absolute;right:5%;top:4%;width:31%;aspect-ratio:5/6}
.gxm-der-2{position:absolute;left:24%;bottom:6%;width:29%;aspect-ratio:8/5}
.gxm-der-3{position:absolute;right:0;bottom:0;width:21%;aspect-ratio:5/7}
.gxm-der-t{position:absolute;left:0;right:0;top:44%;text-align:center;font-family:var(--serif);font-size:13px;letter-spacing:.06em;color:#5a1a14}
:root[data-theme="dark"] .gxm-vacio{background:#262624}
:root[data-theme="dark"] .gxm-vac-n{color:#EDEBE6}
:root[data-theme="dark"] .gxm-canto,:root[data-theme="dark"] .gxm-deriva{background:#262624}
:root[data-theme="dark"] .gxm-can-rail span{color:#EDEBE6}
:root[data-theme="dark"] .gxm-der-t{color:#E0A077}

/* Anchos de la vista previa del editor de galeria (F5). Cambiar de ancho es solo una
   clase en .ge-browser: el iframe NUNCA cambia de padre, porque moverlo lo recarga. */
/* height:min(100%,780px) y no solo max-width: sin tope de alto "Movil" hereda el
   height:100% de .ge-browser de arriba, que en un canvas muy alto (el boton de pantalla
   completa de #ge-canvas, o simplemente una ventana grande) estira el telefono a esa altura
   completa en vez de quedarse del alto de uno real. Mismo bug, mismo tope (780px), que
   ".ge-embebido.ge-portal .ge-browser.ge-w-mobile" ya resolvia mas arriba SOLO para el
   portal -- generalizado aqui porque el canvas comun (galeria-diseno) resulto tener el
   mismo problema latente, expuesto por el nuevo boton de pantalla completa. */
.ge-browser.ge-w-mobile{ max-width:412px; height:min(100%,780px); background:#111; border-radius:var(--r); padding:12px; border-color:#111; }
.ge-browser.ge-w-mobile .ge-bbar{ display:none; }
.ge-browser.ge-w-mobile .ge-bbody{ border-radius:var(--r); background:#fff; }
.ge-canvastop .ge-segdark{ flex:none; }

/* Mockup de Hoja de contactos en el selector */
.gxm-contactos{background:#eeebe3}
.gxm-con-hd{display:flex;justify-content:space-between;align-items:baseline;padding:12px 12px 8px;border-bottom:1px solid rgba(25,23,20,.14);font-family:var(--serif);font-size:12px;color:#191714; letter-spacing:-.01em}
.gxm-con-mono{font-family:var(--mono,monospace);font-size:7px;letter-spacing:.06em;color:#7a736a}
.gxm-con-grid{flex:1;display:grid;grid-template-columns:repeat(3,1fr);gap:10px 8px;padding:10px 12px 12px}
.gxm-con-i{display:flex;flex-direction:column;gap:3px;min-width:0}
.gxm-con-i .gxm-tile{aspect-ratio:1/1}
.gxm-con-m{outline:2px solid #b23a2b;outline-offset:-2px}
.gxm-con-p{font-family:var(--mono,monospace);font-size:6.5px;color:#7a736a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gxm-con-pm{color:#b23a2b}
:root[data-theme="dark"] .gxm-contactos{background:#262624}
:root[data-theme="dark"] .gxm-con-hd{color:#EDEBE6}

/* Mockups de Cine y Paginas en el selector */
.gxm-cine{background:#0c0c0b}
.gxm-cine-v{flex:0 0 44%;background:#000;display:flex;align-items:center;justify-content:center}
.gxm-cine-play{width:26px;height:26px;border-radius:50%;border:1px solid rgba(240,237,230,.5);color:#f0ede6;font-size:9px;display:flex;align-items:center;justify-content:center}
.gxm-cine-t{font-family:var(--serif);font-size:17.5px;color:#f0ede6;padding:10px 12px 6px; letter-spacing:-.01em}
.gxm-cine-t i{font-style:italic;color:#c8814f}
.gxm-cine-banda{flex:1;display:flex;gap:6px;padding:0 12px 12px;overflow:hidden}
.gxm-cine-banda .gxm-tile{flex:0 0 42%;aspect-ratio:3/2;background:linear-gradient(150deg,#4a4238,#332d26)}
.gxm-paginas{background:#f4f2ed;align-items:center;justify-content:center;padding:10px 0}
.gxm-pag-t{font-family:var(--serif);font-size:16.5px;line-height:1.05;text-align:center;color:#1b1a17; letter-spacing:-.01em}
.gxm-pag-t i{font-style:italic;color:#a85d3e}
.gxm-pag-pliego{flex:1;display:grid;grid-template-columns:1fr 1fr;gap:10px;padding:10px 16px;width:100%;min-height:0}
.gxm-pag-pliego .gxm-tile{aspect-ratio:3/4}
.gxm-pag-nav{display:flex;align-items:center;gap:14px;font-size:9px;color:#8d887e;padding-bottom:4px}
.gxm-pag-c{font-family:var(--mono,monospace)}
:root[data-theme="dark"] .gxm-paginas{background:#262624}
:root[data-theme="dark"] .gxm-pag-t{color:#EDEBE6}

/* Mockups de Riel, Pila e Indice en el selector */
.gxm-riel{flex-direction:row;background:#100f0d}
.gxm-riel-idx{flex:none;width:44%;display:flex;flex-direction:column;gap:8px;padding:14px 10px;border-right:1px solid rgba(243,239,232,.1);font-size:8px;color:rgba(243,239,232,.45)}
.gxm-riel-idx .on{color:#f3efe8}
.gxm-riel-idx i{font-style:normal;font-family:var(--mono,monospace);color:#c8814f;margin-right:5px}
.gxm-riel-main{flex:1;display:flex;flex-direction:column;padding:14px 0 14px 10px;min-width:0}
.gxm-riel-cn{font-family:var(--serif);font-size:13px;color:#f3efe8;margin-bottom:8px; letter-spacing:-.01em}
.gxm-riel-pista{flex:1;display:flex;gap:8px;overflow:hidden;min-height:0}
.gxm-riel-pista .gxm-tile{flex:0 0 72%;background:linear-gradient(150deg,#4a4238,#2b2620)}
.gxm-pila{background:#191714;justify-content:center;padding:14px 0}
.gxm-pila-mesa{flex:1;position:relative;display:flex;align-items:center;justify-content:center;min-height:0}
.gxm-pila-c{position:absolute;width:44%;aspect-ratio:4/5;background:linear-gradient(150deg,#4a4238,#2b2620);
  transform:rotate(calc(var(--d) * 1.6deg)) scale(calc(1 - var(--d) * .045)) translateY(calc(var(--d) * 6px));
  z-index:calc(10 - var(--d));opacity:calc(1 - var(--d) * .12);box-shadow:0 14px 30px -14px rgba(0,0,0,.8)}
.gxm-pila-tira{display:flex;gap:5px;justify-content:center;padding:10px 0 0}
.gxm-pila-tira span{width:16px;height:20px;background:#3b342c;opacity:.5}
.gxm-pila-tira .on{opacity:1;outline:1px solid #c8814f}
.gxm-indice{background:#fcfcfb;position:relative}
.gxm-idx-hd{padding:12px 14px 0;font-size:6.5px;letter-spacing:.2em;text-transform:uppercase;color:#a3a19b}
.gxm-idx-l{padding:10px 14px;display:flex;flex-direction:column;max-width:64%}
.gxm-idx-f{display:flex;align-items:center;gap:8px;padding:6px 0;border-bottom:1px solid rgba(27,27,25,.08);font-size:9px;color:#1b1b19}
.gxm-idx-f i{font-style:normal;font-family:var(--mono,monospace);font-size:6.5px;color:#b0aea8}
.gxm-idx-f.on span{font-weight:600}
.gxm-idx-peek{position:absolute;right:10px;top:50%;transform:translateY(-50%);width:28%;aspect-ratio:4/5}
:root[data-theme="dark"] .gxm-indice{background:#262624}
:root[data-theme="dark"] .gxm-idx-f{color:#EDEBE6}

/* --- Tarjetas del selector de PORTADA (.gxp) ---------------------------------------
   Es el mismo mockup de la plantilla, pero solo su primera pantalla: sin la reticula
   debajo, el bloque de portada tiene que llenar la tarjeta en vez de quedarse con el
   62% que le toca cuando abajo va todo lo demas. La regla lleva .gxp.gxm (dos clases)
   a proposito: los flex-basis de cada tema son `.gxm-revista .gxm-cover`, de la misma
   especificidad, y necesitamos ganarles por orden en la hoja. */
.gxp.gxm>*{flex:1 1 auto;min-height:0}
.gxp.gxm>.gxp-banda{flex:0 0 30%}
.gxp.gxm>.gxp-fina{flex:0 0 16%}
.gxp-claro{background:#faf9f6;color:#191714;display:flex;flex-direction:column;justify-content:center;gap:5px}
.gxp-oscuro{background:#1d1a16;color:#f3efe8;display:flex;flex-direction:column;justify-content:center;gap:5px}
.gxp-pad{padding:0 16px}
.gxp-centro{align-items:center;text-align:center}
.gxp-abajo{flex-direction:column;align-items:flex-start;justify-content:flex-end;padding:0 16px 16px}
.gxp-tinta{color:#191714}
.gxp-sub{font-size:8px;letter-spacing:.16em;text-transform:uppercase;color:#a5a29a}
.gxp-alto{letter-spacing:.22em}
.gxp-gigante{font-size:clamp(22px,3.4vw,34px);letter-spacing:-.01em}
.gxp-hdrow{flex-direction:row;align-items:center;justify-content:space-between;gap:10px;font-size:7.5px;letter-spacing:.18em;text-transform:uppercase;color:#8d8a82}
.gxp-mid{font-family:var(--serif);font-size:13px;letter-spacing:0;text-transform:none}
.gxp-fila{display:flex;flex-direction:row}
.gxp-flex1{flex:1}
/* El cover de un tema con foto propia (revista, rubor) ya trae su degradado; el nuestro
   solo necesita que el texto quede legible cuando pintarFotosMock le mete la foto. */
.gxp .gxm-cover{background-size:cover;background-position:center}
:root[data-theme="dark"] .gxp-claro{background:#262624;color:#EDEBE6}
:root[data-theme="dark"] .gxp-tinta{color:#EDEBE6}

/* --- Geometrias de la portada Clasica (galeria-estilos.js: GALGEOM) ----------------
   Las 6 tarjetas que antes eran la fila "Geometria" aparte del editor (app.js), ahora
   fusionadas en este mismo selector. Namespace .gxm-geo-<id> a proposito NO reusa
   .gxm-clasico/.gxm-papel: esos envoltorios traen su propio centrado/flex-direction
   (ver .gxm-clasico .gxm-cover arriba) que pelearia por especificidad contra "Al pie"/
   "Dividida"/"Postal", que necesitan lo contrario. Self-contained, sin ese riesgo. */
.gxm-geo-full .gxm-cover{align-items:center;justify-content:center;flex-direction:column;text-align:center;background:linear-gradient(160deg,#4a4034,#1a1712 75%)}
.gxm-geo-split .gxm-cover{background:#151310}
.gxm-geo-split .gxm-foto{width:44%;flex:none;background:linear-gradient(150deg,#6b5c48,#2e2820)}
.gxm-geo-split .gxm-lado{flex:1;display:flex;flex-direction:column;justify-content:center;text-align:left;padding:0 14px}
.gxm-geo-bottom .gxm-cover{align-items:flex-start;justify-content:flex-end;flex-direction:column;text-align:left;padding:0 16px 16px;background:linear-gradient(178deg,transparent 38%,#1a1712 90%)}

/* Rejilla de fotos del inspector y del selector de foto. */
.pp-fotos{ display:grid; grid-template-columns:repeat(auto-fill, minmax(72px,1fr)); gap:7px; }
.pp-foto{ position:relative; aspect-ratio:1; border:1px solid var(--line2); border-radius:var(--r); background:var(--bone) center/cover no-repeat; cursor:pointer; padding:0; font:inherit; font-size:var(--t-sub); color:var(--muted); }
/* Miniatura de un enlace (tarjeta): mas chica que un hueco de galeria y con
   ancho fijo — vive en una fila junto a los inputs, no en la rejilla de fotos. */
.pp-foto-mini{ width:52px; height:52px; flex:none; aspect-ratio:auto; }
@media (hover:hover){ .pp-foto:hover{ border-color:var(--accent); } }
.pp-foto.vacia{ border-style:dashed; }
.pp-foto.redonda{ border-radius:var(--r); max-width:84px; }
.pp-fmarca{ position:absolute; left:4px; bottom:4px; padding:1px 5px; border-radius:var(--r); background:rgba(0,0,0,.62); color:#fff; font-size:8.5px; letter-spacing:.06em; text-transform:uppercase; }

/* Muestrarios reales en el selector de disenos (public/muestrarios.json) */
/* Cuando un bloque del mockup recibe su foto, se le quita el degradado gris de relleno:
   si no, el gradiente se veria ENCIMA de la imagen (background-image no lo reemplaza). */
.gxm-conf{ background-color:transparent !important; background-image:none; }
.gxm-conf::after{ content:none; }
.gx-card{ position:relative; }
/* El enlace al demo aparece sobre el mockup al acercarse a la tarjeta. En tactil, donde
   no hay hover, se queda visible: si dependiera del cursor no habria forma de abrirlo. */
.gx-demo{ position:absolute; right:12px; top:12px; z-index:2; font-size:var(--t-meta); font-weight:600;
  background:rgba(20,18,16,.82); color:#fff; padding:7px 12px; border-radius:var(--r); text-decoration:none;
  backdrop-filter:blur(6px); opacity:0; transform:translateY(-4px); transition:opacity .18s, transform .18s; }
.gx-card:focus-within .gx-demo{ opacity:1; transform:none; }
@media (hover:hover){ .gx-card:hover .gx-demo{ opacity:1; transform:none; } }
@media (hover:hover){ .gx-demo:hover{ background:#141210; } }
@media (hover: none){ .gx-demo{ opacity:1; transform:none; } }
/* De quien son las fotos de esta tarjeta: es trabajo real del estudio, no un banco de
   imagenes, y decirlo es parte de lo que hace creible el muestrario. */
.gx-cardm{ font-size:var(--t-meta); letter-spacing:.06em; text-transform:uppercase; color:var(--muted); margin-top:6px; }

/* ===== FLUJOS: el metodo de trabajo del estudio (public/app.js, vistas.flujos) =====
   Dos pantallas dentro de la misma vista: la LISTA (compositor en lenguaje natural +
   tarjetas) y el EDITOR (.fed) a pagina completa.

   El editor se ancla al area de contenido igual que .ced y .geditor.ge-embebido, y por la
   MISMA razon: position:fixed tapaba la nav y el chat de Xarpie. Ver la regla
   #view:has(.fed) al final de este bloque. */

/* ---- Lista ---- */
.fl-intro{ margin:-10px 0 22px; max-width:64ch; }
.fl-grid{ display:grid; grid-template-columns:repeat(auto-fill,minmax(276px,1fr)); gap:14px; }
.fl-seccion-t{ font-size:var(--t-eti); letter-spacing:.18em; text-transform:uppercase; color:var(--muted); font-weight:600; margin:30px 0 12px; }
.fl-seccion-t2{ margin-top:38px; }

/* El compositor. Es lo primero de la pantalla a proposito: el camino real a un flujo de
   12 pasos es describirlo, no teclear 12 formularios -- y si el boton de "a mano" fuera
   lo mas visible, todo el mundo empezaria por el camino largo. */
.fl-pedir{ border:1px solid var(--hair); border-radius:var(--r); background:linear-gradient(180deg,var(--paper),var(--deep)); padding:18px 18px 15px; }
.fl-pedir-h{ display:flex; gap:11px; align-items:flex-start; margin-bottom:12px; color:var(--accent); }
.fl-pedir-t{ font-family:var(--serif); font-size:var(--t-sub); font-weight:400; color:var(--ink); line-height:1.15; letter-spacing:-.01em }
.fl-pedir-s{ font-size:var(--t-meta); color:var(--muted); margin-top:3px; }
.fl-pedir-ta{ width:100%; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); padding:11px 13px; font-size:var(--t-texto); line-height:1.5; resize:vertical; outline:none; }
.fl-pedir-ta:focus{ border-color:var(--accent); }
.fl-ejemplos{ display:flex; flex-wrap:wrap; gap:7px; margin-top:10px; }
.fl-ej{ border:1px dashed var(--line2); background:transparent; color:var(--muted); border-radius:var(--r); padding:5px 12px; font:inherit; font-size:var(--t-meta); cursor:pointer; text-align:left; transition:.14s; }
@media (hover:hover){ .fl-ej:hover{ border-style:solid; border-color:var(--accent); color:var(--ink); } }
.fl-pedir-f{ display:flex; align-items:center; gap:12px; margin-top:13px; flex-wrap:wrap; }
.fl-pedir-nota{ font-size:var(--t-meta); color:var(--muted); flex:1; min-width:180px; }
#fl-disenar{ display:inline-flex; align-items:center; gap:7px; }

.fl-card{ border:1px solid var(--hair); border-radius:var(--r); background:var(--paper); padding:15px 15px 13px; display:flex; flex-direction:column; gap:10px; }
.fl-card.on{ border-color:var(--accent); box-shadow:0 0 0 1px var(--accent) inset; }
.fl-card-h{ display:flex; align-items:flex-start; gap:8px; }
.fl-card-n{ font-family:var(--serif); font-size:var(--t-sub); font-weight:400; line-height:1.1; letter-spacing:-.01em }
.fl-card-m{ font-size:var(--t-meta); color:var(--muted); margin-top:3px; }
.fl-card-auto{ color:var(--accent); font-weight:600; }
.fl-card-f{ display:flex; gap:8px; margin-top:auto; }
.fl-vacio{ grid-column:1/-1; display:flex; flex-direction:column; gap:5px; }

/* Interruptor de "aplicarse sola". Es la promesa central de la pantalla, asi que se ve
   como un control y no como una casilla escondida en un menu. */
.fl-auto{ display:flex; align-items:center; gap:9px; width:100%; padding:8px 11px; border:1px solid var(--line2); border-radius:var(--r); background:transparent; cursor:pointer; font:inherit; font-size:var(--t-meta); color:var(--muted); text-align:left; transition:.14s; }
@media (hover:hover){ .fl-auto:hover{ border-color:var(--accent); } }
.fl-auto.on{ border-color:var(--accent); color:var(--ink); background:color-mix(in srgb, var(--accent) 8%, transparent); }
.fl-auto i{ width:30px; height:17px; border-radius:var(--r); background:var(--line2); position:relative; flex:none; transition:background .15s; }
.fl-auto i::after{ content:""; position:absolute; top:2px; left:2px; width:13px; height:13px; border-radius:3px; background:var(--paper); transition:transform .15s; }
.fl-auto.on i{ background:var(--accent); }
.fl-auto.on i::after{ transform:translateX(13px); }

.fl-receta{ border:1px dashed var(--line2); border-radius:var(--r); background:transparent; padding:15px; text-align:left; font:inherit; color:inherit; display:flex; flex-direction:column; gap:8px; transition:.14s; }
/* Biblioteca de Recetas de Xarpen (3b): tarjetas con dos botones (usar / importar), un
   subtitulo, y el pill-boton "Hay version nueva" en las tarjetas del catalogo propio. */
.fl-bib-sub{ font-size:var(--t-texto); margin:-6px 0 12px; }
.fl-receta .fl-card-f{ margin-top:auto; }
.fl-pill-btn{ cursor:pointer; border:1px solid var(--accent); color:var(--accent); background:transparent; font:inherit; font-size:var(--t-meta); }
@media (hover:hover){ .fl-pill-btn:hover{ background:var(--accent); color:var(--bg); } }
/* La receta que aprende (3c): banda en la tarjeta y hoja de propuestas. */
.fl-prop-banda{ display:flex; align-items:center; gap:6px; width:100%; text-align:left; font:inherit; font-size:var(--t-meta); padding:7px 10px; border:1px solid var(--accent); border-radius:var(--r); background:transparent; color:var(--accent); cursor:pointer; }
@media (hover:hover){ .fl-prop-banda:hover{ background:var(--accent); color:var(--bg); } }
.fl-prop{ padding:12px 0; border-top:1px solid var(--line2); }
.fl-prop-t{ font-weight:600; }
.fl-prop-ev{ font-size:var(--t-meta); margin-top:3px; }
.fl-prop-instr{ font-size:var(--t-texto); margin-top:6px; padding:8px 10px; border-radius:var(--r); background:var(--paper); }
@media (hover:hover){ .fl-receta:hover{ border-style:solid; border-color:var(--accent); background:var(--paper); } }
.fl-receta-n{ font-family:var(--serif); font-size:var(--t-campo); font-weight:400; line-height:1.1; letter-spacing:-.01em }
.fl-receta-d{ font-size:var(--t-meta); color:var(--muted); }
.fl-receta-u{ font-size:var(--t-meta); color:var(--accent); font-weight:600; margin-top:auto; }

/* ---- El diagrama (SVG) ----
   Los colores van por clase y no en atributos fill/stroke del SVG: asi el tema oscuro se
   resuelve solo con las mismas variables que el resto de la app. */
.fl-diag-scroll{ overflow-x:auto; overflow-y:hidden; padding:2px 0 4px; }
.fl-diag{ display:block; min-width:100%; }
.fl-diag-vacio{ padding:26px 0; text-align:center; color:var(--muted); font-size:var(--t-texto); }
.fl-eje{ stroke:var(--line2); stroke-width:2; }
.fl-rama{ stroke:var(--line2); stroke-width:1.6; fill:none; stroke-dasharray:4 4; }
.fl-rama-arranque{ stroke-dasharray:none; }
.fl-col-lbl{ fill:var(--muted); font-size:var(--t-eti); font-family:var(--sans); letter-spacing:.14em; text-transform:uppercase; font-weight:600; }
/* La condicion de una rama va en caja baja: en mayusculas con letter-spacing ocupaba casi
   el doble de ancho y se encimaba con el titulo del primer paso de esa rama. */
.fl-rama-lbl{ fill:var(--accent); font-size:var(--t-eti); font-family:var(--sans); font-weight:600; }
.fl-boda{ stroke:var(--accent); stroke-width:1.4; stroke-dasharray:3 3; opacity:.6; }
.fl-boda-lbl{ fill:var(--accent); font-size:var(--t-eti); font-family:var(--sans); letter-spacing:.16em; text-transform:uppercase; font-weight:700; }
/* Marcador de HOY: exclusivo del mapa de la boda (marco.hoyDia), una receta de
   Automatizaciones no tiene un "hoy" contra el cual medirse. Punteado mas discreto que
   .fl-boda -- son dos lineas de referencia y "el evento" es la que manda. */
.fl-hoy{ stroke:var(--accent); stroke-width:1.4; stroke-dasharray:2 3; }
.fl-hoy-lbl{ fill:var(--accent); font-size:var(--t-eti); font-family:var(--sans); letter-spacing:.1em; text-transform:uppercase; font-weight:700; }
.fl-dia{ fill:var(--muted); font-size:var(--t-eti); font-family:var(--sans); font-variant-numeric:tabular-nums; }
.fl-lbl{ fill:var(--ink); font-size:var(--t-eti); font-family:var(--sans); }
.fl-pt-tarea{ fill:var(--paper); stroke:var(--ink); stroke-width:2; }
.fl-pt-msj{ fill:var(--accent); stroke:none; }
.fl-pt-msj-ojo{ fill:var(--paper); stroke:none; }
/* Cobro: tercer tipo de nodo, solo lo produce el mapa de la boda (tareas tipo='cobro').
   Trazo de acento hueco -- ni el relleno solido de un mensaje ni el hueco neutro de una
   tarea, para que se reconozca sin leer la etiqueta. */
.fl-pt-cobro{ fill:var(--paper); stroke:var(--accent); stroke-width:2; }
.fl-nodo{ cursor:pointer; }
@media (hover:hover){ .fl-nodo:hover .fl-lbl{ fill:var(--accent); } }
.fl-nodo-halo{ fill:none; stroke:var(--accent); stroke-width:1.5; opacity:.5; }
.fl-chispa{ display:block; }

.fl-leyenda{ display:flex; gap:14px; font-size:var(--t-meta); color:var(--muted); }
.fl-leyenda span{ display:inline-flex; align-items:center; gap:6px; }
.fl-leyenda i{ width:10px; height:10px; border-radius:100px; flex:none; }
.fl-lg-tarea{ background:var(--paper); border:2px solid var(--ink); }
.fl-lg-msj{ background:var(--accent); }

/* ---- El editor a pagina completa ---- */
.fed{ height:100%; display:flex; flex-direction:column; background:var(--bone); min-height:0; }
.fed-top{ display:flex; align-items:center; gap:14px; padding:16px 26px; border-bottom:1px solid var(--hair); background:var(--paper); flex:none; flex-wrap:wrap; }
.fed-back{ width:36px; height:36px; border-radius:100px; border:1px solid var(--line2); background:transparent; color:var(--muted); display:flex; align-items:center; justify-content:center; cursor:pointer; flex:none; transition:.14s; }
@media (hover:hover){ .fed-back:hover{ border-color:var(--accent); color:var(--accent); } }
.fed-back svg{ transform:rotate(180deg); }
.fed-ident{ flex:1; min-width:200px; }
.fed-nombre{ width:100%; border:none; background:transparent; font-family:var(--serif); font-size:var(--t-titulo); font-weight:400; color:var(--ink); padding:0; outline:none; line-height:1.1; letter-spacing:-.01em }
.fed-nombre::placeholder{ color:var(--line2); }
.fed-sub{ display:flex; align-items:center; gap:8px; margin-top:4px; font-size:var(--t-meta); color:var(--muted); }
.fed-acciones{ display:flex; gap:9px; flex:none; }
.fed-body{ flex:1 1 auto; min-height:0; overflow-y:auto; padding:22px 26px 60px; }
.fed-pasos-caja{ max-width:1080px; }
/* El diagrama quiere TODO el ancho que pueda: con el eje real, 1080 obligaba a hacer scroll
   en flujos que caben. El formulario de pasos se queda en 1080 -- a 1400 seria peor de leer. */
.fed-diag-caja{ max-width:1400px; }
.fed-pasos-caja{ margin-top:26px; }
.fed-diag-h{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:10px; flex-wrap:wrap; }
.fed-h-t{ font-size:var(--t-eti); letter-spacing:.18em; text-transform:uppercase; color:var(--muted); font-weight:600; }
.fed-nota{ display:flex; gap:9px; align-items:flex-start; max-width:1080px; margin-bottom:20px; padding:11px 14px; border:1px solid var(--line2); border-left:3px solid var(--accent); border-radius:var(--r); background:var(--paper); font-size:var(--t-texto); color:var(--muted); }
.fed-nota svg{ color:var(--accent); flex:none; margin-top:1px; }
/* Lo que el sanitizador le recorto a la propuesta de Xarpie: misma tarjeta que la nota,
   en ambar (por token: paridad-flujo-editor vigila colores literales en el editor). */
.fed-avisos{ border-left-color:var(--yellow); }
.fed-avisos svg{ color:var(--yellow); }
/* Refinar la receta conversando (3a): un compositor corto bajo la nota, y los pasos que
   el ultimo refinamiento toco se resaltan por tipo de cambio (una clase por tipo de
   diffPasosFlujo, atado por paridad-flujos). */
.fed-refinar{ max-width:1080px; margin:0 0 20px; padding:12px 14px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); }
.fed-refinar-fila{ display:flex; gap:8px; align-items:flex-end; }
.fed-refinar textarea{ flex:1; min-height:38px; max-height:120px; resize:vertical; font:inherit; font-size:var(--t-texto); padding:8px 10px; border:1px solid var(--line2); border-radius:var(--r); background:var(--bg); color:var(--fg); }
.fed-refinar-pie{ display:flex; gap:10px; align-items:center; margin-top:6px; font-size:var(--t-meta); color:var(--muted); }
.fed-refinar-cambios{ margin:8px 0 0; padding-left:18px; font-size:var(--t-texto); color:var(--fg); }
.fed-refinar-cambios li{ margin:2px 0; }
.fed-refinar[data-apagado] textarea{ opacity:.55; }
.fed-paso--nuevo{ box-shadow:inset 3px 0 0 var(--green); }
.fed-paso--movido{ box-shadow:inset 3px 0 0 var(--yellow); }
.fed-paso--editado{ box-shadow:inset 3px 0 0 var(--accent); }
.fed-paso--quitado{ opacity:.5; text-decoration:line-through; }
.fed-paso-antes{ font-size:var(--t-meta); color:var(--muted); margin:2px 0 0 34px; }
.fed-avisos ul{ margin:4px 0 0; padding-left:18px; }
.fed-avisos li{ margin:2px 0; }
/* Plan sin Xarpie: el compositor se ve, pero apagado y con el porque encima. */
.fl-pedir-aviso{ margin:0 0 10px; padding:9px 12px; border-radius:var(--r); background:var(--tint); color:var(--ink); font-size:var(--t-texto); }
.fl-pedir-sin-ia .fl-pedir-ta, .fl-pedir-sin-ia .fl-ej{ opacity:.55; }
/* Ensayo antes de aplicar una receta (flAplicarConEnsayo): una fila por paso, fecha a la
   izquierda; las que no se crearian van atenuadas con su razon en vez de la fecha. */
.fl-ens{ display:flex; flex-direction:column; max-height:min(52vh, 460px); overflow-y:auto; border:1px solid var(--hair); border-radius:var(--r); }
.fl-ens-fila{ display:grid; grid-template-columns:96px 1fr auto; gap:10px; align-items:baseline; padding:8px 12px; border-bottom:1px solid var(--hair); font-size:var(--t-texto); }
.fl-ens-fila:last-child{ border-bottom:0; }
.fl-ens-fecha{ font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.02em; color:var(--muted); white-space:nowrap; }
.fl-ens-tit{ color:var(--ink); min-width:0; }
.fl-ens-meta{ display:inline-flex; align-items:center; gap:4px; font-size:var(--t-meta); color:var(--muted); white-space:nowrap; }
.fl-ens-meta svg{ color:var(--accent); }
.fl-ens-no{ opacity:.6; }
.fl-ens-no .fl-ens-tit{ text-decoration:line-through; }
.fl-ens-no .fl-ens-meta{ white-space:normal; text-align:right; max-width:220px; }
/* Que paso con el correo de un paso automatico (lista de pasos de la ficha de la boda). */
.evtl-auto{ display:inline-flex; align-items:center; gap:5px; margin-top:3px; font-size:var(--t-meta); color:var(--muted); }
.evtl-auto svg{ color:var(--accent); flex:none; }
/* Bitacora del mes en la tarjeta de la receta. */
.fl-card-bit{ margin:8px 0 2px; font-family:var(--mono); font-size:var(--t-meta); letter-spacing:.02em; color:var(--muted); line-height:1.5; }
.fed-redactar{ width:64px; padding:6px 8px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); font:inherit; font-size:var(--t-texto); }
.fed-pie{ max-width:1080px; font-size:var(--t-meta); margin-top:22px; }

/* Un paso. La primera linea se lee como una frase ("14 dias antes de la boda · Xarpie
   escribe"), que es lo que reemplazo a la reja de 6 controles del editor viejo: ahi el
   fotografo tenia que entender "offset en dias con signo" antes del primer renglon. */
.fed-paso{ border:1px solid var(--hair); border-radius:var(--r); background:var(--paper); padding:13px 14px; margin-bottom:11px; transition:border-color .14s, box-shadow .14s; }
.fed-paso.sel{ border-color:var(--accent); box-shadow:0 0 0 1px var(--accent) inset; }
.fed-paso.msj{ border-left:3px solid var(--accent); }
.fed-paso.destello{ animation:pop .5s ease; }
.fed-paso-barra{ display:flex; align-items:center; gap:9px; flex-wrap:wrap; margin-bottom:9px; }
.fed-paso-n{ width:21px; height:21px; border-radius:100px; background:var(--deep); color:var(--muted); font-size:var(--t-meta); font-weight:700; display:flex; align-items:center; justify-content:center; flex:none; font-variant-numeric:tabular-nums; }
.fed-frase{ display:flex; align-items:center; gap:6px; }
.fed-frase-t{ font-size:var(--t-meta); color:var(--muted); white-space:nowrap; }
.fed-sel-min{ border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); font:inherit; font-size:var(--t-meta); padding:5px 8px; outline:none; cursor:pointer; max-width:100%; }
.fed-sel-min:focus{ border-color:var(--accent); }
.fed-dias{ width:58px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); font:inherit; font-size:var(--t-meta); padding:5px 8px; outline:none; font-variant-numeric:tabular-nums; }
.fed-dias:focus{ border-color:var(--accent); }

/* Segmentado de 2 opciones en vez de un <select>: quien hace el paso es LA decision del
   editor, y un desplegable la esconde detras de un clic. */
.fed-seg{ display:flex; border:1px solid var(--line2); border-radius:var(--r); overflow:hidden; margin-left:auto; }
.fed-seg-b{ display:inline-flex; align-items:center; gap:6px; border:none; background:transparent; color:var(--muted); font:inherit; font-size:var(--t-meta); padding:5px 12px; cursor:pointer; white-space:nowrap; transition:.14s; }
@media (hover:hover){ .fed-seg-b:hover{ color:var(--ink); } }
.fed-seg-b.on{ background:var(--accent-solido); color:var(--accent-tinta); font-weight:600; }
.fed-seg-b:disabled{ cursor:default; }
.fed-quitar{ width:26px; height:26px; border-radius:100px; border:1px solid transparent; background:transparent; color:var(--muted); display:flex; align-items:center; justify-content:center; cursor:pointer; flex:none; transition:.14s; }
@media (hover:hover){ .fed-quitar:hover{ border-color:var(--red); color:var(--red); } }

.fed-titulo{ width:100%; border:1px solid transparent; border-radius:var(--r); background:transparent; color:var(--ink); font:inherit; font-size:var(--t-texto); font-weight:500; padding:6px 8px; margin-left:-8px; outline:none; }
@media (hover:hover){ .fed-titulo:hover{ border-color:var(--line2); } }
.fed-titulo:focus{ border-color:var(--accent); background:var(--bone); }
.fed-titulo::placeholder{ color:var(--muted); font-weight:400; }
.fed-instr{ margin-top:9px; padding:10px 12px; border-radius:var(--r); background:var(--deep); }
.fed-lbl{ display:block; font-size:var(--t-eti); letter-spacing:.12em; text-transform:uppercase; color:var(--muted); font-weight:600; margin-bottom:6px; }
.fed-ta{ width:100%; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); font:inherit; font-size:var(--t-texto); line-height:1.5; padding:8px 10px; resize:vertical; outline:none; }
.fed-ta:focus{ border-color:var(--accent); }
.fed-hint{ font-size:var(--t-meta); color:var(--muted); margin-top:6px; }
.fed-hint-full{ grid-column:1/-1; margin-top:0; }
.fed-paso-pie{ display:flex; align-items:center; gap:9px; margin-top:10px; }
.fed-paso-pie .f1{ flex:1; min-width:0; }
.fed-mas{ border:none; background:transparent; color:var(--muted); font:inherit; font-size:var(--t-meta); cursor:pointer; text-decoration:underline; text-underline-offset:3px; flex:none; }
@media (hover:hover){ .fed-mas:hover{ color:var(--accent); } }
.fed-avanzado{ display:grid; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); gap:10px; margin-top:11px; padding-top:11px; border-top:1px solid var(--hair); }
.fed-campo{ display:flex; flex-direction:column; gap:5px; font-size:var(--t-meta); letter-spacing:.1em; text-transform:uppercase; color:var(--muted); font-weight:600; }

@media (max-width:720px){
  .fed-top{ padding:13px 16px; }
  .fed-body{ padding:16px 16px 50px; }
  .fed-seg{ margin-left:0; }
}

/* Mismo ancla que .ced: el editor ocupa el area de contenido entera, sin position:fixed,
   para no taparle la nav ni el chat al usuario. #/flujos en modo editor nunca convive con
   otro contenido en #view, asi que :has() basta sin clase modificadora. */
.main > #view:has(.fed){ max-width:none; padding:0; overflow:hidden; display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.main:has(#view:has(.fed)){ overflow:hidden; }
/* Aviso dentro de un paso: hoy solo lo dispara una condicion de PROGRESO (ver el grupo
   "estado" en BANDERAS_FLUJO). Se pinta pegado al desplegable que lo causa y no como un
   toast al guardar, porque el error no se nota al guardar -- se nota meses despues,
   cuando el flujo produce menos tareas de las que se ven en pantalla. */
.fed-aviso{ display:flex; gap:8px; align-items:flex-start; margin-top:9px; padding:9px 11px; border-radius:var(--r); background:color-mix(in srgb, var(--yellow) 13%, transparent); color:var(--ink); font-size:var(--t-meta); line-height:1.45; }
.fed-aviso svg{ color:var(--yellow); flex:none; margin-top:1px; }

/* ---- "¿Como funciona?": el ciclo de vida de una automatizacion ----
   Desplegado la primera vez y cuando no hay ninguna (ahi enseñar ES el trabajo de la
   pantalla vacia), plegado despues. Tono de nota al margen, no de alerta: explica algo
   que funciona bien, no avisa de un problema. */
.fl-como{ border:1px solid var(--hair); border-radius:var(--r); background:var(--paper); margin:16px 0 4px; overflow:hidden; }
.fl-como-h{ display:flex; align-items:center; gap:9px; width:100%; padding:12px 15px; border:none; background:transparent; color:var(--ink); font:inherit; font-size:var(--t-texto); font-weight:600; cursor:pointer; text-align:left; }
.fl-como-h svg{ color:var(--accent); flex:none; }
.fl-como-h span{ flex:1; }
.fl-como-chev{ font-style:normal; font-size:var(--t-sub); color:var(--muted); line-height:1; flex:none; }
.fl-como-body{ padding:2px 15px 15px; border-top:1px solid var(--hair); }
.fl-como-pasos{ list-style:none; margin:14px 0 0; padding:0; display:grid; gap:11px; }
.fl-como-paso{ display:flex; gap:11px; align-items:flex-start; font-size:var(--t-texto); line-height:1.5; }
/* El numero va en su propia ficha y no en el texto: es lo que deja leer los 4 pasos como
   una secuencia de un vistazo, sin tener que leerlos. */
.fl-como-n{ width:21px; height:21px; border-radius:100px; background:var(--deep); color:var(--accent); font-size:var(--t-meta); font-weight:700; display:flex; align-items:center; justify-content:center; flex:none; margin-top:1px; }
.fl-como-paso b{ font-weight:600; }
.fl-como-paso span{ color:var(--muted); }
.fl-como-aut{ margin-top:15px; padding:12px 13px; border-radius:var(--r); background:var(--deep); }
.fl-como-aut-t{ font-size:var(--t-eti); letter-spacing:.13em; text-transform:uppercase; color:var(--muted); font-weight:600; margin-bottom:9px; }
.fl-como-aut ul{ list-style:none; margin:0; padding:0; display:grid; gap:6px; }
.fl-como-aut li{ display:flex; gap:10px; align-items:baseline; font-size:var(--t-meta); }
.fl-como-aut li span{ flex:1; min-width:0; }
/* Verde = espera tu visto bueno; acento = sale sin preguntar. El color es la respuesta a
   "¿esto se manda solo?", que es la unica pregunta que da miedo de esta pantalla. */
.fl-como-aut li b.ok{ color:var(--blue); font-weight:600; white-space:nowrap; }
.fl-como-aut li b.solo{ color:var(--accent); font-weight:600; white-space:nowrap; }
.fl-como-aut-pie{ font-size:var(--t-meta); color:var(--muted); margin-top:9px; line-height:1.45; }
.fl-como-parar{ margin-top:14px; font-size:var(--t-meta); color:var(--muted); line-height:1.5; }
.fl-como-parar b{ color:var(--ink); }
.fl-auto-pie{ font-size:var(--t-meta); color:var(--muted); line-height:1.4; margin:-4px 0 2px; }
.fed-diag-pie{ font-size:var(--t-meta); color:var(--muted); line-height:1.5; margin:10px 0 0; max-width:76ch; }

/* ---- Eje de tiempo del diagrama de automatizaciones (Fase 1) ----
   La rejilla NO es decorativa: sin ella un eje lineal no comunica que un hueco es el doble
   de otro, y el dibujo se lee igual que la escala deformada que habia antes. Todo por
   clase y con variables, nunca atributos fill/stroke literales: el SVG vive en una app con
   tema claro y oscuro, y un color literal se ve bien en uno y desaparece en el otro. */
.fl-rejilla{ stroke:var(--hair); stroke-width:1; }
.fl-rejilla-cero{ stroke:transparent; }   /* el dia 0 ya lo marca .fl-boda, en acento */
.fl-eje-linea{ stroke:var(--line2); stroke-width:1.5; }
.fl-tick{ stroke:var(--line2); stroke-width:1.5; }
.fl-tick-men{ stroke:var(--hair); stroke-width:1; }
.fl-tick-lbl{ fill:var(--muted); font-size:var(--t-eti); font-family:var(--sans); }
.fl-tick-boda{ fill:var(--accent); font-weight:700; letter-spacing:.04em; }
/* Segundo renglon del eje: solo aparece con marco.fecha0 (el mapa de la boda), cuando la
   etiqueta principal pasa a ser la fecha real y el "2 meses antes" de siempre baja aqui,
   mas chico -- se pierde jerarquia, no informacion. */
.fl-tick-rel{ fill:var(--muted); font-size:var(--t-eti); font-family:var(--sans); opacity:.75; }
/* Sub-rotulo de la columna de arranque: dice de donde se cuentan SUS dias, que es otro
   reloj distinto al del evento. Sin esa linea, la columna parece parte del mismo eje. */
.fl-col-sub{ fill:var(--muted); font-size:var(--t-eti); font-family:var(--sans); }
.fl-col-cuando{ fill:var(--muted); font-size:var(--t-eti); font-family:var(--sans); }
/* La hairline que separa la columna del eje: es lo que dice "aqui manda otro reloj". */
.fl-col-corte{ stroke:var(--hair); stroke-width:1; }
/* El dia exacto de cada nodo se atenua: con el eje y la rejilla abajo, diez chips "−60d"
   repetidos son ruido sobre informacion que ya esta dicha. Vuelve al pasar por encima y en
   el nodo seleccionado, que es cuando de verdad quieres el numero. En tactil no hay hover,
   pero tocar un nodo lo selecciona, asi que sigue alcanzable. */
.fl-dia{ opacity:0; transition:opacity .12s; }
.fl-nodo.sel .fl-dia{ opacity:1; }
@media (hover:hover){ .fl-nodo:hover .fl-dia{ opacity:1; } }
@media (hover:none){ .fl-dia{ opacity:.55; } }

/* ---- Barra y pestanas del editor de automatizaciones (Fase 2) ----
   Subrayado y no pastillas: `.fchips` en esta app significa "estas filtrando", y aqui no
   se filtra nada -- son dos vistas del MISMO flujo. Mismo lenguaje que las pestanas del
   editor de pagina publica. */
.fed-barra{ display:flex; align-items:center; gap:16px; flex-wrap:wrap; max-width:1400px; margin-bottom:14px; border-bottom:1px solid var(--hair); }
.fed-tabs{ display:flex; gap:2px; }
.fed-tab{ border:none; background:transparent; color:var(--muted); font:inherit; font-size:var(--t-texto); font-weight:600; padding:9px 14px; cursor:pointer; border-bottom:2px solid transparent; margin-bottom:-1px; transition:.14s; }
@media (hover:hover){ .fed-tab:hover{ color:var(--ink); } }
.fed-tab.on{ color:var(--ink); border-bottom-color:var(--accent); }
.fed-barra .fl-leyenda{ margin-left:auto; }
.fed-barra-acc{ padding-bottom:6px; }
.fed-barra .fl-leyenda + .fed-barra-acc{ margin-left:0; }
.fed-barra .fl-leyenda[hidden]{ display:none; }
.fed-barra .fl-leyenda[hidden] + .fed-barra-acc{ margin-left:auto; }
@media (max-width:720px){
  .fed-barra{ gap:8px; }
  .fed-barra .fl-leyenda{ display:none; }
  .fed-barra-acc{ margin-left:auto; }
}

/* ---- El globo de configuracion de un paso (Fase 2) ----
   Hereda de .w-pop el position:fixed y la sombra; se le baja el z-index a 76 (la banda de
   .pendw-pop) y NO se deja en el 220 del .w-pop: con 220 quedaria por encima del modal de
   "cambios sin guardar" (.ov, z-78), que es exactamente al reves de lo que debe pasar. */
.flpop{ width:min(94vw, 340px); padding:0; overflow:hidden; }
.flpop.msj{ border-left:3px solid var(--accent); }
.flpop-h{ display:flex; align-items:center; gap:8px; padding:9px 10px 7px 13px; border-bottom:1px solid var(--hair); }
.flpop-n{ flex:1; font-size:var(--t-eti); letter-spacing:.13em; text-transform:uppercase; color:var(--muted); font-weight:600; }
.flpop-x{ width:24px; height:24px; border-radius:100px; border:none; background:transparent; color:var(--muted); display:flex; align-items:center; justify-content:center; cursor:pointer; flex:none; }
@media (hover:hover){ .flpop-x:hover{ color:var(--ink); background:var(--deep); } }
.flpop-b{ padding:12px 13px; max-height:min(70vh, 560px); overflow-y:auto; }
.flpop-titulo{ width:100%; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); font:inherit; font-size:var(--t-texto); font-weight:500; padding:8px 10px; outline:none; margin-bottom:12px; }
.flpop-titulo:focus{ border-color:var(--accent); }
.flpop-cuando{ display:flex; gap:7px; align-items:center; }
.flpop-cuando .fed-dias{ width:64px; flex:none; }
/* La frase en llano bajo los dos controles: es lo que hace legible el par "numero +
   desde donde", y es la unica linea que dice la respuesta completa. */
.flpop-frase{ font-size:var(--t-meta); color:var(--muted); margin:6px 0 12px; }
.flpop-seg{ width:100%; margin-bottom:12px; }
.flpop-seg .fed-seg-b{ flex:1; justify-content:center; }
.flpop .fed-lbl{ margin-top:2px; }
.flpop .fed-instr{ margin:0 0 12px; }
.flpop .fed-avanzado{ margin-top:10px; }
.flpop .fed-aviso{ margin-top:8px; }
/* El candado de cobro NO va en amarillo de aviso: no es un error del usuario, es una
   proteccion que funciona. Verde, el mismo que dice "espera tu visto bueno" en la lista. */
.flpop-candado{ display:flex; gap:8px; align-items:flex-start; margin:0 0 12px; padding:9px 11px; border-radius:var(--r); background:color-mix(in srgb, var(--blue) 13%, transparent); font-size:var(--t-meta); line-height:1.45; }
.flpop-candado svg{ color:var(--blue); flex:none; margin-top:1px; }
.flpop-f{ border-top:1px solid var(--hair); padding:7px 10px; }
.flpop-quitar{ border:none; background:transparent; color:var(--muted); font:inherit; font-size:var(--t-meta); padding:5px 8px; border-radius:var(--r); cursor:pointer; width:100%; text-align:left; }
@media (hover:hover){ .flpop-quitar:hover{ color:var(--red); background:color-mix(in srgb, var(--red) 9%, transparent); } }
/* En un telefono un globo anclado no cabe: el mismo contenido sube desde abajo como hoja,
   que es el unico patron que funciona en pantalla chica. */
@media (max-width:720px){
  .flpop{ width:100%; left:0 !important; right:0; top:auto !important; bottom:0; border-radius:var(--r) var(--r) 0 0; max-width:none; }
  .flpop-b{ max-height:70dvh; }
}

/* ---- Arrastrar un paso para cambiarle la fecha (Fase 3) ----
   touch-action:none SOLO dentro de (pointer:fine). Fuera del media query romperia el
   scroll horizontal con el dedo encima de cada nodo, que es la unica forma de leer el mapa
   en un telefono. El cursor grab es ademas la senal mas leida de "esto se mueve", y por eso
   la afordancia solo aparece donde el gesto de verdad existe. */
@media (hover:hover) and (pointer:fine){
  .fl-diag .fl-mov{ cursor:grab; touch-action:none; }
  .fl-diag.arrastrando, .fl-diag.arrastrando .fl-mov{ cursor:grabbing; }
  .fl-diag-scroll:has(.arrastrando){ user-select:none; }
}
.fl-nodo:focus{ outline:none; }
.fl-nodo:focus-visible .fl-pt-tarea, .fl-nodo:focus-visible .fl-pt-msj, .fl-nodo:focus-visible .fl-pt-cobro{ stroke:var(--accent); stroke-width:3; }
/* La huella del sitio de donde salio: sin ella no hay referencia de cuanto se movio. */
.fl-fantasma{ fill:none; stroke:var(--line2); stroke-width:2; stroke-dasharray:3 3; }
.fl-guia{ stroke:var(--accent); stroke-width:1.5; stroke-dasharray:4 4; }
.fl-marca{ fill:var(--accent); font-size:var(--t-meta); font-family:var(--sans); font-weight:600; }
.fed-cuenta{ font-size:var(--t-meta); color:var(--muted); font-variant-numeric:tabular-nums; align-self:center; }
.fed-cuenta[hidden]{ display:none; }

/* ---- Barra del mapa: cuanto se ve y con cuanto detalle ----
   Va DENTRO del panel del mapa y no en la barra de pestanas: son controles del mapa, y en
   la vista Lista no significan nada. */
.fed-mapabar{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; margin:0 0 10px; }
.fed-mapabar-l{ font-size:var(--t-meta); color:var(--muted); }
.fed-mapabar-nota{ font-size:var(--t-meta); color:var(--accent); }
.fed-mapabar-nota[hidden]{ display:none; }
.fed-zoom{ display:flex; align-items:center; gap:2px; margin-left:auto; border:1px solid var(--line2); border-radius:var(--r); padding:2px; }
.fed-zoom-b{ width:26px; height:24px; border:none; background:transparent; color:var(--ink); font:inherit; font-size:var(--t-texto); line-height:1; cursor:pointer; border-radius:var(--r); }
@media (hover:hover){ .fed-zoom-b:hover:not(:disabled){ background:var(--deep); } }
.fed-zoom-b:disabled{ color:var(--line2); cursor:default; }
.fed-zoom-n{ font-size:var(--t-meta); color:var(--muted); min-width:56px; text-align:center; }
@media (max-width:720px){ .fed-zoom{ margin-left:0; } }

/* Mockups de las 3 portadas editoriales (2026-08-20). Viven aqui y no en
   galeria-temas.css porque son las TARJETAS del selector (documento del CRM), no la
   galeria real -- por eso si pueden llevar color literal, igual que el resto de .gxm-*. */
/* "cabecera": el titulo toca los dos margenes, y la linea de datos va debajo. */
.gxm-cab{align-items:flex-start;justify-content:flex-end;flex-direction:column;text-align:left;padding:0 10px 11px;background:linear-gradient(178deg,transparent 34%,#1a1712 92%)}
.gxm-cab-t{font-size:clamp(20px,3.6vw,30px);line-height:.95;letter-spacing:-.02em;margin:0 0 9px;width:100%}
.gxm-cab-l{font-size:7px;letter-spacing:.2em;color:#cfc9be}
/* "triptico": tres columnas y el nombre acostado a la izquierda. */
.gxm-tri{flex:0 0 62%;display:flex;gap:5px;background:#faf9f6;padding:10px}
.gxm-tri-t{flex:none;writing-mode:vertical-rl;transform:rotate(180deg);font-family:var(--serif);font-size:clamp(13px,1.7vw,16px);color:#191714;line-height:1;white-space:nowrap;align-self:center; letter-spacing:-.01em}
.gxm-tri-f{flex:1;display:flex;gap:5px;min-width:0}
.gxm-tri-f .gxm-tile{flex:1;min-width:0;height:100%}
:root[data-theme="dark"] .gxm-tri{background:#262624}
:root[data-theme="dark"] .gxm-tri-t{color:#EDEBE6}
/* "franja": la banda solida cruza la foto por el medio. */
.gxm-fra{align-items:stretch;justify-content:flex-end;flex-direction:column;padding:0 0 13% 0}
.gxm-fra-b{background:#1d1a16;color:#f3efe8;padding:9px 10px;text-align:center}
.gxm-fra-t{font-size:clamp(15px,2.3vw,21px);line-height:1;margin:0}

/* Fotos de la portada (triptico = 3, collage = 4). Los huecos se pintan del tamano de la
   fila del riel, no como miniaturas sueltas: el numero encima dice el ORDEN en que salen,
   que es la pregunta que un fotografo se hace al elegirlas. */
/* Los hijos van prefijados con .ge-fotosport a proposito: `.geditor button` resetea
   border y color con especificidad (0,1,1), asi que un `.ge-fp-slot` suelto (0,1,0)
   pierde y los huecos salen sin borde ni fondo. Medido en un fixture antes de subir. */

/* Encuadre por foto (modal). Las cajas van con la proporcion REAL de su hueco, que se
   mide del preview -- por eso el aspect-ratio llega inline y no hay tamano fijo aqui.
   Los hijos van prefijados por el mismo motivo que .ge-fotosport: `.geditor button`
   resetearia el borde, y este modal se abre desde dentro del editor. */
/* Clases propias y NO las del panel (.ge-fp-*): esas viven scopeadas a .ge-fotosport,
   dentro del riel, y este modal se pinta en #modal, fuera de .geditor -- reusarlas
   heredaria el color y perderia la caja. */

/* Mockups de la tanda editorial 2026-08-21 (prensa / archivo). Aqui el color literal SI
   se permite: son tarjetas del CRM, no la galeria. */
/* portada "pliego": franja de tinta + foto */
.gxm-pli{flex:0 0 62%;display:flex;background:#101014}
.gxm-pli-col{flex:0 0 36%;display:flex;flex-direction:column;justify-content:flex-end;gap:5px;padding:0 8px 10px;color:#f2f2f4}
.gxm-pli-t{font-size:clamp(11px,1.5vw,15px);line-height:1.05;margin:0}
.gxm-pli-r{display:block;height:1px;background:currentColor;opacity:.3}
.gxm-pli-f{flex:1;min-width:0;height:100%;background-size:cover;background-position:center}
/* portada "expediente": ano al margen + metadatos + foto chica */
.gxm-exp{flex:0 0 62%;position:relative;display:flex;gap:10px;align-items:center;padding:0 10px;background:#f4f4f0;overflow:hidden}
.gxm-exp-anio{position:absolute;left:-.05em;bottom:-.18em;font-family:'JetBrains Mono',monospace;font-size:clamp(46px,9vw,86px);line-height:.78;letter-spacing:-.05em;color:#0a0a0a;opacity:.08}
.gxm-exp-m{position:relative;z-index:1;flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.gxm-exp-t{font-family:'JetBrains Mono',monospace;font-size:clamp(10px,1.3vw,13px);letter-spacing:-.03em;color:#0a0a0a;margin:0}
.gxm-exp-l{display:block;height:1px;background:#0a0a0a;opacity:.16}
.gxm-exp-f{position:relative;z-index:1;flex:0 0 34%;aspect-ratio:4/5;height:auto}
/* acomodo "pliegos": ancla + dos de apoyo, con filete */
/* Mocks de la tanda editorial 2026-08-28 (verso/horizonte/titular/tablero/anuario/
   velada/cartel + sus portadas y acomodos). Mismo lenguaje de siempre: cajas grises,
   tipografia real, cero fotos (se visten con pintarFotosMock). */
.gxm-vso{columns:2;column-gap:7px;padding:8px;flex:1;min-height:0;overflow:hidden}
.gxm-vso .gxm-tile{margin:0 0 7px;break-inside:avoid;aspect-ratio:4/5}
.gxm-vso-carta{break-inside:avoid;margin:0 0 7px;background:var(--paper);border:1px solid var(--hair);padding:10px 8px;font-family:var(--serif);font-style:normal;font-size:10px;line-height:1.35; letter-spacing:-.01em}
.gxm-vso-t{font-style:normal;font-size:11px}
.gxm-hor{flex:1;min-height:0;display:flex;gap:6px;align-items:stretch;overflow:hidden;padding:8px 0 4px}
.gxm-hor-p{flex:0 0 56%;margin:0;opacity:.4}
.gxm-hor-on{opacity:1}
.gxm-hor-pie{display:flex;justify-content:space-between;font-family:'JetBrains Mono',monospace;font-size:7.5px;letter-spacing:.12em;color:var(--muted);padding:4px 8px 6px}
.gxm-titular,.gxm-anuario{display:flex;flex-direction:column}
.gxm-tit-h{font-family:var(--serif);font-weight:400;font-size:clamp(17.5px,2.2vw,26.5px);line-height:.9;letter-spacing:-.02em;padding:10px 10px 6px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.gxm-tit-linea{border-top:1px dotted var(--line2);margin:0 10px 8px}
/* Correcciones del 2026-09-22. align-items:start dejaba en ALTURA CERO a los tiles que no traen
   aspect-ratio (divs vacios: su contenido mide 0), asi que de las cuatro fotos de Anuario y
   Titular solo se veia una. Y sus cinco tracks en cuatro columnas hacen DOS filas, asi que
   grid-auto-rows:1fr en vez de dejarlas al alto del contenido: reparten el alto del cuerpo y
   lo llenan, que es lo que pide una caja alta. El aspect-ratio del tile grande queda como
   minimo y lo pisa el estirado, a proposito. */
.gxm-tit-grid{display:grid;grid-template-columns:repeat(4,1fr);grid-auto-rows:1fr;gap:6px;padding:0 10px 10px;flex:1;min-height:0;align-items:stretch}
.gxm-tit-grid .gxm-tile{margin:0}
.gxm-tit-a{grid-column:span 2;aspect-ratio:4/3}
.gxm-tit-hueco{grid-column:span 1}
.gxm-anu-g{font-family:var(--serif);font-weight:400;font-size:clamp(21px,2.6vw,31.5px);line-height:.85;letter-spacing:-.02em;text-transform:uppercase;color:#C79A4E;padding:10px 10px 8px}
.gxm-tab{position:relative;display:grid;grid-template-columns:repeat(4,1fr);gap:8px;padding:12px;flex:1;min-height:0;align-items:start;align-content:center}
.gxm-tab .gxm-tile{margin:0}
.gxm-tab-xl{grid-column:span 2;aspect-ratio:4/3;transform:rotate(-1.2deg)}
.gxm-tab-m{grid-column:span 2;aspect-ratio:3/2;transform:rotate(.8deg)}
.gxm-tab-s{aspect-ratio:4/5;transform:rotate(1deg)}
.gxm-tab-s2{aspect-ratio:1/1;transform:rotate(-.8deg)}
.gxm-tab-nota{grid-column:span 1;background:#2B2926;color:#F3F1EA;font-family:var(--serif);font-style:normal;font-size:8.5px;line-height:1.3;padding:8px 7px;transform:rotate(-1deg);align-self:center; letter-spacing:-.01em}
.gxm-velada{background:#141312;color:#F3F1EA}
.gxm-vel-c{flex:1;min-height:0;display:flex;align-items:center;padding:10px}
.gxm-vel-tarjeta{background:#FCFBF7;color:#2B2926;padding:12px 14px;max-width:70%;box-shadow:0 8px 22px rgba(0,0,0,.4)}
.gxm-vel-t{font-family:var(--serif);font-size:14px;line-height:1.1; letter-spacing:-.01em}
.gxm-vel-cap{display:flex;justify-content:center;padding:0 0 12px}
.gxm-vel-ovalo{display:inline-block;border:1px solid rgba(243,241,234,.4);border-radius:var(--r);padding:3px 12px;font-size:8px;letter-spacing:.2em}
.gxm-cartel{display:flex;flex-direction:column}
/* Mock de "Corcho": polaroids torcidas con faldon y un post-it. */
/* Mural (2026-09-04): la hoja de recortes. Cuatro piezas absolutas encimadas sobre crema
   y dos cuadritos de color; las piezas llevan .gxm-tile para que pintarFotosMock las vista. */
.gxm-mural{background:#F3EFE6;padding:8px;position:relative;display:block;flex:1;min-height:0;overflow:hidden}
.gxm-mur-p{position:absolute;margin:0;box-shadow:0 2px 6px rgba(0,0,0,.18)}
.gxm-mur-p0{left:46%;top:8%;width:32%;aspect-ratio:4/5;transform:rotate(.6deg);z-index:1}
.gxm-mur-p1{left:18%;top:22%;width:22%;aspect-ratio:3/4;transform:rotate(-1.2deg);z-index:2}
.gxm-mur-p2{left:38%;top:40%;width:24%;aspect-ratio:5/6;transform:rotate(.8deg);z-index:3}
.gxm-mur-p3{left:12%;bottom:8%;width:42%;aspect-ratio:3/2;transform:rotate(-.5deg);z-index:2}
.gxm-mur-sw{position:absolute;width:7%;aspect-ratio:1;z-index:4}
.gxm-mur-sw0{left:10%;top:14%;background:#C9825B}
.gxm-mur-sw1{right:9%;bottom:12%;background:#33413A}
.gxm-corcho{background:#EBE0CC;padding:8px;position:relative;display:block}
/* La foto se recorta al PADDING, no al borde: el borde blanco ES el marco polaroid, y sin
   esto la foto se pintaba por debajo de el y se perdia el marco. */
.gxm-cor-p{position:absolute;background:#fff;background-clip:padding-box;border:3px solid #fff;border-bottom-width:9px;box-shadow:0 3px 7px rgba(0,0,0,.28)}
.gxm-cor-p::after{content:"";position:absolute;inset:0;background:#b9a894}
/* El relleno beige es el marcador de posicion; con foto real estorba (gxm-conf lo pone
   pintarFotosMock al vestir la tarjeta). */
.gxm-cor-p.gxm-conf::after{display:none}
.gxm-cor-p0{left:6%;top:10%;width:38%;height:52%;transform:rotate(-7deg)}
.gxm-cor-p1{right:8%;top:6%;width:32%;height:44%;transform:rotate(5deg)}
.gxm-cor-p2{left:34%;bottom:6%;width:30%;height:38%;transform:rotate(3deg)}
.gxm-cor-nota{position:absolute;left:8%;bottom:10%;background:#F7EECB;color:#362A1D;font-size:8px;padding:5px 8px;transform:rotate(2deg);box-shadow:1px 3px 6px rgba(0,0,0,.2)}
/* Mock de "Revelado": la tira perforada y una copia con su borde de papel. */
.gxm-revelado{background:#1A0F0B;padding:6px;display:flex;flex-direction:column;gap:5px}
.gxm-neg-tira{background:#000;display:flex;gap:3px;padding:4px 3px;border-top:2px dotted rgba(255,255,255,.45);border-bottom:2px dotted rgba(255,255,255,.45)}
.gxm-neg-tira span{flex:1;height:14px;background:#4a4a4a;filter:grayscale(1)}
.gxm-neg-tira span.on{background:#C08B72;filter:none}
.gxm-neg-copia{flex:1;display:flex;align-items:center;justify-content:center}
.gxm-neg-copia .gxm-tile{width:70%;height:100%;background:#2b2b2b;border:3px solid #fff}
/* Mock de "Proyector": pantallas negras separadas por un intertitulo. */
.gxm-proyector{background:#08080A;padding:6px;display:flex;flex-direction:column;gap:4px}
.gxm-pry-pant{flex:1;display:flex;align-items:center;justify-content:center;min-height:22px}
.gxm-pry-pant .gxm-tile{width:62%;height:100%;background:#1d1e22}
.gxm-pry-inter{text-align:center;font-family:var(--serif);font-style:normal;color:#B8C4D6;font-size:8px;letter-spacing:.2em;padding:2px 0}
.gxm-pry-cred{font-family:var(--serif);color:#EDEDF0;font-size:clamp(11px,1.4vw,14px);text-align:center;background:#08080A;padding:8px 6px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; letter-spacing:-.01em}
/* Mock de "Gaceta" en el selector: la miniatura tiene que gritar PERIODICO a 200px de
   ancho, asi que exagera los tres dispositivos que la definen -- cabecera a lo ancho,
   filete doble y columnas con corondel. */
.gxm-gaceta{background:#F5F1E6;padding:8px;display:flex;flex-direction:column;gap:5px}
.gxm-gac-cab{font-family:var(--serif);font-weight:400;font-size:clamp(12px,1.5vw,16px);color:#1B1914;text-align:center;line-height:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis; letter-spacing:-.01em}
.gxm-gac-filete{border-top:3px double #1B1914}
/* La nota principal CRECE con la caja (flex:1.1), y las columnas de lectura de abajo se
   quedan con el resto. Antes su foto medida 34 px fijos: en la caja alta el mockup se veia
   vacio, con una foto diminuta arriba y un palmo de textura de columnas debajo. */
.gxm-gac-lede{display:grid;grid-template-columns:3fr 2fr;gap:5px;flex:1.1;min-height:0}
.gxm-gac-lede .gxm-tile{height:100%;min-height:34px}
.gxm-gac-tx{display:flex;flex-direction:column;gap:3px}
.gxm-gac-tx b{height:5px;background:#1B1914;width:80%}
.gxm-gac-tx i{height:2px;background:rgba(27,25,20,.3)}
.gxm-gac-cols{display:grid;grid-template-columns:repeat(4,1fr);gap:4px;flex:1;min-height:26px}
.gxm-gac-cols span{background:linear-gradient(rgba(27,25,20,.22) 1px,transparent 1px) 0 0/100% 4px;border-right:1px solid rgba(27,25,20,.18)}
.gxm-gac-cols span:last-child{border-right:0}
.gxm-car-banda{background:#C8102E;color:#F6F1E7;font-family:var(--serif);font-weight:400;font-size:clamp(14px,1.6vw,17.5px);letter-spacing:.02em;padding:14px 12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.gxm-rtl{display:flex;flex-direction:column;flex:1;min-height:0;padding:8px 10px 0}
.gxm-rtl-t{font-family:var(--serif);font-weight:400;font-size:clamp(16px,2vw,23px);line-height:.9;letter-spacing:-.02em}
.gxm-rtl-linea{border-top:1px dotted var(--line2);margin:6px 0}
.gxm-rtl-f{flex:1;min-height:24px;margin:0}
.gxm-flo{display:flex;align-items:center}
.gxm-flo-tar{background:var(--paper);border:1px solid var(--hair);margin-left:12px;padding:10px 12px;max-width:66%;box-shadow:0 8px 20px rgba(0,0,0,.25)}
.gxm-flo-t{font-size:13px}
.gxm-mesa{position:relative;flex:1;min-height:0;margin:8px;overflow:hidden}
.gxm-mesa .gxm-tile{position:absolute;margin:0}
.gxm-mesa-0{left:4%;top:6%;width:38%;aspect-ratio:4/5;transform:rotate(-1.2deg)}
.gxm-mesa-1{right:5%;top:2%;width:30%;aspect-ratio:1/1;transform:rotate(1.4deg)}
.gxm-mesa-2{left:30%;bottom:4%;width:32%;aspect-ratio:3/2;transform:rotate(.8deg)}
.gxm-mesa-tar{position:absolute;right:6%;top:44%;background:#2B2926;color:#F3F1EA;font-family:var(--serif);font-size:11px;padding:8px 12px;transform:rotate(-1deg); letter-spacing:-.01em}
/* Mock del acomodo "panorama": tres paginas asomando en fila con la del centro activa y
   una flecha -- el gesto de revista horizontal en miniatura. */
.gxm-pano{position:relative;flex:1;min-height:0;display:flex;align-items:stretch;gap:6px;overflow:hidden}
.gxm-pano-p{flex:0 0 58%;height:auto;margin:0;opacity:.45}
.gxm-pano-on{opacity:1}
.gxm-pano-fl{position:absolute;right:8px;bottom:6px;font-size:15px;opacity:.6}
.gxm-pgs{display:grid;grid-template-columns:1.62fr 1fr;gap:1px;background:rgba(25,23,20,.16);flex:1;min-height:0}
.gxm-pgs-inv{grid-template-columns:1fr 1.62fr}
.gxm-pgs-col{display:grid;grid-template-rows:1fr 1fr;gap:1px;min-height:0}
.gxm-pgs .gxm-tile,.gxm-pgs-col .gxm-tile{height:100%;margin:0}
/* acomodo "contacto": cuadros pegados */
.gxm-cto{display:grid;grid-template-columns:repeat(6,1fr);gap:1px;background:rgba(10,10,10,.18);flex:1;min-height:0;padding:1px}
.gxm-cto .gxm-tile{aspect-ratio:1/1;height:auto;margin:0;border-radius:0}
.gxm-prensa .gxm-pgs{margin-top:1px}
.gxm-archivo{background:#f4f4f0}
:root[data-theme="dark"] .gxm-exp{background:#232220}
:root[data-theme="dark"] .gxm-exp-anio,:root[data-theme="dark"] .gxm-exp-t{color:#EDEBE6}
:root[data-theme="dark"] .gxm-exp-l{background:#EDEBE6}
:root[data-theme="dark"] .gxm-archivo{background:#232220}

/* Mockups de la tanda editorial 2/2 (bruma / diptico). Color literal permitido: son
   tarjetas del CRM, no la galeria. */
/* "susurro": foto chica flotando, nombre chico arriba */
.gxm-sus{flex:0 0 62%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6px;background:#eef0f1;padding:0 12px}
.gxm-sus-t{font-family:var(--serif);font-size:clamp(8px,1vw,10px);letter-spacing:.16em;text-transform:uppercase;color:#14181b;text-align:center}
.gxm-sus-f{width:100%;max-width:66%;height:52%;margin:0;background-size:cover;background-position:center}
.gxm-sus-l{display:block;width:34%;height:1px;background:#14181b;opacity:.22}
/* "marco": dos copias con paspartu y cartela abajo */
.gxm-mar{flex:0 0 62%;display:flex;flex-direction:column;gap:5px;background:#0e1114;padding:8px 9px 7px}
.gxm-mar-o{flex:1;min-height:0;display:grid;grid-template-columns:1fr 1fr;gap:5px}
.gxm-mar-o .gxm-tile{height:100%;margin:0}
.gxm-mar-c{flex:none;font-family:var(--serif);font-size:clamp(9px,1.2vw,12px);color:#e8ecef;text-align:center;line-height:1.1; letter-spacing:-.01em}
/* "pasada": una foto por pantalla con aire */
.gxm-psd{flex:1;min-height:0;display:flex;flex-direction:column;gap:8px;padding:6px 10px;background:#eef0f1;overflow:hidden}
.gxm-psd .gxm-tile{flex:1;min-height:0;margin:0}
/* "pares": de dos en dos, alternando cual manda */
.gxm-par{display:grid;grid-template-columns:1.62fr 1fr;gap:5px;flex:1;min-height:0;padding:5px}
.gxm-par-inv{grid-template-columns:1fr 1.62fr}
.gxm-par .gxm-tile{height:100%;margin:0}
.gxm-bruma{background:#eef0f1}
.gxm-diptico{background:#0e1114}
:root[data-theme="dark"] .gxm-sus,:root[data-theme="dark"] .gxm-psd,:root[data-theme="dark"] .gxm-bruma{background:#232220}
:root[data-theme="dark"] .gxm-sus-t{color:#EDEBE6}
:root[data-theme="dark"] .gxm-sus-l{background:#EDEBE6}

/* ==================== Movimiento del panel de galerias (2026-08-21) ====================
   Ponderacion: herramienta de productividad -- restriccion y velocidad primero. Lo que se
   anima esta abajo; lo que NO se anima esta igual de pensado y anotado al final. */

/* --- 1. Respuesta al presionar. El CRM entero no tenia NI UN :active con escala: nada
   respondia al dedo. Es lo mas barato y lo que mas se nota. Sin transicion de entrada a
   proposito -- la respuesta al tacto debe ser instantanea; la transicion es solo el
   regreso, para que no de un tiron al soltar. */
.ge-embebido .ge-rail .ge-segbtn,
.ge-embebido .ge-rail .ge-card,
.ge-embebido .ge-rail .ge-sw,
.ge-embebido .ge-rail .ge-row,
.ge-embebido .ge-rail .ge-rbtn,
.ge-txpanel .ge-segbtn,
.ge-txpanel .ge-nudgebtn,
.ge-embebido .ge-rail .ge-pfbtn,
.gx-card { transition-timing-function: var(--ease-estado); }
.ge-embebido .ge-rail .ge-segbtn:active,
.ge-embebido .ge-rail .ge-card:active,
.ge-embebido .ge-rail .ge-row:active,
.ge-embebido .ge-rail .ge-rbtn:active,
.ge-txpanel .ge-segbtn:active,
.ge-txpanel .ge-nudgebtn:active,
.ge-embebido .ge-rail .ge-pfbtn:active,
.gx-card:active { transform: scale(.97); }
.ge-embebido .ge-rail .ge-sw:active { transform: scale(.97); }

/* --- 2. El panel lateral al aparecer. Frecuencia ocasional -> entrada sutil justificada.
   Usa el atributo `hidden`, que NO transiciona: hace falta allow-discrete + @starting-style.
   Detras de @supports, el mismo criterio de mejora progresiva que ya usa la galeria. */
@supports (transition-behavior: allow-discrete) {
  .ge-txpanel {
    transition: opacity var(--dur-2) var(--ease-estado),
                transform var(--dur-2) var(--ease-estado),
                filter var(--dur-2) var(--ease-estado),
                display var(--dur-2) allow-discrete;
    opacity: 1; transform: none; filter: blur(0);
  }
  /* La salida es MAS sutil que la entrada: sin desplazamiento. La atencion del fotografo
     ya se fue a otra parte; lo que se va no debe competir con lo que queda. */
  .ge-txpanel[hidden] { opacity: 0; filter: blur(4px); display: none; }
  @starting-style {
    .ge-txpanel:not([hidden]) { opacity: 0; transform: translateX(8px); filter: blur(4px); }
  }
  .ge-txpanel:not([hidden]) { transition-duration: var(--dur-3); transition-timing-function: var(--ease-entra); }
}

/* --- 3. Los tres selectores a pantalla completa. Hoy aparecen de golpe, mientras que el
   modal normal del CRM si tiene entrada (`pop`): era inconsistencia, no decision. La
   SALIDA queda fuera: se destruyen con .remove() inmediato y darles salida obligaria a
   reescribir su ciclo de vida. */
@keyframes gxEntra { from { opacity: 0; } to { opacity: 1; } }
@keyframes gxEntraGrid { from { opacity: 0; transform: scale(.98); } to { opacity: 1; transform: none; } }
.gx-sel { animation: gxEntra var(--dur-2) var(--ease-entra) both; }
.gx-selscroll { animation: gxEntraGrid var(--dur-3) var(--ease-entra) both; }

/* --- 4. Campos que aparecen y desaparecen dentro del riel (la frase de la portada, el
   aviso de contraste, la alineacion del texto). Hoy saltan de golpe. Nunca `height`: es
   propiedad de layout y provoca reflow. */
@supports (transition-behavior: allow-discrete) {
  #ge-kicker-campo, #ge-tinta-aviso, #ge-tx-align-wrap, #ge-tx-nudge-wrap, #ge-espacio-auto {
    transition: opacity var(--dur-2) var(--ease-estado),
                transform var(--dur-2) var(--ease-estado),
                display var(--dur-2) allow-discrete;
    opacity: 1; transform: none;
  }
  #ge-kicker-campo[hidden], #ge-tinta-aviso[hidden], #ge-tx-align-wrap[hidden],
  #ge-tx-nudge-wrap[hidden], #ge-espacio-auto[hidden] { opacity: 0; display: none; }
  @starting-style {
    #ge-kicker-campo:not([hidden]), #ge-tinta-aviso:not([hidden]), #ge-tx-align-wrap:not([hidden]),
    #ge-tx-nudge-wrap:not([hidden]), #ge-espacio-auto:not([hidden]) { opacity: 0; transform: translateY(-4px); }
  }
}

/* --- 5. Arreglos de foco (los cuatro que la revision encontro) --- */
/* La tarjeta recortaba su propio aro: overflow:hidden + outline-offset positivo. El aro va
   hacia ADENTRO. */
.gx-card:focus-visible { outline-offset: -3px; }
/* El input de color real es opacity:0 -- el aro se dibujaba sobre algo invisible. Se
   traslada al envoltorio, que si se ve. */
.ge-swcustom-wrap .ge-swcustom:focus-visible { outline: none; }
.ge-swcustom-wrap:focus-within { outline: 2px solid var(--ge-ink); outline-offset: 2px; }
/* El aro usaba el acento del CRM tambien dentro del riel, donde desentona con la paleta
   neutra. Dentro del riel usa su propia tinta. */
.ge-embebido .ge-rail :focus-visible { outline-color: var(--ge-ink); }

/* --- 6. Tacto: quita el retardo de ~300ms del doble-tap en pantallas tactiles. */
.ge-embebido .ge-rail button, .ge-embebido .ge-rail label,
.ge-txpanel button, .gx-card, .gx-x { touch-action: manipulation; }

/* --- 7. Lo que NO se anima, y por que:
   - El repintado de la vista previa (post()) y el arrastre del encuadre: corren en cada
     pointermove. Una transicion ahi mete retraso entre el dedo y la imagen.
   - La SELECCION de segmentos y muestras (.on): se tocan decenas de veces por sesion, y
     ademas ~9 sitios hacen classList.toggle("on") en cada cambio de valor -- animar eso
     dispararia la animacion en cada tecleo. Solo llevan :active.
   - Nada que parpadee ni lata: sin puntos pulsantes ni anillos de estado.
   --- 8. Y el respeto a quien pide menos movimiento: */
@media (prefers-reduced-motion: reduce) {
  .geditor, .geditor *, .ge-txpanel, .ge-txpanel *, .gx-sel, .gx-sel * {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  /* El :active se conserva: no es decorativo, es la confirmacion de que el toque llego. */
}

/* ---- El Rodaje: la leccion del dia, dentro de la tarjeta de la manana (public/rodaje.js).
   Va DESPUES del pie en el CSS pero ANTES en el DOM: se cuelga con appendChild sobre .ritual
   y el pie ya se pinto, asi que el orden visual lo fija `order`. Sin esto la leccion aparecia
   debajo de la racha, que es el unico lugar donde no se lee. */
.rod-fila{ order:9; margin-top:10px; padding:11px 12px; border:1px solid var(--line2); border-radius:var(--r); background:var(--bone); }
.rod-cab{ display:flex; align-items:flex-start; justify-content:space-between; gap:8px; }
.rod-tit{ font-weight:600; font-size:var(--t-texto); line-height:1.35; }
/* La X es una salida, no una accion: apagada hasta que la buscas. Es el mismo peso que la de
   perfil.js, a proposito -- dos formas distintas de descartar la misma clase de sugerencia
   se leerian como dos sistemas. */
.rod-x{ background:none; border:0; color:var(--muted); font-size:var(--t-campo); line-height:1; padding:0 2px; cursor:pointer; }
@media (hover:hover){ .rod-x:hover{ color:var(--ink); } }
.rod-porque{ font-size:var(--t-meta); color:var(--muted); margin-top:5px; line-height:1.45; }
/* La ruta manual, mas callada que el porque: es la salida de emergencia, no el camino que
   estamos enseñando. El camino que enseñamos es el chip. */
.rod-mano{ font-size:var(--t-meta); color:var(--muted); opacity:.8; margin-top:5px; }
.rod-acc{ display:flex; flex-wrap:wrap; align-items:center; gap:6px; margin-top:9px; }
.rod-listo{ font-size:var(--t-meta); color:var(--muted); margin-top:5px; }
.rod-fin .rod-porque{ margin-top:4px; }

/* ---- El catalogo de capacidades (#/xarpie). Rejilla que se adapta sola: son 30 entradas
   de alto muy distinto (titulo corto, descripcion de dos lineas, chip con una frase larga),
   asi que auto-fill con minmax le deja a cada una el ancho que necesita sin media queries. */
.cat-sec{ margin-bottom:26px; }
.cat-tema{ font-family:var(--serif); font-weight:400; font-size:var(--t-texto); margin:0 0 10px; padding-bottom:6px; border-bottom:1px solid var(--line2); letter-spacing:-.01em }
.cat-grid{ display:grid; grid-template-columns:repeat(auto-fill, minmax(260px, 1fr)); gap:12px; }
.cat-item{ border:1px solid var(--line2); border-radius:var(--r); padding:12px 13px; display:flex; flex-direction:column; }
.cat-t{ font-weight:600; font-size:var(--t-texto); }
.cat-d{ font-size:var(--t-meta); color:var(--muted); margin-top:4px; line-height:1.45; }
/* El pie se empuja abajo para que los botones de una fila queden alineados aunque las
   descripciones midan distinto. Sin esto la rejilla se ve como una dentadura. */
.cat-pie{ margin-top:auto; padding-top:10px; }
/* Bloqueada por plan: se VE (que sepa que existe es la mitad del punto) pero no se puede
   accionar. Apagada, no tachada: no esta rota, no le alcanza todavia. */
.cat-bloq{ opacity:.55; }
.cat-plan{ font-size:var(--t-meta); color:var(--muted); font-style:italic; }

/* Custodia (fase 3): la pareja eligio su propio diseno, asi que lo que el fotografo
   cambie en esta pestana ya no llega a quien abre la galeria. Va arriba del rail, antes de
   los controles, porque es la condicion bajo la que se usan todos. */
.ge-aviso-custodia{margin:0 0 12px;padding:10px 12px;border:1px solid var(--hair);border-radius:var(--r);background:var(--paper2,var(--paper));color:var(--ink2);font-size:var(--t-meta);line-height:1.5}

/* ---- Sala de Cine en el CRM (public/sala-crm.js) ----
   Prefijo .sc- y nada mas: la lista reusa .gal-card/.gal-cover, los formularios reusan
   .gset/.ge-toggle/.ge-tt/.ge-ts y los botones .btn/.pill, igual que el editor de galeria.
   Aqui solo lo que no existia: la fila de un film, el visor y el panel de diseno. */
#sc-films{display:flex;flex-direction:column;gap:12px}
.sc-fila{display:flex;gap:14px;padding:16px;border:1px solid var(--line2);border-radius:var(--r);background:var(--paper2,var(--paper))}
.sc-fila-arch{opacity:.62}
.sc-fila-b{flex:1;min-width:0;display:flex;flex-direction:column;gap:14px}
/* .sc-mini sigue siendo la de la ficha de boda (renderFbSala): la fila de aqui ahora usa
   .sc-poster, mas grande, para no arrastrar ese cambio a un widget que no se rediseño. */
.sc-mini{width:132px;aspect-ratio:16/9;flex:none;border-radius:3px;background:rgba(0,0,0,.06);background-size:cover;background-position:50% 50%;display:flex;align-items:center;justify-content:center;color:var(--muted)}

/* El reordenamiento vive a la izquierda como un asa: data-subir/data-bajar son los mismos
   de siempre (cablearFilms no cambia), solo que ahora en una columna angosta en vez del
   final de la fila. */
.sc-handle{flex:none;width:20px;display:flex;flex-direction:column;gap:2px;padding-top:2px}
.sc-nudge-b{width:20px;height:18px;padding:0;border:0;border-radius:4px;background:transparent;color:var(--muted);display:flex;align-items:center;justify-content:center;font-size:var(--t-meta);line-height:1;cursor:pointer}
@media (hover:hover){ .sc-nudge-b:hover:not(:disabled){background:var(--line);color:var(--ink)} }
.sc-nudge-b:disabled{opacity:.3;cursor:default}

/* La lista compacta de "Orden de los videos" dentro del panel de Diseno: mismo asa
   (.sc-handle/.sc-nudge-b) que la pestana Videos, sin poster ni pildoras -- aqui solo
   importa el orden. Tokens --ge-* y no --line/--muted: vive dentro de .ge-embebido. */
.sc-dord-fila{display:flex;align-items:center;gap:10px;padding:9px 0}
.sc-dord-fila+.sc-dord-fila{border-top:1px solid var(--ge-line2)}
.sc-dord-tit{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--t-texto);color:var(--ge-ink)}
.sc-dord-dur{flex:none;font-size:var(--t-meta);color:var(--ge-ink2);font-variant-numeric:tabular-nums}

/* Fondo de portada: boton de subida (vacio) o tarjeta de lo ya subido -- las dos viven bajo
   #sc-d-fondo-area, que se repinta entero al cambiar de modo o al terminar una subida. */
.sc-fondo-subir{width:100%;display:flex;align-items:center;justify-content:center;gap:8px;padding:14px;border-radius:var(--r);border:1.5px dashed var(--ge-line);background:transparent;color:var(--ge-ink2);font-size:var(--t-texto);cursor:pointer;transition:border-color .15s,color .15s}
@media (hover:hover){ .sc-fondo-subir:hover{border-color:var(--ge-ink3);color:var(--ge-ink)} }
.sc-fondo-actual{display:flex;align-items:center;gap:10px;padding:8px;border-radius:var(--r);border:1px solid var(--ge-line)}
.sc-fondo-prev{width:40px;height:40px;flex:none;border-radius:4px;background-size:cover;background-position:50% 50%;background-color:var(--ge-canvas)}
/* Un video no se puede usar como background-image: la tarjeta de "ya subido" en modo video
   enseña el icono en vez de un fotograma. */
.sc-fondo-prev-video{display:flex;align-items:center;justify-content:center;background:linear-gradient(150deg,var(--ge-line),var(--ge-canvas));color:var(--ge-ink2)}
.sc-fondo-info{flex:1;min-width:0}
.sc-fondo-nombre{font-size:var(--t-meta);color:var(--ge-ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sc-fondo-meta{margin-top:1px;font-size:11px;color:var(--ge-ink2)}
.sc-fondo-cambiar{flex:none;background:none;border:0;color:var(--accent);font-size:12px;font-weight:600;cursor:pointer;padding:4px}
@media (hover:hover){ .sc-fondo-cambiar:hover{text-decoration:underline} }
.sc-fondo-subiendo{display:flex;align-items:center;gap:10px;padding:14px;border-radius:var(--r);border:1px solid var(--ge-line);color:var(--ge-ink2);font-size:var(--t-texto)}

.sc-top{display:flex;gap:14px}
/* La miniatura guarda 16:9 aunque no haya portada: sin alto fijo, la lista brincaba al
   llegar los posters de los films que todavia estaban procesando. */
.sc-poster{position:relative;flex:none;width:148px;aspect-ratio:16/9;border-radius:var(--r);border:1px solid var(--line2);
  background:rgba(0,0,0,.06);background-size:cover;background-position:50% 50%;display:flex;align-items:center;
  justify-content:center;color:var(--muted);padding:0;overflow:hidden}
.sc-poster-foco{cursor:crosshair}
@media (hover:hover){ .sc-poster-foco:hover{border-color:var(--muted)} }
.sc-poster-foco:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.sc-poster-badge{position:absolute;left:6px;bottom:6px;width:20px;height:20px;border-radius:50%;
  background:rgba(20,18,16,.6);backdrop-filter:blur(2px);display:flex;align-items:center;justify-content:center;
  color:#fff;pointer-events:none}
.sc-poster-star{position:absolute;top:6px;left:6px;width:22px;height:22px;border-radius:50%;background:var(--accent);
  display:flex;align-items:center;justify-content:center;color:#fff;pointer-events:none;box-shadow:0 1px 4px rgba(0,0,0,.35)}

.sc-identity{flex:1;min-width:0;display:flex;flex-direction:column;gap:9px}
.sc-toprow{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
.sc-tit{font-size:var(--t-campo);font-weight:600;border-color:transparent;background:transparent;padding:3px 0}
@media (hover:hover){ .sc-tit:hover:not(:disabled){border-color:var(--line2)} }
.sc-tit:focus{border-color:var(--accent)}
.sc-chiprow{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.sc-sel{max-width:170px;font-size:var(--t-meta);padding:5px 9px;border-radius:var(--r)}
.sc-err{font-size:var(--t-meta);color:var(--red);background:rgba(197,86,49,.08);border:1px solid rgba(197,86,49,.25);padding:9px 11px;border-radius:var(--r);line-height:1.5}
.sc-proc{display:flex;align-items:center;gap:8px;font-size:var(--t-meta);color:#836327}
.sc-proc i{width:6px;height:6px;border-radius:50%;background:currentColor;flex:none;animation:sc-pulse 1.4s ease-in-out infinite}
@keyframes sc-pulse{0%,100%{opacity:.4}50%{opacity:1}}

.sc-acts{flex-wrap:wrap;align-items:center}
.sc-tog{flex-wrap:wrap}
/* El interruptor reusa el checkbox nativo de siempre -- data-publico/data-descarga siguen
   leyendo .checked tal cual en cablearFilms, solo se le cambia la piel para que se vea como
   el .ge-sw2 del editor de galeria. */
.sc-check{display:inline-flex;align-items:center;gap:9px;font-size:var(--t-texto);color:var(--ink);cursor:pointer}
.sc-check input[type="checkbox"]{appearance:none;-webkit-appearance:none;width:36px;height:21px;margin:0;flex:none;border-radius:var(--r);background:rgba(25,23,20,.15);position:relative;cursor:pointer;transition:background .15s}
.sc-check input[type="checkbox"]:after{content:"";position:absolute;top:2px;left:2px;width:17px;height:17px;border-radius:99px;background:#fff;transition:left .15s;box-shadow:0 1px 3px rgba(0,0,0,.25)}
.sc-check input[type="checkbox"]:checked{background:var(--accent)}
.sc-check input[type="checkbox"]:checked:after{left:17px}
:root[data-theme="dark"] .sc-check input[type="checkbox"]{background:rgba(240,236,228,.18)}

.sc-iconbtn{width:32px;height:32px;flex:none;border-radius:var(--r);border:1px solid var(--line2);background:transparent;color:var(--ink);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;padding:0;list-style:none}
.sc-iconbtn::-webkit-details-marker{display:none}
@media (hover:hover){ .sc-iconbtn:hover{background:var(--line)} }
/* El menu "mas acciones" es un <details> nativo: abre/cierra sin estado nuevo en JS, y
   cablearFilms no necesita cablear nada para eso. */
.sc-menu{position:relative;flex:none}
.sc-menu-pop{position:absolute;top:calc(100% + 6px);right:0;z-index:5;min-width:190px;background:var(--paper2,var(--paper));border:1px solid var(--line2);border-radius:var(--r);padding:6px;box-shadow:0 10px 28px rgba(0,0,0,.18)}
.sc-menu-item{display:block;width:100%;text-align:left;padding:8px 10px;border:0;background:transparent;border-radius:var(--r);font-size:var(--t-texto);color:var(--ink);cursor:pointer}
@media (hover:hover){ .sc-menu-item:hover{background:var(--line)} }
.sc-menu-danger{color:var(--red)}
@media (hover:hover){ .sc-menu-danger:hover{background:rgba(197,86,49,.1)} }
.sc-menu-sep{height:1px;background:var(--line);margin:5px 2px}

/* La tarjeta de #/salas: el "abrir" es un boton real (no toda la tarjeta), y el menu de
   "mas acciones" es su HERMANO, flotando encima de la portada. Asi un clic en "Renombrar" o
   "Eliminar" no tiene que pelearle la burbuja al clic que abre la sala. */
.sc-salacard{position:relative}
.sc-salaabrir{display:block;width:100%;text-align:left;border:0;background:transparent;padding:0;cursor:pointer;color:inherit;font:inherit}
.sc-menu.sc-salamenu{position:absolute;top:10px;right:10px;z-index:2}
/* Mismo tratamiento que .sc-poster-badge: un circulo oscuro con blur, porque el boton flota
   sobre una foto que puede ser clara u oscura, y .sc-iconbtn solo, transparente, desaparece
   en la mitad de los casos. */
.sc-salamas{background:rgba(20,18,16,.6);backdrop-filter:blur(2px);border-color:transparent;color:#fff}
@media (hover:hover){ .sc-salamas:hover{background:rgba(20,18,16,.8)} }

.sc-visor{margin-top:2px}
.sc-visor iframe{width:100%;aspect-ratio:16/9;border:1px solid var(--line);border-radius:var(--r)}
.sc-drop-on{outline:2px dashed var(--blue);outline-offset:3px}
/* «Elegir archivo» ES el input, transparente y encima del boton: el clic cae en el control nativo
   y el navegador abre el selector solo, sin un input.click() de por medio. El boton de antes
   lo pedia con ese input.click() y en el navegador de Daniel no abria nada; la causa exacta no
   se reprodujo aqui (el codigo si llegaba a llamarlo). El anillo de teclado lo pinta la
   etiqueta, porque el del input no se veria: esta a 0 de opacidad. */
.sc-elegir{position:relative;overflow:hidden;cursor:pointer}
.sc-elegir input{position:absolute;inset:0;width:100%;height:100%;opacity:0;cursor:pointer}
.sc-elegir:has(input:focus-visible){outline:2px solid var(--tinta);outline-offset:2px}

/* ---- Ajustes: identidad / acceso / zona de riesgo, cada uno su propia tarjeta ----
   .gset existe pero solo remapea variables (--ge-*): no trae borde ni fondo propios, asi que
   .ge-tt/.ge-ts usados FUERA de un .ge-toggle no tenian ninguna regla que los pintara -- por
   eso la pestana de hoy se ve sin ninguna jerarquia. Las tarjetas de aqui son las mismas que
   ya usa la pestana Videos (.sc-fila): mismo borde, mismo radio, mismo fondo. */
.sc-ajustes{display:flex;flex-direction:column;gap:24px;max-width:640px}
.sc-agroup .flabel{margin-bottom:10px}
.sc-acard{background:var(--paper2,var(--paper));border:1px solid var(--line2);border-radius:var(--r);padding:18px 20px}
.sc-afield{display:flex;flex-direction:column;gap:7px}
.sc-afield+.sc-afield{margin-top:16px}
.sc-aflabel{font-size:var(--t-texto);font-weight:600;display:block}
.sc-afhelp{font-size:var(--t-meta);color:var(--muted);line-height:1.5}
/* auto-fit y no un 1fr 1fr fijo: el panel del CRM se angosta con el chat abierto sin que
   cambie el ancho de la ventana, asi que una media query por viewport no lo detectaria. */
.sc-arow2{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:16px}
.sc-arow2 .sc-afield+.sc-afield{margin-top:0}
.sc-arow2+.sc-afield{margin-top:16px}
.sc-alinkrow{display:flex;align-items:center;gap:10px;padding:10px 12px;background:var(--bone);border:1px solid var(--line2);border-radius:var(--r)}
.sc-alinkrow span{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:var(--t-texto);color:var(--muted)}
.sc-adanger{border-color:rgba(217,119,87,.35);background:rgba(217,119,87,.06)}
.sc-adanger .sc-aflabel{color:var(--red)}
.sc-abtn-danger{border-color:rgba(217,119,87,.4);color:var(--red);background:transparent}
@media (hover:hover){ .sc-abtn-danger:hover{background:rgba(217,119,87,.12)} }

/* ---- Actividad: tarjetas con icono para las 3 metricas, tablero por video ---- */
.sc-actividad{display:flex;flex-direction:column;gap:24px}
.sc-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:14px}
.sc-stat{background:var(--paper2,var(--paper));border:1px solid var(--line2);border-radius:var(--r);padding:16px 18px;display:flex;flex-direction:column;gap:10px}
.sc-stat-top{display:flex;align-items:center;justify-content:space-between;gap:8px}
.sc-stat-label{font-size:var(--t-meta);color:var(--muted);font-weight:500}
.sc-stat-ico{width:26px;height:26px;flex:none;border-radius:var(--r);background:var(--bone);color:var(--accent);display:flex;align-items:center;justify-content:center}
.sc-stat-n{font-size:var(--t-saludo);font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.01em;line-height:1}
.sc-stat-sub{font-size:var(--t-meta);color:var(--muted)}
.sc-vcard{padding:0}
.sc-vrow{display:flex;align-items:center;gap:14px;padding:12px 18px}
.sc-vrow+.sc-vrow{border-top:1px solid var(--hair,var(--line))}
.sc-vico{flex:none;width:32px;height:32px;border-radius:var(--r);background:var(--bone);color:var(--muted);display:flex;align-items:center;justify-content:center}
.sc-vtit{flex:1;min-width:0;font-size:var(--t-texto);font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sc-vstat{flex:none;width:104px;text-align:right}
.sc-vstat b{display:block;font-size:var(--t-texto);font-variant-numeric:tabular-nums;font-weight:600}
.sc-vstat span{display:block;font-size:var(--t-eti);color:var(--muted);text-transform:uppercase;letter-spacing:.03em;white-space:normal;line-height:1.3}
.sc-vempty{padding:44px 20px;display:flex;flex-direction:column;align-items:center;gap:12px;text-align:center}
.sc-vempty-ico{width:40px;height:40px;border-radius:var(--r);background:var(--bone);color:var(--muted);display:flex;align-items:center;justify-content:center}
.sc-vempty-t{font-size:var(--t-texto);color:var(--muted)}
@media (max-width:640px){.sc-vrow{flex-wrap:wrap}.sc-vstat{width:auto;flex:1 1 auto;text-align:left}}
.sc-color{width:52px;height:34px;padding:2px;border:1px solid var(--line);border-radius:3px;background:none;cursor:pointer}
/* Visitas de los ultimos 60 dias en la Actividad de la sala: barras CSS, sin libreria. */
.sc-serie{display:flex;align-items:flex-end;gap:2px;height:96px;padding:14px 14px 10px}
.sc-serie-b{flex:1;min-width:2px;background:currentColor;opacity:.5;border-radius:2px 2px 0 0}
/* La geometria del lienzo de Diseno de la sala (.sc-diseno) vive en el bloque EDITOR-UNIFICADO:
   la rejilla de dos columnas con preview pegajoso de antes se borro en la fase 6 de galerias
   unificadas, porque ya nada pinta .sc-diseno sin .ge-unificado. */

/* El panel de preview entero, igual que .ge-canvas del editor de galerias: un marco oscuro
   propio (no el tema claro/oscuro del CRM -- la Sala SIEMPRE se ve oscura, por eso estos
   colores van fijos y no por variable, mismo criterio que ya tenia .sc-prev-caja con su
   fondo #0c0c0b) que envuelve el segmentado de arriba Y la caja del navegador simulado.
   Pantalla completa promueve ESTE elemento entero, no solo la caja: si solo se promoviera la
   caja, el boton para salir (y los segmentados de modo/tamano) quedarian fuera del elemento
   en pantalla completa y desaparecerian de la vista. */
.sc-prev-canvas{display:flex;flex-direction:column;gap:14px;background:#151412;border-radius:var(--r);padding:14px}
.sc-prev-canvas:fullscreen{height:100vh;padding:20px;background:#151412}
.sc-prev-canvas:fullscreen::backdrop{background:#151412}
.sc-prev-top{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
/* .ge-seg/.ge-segbtn son del editor de galerias: su fondo, su tinta y su estado "on" son
   variables (--ge-canvas/--ge-ink2/--ge-bg) que solo existen dentro de .ge-canvas/.ge-embebido.
   Aqui, sin ese ancestro, esas variables no resuelven a nada -- background:var(--ge-bg) se
   vuelve invalido y el navegador cae a su boton de fabrica (fondo y BORDE por defecto), que es
   el contorno blanco que se veia. Se pisan con los mismos colores fijos que ya usa el resto de
   este panel (ver la nota de arriba de .sc-prev-canvas: la Sala siempre se ve oscura). */
.sc-prev-canvas .ge-seg{background:rgba(243,239,232,.08)}
.sc-prev-canvas .ge-segbtn{border:0;background:none;color:rgba(243,239,232,.62)}
@media (hover:hover){ .sc-prev-canvas .ge-segbtn:hover{color:#f3efe8} }
.sc-prev-canvas .ge-segbtn.on{background:#f3efe8;color:#151412;box-shadow:0 1px 3px rgba(0,0,0,.3)}
.sc-prev-stage{flex:1;display:flex;align-items:center;justify-content:center;min-height:0}
/* La caja en tres tamanos. Ahora es un navegador simulado (barra + cuerpo), no un iframe
   suelto: mismo criterio que .ge-browser/.ge-bbar/.ge-bbody del editor de galerias, asi el
   fotografo ve exactamente el mismo tipo de marco en las dos pantallas. El modo movil es un
   telefono de verdad (390px) y no un iframe ancho con media queries mintiendo. */
.sc-prev-caja{border:1px solid var(--line);border-radius:4px;overflow:hidden;background:#0c0c0b;margin:0 auto;
  height:min(78vh,760px);display:flex;flex-direction:column;transition:width .18s ease,max-width .18s ease}
/* Sin max-width: la columna del preview ya es 3/5 de la pagina y la caja debe llenarla (2026-09-15, Daniel la pidio mas grande). Escritorio por aspect-ratio y no por un alto fijo: un alto fijo (antes 620px, luego 480px)
   no sabe nada del ancho real de la columna del preview, asi que a veces salia casi cuadrada
   (se veia a tablet, no a escritorio). aspect-ratio:16/9 + height:auto hace que el alto
   siempre salga proporcional al ancho que de verdad hay -- angosta la columna, angosta la
   caja entera, nunca solo el alto. Mismo criterio que ya usaba el modo tele de abajo, y por
   la misma razon crece solo en pantalla completa (el ancho disponible crece, la caja tambien)
   sin necesitar una regla aparte para :fullscreen. */
.sc-prev-caja[data-modo="escritorio"]{width:100%;max-width:none;height:auto;aspect-ratio:16/9}
.sc-prev-caja[data-modo="movil"]{width:390px;max-width:100%;border-radius:var(--r)}
/* La tele es 16:9 y se ve de lejos: el ancho manda y la altura sale de la proporcion, porque
   una tele con la altura de una laptop no ensena lo que el modo TV hace con el espacio. */
.sc-prev-caja[data-modo="tv"]{width:100%;height:auto;aspect-ratio:16/9}
/* Sin barra de navegador en movil ni en tele: un telefono real no ensena su barra dentro de
   la app instalada, y una television no tiene barra de direcciones que simular. */
.sc-prev-caja[data-modo="movil"] .sc-prev-bbar,.sc-prev-caja[data-modo="tv"] .sc-prev-bbar{display:none}
/* Pantalla completa: movil es el UNICO modo que sigue topado a un alto fijo (390px de ancho
   fijo, un telefono no se ensancha por estar en pantalla completa), asi que es el unico que
   necesita una regla aparte aqui -- escritorio y tele ya crecen solos via aspect-ratio. */
.sc-prev-canvas:fullscreen .sc-prev-caja[data-modo="movil"]{height:min(100%,844px)}
.sc-prev-bbar{height:38px;flex:none;display:flex;align-items:center;gap:10px;padding:0 12px;background:#1a1917;border-bottom:1px solid var(--line)}
.sc-prev-url{flex:1;min-width:0;background:rgba(243,239,232,.06);border-radius:var(--r);height:24px;display:flex;align-items:center;padding:0 10px;font-size:12px;color:rgba(243,239,232,.48);gap:6px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.sc-prev-bbody{flex:1;min-height:0;overflow:hidden;position:relative}
.sc-prev-bbody iframe{position:absolute;inset:0;width:100%;height:100%;border:0;background:#0c0c0b;display:block;transform-origin:0 0}
/* El editor de capitulos, dentro del visor. Va DEBAJO del video y no al lado: el fotografo
   esta mirando la escena, y un panel lateral le roba ancho justo a lo que tiene que ver. */
.sc-caps{margin-top:10px}
.sc-caps-top{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.sc-caps-t{font-variant-numeric:tabular-nums;font-weight:600;margin-left:6px}
.sc-caps-vacio{margin-top:8px}
.sc-caps-lista{margin-top:8px;display:flex;flex-direction:column;gap:6px}
.sc-caps-fila{display:flex;gap:6px;align-items:center}
/* El minuto es angosto y tabular a proposito: es un dato de tiempo, no un titulo, y con la
   cifra alineada se leen veinte capitulos de un vistazo. */
.sc-caps-seg{width:76px;flex:none;font-variant-numeric:tabular-nums;text-align:center}
.sc-caps-fila .inp{min-width:0}
.sc-caps-fila .inp:not(.sc-caps-seg){flex:1}
/* La coleccion vive junto al tipo porque es lo mismo: como se agrupa este video con los otros. */
.sc-col{width:150px;max-width:100%;font-size:var(--t-meta);padding:5px 9px;border-radius:var(--r)}
@media (max-width:640px){.sc-caps-fila{flex-wrap:wrap}.sc-col{width:100%}}

/* El punto de foco vive ahora dentro de .sc-poster (mas grande); .sc-foco-p es el unico
   nombre que cablearFilms sigue buscando con querySelector, asi que no se toca. */
/* Anillo claro con borde oscuro: tiene que verse sobre una novia de blanco y sobre un traje
   negro, y un punto de un solo color desaparece en uno de los dos. */
.sc-foco-p{position:absolute;width:14px;height:14px;margin:-7px 0 0 -7px;border-radius:50%;
  border:2px solid rgba(255,255,255,.95);box-shadow:0 0 0 1.5px rgba(0,0,0,.55),0 1px 4px rgba(0,0,0,.5);pointer-events:none}
/* Encuadre de la portada (panel Diseno): la foto ENTERA y encima el marco de lo que de verdad
   se ve en esa vista (16:9 escritorio, 9:19.5 celular), calculado con la misma matematica de
   background-position que usa la sala. Lo de fuera del marco se oscurece con la sombra del
   propio marco (el contenedor recorta el sobrante), asi se ve que se pierde, no solo que queda. */
/* width:fit-content + img sin object-fit: la caja mide EXACTO lo que la foto. Con un
   object-fit:contain dentro de una caja mas grande, el marco se calcularia sobre la caja y no
   sobre la foto, y quedaria corrido en fotos verticales. */
.sc-encuadre{position:relative;margin-top:10px;width:fit-content;max-width:100%;border-radius:var(--r);overflow:hidden;cursor:crosshair;touch-action:none;user-select:none;background:#0c0c0b;line-height:0}
.sc-encuadre img{display:block;max-width:100%;max-height:320px;width:auto;height:auto;pointer-events:none}
.sc-encuadre-marco{position:absolute;outline:2px solid rgba(255,255,255,.95);box-shadow:0 0 0 9999px rgba(0,0,0,.5);pointer-events:none}
.sc-encuadre[aria-disabled="true"]{cursor:default}
.sc-encuadre-pie{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-top:10px}

/* La tira de candidatos. Scroll horizontal propio y no salto de linea: nueve fotogramas
   envueltos en tres filas dentro de la ficha de un video parecen una galeria, y esto es una
   fila de opciones. La elegida se marca con el acento y no con un check encima: el check
   taparia justo el trozo de imagen por el que se elige. */
.sc-tira-fila{display:flex;gap:6px;margin-top:6px;overflow-x:auto;padding-bottom:4px;scrollbar-width:thin}
.sc-fg{flex:none;width:96px;aspect-ratio:16/9;border:1px solid var(--line);border-radius:3px;padding:0;cursor:pointer;
  background-size:cover;background-position:50% 50%;background-color:rgba(0,0,0,.06)}
@media (hover:hover){ .sc-fg:hover{border-color:var(--muted)} }
.sc-fg.on{border-color:var(--accent);box-shadow:0 0 0 2px var(--accent) inset}
.sc-fg:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
@media (max-width:640px){
  .sc-fila{flex-direction:column}
  .sc-top{flex-wrap:wrap}
  .sc-poster{width:100%}
  .sc-mini{width:100%}
  .sc-fg{width:76px}
}

/* ---- Revelado: de la tarjeta a la galeria, sin salir de Xarpen (public/revelado.js) ----
   Misma familia visual que la Sala de Cine (.sc-*) y la galeria (.gal-prog-*): reusa esos
   dos en vez de reinventar barra de progreso o boton de accion. Lo propio de aqui es la
   zona de arrastre y la grilla de fotos con su chip de estado. */




/* --rv-min lo mueve el zoom de la grilla (A3, #rv-zoom): tamano minimo de miniatura. */
@keyframes rv-shimmer{ 0%{ background-position:200% 0; } 100%{ background-position:-200% 0; } }

/* Los tres estados se marcan con un BORDE de color (el chip ya dice cual con el icono;
   el borde es lo que se ve de reojo al pasar por 2,000 miniaturas). Reject se ve
   atenuada: es la señal de "esta ya no compite" sin taparla del todo (Recuperar la
   necesita reconocible). */



/* Los tres botones de marcar viven encima de la foto, ocultos hasta que el mouse pasa --
   con 2,000 tiles no pueden estar siempre visibles sin volver la grilla un mosaico de
   botones. En tactil (celular/tablet) se quedan siempre visibles: no hay hover que los
   revele, y sin esto no habria manera de marcar nada. */
.rv-foto:focus-within .rv-foto-acciones{ opacity:1; }
@media (hover:hover){ .rv-foto:hover .rv-foto-acciones{ opacity:1; } }
@media (pointer:coarse){ .rv-foto-acciones{ opacity:1; background:none; top:auto; bottom:0; justify-content:flex-end; } .rv-foto-pregunta{ display:none; } }
@media (hover:hover){ .rv-mini:hover{ background:var(--accent); } }

/* PR14 (cierre): a diferencia de .rv-foto-acciones (menu que solo aparece al hover), este
   toggle es la unica accion de la tarjeta y tiene que verse SIEMPRE -- de lo contrario en
   tactil (la mayoria de las veces que se revisa esto) no habria forma de saber que una foto
   ya esta incluida sin tocarla primero. */


/* La lista de #/revelados: una tarjeta por boda, calcada del patron de lista de la Sala. */
@media (hover:hover){ .rv-lista-item:hover{ border-color:var(--line2); background:var(--paper); } }
/* Tarjetas de "Tus revelados" (2026-09-10): .gal-card ya trae cursor/padding/fondo; aqui solo
   se agrega position:relative (para el menu de tres puntos que flota encima) en vez de
   tocar .gal-card, que Galerias y Sala de Cine ya usan tal cual -- mismo patron que
   .sc-salacard en Sala de Cine. */
.rv-tarjeta{ position:relative; }
/* Menu de tres puntos de la tarjeta ("Configuracion del revelado"): mismo .sc-menu/
   .sc-iconbtn/.sc-salamas ya usados por Sala de Cine (mas abajo en este archivo), solo la
   posicion es propia porque aqui flota sobre .gal-cover en vez de sobre .sc-salacard. */
.rv-tarjeta-menu{ position:absolute; top:10px; right:10px; z-index:2; }

/* Boton centrado "Iniciar nuevo revelado" (2026-09-10): reemplaza el panel siempre abierto
   de antes -- ahora abre el mismo picker (agrupado por urgencia + "sin CRM") en un modal.
   El texto lleva el efecto "Filo" (.xa-filo, mas abajo) igual que "Xarpie" en el riel de
   escritorio, mas grande porque aqui es la accion principal de la pantalla. */
@media (hover:hover){ .rv-ini-boton:hover{ border-color:var(--muted); background:var(--deep); } }
.rv-ini-boton:focus-visible{ outline:2px solid var(--accent); outline-offset:4px; }
.rv-ini-boton .xa-filo{ font-size:19px; }

.rv-ini-eyebrow{ font-size:11px; font-weight:600; letter-spacing:.06em; text-transform:uppercase; color:var(--muted); margin-bottom:14px; }
.rv-ini-grupo .rv-ini-fila:first-of-type{ border-top:0; }
@media (hover:hover){ .rv-ini-sinboda-abrir:hover{ color:var(--ink); } }
.rv-ini-sinboda-form .inp{ flex:1; }
/* Rediseño 2026-09-11: "Ligar a un evento" es ahora la opcion SECUNDARIA (colapsada) --
   mismo patron visual que el viejo .rv-ini-sinboda, solo que envolviendo la lista de
   eventos en vez del formulario sin CRM. */
#rv-ini-eventos-lista{ margin-top:12px; }

/* ---- Asistente de configuracion previa (PR16, 3 pasos, no un modal -- ver el plan grande
   de Revelado). Pagina normal, no .mbody: reusa .al-wsteps/.quiz-q/.quiz-qt/.quiz-ops/
   .quiz-op/.quiz-grupo-t/.seg/.seg-btn/.alw-preset/.sc-check/.payline tal cual (todos ya
   existen en otras pantallas); esto SOLO agrega lo que de verdad es nuevo. ---- */
.rv-cfg-subop:disabled{ opacity:.45; cursor:not-allowed; }

@media (max-width:640px){
}

/* ---- Revelado: visor de revision a pantalla completa (abrirRevisor en revelado.js) ----
   Mismas clases .lbx-* de la galeria (public/app.js): esto SOLO agrega lo propio de
   revisar culling -- la pregunta de Xarpie, la fila de comparacion de rafaga, la ayuda de
   teclado/gesto, y el tinte de arrastre al deslizar en tactil. */
/* ---- PR22: estrellas / color / bandera (revision enriquecida). Colores SIN rojo/amarillo/
   azul a proposito: esos ya significan reject/maybe/keep en el anillo de la foto. ---- */
:root{ --rv-verde:#7c9a6f; --rv-lavanda:#a98fc4; --rv-gris:#8B887F; }
.rv-dot-verde{ background:var(--rv-verde); } .rv-dot-lavanda{ background:var(--rv-lavanda); } .rv-dot-gris{ background:var(--rv-gris); }
.rv-chip-key b{ font-family:var(--mono); background:rgba(255,255,255,.16); color:#fff; padding:0 5px; border-radius:3px; font-weight:500; }
.rv-leyenda-fila b{ font-family:var(--mono); font-weight:500; min-width:88px; color:#fff; }
.rv-ind-color.verde{ border-bottom-color:var(--rv-verde); } .rv-ind-color.lavanda{ border-bottom-color:var(--rv-lavanda); } .rv-ind-color.gris{ border-bottom-color:var(--rv-gris); }
/* ---- A2: visor oscuro de pantalla completa (pantalla 7 del lienzo). Fondo opaco, grano de
   pelicula mas presente que el del resto de la app (.045 -> .08), solo la foto y lo minimo. ---- */
.rv-visor.rv-v2::before{ content:""; position:absolute; inset:0; z-index:0; pointer-events:none; opacity:.08; background-size:220px 220px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.45' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E"); }
.rv-top .lbx-count{ color:rgba(255,255,255,.7); }
.rv-pasp button{ border:0; background:transparent; color:rgba(255,255,255,.6); font-size:11px; padding:5px 10px; border-radius:99px; cursor:pointer; letter-spacing:.04em; }
.rv-pasp button.on{ background:rgba(255,255,255,.2); color:#fff; }
/* El paspartu es el aire alrededor de la foto: S/M/L mueven el padding del escenario. */
.rv-v2 .lbx-stage{ padding:64px 72px 8px; }
.rv-v2.rv-pasp-s .lbx-stage{ padding:56px 28px 8px; }
.rv-v2.rv-pasp-l .lbx-stage{ padding:80px 140px 8px; }
.rv-v2 .lbx-img{ border-radius:2px; }
.rv-carril-h i{ width:18px; height:2px; background:rgba(255,255,255,.6); border-radius:2px; }
.rv-carril-tira::-webkit-scrollbar{ display:none; }
@media (max-width:640px){ .rv-v2 .lbx-stage, .rv-v2.rv-pasp-s .lbx-stage, .rv-v2.rv-pasp-l .lbx-stage{ padding:56px 8px 8px; } .rv-pasp{ display:none; } .rv-ayuda-linea{ display:none; } }
/* ---- A4: asistencias (cada una con su interruptor). Nada de esto decide ni esconde una
   foto: agrupa, avisa o resalta -- ver [[revelado-prioridad-manual-sobre-ia]]. ---- */
/* B4: el numero que dice si el motor esta acertando, en la propia pantalla del revelado. */

/* Trabajos en segundo plano: la ficha que sigue viva al salir de la pantalla. z-index bajo
   el de los toasts a proposito -- un aviso puntual siempre debe poder taparla. */
@media (hover:hover){ .rv-trabajo:hover{ border-color:var(--accent); } }
.rv-trabajo.listo{ border-color:var(--blue); }
.rv-trabajo .gal-prog{ display:block; }
@media (max-width:640px){ .rv-trabajos{ right:10px; bottom:78px; max-width:calc(100vw - 20px); } }

/* "Enseñarle tu estilo": las dos carpetas, lado a lado. */
@media (hover:hover){ .rv-ap-drop:hover{ border-color:var(--accent); } }
.rv-asist-op input{ accent-color:var(--accent); }
@media (hover:hover){ .rv-foto:hover .rv-rafaga-x{ opacity:1; } }
/* Comparacion N-up: el zoom/paneo es el MISMO objeto para todas las celdas (revelado.js). */
.rv-nup-celda img{ width:100%; height:100%; object-fit:contain; transform-origin:50% 50%; user-select:none; -webkit-user-drag:none; }
/* Resaltado de enfoque: capa encima de la foto, mismo tamano que la imagen mostrada. */
.rv-mas-filtros[hidden]{ display:none; } /* display:flex le ganaria al atributo hidden */
.rv-mas-filtros .chip{ display:inline-flex; align-items:center; gap:6px; }
.rv-mas-filtros .chip.on{ border-color:var(--ink); color:var(--ink); }
@media (pointer:coarse){ .rv-visor-ayuda{ display:none; } .rv-visor-ayuda-tactil{ display:block; } }
/* El tinte va en el propio .lbx-img (no en el stage): as sigue el drag junto con la foto. */
.rv-visor .lbx-img{ touch-action:none; }
.rv-visor .lbx-img.rv-drag-keep{ box-shadow:0 0 0 6px var(--blue) inset; }
.rv-visor .lbx-img.rv-drag-reject{ box-shadow:0 0 0 6px var(--red) inset; }
.rv-visor .lbx-img.rv-drag-maybe{ box-shadow:0 0 0 6px var(--yellow) inset; }
@media (max-width:640px){ .rv-visor-rafaga-item{ width:44px; height:44px; } }

/* --- PR9: editor de revelado (#/revelado/:id/ajustar) --- */
.rv-ed-head{ align-items:flex-start; }
.rv-ed-estado{ font-family:var(--mono); font-size:10px; letter-spacing:.14em; text-transform:uppercase; align-self:center; }
.rv-ed-cap-tt{ font-family:var(--mono); font-size:9px; letter-spacing:.12em; text-transform:uppercase; margin:10px 0 6px; }
.rv-ed-tiras{ display:grid; grid-template-columns:1fr 1fr; gap:6px; }
.rv-ed-tira{ position:relative; aspect-ratio:1; border:0; padding:0; border-radius:4px; background:var(--deep) center/cover no-repeat; cursor:pointer; opacity:.8; outline:2px solid transparent; }
.rv-ed-tira.on{ opacity:1; outline-color:var(--ink); }
.rv-ed-tira-badge{ position:absolute; right:2px; bottom:2px; background:var(--ink); color:var(--paper); border-radius:3px; padding:1px 2px; display:flex; }
.rv-ed-canvas-wrap{ position:relative; }
.rv-ed-canvas-box{ position:relative; background:var(--ink); border-radius:6px; overflow:hidden; display:flex; }
.rv-ed-canvas{ width:100%; height:auto; display:block; }
.rv-ed-badge{ position:absolute; right:10px; bottom:10px; background:rgba(20,19,17,.72); color:var(--bone); font-size:10.5px; padding:5px 9px; border-radius:4px; max-width:60%; line-height:1.3; }
.rv-ed-panel{ position:sticky; top:12px; }
.btn-block{ display:block; width:100%; }
@media (max-width:860px){
  .rv-ed-tiras{ grid-template-columns:repeat(auto-fill,minmax(56px,1fr)); }
  .rv-ed-panel{ position:static; }
}

/* ---------- Legal: casilla de aceptacion, aviso bajo Google y hoja de re-aceptacion ----------
   Las tres superficies de aceptacion de los Terminos viven juntas porque comparten el tono
   (texto chico, secundario, sin gritar): separarlas es como el aviso bajo el boton de Google
   acabaria con un tamano distinto al de la casilla que tiene al lado. */
.legal-check{display:flex;gap:9px;align-items:flex-start;font-size:var(--t-meta);line-height:1.5;
  color:var(--muted);margin:2px 0 4px;cursor:pointer;text-align:left}
.legal-check input{margin:2px 0 0;flex:0 0 auto;width:15px;height:15px;cursor:pointer;accent-color:var(--accent)}
.legal-check a{color:var(--accent);text-decoration:underline}
.legal-aviso{font-size:var(--t-meta);line-height:1.5;color:var(--muted);text-align:center;margin:10px 0 0}
.legal-aviso a{color:var(--accent);text-decoration:underline}
.legal-aviso:empty{display:none}

.legal-gate{position:fixed;inset:0;z-index:9000;display:flex;align-items:center;justify-content:center;
  padding:20px;background:rgba(20,19,17,.62);-webkit-backdrop-filter:blur(3px);backdrop-filter:blur(3px)}
/* --paper, no --panel: `--panel` NO existe en esta hoja, asi que var(--panel,#FCFBF7) caia
   siempre al blanco fijo mientras --ink SI cambia a claro en modo oscuro -- texto claro
   sobre tarjeta clara, con el titulo practicamente invisible. Visto en vivo, no en
   revision. El par correcto es --paper/--ink/--hair, el mismo de las paginas legales. */
.legal-gate-card{background:var(--paper);color:var(--ink);border:1px solid var(--hair);border-radius:var(--r);
  padding:26px 26px 22px;max-width:440px;width:100%;box-shadow:0 18px 50px rgba(0,0,0,.28);text-align:left}
.legal-gate-card h2{font-family:var(--serif,Georgia,serif);font-weight:500;font-size:var(--t-titulo);margin:0 0 10px;line-height:1.2}
.legal-gate-card p{font-size:var(--t-texto);line-height:1.6;margin:0 0 12px;color:var(--muted)}
.legal-gate-card a{color:var(--accent);text-decoration:underline}
.legal-gate-ver{font-size:var(--t-meta) !important;opacity:.75}
.legal-gate-card .btn{width:100%;margin-top:6px}
.legal-gate-salir{display:block;width:100%;margin-top:10px;background:none;border:0;
  color:var(--muted);font-size:var(--t-meta);text-decoration:underline;cursor:pointer;padding:6px}

/* Rediseno minimalista: grano de pelicula, SOLO en tema oscuro (en claro se leia como polvo
   sobre papel). Es CSS puro con feTurbulence en data URI: cero peticiones, cero JS. Parametros
   los elegidos en el lienzo (grano grueso = baseFrequency .45, intensidad .045); desaturado con
   feColorMatrix para que el ruido no meta color en una app monocroma. pointer-events:none es lo
   que lo hace inofensivo encima de todo; fuera de impresion para no ensuciar PDFs. */
:root[data-theme="dark"] body::after{
  content:""; position:fixed; inset:0; z-index:10000; pointer-events:none; opacity:.045;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.45' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  background-size:220px 220px;
}
@media print{ :root[data-theme="dark"] body::after{ display:none; } }

/* ============================================================================
   Rediseno minimalista del INICIO DEL CHAT (2026-09-10). Fuente: lienzos "Dos columnas"
   y "Aire" (taller/diseno-minimal/Dos.dc.html y Main.dc.html). Acotado a:
   - escritorio ancho (>=1188px, el unico ancho donde existe .riel-izq) Y #app.crm-colapsado
     (= la ruta es el chat). En cualquier otra pantalla la barra de arriba sigue igual.
   - telefono (<=860px) para la cabecera y el saludo.
   Lo que el lienzo no tiene se ESCONDE, no se borra (notas fijadas, ritual, plegar): el
   DOM y sus handlers siguen vivos; quitar la regla los regresa. Calendario y lista del dia
   SI volvieron a mostrarse (pedido de Daniel, 2026-09-10): ocupan el lugar que dejo libre
   #muelle (CREAR), que paso a ser lo escondido -- ver el comentario de #muelle mas abajo.
   ============================================================================ */
.riel-negocio-tit{ display:none; }

/* El saludo, en todos los anchos: sin kicker ni banda de textura, 32px ligero. !important en
   el ::before porque fondos.css pinta la textura con [data-fondo] y carga despues. */
.greet.fondo{ margin:32px 0 0; padding:0; }
.greet.fondo::before{ display:none !important; }
.greetkicker{ display:none; }
.greetname{ font-size:var(--t-saludo); font-weight:400; letter-spacing:-.02em; line-height:1.14; margin-top:0; }

/* Sugerencias: texto, no pastillas. min-height para que sigan siendo tocables. */
#chat-tips{ gap:24px; }
#chat-tips .chip{ min-height:32px; padding:4px 0; border:0; background:transparent; color:var(--muted); font-size:var(--t-meta); letter-spacing:0; }
@media (hover:hover){ #chat-tips .chip:hover{ color:var(--ink); background:transparent; } }

@media (min-width:1188px){
  /* La barra de arriba se queda solo con campana/engrane. visibility (no display) para no
     mover su rejilla y para sacar lo escondido del orden de foco. */

  #app.crm-colapsado .riel-izq:not([hidden]){
    flex-basis:256px !important; gap:32px; padding:32px 24px; align-items:stretch;
    background:transparent; border-right:0;
  }
  #app.crm-colapsado .riel-izq .riel-cab,
  #app.crm-colapsado .riel-izq #riel-notas,
  #app.crm-colapsado .riel-izq #riel-ritual{ display:none !important; }
  /* #muelle (CREAR) se escondio aqui (2026-09-10, pedido de Daniel): calendario y lista del
     dia recuperan su lugar en el orden natural del DOM (#riel-cal y #diaria van justo
     despues de #muelle en index.html), asi que quitar #muelle de en medio basta -- no hace
     falta reordenar nada, sincDiaria()/sincRieles()/pintarRielCalendario() (app.js) ya
     sabian pintar los dos en este modo desde antes del rediseno, solo estaban tapados. El
     "+" del composer sigue siendo el camino para crear sin comando "/" en este modo. */
  #app.crm-colapsado .riel-izq #muelle{ display:none !important; }

  /* La lista del dia se diseno para un riel de 296px (ver el comentario de .diaria-hora
     mas arriba); esta columna mide 256px con 24px de relleno a cada lado, o sea 208px de
     contenido -- 88px menos. Con hora(32) + casilla(15) + menu-kebab(22) + agarre(14) fijos
     mas los espacios entre los seis elementos de la fila, a .diaria-txt le quedaban ~60px y
     a .diaria-quien ~9px (medido en vivo con una tarea real: el titulo se partia palabra por
     palabra y el nombre del cliente no se alcanzaba a leer, reportado por Daniel con una
     captura). Se esconden hora y agarre (arrastrar para reordenar sigue disponible en la
     hoja de telefono y en el riel de 296px fuera de este modo) y quien deja de encogerse --
     total: 208 -> le regresan ~70px extra a .diaria-txt. */
  #app.crm-colapsado .riel-izq #diaria .diaria-hora,
  #app.crm-colapsado .riel-izq #diaria .diaria-grip{ display:none; }
  #app.crm-colapsado .riel-izq #diaria .diaria-quien{ flex-shrink:0; }
  /* Aun con lo de arriba, el titulo solo se queda con ~88px: un titulo largo de verdad
     todavia envolvia a 5 lineas, una fila comiendose media columna. Mismo recorte de 2
     lineas que ya usa .riel-izq.plegado .nota-txt para el mismo problema (una tarjeta
     angosta, un texto largo) -- el titulo completo sigue en el `title` del span y a un
     click de distancia (abre modalTarea). */
  #app.crm-colapsado .riel-izq #diaria .diaria-txt{
    display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden;
  }


  /* HOY: renglones "numero  etiqueta". Se quedan tareas e ingreso; "a tiempo" se va y
     "atrasadas" solo aparece cuando hay alguna (es la unica que significa algo en rojo). */
  #app.crm-colapsado .riel-negocio{ flex-direction:column; align-items:stretch; gap:12px; margin:0; padding:0; border:0; }
  #app.crm-colapsado .riel-negocio-tit{ display:block; font-size:var(--t-eti); letter-spacing:.18em; text-transform:uppercase; color:var(--muted); }
  #app.crm-colapsado .riel-negocio-sep,
  #app.crm-colapsado .riel-negocio-col[data-rn="galerias"],
  #app.crm-colapsado .riel-negocio > .riel-negocio-col:nth-of-type(2):not(:has(.mal)){ display:none; }
  #app.crm-colapsado .riel-negocio-col{ flex:none; flex-direction:row; align-items:baseline; gap:12px; padding:0; }
  @media (hover:hover){ #app.crm-colapsado .riel-negocio-col:hover{ background:transparent; } }
  #app.crm-colapsado .riel-negocio-n{ flex:0 0 56px; text-align:left; font-weight:400; }
  #app.crm-colapsado .riel-negocio-l{ font-size:var(--t-meta); text-transform:none; letter-spacing:0; }

  /* CREAR: lista de texto, sin iconos ni rejilla. Tambien anula el estado plegado. */
  #app.crm-colapsado .muelle{ display:flex; flex-direction:column; gap:0; }
  #app.crm-colapsado .muelle-tit{ letter-spacing:.18em; margin-bottom:8px; }
  #app.crm-colapsado .muelle .muelle-btn{ flex-direction:row; justify-content:flex-start; text-align:left; padding:7px 0; font-size:var(--t-texto); line-height:1.3; color:var(--ink); border-radius:0; }
  @media (hover:hover){ #app.crm-colapsado .muelle .muelle-btn:hover{ background:transparent; text-decoration:underline; text-underline-offset:3px; } }
  #app.crm-colapsado .muelle .muelle-btn svg{ display:none; }
  #app.crm-colapsado .riel-izq.plegado .muelle-tit,
  #app.crm-colapsado .riel-izq.plegado .muelle-btn span{ display:revert; }

  /* Columna de lectura de 560px (el lienzo: ~70 caracteres a 14px) en vez de 780. */
  #app.crm-colapsado .chatpane .greet,
  #app.crm-colapsado .chatpane .chatscroll,
  #app.crm-colapsado .chatpane .chips{ padding-inline:max(0px, calc((100% - 560px) / 2)); }
  #app.crm-colapsado .chatpane .attach-prev,
  #app.crm-colapsado .chatpane .composer{ max-width:560px; }
  /* Composer relleno, sin borde; enviar cuadrado de 36. */
  #app.crm-colapsado .chatpane .composer{ border-color:transparent; background:var(--paper); padding:4px 4px 4px 8px; }
  #app.crm-colapsado #chat-send{ width:36px; height:36px; border-radius:3px; }
}

@media (max-width:860px){
  /* Cabecera del telefono: solo ☰ y ×, la marca ya no ocupa la fila. */
  .chatpane .cp-brand .xarpen-logo{ display:none; }
  .chatpane .cp-brand{ justify-content:space-between; align-items:center; }
  /* "Tu dia": renglon de texto, no caja. Sigue siendo el boton que abre la hoja. */
  .dialinea:not([hidden]){ border:0; padding:8px 0; min-height:44px; margin-top:12px; color:var(--muted); }
  .dialinea:active{ background:transparent; color:var(--ink); }
}
/* Ajustes medidos en vivo sobre el bloque de arriba:
   - .fondo (fondos.css) le pone background-color a la caja y un velo en ::after, asi que
     quitar solo el ::before dejaba un rectangulo detras del saludo.
   - En telefono el ☰ y la × tenian caja con borde; el lienzo los dibuja como iconos sueltos. */
.greet.fondo{ background:none; }
.greet.fondo::after{ display:none !important; }
@media (min-width:1188px){
  #app.crm-colapsado .riel-negocio-l{ text-transform:lowercase; }
}
@media (max-width:860px){
  .chatpane .cp-brand .cp-close{ border:0; background:transparent; box-shadow:none; }
}

/* ============================================================================
   Xarpie: FILO (2026-09-10, elegido por Daniel en el lienzo "Xarpie Prisma" entre 4+4
   variaciones: "Filo · mas notorio", siempre corriendo). Nacio en la nav de texto del riel
   (retirada con el menu de 4 secciones); hoy lo usa el boton "Iniciar un revelado".
   La letra es metal (background-clip:text) y el color vive SOLO en el filo: dos copias de
   la palabra, roja y cian, DETRAS del metal y corridas medio pixel; solo asoma lo que
   sobresale del contorno -- la aberracion cromatica de un lente real. Cada 6.1s pasa una luz
   y el filo se abre a 1px.
   Dos cosas de las que depende, y que un cambio inocente rompe en silencio:
   - .xa-filo NO puede ser contexto de apilamiento (sin filter/opacity/transform/z-index en
     ella): si lo fuera, sus copias z-index:-1 pintarian ENCIMA del metal. Por eso tampoco
     hay efecto de hover con filter aqui.
   - El boton que la contiene SI tiene que ser contexto (isolation): asi las copias quedan dentro, por encima de
     los fondos del riel y de #app, y no desaparecen detras de ellos.
   Las copias heredan -webkit-text-fill-color:transparent del padre: sin currentColor
   serian invisibles (paso en el lienzo). --k escala el filo (1 = lo aprobado).
   ============================================================================ */
@property --xf-a{ syntax:"<percentage>"; inherits:false; initial-value:130%; }
.xa-filo{
  --k:1;
  --xf-luz: color-mix(in srgb, var(--ink) 55%, #fff);
  --xf-sombra: color-mix(in srgb, var(--ink) 78%, #000);
  position:relative; display:inline-block; font-weight:500; letter-spacing:.01em; color:var(--ink);
  background-image:
    linear-gradient(105deg, transparent 41%, rgba(255,236,220,.35) 45%, rgba(255,255,255,.8) 47%, rgba(220,240,255,.35) 49%, transparent 53%),
    linear-gradient(180deg, var(--xf-luz) 0%, var(--ink) 52%, var(--xf-sombra) 100%);
  background-size:260% 100%, 100% 100%;
  background-position:var(--xf-a) 0, 0 0;
  -webkit-background-clip:text; background-clip:text; -webkit-text-fill-color:transparent;
  animation:xf-luz 6.1s cubic-bezier(.45,.05,.2,1) infinite;
}
.xa-filo::before, .xa-filo::after{
  content:attr(data-t); content:attr(data-t) / ""; position:absolute; inset:0; z-index:-1; pointer-events:none;
  -webkit-text-fill-color:currentColor;
}
.xa-filo::before{ color:rgba(255,64,104,.95); animation:xf-rojo 6.1s cubic-bezier(.45,.05,.2,1) infinite; }
.xa-filo::after{ color:rgba(52,198,255,.95); animation:xf-cian 6.1s cubic-bezier(.45,.05,.2,1) infinite; }
@keyframes xf-luz{ 0%{--xf-a:130%} 35%{--xf-a:-30%} 100%{--xf-a:-30%} }
@keyframes xf-rojo{ 0%{transform:translate(calc(-.03em * var(--k)),0);opacity:.78} 17%{transform:translate(calc(-.07em * var(--k)),calc(.01em * var(--k)));opacity:1} 35%,100%{transform:translate(calc(-.03em * var(--k)),0);opacity:.78} }
@keyframes xf-cian{ 0%{transform:translate(calc(.03em * var(--k)),0);opacity:.78} 17%{transform:translate(calc(.07em * var(--k)),calc(-.01em * var(--k)));opacity:1} 35%,100%{transform:translate(calc(.03em * var(--k)),0);opacity:.78} }
@media (prefers-reduced-motion: reduce){
  /* Quieto: el filo se queda en reposo (medio pixel), sin barrido. */
  .xa-filo, .xa-filo::before, .xa-filo::after{ animation:none; }
  .xa-filo::before{ transform:translateX(-.03em); opacity:.78; }
  .xa-filo::after{ transform:translateX(.03em); opacity:.78; }
}

/* ============================================================================
   INTRO: el logo de Xarpen ENFOCA al abrir la app (2026-09-10, pedido de Daniel; es el
   "Filo · enfoque" del lienzo, llevado a la marca).
   Choque con el handoff de marca, a sabiendas: el handoff pone los desenfoques entre "lo que
   rompe el sistema" (ver .xarpen-mark--enfoque arriba, que por eso anima solo opacidad).
   Aqui el desenfoque existe SOLO durante el movimiento: el logo termina en su estado de
   especificacion (sin filtro, opacidades .3/.6/1 de sus anillos) antes de desvanecerse.
   Cuando: en cada carga de la pagina (recargar incluido), nunca con reducir movimiento. Lo decide public/intro-init.js
   ANTES del primer pintado (pone html[data-intro]); sin ese atributo esto no existe.
   Lo que lo hace sentir lente y no "borroso":
   - el autofoco CAZA: baja casi a nitido, se pasa (58%), regresa y fija;
   - VELO: pierde contraste y se aclara fuera de foco;
   - color de desenfoque (aberracion longitudinal): violeta antes del foco, verde al pasarse;
   - la marca "respira" 3%; al fijar, los anillos pulsan del centro hacia afuera (el pulso
     xarpen-pulso de siempre, retrasado para caer justo en el momento del foco).
   El orden de las funciones de filter es el MISMO en cada paso: si cambia, no interpola.
   ============================================================================ */
#intro-xarpen{ display:none; }
html[data-intro] #intro-xarpen{
  display:grid; place-items:center; position:fixed; inset:0; z-index:9990;
  background:var(--bone); transition:opacity .45s ease;
}
#intro-xarpen.saliendo{ opacity:0; pointer-events:none; }
.intro-lente{
  color:var(--xarpen-ink); transform-origin:center;
  animation:intro-enfoque 1.5s cubic-bezier(.45,.05,.2,1) both;
}
@keyframes intro-enfoque{
  0%   { filter:blur(14px) contrast(.8) brightness(1.1) drop-shadow(-3px 0 0 rgba(206,96,255,.55)) drop-shadow(3px 0 0 rgba(255,96,200,.5));  transform:scale(1.03);  opacity:.75; }
  42%  { filter:blur(1.6px) contrast(.95) brightness(1.03) drop-shadow(-1.5px 0 0 rgba(226,90,220,.45)) drop-shadow(1.5px 0 0 rgba(236,110,230,.4)); transform:scale(1.006); opacity:.95; }
  58%  { filter:blur(4px) contrast(.9) brightness(1.05) drop-shadow(-2px 0 0 rgba(120,240,150,.5)) drop-shadow(2px 0 0 rgba(90,235,190,.45)); transform:scale(1.012); opacity:.92; }
  78%  { filter:blur(.6px) contrast(.99) brightness(1.01) drop-shadow(-.8px 0 0 rgba(255,78,124,.4)) drop-shadow(.8px 0 0 rgba(70,216,255,.4)); transform:scale(1.002); opacity:1; }
  100% { filter:blur(0) contrast(1) brightness(1) drop-shadow(0 0 0 transparent) drop-shadow(0 0 0 transparent); transform:scale(1); opacity:1; }
}
/* Los anillos pulsan al fijar el foco (1.5s), en la misma onda centro -> afuera de siempre. */
#intro-xarpen .xarpen-mark--enfoque circle[r="3"] { animation-delay:1.38s; }
#intro-xarpen .xarpen-mark--enfoque circle[r="9"] { animation-delay:1.45s; }
#intro-xarpen .xarpen-mark--enfoque circle[r="15"]{ animation-delay:1.52s; }
#intro-xarpen .xarpen-mark--enfoque circle[r="21"]{ animation-delay:1.59s; }
/* Modo video (tema oscuro): el logo CSS no se pinta mientras se decide; si el video falla,
   introXarpen() cambia data-intro a "" y el logo CSS aparece con su animacion desde cero.
   El video se ve completo (contain: en un telefono vertical, cover cortaria el logo) y una
   mascara radial funde sus orillas con el fondo: asi no se nota donde termina el cuadro, y
   de paso se apagan los halos de arcoiris que el modelo dejo en los bordes de la toma.
   Mascara = DOS desvanecidos lineales (vertical y horizontal) intersectados, no una elipse: con
   el video v2 (papel mas claro que el fondo) la elipse dejaba duros los lados largos de la caja
   -- su centro opaco llega casi a esos bordes en una caja alargada. Los lineales llevan cada
   borde a transparente dentro de la caja, en cualquier proporcion de pantalla. */
html[data-intro="video"] #intro-xarpen .intro-lente{ display:none; }
#intro-xarpen .intro-video{
  /* La CAJA del video mide exactamente lo que la imagen (1344:768), centrada y lo mas grande
     que quepa. Con inset:0 + contain la caja era toda la pantalla y la imagen una tira: la
     mascara fundia la caja, no la imagen, y en telefono quedaban dos bordes duros (medido en
     composicion-intro.html). Asi la mascara cae sobre los cuatro bordes de la imagen. */
  position:absolute; left:50%; top:50%; transform:translate(-50%,-50%);
  /* --intro-escala: el video NO llena la pantalla en escritorio (Daniel: "mas pequeno"); en
     telefono si, porque ahi el logo ya es chico y mas pequeno no se leeria. */
  width:calc(min(100vw, 100vh * 1344 / 768) * var(--intro-escala, .6)); height:auto; aspect-ratio:1344 / 768;
  object-fit:cover; background:transparent;
  /* brightness(.9): el fondo del video es apenas mas claro que --bone, y con el video al 60%
     el borde del recuadro caia dentro de la pantalla como un rectangulo tenue. Oscurecerlo 10%
     iguala su fondo al de la app (y de paso baja un poco el brillo del logo, que Daniel pidio). */
  filter:brightness(.9);
  opacity:0; transition:opacity .35s ease; pointer-events:none;
  -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 22%, #000 78%, transparent 100%), linear-gradient(to right, transparent 0%, #000 16%, #000 84%, transparent 100%);
  -webkit-mask-composite:source-in;
  mask-image:linear-gradient(to bottom, transparent 0%, #000 22%, #000 78%, transparent 100%), linear-gradient(to right, transparent 0%, #000 16%, #000 84%, transparent 100%);
  mask-composite:intersect;
}
@media (max-width:760px){ #intro-xarpen .intro-video{ --intro-escala:1; } }
#intro-xarpen.con-video .intro-video{ opacity:1; }
#intro-xarpen:not(.con-video) .intro-video{ visibility:hidden; }
@media (prefers-reduced-motion: reduce){ #intro-xarpen{ display:none !important; } }
@media print{ #intro-xarpen{ display:none !important; } }

/* ============================================================================
   iPhone con la app INSTALADA (manifest display:standalone + viewport-fit=cover, sin
   status bar translucida): el sistema reserva la franja de la barra de estado y la vista
   empieza DEBAJO de ella, pero 100vh sigue midiendo la pantalla COMPLETA. Todo lo que mide
   100vh sobraba hacia abajo exactamente esa franja (~42pt en el iPhone de Daniel,
   2026-09-10): el composer del chat quedaba cortado detras del indicador de inicio, y el
   intro -- centrado en una caja igual de alta -- dejaba el logo media franja abajo del
   centro. 100dvh es la altura que DE VERDAD se ve (mismo remedio que ya documentan
   .pp-menu y .hojadia en este archivo). Va al final a proposito: estas reglas tienen que
   ganarle por orden a .chatpane (1102, 5105) y a #intro-xarpen, con la misma especificidad.
   El 100vh de antes se queda como respaldo para navegadores sin dvh.
   ============================================================================ */
@media (max-width:860px){
  #app{ min-height:100vh; min-height:100dvh; }
  .main{ height:100vh; height:100dvh; }
  .chatpane{ height:100vh; height:100dvh; padding-bottom:calc(14px + env(safe-area-inset-bottom)); }
}
html[data-intro] #intro-xarpen{ inset:auto; top:0; left:0; width:100%; height:100vh; height:100dvh; }
#intro-xarpen .intro-video{
  width:calc(min(100vw, 100vh * 1344 / 768) * var(--intro-escala, .6));
  width:calc(min(100vw, 100dvh * 1344 / 768) * var(--intro-escala, .6));
}

/* ==========================================================================================
   C3 -- "Edita estas primero" (#/revelado/:id/anclas). Diseno aprobado: lienzo "Anclas (C3)".
   El borde de estado va con outline y no con box-shadow inset: la <img> cubre la tarjeta
   completa y taparia la sombra; el outline se pinta encima del contenido.
   ========================================================================================== */
.rv-an-foto img{ width:100%; height:100%; object-fit:cover; display:block; }
.rv-an-foto.lista{ outline:2px solid var(--ink); outline-offset:-2px; }
.rv-an-foto.siguiente{ outline:2px solid var(--yellow); outline-offset:-2px; }
.rv-an-marca svg{ width:10px; height:10px; }
/* Las dos ultimas columnas a max-content y la muestra con piso de 200px: con el panel de Xarpie
   abierto el area util baja a ~500px, y con 190/210 fijos la columna 1fr colapsaba a CERO. Eso
   no solo encimaba los titulos: una <img loading="lazy"> de area cero nunca se pide. */
.rv-an-mini img{ width:100%; height:100%; object-fit:cover; display:block; }
.rv-an-mini.ancla{ outline:2px solid var(--ink); outline-offset:-2px; }
@media (max-width:1100px){
  /* Momento | salio de | deshacer en una linea, la muestra debajo a todo el ancho. Los titulos
     de columna dejan de corresponder a nada, asi que se ocultan en vez de quedar descuadrados. */
}
@media (max-width:760px){
}

/* ==========================================================================================
   C5 -- "Por que se ve asi" en el editor y "Tus looks". Diseno aprobado: lienzo "Explicar y looks (C5)".
   ========================================================================================== */
.rv-pq-seg .seg-btn{ flex:1; font-size:12px; padding:7px 8px; }

.rv-lk-muestras div{ background:var(--deep) center/cover no-repeat; }
.rv-lk-muestras div:first-child{ grid-row:1 / span 2; }
.rv-lk-fotos div{ aspect-ratio:3/2; border-radius:3px; background:var(--deep) center/cover no-repeat; }

/* C6 -- al guardar, el momento se re-sugiere. Diseno aprobado: lienzo "Propagar al guardar (C6)". */

/* ============================================================================
   Menu de 4 secciones (rediseno de navegacion aprobado 2026-09-12, lienzo "Navegacion en
   cuatro secciones"): fila de sub-pestanas arriba del CRM, contador de las secciones y
   selector de vista. Valores del lienzo, que a su vez salen de .cp-navbtn/.cp-navcfg/.tab.
   ============================================================================ */
.cp-modo{ display:none; }
.nav-badge{
  min-width:16px; height:16px; padding:0 4px; border-radius:var(--r); flex:none;
  background:var(--line2); color:var(--ink); font-size:var(--t-eti); font-weight:600; line-height:16px; text-align:center;
}
.nav-badge[hidden]{ display:none; }
.cp-navbtn.on .nav-badge{ background:var(--paper); color:var(--ink); }
/* sticky DENTRO del scroll de .main: la fila se queda arriba mientras la pagina baja. */
.subtabs{
  position:sticky; top:0; z-index:5; flex:none; display:flex; align-items:stretch; gap:6px;
  height:40px; padding:0 26px; background:var(--bone); border-bottom:1px solid var(--hair);
  overflow-x:auto; overflow-y:hidden; scrollbar-width:none;
}
.subtabs[hidden]{ display:none; }
.subtabs::-webkit-scrollbar{ display:none; }
.subtab{
  position:relative; flex:none; display:flex; align-items:center; gap:6px; padding:0 10px;
  border:0; background:transparent; color:var(--muted); font:inherit; font-size:var(--t-texto);
  font-weight:500; white-space:nowrap; cursor:pointer;
}
.subtab .ico{ width:14px; height:14px; }
.subtab.on, .subtab[aria-expanded="true"]{ color:var(--ink); }
@media (hover:hover){ .subtab:hover{ color:var(--ink); } }
.subtab[aria-expanded="true"]{ background:var(--paper); }
.subtab.on::after{ content:""; position:absolute; left:10px; right:10px; bottom:-1px; height:2px; border-radius:2px; background:var(--ink); }
.subtab:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
.subtab.off{ cursor:default; color:color-mix(in srgb, var(--muted) 62%, transparent); }
.subtab-pronto{ font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); border:1px solid var(--line2); border-radius:var(--r); padding:1px 5px; }
.subtab-sep{ flex:none; width:1px; margin:12px 4px; background:var(--line2); }
.um-grupo{ padding:8px 12px 4px; font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); }
@media (min-width:861px){
  .cp-navbtn .nav-badge{ margin-left:2px; }
  .cp-modo{ display:flex; gap:2px; padding:3px; margin-left:8px; border:1px solid var(--line2); border-radius:var(--r); align-self:center; }
  .cp-modo-btn{ width:30px; height:26px; display:flex; align-items:center; justify-content:center; border:0; border-radius:3px; background:transparent; color:var(--muted); cursor:pointer; transition:background .13s, color .13s; }
  @media (hover:hover){ .cp-modo-btn:hover{ color:var(--ink); } }
  .cp-modo-btn.on{ background:var(--line2); color:var(--ink); }
  .cp-modo-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:1px; }
}
@media (max-width:860px){
  .subtabs{ padding:0 8px; height:44px; scroll-snap-type:x proximity; }
  .subtab{ scroll-snap-align:start; }
}

/* ============================================================================
   PANEL DE NAVEGACION LATERAL (N1, lienzo "Panel de navegacion izquierdo", 2026-09-13).
   Solo escritorio. Cerrado es una tira de 64px con los iconos de las secciones; al pasar el
   cursor (o con foco de teclado) se despliega a 256px ENCIMA del chat, sin moverlo; con el pin
   se queda abierto y empuja la barra de arriba y la app (--navlat-w). Las secciones y sus
   paginas viven aqui, asi que en escritorio se esconden las 4 de arriba y #subtabs.
   El look Guijarro (piedra flotante, grano) es N3: aqui van los tokens de hoy.
   ============================================================================ */
.nav-lat, .cp-miga{ display:none; }
@media (min-width:861px){
  :root{ --navlat-w:64px; }
  body.nav-lat-fijo{ --navlat-w:256px; }
  body.nav-lat-on .nav-lat.show{ display:block; position:fixed; left:0; top:0; bottom:0; width:var(--navlat-w); z-index:60; }
  body.nav-lat-on #cp-riel.show, body.nav-lat-on #app.show{ margin-left:var(--navlat-w); }
  /* El logo vuelve a tener columna propia (2026-09-14): con el panel lateral activo ya no
     comparte fila con las 4 secciones (.cp-nav-central, oculta abajo), asi que pasa de
     1fr/auto a auto/1fr/auto -- logo a su ancho natural, la miga empuja el resto, los
     iconos de siempre a la derecha. Sin padding-left: el logo ya ocupa ese espacio, no
     hace falta compensar un hueco que dejo de existir. */
  body.nav-lat-on #cp-riel.show{ grid-template-columns:auto 1fr auto; }
  body.nav-lat-on .cp-nav-central, body.nav-lat-on .subtabs{ display:none; }
  body.nav-lat-on .cp-miga{ display:flex; align-items:center; gap:8px; min-width:0; font-size:var(--t-texto); font-weight:500; color:var(--muted); white-space:nowrap; }
  .cp-miga b{ font-weight:500; color:var(--ink); overflow:hidden; text-overflow:ellipsis; }
  .cp-miga-sep{ color:var(--line2); }

  .nl-panel{ position:absolute; left:0; top:0; bottom:0; width:64px; display:flex; flex-direction:column; overflow:hidden;
    background:var(--deep); border-right:1px solid var(--hair);
    transition:width var(--dur-3) var(--ease-entra), box-shadow var(--dur-3) var(--ease-estado); }
  .nav-lat.abierto .nl-panel, body.nav-lat-fijo .nl-panel{ width:256px; }
  body:not(.nav-lat-fijo) .nav-lat.abierto .nl-panel{ box-shadow:0 24px 60px -18px rgba(0,0,0,.45); }
  /* Sin el logo (se movio a .cp-riel-logo, 2026-09-14) el unico hijo es el pin -- justify-content
     lo manda al borde derecho en vez de dejarlo pegado a la izquierda con un hueco vacio
     enorme. padding simetrico de 16px: en el panel COLAPSADO (64px de ancho) el pin de 32px
     queda perfecto centrado (16+32+16=64); abierto, se queda pegado al borde derecho con aire. */
  .nl-cab{ height:var(--topnav-h); flex:none; display:flex; align-items:center; justify-content:flex-end; padding:0 16px; border-bottom:1px solid var(--hair); white-space:nowrap; }
  .nl-logo{ flex:none; color:var(--ink); }
  .nl-marca{ flex:1; min-width:0; font-weight:600; letter-spacing:-.045em; font-size:20.8px; color:var(--ink); }
  .nl-pin{ flex:none; width:32px; height:32px; display:flex; align-items:center; justify-content:center; border:0; border-radius:var(--r); background:transparent; color:var(--muted); cursor:pointer; }
  .nl-pin.on{ background:var(--line2); color:var(--ink); }
@media (hover:hover){ .nl-pin:hover{ background:var(--line2); color:var(--ink); } }
  .nl-pin:focus-visible, .nl-fila:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
  .nl-cuerpo{ flex:1; min-height:0; overflow-y:auto; overflow-x:hidden; padding:10px 0; scrollbar-width:thin; }
  .nl-fila{ position:relative; display:flex; align-items:center; gap:12px; width:calc(100% - 16px); height:36px; margin:1px 8px; padding:0 8px 0 15px;
    border:0; border-radius:var(--r); background:transparent; color:var(--muted); font:inherit; font-size:var(--t-texto); font-weight:500;
    text-align:left; white-space:nowrap; cursor:pointer; transition:background var(--dur-1), color var(--dur-1); }
  .nl-fila.on{ background:var(--line2); color:var(--ink); }
@media (hover:hover){ .nl-fila:hover{ background:var(--line2); color:var(--ink); } }
  .nl-fila.sec-on{ color:var(--ink); }
  .nl-fila .ico{ flex:none; }
  .nl-lbl{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; }
  .nl-flecha{ flex:none; display:flex; color:var(--muted); transition:transform var(--dur-2) var(--ease-estado); }
  .nl-sec.plegada .nl-flecha{ transform:rotate(-90deg); }
  .nl-hijas{ display:none; }
  .nl-hija{ height:32px; padding-left:45px; }
  .nl-hija.off{ cursor:default; color:color-mix(in srgb, var(--muted) 62%, transparent); }
  @media (hover:hover){ .nl-hija.off:hover{ background:transparent; } }
  .nl-pronto{ flex:none; font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); }
  .nl-grupo{ padding:10px 0 2px 45px; font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); white-space:nowrap; }
  /* Abierto (hover, foco o pin): se ven textos, flechas y las paginas de lo desplegado. */
  .nl-marca, .nl-pin, .nl-lbl, .nl-flecha, .nl-pronto, .nl-sec-fila .nav-badge{ opacity:0; transition:opacity var(--dur-1); }
  .nav-lat.abierto :is(.nl-marca, .nl-pin, .nl-lbl, .nl-flecha, .nl-pronto, .nl-sec-fila .nav-badge),
  body.nav-lat-fijo :is(.nl-marca, .nl-pin, .nl-lbl, .nl-flecha, .nl-pronto, .nl-sec-fila .nav-badge){ opacity:1; }
  .nav-lat.abierto .nl-sec:not(.plegada) .nl-hijas, body.nav-lat-fijo .nl-sec:not(.plegada) .nl-hijas{ display:block; }
  .nl-sec-fila .nav-badge{ margin-left:auto; }
  /* Cerrado: el contador de la seccion no cabe en 64px; queda como un punto sobre el icono. */
  body:not(.nav-lat-fijo) .nav-lat:not(.abierto) .nl-sec-fila .nav-badge:not([hidden]){
    position:absolute; left:34px; top:6px; opacity:1; min-width:8px; width:8px; height:8px; padding:0; font-size:0; border-radius:50%;
    background:var(--ink); box-shadow:0 0 0 2px var(--deep);
  }
}
/* N2: Favoritos arriba, Recientes al pie, estrellas y la estrella de la barra de arriba. */
.cp-miga-caja{ display:none; }
@media (min-width:861px){
  body.nav-lat-on .cp-miga-caja{ display:flex; align-items:center; gap:4px; min-width:0; }
  .cp-fav{ flex:none; width:32px; height:32px; display:flex; align-items:center; justify-content:center; border:0; border-radius:var(--r); background:transparent; color:var(--muted); cursor:pointer; }
  .cp-fav[hidden]{ display:none; }
  @media (hover:hover){ .cp-fav:hover{ background:var(--line2); color:var(--ink); } }
  .cp-fav.llena, .nl-estrella.llena{ color:var(--ink); }
  .cp-fav.llena .ico, .nl-estrella.llena .ico{ fill:currentColor; }
  .cp-fav:focus-visible, .nl-estrella:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
  .nl-cab-grupo{ position:relative; height:28px; display:flex; align-items:center; padding:0 12px 0 23px; margin-top:6px;
    font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); white-space:nowrap; }
  .nl-cab-grupo .nl-lbl{ flex:1; }
  /* Cerrado: el titulo no cabe; queda una rayita que separa los grupos de iconos. */
  .nl-cab-grupo::before{ content:""; position:absolute; left:22px; top:50%; width:20px; height:1px; background:var(--line2); transition:opacity var(--dur-1); }
  .nav-lat.abierto .nl-cab-grupo::before, body.nav-lat-fijo .nl-cab-grupo::before{ opacity:0; }
  .nl-vacio{ display:none; padding:2px 16px 8px 23px; font-size:var(--t-meta); line-height:1.4; color:var(--muted); }
  .nav-lat.abierto .nl-vacio, body.nav-lat-fijo .nl-vacio{ display:block; }
  .nl-recientes{ flex:none; border-top:1px solid var(--hair); padding:2px 0 10px; }
  .nl-recientes:empty{ display:none; }
  .nl-extra{ display:none; }
  .nav-lat.abierto .nl-extra, body.nav-lat-fijo .nl-extra{ display:flex; }
  .nl-cuando{ flex:none; font-size:var(--t-meta); color:var(--muted); padding-right:4px; }
  .nl-estrella{ flex:none; width:28px; height:28px; margin-right:-4px; display:flex; align-items:center; justify-content:center; border:0; border-radius:var(--r); background:transparent; color:var(--muted); cursor:pointer; }
  @media (hover:hover){ .nl-estrella:hover{ background:var(--hair); color:var(--ink); } }
  @media (hover:hover){ .nl-fila:hover .nl-cuando{ display:none; } }
  /* La estrella vacia aparece al pasar por la fila; la llena se queda. Cerrado no se ve ninguna. */
  .nl-estrella, .nl-cuando{ opacity:0; transition:opacity var(--dur-1); }
  @media (hover:hover){ .nav-lat.abierto :is(.nl-fila:hover .nl-estrella, .nl-estrella.llena, .nl-estrella:focus-visible, .nl-cuando), body.nav-lat-fijo :is(.nl-fila:hover .nl-estrella, .nl-estrella.llena, .nl-estrella:focus-visible, .nl-cuando){ opacity:1; } }
}
@media (min-width:861px) and (prefers-reduced-motion: reduce){
  .nl-panel, .nl-flecha, .nl-marca, .nl-pin, .nl-lbl, .nl-pronto, .nl-estrella, .nl-cuando, .nl-cab-grupo::before{ transition:none; }
}

/* ============================================================================
   N3 · Direccion "Guijarro" con grano en los modulos (lienzo aprobado 2026-09-13).
   Superficies redondeadas que flotan sobre la pagina: el panel lateral, la caja de escribir
   del chat y el bloque del CRM. Solo escritorio con el panel activo (body.nav-lat-on): el
   telefono no cambia.
   Grano de modulos: los valores que Daniel calibro en el lienzo (intensidad .165, frecuencia
   .62, 5 octavas). La intensidad va DENTRO del ruido (feFuncA) y el ruido es una capa del
   FONDO, no un elemento encima: no tapa el texto, no necesita z-index y sigue funcionando en
   un contenedor que scrollea (.main). Solo tema oscuro, igual que el grano general de pantalla
   (body::after, .045), que se QUEDA y se suma (decision de Daniel).
   ============================================================================ */
:root{
  --guijarro:var(--paper); --guijarro-on:rgba(43,41,38,.07); --guijarro-hover:rgba(43,41,38,.045);
  --grano-modulo:none;
}
:root[data-theme="dark"]{
  --guijarro:#191917; --guijarro-on:#272624; --guijarro-hover:#211F1D;
  --grano-modulo:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.62' numOctaves='5' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='.165'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
}
/* Papel punteado en el chat (lienzo 2026-09-14): reticula de puntos de 1.1px cada 18px al 16%,
   en el tono del texto de cada tema. Solo background-image: el color de fondo lo sigue poniendo
   cada regla de .chatpane (transparente en escritorio, --deep en telefono). */
:root{ --puntos-chat:rgba(43,41,38,.04); }
:root[data-theme="dark"]{ --puntos-chat:rgba(201,198,191,.04); }
.chatpane{
  background-image:radial-gradient(circle at center, var(--puntos-chat) 1.1px, transparent 1.7px);
  background-size:18px 18px; background-position:9px 9px;
}
@media (min-width:861px){
  /* El panel es una piedra de 56px con 10px de aire alrededor (76 cerrado, 276 con pin). */
  body.nav-lat-on{ --navlat-w:76px; }
  body.nav-lat-on.nav-lat-fijo{ --navlat-w:276px; }
  body.nav-lat-on .nl-panel{
    left:10px; top:10px; bottom:10px; width:56px; border:0; border-radius:24px;
    background-color:var(--guijarro); background-image:var(--grano-modulo); background-size:220px 220px;
  }
  body.nav-lat-on.nav-lat-fijo .nl-panel, body.nav-lat-on .nav-lat.abierto .nl-panel{ width:256px; }
  body.nav-lat-on:not(.nav-lat-fijo) .nav-lat.abierto .nl-panel{ box-shadow:0 30px 60px -24px rgba(0,0,0,.6); }
  /* El panel arranca a la altura del bloque del CRM (.main), no pegado al techo: la franja de
     arriba es de la barra y, con el panel fijado, del logo (2026-09-14, pedido de Daniel). El
     abajo de 12px es el mismo margen que .main, para que los dos modulos terminen parejos. */
  body.nav-lat-on .nl-panel{ top:var(--topnav-h); bottom:12px; }
  body.nav-lat-on .nl-cab{ height:52px; padding-left:16px; border-bottom:0; }
  /* Fijado: el logo se sienta ENCIMA del panel (fixed sobre su columna) y sale del grid de la
     barra, que vuelve a miga | iconos. Cerrado (76px) no cabe la palabra: se queda en la barra. */
  body.nav-lat-on.nav-lat-fijo .cp-riel-logo{ position:fixed; left:26px; top:0; height:var(--topnav-h); display:inline-flex; align-items:center; z-index:61; }
  body.nav-lat-on.nav-lat-fijo #cp-riel.show{ grid-template-columns:1fr auto; }
  body.nav-lat-on .nl-pin, body.nav-lat-on .nl-estrella, body.nav-lat-on .cp-fav{ border-radius:50%; }
  body.nav-lat-on .nl-pin.on{ background:var(--guijarro-on); }
@media (hover:hover){ body.nav-lat-on .nl-pin:hover{ background:var(--guijarro-on); } }
  body.nav-lat-on .nl-fila{ padding-left:11px; border-radius:14px; }
  @media (hover:hover){ body.nav-lat-on .nl-fila:hover{ background:var(--guijarro-hover); } }
  body.nav-lat-on .nl-fila.on{ background:var(--guijarro-on); }
  @media (hover:hover){ body.nav-lat-on .nl-hija.off:hover{ background:transparent; } }
  body.nav-lat-on .nl-hija{ padding-left:41px; }
  body.nav-lat-on .nl-grupo{ padding-left:41px; }
  body.nav-lat-on .nl-cab-grupo{ padding-left:19px; text-transform:none; letter-spacing:0; font-size:var(--t-meta); }
  body.nav-lat-on .nl-cab-grupo::before{ left:16px; width:24px; height:4px; margin-top:-2px; border-radius:2px; background:var(--guijarro-on); }
  body.nav-lat-on .nl-recientes{ border-top:0; }
  body.nav-lat-on .nl-sec-fila .nav-badge{ border-radius:10px; min-width:20px; height:20px; line-height:20px; padding:0 6px; background:var(--guijarro-on); }
  /* Iconos organicos: un pelo mas gruesos que el 1.5 del set, como en el lienzo; lo activo lleva un relleno suave. */
  body.nav-lat-on .nl-panel .ico, body.nav-lat-on .cp-fav .ico{ stroke-width:1.7; }
  body.nav-lat-on .nl-fila.on .ico, body.nav-lat-on .nl-fila.sec-on .ico{ fill:currentColor; fill-opacity:.16; }
  body.nav-lat-on .nl-estrella.llena .ico, body.nav-lat-on .cp-fav.llena .ico{ fill-opacity:1; }

  /* La barra de arriba ya no es una franja: flota sobre la pagina, sin fondo ni borde. */
  body.nav-lat-on #cp-riel.show{ background:transparent; border-bottom-color:transparent; }
  /* Modulos: la caja de escribir del chat y el bloque del CRM. */
  body.nav-lat-on .chatpane .composer{
    border:0; border-radius:22px;
    background-color:var(--guijarro); background-image:var(--grano-modulo); background-size:220px 220px;
  }
  body.nav-lat-on #app.show .main{
    margin:0 12px 12px 0; height:calc(100% - 12px); border-radius:24px;
    background-color:var(--guijarro); background-image:var(--grano-modulo); background-size:220px 220px;
  }
}

/* ============================================================================
   TELEFONO con el menu de 4 secciones (2026-09-12, lienzo mesas 10-12): el carril deja de ser
   un cajon y se vuelve la cabecera (logo, notificaciones, engrane); las secciones bajan a la
   barra de abajo (#barra-inf) con Xarpie al centro. Va AL FINAL a proposito: le gana por orden
   a las reglas del cajon de mas arriba, que tienen la misma especificidad.
   ============================================================================ */
.barra-inf, .chat-menu-btn{ display:none; }
@media (max-width:860px){
  #cp-riel.show, .cp-riel{
    position:sticky; top:0; inset:auto; z-index:60; width:auto; height:52px; transform:none; transition:none;
    flex-direction:row; align-items:center; gap:0; padding:0 4px 0 16px;
    background:var(--deep); border-right:0; border-bottom:1px solid var(--hair); box-shadow:none;
  }
  .cp-riel .cp-nav-central, #cp-riel .cp-close{ display:none; }
  .cp-riel-logo{ display:inline-flex; padding:0; }
  .cp-riel-der{ display:flex; align-items:center; margin-left:auto; gap:0; }
  .cp-riel .cp-navcfg{ width:44px; height:44px; margin:0; padding:0; justify-content:center; }
  .cp-riel .cp-navcfg-lbl{ display:none; }
  /* La cabecera ocupa 52px en flujo: .main (el que hace scroll) mide el resto, y reserva abajo
     el alto de la barra para que la ultima fila de cualquier lista no quede debajo de ella. */
  .main{ height:calc(100vh - 52px); height:calc(100dvh - 52px); padding-bottom:calc(66px + env(safe-area-inset-bottom)); }
  .barra-inf{
    position:fixed; left:0; right:0; bottom:0; z-index:58;
    display:grid; grid-template-columns:repeat(5, minmax(0, 1fr)); align-items:center;
    padding:6px 4px calc(6px + env(safe-area-inset-bottom)); background:var(--deep); border-top:1px solid var(--hair);
  }
  /* z58: debajo del chat (70), del panel derecho (66) y de la hoja del dia (73). Con el chat
     abierto se esconde del todo: el composer toma su lugar y trae "Menu" para volver. */
  .barra-inf[hidden], body:has(.chatpane.open) .barra-inf{ display:none; }
  .bi-btn{
    position:relative; min-width:0; height:54px; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:4px;
    border:0; background:transparent; color:var(--muted); font:inherit; font-size:var(--t-eti); font-weight:500; cursor:pointer;
  }
  .bi-txt{ max-width:100%; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
  .bi-btn.on{ color:var(--ink); }
  .bi-btn:focus-visible{ outline:2px solid var(--accent); outline-offset:-2px; }
  .bi-btn .nav-badge{ position:absolute; top:4px; left:calc(50% + 6px); box-shadow:0 0 0 2px var(--deep); }
  .bi-xarpie{ width:44px; height:44px; border-radius:50%; background:var(--ink); color:var(--paper); display:flex; align-items:center; justify-content:center; }
  .chat-menu-btn{
    display:flex; flex:none; flex-direction:column; align-items:center; justify-content:center; gap:2px;
    width:52px; min-height:44px; margin-left:-8px; align-self:center; border:0; background:transparent;
    color:var(--ink); font:inherit; font-size:var(--t-eti); font-weight:500; cursor:pointer;
  }
}

/* ============================================================================
   Buscador (Cmd+K) y tarjeta de Planes de la barra (A2 del menu de 4 secciones, 2026-09-12;
   lienzo mesas 5 y 6). Tokens de siempre: nada de color nuevo, el ambar/rojo de la barra de
   IA son --yellow/--red, los mismos del medidor.
   ============================================================================ */
.modal.modal-buscador{ width:min(640px, 94vw); max-width:none; padding:0; overflow:hidden; }
.bus-campo{ display:flex; align-items:center; gap:12px; padding:14px 18px; border-bottom:1px solid var(--line2); }
.bus-campo .ico{ color:var(--muted); flex:none; }
.bus-campo input{ flex:1; min-width:0; border:0; background:transparent; color:var(--ink); font:inherit; font-size:var(--t-sub); outline:none; }
.bus-lista{ max-height:min(420px, 60vh); overflow-y:auto; padding:6px 8px; }
.bus-grupo{ padding:10px 10px 6px; font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); }
.bus-item{ display:flex; align-items:center; gap:12px; width:100%; padding:10px; border:0; border-radius:var(--r); background:transparent; color:var(--ink); font:inherit; font-size:var(--t-texto); text-align:left; cursor:pointer; }
.bus-item .ico{ color:var(--muted); flex:none; }
.bus-item.on{ background:var(--paper); }
@media (hover:hover){ .bus-item:hover{ background:var(--paper); } }
.bus-nombre{ flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.bus-meta{ flex:none; font-size:var(--t-meta); color:var(--muted); }
.bus-vacio{ padding:18px 12px; color:var(--muted); font-size:var(--t-texto); }
.bus-pie{ display:flex; justify-content:space-between; gap:12px; padding:10px 18px; border-top:1px solid var(--line2); font-size:var(--t-meta); color:var(--muted); }
.plan-panel{ width:300px; padding:16px; }
.plan-sec + .plan-sec{ margin-top:16px; }
.plan-eti{ font-size:var(--t-eti); letter-spacing:.16em; text-transform:uppercase; color:var(--muted); }
.plan-fila{ display:flex; align-items:baseline; justify-content:space-between; gap:10px; margin-top:6px; }
.plan-nombre{ font-size:var(--t-sub); }
.plan-meta{ font-size:var(--t-meta); color:var(--muted); }
.plan-barra{ height:6px; margin:8px 0 6px; border-radius:var(--r); background:var(--bone); border:1px solid var(--line2); overflow:hidden; }
.plan-barra i{ display:block; height:100%; background:var(--ink); }
.plan-barra i.alto{ background:var(--yellow); }
.plan-barra i.tope{ background:var(--red); }
.plan-panel .btn{ width:100%; margin-top:16px; }
@media (max-width:860px){
  #nav-plan-btn{ display:none !important; }
  .modal.modal-buscador{ width:100vw; }
}

/* Fase D -- acabado de Xarpen de toda la boda. Diseno aprobado: lienzo "Acabados propios (Fase D)". */

/* Visor instantaneo PR0: capa de medicion (solo con localStorage.rv_medir = "1"). */

/* "Y ahora que sigue?" -- aviso del siguiente paso del revelado (editor y pantalla del revelado). */
.rv-paso{ display:flex; gap:12px; align-items:flex-start; justify-content:space-between; flex-wrap:wrap; margin:0 0 14px; padding:12px 14px; border:1px solid var(--line2); border-radius:var(--r); background:var(--bone); }
.rv-paso.falta{ border-left:3px solid var(--ink); }
.rv-paso-cuerpo{ flex:1; min-width:240px; }
.rv-paso-tt{ font-weight:600; margin-bottom:3px; }
.rv-paso-txt{ font-size:var(--t-texto); color:var(--muted); line-height:1.45; }
.rv-paso-nota{ font-size:12px; color:var(--muted); margin-top:6px; }

/* F4 flujo Lightroom: revisar lo que igualo Xarpie. Diseno aprobado: lienzo "Flujo con Lightroom (nuevo)". */
.rv-luz-cuerpo{ display:grid; grid-template-columns:230px 1fr 320px; gap:16px; align-items:start; }
.rv-luz-momentos{ max-height:calc(100vh - 220px); overflow-y:auto; }
.rv-luz-momento{ border:1px solid var(--hair); border-radius:6px; padding:8px; margin-bottom:8px; content-visibility:auto; contain-intrinsic-size:160px; }
.rv-luz-momento.on{ border-color:var(--ink); }
.rv-luz-momento-tt{ display:flex; justify-content:space-between; font-size:12px; margin-bottom:6px; }
.rv-luz-momento .rv-ed-tiras{ grid-template-columns:repeat(4,1fr); gap:4px; }
.rv-luz-comparar{ position:absolute; left:10px; bottom:10px; background:rgba(20,19,17,.72); }
.rv-luz-aj{ display:grid; grid-template-columns:1fr auto auto auto; gap:6px; align-items:center; padding:7px 0; border-bottom:1px solid var(--hair); font-size:13px; }
.rv-luz-v{ font-family:var(--mono); font-size:12px; min-width:66px; text-align:right; }
.rv-luz-pm{ width:26px; height:24px; border:1px solid var(--line2); border-radius:4px; background:transparent; color:var(--ink); cursor:pointer; }
.rv-luz-nota{ font-size:11.5px; line-height:1.45; margin:8px 0 12px; }
/* La foto cabe entera en la ventana, vertical u horizontal (primer lote real, 2026-09-13: las verticales se
   estiraban a todo el ancho de la columna y bajaban mas alla de la pantalla). El canvas conserva su proporcion
   por sus atributos width/height; aqui solo se le pone techo de alto y se centra sobre un fondo oscuro. */
.rv-luz-cuerpo .rv-ed-canvas-box{ justify-content:center; align-items:center; background:#0b0b0a; height:calc(100vh - 230px); min-height:360px; }
.rv-luz-cuerpo .rv-ed-canvas{ width:auto; height:auto; max-width:100%; max-height:100%; }
@media (max-width:1100px){ .rv-luz-cuerpo{ grid-template-columns:1fr; } .rv-luz-momentos{ max-height:none; order:3; } }

/* ---- Guia del plugin de Lightroom en Revelado (diseno aprobado 2026-09-13, lienzo "Guia del plugin") ----
   Los dibujos de Lightroom (.rv-gl-dlg, .rv-gl-menu, .rv-gl-finder) usan los grises de macOS/Lightroom a
   proposito, no los tokens: tienen que parecerse a la ventana que el fotografo va a buscar. */
.rv-gl{ border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); margin:0 0 28px; }
.rv-gl-head{ display:flex; justify-content:space-between; align-items:center; gap:12px; padding:16px 20px; border-bottom:1px solid var(--hair); }
.rv-gl-tt{ font-size:var(--t-sub); color:var(--ink); }
.rv-gl-barra{ width:220px; max-width:100%; height:4px; background:var(--line2); border-radius:2px; overflow:hidden; margin-top:8px; }
.rv-gl-barra i{ display:block; height:100%; background:var(--ink); }
.rv-gl-aviso{ font-size:var(--t-meta); color:var(--muted); line-height:1.45; }
.rv-gl-cuerpo{ display:grid; grid-template-columns:300px 1fr; }
.rv-gl-pasos{ border-right:1px solid var(--hair); padding:10px 0; }
.rv-gl-grupo{ font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); padding:12px 20px 4px; }
.rv-gl-p{ display:grid; grid-template-columns:26px 1fr; gap:10px; padding:10px 20px; font-size:var(--t-texto); align-items:start; width:100%; text-align:left; background:none; border:0; border-left:2px solid transparent; color:var(--ink); cursor:pointer; }
@media (hover:hover){ .rv-gl-p:hover{ background:var(--deep); } }
.rv-gl-p .n{ width:22px; height:22px; border-radius:50%; border:1px solid var(--line2); display:grid; place-items:center; font-size:11px; color:var(--muted); }
.rv-gl-p.hecho .n{ background:var(--blue); border-color:var(--blue); color:#fff; }
.rv-gl-p.hecho .t{ color:var(--muted); text-decoration:line-through; }
.rv-gl-p.on{ background:var(--deep); border-left-color:var(--ink); }
.rv-gl-p.on .n{ border-color:var(--ink); color:var(--ink); }
.rv-gl-p .d{ font-size:var(--t-meta); color:var(--muted); margin-top:2px; }
.rv-gl-det{ padding:22px 26px; min-width:0; }
.rv-gl-det-tt{ font-size:var(--t-titulo); color:var(--ink); margin-bottom:6px; }
.rv-gl-det-txt{ font-size:var(--t-texto); color:var(--muted); line-height:1.55; max-width:680px; }
.rv-gl-dos{ display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:22px; margin-top:20px; align-items:start; }
.rv-gl-num{ font-size:13px; line-height:1.6; margin:0; padding-left:18px; }
.rv-gl-num li{ margin-bottom:6px; }
.rv-gl-codigo{ display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin:18px 0 8px; }
.rv-gl-codigo code{ font-family:ui-monospace,Menlo,monospace; font-size:14px; background:var(--bone); border:1px solid var(--line2); border-radius:var(--r); padding:10px 14px; color:var(--ink); word-break:break-all; user-select:all; }
.rv-gl-fila-acc{ display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin-top:16px; }
.rv-gl-ilus{ border:1px solid var(--line2); border-radius:6px; background:#2b2b2b; padding:14px; overflow-x:auto; }
.rv-gl-cap{ font-size:11px; color:#a8a8a8; margin-top:8px; }
.rv-gl-ilus-fila{ display:flex; flex-wrap:wrap; gap:14px; align-items:flex-start; }
.rv-gl-marca{ display:inline-block; background:#C79A4E; color:#111; font-size:11px; font-weight:600; padding:2px 8px; border-radius:10px; margin-left:6px; white-space:nowrap; font-family:var(--sans); vertical-align:middle; }
.rv-gl-mac{ font-family:-apple-system,BlinkMacSystemFont,"Helvetica Neue",Arial,sans-serif; font-size:12px; }
.rv-gl-dlg{ background:#ececec; border-radius:8px; color:#1d1d1f; overflow:hidden; box-shadow:0 12px 30px rgba(0,0,0,.5); min-width:260px; }
.rv-gl-dlg-bar{ height:24px; background:#e1e1e1; border-bottom:1px solid #cfcfcf; display:flex; align-items:center; justify-content:center; font-weight:600; position:relative; padding:0 50px; white-space:nowrap; }
.rv-gl-dlg-bar i{ position:absolute; left:9px; top:7px; width:10px; height:10px; border-radius:50%; background:#fe5f57; box-shadow:15px 0 0 #febc2e, 30px 0 0 #28c840; }
.rv-gl-dlg-cuerpo{ padding:10px 14px; line-height:1.5; }
.rv-gl-dlg-pie{ display:flex; justify-content:flex-end; gap:8px; padding:0 14px 12px; }
.rv-gl-b{ border-radius:5px; padding:2px 12px; border:1px solid #c2c2c2; background:#fff; }
.rv-gl-b.p{ background:#2f7cf6; border-color:#2f7cf6; color:#fff; }
.rv-gl-campo-fila{ display:grid; grid-template-columns:110px auto; gap:8px; align-items:center; margin-top:6px; }
.rv-gl-campo{ background:#fff; border:1px solid #c7c7c7; border-radius:4px; padding:3px 8px; display:inline-flex; justify-content:space-between; gap:12px; }
.rv-gl-campo.foco{ outline:3px solid rgba(47,124,246,.45); border-color:#2f7cf6; }
.rv-gl-menu{ min-width:250px; background:#3c3c3c; border:1px solid #1e1e1e; border-radius:8px; padding:6px 0; color:#e6e6e6; box-shadow:0 10px 30px rgba(0,0,0,.45); }
.rv-gl-menu div{ padding:4px 14px; display:flex; justify-content:space-between; gap:18px; }
.rv-gl-menu .sep{ height:1px; background:#555; margin:5px 0; padding:0; }
.rv-gl-menu .on{ background:#2f6fde; color:#fff; border-radius:4px; margin:0 5px; padding:4px 9px; }
.rv-gl-menu .gris{ color:#9a9a9a; }
.rv-gl-finder{ background:#f5f5f5; border-radius:8px; overflow:hidden; color:#1d1d1f; box-shadow:0 12px 30px rgba(0,0,0,.5); }
.rv-gl-finder .fila{ display:flex; gap:8px; align-items:center; padding:5px 12px; }
.rv-gl-finder .fila.on{ background:#2f7cf6; color:#fff; }
.rv-gl-finder .ico{ width:16px; height:13px; background:#7fb1f5; border-radius:2px; flex:0 0 auto; }
.rv-gl-finder .ico.zip{ background:#bdbdbd; }
.rv-gl-pm{ display:grid; grid-template-columns:200px 1fr; min-height:180px; }
.rv-gl-pm-lista{ border-right:1px solid #cfcfcf; background:#fff; display:flex; flex-direction:column; }
.rv-gl-pm-lista .it{ padding:7px 10px; display:flex; gap:8px; border-bottom:1px solid #eee; }
.rv-gl-pm-lista .it.on{ background:#dce8fd; }
.rv-gl-pm-lista small{ color:#777; }
.rv-gl-pm-lista .punto{ width:9px; height:9px; border-radius:50%; background:#28c840; margin-top:3px; flex:0 0 auto; }
.rv-gl-pm-lista .bot{ margin-top:auto; display:flex; flex-wrap:wrap; gap:6px; align-items:center; padding:8px; border-top:1px solid #ddd; }
.rv-gl-pm-det{ padding:10px 12px; line-height:1.6; }
.rv-gl-mini{ background:var(--bone); border:1px solid var(--line2); border-radius:6px; padding:12px; }
.rv-gl-mini-foto{ height:110px; border-radius:4px; background:linear-gradient(135deg,#7a6247 0%,#9c8363 55%,#6a5540 100%); margin-top:8px; }
.rv-gl-bar{ display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:10px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); padding:10px 16px; margin-bottom:14px; font-size:13px; }
.rv-gl-punto{ display:inline-block; width:8px; height:8px; border-radius:50%; background:var(--blue); margin-right:8px; }
.rv-gl-punto.no{ background:var(--line2); }
.rv-gl-panel{ border:1px solid var(--line2); border-radius:6px; background:var(--paper); margin:0 0 24px; max-width:560px; margin-left:auto; }
.rv-gl-panel-head{ display:flex; justify-content:space-between; align-items:center; padding:12px 18px; border-bottom:1px solid var(--hair); }
.rv-gl-sec{ padding:14px 18px; border-bottom:1px solid var(--hair); font-size:13px; }
.rv-gl-sec:last-child{ border-bottom:0; }
.rv-gl-sec-tt{ font-size:var(--t-eti); letter-spacing:.08em; text-transform:uppercase; color:var(--muted); margin-bottom:8px; }
.rv-gl-kv{ display:grid; grid-template-columns:140px 1fr; gap:4px 10px; }
.rv-gl-kv > span:nth-child(odd){ color:var(--muted); }
.rv-gl-acc{ display:flex; flex-wrap:wrap; justify-content:space-between; align-items:center; gap:8px; padding:6px 0; }
.rv-gl-link{ background:none; border:0; padding:4px 0; color:var(--ink); text-decoration:underline; text-decoration-color:var(--line2); cursor:pointer; font:inherit; text-align:left; }
.rv-gl-sec details{ padding:6px 0; }
.rv-gl-sec summary{ cursor:pointer; }
.rv-gl-sec details p{ margin:6px 0 0; color:var(--muted); line-height:1.5; }
@media (max-width: 860px){
  .rv-gl-cuerpo, .rv-gl-dos{ grid-template-columns:1fr; }
  .rv-gl-pasos{ border-right:0; border-bottom:1px solid var(--hair); }
  .rv-gl-pm{ grid-template-columns:1fr; }
}

/* ============================================================================
   PORTALES (lienzo "Portales del estudio", aprobado 2026-09-14): la grilla de un
   cliente por tarjeta. Guijarro como el panel: tarjeta radio 22, foto radio 17 con
   6px de aire, sin montos. En telefono cada tarjeta se vuelve una fila (foto 74px a
   la izquierda), igual que el lienzo de telefono.
   ============================================================================ */
.portales .por-toolbar{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; margin:4px 0 16px; }
.por-grilla{ display:grid; grid-template-columns:repeat(auto-fill, minmax(240px, 1fr)); gap:14px; }
.por-card{ position:relative; border-radius:22px; background:var(--guijarro-hover); padding:6px; cursor:pointer; transition:background .14s ease; }
.por-card:focus-visible{ background:var(--guijarro-on); outline:none; }
@media (hover:hover){ .por-card:hover{ background:var(--guijarro-on); outline:none; } }
.por-foto{ height:132px; border-radius:17px; background-color:var(--line2); background-size:cover; background-position:center; }
.por-foto.sin{ display:flex; align-items:center; justify-content:center; font-size:26px; color:var(--muted);
  background-image:radial-gradient(circle at center, var(--puntos-chat) 1.1px, transparent 1.7px); background-size:14px 14px; }
.por-cuerpo{ padding:11px 10px 8px; min-width:0; }
.por-nombre{ font-size:16px; font-weight:500; color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.por-sub{ font-size:12px; color:var(--muted); margin-top:3px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.por-sigue{ display:flex; align-items:center; gap:8px; margin-top:10px; font-size:13px; color:var(--ink); min-width:0; }
.por-sigue span:last-child{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
.por-tono{ display:inline-block; width:7px; height:7px; border-radius:50%; flex:none; }
.por-tono.urge{ background:#D97757; }
.por-tono.espera{ background:var(--muted); }
.por-tono.calma{ box-shadow:inset 0 0 0 1.5px var(--line2); }
.fchip .por-tono{ margin-right:7px; vertical-align:1px; }
/* Etiqueta y boton sobre la foto: fondo oscuro translucido en los dos temas (van sobre una foto). */
.por-etq{ position:absolute; left:14px; top:14px; font-size:11px; font-weight:500; color:#F3F1EA; background:rgba(15,15,14,.66); padding:3px 9px; border-radius:10px; }
.por-etq-in{ display:none; }
.por-mas{ position:absolute; right:14px; top:14px; width:30px; height:30px; border-radius:50%; border:0; display:flex; align-items:center; justify-content:center; color:#F3F1EA; background:rgba(15,15,14,.66); opacity:0; cursor:pointer; transition:opacity .12s ease; }
.por-mas:focus-visible{ opacity:1; }
@media (hover:hover){ .por-card:hover .por-mas{ opacity:1; } }
@media (hover:none){ .por-mas{ opacity:1; } }
.por-leyenda{ margin-top:18px; font-size:12px; color:var(--muted); }
.por-fotos{ display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:8px; margin:14px 0; max-height:360px; overflow:auto; }
.por-op{ height:92px; border-radius:14px; border:0; background-color:var(--line2); background-size:cover; background-position:center; cursor:pointer; }
@media (hover:hover){ .por-op:hover{ box-shadow:inset 0 0 0 2px var(--muted); } }
.por-op.on{ box-shadow:inset 0 0 0 3px var(--ink); }
.por-img-pie{ display:flex; justify-content:flex-end; gap:10px; flex-wrap:wrap; margin-top:14px; }
@media (max-width: 860px){
  .por-grilla{ grid-template-columns:1fr; gap:8px; }
  .por-card{ display:grid; grid-template-columns:74px minmax(0, 1fr); gap:12px; align-items:center; border-radius:20px; }
  .por-foto{ width:74px; height:74px; border-radius:15px; }
  .por-foto.sin{ font-size:20px; background-size:12px 12px; }
  .por-cuerpo{ padding:0 40px 0 0; }
  .por-sigue{ margin-top:6px; }
  .por-etq{ display:none; }
  .por-etq-in{ display:inline-block; margin-left:6px; font-size:10px; font-weight:600; color:var(--ink); background:var(--line2); padding:1px 7px; border-radius:8px; vertical-align:2px; }
  .por-mas{ top:50%; right:8px; transform:translateY(-50%); opacity:1; background:transparent; color:var(--muted); }
}

/* PORTALES P2: el portal por dentro (#/portales/:id). Reusa la ficha de cliente y la de boda;
   aqui solo la cabecera con la foto a la izquierda y los trabajos como capitulos. */
/* El ancho que manda es el del CRM, no el de la ventana: con el chat abierto el portal puede
   quedar angosto en una pantalla grande. Por eso la cabecera se apila con un container query
   (foto arriba a lo ancho) y no con @media. */
.ficha-portal{ container-type:inline-size; }
.ficha-portal .por-hero{ display:grid; grid-template-columns:280px minmax(0, 1fr); gap:22px; align-items:stretch; margin-bottom:8px; }
@container (max-width: 680px){
  .ficha-portal .por-hero{ grid-template-columns:1fr; gap:14px; }
  .ficha-portal .por-hero-foto{ min-height:180px; }
}
.por-hero-foto{ position:relative; min-height:170px; border-radius:22px; background-color:var(--line2); background-size:cover; background-position:center; }
.por-hero-foto.sin{ display:flex; align-items:center; justify-content:center; font-size:40px; color:var(--muted);
  background-image:radial-gradient(circle at center, var(--puntos-chat) 1.1px, transparent 1.7px); background-size:16px 16px; }
.por-hero-cambiar{ position:absolute; left:10px; bottom:10px; display:flex; align-items:center; gap:6px; border:0; cursor:pointer; font:inherit; font-size:12px; font-weight:500; color:#F3F1EA; background:rgba(15,15,14,.66); padding:7px 11px; border-radius:14px; }
.por-hero-der{ min-width:0; display:flex; flex-direction:column; justify-content:space-between; gap:10px; }
/* La foto grande ya es la identidad: el avatar redondo y el papel decorativo de la ficha de
   cliente sobran aqui. */
.ficha-portal .ficha-avatar{ display:none; }
/* La textura de .fondo vive en ::before/::after (public/fondos.css), no en background-image. */
.ficha-portal .fc-hero.fondo{ background-color:transparent; }
.ficha-portal .fc-hero.fondo::before, .ficha-portal .fc-hero.fondo::after{ display:none; }
.ficha-portal .fc-hero .fb-hero-velo{ display:none; }
.por-hero-acc{ display:flex; gap:8px; flex-wrap:wrap; }
/* PORTALES P5 (2026-09-18): la ficha de boda se fundio en el portal. Encabezado del trabajo elegido,
   barra de secciones pegada, aviso de "sin cliente" y pendientes juntos. Solo tokens del sistema. */
.por-cab{ display:flex; align-items:flex-start; gap:24px; padding:26px 0 6px; }
.por-cab-txt{ flex:1; min-width:0; }
.por-cab-t{ margin:0; font-size:var(--t-titulo); font-weight:500; letter-spacing:-.02em; line-height:1.15; color:var(--ink); }
.por-cab-sub{ margin-top:6px; font-size:var(--t-texto); color:var(--muted); }
.por-cab-chips{ display:flex; align-items:center; flex-wrap:wrap; gap:12px; margin-top:12px; }
.por-cab .fb-cuenta{ flex:none; margin:0; }
.por-cab-mas{ flex:none; }
/* Se pega el CONTENEDOR (#por-nav), no la barra: un sticky no sale de la caja de su padre. */
.ficha-portal #por-nav{ position:sticky; top:var(--por-off, 0px); z-index:var(--z-pegajoso); background:var(--pag); }
/* .wrap declara overflow-x:auto y eso vuelve a #view un contenedor de scroll (el eje y se vuelve auto):
   nunca scrollea (crece con su contenido) pero le roba el sticky a la barra, que se ata a el y no a
   .main, que es quien de verdad hace scroll. Con clip no hay contenedor de scroll y el sticky sube a .main. */
#view:has(> .ficha-portal){ overflow-x:clip; overflow-y:visible; }
/* Las pestanas del portal son `Piezas.pestanas` (piezas.css): aqui solo queda que la barra se
   pegue y que las secciones de OTRA pestana no se vean. Se esconden, no se desmontan: el
   movimiento de Xarpie necesita poder encontrar su ancla para saltar a su pestana. */
.por-tabs{ min-height:44px; display:flex; align-items:flex-end; }
.ficha-portal .fsec.por-oculta{ display:none; }
/* Al saltar a una seccion, el titulo no debe quedar debajo de la barra pegada. */
.ficha-portal .fsec{ scroll-margin-top:calc(var(--por-off, 0px) + 56px); }
/* En telefono la barra de secciones ya es la franja de arriba: la mini-cabecera de la ficha sobra. */
.ficha-portal .ficha-mini{ display:none !important; }
@media (max-width: 860px){
  .por-cab{ gap:14px; }

}
/* WhatsApp llevaba texto blanco fijo sobre un fondo claro en tema claro (casi ilegible): en el portal es la
   accion principal del cliente y usa el par de boton principal del sistema. */
/* (.btn-wa fija su color con !important y :root[data-theme] .btn le gana el fondo: hace falta el mismo peso.) */
:root[data-theme] .ficha-portal .btn-wa{ background:var(--boton); color:var(--boton-t) !important; }
.por-aviso{ display:flex; align-items:center; flex-wrap:wrap; gap:12px; padding:4px 0; font-size:var(--t-texto); color:var(--muted); }
.por-pend-lab{ padding:6px 0 0; font-size:var(--t-meta); color:var(--muted); }
.por-pend-cli{ margin-top:10px; }
.por-trabs{ display:flex; flex-wrap:wrap; gap:6px; }
.por-trab{ display:flex; flex-direction:column; align-items:flex-start; gap:1px; padding:8px 14px; border:0; border-radius:16px; background:var(--guijarro-hover); cursor:pointer; text-align:left; font:inherit; color:var(--ink); }
@media (hover:hover){ .por-trab:hover{ background:var(--guijarro-on); } }
.por-trab-t{ font-size:13px; font-weight:500; }
.por-trab-e{ font-size:11px; color:var(--muted); }
.por-trab.on{ background:var(--ink); color:var(--paper); }
.por-trab.on .por-trab-e{ color:var(--paper); opacity:.7; }
.por-trab.cancelado{ opacity:.55; }
.por-trab.nuevo{ justify-content:center; color:var(--muted); box-shadow:inset 0 0 0 1px var(--line2); background:transparent; font-size:13px; }
@media (max-width: 860px){
  .ficha-portal .por-hero{ grid-template-columns:1fr; }
  .por-hero-foto{ min-height:180px; }
  .por-trabs{ flex-wrap:nowrap; overflow-x:auto; margin:0 -16px; padding:0 16px 4px; scrollbar-width:none; }
  .por-trab{ flex:none; }
}
/* Trabajos agrupados por ano (clientes con muchos, como un corporativo). */
.por-anio{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.por-anio + .por-anio{ margin-top:8px; }
.por-anio-t{ font-size:12px; color:var(--muted); width:40px; flex:none; }
.por-trab.ver{ justify-content:center; background:transparent; box-shadow:inset 0 0 0 1px var(--line2); color:var(--muted); font-size:13px; }
/* Lo que ya hizo tu cliente / lo que todavia no ve / proyectos. */
.por-hizo{ display:flex; flex-wrap:wrap; gap:8px; }
.por-hz{ display:flex; align-items:center; gap:8px; padding:8px 12px 8px 10px; border-radius:15px; background:var(--guijarro-hover); font-size:13px; color:var(--ink); }
.por-hz .por-hz-f{ font-size:11px; color:var(--muted); }
.por-nove{ display:flex; align-items:center; gap:12px; padding:10px 0; border-bottom:1px solid var(--hair); font-size:14px; color:var(--ink); }
.por-nove:last-child{ border-bottom:0; }
.por-nove .por-tono{ margin:0 4px; }
.por-nove-t{ flex:1; min-width:0; line-height:1.45; }
.por-proy{ display:flex; align-items:center; gap:12px; padding:10px 0; border-bottom:1px solid var(--hair); font-size:14px; color:var(--ink); text-decoration:none; }
.por-proy:last-child{ border-bottom:0; }
@media (hover:hover){ .por-proy:hover .por-proy-n{ text-decoration:underline; } }
.por-proy-n{ flex:1; min-width:0; }
.por-proy-f{ font-size:12px; color:var(--muted); white-space:nowrap; }

/* ============================================================================
   XARPIE SIEMPRE ABAJO (escritorio, 2026-09-14, lienzo "Xarpie siempre abajo")
   Tres estados en #app: xa-barra (la caja flota sobre el bloque del CRM, con bruma),
   xa-media (hoja de vidrio a media pantalla, el CRM de arriba sigue usable) y xa-completa
   (Xarpie a pantalla completa = el crm-colapsado de siempre, en flujo). Va AL FINAL: le gana
   por orden a las reglas de columna de .chatpane con la misma especificidad. Telefono no
   usa nada de esto (las clases ni se ponen, ver ponerXa en app.js).
   ============================================================================ */
.xa-agarre, .xa-asomo, #xa-completa-btn, .xa-bruma{ display:none; }
/* T7 de Cuarto Oscuro (2026-09-16): aqui vivia el bloque de ESCRITORIO de "Xarpie siempre abajo"
   (@media min-width:861px, ~100 lineas). Quedo inerte desde dep-699, cuando el escritorio regreso a
   columnas y xaEscritorio() empezo a devolver xaTelefono(): ninguna de sus clases se pone ya en
   escritorio. Lo que sigue abajo SI aplica, porque el telefono usa los mismos estados xa-*. */

/* La conversacion tambien se desvanece arriba (2026-09-15): el texto que sube con el scroll se
   pierde en el fondo en vez de cortarse en seco debajo de la agarradera. Escritorio y telefono. */
#app.xa-media .chatpane > .chatscroll, #app.xa-completa .chatpane > .chatscroll{
  padding-top:36px;
  -webkit-mask-image:linear-gradient(to bottom, transparent 0, rgba(0,0,0,.35) 18px, #000 56px);
  mask-image:linear-gradient(to bottom, transparent 0, rgba(0,0,0,.35) 18px, #000 56px);
}

/* Las sugerencias quedaban de ~4px y cortadas (2026-09-15): con la hoja a la medida de la respuesta
   (max-height) el flex encogia TODOS los hijos, no solo la conversacion. Solo la conversacion se
   encoge; sugerencias, Viendo, adjuntos y la caja conservan su alto. Las sugerencias se deslizan
   de lado si no caben. */
#app.xa-media .chatpane > .chips, #app.xa-completa .chatpane > .chips,
#app.xa-media .chatpane > .chat-viendo, #app.xa-media .chatpane > .attach-prev,
#app.xa-media .chatpane > .xa-agarre, #app.xa-media .chatpane > .composer{ flex-shrink:0; }
#app.xa-media .chatpane > .chips, #app.xa-completa .chatpane > .chips{
  flex-wrap:nowrap; overflow-x:auto; overflow-y:hidden; scrollbar-width:none; min-height:max-content;
}

/* Sugerencias fuera al hacer scroll o al escribir (app.js pone #app.xa-sin-tips). */
#app.xa-sin-tips .chatpane > .chips{ display:none !important; }

/* ================= LISTA UNIFICADA DE ENTREGAS (#/galerias) =================
   La tarjeta, la portada, el menu y los chips son los que YA existen (.gal-card,
   .gal-cover, .sc-salamenu, .fchip): aqui solo lo que no tenia clase todavia -- el conteo
   dentro del chip, la fila de piezas de cada boda, el aviso de ruta movida y las opciones
   del panel de "que vas a entregar". Nada de esto toca selectores compartidos. */
.ent-chip-n{ margin-left:7px; opacity:.65; font-variant-numeric:tabular-nums; }
/* Las piezas van FUERA del boton que abre la tarjeta (un boton dentro de otro no es HTML
   valido, la misma razon por la que .gal-acc existe aparte en la lista de galerias). */
.ent-piezas{ display:flex; flex-wrap:wrap; gap:6px; margin-top:9px; padding:0 2px; }
.ent-pieza{ display:inline-flex; align-items:center; gap:6px; padding:4px 9px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); font:inherit; font-size:var(--t-meta); cursor:pointer; }
@media (hover:hover){ .ent-pieza:hover{ border-color:var(--accent); } }
.ent-dot{ width:6px; height:6px; border-radius:50%; flex:none; }
.ent-dot-si{ background:var(--blue); }
.ent-dot-no{ background:var(--line2); border:1px solid var(--muted); }
.ent-aviso{ display:flex; align-items:center; gap:12px; padding:11px 14px; margin:0 0 18px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); font-size:var(--t-texto); }
.ent-aviso > span{ flex:1; min-width:0; }
.ent-aviso-ro{ color:var(--muted); }
.ent-aviso-ro .ico{ vertical-align:-2px; }
/* El filtro que puso un KPI ("Entregadas sin abrir"): se quita desde el mismo texto que
   dice que esta puesto, para que no quede un filtro invisible que nadie sabe apagar. */
.ent-quitar{ border:0; background:transparent; padding:0; font:inherit; font-size:12px; color:var(--red); cursor:pointer; text-decoration:underline; }
.ent-quitar .ico{ vertical-align:-1px; }
.ent-opts{ display:flex; flex-direction:column; gap:10px; }
.ent-opt{ display:flex; align-items:flex-start; gap:12px; width:100%; text-align:left; padding:14px 15px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); font:inherit; cursor:pointer; }
@media (hover:hover){ .ent-opt:hover{ border-color:var(--accent); } }
.ent-opt-off{ opacity:.55; cursor:default; }
@media (hover:hover){ .ent-opt-off:hover{ border-color:var(--line2); } }
.ent-opt-ico{ flex:none; color:var(--muted); line-height:0; padding-top:2px; }
.ent-opt-txt{ display:flex; flex-direction:column; gap:3px; min-width:0; }
.ent-opt-t{ font-size:var(--t-texto); font-weight:600; }
.ent-opt-s{ font-size:var(--t-meta); color:var(--muted); line-height:1.45; }

/* ================= EDITOR-UNIFICADO (public/entrega-editor.js) =================
   El cascaron compartido de los editores de entrega: hoy Video (#/sala/:id), despues Fotos y
   la Puerta. Solo selectores .edg / .ge-unificado: NUNCA tocar desde aqui las bases
   `.ge-embebido .ge-rail`, que comparten el editor de galeria y el del portal (ver el aviso
   "asumir DOS consumidores" en el bloque del riel). */

/* 1. A alto fijo, como .ced y el editor del portal: la vista previa y el riel scrollean por dentro.
   container-type en #view (el ANCESTRO real) y no en el editor: una container query no puede
   estilizar a su propio contenedor. El padding-bottom de la barra de Xarpie
   (#app.xa-barra #view) le gana por especificidad al padding:0 de aqui -- una sola reserva,
   en el host, que es la leccion ya escrita junto a esa regla. */
.main > #view:has(> .edg){ container-type:inline-size; max-width:none; padding:0; overflow:hidden; display:flex; flex-direction:column; flex:1 1 auto; min-height:0; }
.main:has(> #view > .edg){ overflow:hidden; }

/* 2. SIEMPRE oscuro (decision 4 del plan), tambien con el CRM en claro. Se redefinen los MISMOS
   tokens del bloque :root[data-theme="dark"] sobre el subarbol, asi que todo lo que ya pinta
   con variables sale oscuro solo. Lo que tenia color fijo por tema se repite abajo. Los
   modales que abre el editor viven fuera de .edg y siguen el tema del CRM, a proposito. */
.edg{
  color-scheme:dark;
  --bone:#0F0F0E; --paper:#171716; --deep:#141413;
  --ink:#C9C6BF; --muted:#A6A39C; --hair:#1E1E1C; --line2:#2A2A28;
  --red:#D97757; --accent:#C9C6BF; --accent-solido:#2A2A28; --accent-tinta:#C9C6BF;
  --tint:rgba(201,198,191,.06); --ok:#93a986; --blue:#8fb0d4; --yellow:#cfa15e; --gold:#cfa15e;
  display:flex; flex-direction:column; flex:1 1 auto; min-height:0; min-width:0;
  background:var(--bone); color:var(--ink);
}
.edg .inp, .edg .sel, .edg .ta{ background:#262624; border-color:var(--line2); color:var(--ink); }
.edg .inp:focus, .edg .sel:focus, .edg .ta:focus{ background:#2C2C2A; }
@media (hover:hover){ .edg .btn:hover{ background:#3A3A37; color:var(--ink); } }
@media (hover:hover){ .edg .x:hover, .edg .um-item:hover{ background:#3A3A37; } }
.edg .pill-red{ background:#3A2A25; color:#E9A385; }
.edg .pill-blue{ background:#29332C; color:#A7C199; }
.edg .pill-yellow{ background:#33311F; color:#E0C589; }
.edg .pill-ink{ background:#34342F; color:#B8B7AF; }
.edg .gset .ge-sw2, .edg .sc-check input[type="checkbox"]{ background:rgba(240,236,228,.18); }
.edg .ge-embebido .ge-rail{
  --ge-bg:#1a1a1a; --ge-ink:#ededed; --ge-ink2:#8a8a8a; --ge-ink3:#8f8f8f;
  --ge-line:rgba(255,255,255,.1); --ge-line2:rgba(255,255,255,.06);
  --ge-prev:#242424; --ge-focus:rgba(255,255,255,.45); --ge-warn:#e0a878; --ge-ink2-caja:#949494;
}

/* 3. Cabecera, pestanas y cuerpo. */
.edg-cab{ flex:none; display:flex; align-items:flex-end; justify-content:space-between; gap:16px 24px; flex-wrap:wrap; padding:22px 32px 0; }
.edg-cab-izq{ min-width:0; }
.edg-volver{ display:inline-flex; align-items:center; gap:6px; border:0; background:none; padding:0; font:inherit; font-size:var(--t-texto); color:var(--muted); cursor:pointer; }
@media (hover:hover){ .edg-volver:hover{ color:var(--ink); } }
.edg-volver svg{ transform:rotate(180deg); }
.edg-titulo{ margin:6px 0 0; overflow-wrap:anywhere; }
.edg-meta{ font-size:var(--t-meta); color:var(--muted); margin-top:6px; }
.edg-pub{ color:var(--blue); }
.edg-guardado:empty{ display:none; }
.edg-guardado::before{ content:"·\00a0"; }
.edg-g-error{ color:var(--red); }
.edg-cab-der{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.edg-min{ width:190px; margin-right:6px; }
.edg-min-fila{ display:flex; justify-content:space-between; gap:8px; font-size:var(--t-meta); color:var(--muted); }
.edg-min-fila span{ min-width:0; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.edg-min-fila b{ font-weight:500; color:var(--ink); white-space:nowrap; }
.edg-min-barra{ height:4px; border-radius:var(--r); background:var(--line2); margin-top:6px; overflow:hidden; }
.edg-min-barra i{ display:block; height:100%; background:var(--ink); }
.edg-aviso{ flex:none; margin:14px 32px 0; max-width:none; }
.edg-tabs{ flex:none; padding:16px 32px 14px; }
.edg-tabs .seg{ margin:0; max-width:100%; overflow-x:auto; scrollbar-width:none; }
.edg-cuerpo{ flex:1 1 auto; min-height:0; overflow:auto; border-top:1px solid var(--hair); padding:20px 32px 32px; }
.edg-cuerpo:has(> .ge-unificado){ padding:0; overflow:hidden; display:flex; }

/* 4. El lienzo de Diseno: vista previa a la IZQUIERDA (primera en el DOM), riel de 400px a la
   derecha, cada uno con su scroll. */
.sc-diseno.ge-unificado{ display:flex; flex:1 1 auto; min-width:0; min-height:0; gap:0; align-items:stretch; }
.ge-unificado .sc-diseno-prev{ position:static; flex:1 1 auto; min-width:0; min-height:0; display:flex; flex-direction:column; }
.ge-unificado .sc-prev-canvas{ flex:1 1 auto; min-height:0; border-radius:0; padding:14px 20px; gap:12px; }
.ge-unificado .sc-prev-stage{ align-items:flex-start; overflow:hidden; }
/* La caja la dimensiona EntregaEditor.encajar en px: fuera anchos al 100% y aspect-ratio. */
.ge-unificado .sc-prev-caja, .ge-unificado .sc-prev-caja[data-modo]{ width:auto; max-width:none; height:auto; aspect-ratio:auto; margin:0 auto; }
.edg-dims{ font-size:var(--t-eti); letter-spacing:.12em; text-transform:uppercase; color:rgba(243,239,232,.5); font-variant-numeric:tabular-nums; white-space:nowrap; }
.ge-unificado .edg-prev-nota{ flex:none; margin:0; color:rgba(243,239,232,.5); }
.ge-unificado .ge-rail{ width:400px; flex:none; height:auto; max-height:none; min-height:0; display:flex; flex-direction:column; background:var(--ge-bg); border-right:0; border-left:1px solid var(--ge-line2); }
.ge-unificado .ge-nav{ padding:12px 24px; }
.ge-unificado .ge-railscroll{ flex:1 1 auto; min-height:0; overflow:auto; padding:0 24px 48px; }
/* Los dos botones de la vista previa son SOLO de telefono (se encienden en el @container de
   abajo). `:root[data-theme] .btn{display:inline-flex}` de cuarto-oscuro.css (0-3-0, y ese
   archivo carga al final) le ganaba a `.edg-abrir-prev` (0-1-0) y salian tambien en escritorio:
   "Volver a editar" flotando sobre la vista previa de Video y de la Puerta, y "Volver a la boda"
   sobre la rejilla de plantillas al crear, sin nada que hacer ahi. `.btn` en el selector es lo
   que empata la especificidad (0-4-0); el encendido de abajo usa el MISMO selector y gana por
   venir despues, y el de cerrar suma .edg-prev-abierta. */
.edg .ge-unificado .btn.edg-abrir-prev, .edg .ge-unificado .btn.edg-cerrar-prev{ display:none; }

/* 4b. El lienzo de Diseno de FOTOS (pintarDisenoGaleria, app.js): .geditor.ge-embebido con el
   mismo modificador. Su marcado no se movio (riel primero en el DOM, ~30 funciones lo leen
   por id), asi que la vista previa pasa a la izquierda con `order`. Los tokens del editor de
   galeria (--ge-bg/--ge-canvas/--ge-ink...) se fijan al valor OSCURO, igual que el resto de
   .edg: con el CRM en claro, .geditor los pintaba claros. */
.edg .geditor{ --ge-bg:#232220; --ge-canvas:#161513; --ge-ink:#f0ece4; --ge-ink2:#a49c90; --ge-ink3:#6f675c; --ge-line:rgba(240,236,228,.14); --ge-line2:rgba(240,236,228,.07); }
.geditor.ge-unificado{ flex:1 1 auto; min-width:0; min-height:0; height:auto; }
.geditor.ge-unificado > .ge-canvas{ order:-1; flex:1 1 auto; min-width:0; min-height:0; height:auto; }
.ge-unificado .ge-stagewrap{ align-items:flex-start; overflow:hidden; }
/* La caja la dimensiona EntregaEditor.encajar en px; fuera los topes de ancho por dispositivo
   y el bisel de 12px del telefono (Video no lo tiene, y los dos tienen que verse igual). */
.ge-unificado .ge-browser, .ge-unificado .ge-browser.ge-w-mobile, .ge-unificado .ge-browser.ge-w-desktop{ flex:none; width:auto; max-width:none; height:auto; padding:0; }
.ge-unificado .ge-browser.ge-w-mobile{ background:#fff; border-color:var(--ge-line); }
.ge-unificado .ge-bbody iframe{ transform-origin:0 0; }
/* "Guardado" vive en la cabecera del editor (EntregaEditor.indicadorGuardado): el del riel
   decia lo mismo dos veces. */
.ge-unificado .ge-savestate{ display:none; }

/* 4c. El editor de la PUERTA (paginaHibrida, hg-crm.js). Su lienzo de Diseno usa el marcado de
   la sala (4 de arriba); aqui solo lo suyo: las dos piezas de Contenido, los titulos de
   Actividad y las miniaturas de las tres plantillas. */
.hge-intro{ margin:0 0 18px; max-width:620px; font-size:var(--t-texto); color:var(--muted); line-height:1.5; }
.hge-piezas{ display:grid; grid-template-columns:repeat(auto-fill,minmax(260px,1fr)); gap:20px; max-width:760px; }
.hge-pieza-b{ display:flex; align-items:center; justify-content:space-between; gap:12px; padding:10px 2px 0; }
.hge-pieza-b a.btn{ text-decoration:none; }
.hge-act-t{ margin:26px 0 12px; font-size:var(--t-eti); font-weight:600; letter-spacing:.14em; text-transform:uppercase; color:var(--muted); }
.hge-act-t:first-child{ margin-top:0; }
/* Sin segmentado de pareja/enlace a la izquierda (la puerta es la misma para los dos): los
   tamanos se van a la derecha, donde estan en Video y Fotos. */
.hge-prev-top{ justify-content:flex-end; }
/* Miniatura de cada plantilla, dibujada con dos trazos: no hay captura real de cada una, y un
   "Aa" (el de las tarjetas de tipografia) no dice nada de una puerta. */
/* El fondo va con .ge-embebido .ge-rail .ge-card delante: la regla del riel que pinta la caja
   de toda tarjeta (background:var(--ge-prev), (0,4,0)) le ganaba a las de aqui y las tres
   miniaturas salian del mismo gris. */
.hge-mini{ position:relative; overflow:hidden; }
.hge-mini i{ position:absolute; display:block; border-radius:2px; }
.ge-embebido .ge-rail .ge-card .ge-prev.hge-mini-auto{ background:#f3f1ea; }
.hge-mini-auto i:first-child{ left:22%; right:22%; top:30%; height:12%; background:#151310; }
.hge-mini-auto i:last-child{ left:30%; right:30%; top:56%; height:14%; background:#c96442; }
.ge-embebido .ge-rail .ge-card .ge-prev.hge-mini-doble{ background:linear-gradient(90deg,#b98a6a 50%,#2a2825 50%); }
.hge-mini-doble i:first-child{ left:12%; width:26%; bottom:18%; height:10%; background:#f3efe8; }
.hge-mini-doble i:last-child{ right:12%; width:26%; bottom:18%; height:10%; background:#f3efe8; }
.ge-embebido .ge-rail .ge-card .ge-prev.hge-mini-cartelera{ background:linear-gradient(180deg,#3a352c 0 45%,#0c0c0b 45%); }
.hge-mini-cartelera i:first-child{ left:14%; right:14%; top:58%; height:8%; background:#f3efe8; }
.hge-mini-cartelera i:last-child{ left:14%; right:40%; top:76%; height:8%; background:#c8814f; }

/* 4c-bis. La barra de pasos de la hibrida (EntregaEditor.montarPasos; lienzo D3). Colores de
   estado fijos, los mismos de las pildoras oscuras: el editor es siempre oscuro. */
.edg-pasos{ display:flex; align-items:center; gap:10px 14px; flex-wrap:wrap; margin-top:12px; }
.edg-pasos-barra{ display:flex; align-items:center; gap:6px; flex-wrap:wrap; }
.edg-paso{ display:inline-flex; align-items:center; gap:7px; padding:6px 11px; border-radius:var(--r); border:1px solid rgba(255,255,255,.1); font-size:var(--t-meta); font-weight:600; color:#8a8a8a; text-decoration:none; white-space:nowrap; }
@media (hover:hover){ .edg-paso:hover{ border-color:rgba(255,255,255,.3); color:var(--ink); } }
.edg-paso.on{ background:#ededed; border-color:#ededed; color:#1a1a1a; }
.edg-paso.ok{ color:#A7C199; border-color:#29332C; background:#1d241f; }
.edg-paso.proc{ color:#E0C589; border-color:#33311F; background:#22211a; }
.edg-paso.falta{ color:#E9A385; border-color:#3A2A25; background:#251c19; }
.edg-paso.lock{ color:#6e6e6e; border-style:dashed; }
.edg-paso-n{ width:16px; height:16px; border-radius:50%; display:grid; place-items:center; font-size:10px; border:1px solid currentColor; }
.edg-paso-sep{ width:14px; height:1px; background:var(--line2); }
.edg-pasos-sig{ text-decoration:none; }

/* 4d. El paso de boda de CREAR (public/entregas-crear.js). Vive en el riel del mismo lienzo;
   aqui solo sus filas (una boda por renglon, con sus insignias) y los enlaces de texto. */
.ecr-riel{ padding-top:24px; }
.ecr-sec .inp{ width:100%; }
.ecr-lista{ display:flex; flex-direction:column; gap:8px; margin:14px 0 6px; }
.ecr-fila{ display:flex; align-items:center; gap:10px; width:100%; text-align:left; padding:10px 12px; border:1px solid var(--ge-line); border-radius:var(--r); background:var(--ge-prev); color:var(--ge-ink); font:inherit; cursor:pointer; }
@media (hover:hover){ .ecr-fila:hover{ border-color:var(--ge-focus); } }
.ecr-fila-fija{ cursor:default; }
@media (hover:hover){ .ecr-fila-fija:hover{ border-color:var(--ge-line); } }
.ecr-fila-txt{ display:flex; flex-direction:column; gap:2px; min-width:0; flex:1; }
.ecr-ft{ font-size:var(--t-texto); overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ecr-fs{ font-size:var(--t-meta); color:var(--ge-ink2); }
.ecr-insignias{ display:flex; flex-wrap:wrap; gap:5px; margin-top:6px; }
.ecr-ins{ flex:none; font-size:11px; padding:2px 8px; border-radius:var(--r); background:rgba(255,255,255,.07); color:var(--ge-ink2); white-space:nowrap; }
.ecr-ins-abrir{ background:#29332C; color:#A7C199; }
.ecr-nueva{ display:flex; align-items:center; gap:8px; width:100%; margin-top:6px; padding:10px 12px; border:1px dashed var(--ge-line); border-radius:var(--r); background:none; color:var(--ge-ink); font:inherit; font-size:var(--t-texto); cursor:pointer; text-align:left; }
@media (hover:hover){ .ecr-nueva:hover{ border-color:var(--ge-focus); } }
.ecr-link{ border:0; background:none; padding:10px 2px; font:inherit; font-size:var(--t-meta); color:var(--ge-ink2); text-decoration:underline; cursor:pointer; }
@media (hover:hover){ .ecr-link:hover{ color:var(--ge-ink); } }
.ecr-filtro{ font-size:var(--t-meta); color:var(--ge-ink2); margin:-10px 0 12px; }
.ecr-filtro .ecr-link{ padding:0; }
.ecr-pie{ display:flex; gap:10px; margin-top:22px; }
.ecr-pie .btn{ flex:1; justify-content:center; }

/* 4d-bis. Las plantillas al crear una galeria de FOTOS: la rejilla de abrirSelectorEstilos
   (.gx-selgrid/.gx-card) metida en el lienzo del panel, en vez de la muestra de una sola.
   Aqui SOLO va el acomodo: los colores ya salen bien solos porque .edg redefine --paper,
   --hair, --muted y --accent a sus valores oscuros sobre todo el subarbol (bloque 2 de este
   archivo), asi que las tarjetas se ven oscuras tambien con el CRM en claro sin repetir un
   color a mano. La rejilla del overlay es de 380px; aqui cabe menos ancho (el riel de la
   boda se lleva 400) y a 380 salia una sola columna. */
.ecr-pls{ width:100%; align-self:stretch; overflow:auto; padding:2px 2px 18px; }
.ecr-pls .gx-selgrid{ grid-template-columns:repeat(auto-fill,minmax(min(280px,100%),1fr)); gap:18px; max-width:none; }
.ecr-pls .gx-cardfoot{ padding:12px 14px; }
/* La elegida se queda marcada aunque el dedo no este encima: en el selector "Usar esta" solo
   aparece al pasar el raton, y aqui es la unica senal de que ya hay una plantilla puesta. */
.ecr-pls .gx-card.on .gx-usar{ opacity:1; transform:none; }

/* 5. Angosto (decision 14): el editor completo, con el riel a todo el ancho y la vista previa
   detras de "Vista previa". Por @container sobre #view y no por @media: lo que manda es el
   ancho del panel, que se angosta tambien con el chat abierto en escritorio. */
@container (max-width:1120px){ .ge-unificado .ge-rail{ width:340px; } }
@container (max-width:900px){
  .edg-cab{ padding:16px 16px 0; }
  .edg-aviso{ margin:12px 16px 0; }
  .edg-tabs{ padding:12px 16px 10px; }
  .edg-cuerpo{ padding:16px 16px 24px; }
  .edg-min{ width:100%; margin-right:0; }
  /* overflow:hidden pisa el overflow:auto que la regla generica de .ge-embebido pone a este
     mismo ancho: el riel ya scrollea por dentro, y dos scrolls anidados se pelean el dedo. */
  .sc-diseno.ge-unificado{ flex-direction:column; overflow:hidden; }
  .ge-unificado .ge-rail{ width:100%; flex:1 1 auto; border-left:0; }
  .ge-unificado .sc-diseno-prev, .geditor.ge-unificado > .ge-canvas{ display:none; }
  .geditor.ge-unificado{ flex-direction:column; overflow:hidden; }
  .geditor.ge-unificado.edg-prev-abierta > .ge-canvas{ display:flex; position:fixed; inset:0; z-index:400; min-height:0; }
  .ge-unificado #ge-canvasfullwrap, .ge-unificado #ge-dims{ display:none; }
  /* Mismo arreglo que Video: la fila de tamanos + "Volver a editar" no cabe a 375px y el boton
     de salir se cortaba por la derecha (medido: terminaba en x=386). */
  .ge-unificado .ge-canvastop, .ge-unificado .ge-canvastop > .fx{ flex-wrap:wrap; }
  .ge-unificado .ge-stagewrap{ padding:6px 0 16px; }
  /* `.geditor button{ border:none; background:none }` (0,1,1) le gana a `.btn` (0,1,0) y dejaba
     los dos botones de la vista previa como texto suelto dentro del editor de fotos. */
  .geditor.ge-unificado .btn.edg-abrir-prev, .geditor.ge-unificado .btn.edg-cerrar-prev{ border:1px solid var(--line2); background:var(--paper); color:var(--ink); }
  .edg .ge-unificado .btn.edg-abrir-prev{ display:inline-flex; align-items:center; justify-content:center; gap:8px; margin:12px 16px 0; }
  /* La vista previa se abre a pantalla completa, ENCIMA de todo: la barra de arriba del CRM y
     la pildora de Xarpie de abajo incluidas. Con z-index bajo, la barra de arriba tapaba el
     segmentado "Vista de la pareja / Enlace publico" (medido a 375px: fixed se ancla a la
     ventana, no a #view). Un telefono no tiene espacio para ensenar la pagina y el CRM a la
     vez, y "Volver a editar" siempre queda a la vista para salir. */
  .ge-unificado.edg-prev-abierta .sc-diseno-prev{ display:flex; position:fixed; inset:0; z-index:400; }
  .edg .ge-unificado.edg-prev-abierta .btn.edg-cerrar-prev{ display:inline-flex; white-space:nowrap; }
  .ge-unificado .edg-prev-nota{ display:none; }
  /* A 375px la fila de tamanos + pantalla completa + "Volver a editar" no cabe y el boton
     para salir quedaba cortado por la derecha (medido). Pantalla completa sobra aqui: la vista
     previa YA ocupa la pantalla entera. Y la fila puede partirse antes de cortar nada. */
  .ge-unificado .sc-prev-top > .fx{ flex-wrap:wrap; }
  .ge-unificado #sc-prevfull{ display:none; }
  .ge-unificado .sc-prev-top .ge-seg:has(> #sc-prevfull){ display:none; }
  .ge-unificado .sc-prev-canvas{ padding:12px; }
  .ge-unificado .ge-nav{ padding:12px 16px; }
  .ge-unificado .ge-railscroll{ padding:0 16px 32px; }
}

/* ---------- Bienvenida del chat: 4 accesos (lienzo "Bienvenida de Xarpie", opcion D) ----------
   Rejilla 2x2 sobre las sugerencias. Al tocar, .xb-capa crece desde el boton hasta llenar la
   pantalla (clip-path, 0.7 s, --ease-entra) mientras el chat se desenfoca; app.js navega al
   terminar y la capa se desvanece sobre la vista ya montada. */
.xb-bienv{ display:none; }
/* La bienvenida vive DENTRO del scroll del chat y es su PRIMER bloque (2026-09-18, pedido de
   Daniel). Antes se llevaba el panel entero (#chat-msgs quedaba en display:none) y se borraba
   entera al primer scroll hacia arriba o a la primera tecla: eso es lo que se sentia como que
   "desaparece". Ahora no se va nunca. Con la conversacion vacia queda a media altura, y en
   cuanto hay mensajes sube como sube cualquier mensaje.
   El centrado es :only-child + margin-block:auto, no JS: en una columna flex el margen auto se
   come el espacio libre, y en cuanto entra el primer mensaje la regla deja de aplicar sola. */
#chat-msgs > .xb-bienv:not([hidden]){ display:flex; flex-direction:column; }
#chat-msgs > .xb-bienv:only-child{ margin-block:auto; }
/* Modo bienvenida: mientras no hay nada que decir, el chat no ensena repisa, sugerencias ni el
   saludo viejo. Vuelven con scroll o al escribir. #chat-msgs ya NO se esconde aqui. */
.chatpane.xb-modo > .greet, .chatpane.xb-modo > .dialinea, .chatpane.xb-modo > #repisa,
.chatpane.xb-modo > #chat-viendo, .chatpane.xb-modo > #chat-tips, .chatpane.xb-modo > #xa-asomo{ display:none !important; }
.xb-saludo{ display:flex; flex-direction:column; gap:8px; margin-block:auto; padding-block:24px; }
.xb-kicker{ font-size:var(--t-eti); letter-spacing:.2em; text-transform:uppercase; font-weight:600; color:var(--muted); }
.xb-nombre{ font-family:var(--serif); font-size:var(--t-saludo); font-weight:400; line-height:1.02; letter-spacing:-.01em; color:var(--ink); }
.xb-linea{ font-size:var(--t-campo); line-height:1.45; color:var(--muted); text-wrap:pretty; }
.xb-rejilla{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:12px; }
#chat-msgs.xb-entra{ animation:xbAparece 420ms var(--ease-entra) both; }
@keyframes xbAparece{ from{ opacity:0; transform:translateY(10px); } to{ opacity:1; transform:none; } }
.xb-tile{ height:72px; box-sizing:border-box; display:flex; flex-direction:column; justify-content:space-between; gap:6px; padding:12px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); text-align:left; cursor:pointer; font:inherit; min-width:0;
  transition:transform var(--dur-1) var(--ease-estado), border-color var(--dur-1) var(--ease-estado); -webkit-tap-highlight-color:transparent; }
.xb-tile:active{ transform:scale(.97); }
@media (hover:hover){ .xb-tile:hover{ border-color:var(--muted); } }
.xb-cab{ display:flex; align-items:center; justify-content:space-between; gap:8px; color:var(--muted); min-width:0; }
.xb-acento .xb-cab .ico, .xb-acento .xb-cab svg{ color:var(--red); }
.xb-meta{ font-size:var(--t-meta); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.xb-tit{ font-size:var(--t-texto); font-weight:600; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.xb-capa{ position:fixed; inset:0; z-index:200; background:var(--paper); pointer-events:none;
  transition:clip-path 700ms var(--ease-entra), opacity 320ms var(--ease-estado); will-change:clip-path; }
.xb-capa.xb-sale{ opacity:0; }
.chatpane.xb-difumina > *{ filter:blur(8px); opacity:.35; transition:filter 700ms var(--ease-entra), opacity 700ms var(--ease-entra); }
@media (prefers-reduced-motion:reduce){ .xb-capa, .chatpane.xb-difumina > *{ transition:none; } #chat-msgs > .xb-bienv, #chat-msgs.xb-entra{ animation:none; } }

/* Telefono: el chat abierto es siempre pantalla completa y se ve completo, sin el difuminado de
   arriba del texto ni el boton de media pantalla (2026-09-16). */
@media (max-width:860px){
  #app.xa-completa .chatpane > .chatscroll{ -webkit-mask-image:none; mask-image:none; padding-top:8px; }
  #app.xa-completa #xa-media{ display:none !important; }
}

/* Quitar una tarjeta del chat: x en la esquina para las tarjetas sin cabecera de widget. */
.chat-quitar{ position:absolute; top:8px; right:8px; z-index:3; width:26px; height:26px; display:flex; align-items:center; justify-content:center;
  border:0; border-radius:50%; background:color-mix(in srgb, var(--paper) 80%, transparent); color:var(--muted); cursor:pointer; opacity:.7; }
.chat-quitar:focus-visible{ opacity:1; color:var(--ink); background:var(--guijarro-on, var(--hair)); }
@media (hover:hover){ .chat-quitar:hover{ opacity:1; color:var(--ink); background:var(--guijarro-on, var(--hair)); } }
@media (hover:hover){ .chat-quitar{ opacity:0; } *:hover > .chat-quitar, .chat-quitar:focus-visible{ opacity:.8; } }

/* ---------- Notificaciones en el chat (2026-09-16) ----------
   Mismo lenguaje que .xaviso (linea de sistema, no burbuja de Xarpie), con el icono del tipo
   de la campana. .xnotifs agrupa las no leidas al cargar; .xb-notifs es la franja de la
   bienvenida, entre el saludo y los accesos. */
.xaviso-notif{ border-style:solid; background:var(--paper); }
.xaviso-ico{ flex:none; display:flex; color:var(--muted); }
.xaviso-hecho{ opacity:.5; }
.xnotifs{ display:flex; flex-direction:column; gap:6px; margin:12px 0 2px 40px; max-width:520px; }
.xnotifs .xaviso{ margin:0; max-width:none; }
.xnotifs-cab{ display:flex; align-items:center; justify-content:space-between; gap:10px; min-height:28px; }
.xb-notifs{ display:flex; flex-direction:column; gap:8px; margin-bottom:12px; }
.xb-notif{ display:flex; align-items:center; gap:12px; min-height:52px; padding:8px 12px; border:1px solid var(--line2); border-radius:var(--r); background:var(--paper); color:var(--ink); text-align:left; font:inherit; cursor:pointer; min-width:0; -webkit-tap-highlight-color:transparent; transition:transform var(--dur-1) var(--ease-estado); }
.xb-notif:active{ transform:scale(.98); }
.xb-notif-ico{ flex:none; display:flex; color:var(--red); }
.xb-notif-txt{ display:flex; flex-direction:column; gap:2px; flex:1; min-width:0; }
.xb-notif-tit{ font-size:var(--t-texto); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.xb-notif-cuando{ font-size:var(--t-meta); color:var(--muted); }
.xb-notif-ver{ flex:none; display:flex; align-items:center; gap:4px; font-size:var(--t-meta); font-weight:600; color:var(--ink); }
.xb-notif-mas{ align-self:flex-start; min-height:32px; padding:4px 0; border:0; background:none; color:var(--muted); font:inherit; font-size:var(--t-meta); cursor:pointer; }
@media (max-width:860px){ .xnotifs{ margin-left:0; } }

/* ============================================================================
   TELEFONO: XARPIE Y EL CRM COMO PAGINAS (lienzo "Xarpie en el telefono v19", opcion A,
   aprobado por Daniel 2026-09-16). Paso 1 de 2: sin conversaciones separadas todavia.
   Dos paginas: #app.xa-completa = Xarpie (el chat encima de todo) y #app.xa-barra = el CRM (el
   chat se va a la izquierda y queda el CRM de siempre). Se pasa deslizando el chat o con
   "Portales ›" / "‹ Xarpie". El CRM NO se desliza: tiene subpestanas, tablas, agenda y galerias
   que ya se mueven de lado (ver montarTelefonoPaginas en app.js).
   Forma: pildora = lo que se toca; 16px = lo que flota (hojas); --r = contenido.
   Tiempos (Emil): pagina 240ms, hojas suben 280ms; curva de iOS para lo que el dedo arrastra.
   Reemplaza al bloque "XARPIE EN EL TELEFONO" de 2026-09-15 (la pildora que se volvia caja) y va
   AL FINAL: le gana por orden al cajon viejo, a la barra de 4 secciones y a la bienvenida de 4
   accesos, que tienen la misma especificidad.
   ============================================================================ */
.tel-fila-xa, .tel-a-xarpie, .tel-velo, .tel-menu, .um-propone{ display:none; }
/* "Viendo:" vacio se veia como una raya de 1px arriba del chat: .chat-viendo{display:flex} le
   ganaba al [hidden] del navegador. */
.chat-viendo[hidden]{ display:none; }
.tel-sr{ position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
:root{ --tel-xa-fondo:var(--deep); --tel-ios:cubic-bezier(.32,.72,0,1); }
:root[data-theme="dark"]{ --tel-xa-fondo:#060605; }
@media (max-width:860px){
  /* ---- Las dos paginas ---- */
  #app .chatpane, #app.xa-barra .chatpane, #app.xa-media .chatpane, #app.xa-completa .chatpane{
    position:fixed; top:0; right:0; bottom:0; left:0; width:auto; height:100dvh; max-height:none; z-index:70;
    display:flex; flex-direction:column; gap:0;
    padding:calc(4px + env(safe-area-inset-top)) 16px calc(20px + env(safe-area-inset-bottom));
    background-color:var(--tel-xa-fondo); border:0; box-shadow:none; clip-path:none; animation:none;
    pointer-events:auto; touch-action:pan-y;
    transform:translate3d(0,0,0); visibility:visible;
    transition:transform var(--tel-dur, 240ms) var(--tel-ios), visibility 0s;
  }
  #app.xa-barra .chatpane{
    transform:translate3d(-100%,0,0); visibility:hidden; pointer-events:none;
    transition:transform var(--tel-dur, 240ms) var(--tel-ios), visibility 0s linear var(--tel-dur, 240ms);
  }
  #app .chatpane::before{ content:none; }
  /* Lo que era del cajon, de la pildora y de la hoja a media pantalla: fuera (los nodos siguen en
     el DOM porque app.js los lee al cargar). */
  #app .chatpane > .xa-agarre, #app .chatpane > .cp-brand, #app .chatpane > .greet, #app .chatpane > .dialinea,
  #app .chatpane > .xa-asomo, #app .chatpane .chat-menu-btn, #xa-completa-btn, .cp-backdrop, .xa-bruma{ display:none !important; }
  /* Sin difuminado arriba: en telefono Daniel lo quito de la pantalla completa (dep-702). */
  /* overscroll-behavior:contain: al llegar al tope el gesto NO se le pasa a la pagina. Sin
     esto, en iPhone el rebote de la pagina se come el movimiento y se siente como si el chat
     no respondiera (video de Daniel, 2026-09-17). */
  #app .chatpane > .chatscroll{ flex:1 1 auto; min-height:0; touch-action:pan-y; overscroll-behavior:contain; }

  /* ---- Fila de arriba de Xarpie: "Portales ›" ---- */
  .tel-fila-xa{ display:flex; align-items:center; height:44px; flex:none; margin:0 -8px; }
  .tel-flex{ flex:1 1 auto; }
  .tel-nav{
    display:inline-flex; align-items:center; gap:2px; height:44px; padding:0 4px 0 12px; border:0; border-radius:22px;
    background:transparent; color:var(--muted); font:inherit; font-size:var(--t-texto); cursor:pointer;
    -webkit-tap-highlight-color:transparent; transition:transform 140ms var(--ease-entra);
  }
  .tel-nav-izq{ padding:0 12px 0 4px; }
  .tel-nav:active{ transform:scale(.97); transition-duration:60ms; }
  .tel-nav:focus-visible{ outline:2px solid var(--ink); outline-offset:-2px; }
  .tel-nav .ico{ flex:none; }

  /* ---- Pagina del CRM: "‹ Xarpie" a la izquierda, buscar y campana a la derecha ---- */
  .tel-a-xarpie{ display:inline-flex; }
  #cp-riel .cp-riel-logo, #nav-cfg-btn{ display:none !important; }
  #cp-riel.show, .cp-riel{ padding:calc(env(safe-area-inset-top)) 4px 0 8px; border-bottom:0; background:var(--bone); }

  /* La puerta a Xarpie vive AL CENTRO de la pildora de abajo (2026-09-17): el "‹ Xarpie" de
     la cabecera se retira para no tener dos puertas al mismo lugar. El nodo se queda en el
     DOM porque montarTelefonoPaginas le cuelga su handler al cargar. */
  #tel-a-xarpie{ display:none !important; }

  /* ---- Pildora del CRM: Portales · Tareas · Xarpie · Crear · Menu ---- */
  .main{ padding-bottom:calc(96px + env(safe-area-inset-bottom)); }
  .barra-inf, .barra-inf:not([hidden]){
    position:fixed; left:16px; right:16px; bottom:calc(20px + env(safe-area-inset-bottom)); z-index:58;
    display:flex; align-items:center; justify-content:space-around; height:56px; padding:0 10px;
    border:0; border-radius:28px; grid-template-columns:none;
    background:color-mix(in srgb, var(--guijarro, var(--deep)) 92%, transparent);
    backdrop-filter:blur(20px) saturate(1.2); -webkit-backdrop-filter:blur(20px) saturate(1.2);
    box-shadow:0 22px 44px -18px rgba(0,0,0,.55), inset 0 0 0 1px color-mix(in srgb, var(--ink) 7%, transparent);
    opacity:1; pointer-events:auto; transition:none;
  }
  .barra-inf[hidden]{ display:none; }
  body:has(#app.xa-media) .barra-inf, body:has(#app.xa-completa) .barra-inf{ opacity:1; pointer-events:auto; }
  .bi-btn{
    position:relative; flex:none; width:52px; height:44px; gap:0; display:flex; align-items:center; justify-content:center;
    border:0; border-radius:22px; background:transparent; color:var(--muted); cursor:pointer;
    -webkit-tap-highlight-color:transparent; transition:transform 140ms var(--ease-entra);
  }
  .bi-btn:active{ transform:scale(.97); transition-duration:60ms; }
  .bi-btn.on{ background:var(--guijarro-on, var(--hair)); color:var(--ink); }
  .bi-cuenta{
    position:absolute; top:3px; right:5px; min-width:16px; height:16px; padding:0 4px; border-radius:8px;
    background:var(--ink); color:var(--bone); font-size:10px; font-weight:600; line-height:16px; text-align:center;
    font-variant-numeric:tabular-nums;
  }
  .bi-cuenta[hidden]{ display:none; }

  /* ---- Hojas de abajo: Crear, el "+", Tareas, Menu, Configuracion, Notificaciones ---- */
  @keyframes telHojaSube{ from{ transform:translate3d(0,100%,0); } to{ transform:none; } }
  @keyframes telFundido{ from{ opacity:0; } to{ opacity:1; } }
  body:has(#tel-menu:not([hidden])) .tel-velo,
  body:has(#usermenu:not([hidden])) .tel-velo,
  body:has(#notif-panel:not([hidden])) .tel-velo{
    display:block; position:fixed; inset:0; z-index:74; background:rgba(0,0,0,.5); animation:telFundido 180ms var(--ease-estado) both;
  }
  .agregar-backdrop:not([hidden]){ background:rgba(0,0,0,.5); animation:telFundido 180ms var(--ease-estado) both; }
  .agregar-sheet:not([hidden]), .tel-menu:not([hidden]),
  #usermenu.cfg-menu:not([hidden]), #notif-panel.cfg-menu:not([hidden]){
    display:flex; flex-direction:column; position:fixed; left:0 !important; right:0 !important; top:auto !important; bottom:0;
    width:auto; max-width:none; max-height:80dvh; overflow-y:auto; overscroll-behavior:contain; z-index:80;
    border:0; border-radius:16px 16px 0 0; background:var(--guijarro, var(--deep));
    padding:8px 16px calc(24px + env(safe-area-inset-bottom));
    box-shadow:0 -20px 50px -20px rgba(0,0,0,.5);
    animation:telHojaSube 280ms var(--tel-ios) both;
  }
  #usermenu.cfg-menu:not([hidden])::before, #notif-panel.cfg-menu:not([hidden])::before, .tel-grab, .ag-grabber{
    content:""; display:block; flex:none; width:40px; height:5px; border-radius:3px; background:var(--line2); margin:2px auto 12px;
  }
  .tel-cab{ font-size:var(--t-meta); color:var(--muted); margin:14px 10px 4px; }
  .tel-sep{ height:1px; background:var(--hair); margin:10px 0; }
  .tel-fila-menu{
    display:flex; align-items:center; gap:14px; width:100%; min-height:48px; padding:0 10px; border:0; border-radius:var(--r);
    background:transparent; color:var(--ink); font:inherit; font-size:var(--t-campo); text-align:left; cursor:pointer;
    -webkit-tap-highlight-color:transparent; transition:background-color 120ms var(--ease-estado);
  }
  .tel-fila-menu:active{ background:var(--guijarro-on, var(--hair)); transition-duration:40ms; }
  .tel-fila-menu.on{ background:var(--guijarro-on, var(--hair)); }
  .tel-fila-ico .ico{ color:var(--muted); flex:none; }
  /* Crear: la rejilla de siempre, con los iconos mas grandes y sin cajas. */
  .tel-crear{ display:grid; grid-template-columns:repeat(3, minmax(0, 1fr)); gap:4px; }
  .tel-crear .muelle-btn{ flex-direction:column; justify-content:center; gap:8px; height:80px; border:0; background:transparent; font-size:var(--t-texto); }
  .tel-crear .muelle-btn:active{ background:var(--guijarro-on, var(--hair)); }
  .tel-crear .muelle-btn .ico{ color:var(--muted); }
  /* Configuracion y notificaciones: filas de hoja, no de menu flotante. */
  #usermenu.cfg-menu .um-item, #notif-panel.cfg-menu .um-item{ min-height:48px; font-size:var(--t-campo); border-radius:var(--r); }
  #usermenu.cfg-menu .um-head{ padding:4px 10px 10px; }
  .um-propone{ display:flex; align-items:center; justify-content:space-between; gap:12px; }
  .um-propone-val{ font-size:var(--t-texto); color:var(--muted); }
  /* Tareas: la hoja del dia deja de ser pantalla completa y se vuelve hoja de abajo. */
  .hojadia:not([hidden]){
    display:flex; flex-direction:column; justify-content:flex-end; position:fixed; inset:0; height:auto; z-index:73;
    background:rgba(0,0,0,.5); animation:telFundido 180ms var(--ease-estado) both;
  }
  .hojadia-cuerpo{
    flex:0 1 auto; max-height:80dvh; min-height:0; border-radius:16px 16px 0 0; background:var(--guijarro, var(--deep));
    padding:8px 0 env(safe-area-inset-bottom); box-shadow:0 -20px 50px -20px rgba(0,0,0,.5);
    animation:telHojaSube 280ms var(--tel-ios) both;
  }
  .hojadia-cuerpo::before{ content:""; display:block; flex:none; width:40px; height:5px; border-radius:3px; background:var(--line2); margin:2px auto 6px; }
  /* Buscar baja desde arriba: sale del icono y el teclado no la tapa. */
  .ov:has(.modal-buscador){ align-items:flex-start; padding:0; }
  .modal.modal-buscador{ width:100vw; max-width:none; margin:0; border:0; border-radius:0 0 16px 16px; padding-top:env(safe-area-inset-top); animation:telBaja 280ms var(--tel-ios) both; }
  @keyframes telBaja{ from{ transform:translate3d(0,-100%,0); } to{ transform:none; } }
  /* Las pistas de teclado (flechas, Enter, Cmd+K) no aplican en un telefono. */
  .modal.modal-buscador .bus-pie{ display:none; }

  /* ---- Xarpie: saludo y una oracion ---- */
  #chat-msgs > .xb-bienv:not([hidden]){ align-items:center; text-align:center; padding:0 12px 24px; animation:none; }
  .tel-saludo{ margin:0; font-size:var(--t-saludo); font-weight:400; line-height:1.1; letter-spacing:-.02em; color:var(--muted); text-wrap:balance; }
  .tel-saludo b{ font-weight:500; color:var(--ink); }
  .tel-linea{ max-width:300px; margin:12px 0 0; font-size:var(--t-campo); line-height:1.5; color:var(--muted); text-wrap:pretty; }
  .tel-enlace{
    display:inline; padding:0; border:0; background:none; font:inherit; color:var(--ink); font-weight:500; cursor:pointer;
    text-decoration:underline; text-decoration-color:var(--line2); text-underline-offset:4px; -webkit-tap-highlight-color:transparent;
    transition:opacity 120ms var(--ease-estado);
  }
  .tel-enlace:active{ opacity:.6; }
  /* Sugerencias: solo al tocar la caja vacia. */
  #app .chatpane > #chat-tips{ display:none !important; }
  #app .chatpane.tel-sug > #chat-tips{
    display:flex !important; flex-wrap:wrap; justify-content:center; gap:8px; overflow:visible; min-height:0; padding:0; margin:0 0 12px;
    animation:telFundido 120ms var(--ease-estado) both;
  }
  #app .chatpane.tel-sug > #chat-tips .chip{
    min-height:36px; padding:0 14px; border:0; border-radius:18px; background:var(--guijarro, var(--paper));
    box-shadow:inset 0 0 0 1px var(--hair); color:var(--ink); font-size:var(--t-texto);
  }

  /* ---- La caja de escribir: pildora de 56px ---- */
  #app .chatpane .composer{
    flex:none; margin:0; min-height:56px; padding:0 8px 0 4px; align-items:center; border:0; border-radius:28px; animation:none;
    background:color-mix(in srgb, var(--guijarro, var(--deep)) 92%, transparent);
    box-shadow:0 22px 44px -18px rgba(0,0,0,.55), inset 0 0 0 1px color-mix(in srgb, var(--ink) 7%, transparent);
  }
  /* 16px: con menos, iOS hace zoom al enfocar el campo (misma regla que --t-campo). */
  #app .chatpane .composer textarea{ font-size:16px; }
  #chat-send{ opacity:.45; transition:opacity 120ms var(--ease-estado), transform 140ms var(--ease-entra); }
  #chat-send.listo{ opacity:1; }
  #chat-send:active{ transform:scale(.97); }

  @media (prefers-reduced-motion:reduce){
    #app .chatpane, #app.xa-barra .chatpane{ transition-duration:0.01ms !important; transition-delay:0s !important; }
    .agregar-sheet:not([hidden]), .tel-menu:not([hidden]), #usermenu.cfg-menu:not([hidden]), #notif-panel.cfg-menu:not([hidden]),
    .hojadia-cuerpo, .modal.modal-buscador{ animation:telFundido 120ms linear both !important; }
    .tel-nav, .bi-btn, .tel-enlace, #chat-send{ transition:none; }
    .tel-nav:active, .bi-btn:active, #chat-send:active{ transform:none; }
  }
}

/* ============================================================================
   TELEFONO: CONVERSACIONES (lienzo "Xarpie en el telefono v19", paso 2, 2026-09-16).
   La tercera pagina, a la izquierda de Xarpie: #app.tel-en-convs la trae y empuja el chat a la
   derecha. Fondo del tema (el papel oscuro es solo de Xarpie, para distinguir las paginas).
   Filas sin cajas; mantener presionada una fila abre Renombrar / Borrar.
   ============================================================================ */
.tel-convs, .tel-ib{ display:none; }
@media (max-width:860px){
  #app .tel-convs{
    display:flex; flex-direction:column; position:fixed; inset:0; height:100dvh; z-index:71;
    padding:calc(4px + env(safe-area-inset-top)) 16px calc(20px + env(safe-area-inset-bottom));
    background:var(--bone); touch-action:pan-y;
    transform:translate3d(-100%,0,0); visibility:hidden; pointer-events:none;
    transition:transform var(--tel-dur, 240ms) var(--tel-ios), visibility 0s linear var(--tel-dur, 240ms);
  }
  #app.tel-en-convs .tel-convs{
    transform:translate3d(0,0,0); visibility:visible; pointer-events:auto;
    transition:transform var(--tel-dur, 240ms) var(--tel-ios), visibility 0s;
  }
  #app.tel-en-convs .chatpane{ transform:translate3d(100%,0,0); }
  body:has(#app.tel-en-convs) #toast{ bottom:calc(96px + env(safe-area-inset-bottom)); }

  .tel-ib, .tel-ib:not([hidden]){
    display:inline-flex; align-items:center; justify-content:center; flex:none; width:44px; height:44px; padding:0;
    border:0; border-radius:22px; background:transparent; color:var(--muted); cursor:pointer;
    -webkit-tap-highlight-color:transparent; transition:transform 140ms var(--ease-entra);
  }
  .tel-ib[hidden]{ display:none; }
  .tel-ib:active{ transform:scale(.97); transition-duration:60ms; }
  .tel-ib:focus-visible{ outline:2px solid var(--ink); outline-offset:-2px; }
  #tel-fila-xa .tel-nav-izq + .tel-ib{ margin-left:-6px; }

  .tc-tit{ flex:none; margin:12px 0 0; font-size:var(--t-titulo); font-weight:500; letter-spacing:-.02em; line-height:1.15; color:var(--ink); }
  .tc-tit[hidden], .tc-busca-fila[hidden]{ display:none; }
  .tc-busca-fila{ flex:none; display:flex; align-items:center; gap:8px; margin-top:10px; }
  .tc-busca{
    flex:1; min-width:0; display:flex; align-items:center; gap:8px; height:44px; padding:0 14px; border-radius:22px;
    background:var(--guijarro, var(--paper)); box-shadow:inset 0 0 0 1px var(--hair); color:var(--muted);
  }
  .tc-busca:focus-within{ box-shadow:inset 0 0 0 1px var(--hair), 0 0 0 2px var(--line2); }
  .tc-busca input{ flex:1; min-width:0; border:0; outline:0; background:transparent; font:inherit; font-size:16px; color:var(--ink); -webkit-appearance:none; appearance:none; }
  .tc-busca input::-webkit-search-cancel-button{ display:none; }
  .tc-cancelar{ flex:none; min-height:44px; padding:0 6px; border:0; background:none; font:inherit; font-size:var(--t-texto); color:var(--ink); cursor:pointer; }

  .tc-lista{ flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; scrollbar-width:none; margin:0 -6px; padding:0 6px 8px; }
  .tc-lista::-webkit-scrollbar{ display:none; }
  .tc-cab{ margin:16px 10px 4px; font-size:var(--t-meta); color:var(--muted); }
  .tc-nota{ margin:24px 10px; font-size:var(--t-texto); color:var(--muted); }
  .tc-fila{ position:relative; border-radius:var(--r); }
  .tc-fila.on{ background:var(--guijarro-on, var(--hair)); }
  .tc-abre{
    display:flex; flex-direction:column; align-items:flex-start; width:100%; min-height:56px; padding:10px; border:0; border-radius:var(--r);
    background:transparent; font:inherit; text-align:left; cursor:pointer; color:inherit;
    -webkit-tap-highlight-color:transparent; -webkit-touch-callout:none; -webkit-user-select:none; user-select:none;
    transition:background-color 120ms var(--ease-estado);
  }
  .tc-abre:active{ background:var(--guijarro-on, var(--hair)); transition-duration:40ms; }
  .tc-t{ display:block; max-width:100%; font-size:var(--t-campo); color:var(--ink); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .tc-s{ display:block; margin-top:2px; font-size:var(--t-meta); color:var(--muted); font-variant-numeric:tabular-nums; }
  @keyframes tcMenu{ from{ opacity:0; transform:scale(.96); } to{ opacity:1; transform:none; } }
  .tc-menu{
    position:absolute; right:6px; top:48px; z-index:3; width:200px; padding:6px; border-radius:16px;
    background:var(--guijarro, var(--paper)); box-shadow:0 18px 40px -12px rgba(0,0,0,.45), inset 0 0 0 1px var(--hair);
    transform-origin:top right; animation:tcMenu 120ms var(--ease-entra) both;
  }
  .tc-menu.arriba{ top:auto; bottom:48px; transform-origin:bottom right; }
  .tc-menu button{ display:block; width:100%; min-height:44px; padding:0 10px; border:0; border-radius:var(--r); background:transparent; font:inherit; font-size:var(--t-texto); color:var(--ink); text-align:left; cursor:pointer; }
  .tc-menu button:active{ background:var(--guijarro-on, var(--hair)); }
  .tc-menu button.peligro{ color:var(--red); }

  .tc-vacio{ display:flex; flex-direction:column; align-items:center; justify-content:center; gap:10px; min-height:100%; padding:0 28px; text-align:center; }
  .tc-vt{ margin:0; font-size:var(--t-sub); font-weight:500; color:var(--ink); text-wrap:balance; }
  .tc-vs{ margin:0; font-size:var(--t-texto); line-height:1.5; color:var(--muted); text-wrap:pretty; }
  .tc-empezar{ margin-top:8px; min-height:44px; padding:0 20px; border:0; border-radius:22px; background:var(--ink); color:var(--bone); font:inherit; font-size:var(--t-texto); font-weight:500; cursor:pointer; transition:transform 140ms var(--ease-entra); }
  .tc-empezar:active{ transform:scale(.97); }

  .tc-perfil{
    flex:none; display:flex; align-items:center; gap:12px; width:100%; height:56px; margin-top:10px; padding:0 16px 0 8px;
    border:0; border-radius:28px; text-align:left; font:inherit; color:inherit; cursor:pointer;
    background:color-mix(in srgb, var(--guijarro, var(--deep)) 92%, transparent);
    box-shadow:0 22px 44px -18px rgba(0,0,0,.55), inset 0 0 0 1px color-mix(in srgb, var(--ink) 7%, transparent);
    -webkit-tap-highlight-color:transparent; transition:transform 140ms var(--ease-entra);
  }
  .tc-perfil:active{ transform:scale(.97); transition-duration:60ms; }
  .tc-avatar{ flex:none; width:40px; height:40px; border-radius:50%; display:flex; align-items:center; justify-content:center; background:var(--guijarro-on, var(--hair)); color:var(--ink); font-size:var(--t-campo); font-weight:500; }
  .tc-perfil-txt{ flex:1; min-width:0; }
  .tc-pn, .tc-ps{ display:block; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
  .tc-pn{ font-size:var(--t-texto); font-weight:500; color:var(--ink); }
  .tc-ps{ margin-top:1px; font-size:var(--t-meta); color:var(--muted); }

  @media (prefers-reduced-motion:reduce){
    #app .tel-convs, #app.tel-en-convs .tel-convs{ transition-duration:0.01ms !important; transition-delay:0s !important; }
    .tc-menu{ animation:none; }
    .tel-ib, .tc-perfil, .tc-empezar{ transition:none; }
    .tel-ib:active, .tc-perfil:active, .tc-empezar:active{ transform:none; }
  }
}
/* «Antes de publicar» (EntregaEditor.listaPublicar). Vive en #modal, fuera de .edg: usa los
   tokens del tema del CRM, no los oscuros del editor. */
.edg-lp .edg-lp-resumen { margin: 0 0 12px; font-weight: 600; }
.edg-lp .edg-lp-grupo { margin: 14px 0 4px; font-size: var(--t-eti); letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.edg-lp .edg-lp-lista { list-style: none; margin: 0; padding: 0; }
.edg-lp .edg-lp-item { display: flex; align-items: center; gap: 10px; padding: 10px 0; border-bottom: 1px solid var(--line2); }
.edg-lp .edg-lp-ic { flex: none; width: 22px; height: 22px; border-radius: 50%; display: grid; place-items: center; font-size: var(--t-meta); font-weight: 700; background: var(--line2); color: var(--ink2); }
.edg-lp .edg-lp-item.ok .edg-lp-ic { background: color-mix(in srgb, var(--ok) 20%, transparent); color: var(--ok); }
.edg-lp .edg-lp-item.no .edg-lp-ic { background: color-mix(in srgb, var(--warn) 20%, transparent); color: var(--warn); }
.edg-lp .edg-lp-tx { flex: 1; min-width: 0; }
.edg-lp .edg-lp-item.ok .edg-lp-tx { color: var(--ink2); }
.edg-lp .edg-lp-nota { margin: 14px 0 0; font-size: var(--t-meta); color: var(--muted); }

/* Linea que separa una conversacion vieja de la nueva cuando la app se quedo abierta mas de
   30 minutos sin escribir (enviarChat). Lo de arriba se ve pero Xarpie ya no lo relee. */
.conv-sep{ margin:18px 0 6px; text-align:center; font-size:var(--t-meta); color:var(--apagado); }
