/* ════════════════════════════════════════════════════════════════════════════
   TEMA · el sistema visual de Novoconect desde el 6 de septiembre de 2026
   ────────────────────────────────────────────────────────────────────────────
   Traducción de `tema.css` (Tailwind v4 + shadcn/ui) al lenguaje del producto:
   HTML, CSS y JS a mano, sin empaquetador. Los valores son LOS MISMOS, uno a
   uno. Lo único que cambia es de dónde salen: donde había una clase de utilidad
   («gap-6», «text-sm») hay ahora la medida que esa clase generaba.

   TRES COSAS QUE HAY QUE SABER PARA LEER ESTO:

   1 · LOS SELECTORES `[data-slot="…"]` SE HAN CONSERVADO. Son los de shadcn.
       El fichero de Marc solo SOBRESCRIBE ese componente base, así que aquí
       está primero la base —bajada del registro público de shadcn, no
       inventada— y encima, sin tocarla, su capa.
       Conservarlos permite comparar con el original línea a línea.

   2 · EL INTERRUPTOR ES `data-tema`, EL QUE YA TIENE EL PRODUCTO. El fichero
       original trae la paleta clara en `:root` y la oscura en `.dark`. Aquí van
       al revés porque el producto arranca OSCURO y marca el claro con
       `html[data-tema="claro"]`, que es lo que escribe el SERVIDOR en el
       subdominio de admin y lo que lee el localStorage de siempre.
       Los colores son idénticos. Solo cambia a qué selector cuelgan.

   3 · LA TIPOGRAFÍA VA DENTRO. Geist y Geist Mono viven en ./fuentes/, sacadas
       del paquete `geist` 1.7.2 (SIL Open Font License). NI GOOGLE NI NINGÚN
       CDN: el panel de red de estas pantallas tiene que salir a cero peticiones
       de fuera, y una tipografía remota lo rompe además de contarle a un
       tercero quién entra y cuándo.
   ══════════════════════════════════════════════════════════════════════════ */

@font-face{ font-family:"Geist"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url("./fuentes/Geist-Variable.woff2") format("woff2") }
@font-face{ font-family:"Geist Mono"; font-style:normal; font-weight:100 900; font-display:swap;
  src:url("./fuentes/GeistMono-Variable.woff2") format("woff2") }

/* ─────────────────────────────────────────────────────────
   PALETA: sacada del propio Soft Aurora
   #f7f7f7  su color1        #e100ff  su color2
   el resto son negros construidos alrededor de ellos
   ───────────────────────────────────────────────────────── */
:root{
  --radius: .625rem;                      /* 10px */
  --radius-sm: calc(var(--radius) - 4px); /*  6px */
  --radius-md: calc(var(--radius) - 2px); /*  8px */
  --radius-lg: var(--radius);             /* 10px */
  --radius-xl: calc(var(--radius) + 4px); /* 14px */

  --font-sans: "Geist", -apple-system, "Segoe UI", Roboto, sans-serif;
  --font-mono: "Geist Mono", ui-monospace, monospace;

  /* OSCURO, que es como arranca el producto */
  color-scheme: dark;
  --background:#000000; --foreground:#F7F7F7;
  --card:#0A0A0C; --card-foreground:#F7F7F7;
  --popover:#0E0E11; --popover-foreground:#F7F7F7;
  --primary:#F7F7F7; --primary-foreground:#08080A;
  --secondary:#141418; --secondary-foreground:#F7F7F7;
  --muted:#141418; --muted-foreground:#8A8A96;
  --accent:#1A1020; --accent-foreground:#F7F7F7;
  --destructive:#FF5C47;
  --border:#1D1D22; --input:#26262D; --ring:#E100FF; --borde-campo:#6E6E82;
  /* #37 · el paso INTERMEDIO entre «no es esta» y «es esta». Es la mezcla
     exacta de --muted-foreground y --foreground, no un gris a ojo: si un dia
     cambia cualquiera de los dos, este tiene que ir con ellos. */
  --pestana-roce:#C1C1C7;
  /* 28/09 · EL VERDE DE «HECHO BIEN» (la exclusiva conseguida). UNO y el mismo en
     los dos temas. Va como FONDO con tinta oscura (#08080A, 5,9:1 · AA), no como
     letra: ningún verde pasa AA como texto sobre el fondo oscuro Y sobre el claro
     a la vez (haría falta una luminancia ≤0,183 para el claro y ≥0,19 para el
     oscuro). Sobre la tarjeta oscura el relleno mide 5,9:1 y sobre la blanca 3,4:1
     (≥3:1, lo que pide una forma). */
  --exito:#22A05B;
  /* 09/10 · el verde como TEXTO (el €/m² de una ficha por debajo de su zona): sobre el negro
     vale el mismo; sobre el blanco se oscurece para llegar a 4,5:1, que es lo que pide un texto. */
  --exito-txt:#22A05B;
}
html[data-tema="claro"]{
  color-scheme: light;
  --exito-txt:#15803D;
  --background:#FAFAFA; --foreground:#08080A;
  --card:#FFFFFF; --card-foreground:#08080A;
  --popover:#FFFFFF; --popover-foreground:#08080A;
  --primary:#08080A; --primary-foreground:#FAFAFA;
  --secondary:#F1F1F3; --secondary-foreground:#08080A;
  --muted:#F1F1F3; --muted-foreground:#6B6B75;
  --accent:#F4EAFB; --accent-foreground:#08080A;
  --destructive:#D42B1F;
  --border:#E3E3E8; --input:#DDDDE3; --ring:#E100FF; --borde-campo:#80808E;
  --pestana-roce:#3A3A40;
}

/* 🔴 #14 · QUE `hidden` OCULTE DE VERDAD, Y ESTO ES LA RAÍZ.
   `[hidden]` es una regla del NAVEGADOR con especificidad cero: cualquier
   clase nuestra que ponga `display` la pisa sin avisar. Y eso es lo que
   pasaba con `.hoja .dos-salidas{ display:flex }`: la hoja de «Dárselo a un
   agente» hacía `$('h-salidas').hidden = true` y la caja SEGUÍA VISIBLE —
   44 px de botón, sin texto y sin hacer nada, porque esa hoja no tiene
   botón de aceptar. Medido el 08/09/2026: hidden=true, display=flex,
   alto=44, texto="".
   ⚠️ El bug no era de esa hoja: era de todo el producto. `hidden` se usa en
   catorce sitios y en cualquiera de ellos podía estar pasando lo mismo sin
   que nadie lo viera. Por eso se arregla aquí y no allí.
   ⚠️ `!important` a propósito, y es de los pocos que hay: `hidden` no es un
   estilo, es un hecho — si algo está oculto no hay ningún caso en que una
   clase deba poder enseñarlo. */
[hidden]{ display:none !important }

/* 🔴 #64 · EL HOVER SOLO DONDE HAY RATÓN, Y ESTO ES LA RAÍZ.
   Marc, en el móvil: «seleccionas las 3 líneas, clicas la X, y se queda
   seleccionado». Medido con toque de verdad: tras tocar la X, el botón seguía
   con el fondo del hover —`:hover` da true— porque en una pantalla táctil el
   «puntero» se queda donde se tocó hasta que se toca otra cosa. No era el
   menú ni la X: era el hover pegado, y le pasa a CUALQUIER cosa con :hover
   que se toque. Por eso el arreglo no es en el botón del menú: TODAS las
   reglas con :hover de esta hoja van dentro de @media (hover:hover), que es
   «hay un puntero que puede flotar». En el móvil no existen; en el escritorio
   no cambia nada. Cuarenta y cuatro reglas, envueltas con un script que
   contó antes y después (561 reglas las dos veces). Una regla nueva con
   :hover va también envuelta, o se queda pegada en el móvil. */

*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0 }
*{ border-color: var(--border) }
html,body,#raiz{ min-height:100% }
/* ══ LA ALTURA DE LA PANTALLA EN EL MÓVIL ══════════════════════════════════
   En un móvil hay TRES alturas y no una:
     lvh · con la barra del navegador escondida — la más alta
     svh · con la barra a la vista — la más baja
     dvh · la de ahora mismo, que cambia al aparecer y desaparecer la barra
   `100vh` es lvh: por eso una pantalla hecha con vh sale más alta que el hueco
   que se ve y lo de abajo queda debajo de la barra. En este producto NO HAY NI
   UN `100vh` —se buscaron los tres nombres, incluidos `h-screen` y
   `min-h-screen`, y no aparece ninguno—, así que aquí no hay nada que
   arreglar: hay que elegir entre svh y dvh, y la elección no es la misma en
   todas las pantallas.

   ⚖️ LA REGLA, Y ESTÁ ESCRITA SITIO A SITIO ABAJO:
     · dvh donde NO se escribe. La pantalla acompaña a la barra y se siente
       como una app, que es lo que pidió Marc.
     · svh donde SÍ se escribe. El teclado también encoge la altura dinámica,
       así que con dvh la caja se recoloca mientras se teclea. Un formulario
       que se mueve bajo los dedos es peor que un hueco de 60 px.
   Y siempre las dos, en este orden: el navegador que no entienda dvh se queda
   con svh, que es la que nunca corta. */
#raiz{ min-height:calc(100svh / var(--zoom, 1)); min-height:calc(100dvh / var(--zoom, 1)) }
/* 🔴 LA VENTANA YA NO SE DESPLAZA: SE DESPLAZA LA APP. Con la página entera
   moviéndose, la cabecera se iba hacia arriba, la barra del navegador entraba
   y salía, y la barra de desplazamiento del sistema cruzaba la pantalla por la
   derecha. Eso es una web. Ahora el único que se mueve es el cuerpo —.lienzo—
   y la cabecera se queda donde está sin ser `position:fixed`: es un hermano
   que no está dentro de lo que se desplaza, que se sostiene solo.
   ⚠️ Las pantallas SIN .cola —la pública— siguen desplazándose en la ventana,
   y por eso esto no está en `html`: está en el body de las que tienen app. */
body:has(.cola){ overflow:hidden }
/* 🔴 #90 · TODO MÁS GRANDE EN EL MÓVIL · Marc, 12/09/2026: «un hombre con dedos
   gruesos no puede clicar bien ni leer bien lo actual; súbelo hasta que sea
   ideal». Hay 95 tamaños de letra de 10 a 13 px escritos uno a uno; subirlos
   de uno en uno es 95 sitios y 95 oportunidades de desigualar. Se sube TODO
   de golpe con `zoom` en la raíz, que escala letra, botones, márgenes y
   huecos a la vez —lo que se toca y lo que se lee crecen juntos—: un 10 %.
   Los botones de 40 px pasan a 44 (el mínimo táctil de Apple), la letra de
   13 a 14,3. Medido en pruebas a 414: sin desbordamiento horizontal en las
   cuatro pantallas. Solo en el móvil: el escritorio tiene su propia rejilla
   (#72) y se lee de más lejos con ratón, no con el dedo. */
/* 🔴 A (Marc, 12/09/2026) · EL ZOOM Y LAS ALTURAS DE VIEWPORT NO SE LLEVAN BIEN.
   Medido a 414×896: `100dvh` dentro de una raíz con zoom 1.1 mide 896 px de
   CSS que se pintan a 985 → la app era un 10 % más alta que la pantalla y la
   ventana podía desplazarse 90 px (en iOS, que ignora el overflow:hidden del
   body, con el dedo): o se perdía la cabecera o no se llegaba al final. Todo
   alto de viewport se divide por --zoom, que vale 1 donde no hay zoom. */
@media (max-width:640px){ html{ zoom:1.1; --zoom:1.1 } }
body{ background:var(--background); color:var(--foreground); overflow-y:auto; overflow-x:hidden;
  font-family:var(--font-sans);
  -webkit-font-smoothing:antialiased; -moz-osx-font-smoothing:grayscale;
  letter-spacing:-.012em }
a{ color:inherit; text-decoration:none }
button{ font-family:inherit; font-size:inherit; color:inherit; background:none; border:0; cursor:pointer }
input,textarea{ font-family:inherit }
svg{ display:block; flex:none }

/* ══ LA BASE DE SHADCN ═════════════════════════════════════════════════════
   Bajada del registro público (estilo new-york-v4) y traducida. Cada bloque
   lleva al lado las clases de utilidad de las que sale, para poder cotejarlo.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Card · "flex flex-col gap-6 rounded-xl border bg-card py-6 text-card-foreground shadow-sm"
   El relleno LATERAL lo pone AQUÍ y solo aquí. Ver la nota de abajo. */
[data-slot="card"]{ display:flex; flex-direction:column; gap:24px; padding:26px 20px;
  border:1px solid var(--border); border-radius:var(--radius-xl);
  background:var(--card); color:var(--card-foreground);
  box-shadow:0 1px 3px 0 rgb(0 0 0/.1), 0 1px 2px -1px rgb(0 0 0/.1) }

/* 🔴 EL RELLENO LATERAL SE PAGABA DOS VECES. shadcn lo reparte: la tarjeta
   pone el de arriba y abajo (`py-6`) y cada hijo pone el suyo a los lados
   (`px-6`). Sumado a un relleno lateral en la tarjeta son 24+24 = 48 px que
   se le quitan al campo por dentro sin que se vean por fuera.
   Con la tarjeta a 356 px eso deja el campo en 267; poniéndolo una sola vez
   pasa a 314. Cuarenta y siete píxeles de diferencia, que es exactamente lo
   que hacía que un correo de treinta letras se cortara.
   Los hijos van a CERO a los lados. El relleno vive en un solo sitio. */
[data-slot="card-header"]{ display:grid; grid-auto-rows:min-content; align-items:start;
  gap:8px; padding:0 0 4px }
[data-slot="card-content"]{ padding:0 }
[data-slot="card-footer"]{ display:flex; align-items:center; padding:0 }

/* CardTitle · «Entra» es el título del panel, no una etiqueta más.
   La escala manda: marca 34 › título 23 › etiquetas 14. */
[data-slot="card-title"]{ font-size:23px; line-height:1.15; font-weight:600;
  letter-spacing:-.026em; text-align:center }
/* CardDescription · "text-sm text-muted-foreground" */
[data-slot="card-description"]{ font-size:14px; line-height:20px; color:var(--muted-foreground);
  text-align:center }

/* FieldGroup · la separación entre campos */
[data-slot="field-group"]{ display:flex; width:100%; flex-direction:column; gap:22px }
/* Field (vertical) · "flex w-full gap-3 flex-col [&>*]:w-full" */
[data-slot="field"]{ display:flex; width:100%; flex-direction:column; gap:12px }
[data-slot="field"] > *{ width:100% }
/* FieldLabel · "flex w-fit gap-2 leading-snug" + Label "text-sm font-medium" */
[data-slot="field-label"]{ display:flex; width:fit-content; gap:8px; line-height:1.375;
  font-size:14px; font-weight:500 }
/* FieldDescription · "text-sm leading-normal font-normal text-muted-foreground" */
[data-slot="field-description"]{ font-size:14px; line-height:1.5; font-weight:400;
  color:var(--muted-foreground) }
[data-slot="field-description"] a{ text-decoration:underline; text-underline-offset:4px }
@media (hover:hover){ [data-slot="field-description"] a:hover{ color:var(--primary) } }

/* Input · "h-9 w-full min-w-0 rounded-md border border-input bg-transparent px-3 py-1
            text-base shadow-xs transition-[color,box-shadow] outline-none md:text-sm" */
[data-slot="input"]{ width:100%; min-width:0; padding:4px 12px;
  /* 🔴 EL BORDE DE UN CAMPO ES LO ÚNICO QUE DICE DÓNDE SE ESCRIBE, y no se
     veía: medido, 1,22 en oscuro y 1,20 en claro contra un listón de 3,0.
     Sube a un color propio en vez de tocar --input, que lo usa media
     interfaz — tarjetas, tablas, separadores— y subirlo entero convertiría
     el producto en una rejilla.
     Medido DONDE ESTÁ EL CAMPO y no donde uno cree (ver LEY 35 y el borde de
     los botones, que se midió dos veces por eso mismo). */
  border:1px solid var(--borde-campo); border-radius:var(--radius-md);
  color:inherit; font-size:14px; outline:none;
  box-shadow:0 1px 2px 0 rgb(0 0 0/.05);
  transition:color .15s ease, box-shadow .15s ease, border-color .15s ease }
[data-slot="input"]::placeholder{ color:var(--muted-foreground) }
[data-slot="input"]:disabled{ pointer-events:none; cursor:not-allowed; opacity:.5 }

/* Button · "inline-flex shrink-0 items-center justify-center gap-2 rounded-md text-sm
            font-medium whitespace-nowrap transition-all outline-none" + size default h-9 px-4 py-2 */
[data-slot="button"]{ display:inline-flex; flex:none; align-items:center; justify-content:center;
  gap:8px; padding:8px 16px; border:1px solid transparent; border-radius:var(--radius-md);
  font-size:14px; font-weight:500; white-space:nowrap; outline:none;
  box-shadow:none }   /* D · la transición la pone el molde, al final */
[data-slot="button"]:disabled{ pointer-events:none; opacity:.5 }
[data-slot="button"] svg{ pointer-events:none; flex:none; width:16px; height:16px }
[data-slot="button"][data-variant="default"]{ background:var(--primary); color:var(--primary-foreground) }
@media (hover:hover){ [data-slot="button"][data-variant="default"]:hover{ background:color-mix(in srgb, var(--primary) 90%, transparent) } }
/* outline · "border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground
              dark:border-input dark:bg-input/30 dark:hover:bg-input/50"
   ⚠️ LA CAPA `dark:` NO ES ADORNO. Con el `bg-background` de la variante clara,
   en oscuro el botón se pinta del NEGRO DEL BODY encima de una tarjeta que es
   #0A0A0C: deja de parecer un botón y parece un agujero. Se vio en el cuadro
   de «¿Sin contraseña?». */
/* 🔴 EL BORDE DE LOS «outline» SUBE A 3,0 DE CONTRASTE · 08/09/2026.
   Un botón outline no tiene fondo propio: su borde ES el botón. Medido con el
   medidor ya probado (ver LEY 35), el borde daba **1,32** en oscuro y **1,23**
   en claro — o sea, casi invisible: se lee el texto pero no parece un botón, y
   un botón que no parece botón no lo pulsa nadie.
   La WCAG pide 3,0 para lo que no es texto. Con el fondo real de cada tema
   —#0A0A0C y #FAFAFA— eso son estos dos, medidos uno a uno:
       oscuro  #626272 → 3,12     claro  #8E8E9D → 3,09
   ⚠️ El de oscuro se midió DOS VECES: #5F5F6E daba 3,07 sobre el fondo de la
   página (#0A0A0C) y 2,98 sobre el del cuadro de diálogo (rgb 18,18,22), que
   es un pelo más claro. Se mide donde está el botón, no donde uno cree.
   ⚠️ Es un borde bastante más marcado que el de shadcn, y es a propósito: lo
   otro era un adorno. Las variables --input y --border NO se tocan, que las usa
   media interfaz; esto es solo el borde de estos botones.
   ⏳ Quedan fuera, y son decisión de Marc: los bordes de los CAMPOS (1,2 en las
   dos), el botón «Ver más» de Propietarios y las pestañas de admin. */
[data-slot="button"][data-variant="outline"]{ border-color:#6E6E82;
  background:color-mix(in srgb, var(--input) 30%, transparent);
  box-shadow:0 1px 2px 0 rgb(0 0 0/.05) }
@media (hover:hover){ [data-slot="button"][data-variant="outline"]:hover{
  background:color-mix(in srgb, var(--input) 50%, transparent) } }
html[data-tema="claro"] [data-slot="button"][data-variant="outline"]{
  border-color:#80808E; background:var(--background) }
@media (hover:hover){ html[data-tema="claro"] [data-slot="button"][data-variant="outline"]:hover{
  background:var(--accent); color:var(--accent-foreground) } }
[data-slot="button"][data-variant="ghost"]{ background:none }
@media (hover:hover){ [data-slot="button"][data-variant="ghost"]:hover{ background:var(--accent); color:var(--accent-foreground) } }
[data-slot="button"][data-size="icon"]{ width:36px; height:36px; padding:0 }
/* 🔴 EL TAMAÑO PEQUEÑO · #61 y #62 de la pasada de Marc, 08/09/2026: «el
   botón de Tu equipo parece texto» y «devolver a su lista / a la lista
   general parecen texto». Eran dos sitios con su propio CSS de «botón sin
   borde», o sea texto con cursor. Un botón es un botón del sistema; lo que
   les faltaba era un tamaño que cupiera en una línea de ficha. Es el `sm`
   de shadcn (h-8, px-3) con la letra de 13 px que ya usaban. */
[data-slot="button"][data-size="sm"]{ height:32px !important; padding:0 12px; font-size:13px; gap:6px }

/* Badge outline · "inline-flex w-fit items-center justify-center gap-1 rounded-full border
                    px-2 py-0.5 text-xs font-medium" + "border-border text-foreground" */
[data-slot="badge"]{ display:inline-flex; width:fit-content; flex:none; align-items:center;
  justify-content:center; gap:4px; overflow:hidden; padding:2px 8px;
  border:1px solid var(--border); border-radius:9999px;
  font-size:12px; line-height:16px; font-weight:500; white-space:nowrap; color:var(--foreground) }
[data-slot="badge"] svg{ width:12px; height:12px; pointer-events:none }

/* ══ EL PUNTO DE LA MARCA ══════════════════════════════════════════════════
   CLASE DE SISTEMA, no del acceso. El punto de «Novoconect.» va con `.punto`
   en TODAS las pantallas. Los colores no son de gusto: salen del propio fondo
   —el #E100FF es el color2 del Soft Aurora— y el recorrido pasa por donde pasa
   la aurora, hasta el casi blanco del color1 y de vuelta.

   Veinticuatro segundos es a propósito: tan lento que no se ve moverse, solo
   se nota que no es el mismo de hace un rato. Un latido rápido sería un adorno
   pidiendo atención en la pantalla donde alguien está tecleando su contraseña.
   ═══════════════════════════════════════════════════════════════════════════ */
@keyframes latido-marca{
  0%{color:#E100FF} 20%{color:#A66BFF} 40%{color:#5C8CFF}
  60%{color:#F2F2F7} 80%{color:#FF5CB0} 100%{color:#E100FF}
}
.punto{ animation: latido-marca 24s ease-in-out infinite }
@media (prefers-reduced-motion: reduce){
  .punto{ animation:none; color:#E100FF }
}

/* ══ LA MUESCA DEL MÓVIL ═══════════════════════════════════════════════════
   CLASES DE SISTEMA. Lo que va pegado al borde de arriba o de abajo lleva
   `.techo` o `.suelo` y deja de meterse debajo de la muesca o de la barra
   del gesto.

   ⚠️ `env(safe-area-inset-*)` vale CERO si el `<meta viewport>` no lleva
   `viewport-fit=cover`. Sin eso el navegador no pinta bajo el borde, así que
   no hay hueco que compensar y estas dos reglas se quedan en los 14 px.
   Comprobado: de las ocho pantallas del producto lo llevan siete. La que no
   es producto.html, y ahí NO se ha añadido a propósito —ver docs—.

   Los 14 px son el suelo, no el techo: en un móvil sin muesca `env()` da 0 y
   sin el `max()` lo pegado al borde se quedaría pegado al borde.
   ═══════════════════════════════════════════════════════════════════════════ */
.techo{ padding-top: max(14px, env(safe-area-inset-top)) }
.suelo{ padding-bottom: max(14px, env(safe-area-inset-bottom)) }

/* ══ EL MOLDE DEL BOTON ═════════════════════════════════════════════════════
   Las tres cosas que hace un boton al pulsarlo. Salen de la pagina de efectos
   que mando Marc el 07/09/2026; lo que las dispara vive en boton.js y aqui
   esta como se ven.

   ⚠️ Van sobre `[data-slot="button"]`, que es como se marcan los botones del
   sistema nuevo, y NO sobre `button` a secas: hay botones que no son botones
   —las pestañas de abajo, la equis de cerrar, las tres rayas— y hundirlos al
   pulsar los convertiria en otra cosa.

   ⚠️ Y EL SISTEMA VIEJO YA TIENE EL SUYO, que no se toca: ui.css hunde a .97
   con la luz champan, y eso es una ley de Marc —«el tacto sale del boton
   + Añadir»—. Aqui es .965 porque es lo que dice la maqueta nueva. Dos numeros
   a la vez mientras dure la migracion, uno cuando termine; lo que NO puede
   haber es dos dentro del mismo sistema, que es como estaba antes de esa ley. */
:root{ --hunde:.965 }   /* uno solo para todo el sistema nuevo */
/* 🔴 #94 · LA CURVA NO EXISTÍA · 12/09/2026. Once transiciones de esta hoja
   dicen `var(--curva)` —las tres líneas del menú, el hundido de los botones,
   los botones de devolver…— y `--curva` no estaba definida en ningún sitio:
   una variable que no existe invalida la transición ENTERA (medido: el
   navegador daba «0s» para `.tres path`). Por eso las tres líneas «se convertían
   en X» a golpe (#36 dijo que giraban, y no giraban), y por eso Marc lo llama
   brusco. Es la curva del sistema, la de la maqueta de Marc (`.entra`) y la
   única que admite la prueba 15. */
:root{ --curva:cubic-bezier(.16,1,.3,1) }

/* 🔴 D · UN SOLO LENGUAJE DE PULSACIÓN · Marc, 12/09/2026: «el efecto bueno es
   el de Volver a Equipo… sácalo a un único estilo compartido y aplícalo a TODOS
   los elementos pulsables». Ese botón no tiene nada propio: es este molde
   ([data-slot="button"]). Lo que no es un botón del sistema pero se pulsa
   —las pestañas de arriba, las de abajo del agente, las tarjetas del equipo,
   los chips— lleva `data-pulsa` y recibe EXACTAMENTE lo mismo: se hunde a
   --hunde con --curva y marca dónde le has dado (la onda, boton.js). Se
   define aquí y en ningún otro sitio. */
/* 1 · SE HUNDE · las reglas están AL FINAL de esta hoja (§ EL MOLDE, AL FINAL):
   así ganan a cualquier `transition` escrita antes para un botón concreto
   (.chip, .icono-btn…), que es como se cuelan dos lenguajes. */

/* 2 · MARCA DONDE LE HAS DADO. El circulo sale de las coordenadas del dedo y
   se borra solo al acabar. `isolation` y `overflow` son los que lo mantienen
   dentro del boton; sin ellos se desborda y pinta una mancha en la pantalla. */
:is(button, [data-slot="button"], [data-onda], [data-pulsa]){ position:relative; overflow:hidden; isolation:isolate }
/* 🔴 10/10 · Marc: nada de fondo gris al tocar lo que no tiene borde. El navegador del teléfono
   (Safari en el iPhone) pinta su propio rectángulo gris sobre TODO lo que se toca: aquí no se
   había apagado. Se apaga entero; el «te he oído» lo dicen el hundimiento y, en lo que tiene
   forma, la onda (boton.js). */
*, *::before, *::after{ -webkit-tap-highlight-color:transparent }
.onda{ position:absolute; border-radius:50%; transform:scale(0); pointer-events:none;
  background:currentColor; opacity:.22; animation:onda .55s var(--curva) forwards }
@keyframes onda{ to{ transform:scale(2.4); opacity:0 } }

/* 3 · DICE QUE ESTA TRABAJANDO. El texto se va y queda la ruedecita, asi el
   boton no cambia de tamaño y la fila no salta. */
/* 🔴 #76 · EL BOTÓN BLANCO, TERCERA CARA · Marc, 12/09/2026: «al clicar el CTA de
   crear contraseña, y el de Enviar la invitación, desaparece el texto y el
   CTA se ve todo blanco… es como que el loader sale en blanco». Medido: los
   botones que traen su PROPIA ruedecita (login, activar, Añadir) llevaban
   `color:inherit !important` para escapar del transparente de abajo, y
   `inherit` es el color del PADRE —el blanco de la hoja—, no el negro del
   botón principal: texto blanco y rueda blanca sobre el botón blanco. No es
   que se fuera el texto: es que no se veía. Ahora el transparente solo va a
   los botones sin rueda propia, y los otros conservan su color de siempre. */
[data-cargando]{ pointer-events:none; position:relative }
[data-cargando]:not([data-rueda]){ color:transparent !important }
[data-cargando]:not([data-rueda])::after{ content:""; position:absolute; inset:0; margin:auto;
  width:16px; height:16px; border:2px solid currentColor; border-top-color:transparent;
  border-radius:50%; color:var(--foreground); animation:gira .7s linear infinite }
[data-slot="button"][data-variant="default"][data-cargando]:not([data-rueda])::after{ color:var(--primary-foreground) }
@keyframes gira{ to{ transform:rotate(1turn) } }

/* El anillo de foco de shadcn: "focus-visible:border-ring focus-visible:ring-[3px] ring-ring/50" */
[data-slot="button"]:focus-visible,[data-slot="badge"]:focus-visible{
  border-color:var(--ring); box-shadow:0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent) }

/* ══ Y ENCIMA, LA CAPA DE MARC · copiada tal cual ══════════════════════════ */

/* SHARP: tarjeta sólida, sin cristal, con canto de 1 px nítido */
[data-slot="card"]{
  background:var(--card) !important;
  border:1px solid var(--border) !important;
  border-radius:14px !important;
  backdrop-filter:none !important; -webkit-backdrop-filter:none !important;
  box-shadow: 0 0 0 1px rgba(0,0,0,.55), 0 24px 60px -18px rgba(0,0,0,.85);
}
html[data-tema="claro"] [data-slot="card"]{ box-shadow: 0 1px 2px rgba(8,8,10,.06), 0 18px 44px -20px rgba(8,8,10,.22) }
/* el filo de luz de arriba, que es lo que da el aire caro */
[data-slot="card"]::before{ content:""; position:absolute; inset:0 0 auto; height:1px; border-radius:14px 14px 0 0;
  background:linear-gradient(90deg,transparent,rgba(247,247,247,.16),transparent) }
[data-slot="card"]{ position:relative }
html[data-tema="claro"] [data-slot="card"]::before{ background:linear-gradient(90deg,transparent,rgba(8,8,10,.08),transparent) }

[data-slot="card-title"]{ letter-spacing:-.024em; font-weight:600 }
[data-slot="input"]{ border-radius:9px !important; background:var(--secondary) !important; height:40px }
/* 29/09 · EL CAMPO DE FECHA ES NUESTRO (fecha.js). El control nativo se salía de su caja en
   el iPhone y luego no centraba su texto: con CSS no se le puede mandar del todo. Ahora la
   caja es el campo del sistema y el texto lo pintamos nosotros, centrado; el <input date>
   va encima, del mismo tamaño y transparente, para que el toque abra el selector del
   teléfono. Nada del control nativo se ve, así que ya no hay nada suyo que se salga. */
.campo-fecha{ position:relative; display:flex; align-items:center; justify-content:center; cursor:pointer;
  box-sizing:border-box; min-width:0 }
.campo-fecha .valor{ pointer-events:none; text-align:center; font-variant-numeric:tabular-nums;
  white-space:nowrap; overflow:hidden; text-overflow:ellipsis }
.campo-fecha.vacio .valor{ color:var(--muted-foreground) }
.campo-fecha > input[type="date"]{ position:absolute; inset:0; width:100%; height:100%; min-width:0; margin:0; padding:0;
  border:0; opacity:0; -webkit-appearance:none; appearance:none; box-sizing:border-box; cursor:pointer; font-size:16px }
.campo-fecha:focus-within{ border-color:var(--ring) !important;
  box-shadow:0 0 0 3px color-mix(in srgb, var(--ring) 22%, transparent) }
[data-slot="input"]:focus-visible{ outline:none; border-color:var(--ring) !important;
  box-shadow:0 0 0 3px color-mix(in oklch, var(--ring) 22%, transparent) }
[data-slot="button"]{ border-radius:9px !important; font-weight:500; height:40px }

.entra{ animation:sube .8s cubic-bezier(.16,1,.3,1) both }
@keyframes sube{ from{opacity:0; transform:translateY(12px)} to{opacity:1; transform:none} }
.vineta{ position:fixed; inset:0; z-index:1; pointer-events:none;
  background:radial-gradient(120% 90% at 50% 42%, transparent 30%, #000 100%) }
html[data-tema="claro"] .vineta{ background:radial-gradient(120% 90% at 50% 42%, transparent 40%, rgba(250,250,250,.85) 100%) }

/* MÓVIL */
@media (max-width: 480px){
  [data-slot="card"]{ border-radius:16px !important }
  .vineta{ background:radial-gradient(140% 70% at 50% 40%, transparent 22%, #000 100%) }
}
/* si alguien prefiere no ver movimiento, se lo respetamos */
@media (prefers-reduced-motion: reduce){
  .entra{ animation:none }
}

/* dedo, no ratón: 44 px mínimo en zonas táctiles */
@media (max-width: 640px){
  [data-slot="input"]{ height:44px; font-size:16px }   /* 16px evita que iOS haga zoom al enfocar */
  [data-slot="button"]{ height:44px }
  .ojo{ height:44px !important; width:44px !important }
  /* si el ojo mide 44, el hueco del texto también: con 40 la última letra de
     una contraseña larga se metía debajo del icono */
  [data-slot="input"].con-hueco{ padding-right:44px }
  [data-slot="card"]{ padding-left:18px; padding-right:18px }
}

/* La regla por altura de pantalla va AL FINAL del fichero. Ver allí. */

/* ══ EL FONDO ══════════════════════════════════════════════════════════════
   El .jsx traía un `import './SoftAurora.css'` que no venía en el envío. Son
   las dos reglas que ese fichero tiene que llevar: llenar al padre y que el
   canvas no deje el hueco de línea base de los elementos en línea.
   ═══════════════════════════════════════════════════════════════════════════ */
.aurora{ position:fixed; inset:0; z-index:0 }
.aurora canvas{ display:block; width:100%; height:100% }

/* ══ EL AVISO · lo que en la maqueta hacía `sonner` ════════════════════════ */
.avisos{ position:fixed; top:16px; left:50%; transform:translateX(-50%);
  z-index:60; display:flex; flex-direction:column; gap:8px; align-items:center;
  width:min(420px, calc(100vw - 32px)); pointer-events:none }
.aviso{ width:100%; display:flex; gap:10px; align-items:flex-start;
  padding:12px 14px; border-radius:10px; border:1px solid var(--border);
  background:var(--popover); color:var(--popover-foreground);
  box-shadow:0 10px 30px -12px rgba(0,0,0,.6);
  font-family:var(--font-sans); font-size:13.5px; line-height:1.45;
  animation:aviso-entra .28s cubic-bezier(.16,1,.3,1) both }
.aviso.se-va{ animation:aviso-sale .2s ease forwards }
.aviso b{ display:block; font-weight:600 }
.aviso span{ display:block; color:var(--muted-foreground) }
/* richColors: el error se tiñe, el resto no */
.aviso.malo{ border-color:color-mix(in srgb, var(--destructive) 45%, var(--border));
  color:var(--destructive) }
.aviso.malo span{ color:color-mix(in srgb, var(--destructive) 72%, var(--muted-foreground)) }
.aviso svg{ width:16px; height:16px; margin-top:1px }
@keyframes aviso-entra{ from{opacity:0; transform:translateY(-10px)} to{opacity:1; transform:none} }
@keyframes aviso-sale{ to{opacity:0; transform:translateY(-8px)} }
@media (prefers-reduced-motion: reduce){ .aviso,.aviso.se-va{ animation:none } }

/* ══ EL ACCESO ═════════════════════════════════════════════════════════════
   Las medidas salen de acceso.jsx y formulario-acceso.jsx, clase de utilidad
   a clase de utilidad.
   ═══════════════════════════════════════════════════════════════════════════ */

/* "fixed top-4 right-4 z-20 size-9 grid place-items-center rounded-lg border
    bg-card text-muted-foreground transition hover:text-foreground" */
.conmuta-tema{ position:fixed; top:16px; right:16px; z-index:20; width:36px; height:36px;
  display:grid; place-items:center; border-radius:var(--radius-lg);
  border:1px solid var(--border); background:var(--card); color:var(--muted-foreground);
  transition:color .15s ease }
@media (hover:hover){ .conmuta-tema:hover{ color:var(--foreground) } }
.conmuta-tema svg{ width:16px; height:16px }

/* 20 px por los cuatro lados y CENTRADO A SECAS.
   ⛔ AQUÍ HUBO UN CENTRADO ÓPTICO —9vh de más abajo— Y ESTABA MAL. No por la
   idea, por la aritmética: 9vh son 60 px en un iPhone SE y 84 en un Pro Max,
   y encima por debajo de 720 px de alto se apagaba. Tres alturas distintas
   para la misma pantalla, y se notaba pasando de un móvil a otro.
   Centrado limpio, medido en siete tamaños: 0 px de diferencia entre el hueco
   de arriba y el de abajo en las siete. */
/* ⚠️ SVH A PROPÓSITO, Y NO ES UN OLVIDO. Aquí hay dos campos y un teclado: con
   dvh, al abrirse el teclado la altura cambia y la tarjeta —que está CENTRADA—
   se recoloca mientras el dedo escribe. El hueco de la barra se ve; el salto
   se sufre. */
.acceso{ position:relative; z-index:10; display:grid; min-height:calc(100svh / var(--zoom, 1)); place-items:center;
  padding:20px }
/* `min-width:0` NO es adorno. Un elemento de rejilla trae `min-width:auto`, o
   sea que se niega a encogerse por debajo de su contenido: con el texto del
   sistema agrandado a 24 px, la tarjeta se salía 32 px por la derecha en una
   pantalla de 320. Con esto encoge y lo de dentro se reparte. */
.acceso-caja{ width:100%; max-width:356px; min-width:0 }
/* Un campo trae ancho propio por el atributo `size` (20 caracteres). A 24 px
   eso son casi 250 px que nadie pidió y que empujan la tarjeta. */
[data-slot="input"]{ min-width:0 }

.marca{ margin-bottom:28px; text-align:center }
/* "text-[34px] leading-[1.05] font-semibold tracking-[-.045em] sm:text-[40px]" */
.marca h1{ font-size:34px; line-height:1.05; font-weight:600; letter-spacing:-.045em }
@media (min-width:640px){ .marca h1{ font-size:40px } }
/* "mt-2 text-[13.5px] text-muted-foreground sm:text-[14px]" */
.marca p{ margin-top:8px; font-size:13.5px; color:var(--muted-foreground) }
@media (min-width:640px){ .marca p{ font-size:14px } }

/* LA FILA DE DEBAJO DE LA CLAVE, donde está hoy: «Recuérdame» a la izquierda y
   «¿Has olvidado la contraseña?» a la derecha. La maqueta ponía el enlace
   arriba, pegado a la etiqueta; se queda donde el producto lo tiene.
   "flex items-center" + "ml-auto text-[12.5px] text-muted-foreground" */
/* `flex-wrap` para el caso extremo: con el texto del sistema agrandado a 24 px
   en una pantalla de 320, «Recuérdame» y «¿Has olvidado la contraseña?» no
   caben en la misma línea y el segundo se salía por la derecha. Bajando de
   línea no se pierde nada. En las medidas normales caben las dos —medido: 17,9
   px de hueco a 375— así que esto no mueve un píxel del diseño aprobado. */
.fila-recuerda{ display:flex; align-items:center; gap:12px; margin-top:4px; flex-wrap:wrap }
/* ⛔ AQUÍ HUBO UN BOTÓN `.olvide` QUE ABRÍA UN CUADRO, y el cuadro se borró
   el 08/09/2026 por orden de Marc. Lo que queda es un TEXTO con la dirección
   dentro: nada que rellenar, nada que abrir.
   ⚠️ Ya NO lleva `margin-left:auto` ni `text-align:right`: como botón corto
   se iba a la derecha de la fila; como frase de dos líneas eso lo dejaba
   descolgado. Ocupa su ancho y se lee de izquierda a derecha, como un texto. */
/* El enlace que lo despliega: en su sitio de siempre, a la derecha de la fila. */
.olvide{ margin-left:auto; font-size:12.5px; text-align:right;
  color:var(--muted-foreground); text-underline-offset:4px }
@media (hover:hover){ .olvide:hover{ color:var(--foreground); text-decoration:underline } }
/* Y el texto que aparece debajo. No es un cuadro: es parte de la pantalla. */
.olvide-txt{ margin:10px 0 0; padding:11px 13px; border-radius:9px;
  background:var(--muted, rgba(127,127,140,.10)); font-size:12.5px; line-height:1.6;
  color:var(--muted-foreground) }
.olvide-txt .enlace{ color:var(--foreground); text-underline-offset:4px }

/* EL AVISO DE ERROR SE QUEDA PUESTO. Hoy es un bloque que no se va solo, y
   quitarlo por un aviso flotante sería perder función: el que falla al entrar
   tiene que poder leerlo mientras vuelve a escribir. Cambia cómo se ve, no
   cuánto dura. */
.err{ display:none; gap:9px; align-items:flex-start; margin-top:-8px;
  padding:10px 12px; border-radius:9px;
  border:1px solid color-mix(in srgb, var(--destructive) 40%, var(--border));
  background:color-mix(in srgb, var(--destructive) 9%, var(--card));
  color:var(--destructive); font-size:13px; line-height:1.45 }
.err.on{ display:flex }
.err svg{ width:15px; height:15px; margin-top:1px; stroke:currentColor }

/* el ojo, dentro del campo · "absolute right-0 top-0 grid h-10 w-10 place-items-center" */
.con-ojo{ position:relative }
.ojo{ position:absolute; right:0; top:0; width:40px; height:40px; display:grid;
  place-items:center; color:var(--muted-foreground); transition:color .15s ease }
@media (hover:hover){ .ojo:hover{ color:var(--foreground) } }
.ojo svg{ width:16px; height:16px }
[data-slot="input"].con-hueco{ padding-right:40px }

/* «Recuérdame», donde está hoy: en la fila de debajo de los campos */
.recuerda{ display:flex; align-items:center; gap:8px; width:fit-content;
  font-size:13.5px; color:var(--muted-foreground); cursor:pointer }
.recuerda input{ position:absolute; opacity:0; width:0; height:0 }
.recuerda .marca-check{ width:16px; height:16px; display:grid; place-items:center;
  border:1px solid var(--input); border-radius:5px; background:var(--secondary);
  transition:background-color .15s ease, border-color .15s ease }
.recuerda .marca-check svg{ width:11px; height:11px; opacity:0; transition:opacity .12s ease;
  stroke:var(--primary-foreground) }
.recuerda input:checked + .marca-check{ background:var(--primary); border-color:var(--primary) }
.recuerda input:checked + .marca-check svg{ opacity:1 }
.recuerda input:focus-visible + .marca-check{ border-color:var(--ring);
  box-shadow:0 0 0 3px color-mix(in oklch, var(--ring) 22%, transparent) }
@media (hover:hover){ .recuerda:hover{ color:var(--foreground) } }

/* la ruedecita del botón mientras entra */
.rueda{ width:16px; height:16px; border-radius:50%; border:2px solid currentColor;
  border-right-color:transparent; animation:gira .7s linear infinite }
@keyframes gira{ to{ transform:rotate(360deg) } }
@media (prefers-reduced-motion: reduce){ .rueda{ animation-duration:2s } }

/* EL PIE, EN DOS FRASES. Y «¿Qué es Novoconect?» lejos, que era el mispulsado:
   pegado a «Escríbenos» se abría el correo cuando lo que se quería era leer
   qué es esto. Los 32 px de margen dejan unos 39 px de hueco entre los dos
   textos, contando el interlineado. */
.pie{ margin-top:24px; text-align:center; font-size:12.5px; line-height:1.65;
  color:var(--muted-foreground) }
.pie .enlace{ color:var(--foreground); text-decoration:underline; text-underline-offset:4px;
  font-size:inherit }
@media (hover:hover){ .pie .enlace:hover{ color:#e100ff } }
/* 36 px de margen, que con el interlineado dejan los 39 de HUECO. Y el número
   que importa es el hueco, no el margen: lo que se estaba midiendo mal era la
   distancia entre las dos cosas que se pulsan con el pulgar. */
.pie .que-es{ display:inline-block; margin-top:36px }

/* ══ ZONA DE TOQUE DE 24 px, SIN MOVER UN PÍXEL DE LO QUE SE VE ════════════
   El listón es WCAG 2.5.8, nivel AA: 24×24 px, con excepción para los enlaces
   que van DENTRO de una frase. Los 44×44 son el 2.5.5, nivel AAA, y solo se
   piden aquí para campos, botón y ojo.

   Así que «Escríbenos» y el «escríbenos» del cuadro NO se tocan: van dentro
   de una frase y la norma los exime. Suben estos tres, y suben por dentro:
   lo que se ve sigue midiendo 17 y 20,6 px, y lo que crece es un rectángulo
   invisible centrado encima. De 17 a 24 son 3,5 px por lado, así que no se
   pisan entre ellos ni invaden el campo de arriba.

   Un pseudo-elemento absoluto recibe el clic por su elemento: por eso amplía
   la zona sin cambiar la maquetación ni una décima.
   ═══════════════════════════════════════════════════════════════════════════ */
.olvide, .pie .que-es, .recuerda{ position:relative }
.olvide::after, .pie .que-es::after, .recuerda::after{
  content:""; position:absolute; left:0; right:0; top:50%;
  transform:translateY(-50%); height:24px;
}

/* ══ EL CUADRO DE «¿Has olvidado la contraseña?» ═══════════════════════════
   Se queda como está hoy: no es un enlace, es la respuesta a la duda.
   ═══════════════════════════════════════════════════════════════════════════ */
.velo{ position:fixed; inset:0; z-index:70; display:grid; place-items:center;
  padding:20px; background:rgba(0,0,0,.55);
  opacity:0; visibility:hidden; transition:opacity .22s ease, visibility .22s ease }
html[data-tema="claro"] .velo{ background:rgba(8,8,10,.32) }
.velo.on{ opacity:1; visibility:visible }
.cuadro{ width:100%; max-width:380px; padding:24px;
  border:1px solid var(--border); border-radius:14px; background:var(--card);
  box-shadow:0 24px 60px -18px rgba(0,0,0,.85);
  transform:translateY(10px); transition:transform .22s cubic-bezier(.16,1,.3,1) }
.velo.on .cuadro{ transform:none }
.cuadro h2{ font-size:17px; font-weight:600; letter-spacing:-.024em }
.cuadro p{ margin-top:12px; font-size:13.5px; line-height:1.55; color:var(--muted-foreground) }
.cuadro p b{ color:var(--foreground); font-weight:600 }
.cuadro .enlace{ color:var(--foreground); text-decoration:underline; text-underline-offset:4px;
  font-size:inherit }

/* EL CUADRO DE «CAMBIAR LA CONTRASEÑA» · el del acceso.
   Dos botones en fila con el principal a la derecha, que es donde lo busca la
   mano en un dialogo. En movil se apilan: a 380 px de ancho, dos botones con
   texto largo se pisan. */
.cuadro #olv-form{ margin-top:16px }
.cuadro .olv-botones{ display:flex; gap:10px; margin-top:16px; justify-content:flex-end }
.cuadro .olv-botones [data-slot="button"]{ flex:0 0 auto }
@media (max-width:420px){
  .cuadro .olv-botones{ flex-direction:column-reverse }
  .cuadro .olv-botones [data-slot="button"]{ width:100% }
}
/* La salida de la agencia sin cuenta: separada y mas pequenia, para que no
   compita con lo que ha venido a hacer aqui el 99% de la gente. */
.cuadro .olv-pie{ margin-top:18px; padding-top:14px; border-top:1px solid var(--border);
  font-size:12.5px }
@media (hover:hover){ .cuadro .enlace:hover{ color:#e100ff } }
.cuadro [data-slot="button"]{ margin-top:20px; width:100% }
@media (prefers-reduced-motion: reduce){
  .velo,.cuadro{ transition:none }
}

/* Nadie ve el foco con el ratón, pero con el teclado hace falta. */
:focus-visible{ outline:none }
a:focus-visible,.olvide:focus-visible,.pie .enlace:focus-visible,.cuadro .enlace:focus-visible{
  border-radius:4px; box-shadow:0 0 0 3px color-mix(in oklch, var(--ring) 45%, transparent) }

/* ══ 🔴 LA PANTALLA BAJA · Y VA LA ÚLTIMA, QUE NO ES UN DETALLE ════════════
   Un iPhone SE tiene 667 px de alto y con las medidas de arriba el login NO
   CABE: sale scroll en la pantalla donde solo hay que escribir dos cosas.
   Se recorta el AIRE —relleno, separación entre campos y el hueco de la
   marca— y nada más.

   ⚠️ ESTE BLOQUE ESTUVO A MITAD DEL FICHERO Y NO FUNCIONABA ENTERO. El
   `margin-bottom:14px` de la marca no llegaba nunca, porque `.marca` se
   declara más abajo con la misma especificidad y lo de después gana. Medido:
   la marca seguía en 28 px con la regla «aplicada». Una media query no sirve
   de nada si lo que quiere pisar se declara después que ella.

   ⛔ LO QUE NO SE RECORTA NUNCA SON LOS TOQUES. Campos, botón y ojo se quedan
   en 44 px en todas las medidas: una pantalla pequeña es justo donde peor se
   acierta con el dedo, así que encoger ahí sería hacerlo al revés.

   Aquí había una línea que apagaba el centrado óptico. Ya no hace falta:
   el centrado óptico se ha ido del todo, así que no hay nada que apagar y
   esta pantalla se centra igual que las demás.
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-height: 720px){
  [data-slot="card"]{ padding-top:20px; padding-bottom:20px }
  [data-slot="field-group"]{ gap:16px }
  .marca{ margin-bottom:14px }
}

/* ══════════════════════════════════════════════════════════════════════════
   LA COLA · /agente
   ──────────────────────────────────────────────────────────────────────────
   Un lead a la vez. No es una lista corta: es que la pantalla tiene UN trabajo
   —la siguiente llamada— y todo lo demás estorba.
   ══════════════════════════════════════════════════════════════════════════ */
/* La pantalla del agente no tiene ni un campo donde escribir —la nota vive en
   una hoja aparte—, así que aquí dvh no puede pelearse con ningún teclado y sí
   hace lo que se busca: la lista acompaña a la barra del navegador en vez de
   dejar un hueco muerto debajo. */
/* ⚠️ ALTO EXACTO, NO MÍNIMO. Con `min-height` el contenido empujaba la caja
   hacia abajo y volvía a desplazarse la ventana. Con `height` la caja mide lo
   que se ve y lo que sobra se desplaza DENTRO.
   ⚠️ Y menos la franja de la visita de administrador. Ese trozo lo publica
   cabeza.js en `--tope` porque su alto depende de lo largo que sea el nombre
   de la agencia: con un número escrito a mano, una agencia de nombre largo
   parte el texto en dos líneas y la pantalla se sale por abajo. */
.cola{ display:flex; flex-direction:column;
  height:calc(100svh / var(--zoom, 1)); height:calc(100dvh / var(--zoom, 1) - var(--tope, 0px)) }

.cabecera{ display:flex; align-items:center; gap:6px; padding-left:20px; padding-right:14px;
  padding-bottom:12px }
.cabecera .marca-txt{ font-size:15px; font-weight:600; letter-spacing:-.035em }
.cabecera .hueco{ margin-left:auto }
.icono-btn{ width:36px; height:36px; display:grid; place-items:center; border-radius:9px;
  color:var(--muted-foreground) }   /* D · la transición la pone el molde */
@media (hover:hover){ .icono-btn:hover{ color:var(--foreground); background:var(--secondary) } }
.icono-btn svg{ width:18px; height:18px }
@media (max-width:640px){ .icono-btn{ width:44px; height:44px } }

/* el progreso: una barra fina y una frase. Sin número encima. */
.progreso{ padding:0 20px }
.barra{ height:3px; width:100%; border-radius:999px; background:var(--secondary); overflow:hidden }
.barra i{ display:block; height:100%; border-radius:999px; background:var(--foreground);
  transition:width .7s cubic-bezier(.16,1,.3,1) }
.quedan{ margin-top:14px; font-size:13.5px; color:var(--muted-foreground) }
.quedan b{ color:var(--foreground); font-weight:400; font-variant-numeric:tabular-nums }
/* #30 · lo intentado y no cerrado, debajo de «te quedan N». En tono aun mas
   bajo que la frase de arriba: es contexto, no lo que hay que hacer ahora. */
.aparte{ margin-top:4px; font-size:12.5px; color:var(--muted-foreground); opacity:.8;
  font-variant-numeric:tabular-nums }

/* EL CUERPO · lo único que se mueve.
   ⚠️ `min-height:0` NO es adorno: un elemento de una caja flexible se niega a
   encogerse por debajo de su contenido, así que sin esto `flex:1` no le da
   una altura con la que desplazarse y el desbordamiento se lo vuelve a comer
   la ventana. Es el mismo detalle que en el acceso con `min-width`.
   ⚠️ `overscroll-behavior:contain` es lo que impide que al llegar al final se
   arrastre la página de detrás — el «rebote» que en un móvil se siente como
   que la app se despega.
   ⛔ Y NADA DE `scroll-snap-type: mandatory` AQUÍ. Marc lo pidió para
   «deslizarse de pantalla en pantalla», y eso vale para secciones que ocupan
   la pantalla entera; en una lista de cuarenta propietarios, un enganche
   obligatorio secuestra el dedo y no deja parar donde uno quiere. Si se quiere
   ese tacto, su sitio es la página pública, que sí tiene secciones. */
.lienzo{ flex:1; min-height:0; overflow-y:auto; overscroll-behavior:contain;
  width:100%; max-width:32rem; margin:0 auto; padding:20px 20px 28px }
/* 🔴 #72 · EN EL ESCRITORIO LA RUEDA DESPLAZA DESDE CUALQUIER SITIO · Marc,
   11/09/2026: «no se puede hacer scroll hacia abajo». Medido a 1440×900: la
   página no desplaza (900/900), lo que desplaza es esta columna de 32 rem, y
   la rueda con el ratón fuera de ella —484 px de margen a cada lado— no movía
   nada. La columna pasa a ocupar el ancho entero y el contenido se centra con
   el relleno: la rueda desplaza en cualquier punto y la lista sigue donde
   estaba (mismo ancho, misma x). */
@media (min-width:640px){
  .lienzo{ max-width:none; padding-left:max(20px, calc((100% - 32rem) / 2));
    padding-right:max(20px, calc((100% - 32rem) / 2)) }
}

/* 🔴 #97 · EN EL ESCRITORIO LAS BARRAS DE DESPLAZAMIENTO SE VEN · Marc,
   12/09/2026: «los desplegables de filtros deberían tener barra; y diría que
   no hay en ningún lado y debería: en la lista del agente no se puede bajar».
   Las barras se escondieron para el móvil (la de Windows era una franja gris
   de 15 px); a partir de 1024 px vuelven, finas y del color del producto, en
   todo lo que desplaza: la ventana, la columna, los desplegables y las hojas.
   Y la cola del agente desplaza también desde el margen (el mismo relleno
   centrador del #72). */
@media (min-width:1024px){
  html{ scrollbar-color:var(--muted-foreground) transparent }
  html, body, .lienzo, .elige-lista, .hoja, #h-cuerpo{ scrollbar-width:thin !important; scrollbar-color:color-mix(in srgb, var(--muted-foreground) 55%, transparent) transparent }
  body::-webkit-scrollbar, .lienzo::-webkit-scrollbar, .elige-lista::-webkit-scrollbar, .hoja::-webkit-scrollbar{ width:8px !important; height:8px }
  body::-webkit-scrollbar-thumb, .lienzo::-webkit-scrollbar-thumb, .elige-lista::-webkit-scrollbar-thumb, .hoja::-webkit-scrollbar-thumb{ background:color-mix(in srgb, var(--muted-foreground) 55%, transparent); border-radius:999px }
}

/* ══════════════════════════════════════════════════════════════════════════
   EL ESCRITORIO · #72(c) · Marc, 11/09/2026: «no está bien diseñado para
   desktop: no es visualmente agradable, pantalla centrada».
   ──────────────────────────────────────────────────────────────────────────
   Medido a 1440×900: una columna de 512 px en el centro y 464 px de negro a
   cada lado. Eso es el móvil ensanchado, no un escritorio. A partir de 1024 px
   el ancho se USA, sin cajas nuevas (ley: menos cajas) y sin tocar el HTML:
     · Propietarios · los mandos (cifra, buscador, zona, filtros, orden) a la
       izquierda, FIJOS mientras la lista corre a la derecha. Es lo que hace
       cualquier lista con filtros (Linear, Stripe): lo que se ajusta no se va
       con el scroll.
     · Mi equipo · las fichas de los agentes en DOS columnas: seis agentes se
       ven de un vistazo sin bajar.
     · La ficha del agente · lo que se decide (Hoy, Qué le repartes) a la
       izquierda; lo que se consulta (Su lista, Descartados, A quién ha
       llamado) a la derecha.
   La cola del agente NO cambia: es UNA llamada y va centrada a propósito.
   Por debajo de 1024 px todo sigue como estaba.
   ══════════════════════════════════════════════════════════════════════════ */
@media (min-width:1024px){
  .p-leads .lienzo, .p-equipo .lienzo, .p-ficha .lienzo{
    padding-left:max(28px, calc((100% - 64rem) / 2));
    padding-right:max(28px, calc((100% - 64rem) / 2)) }
  /* En el escritorio desplaza LA PÁGINA, no la columna: la cabecera con las
     pestañas se queda pegada arriba y la rueda funciona en cualquier punto.
     Y hace falta para la rejilla de abajo: con la columna de alto fijo, la
     fila flexible de la lista medía el hueco de la ventana y la lista se
     salía de la rejilla por debajo, encima del «Ver más». Con la página de
     alto libre, la fila mide lo que mide la lista. */
  .p-leads .cola, .p-equipo .cola, .p-ficha .cola{ height:auto; min-height:calc(100dvh / var(--zoom, 1)) }
  /* body:has(.cola){overflow:hidden} es para el móvil (ver arriba): en el
     escritorio la ventana vuelve a desplazar, sin la barra del sistema. */
  body.p-leads, body.p-equipo, body.p-ficha{ overflow-y:auto }
  .p-leads .lienzo, .p-equipo .lienzo, .p-ficha .lienzo{ flex:none; overflow:visible; min-height:auto }
  .p-leads #cabeza, .p-equipo #cabeza, .p-ficha #cabeza{ position:sticky; top:0; z-index:30; background:var(--background) }

  /* Propietarios: dos columnas, los mandos pegados arriba */
  .p-leads .lienzo{ display:grid; grid-template-columns:18rem minmax(0, 1fr);
    grid-template-rows:auto auto auto auto auto 1fr auto; column-gap:40px; align-content:start }
  .p-leads .lienzo > *{ grid-column:1; min-width:0 }
  .p-leads .lienzo > .cifra{ padding:0 }
  .p-leads .lienzo > #lista, .p-leads .lienzo > .mas{ grid-column:2 }
  .p-leads .lienzo > #lista{ grid-row:1 / span 6 }
  .p-leads .lienzo > .mas{ grid-row:7; justify-self:start; margin-top:18px }
  /* Los mandos se quedan a la vista mientras la lista corre: cada uno es
     pegajoso con su propio «top», que es la suma de los de arriba (alturas
     medidas a 1440: 76 · 20+40 · 12+74 · 12+40 · 14+24 = 312 px). La fila
     sexta (1fr) absorbe el alto de la lista, que abarca las siete: sin esa
     fila flexible la rejilla repartiría el alto de la lista entre las filas
     de los mandos y los separaría. */
  .p-leads .lienzo > .cifra, .p-leads .lienzo > .busca-prop, .p-leads .lienzo > .zona,
  .p-leads .lienzo > .fila-mando, .p-leads .lienzo > .orden-frase{ position:sticky; align-self:start }
  /* …más la cabecera pegada (104 px), el relleno de arriba (20 px) y la franja
     de visita del administrador cuando la hay (--tope, la publica cabeza.js;
     medido en producción: sin ella los mandos bajaban 45 px antes de pegarse). */
  .p-leads .lienzo > .cifra{ top:calc(124px + var(--tope, 0px)) }
  .p-leads .lienzo > .busca-prop{ top:calc(220px + var(--tope, 0px)) }
  .p-leads .lienzo > .zona{ top:calc(272px + var(--tope, 0px)) }
  .p-leads .lienzo > .fila-mando{ top:calc(358px + var(--tope, 0px)) }
  .p-leads .lienzo > .orden-frase{ top:calc(412px + var(--tope, 0px)) }

  /* Mi equipo: las fichas en dos columnas */
  .p-equipo .equipo{ display:grid; grid-template-columns:repeat(2, minmax(0, 1fr)); gap:12px }
  .p-equipo .ag + .ag{ margin-top:0 }

  /* La ficha del agente: decidir a la izquierda, consultar a la derecha */
  .p-ficha .lienzo{ display:grid; grid-template-columns:minmax(0, 22rem) minmax(0, 1fr);
    grid-auto-flow:row dense; column-gap:40px; align-content:start; align-items:start }
  .p-ficha .lienzo > *{ min-width:0 }
  .p-ficha .lienzo > .titulo, .p-ficha .lienzo > .pie-ficha{ grid-column:1 / span 2 }
  .p-ficha .lienzo > section.bloque{ grid-column:1 }
  .p-ficha .lienzo > section.bloque:nth-of-type(n+3){ grid-column:2 }
}

/* NI UNA BARRA DE DESPLAZAMIENTO DEL SISTEMA. La de Windows es una franja gris
   de 15 px que no se parece a nada del producto. */
.lienzo{ scrollbar-width:none; -ms-overflow-style:none }
.lienzo::-webkit-scrollbar{ width:0; height:0 }

/* 🔴 Y ALGO TIENE QUE DECIR QUE HAY MÁS ABAJO, porque la barra era la única
   pista y se acaba de ir. Una lista cortada por el borde se lee como una lista
   que se acaba ahí. Se difumina el borde de abajo, y SOLO cuando queda algo:
   la clase la pone y la quita desliza.js mirando el desplazamiento de verdad.
   Con `mask` sobre el propio cuerpo, así que no hay ningún elemento nuevo que
   pueda quedarse flotando encima de un botón. */
.lienzo.hay-mas{
  -webkit-mask-image:linear-gradient(to bottom, #000 calc(100% - 44px), transparent);
          mask-image:linear-gradient(to bottom, #000 calc(100% - 44px), transparent) }

/* ── LA TARJETA ─────────────────────────────────────────────────────────── */
.lead{ padding:26px 22px }
@media (max-width:640px){ .lead{ padding:22px 18px } }
.lead .arriba{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px }
/* #82 · la marca de lo último: esquina superior derecha, chapa del sistema */
.lead{ position:relative }
.lead .marca-ultimo{ position:absolute; top:14px; right:14px; font-size:11.5px;
  color:var(--muted-foreground); border-color:var(--border) }
.lead .marca-ultimo.luego{ color:var(--foreground); border-color:var(--foreground) }
.lead .precio{ font-size:38px; font-weight:600; line-height:1; letter-spacing:-.04em;
  font-variant-numeric:tabular-nums }
.lead .nombre{ margin-top:10px; font-size:15px }
.lead .tel{ display:block; margin-top:24px; font-family:var(--font-mono); font-size:26px;
  letter-spacing:-.02em; font-variant-numeric:tabular-nums; color:inherit }
@media (hover:hover){ .lead .tel:hover{ color:#e100ff } }
/* La referencia de milanuncios que no es un teléfono (ver telDe en tel.js): se
   dice en pequeño y sin el mono de los números, que es lo que dice «llama». */
.lead .tel.sin-tel{ font-family:inherit; font-size:14px; letter-spacing:0; color:var(--muted-foreground) }
/* ── LOS INTENTOS · lo que se ha probado con este teléfono ────────────────
   Va debajo del número y en tono menor: es contexto para la llamada, no un
   dato del inmueble. */
.lead .veces{ margin-top:8px; font-size:13px; color:var(--muted-foreground) }
.lead .veces b{ color:var(--foreground); font-weight:500 }

/* ── LA SEGUNDA FILA DE ACCIONES ──────────────────────────────────────────
   «No contestó» y «Luego hoy» son la salida NORMAL de una llamada —la mayoría
   no se cogen— pero no son la acción principal: la principal es llamar. Van
   debajo, sin caja, y con 44 px de alto para que se puedan pulsar con el dedo
   yendo en el coche. */
.lead .reintentos{ display:flex; gap:18px; margin-top:12px }
.lead .reintentos button{ min-height:44px; padding:0 2px; background:none; border:0;
  color:var(--muted-foreground); font:inherit; font-size:13.5px; cursor:pointer;
  border-bottom:1px solid transparent }   /* D · la transición y el hundido los pone el molde */
@media (hover:hover){ .lead .reintentos button:hover{ color:var(--foreground); border-bottom-color:var(--border) } }
/* Descartar saca el lead de la lista y los otros dos no: va al otro extremo de
   la fila para que no se pulse por vecindad. */
.lead .reintentos .descartar{ margin-left:auto }
@media (hover:hover){ .lead .reintentos .descartar:hover{ color:var(--destructive); border-bottom-color:var(--destructive) } }

.lead .datos{ margin-top:20px; display:flex; flex-direction:column; gap:4px;
  font-size:13.5px; color:var(--muted-foreground) }

/* ══ EL DIÁLOGO · EL DEL NAVEGADOR, NO UNO NUESTRO ═══════════════════════════
   <dialog> trae hecho lo que cuesta hacer bien: atrapa el foco, cierra con
   Escape, bloquea lo de detrás y sale por encima de todo sin pelear con ningún
   z-index. Lo único que le faltaba era entrar y salir animado, y eso ya es CSS
   puro con @starting-style y allow-discrete.
   ⚠️ LAS TRES DECLARACIONES HACEN FALTA y no sobra ninguna: la de reposo dice
   de dónde viene, la de [open] a dónde va, y @starting-style es la que hace
   que la primera se aplique en el fotograma en que aparece —sin ella el
   diálogo entra de golpe y solo se anima al cerrarse—.
   Sale de la página de efectos que mandó Marc el 07/09/2026. */
dialog{ border:1px solid var(--border); border-radius:16px; padding:0;
  background:var(--card); color:var(--card-foreground);
  max-width:400px; width:calc(100% - 40px);
  /* 🔴 SIN ESTO SE PEGA A LA ESQUINA DE ARRIBA A LA IZQUIERDA. El <dialog>
     modal se centra con los márgenes automáticos, y la maqueta de la página de
     efectos no los llevaba porque allí se miraba en un ordenador ancho y el
     hueco no se notaba. En el móvil del agente sí: se vio mirándolo. */
  margin:auto;
  opacity:0; transform:translateY(14px) scale(.97);
  transition:opacity .28s var(--curva), transform .28s var(--curva),
             overlay .28s allow-discrete, display .28s allow-discrete }
dialog[open]{ opacity:1; transform:none }
@starting-style{ dialog[open]{ opacity:0; transform:translateY(14px) scale(.97) } }
dialog::backdrop{ background:rgba(4,4,6,0); backdrop-filter:blur(0px);
  transition:background .28s var(--curva), backdrop-filter .28s var(--curva),
             overlay .28s allow-discrete, display .28s allow-discrete }
dialog[open]::backdrop{ background:rgba(4,4,6,.66); backdrop-filter:blur(3px) }
@starting-style{ dialog[open]::backdrop{ background:rgba(4,4,6,0); backdrop-filter:blur(0px) } }
.dlg{ padding:22px }
.dlg h3{ margin:0; font-size:18px; font-weight:600; letter-spacing:-.01em }
.dlg p{ margin:9px 0 0; color:var(--muted-foreground); font-size:14px; line-height:1.55 }
.dlg p b{ color:var(--foreground); font-weight:500 }
/* 09/10 · Marc: los botones de los avisos (Mejor no · Descartar…), centrados. */
.dlg .actos{ display:flex; gap:9px; justify-content:center; margin-top:20px; flex-wrap:wrap }
.dlg .actos button{ min-height:44px }

/* ── EL DESGLOSE DEL DÍA Y LA SALA DE ESPERA ─────────────────────────────
   El desglose va pegado al número grande y en tono menor: explica de qué está
   hecho, no compite con él. */
.desglose{ margin:8px 0 0; font-size:13px; color:var(--muted-foreground) }
/* La razón por la que el reparto está apagado. Va pegada al campo y no al pie:
   se lee al mirar el campo, que es cuando surge la pregunta. */
.sin-alta{ margin:10px 0 0; font-size:13px; line-height:1.5; color:var(--muted-foreground) }
.llamado .tel-sala{ font-family:var(--font-mono); font-size:13px;
  font-variant-numeric:tabular-nums; color:var(--muted-foreground) }
.l2-sala{ display:flex; align-items:center; justify-content:flex-start;
  gap:8px 10px; margin-top:6px; flex-wrap:wrap }
/* #87 · Marc: «los CTA deberían ser fijos: uno sale al final de una línea y el
   otro al principio de la siguiente». El apunte del motivo ocupa su línea entera
   y los dos botones van siempre juntos, debajo, en el mismo orden. */
.l2-sala .apunte{ flex:1 0 100% }
.l2-sala .devolver-uno{ flex:0 0 auto }
/* ⛔ Aquí había un `.devolver-uno` sin fondo ni borde, con un subrayado al
   pasar: texto con cursor (#62, Marc: «deberían parecer botones»). Son
   botones del sistema (outline, sm); el resto lo pone [data-slot="button"]. */

/* ══ LO QUE SE ABRE · «Ver quiénes son», «Ver los 12», «Ver las 30 anteriores»
   Un <details> del navegador y no un desplegable nuestro: no hay estado que
   se pueda quedar mal, funciona sin JavaScript y el teclado ya sabe usarlo.
   ⚠️ El summary es la zona que se pulsa, así que tiene los 44 px de alto
   mínimos igual que cualquier botón — en un móvil se falla si no. */
.despliega{ margin-top:12px }
/* 10/10 · Marc: «los desplegables deberían activarse al clicar la línea ENTERA, no solo las
   letras» (como en Seguimiento del agente). Era inline-flex: la zona pulsable acababa donde
   acababa «Ver cuáles». Ahora el summary ocupa la fila. */
.despliega > summary{ display:flex; width:100%; align-items:center; gap:6px;
  min-height:44px; cursor:pointer; list-style:none;
  font-size:13px; color:var(--muted-foreground);
  border-bottom:1px solid transparent; transition:color .14s var(--curva) }
.despliega > summary::-webkit-details-marker{ display:none }
@media (hover:hover){ .despliega > summary:hover{ color:var(--foreground); border-bottom-color:var(--border) } }
/* La flecha se dibuja aquí y no en el HTML: es decoración del control, no
   contenido, y así ninguna de las llamadas tiene que acordarse de ella.
   🔴 10/10 · Marc: «que funcionen como la de Lo que dice el anuncio, que es muy fluido; cambia
   en todas». Era el carácter «›», que se sentaba en la línea de base y giraba con otra curva.
   Ahora es EXACTAMENTE la de .anuncio: el mismo chevron de lucide (15 px, trazo 2, puntas
   redondas), centrado por el flex del summary y girando 90° en .2s ease. Va como máscara para
   que tome el color del texto y no haya que poner un <svg> en cada desplegable. */
.despliega > summary::before{ content:''; flex:none; width:15px; height:15px; background:currentColor;
  -webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E") center / contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m9 18 6-6-6-6'/%3E%3C/svg%3E") center / contain no-repeat;
  transition:transform .2s ease }
.despliega[open] > summary::before{ transform:rotate(90deg) }
.despliega[open] > summary{ margin-bottom:4px }

/* Quiénes tiene en su lista. Misma fila que la sala de espera —de ahí que
   reuse `.llamado`— y solo separa el bloque del número de arriba. */
.quienes{ margin-top:2px }

/* La nota que no cabe. El resumen se lee como la nota corta —comillas,
   tono menor— y el «ver más» es lo único que parece pulsable. */
.nota-larga{ margin:2px 0 0 }
.nota-larga > summary{ display:block; cursor:pointer; list-style:none;
  font-size:13px; line-height:1.5; color:var(--muted-foreground) }
.nota-larga > summary::-webkit-details-marker{ display:none }
.nota-larga > summary span{ white-space:nowrap; border-bottom:1px solid var(--border) }
@media (hover:hover){ .nota-larga > summary:hover span{ color:var(--foreground) } }
.nota-larga[open] > summary{ display:none }
.nota-larga > .apunte{ margin:0 }

/* Los motivos del descarte. Fila que se parte, y nada más: el aspecto del
   chip es el de `chips.js` y aquí solo se coloca. */
.dd-motivos{ display:flex; flex-wrap:wrap; gap:8px; margin:14px 0 0 }
#dd-otro{ margin-top:10px; width:100% }


/* ══ «ESTO ES DE HACE UN RATO» ══════════════════════════════════════════════
   Cuando la pantalla abre con lo último que sabía, hay que decirlo — y decirlo
   sin tapar nada. Es una línea fina bajo la cabecera, del color de lo
   secundario, que desaparece sola en cuanto llega lo nuevo.
   ⛔ NO es un «Cargando» encima del contenido: el contenido ya está ahí y se
   puede leer. Taparlo sería cambiar una espera por otra. */

/* ══ EL ESQUELETO · lo que se enseña mientras llega ═════════════════════════
   Una ruedecita dice «espera». Un esqueleto dice «esto ya viene y va a tener
   esta forma», y es lo correcto casi siempre. De la página de efectos que
   mandó Marc el 07/09/2026.
   ⚠️ El brillo que lo recorre es la ÚNICA animación larga que se permite aquí
   (1,3 s): no se está esperando a que termine —es un latido mientras dura la
   espera— y pararlo dejaría un bloque gris que parece un fallo de pintado. */
.hueso{ border-radius:8px;
  background:linear-gradient(100deg,
    var(--secondary) 30%, color-mix(in oklch, var(--secondary) 55%, var(--foreground)) 50%,
    var(--secondary) 70%);
  background-size:220% 100%; animation:hueso 1.3s linear infinite }
@keyframes hueso{ to{ background-position:-220% 0 } }
.esqueleto{ display:grid; gap:26px; padding-top:6px }
/* #77 · con un fotograma guardado, el esqueleto no se ve (ver el script de cada
   pantalla junto al <main>): lo guardado lo sustituye enseguida. */
html.callado .esqueleto{ visibility:hidden }
.esqueleto .ficha{ display:grid; gap:10px }
.esqueleto .g{ height:26px; width:62% }
.esqueleto .l{ height:12px }
.esqueleto .p{ height:12px; width:44% }
.esqueleto .b{ height:38px; width:58%; margin-top:6px; border-radius:10px }
@media (prefers-reduced-motion:reduce){ .hueso{ animation:none } }

/* ══ EL DESPLEGABLE, NUESTRO ════════════════════════════════════════════════
   Un `<select>` nativo lo pinta el sistema: en el móvil una rueda gris desde
   abajo, en Windows una lista con la letra del sistema. No se parece a nada
   del producto y rompe el diseño justo al abrirse.
   El nativo sigue ahí —escondido y vivo, es el dueño del valor— y esto es la
   cara. Ver public/elige.js.
   ⚠️ Se esconde con posición y tamaño cero, NO con display:none: un `<select>`
   en display:none deja de contar para el formulario en algunos navegadores, y
   entonces el valor que manda el producto sería otro. */
/* ⚠️ CON !important, Y ESTA ES LA VEZ EN QUE TOCA. Se midió dos veces:
   con `.elige-nativo` a secas ganaba `[data-slot="input"]{width:100%}`, y con
   `select.elige-nativo` ganaba `.zona select{width:100%}` —misma
   especificidad y va después—. Y seguirá pasando: esta clase la pone un
   componente sobre un elemento que no sabe dónde va a caer, así que tiene que
   ganar a cualquier regla de la pantalla que lo aloje. Esconder algo es de las
   pocas cosas que no admiten «casi». */
select.elige-nativo{ position:absolute !important; width:0 !important; height:0 !important;
  opacity:0 !important; pointer-events:none !important;
  padding:0 !important; border:0 !important; margin:0 !important }

.elige{ display:flex; align-items:center; gap:8px; width:100%;
  min-height:44px; padding:0 12px; border-radius:10px;
  border:1px solid var(--border); background:var(--input);
  color:var(--foreground); font:inherit; font-size:14px; text-align:left;
  cursor:pointer; transition:border-color .15s var(--curva), background .15s var(--curva) }
@media (hover:hover){ .elige:hover{ border-color:var(--ring) } }
.elige:focus-visible{ outline:none; border-color:var(--ring);
  box-shadow:0 0 0 3px color-mix(in oklch, var(--ring) 50%, transparent) }
.elige .elige-txt{ flex:1; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.elige svg{ width:16px; height:16px; flex:none; color:var(--muted-foreground);
  transition:transform .18s var(--curva) }
.elige[aria-expanded="true"] svg{ transform:rotate(180deg) }

/* La lista va en el body y por encima de las hojas —que están en z-index 80—
   porque se abre DENTRO de una de ellas. */
/* EL ROTULO DE UN GRUPO. No es una opcion: no se puede elegir, no se resalta
   al pasar por encima y el teclado la salta —mueve() solo mira .elige-op—.
   Pequenio y en mayusculas pequenias: tiene que leerse como un encabezado de
   la lista, no como la primera opcion del grupo. */
/* UNA ETIQUETA NUESTRA, NO EL NOMBRE DE NADIE · «Particular»
   Va en cursiva ademas de entre comillas, porque las comillas solas se pierden
   en una lista larga y porque hay gente que se apellida asi. La usan la lista
   de Propietarios (sin nombre) y ficha.js (nombre con marca de portal), que
   son el mismo caso: lo que hay ahi no es un nombre.
   ⚠️ Sin cambiar el color: no es un dato peor, es un dato distinto. Ponerlo
   gris lo convertiria en «esto importa menos», y a quien llama le importa
   igual. */
.nom.etiqueta, .pf-nom.etiqueta, .n.etiqueta{ font-style:italic }

.elige-grupo{ padding:8px 12px 4px; font-size:11px; font-weight:500;
  letter-spacing:.04em; text-transform:uppercase; color:var(--muted-foreground);
  pointer-events:none }
.elige-grupo + .elige-op{ margin-top:0 }
.elige-lista .elige-grupo:not(:first-child){ margin-top:4px;
  border-top:1px solid var(--border); padding-top:8px }

.elige-lista{ position:fixed; z-index:90; overflow-y:auto; padding:6px;
  border:1px solid var(--border); border-radius:12px; background:var(--card);
  box-shadow:0 18px 48px -12px rgba(0,0,0,.6);
  scrollbar-width:none }
.elige-lista::-webkit-scrollbar{ width:0 }
/* F · el buscador de las listas largas (elige.js): arriba y quieto al desplazar */
.elige-busca{ position:sticky; top:-6px; z-index:1; display:block; width:100%; height:40px; margin:-6px 0 6px;
  padding:0 12px; border:0; border-bottom:1px solid var(--border); border-radius:12px 12px 0 0;
  background:var(--card); color:inherit; font:inherit; font-size:14px; outline:none }
.elige-busca::placeholder{ color:var(--muted-foreground) }
@media (max-width:640px){ .elige-busca{ height:44px; font-size:16px } }
.elige-op[hidden], .elige-grupo[hidden]{ display:none }
.elige-op{ padding:9px 10px; min-height:44px; display:flex; align-items:center;
  border-radius:8px; font-size:14px; cursor:pointer }
.elige-op.encima{ background:var(--secondary) }
.elige-op[aria-selected="true"]{ color:var(--foreground); font-weight:500 }
.elige-op[data-off]{ color:var(--muted-foreground); cursor:default }

/* ══ LAS ESPERAS Y LOS VACÍOS · CENTRADOS ═══════════════════════════════════
   🔴 ESTABAN ARRIBA A LA IZQUIERDA. «Cargando…» era una línea gris pegada al
   borde, y el mensaje de bandeja vacía empezaba a 56 px del techo con media
   pantalla en negro debajo. Los dos dicen lo mismo —«aquí no hay nada, de
   momento»— y los dos se leen mejor en el centro del hueco que hay.
   ⚠️ Funciona porque el cuerpo tiene un alto de verdad desde que se desplaza
   por dentro: `min-height:100%` sobre un padre de altura automática no habría
   centrado nada. */
.vacio{ min-height:100%; display:grid; align-content:center; justify-items:center;
  padding:32px 8px; text-align:center }

/* ── LA CAJA DE ANTIGÜEDAD ──────────────────────────────────────────────────
   Sube de nota al pie a caja propia, y no es cosmética: el anuncio más fresco
   de toda la base tiene 5 días, la media son 593 y el 46,7% pasa del año. Un
   piso que lleva tres años sin venderse es un propietario cansado, y eso ES
   el argumento de la llamada. */
.antiguedad{ margin-top:20px; padding:12px 14px; border:1px solid var(--border);
  border-radius:10px; font-size:13.5px }
.antiguedad.vieja{ border-color:color-mix(in srgb, #e100ff 35%, transparent);
  background:color-mix(in srgb, #e100ff 7%, transparent) }
.antiguedad .sin{ display:block; margin-top:5px; font-size:12px; color:var(--muted-foreground) }

/* ── EL TEXTO DEL ANUNCIO, PLEGADO ─────────────────────────────────────────
   ⛔ Nunca altura fija: la mediana son 196 letras, el máximo 8.305 y el 37%
   baja de 120. Techo con scroll propio, que es lo único que aguanta las tres. */
.anuncio{ margin-top:18px; border-top:1px solid var(--border); padding-top:16px }
.anuncio > summary{ display:flex; align-items:center; gap:8px; cursor:pointer;
  font-size:13.5px; color:var(--muted-foreground); list-style:none; min-height:24px }
.anuncio > summary::-webkit-details-marker{ display:none }
@media (hover:hover){ .anuncio > summary:hover{ color:var(--foreground) } }
.anuncio > summary svg{ width:15px; height:15px; transition:transform .2s ease }
.anuncio[open] > summary svg{ transform:rotate(90deg) }
.anuncio .texto{ margin-top:12px; max-height:190px; overflow-y:auto; font-size:13.5px;
  line-height:1.55; color:var(--muted-foreground); white-space:pre-wrap;
  overscroll-behavior:contain }
.anuncio .enlaces{ display:flex; flex-wrap:wrap; gap:16px; margin-top:14px; font-size:12.5px }
.anuncio .enlaces a{ color:var(--foreground); text-decoration:underline; text-underline-offset:4px;
  display:inline-block; min-height:24px }
@media (hover:hover){ .anuncio .enlaces a:hover{ color:#e100ff } }

/* ── LOS DOS BOTONES ────────────────────────────────────────────────────── */
.acciones{ margin-top:24px; display:flex; flex-direction:column; gap:10px }
.acciones [data-slot="button"]{ width:100%; height:44px !important; font-size:14px }
.aclara{ margin-top:12px; text-align:center; font-size:11.5px; line-height:1.5;
  color:var(--muted-foreground) }

/* ── LAS DOS PESTAÑAS, abajo y con el pulgar ────────────────────────────── */
.pestanas{ position:sticky; bottom:0; z-index:20; display:flex;
  border-top:1px solid var(--border); background:var(--background);
  padding-left:env(safe-area-inset-left); padding-right:env(safe-area-inset-right) }
.pestanas button{ flex:1; display:flex; flex-direction:column; align-items:center; gap:3px;
  padding:10px 6px; min-height:56px; font-size:11.5px; color:var(--muted-foreground);
  border-top:2px solid transparent; margin-top:-1px }   /* D · la pulsación la pone el molde (data-pulsa) */
.pestanas button svg{ width:19px; height:19px }
.pestanas button.aqui{ color:var(--foreground); border-top-color:var(--foreground) }

/* ── LO QUE SE VE CUANDO NO HAY NADA ────────────────────────────────────────
   Y hoy esto es lo ÚNICO que se ve: lead_asignado está a 0 en producción. */
/* ⚠️ El centrado y el relleno de .vacio están ARRIBA, con las esperas: los
   dos casos —«todavía no hay nada» y «ya no queda nada»— son el mismo hueco y
   se resuelven juntos. Aquí quedaban unos 56 px de relleno que peleaban con
   ese centrado. */
.vacio svg{ width:34px; height:34px; margin:0 auto 18px; color:var(--muted-foreground);
  opacity:.7 }
.vacio h2{ font-size:17px; font-weight:600; letter-spacing:-.024em }
.vacio p{ margin-top:8px; font-size:13.5px; line-height:1.55; color:var(--muted-foreground) }

/* ── YA LLAMADOS ────────────────────────────────────────────────────────── */
.hecho{ padding:14px 0; border-bottom:1px solid var(--border) }
.hecho:last-child{ border-bottom:0 }
/* #31 · el apartado se lee de un vistazo, sin llegar al ultimo renglon: la
   fila entera baja de tono y la chapa va delante del precio. NO se tacha ni
   se pone en rojo —no ha hecho nada malo, es una salida normal— pero tiene
   que distinguirse de una llamada atendida antes de leerla. */
.hecho.apartado .p, .hecho.apartado .n, .hecho.apartado .l2{ opacity:.62 }
.hecho .chapa-apartado{ align-self:center }
/* …y la chapa misma (y la de un motivo en una tarjeta): parte por palabras dentro de su borde.
   Una línea de chapa partida en dos lleva su radio más pequeño para seguir pareciendo una chapa. */
.hecho .chapa-apartado, .prop .apunte [data-slot="badge"]{ white-space:normal; flex:0 1 auto; max-width:100%;
  overflow-wrap:anywhere; text-align:left; justify-content:flex-start; border-radius:12px }
.hecho{ overflow-wrap:anywhere; min-width:0 }

/* 09/10 · LA FILA NO SE SALE NUNCA (Marc: «una opción de descarte larga descoloca la ficha, se sale
   por la derecha y se puede deslizar»). La causa: la chapa es un badge (nowrap, flex:none) dentro de
   una fila que no partía. Ahora la fila parte, nada en ella puede pasar de su ancho, y una chapa larga
   baja a su línea y se parte por palabras en vez de empujar. */
.hecho .l1{ display:flex; align-items:baseline; gap:6px 10px; flex-wrap:wrap; min-width:0 }
.hecho .l1 > *{ min-width:0; max-width:100% }
.hecho .p{ font-size:15px; font-variant-numeric:tabular-nums }
.hecho .n{ font-size:13.5px; color:var(--muted-foreground) }
.hecho .cuando{ margin-left:auto; font-size:12px; color:var(--muted-foreground);
  white-space:nowrap }
.hecho .l2{ margin-top:5px; font-size:12.5px; color:var(--muted-foreground) }
/* El teléfono de «ya llamados»: marcable, monoespaciado y del mismo tamaño que
   el de la lista de Propietarios. No es el protagonista —eso es el nombre y lo
   que anotó— pero tiene que poder pulsarse sin buscarlo. */
.hecho .tel-hecho{ display:inline-block; margin-top:6px; min-height:24px;
  font-family:var(--font-mono); font-size:14px; letter-spacing:-.01em;
  font-variant-numeric:tabular-nums; color:var(--foreground) }
@media (hover:hover){ .hecho .tel-hecho:hover{ color:#e100ff } }
.hecho .nota{ margin-top:7px; font-size:12.5px; line-height:1.5; color:var(--muted-foreground) }
.hecho .nota b{ color:var(--foreground); font-weight:500 }
/* 🔴 «Ver más» ES UN BOTÓN SIN FONDO: su borde es todo lo que tiene. Medido,
   1,25 en oscuro y 1,23 en claro contra un listón de 3,0 — o sea, una línea
   que casi no está debajo de una lista de cuarenta fichas. Usa la misma
   variable que los campos, que ya está medida. */
/* El «y N más» de la cola del agente (#17): es un boton, pero se lee como el
   distintivo que sustituye — el sitio y el tamaño son los mismos. */
.mas-anuncios{ padding:3px 9px; border-radius:999px; border:1px solid var(--borde-campo);
  font-size:11.5px; font-weight:500; color:var(--muted-foreground); background:none;
  white-space:nowrap }
@media (hover:hover){ .mas-anuncios:hover{ color:var(--foreground); border-color:var(--foreground) } }

.mas{ width:100%; margin-top:18px; height:40px; border:1px solid var(--borde-campo);
  border-radius:9px; font-size:13px; color:var(--muted-foreground) }
@media (hover:hover){ .mas:hover{ color:var(--foreground); border-color:var(--foreground) } }

/* ── LA HOJA · sube desde abajo en el móvil, centrada en el escritorio ──── */
/* ⚠️ 88svh Y NO dvh, otra vez por el teclado: esta hoja es la de «¿qué te ha
   dicho?», con su textarea. Con dvh, al abrirse el teclado el techo de la hoja
   baja de golpe y lo escrito se va de la vista. */
/* 🔴 TANDA 2 · 1 (Marc, 12/09/2026): «la hoja NUNCA es más alta que lo que se ve.
   Cabecera fija arriba, cuerpo que se desliza dentro, y el botón de acción SIEMPRE
   visible abajo». La hoja es una columna: título y frase arriba, #h-cuerpo (o
   #f-cuerpo) desliza en medio, los botones abajo. Y la altura va dividida por el
   zoom del móvil (bloque A). */
.hoja{ position:fixed; left:0; right:0; bottom:0; z-index:80; overscroll-behavior:contain;
  max-height:calc(88svh / var(--zoom, 1)); display:flex; flex-direction:column; overflow-x:hidden; overflow-y:auto;
  padding:22px 20px; padding-bottom:max(22px, calc(env(safe-area-inset-bottom) + 22px));
  border-top:1px solid var(--border); border-radius:16px 16px 0 0;
  background:var(--card); box-shadow:0 -24px 60px -18px rgba(0,0,0,.85);
  transform:translateY(102%); transition:transform .28s cubic-bezier(.16,1,.3,1);
  visibility:hidden }
.hoja.on{ transform:none; visibility:visible }
@media (min-width:640px){
  .hoja{ left:50%; right:auto; bottom:auto; top:50%; width:min(420px, calc(100vw - 40px));
    border-radius:14px; border:1px solid var(--border);
    transform:translate(-50%,-46%) scale(.98); opacity:0 }
  .hoja.on{ transform:translate(-50%,-50%); opacity:1 }
}
.hoja h2{ font-size:17px; font-weight:600; letter-spacing:-.024em; flex:none }
.hoja > #h-cuerpo, .hoja > #f-cuerpo{ flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain; -webkit-overflow-scrolling:touch }
/* 28/09 · NINGUNA PIEZA DE UNA HOJA SE ENCOGE. Antes era una lista a mano (quien, pista,
   dos-salidas, otra, botón) y lo que no estaba en ella se aplastaba cuando la hoja no cabía:
   en «Añadir a alguien» (sin cuerpo propio) el selector Agente/Responsable quedaba en 26 px
   de alto con el texto cortado, porque el molde de pulsar pone overflow:hidden a todo botón
   y eso le deja encogerse hasta 0. Ahora nada se encoge: si no cabe, desplaza el cuerpo
   (#h-cuerpo / #f-cuerpo, la regla de arriba, que gana por especificidad) o, si la hoja no
   tiene cuerpo, la hoja entera (overflow-y:auto en .hoja). */
.hoja > *{ flex-shrink:0 }
.hoja .quien{ margin-top:6px; font-size:13px; color:var(--muted-foreground) }
.hoja label{ display:block; margin-top:18px; font-size:13.5px; font-weight:500 }
.hoja textarea{ width:100%; margin-top:8px; min-height:88px; resize:vertical;
  padding:10px 12px; border:1px solid var(--input); border-radius:9px;
  background:var(--secondary); color:inherit; font-size:14px; line-height:1.5; outline:none;
  font-family:inherit }
@media (max-width:640px){ .hoja textarea{ font-size:16px } }
.hoja textarea:focus-visible{ border-color:var(--ring);
  box-shadow:0 0 0 3px color-mix(in oklch, var(--ring) 22%, transparent) }
.hoja [data-slot="input"]{ width:100%; margin-top:8px }
.hoja .pista{ margin-top:6px; font-size:12px; color:var(--muted-foreground);
  overflow-wrap:anywhere }
.hoja [data-slot="button"]{ width:100%; margin-top:18px; height:44px !important }
.hoja .otra, .dlg .otra{ margin-top:18px; padding-top:16px; border-top:1px solid var(--border);   /* G2 · el mismo «No es un particular» en Descartar */
  text-align:center }
.hoja .otra button, .dlg .otra button{ font-size:13px; color:var(--muted-foreground); min-height:24px;
  text-decoration:underline; text-underline-offset:4px }
@media (hover:hover){ .hoja .otra button:hover, .dlg .otra button:hover{ color:var(--destructive) } }
@media (prefers-reduced-motion: reduce){ .hoja{ transition:none } }

/* los filtros, dentro de la misma hoja */
.filtro{ margin-top:18px }
.filtro .et{ font-size:12.5px; color:var(--muted-foreground) }
.filtro .ops{ display:flex; flex-wrap:wrap; gap:7px; margin-top:9px }
/* ══ LOS CHIPS · UN SOLO ESTILO, EL DEL COMPONENTE (ver chips.js) ══════════
   Habia dos: este (32 px, .chip.on) y el de la hoja de Ajustes (.tipos button,
   36 px y aria-pressed). Se queda UNO, y gana el grande: 36 px, 44 en movil.
   Los 32 estaban por debajo de lo que se toca sin fallar.
   🔴 Y lo elegido cuelga de aria-pressed, no de una clase: asi no hay forma
   de que se vea encendido y no lo este. */
/* El hueso que ocupa el sitio de la cifra mientras llega (#18). Su ancho es
   el de un numero de seis cifras, que es lo que caben: 172.761. */
.n-hueso{ display:inline-block; width:3.2em; height:.72em; border-radius:6px;
  vertical-align:baseline }

.grupo-chips + .grupo-chips{ margin-top:16px }
.rot-chips{ margin:0 0 10px; font-size:12px; font-weight:500;
  color:var(--muted-foreground) }
.chips{ display:flex; flex-wrap:wrap; gap:6px }
.chip{ height:36px; padding:0 14px; border:1px solid var(--border); border-radius:999px;
  background:var(--background); font-size:13px; color:var(--muted-foreground);
  }   /* D · la transición la pone el molde */
@media (hover:hover){ .chip:hover{ color:var(--foreground); border-color:var(--input) } }
.chip[aria-pressed="true"]{ color:var(--primary-foreground); background:var(--primary);
  border-color:var(--primary) }
@media (max-width:640px){ .chip{ height:44px } }
.dos{ display:flex; gap:10px; margin-top:9px }
.dos input{ flex:1; min-width:0 }

/* ══════════════════════════════════════════════════════════════════════════
   ⚖️ LOS EXTREMOS · reglas de sistema, no de una pantalla
   ──────────────────────────────────────────────────────────────────────────
   NINGÚN TEXTO ROMPE LA CAJA. NINGUNA CIFRA DESBORDA. NINGUNA LISTA SE
   DESCUADRA POR ESTAR VACÍA O LLENA.

   Esto no cambia ni una medida del diseño aprobado: cambia lo que pasa cuando
   el dato es raro. Y los datos raros son reales, no hipótesis: 8.305 letras de
   descripción, precios de siete cifras, 220.000 m², 2.614 días, y municipios
   como «Navalperal de Pinares».
   ══════════════════════════════════════════════════════════════════════════ */

/* Una línea y punto. Puntos suspensivos, nunca envolver ni empujar al vecino.
   Tres cosas, y las tres hacen falta:
     · `min-width:0` — sin él, un hijo de flex se niega a encogerse por debajo
       de su contenido y en vez de recortarse EMPUJA;
     · `display:block` — `overflow` y `text-overflow` NO se aplican a un
       elemento en línea. Un <span> con esta clase y sin esto no recorta nada:
       se sale de la caja como si la clase no estuviera. Pasó aquí con la frase
       de la regla, y solo se vio forzando el texto del sistema a 24 px.
       El nombre sí recortaba, y por eso despistaba: es hijo de un flex, y eso
       ya lo convierte en bloque por su cuenta.
     · el resto, el recorte en sí. */
.una-linea{ display:block; min-width:0;
  overflow:hidden; text-overflow:ellipsis; white-space:nowrap }

/* Palabras sin espacios —correos, URLs, referencias de anuncio— abriendo la
   caja por dentro. `anywhere` parte donde haga falta y solo cuando hace falta. */
.parte-palabras{ overflow-wrap:anywhere; word-break:break-word }

/* Una cifra no se corta NUNCA. Si no cabe, encoge. */
.cifra-que-encoge{ font-size:clamp(30px, 9vw, 46px) }

/* ══════════════════════════════════════════════════════════════════════════
   MI EQUIPO · la vista del responsable
   ══════════════════════════════════════════════════════════════════════════ */
.cifra{ padding:0 20px }
.cifra .n{ font-weight:600; line-height:1; letter-spacing:-.04em;
  font-variant-numeric:tabular-nums }
.cifra .n span{ color:var(--muted-foreground) }
/* «Sin reparto» no es una cifra: es una frase, y va más pequeña. */
.cifra .n.sin{ font-size:clamp(26px, 7.5vw, 38px) }
.cifra .l{ margin-top:10px; font-size:13.5px; line-height:1.5; color:var(--muted-foreground) }

.mando-eq{ display:flex; align-items:center; gap:10px; margin-top:22px }
.mando-eq .busca{ position:relative; flex:1; min-width:0 }
.mando-eq [data-slot="input"]{ width:100% }
.mando-eq [data-slot="button"]{ flex:none; white-space:nowrap }

.equipo{ margin-top:16px }
.ag{ display:block; width:100%; text-align:left; padding:16px 18px;
  border:1px solid var(--border); border-radius:12px; background:var(--card) }   /* D · la pulsación la pone el molde (data-pulsa) */
@media (hover:hover){ .ag:hover{ border-color:var(--input) } }
.ag + .ag{ margin-top:10px }
/* #89 · Marc: «Equipo sale muy apretado; Qué es Novoconect en el iPhone sale muy
   bien». Las fichas del equipo respiran como aquella: más relleno y más aire
   entre ellas en el móvil (a partir del zoom del #90). */
@media (max-width:640px){ .ag{ padding:20px 20px } .ag + .ag{ margin-top:14px } .equipo{ margin-top:22px } }
/* `flex-wrap` para que la cuenta del día se baje de línea en vez de salirse.
   No cambia nada en las medidas normales —ahí caben las dos— y evita que un
   objetivo de siete cifras, o el texto del sistema agrandado, echen el número
   fuera de la tarjeta. */
.ag .fila1{ display:flex; align-items:center; gap:10px; flex-wrap:wrap }
.ag .nom{ font-size:15px; font-weight:500; flex:1 1 auto }
.ag .hoy{ flex:0 1 auto; min-width:0; font-size:12.5px; color:var(--muted-foreground);
  white-space:nowrap; font-variant-numeric:tabular-nums }
.ag .hoy b{ color:var(--foreground); font-weight:500 }
.ag .regla{ margin-top:4px; font-size:12px; color:var(--muted-foreground) }
.ag .etqs{ display:flex; flex-wrap:wrap; gap:6px; margin-top:10px }
.etq{ padding:3px 9px; border:1px solid var(--border); border-radius:999px;
  font-size:11.5px; color:var(--muted-foreground); white-space:nowrap }
/* `display:block` porque en la tarjeta la barra es un <span> dentro de un
   <button>, y a un elemento en línea no se le aplican ni `height` ni `width`:
   existía en el HTML y no se pintaba. Es el mismo fallo que tenía la frase de
   la regla, y otra vez solo se vio mirando la captura. */
.ag .barra{ display:block; margin-top:12px }
/* Verde SOLO al llegar al objetivo. El resto del tiempo es el gris de siempre:
   si el verde saliera antes, dejaría de querer decir «ya está».
   Una sola regla para las tres barras (Mi equipo, la ficha y la cola del
   agente, #56): el mismo verde quiere decir lo mismo en todas. */
.barra i.full{ background:#3FBF7F }

/* Los que se fueron. Plegados: no son equipo, pero su histórico es lo que se
   mira cuando entra el sustituto. */
/* scroll-margin-top: al desplegarlo, la pagina se lleva la vista aqui (ver
   pintaBajas en equipo.html) y sin este hueco el rotulo «Dados de baja»
   acababa DEBAJO de la cabecera pegajosa — o sea, ibas a un sitio y no veias
   a donde habias ido. Son la cabecera (56) y las pestanas (41) mas un respiro. */
.bajas{ margin-top:26px; border-top:1px solid var(--border); padding-top:16px;
  scroll-margin-top:108px }
.bajas > summary{ display:flex; align-items:center; gap:8px; cursor:pointer;
  font-size:13px; color:var(--muted-foreground); list-style:none; min-height:24px }
.bajas > summary::-webkit-details-marker{ display:none }
@media (hover:hover){ .bajas > summary:hover{ color:var(--foreground) } }
.bajas > summary svg{ width:15px; height:15px; transition:transform .2s ease }
.bajas[open] > summary svg{ transform:rotate(90deg) }
/* Una fila de baja SE ABRE: es un botón, no un párrafo. Ancho entero y
   alineada a la izquierda, que es lo que un <button> no hace solo. */
.baja{ display:block; width:100%; text-align:left; min-height:44px;
  padding:12px 0; border-bottom:1px solid var(--border-muted, var(--border));
  color:inherit }   /* D · la transición la pone el molde */
.baja:last-child{ border-bottom:0 }
@media (hover:hover){ .baja:hover{ opacity:.72 } }
.baja .n{ font-size:14px }
.baja .d{ margin-top:3px; font-size:12px; color:var(--muted-foreground) }

/* ── ELEGIR QUÉ VA A SER: agente o responsable ─────────────────────────────
   Dos opciones grandes y con su explicación debajo, no un desplegable: quien
   añade a alguien lo hace tres veces al año y tiene que poder leer qué es
   cada cosa sin abrir nada. */
/* #128 · Se llama .elige-rol y no .elige: .elige es el BOTÓN del desplegable
   (elige.js, arriba) y este bloque le pisaba el centrado vertical (stretch) y
   le metía margen —«Toda España» salía pegado arriba en provincia y municipio. */
/* 28/09 · SIN CORTES POR ANCHO. Era flex en fila y, por debajo de 400 px, columna (un parche
   para un ancho). Ahora una rejilla que decide sola: lado a lado mientras cada opción tenga
   sitio para su explicación en dos líneas, una debajo de otra cuando no. Las dos iguales
   siempre (1fr de ancho y grid-auto-rows:1fr de alto) y nunca por debajo de 44 px. */
/* 28/09 · Y ES LA REGLA DE TODA FILA DE OPCIONES IGUALES (.fila-igual): las tres
   acciones de cada tarjeta en la ficha de un agente (Devolver / A la general /
   Pasárselo a otro) se reparten con esta misma rejilla. Una regla, una definición. */
:is(.elige-rol, .fila-igual, .hoja .dos-salidas){ display:grid; grid-template-columns:repeat(auto-fit, minmax(min(100%, 8.5rem), 1fr));
  grid-auto-rows:1fr; gap:8px; margin-top:14px }
/* 29/09 · Y SI SON TRES Y CABEN DOS POR FILA (Marc, las acciones de la ficha del agente), el
   tercero baja y se queda CENTRADO entre los dos de arriba, del mismo ancho, en vez de
   pegarse a la izquierda. Se mide la tarjeta (container query) con los mismos cortes que
   la rejilla: dos por fila de 17,5rem a 26,5rem (2 × 8,5rem + hueco; 3 × 8,5rem + huecos). */
.prop{ container-type:inline-size }
@container (min-width:17.5rem) and (max-width:26.49rem){
  /* .prop delante para pesar lo mismo que la regla común (:is(…) pesa como su selector
     más fuerte) y ganarle por ir después; sin !important. */
  .prop .fila-igual{ grid-template-columns:1fr 1fr }
  .prop .fila-igual > [data-slot="button"]:nth-child(3):last-child{ grid-column:1 / -1; justify-self:center; width:calc(50% - 4px) }
}
/* Los botones del sistema dentro de la fila: sin altura fija (la pone el texto),
   nunca por debajo de 44 px, el texto partido con equilibrio y no a lo bruto. */
:is(.fila-igual, .hoja .dos-salidas) > [data-slot="button"]{ min-width:0; width:100%; height:auto !important; min-height:44px;
  padding:8px 12px; white-space:normal; text-wrap:balance; line-height:1.25; font-size:13px }
.elige-rol button{ min-width:0; min-height:44px; display:flex; flex-direction:column; justify-content:center; gap:3px;
  text-align:left; padding:11px 12px; border:1px solid var(--border); border-radius:10px;
  background:var(--card); color:var(--muted-foreground) }   /* D · la transición la pone el molde */
.elige-rol button b{ font-size:13.5px; font-weight:600 }
.elige-rol button span{ font-size:11.5px; line-height:1.35; text-wrap:balance }
@media (hover:hover){ .elige-rol button:hover{ border-color:var(--input) } }
.elige-rol button.on{ border-color:var(--primary); color:var(--foreground);
  background:color-mix(in srgb, var(--primary) 8%, var(--card)) }

/* ── EL ENLACE QUE HAY QUE PASAR A MANO ────────────────────────────────────
   Solo sale cuando el correo NO ha salido. Es la única copia que existe: en
   la base solo está su sha256. Se enseña ENTERO —partido por donde haga
   falta— porque medio enlace no sirve de nada. */
.enlace-suelto{ margin-top:16px; padding:13px 14px; border-radius:10px;
  border:1px solid color-mix(in srgb, var(--destructive) 40%, var(--border));
  background:color-mix(in srgb, var(--destructive) 8%, var(--card)) }
.enlace-suelto .malo{ font-size:13px; line-height:1.45; color:var(--destructive) }
.enlace-suelto code{ display:block; margin-top:10px; padding:9px 10px; border-radius:8px;
  background:var(--secondary); color:var(--foreground);
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace; font-size:12px;
  line-height:1.5; overflow-wrap:anywhere; user-select:all }
.enlace-suelto [data-slot="button"]{ width:100%; margin-top:10px }

/* ══════════════════════════════════════════════════════════════════════════
   LA FICHA DE UN AGENTE · /equipo/<slug>
   ──────────────────────────────────────────────────────────────────────────
   El orden ES la decisión: «qué le repartes» va SEGUNDO y no al final. Con
   diez claves de filtro eso no es un ajuste, es la palanca con la que el
   responsable dirige a su equipo. Abajo del todo, la ficha parecería de
   consulta.
   ══════════════════════════════════════════════════════════════════════════ */
/* ⛔ Aquí había un `.volver` gris sin borde, con un chevron «‹»: se leía como
   texto (#61, Marc: «debería parecer un botón… y cambia el < por algo no
   cutre»). Ahora es un botón del sistema (outline, sm) con la flecha
   entera; lo pinta cabeza.js y no lleva CSS propio. */

.titulo{ margin-bottom:26px }
.titulo .fila{ display:flex; align-items:center; gap:8px; flex-wrap:wrap }
/* El nombre se edita en su sitio. Un campo que parece texto hasta que se toca:
   sin caja, sin borde y con el mismo tamaño y peso que el título que sustituye,
   porque si al enfocarlo el texto salta de sitio parece que se ha roto algo. */
.titulo input{ flex:1 1 auto; min-width:0; width:100%;
  font-family:inherit; font-size:26px; font-weight:600; letter-spacing:-.03em;
  line-height:1.2; color:var(--foreground); background:none; border:0;
  border-radius:8px; padding:2px 6px; margin-left:-6px; outline:none;
  text-overflow:ellipsis }
@media (hover:hover){ .titulo input:hover{ background:var(--secondary) } }
.titulo input:focus{ background:var(--secondary);
  box-shadow:0 0 0 3px color-mix(in oklch, var(--ring) 22%, transparent) }
.titulo .correo{ margin-top:6px; font-size:13px; color:var(--muted-foreground);
  overflow-wrap:anywhere }
.titulo .guardado{ font-size:12px; color:var(--muted-foreground) }

.bloque{ padding:20px 0; border-top:1px solid var(--border) }
.bloque:first-of-type{ border-top:0; padding-top:0 }
.bloque > h2{ font-size:11.5px; font-weight:500; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted-foreground) }
.bloque > .cuerpo{ margin-top:14px }

/* 1 · HOY */
.hoy-n{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap }
.hoy-n b{ font-size:34px; font-weight:600; line-height:1; letter-spacing:-.035em;
  font-variant-numeric:tabular-nums }
.hoy-n span{ font-size:15px; color:var(--muted-foreground);
  font-variant-numeric:tabular-nums }
.barra-6{ display:block; height:6px; width:100%; margin-top:14px; border-radius:999px;
  background:var(--secondary); overflow:hidden }
.barra-6 i{ display:block; height:100%; border-radius:999px; background:var(--foreground);
  transition:width .7s cubic-bezier(.16,1,.3,1) }
.barra-6 i.full{ background:#3FBF7F }
.barra-6.apagada{ opacity:.4 }
.semana{ margin-top:12px; font-size:12.5px; color:var(--muted-foreground);
  font-variant-numeric:tabular-nums }

/* 2 · QUÉ LE REPARTES */
.por-dia{ display:flex; align-items:center; gap:10px; flex-wrap:wrap; font-size:14px }
.por-dia [data-slot="input"]{ width:84px; flex:none; text-align:center;
  font-variant-numeric:tabular-nums }
.regla-dice{ margin-top:14px; font-size:14px; line-height:1.5 }
.regla-dice.vacia{ color:var(--muted-foreground) }
.regla-dice + .regla-dice{ margin-top:4px }   /* #100 · «Hoy» y «Desde mañana», juntas */
.regla-dice b{ font-weight:600 }
.aviso-manana{ margin-top:12px; padding:10px 12px; border-radius:9px;
  border:1px solid var(--border); background:var(--secondary);
  font-size:12.5px; line-height:1.45; color:var(--muted-foreground) }

/* 3 · SU LISTA */
.dos-botones{ display:flex; gap:10px; margin-top:14px; flex-wrap:wrap }
.dos-botones [data-slot="button"]{ flex:1 1 auto; min-width:0 }
.nota-pie{ margin-top:10px; font-size:12.5px; color:var(--muted-foreground) }
/* #80 · la línea de la pausa reserva su sitio: aparecer o irse no mueve la página */
.nota-pie.reservada{ min-height:1.5em }
@media (max-width:640px){ .nota-pie.reservada{ min-height:3em } }   /* la frase larga ocupa dos líneas en el móvil */
/* y el «Guardado» del nombre no empuja la fila: flota a la derecha del campo */
.titulo .fila{ position:relative }
.titulo .guardado{ position:absolute; right:0; bottom:-18px; white-space:nowrap; pointer-events:none }

/* 4 · A QUIÉN HA LLAMADO · las filas son las de «Ya llamados», reutilizadas */
.llamado{ padding:13px 0; border-bottom:1px solid var(--border) }
.llamado:last-child{ border-bottom:0 }
.llamado .l1{ display:flex; align-items:baseline; gap:10px; flex-wrap:nowrap; min-width:0 }   /* 6 · una línea: el municipio largo se corta, la fila no crece */
.llamado .cuando{ font-size:12px; color:var(--muted-foreground); white-space:nowrap;
  font-variant-numeric:tabular-nums }
.llamado .nom{ font-size:14px }
.llamado .pre{ font-size:14px; font-variant-numeric:tabular-nums }
.llamado .mun{ margin-left:auto; font-size:12.5px; color:var(--muted-foreground); flex:0 1 40%; min-width:0; text-align:right }
.llamado .nom{ flex:1 1 auto; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.llamado .tel-sala, .llamado .pre{ flex:none; white-space:nowrap }   /* 6 · ni el teléfono ni el precio se parten en dos líneas */
.llamado .apunte{ margin-top:6px; font-size:12.5px; line-height:1.5;
  color:var(--muted-foreground) }

/* Abajo, separado: lo que no se hace todos los días */
.pie-ficha{ margin-top:30px; padding-top:18px; border-top:1px solid var(--border);
  display:flex; gap:18px; flex-wrap:wrap; align-items:center }
.pie-ficha button{ font-size:13px; color:var(--muted-foreground); min-height:24px;
  text-decoration:underline; text-underline-offset:4px }
@media (hover:hover){ .pie-ficha button:hover{ color:var(--foreground) } }
@media (hover:hover){ .pie-ficha .baja-btn:hover{ color:var(--destructive) } }

/* El diálogo de confirmar: dos botones, y el que actúa lleva SU VERBO.
   «Confirmar» no dice qué va a pasar, y aquí lo que pasa no se deshace. */
/* 28/09 · LAS DOS SALIDAS DE UNA HOJA SIGUEN LA REGLA DE .fila-igual (más abajo, con
   .elige-rol): eran un flex con botones que no parten el texto, y «Sí, exclusiva
   conseguida» se salía del botón a 320 px. Ahora, en fila si caben y una encima de
   otra si no, iguales y de 44 px como mínimo. */
.hoja .dos-salidas{ margin-top:20px }
.hoja .dos-salidas [data-slot="button"]{ margin-top:0 }
.hoja [data-slot="button"][data-variant="malo"]{ background:var(--destructive);
  color:#fff; border-color:var(--destructive) }
@media (hover:hover){ .hoja [data-slot="button"][data-variant="malo"]:hover{ filter:brightness(1.08) } }

/* ══════════════════════════════════════════════════════════════════════════
   PROPIETARIOS · /propietarios
   ──────────────────────────────────────────────────────────────────────────
   ⭐ ESTO NO ES UN CATÁLOGO QUE SE EXPLORA, ES UN ALMACÉN DEL QUE SE SACA.
   El responsable no entra a leer 172.761 fichas: entra a decir «dame veinte
   de Dénia para Lucía». Todo el orden de la pantalla sale de ahí — la zona
   arriba y sola, el reparto a un clic, y lo demás guardado.
   ══════════════════════════════════════════════════════════════════════════ */
.busca-prop{ margin-top:20px; position:relative }
.busca-prop [data-slot="input"]{ width:100%; padding-right:34px }
/* LA TECLA QUE LO ABRE, dicha en el propio campo. Sin esto el atajo existe y
   no lo sabe nadie. Se esconde con el dedo: en un móvil no hay `/` que pulsar
   y ocuparía sitio para nada. */
.busca-prop kbd{ position:absolute; right:9px; top:50%; transform:translateY(-50%);
  padding:1px 6px; border:1px solid var(--border); border-radius:5px;
  background:var(--secondary); color:var(--muted-foreground);
  font-family:inherit; font-size:11.5px; line-height:1.5; pointer-events:none }
@media (pointer: coarse){ .busca-prop kbd{ display:none }
  .busca-prop [data-slot="input"]{ padding-right:12px } }

/* ── LA ZONA, arriba y sola ─────────────────────────────────────────────────
   Provincia y municipio salen del cajón de los diez: la oficina trabaja tres
   municipios, no España. Ese filtro no puede competir en igualdad con ocho
   que casi nadie usa. */
.zona{ display:flex; gap:10px; margin-top:12px; flex-wrap:wrap }
.zona label{ flex:1 1 150px; min-width:0; display:block }
.zona .et{ display:block; margin-bottom:6px; font-size:12px; color:var(--muted-foreground) }
.zona select{ width:100% }
select[data-slot="input"]{ appearance:none; padding-right:30px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238A8A96' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat; background-position:right 9px center; background-size:15px }
html[data-tema="claro"] select[data-slot="input"]{
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%236B6B75' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") }

.fila-mando{ display:flex; gap:10px; margin-top:12px; flex-wrap:wrap; align-items:center }
.fila-mando [data-slot="button"]{ flex:0 0 auto }
.limpia{ font-size:12.5px; color:var(--muted-foreground); min-height:24px;
  text-decoration:underline; text-underline-offset:4px }
@media (hover:hover){ .limpia:hover{ color:var(--foreground) } }
.orden-frase{ margin-top:14px; font-size:12.5px; color:var(--muted-foreground) }
.orden-frase button{ color:var(--foreground); font-size:inherit;
  text-decoration:underline; text-underline-offset:4px; min-height:24px }
@media (hover:hover){ .orden-frase button:hover{ color:#e100ff } }

/* ── LA FICHA DE UN PROPIETARIO ─────────────────────────────────────────── */
.prop{ padding:18px 0; border-bottom:1px solid var(--border) }
.prop:last-of-type{ border-bottom:0 }
.prop .l1{ display:flex; align-items:baseline; gap:10px; flex-wrap:wrap }
.prop .precio{ font-size:19px; font-weight:600; letter-spacing:-.02em;
  font-variant-numeric:tabular-nums }
.prop .nom{ font-size:14px; color:var(--muted-foreground); flex:1 1 auto }
/* EL TELÉFONO · a la derecha del todo, para que los de una lista queden en
   columna y se lean de un vistazo. Tabular para que las cifras no bailen, y
   seleccionable: de aquí se copia para buscarlo. */
.prop .tel{ margin-left:auto; font-family:var(--font-mono); font-size:14px;
  letter-spacing:-.01em; font-variant-numeric:tabular-nums; user-select:text }
.prop .dato{ margin-top:5px; font-size:13px; color:var(--muted-foreground) }
/* Más de un año en el mercado: se enciende. Un piso que lleva años sin
   venderse es un propietario cansado, y eso ES el motivo de la llamada. */
.prop .viejo{ color:#e100ff }
.prop .pie{ display:flex; align-items:center; gap:14px; margin-top:12px; flex-wrap:wrap }
.prop .pie [data-slot="button"]{ height:34px !important; font-size:13px }
.prop .ver{ font-size:12.5px; color:var(--muted-foreground); min-height:24px;
  text-decoration:underline; text-underline-offset:4px }
@media (hover:hover){ .prop .ver:hover{ color:var(--foreground) } }
.prop .puntos{ margin-left:auto; width:32px; height:32px; display:grid; place-items:center;
  border-radius:8px; color:var(--muted-foreground) }
@media (hover:hover){ .prop .puntos:hover{ color:var(--foreground); background:var(--secondary) } }
.prop .puntos svg{ width:16px; height:16px }
@media (max-width:640px){ .prop .puntos{ width:44px; height:44px } }
/* Lo que la tarjeta añade en la ficha de un agente: la nota y quién/cuándo. */
.prop .apunte{ margin-top:6px; font-size:13px; line-height:1.45; color:var(--muted-foreground) }

/* ── LA EXCLUSIVA CONSEGUIDA · 28/09/2026 ─────────────────────────────────
   La pastilla verde: el único sitio del producto que usa --exito. Rellena y con
   tinta oscura (ver el token): se ve de lejos en los dos temas. */
.pill-exito{ display:inline-flex; align-items:center; gap:6px; width:fit-content;
  padding:4px 10px; border-radius:9999px; background:var(--exito); color:#08080A;
  font-size:12.5px; font-weight:600; line-height:16px; white-space:nowrap }
.pill-exito svg{ width:14px; height:14px; flex:none }
/* La fila de la exclusiva en «Ya llamados»: el icono para marcarla o la pastilla
   con «Quitar». El icono con la misma medida que el edificio de Propietarios. */
.hecho .exclusiva{ display:flex; align-items:center; gap:12px; margin-top:10px }
.hecho .exclusiva .marca-ex{ display:inline-flex; align-items:center; gap:8px; min-height:44px;
  font-size:13px; color:var(--muted-foreground) }
.hecho .exclusiva .marca-ex svg{ width:18px; height:18px }
@media (hover:hover){ .hecho .exclusiva .marca-ex:hover{ color:var(--foreground) } }
.hecho .exclusiva .quita-ex{ min-height:44px; font-size:12.5px; color:var(--muted-foreground);
  text-decoration:underline; text-underline-offset:4px }
/* 29/09 · LA FILA DE ABAJO DE UNA FICHA DE «YA LLAMADOS»: «Ver anuncio» a la izquierda y la
   exclusiva a la derecha; si no caben, la exclusiva baja y se queda a la izquierda
   (space-between con un solo elemento en la línea lo deja al principio). Nada se parte.
   Debajo, el «Del … al …». */
.pie-hecho{ margin-top:10px }
.pie-hecho .fila-ver{ display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:0 16px }
.pie-hecho .ver{ display:inline-flex; align-items:center; min-height:44px; font-size:12.5px; color:var(--muted-foreground);
  text-decoration:underline; text-underline-offset:4px }
@media (hover:hover){ .pie-hecho .ver:hover{ color:var(--foreground) } }
.pie-hecho .exclusiva{ margin-top:0; flex-wrap:nowrap; white-space:nowrap }
.rango-ex{ margin:2px 0 0; font-size:13px; color:var(--muted-foreground) }
/* La pastilla dentro de la tarjeta de la ficha del agente (responsable). */
.prop .ex-ficha{ margin-top:10px }

/* ── LAS EXCLUSIVAS POR PERIODO (exclusivas.js) ──────────────────────────
   El selector son los chips del sistema (chips.js), de uno en uno; la cifra es
   la de «Hoy» (.hoy-n) y la comparación va pequeña al lado. */
.periodo .chips{ margin-top:2px }
/* 29/09 · en la hoja del agente el selector iba pegado al título (Marc): el mismo aire que
   hay entre una etiqueta y su campo en las hojas (18 px). */
.hoja > #mx-cuerpo{ margin-top:18px }
/* 10/10 · Marc: «que el pop-up de exclusivas sea consistente de tamaño, haya 1 o haya 10 —si no es
   molesto al cambiar de Esta semana a Siempre— y scrolleable». La hoja tiene SIEMPRE el mismo alto
   y lo que se desliza es su contenido, no la hoja. */
#hoja-exclusivas{ height:min(calc(78svh / var(--zoom, 1)), 640px); overflow-y:hidden }
#hoja-exclusivas > #mx-cuerpo{ flex:1 1 auto; min-height:0; overflow-y:auto; overscroll-behavior:contain;
  margin-right:-8px; padding-right:8px }
.periodo .cifra-periodo{ margin-top:16px }
.periodo .hoy-n .antes{ font-size:13px; color:var(--muted-foreground) }
.periodo .rot{ margin:22px 0 8px; font-size:11.5px; font-weight:500; letter-spacing:.1em;
  text-transform:uppercase; color:var(--muted-foreground) }
.periodo .vacio-p{ margin-top:14px; font-size:14px; color:var(--muted-foreground) }
/* Por agente: filas que se tocan para filtrar. Toda la fila es el botón. */
.por-agente{ display:flex; flex-direction:column }
.por-agente button{ display:flex; align-items:center; gap:10px; min-height:44px; padding:0 2px;
  border-bottom:1px solid var(--border); text-align:left; font-size:14px; color:var(--foreground) }
.por-agente button:last-child{ border-bottom:0 }
.por-agente button .n{ margin-left:auto; font-variant-numeric:tabular-nums; font-weight:600 }
.por-agente button .cero{ color:var(--muted-foreground); font-weight:400 }
.por-agente button[aria-pressed="true"]{ color:var(--foreground); font-weight:600 }
.por-agente button[aria-pressed="false"].hay-filtro{ color:var(--muted-foreground) }
/* 29/09 · la cabecera de la lista: el rótulo a la izquierda y «Ver las de todos» fijo a la
   derecha, con alto fijo; el nombre del agente filtrado va debajo y no lo mueve. */
.periodo .cab-lista{ display:flex; align-items:center; justify-content:space-between; gap:12px;
  min-height:44px; margin:22px 0 4px }
.periodo .cab-lista .rot{ margin:0 }
.periodo .cab-lista button{ flex:none; min-height:44px; font-size:13px; color:var(--foreground);
  text-decoration:underline; text-underline-offset:4px; white-space:nowrap }
.periodo .filtro-ag{ margin:0 0 4px; font-size:13px; color:var(--muted-foreground); overflow-wrap:anywhere }
/* La lista corta (la del agente): nombre y fecha, una línea cada una. */
.ex-corta{ display:flex; flex-direction:column }
.ex-corta .fila{ display:flex; align-items:baseline; gap:4px 10px; flex-wrap:wrap; padding:12px 0; border-bottom:1px solid var(--border) }
.ex-corta .fila .rango{ flex-basis:100%; font-size:13px; color:var(--muted-foreground) }
.ex-corta .fila:last-child{ border-bottom:0 }
.ex-corta .fila .cuando{ margin-left:auto; font-size:13px; color:var(--muted-foreground); white-space:nowrap }
/* ── EL SEGUIMIENTO (seguimiento.js) · 09/10/2026 ─────────────────────────
   La misma pieza que Exclusivas: chips, cifra, «Por agente» y la tarjeta de
   Propietarios. Lo único suyo es cuándo toca. VENCIDO pide atención con lo mismo
   que la espera vieja (tinta entera y 600); el verde sigue siendo SOLO de la
   exclusiva conseguida. «Pon fecha» = uno migrado de «Ya he hablado» sin fecha. */
.prop .apunte [data-slot="badge"].toca.vencido,
.prop .apunte [data-slot="badge"].pon-fecha{ color:var(--foreground); font-weight:600; border-color:var(--foreground) }
/* «Próximos» y «Exclusivas conseguidas»: el plegable del sistema (.despliega, con su
   flecha que gira), a lo ancho y con su raya encima, para que se lea como una sección
   que se abre y no como un texto suelto. Dentro de «Próximos», un rótulo por DÍA. */
.periodo .seg-plegable{ margin-top:22px; border-top:1px solid var(--border) }
.periodo .seg-plegable > summary{ display:flex; width:100%; min-height:52px; font-size:14px; font-weight:500;
  color:var(--foreground) }
/* La flecha es la de todos los desplegables (.despliega, arriba = la de «Lo que dice el
   anuncio»); aquí solo el aire y su gris. */
.periodo .seg-plegable > summary{ gap:10px }
.periodo .seg-plegable > summary::before{ color:var(--muted-foreground) }
/* «Iniciar seguimiento»: la aclaración del siguiente paso, separada de su pregunta */
.hoja .pista.pista-paso{ margin:10px 0 14px }
/* 09/10 · Marc: entre «Lo apartas… tu responsable» y el primer motivo, aire */
#dd-motivos{ margin-top:18px }
.periodo .seg-dia{ display:flex; align-items:baseline; gap:8px; margin:20px 0 0; padding-bottom:6px;
  border-bottom:1px solid var(--border); font-size:13px; font-weight:600; color:var(--foreground) }
.periodo .seg-dia .n{ margin-left:auto; font-weight:500; color:var(--muted-foreground); font-variant-numeric:tabular-nums }
.periodo .seg-dia + .prop{ padding-top:12px }
/* Los atajos de la fecha del próximo contacto (fecha.js): los chips, debajo del campo. */
.chips.atajos-fecha{ margin-top:10px }

/* ── LA REFERENCIA DE ZONA (Prop.zona, prop.js) · 09/10/2026 ───────────────
   Un dato más de la ficha. Marc: lo de SU caso (su €/m² y el %) en verde si está por
   debajo de la zona y en rojo si está por encima; la referencia, en el gris del dato.
   Nada más: ni «revisar m²» ni otros estados («todo simple»). */
.pf-pct{ font-variant-numeric:tabular-nums; white-space:nowrap }
/* 09/10 · Marc: lo de SU caso en color —por debajo de la zona en verde, por encima en rojo—;
   la referencia de la zona, no: se queda en el gris del dato. */
.ref-zona .su.bajo, .pf-pct.bajo{ color:var(--exito-txt); font-weight:600 }
.ref-zona .su.sobre, .pf-pct.sobre{ color:var(--destructive); font-weight:600 }
.ref-zona{ font-variant-numeric:tabular-nums; overflow-wrap:anywhere }

/* Encima de cada tarjeta de la lista del responsable: fecha y agente. */
.ex-cab{ margin-top:18px; font-size:12.5px; color:var(--muted-foreground) }
.ex-cab + .prop{ padding-top:6px }

/* ── EL BUSCADOR DE «YA LLAMADOS» · el campo del sistema, sin estilo propio ── */
.busca-hechos{ margin:4px 0 8px }
/* 09/10 · el HISTORIAL (antes «Ya llamados») se abre desde el menú: lleva su título arriba. */
.cab-historial{ margin:4px 0 14px }
.cab-historial .saludo{ margin:0 }
.cab-historial .sub-historial{ margin:6px 0 0; font-size:14px; color:var(--muted-foreground) }
.busca-hechos [data-slot="input"]{ width:100% }
.nadie-con{ padding:28px 0; text-align:center; font-size:14px; color:var(--muted-foreground) }
.nadie-con [data-slot="button"]{ margin-top:12px }
.prop .suyo{ display:inline-flex; align-items:center; gap:6px; font-size:13px;
  color:var(--muted-foreground) }
.prop .suyo b{ color:var(--foreground); font-weight:500 }
.prop .suyo svg{ width:15px; height:15px; color:#3FBF7F }

/* los inmuebles, desplegados */
.inmuebles{ margin-top:12px; padding-left:12px; border-left:1px solid var(--border) }
.inmueble{ padding:9px 0 }
.inmueble + .inmueble{ border-top:1px solid var(--border-muted, var(--border)) }
.inmueble .a{ display:flex; align-items:baseline; gap:8px; flex-wrap:wrap; font-size:13px }
.inmueble .b{ margin-top:3px; font-size:12px; color:var(--muted-foreground) }
.inmueble a{ color:var(--foreground); text-decoration:underline; text-underline-offset:4px;
  display:inline-block; min-height:24px; font-size:12.5px }
@media (hover:hover){ .inmueble a:hover{ color:#e100ff } }
.aviso-enlace{ margin-top:10px; font-size:11.5px; line-height:1.5; color:var(--muted-foreground) }

/* el agente elegido, en el diálogo de repartir */
.agentes{ margin-top:14px; display:flex; flex-direction:column; gap:8px }
.ag-op{ display:flex; align-items:center; gap:10px; width:100%; text-align:left;
  padding:11px 13px; border:1px solid var(--border); border-radius:10px;
  background:var(--card); font-size:14px }   /* D · la transición la pone el molde */
@media (hover:hover){ .ag-op:hover:not(:disabled){ border-color:var(--input) } }
.ag-op:disabled{ opacity:.55; cursor:not-allowed }
.ag-op .n{ flex:1 1 auto; min-width:0 }
.ag-op .c{ flex:none; font-size:12.5px; color:var(--muted-foreground);
  font-variant-numeric:tabular-nums; white-space:nowrap }

@media (max-width:340px){
  /* Solo en las MUY estrechas —un iPhone SE de primera, 320 px— el botón no
     cabe al lado del buscador sin dejarlo inservible. Baja de línea; no
     encoge, que es lo que lo dejaría sin poder pulsarse.
     ⚠️ Esto estuvo en 400 px y se disparaba en un iPhone 14 (393), donde caben
     los dos de sobra. Un punto de ruptura mal puesto se ve en el móvil más
     común que hay. */
  .mando-eq{ flex-wrap:wrap }
  .mando-eq .busca{ flex-basis:100% }
  .mando-eq [data-slot="button"]{ flex:1 }
}

/* ══════════════════════════════════════════════════════════════════════════
   LA CABECERA COMPARTIDA · lo que trajo el cambio de puerta
   ──────────────────────────────────────────────────────────────────────────
   Cuando `/` pasó a ser «Mi equipo» y `/leads` a «Propietarios», el panel
   viejo dejó de servirse. Estas son las cuatro cosas suyas que eran de la
   cabecera y no podían caerse: en qué agencia estás, quién eres, la puerta a
   «¿Qué es Novoconect?» y la franja de visita de administrador. Las pinta
   cabeza.js, una vez, para las tres pantallas.
   ══════════════════════════════════════════════════════════════════════════ */

/* LA AGENCIA, AL LADO DE LA MARCA. Con su barrita delante, y solo cuando hay
   nombre: `:empty` evita que un separador suelto quede colgando mientras
   /api/yo todavía no ha contestado. */
.cabecera .marca-ag{ min-width:0; font-size:13px; color:var(--muted-foreground) }
.cabecera .marca-ag:not(:empty)::before{ content:""; display:inline-block;
  width:1px; height:11px; margin:0 9px -1px 3px; background:var(--border) }
@media (max-width:480px){ .cabecera .marca-ag{ font-size:12px } }

/* EL MENÚ DE QUIÉN ERES. Cuelga de la cabecera, no del cuerpo, para que no
   haya que calcularle la posición. */
.cabecera{ position:relative }
.menu{ position:absolute; top:calc(100% - 6px); right:14px; z-index:60;
  min-width:210px; max-width:calc(100vw - 28px);
  padding:6px; border:1px solid var(--border); border-radius:12px;
  background:var(--card); box-shadow:0 18px 44px -18px rgba(0,0,0,.7);
  opacity:0; visibility:hidden; transform:translateY(-4px);
  transition:opacity .14s ease, transform .14s ease, visibility .14s }
.menu.on{ opacity:1; visibility:visible; transform:none }
.menu .quien{ padding:10px 11px 11px; border-bottom:1px solid var(--border);
  margin-bottom:6px; display:flex; flex-direction:column; gap:2px }
.menu .quien b{ font-size:14px; font-weight:600; overflow-wrap:anywhere }
.menu .quien span{ font-size:12.5px; color:var(--muted-foreground); overflow-wrap:anywhere }
.menu .quien i{ margin-top:4px; font-style:normal; font-size:11.5px;
  color:var(--muted-foreground); text-transform:uppercase; letter-spacing:.06em }
.menu a, .menu button{ display:flex; align-items:center; width:100%; text-align:left;
  min-height:38px; padding:0 11px; border-radius:8px; font-size:13.5px;
  color:var(--foreground) }   /* D · la transición la pone el molde */
@media (hover:hover){ .menu a:hover, .menu button:hover{ background:var(--secondary) } }
@media (prefers-reduced-motion: reduce){ .menu{ transition:none } }

/* ── LAS PESTAÑAS ─────────────────────────────────────────────────────────
   Las dos secciones del producto, y solo las dos. Van debajo de la cabecera
   —no dentro— porque no son un mando de la cabecera: son dónde estás.
   ⛔ Retirados no está: queda fuera de V1. */
.pestanas{ display:flex; gap:4px; padding:0 20px;
  border-bottom:1px solid var(--border) }
.pestanas a{ position:relative; display:flex; align-items:center; min-height:40px;
  padding:0 12px; font-size:13.5px; color:var(--muted-foreground) }   /* D · la pulsación la pone el molde (data-pulsa) */
/* 🔴 #37 · EL HOVER NO PUEDE LLEGAR AL COLOR DE «SELECCIONADO».
   Marc: «al abrir y cerrar se buguea el brillo de seleccionado: parece activo
   cuando no lo esta, y al reves». Medido el 08/09/2026: la pestania inactiva
   con el raton encima daba rgb(247,247,247), EXACTAMENTE el mismo color que la
   activa. Con el puntero en cualquier sitio de la barra, las dos se leian
   igual — y en un movil el hover se queda pegado despues de tocar, asi que se
   queda asi hasta que tocas otra cosa.
   ⚠️ El hover se queda A MEDIO CAMINO. La activa se distingue por tres cosas
   a la vez —color, peso y la raya de abajo— y el hover solo toca el color, y
   sin llegar. */
@media (hover:hover){ .pestanas a:hover{ color:var(--pestana-roce) } }
/* Y el foco por teclado SE VE. Estaba en  sin nada en su sitio:
   con Tab no habia forma de saber donde estabas. Es la misma raya de la activa
   pero en el color del texto, para que no se confunda con «esta seleccionada». */
.pestanas a:focus-visible{ color:var(--foreground); outline:2px solid var(--ring);
  outline-offset:-2px; border-radius:6px }

/* ══ #36 · LAS TRES LÍNEAS SE CONVIERTEN EN X ═══════════════════════════════
   Las tres nacen en el MISMO sitio —el centro, y=12— y se separan con
   transform. Así girar es girar sobre su propio eje: la de arriba baja al
   centro y gira 45°, la de abajo sube y gira -45°, y la del medio se apaga.
   ⚠️ Se separan con `translateY` y no con tres `d` distintos porque una `d`
   no se puede animar sin trampas, y esto tiene que ser un gesto, no un salto.
   ⚠️ `transform-box: fill-box` + `transform-origin: center`: sin eso el giro
   se hace sobre el origen del SVG y la X sale desplazada. Es el fallo clásico
   de esto y no se ve hasta que se prueba.
   ⚠️ Y respeta a quien pide menos movimiento: entonces cambia igual, pero sin
   el viaje. La X tiene que estar; lo que sobra es el trayecto. */
/* #94 · Marc: «el cambio de las 3 líneas a la X debería ser más suave; ahora es muy
   brusco». Era .22 s con la curva del producto (que arranca a golpe); ahora .4 s
   con una curva simétrica y la del medio se apaga a la vez que giran. */
.tres path{ transition:transform .32s var(--curva), opacity .2s var(--curva);
  transform-box:fill-box; transform-origin:center }
.tres .l1{ transform:translateY(-6px) }
.tres .l3{ transform:translateY(6px) }
.icono-btn.x .tres .l1{ transform:translateY(0) rotate(45deg) }
.icono-btn.x .tres .l2{ opacity:0 }
.icono-btn.x .tres .l3{ transform:translateY(0) rotate(-45deg) }
@media (prefers-reduced-motion: reduce){ .tres path{ transition:none } }

/* LA DE LA PÁGINA, MARCADA. `aria-current` no es un adorno de accesibilidad
   aquí: es lo que dibuja la marca, así que no pueden separarse. */
/* 🔴 #92 · LAS PESTAÑAS SE VEN PULSABLES · Marc, 12/09/2026: «deberían aparentar
   que se pueden pulsar; sin inventar diseño, siguiendo el patrón del producto,
   pero que no parezcan títulos». El patrón es el de los botones con borde del
   sistema (los outline del #46): cada pestaña es una pastilla con borde de
   contraste 3,0; la activa lleva además el fondo del producto (el mismo tinte
   del elegido en «Añadir»). La raya de debajo sigue: son las dos señales. */
.pestanas{ gap:8px; padding-top:10px; padding-bottom:10px }   /* D · centradas entre sus dos líneas: mismo aire arriba y abajo */
.pestanas a{ min-height:36px; padding:0 14px; border:1px solid #6E6E82; border-radius:9px;
  background:color-mix(in srgb, var(--input) 30%, transparent) }
html[data-tema="claro"] .pestanas a{ border-color:#80808E; background:var(--background) }
.pestanas a[aria-current="page"]{ color:var(--foreground); font-weight:500;
  border-color:var(--primary); background:color-mix(in srgb, var(--primary) 8%, var(--card)) }
.pestanas a[aria-current="page"] .n{ color:var(--foreground) }
/* ⛔ #92 · la raya de debajo se fue con las pastillas: el borde y el fondo de la
   activa ya la señalan, y una raya bajo una pastilla redondeada no encaja. */
/* EL NÚMERO DE LA PESTAÑA · «Equipo 8 · Propietarios 172.761»
   Gris y más pequeño: dice qué hay dentro, no compite con el nombre. Nace
   VACÍO y se rellena cuando llega /api/cuentas (ver cabeza.js), así que no
   puede dejar un hueco ni empujar nada: sin contenido no ocupa, y el
   margen solo aparece cuando hay número.
   ⚠️ tabular-nums para que 8 y 172.761 no bailen al cambiar de pestaña. */
/* C (Marc, 12/09/2026) · sitio reservado desde el principio: ancho mínimo por
   pestaña (cabe «Propietarios 165.146») y dígitos tabulares, para que el número
   no las mueva; y centradas en vertical entre sus dos líneas. */
.pestanas a{ justify-content:center; align-items:center; font-variant-numeric:tabular-nums }
.pestanas a[href$="/"], .pestanas a[href$="/equipo"]{ min-width:7.4em }
.pestanas a[href$="/leads"], .pestanas a[href$="/propietarios"]{ min-width:12.6em }
.pestanas a .n{ font-size:12px; color:var(--muted-foreground); font-variant-numeric:tabular-nums;
  font-variant-numeric:tabular-nums; font-weight:400 }
.pestanas a .n:not(:empty){ margin-left:6px }
/* En la activa el número sigue siendo secundario: el nombre es el que manda. */
.pestanas a[aria-current="page"] .n{ color:var(--muted-foreground) }

@media (max-width:640px){ .pestanas a{ min-height:44px; padding:0 14px } }

/* ── LA FRANJA DE VISITA DE ADMINISTRADOR ─────────────────────────────────
   Pegada arriba y por encima de todo. Dos estados y se distinguen de lejos:
   cobre = solo mirar, rojo = actuando. El hueco que deja lo mide cabeza.js;
   aquí no hay ni un número de alto escrito a mano. */
.franja-admin{ position:fixed; top:0; left:0; right:0; z-index:90;
  display:flex; align-items:center; gap:10px; flex-wrap:wrap;
  padding:9px 14px; padding-top:max(9px, env(safe-area-inset-top, 0px));
  font-size:12.5px; line-height:1.4;
  color:#f4e3c4; background:#3a2a10; border-bottom:1px solid #6b4e1a }
.franja-admin.actuando{ color:#ffe4e4; background:#4a1414; border-bottom-color:#8c2a2a }
.franja-admin .fa-ojo{ display:grid; place-items:center; flex:none }
.franja-admin .fa-ojo svg{ width:15px; height:15px }
/* `flex:1 1 0` y no `auto`: con la base en el contenido, el texto no cabía al
   lado del ojo y se iba a la línea de abajo dejando el icono solo en una fila
   para él. Con base cero encoge y se queda donde tiene que estar. */
.franja-admin .fa-t{ flex:1 1 0; min-width:0 }
.franja-admin .fa-t b{ font-weight:600 }
.franja-admin button{ flex:none; min-height:26px; padding:0 10px; border-radius:7px;
  border:1px solid currentColor; font-size:12px; color:inherit }   /* D · la transición la pone el molde */
@media (hover:hover){ .franja-admin button:hover{ background:rgba(255,255,255,.1) } }
.franja-admin button:disabled{ opacity:.5 }
/* Lo que se queda pegado arriba empieza POR DEBAJO de la franja, no detrás.
   `--tope` lo publica cabeza.js con el alto medido de verdad. */
.con-franja-admin .pestanas{ position:relative; z-index:1 }

/* ── EL SALUDO ────────────────────────────────────────────────────────────
   «Buenos días, Marc» y, debajo, qué es esta pantalla. Estaba en el panel
   viejo y se queda. */
.saludo{ font-size:20px; font-weight:600; letter-spacing:-.03em; margin-bottom:14px }   /* #101 · Marc: aire entre «Buenas tardes, X» y el «1 de 21» */
.saludo b{ font-weight:600 }
.saludo-sub{ margin-top:4px; font-size:13.5px; color:var(--muted-foreground) }

/* ══════════════════════════════════════════════════════════════════════════
   AJUSTAR QUÉ RECIBE · la hoja lateral
   ──────────────────────────────────────────────────────────────────────────
   No es una pantalla: es una hoja que entra por la derecha con la ficha
   detrás, para que no se pierda de vista a quién se le está ajustando. En el
   móvil ocupa todo, porque media pantalla en 393 px no es media pantalla, es
   un pasillo.
   ⚠️ TRES PREGUNTAS, NO OCHO CAMPOS: dónde, qué y de cuánto. Nadie piensa en
   «clave 6 de 8».
   ══════════════════════════════════════════════════════════════════════════ */
.velo-lado{ position:fixed; inset:0; z-index:80; display:flex; justify-content:flex-end;
  background:rgba(0,0,0,.55); opacity:0; visibility:hidden;
  transition:opacity .22s ease, visibility .22s ease }
.velo-lado.on{ opacity:1; visibility:visible }
html[data-tema="claro"] .velo-lado{ background:rgba(8,8,10,.32) }

.hoja-lado{ display:flex; flex-direction:column; width:100%; height:100%;
  background:var(--card); border-left:1px solid var(--border);
  transform:translateX(100%); transition:transform .24s cubic-bezier(.16,1,.3,1) }
.velo-lado.on .hoja-lado{ transform:none }
@media (min-width:640px){ .hoja-lado{ max-width:440px } }
@media (prefers-reduced-motion: reduce){
  .velo-lado, .hoja-lado{ transition:none }
}

.hoja-lado .cab{ display:flex; align-items:center; gap:12px;
  padding:0 20px 12px; border-bottom:1px solid var(--border) }
.hoja-lado .cab h2{ flex:1; min-width:0; font-size:17px; font-weight:600;
  letter-spacing:-.02em; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.hoja-lado .cuerpo{ flex:1; overflow-y:auto; padding:20px }
.hoja-lado .grupo + .grupo{ margin-top:28px }
.hoja-lado .rot{ font-size:11.5px; font-weight:500; text-transform:uppercase;
  letter-spacing:.16em; color:var(--muted-foreground) }
/* Los desplegables nativos: en el móvil abren la rueda del sistema, que gana a
   cualquier lista propia por bien hecha que esté. */
.hoja-lado select{ width:100%; height:40px; margin-top:12px; padding:0 12px;
  border:1px solid var(--input); border-radius:9px;
  background:var(--background); color:inherit; font-family:inherit; font-size:14px }
@media (max-width:640px){ .hoja-lado select{ height:44px; font-size:16px } }
.hoja-lado .pista{ margin-top:8px; font-size:12.5px; color:var(--muted-foreground) }
/* E.2 · el número del día vive dentro de la hoja, arriba, fuera del cuerpo que
   desplaza; y E.3/E.4: el fallo se dice en el pie, encima de los botones. */
.hoja-lado .grupo.cuantos{ padding:16px 20px 0 }
.hoja-lado .fila-pd{ display:flex; align-items:center; gap:10px; margin-top:10px; font-size:14px }
.hoja-lado .fila-pd input{ width:96px; text-align:center; font-variant-numeric:tabular-nums }
.hoja-lado .fallo{ margin:0 0 10px; font-size:13px; color:var(--destructive, #e5484d) }
.hoja-lado .fallo:empty{ display:none }

/* Lo elegido baja a fichas que se quitan de una en una. */
.elegidos{ display:flex; flex-wrap:wrap; gap:6px; margin-top:12px }
.elegido{ display:inline-flex; align-items:center; gap:6px; height:32px;
  padding:0 8px 0 12px; border:1px solid var(--border); border-radius:999px;
  background:var(--secondary); color:inherit; font-size:13px }
.elegido span{ max-width:190px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap }
.elegido svg{ width:14px; height:14px; flex:none; color:var(--muted-foreground) }
@media (hover:hover){ .elegido:hover svg{ color:var(--foreground) } }
@media (max-width:640px){ .elegido{ height:44px } }

/* ⛔ AQUI VIVIA , el segundo estilo de lo mismo. Se fue con el #11:
   ahora las dos pantallas usan .chips del componente. */
.tipos{ display:flex; flex-wrap:wrap; gap:6px; margin-top:12px }
.tipos button{ height:36px; padding:0 14px; border:1px solid var(--border);
  border-radius:999px; background:var(--background); font-size:13px }   /* D · la transición la pone el molde */
@media (hover:hover){ .tipos button:hover{ background:var(--secondary) } }
.tipos button[aria-pressed="true"]{ background:var(--primary);
  color:var(--primary-foreground); border-color:var(--primary) }
@media (max-width:640px){ .tipos button{ height:44px } }

.rango + .rango{ margin-top:16px }
.rango .et{ margin-bottom:6px; font-size:13px; color:var(--muted-foreground) }
.rango .fila{ display:flex; align-items:center; gap:8px }
.rango [data-slot="input"]{ height:40px; font-variant-numeric:tabular-nums; min-width:0 }
.rango .guion{ color:var(--muted-foreground) }
.rango .uni{ width:36px; flex:none; font-size:13px; color:var(--muted-foreground) }

/* ⚠️ SE LLAMA `pie-hoja` Y NO `pie` A PROPÓSITO. Con `.hoja-lado .pie` heredaba
   el `.pie` del acceso ENTERO —margen de 24, tamaño, color y text-align:center—
   y la línea del pie salía centrada sin que nadie lo hubiera pedido. Se vio
   mirándola; medido decía center y era verdad, pero no decía de dónde.
   Un nombre genérico en una hoja compartida es una colisión esperando. */
.hoja-lado .pie-hoja{ padding:16px 20px;
  padding-bottom:max(16px, calc(env(safe-area-inset-bottom) + 16px));
  border-top:1px solid var(--border) }
.hoja-lado .pie-hoja .dos{ display:flex; gap:8px }
.hoja-lado .pie-hoja .dos [data-slot="button"]{ flex:1; height:44px }

/* ── LA LÍNEA QUE SIEMPRE ESTÁ ────────────────────────────────────────────
   Va en el pie de la hoja Y en la caja de la ficha, y con FONDO, no en gris:
   no es una nota al pie, es lo que hay que saber antes de guardar.
   ⛔ Aquí hubo un contador de alcance —«tiene para 7 días»— y se tiró con
   razón: proyectar sobre un stock que se rellena solo nace caducado. */
.aviso-zona{ margin-bottom:12px; padding:10px 12px; border-radius:10px;
  background:var(--secondary); font-size:12.5px; line-height:1.6 }
/* 🔴 Y EL CASO EN QUE NO LLEGA NADIE, que sí es un hecho del momento y no una
   proyección: se sustituye la línea, se pinta en magenta y Guardar se apaga.
   Sin esto se guarda una regla que deja al agente seco mañana. */
.aviso-seco{ display:flex; gap:10px; margin-bottom:12px; padding:12px;
  border-radius:10px;
  border:1px solid color-mix(in srgb, var(--primary) 40%, transparent);
  background:color-mix(in srgb, var(--primary) 8%, transparent);
  font-size:13px; line-height:1.55 }
.aviso-seco svg{ width:16px; height:16px; flex:none; margin-top:1px; color:var(--primary) }

/* ══ LAS NOTAS · tanda 2 · 5 (Marc, 12/09/2026) · nota.js ═══════════════════
   Tres líneas y se corta; «Ver más» la abre entera. `overflow-wrap:anywhere` es lo
   que impide que una palabra sin espacios se salga por la derecha. */
.nota-txt{ display:-webkit-box; -webkit-box-orient:vertical; -webkit-line-clamp:3; overflow:hidden;
  overflow-wrap:anywhere; word-break:break-word; white-space:pre-line }
.nota-txt.abierta{ -webkit-line-clamp:unset; display:block }
.nota-mas{ display:inline-block; margin-top:2px; font-size:12.5px; color:var(--foreground);
  border-bottom:1px solid var(--border); padding:0 }
.apunte, .hecho .nota, .llamado .apunte{ overflow-wrap:anywhere; word-break:break-word }
.nota-cuenta{ margin-top:4px; font-size:12px; color:var(--muted-foreground); text-align:right; min-height:1em }
.nota-cuenta.al-tope{ color:var(--destructive, #e5484d) }

/* ══ EL MOLDE, AL FINAL · D (Marc, 12/09/2026) ═════════════════════════════
   Un solo lenguaje de pulsación para TODO lo que se pulsa: cualquier <button>,
   los botones del sistema ([data-slot="button"], que es lo que lleva «Volver a
   Equipo») y lo que no es botón pero se pulsa ([data-pulsa]: las pestañas de
   arriba, las tarjetas del equipo). Se hunde a --hunde con --curva y marca dónde
   le has dado (la onda, boton.js). Va al final y con :is() —especificidad de
   clase— para que ninguna `transition` escrita antes para un botón concreto
   pueda darle otro tacto. Si mañana cambia, cambia aquí y en ningún otro sitio. */
:is(button, [data-slot="button"], [data-pulsa], a[role="menuitem"], .lead a, .inmueble a, .vacio a, .nota-mas){
  transition:transform .12s var(--curva), background .2s var(--curva),
  border-color .2s var(--curva), opacity .2s var(--curva), color .15s var(--curva) }
:is(button, [data-slot="button"], [data-pulsa], a[role="menuitem"], .lead a, .inmueble a, .vacio a, .nota-mas):active:not(:disabled){ transform:scale(var(--hunde)) }
/* y si alguien prefiere no ver movimiento: ni hundido ni onda, solo el color */
/* ── #132 · CAMBIAR DE SECCIÓN SIN QUE PARPADEE LA PANTALLA (Marc, 13/09/2026) ──
   Equipo y Propietarios son dos documentos: al pasar de uno a otro el navegador
   vaciaba la pantalla y pintaba la nueva, y eso es el «pestañeo de toda la
   pantalla». Con la transición de vista entre documentos (Chrome 126+, Safari
   18.2+) el navegador se queda con la foto de la pantalla vieja hasta que la
   nueva está pintada, y entonces la cambia. Y la cambia EN SECO —sin fundido—,
   que es lo que hace la cola del agente entre Lista y Llamados. Donde no existe
   la regla, no pasa nada: se ignora. */
@view-transition { navigation: auto }
::view-transition-old(root), ::view-transition-new(root){ animation:none }

@media (prefers-reduced-motion: reduce){
  :is(button, [data-slot="button"], [data-pulsa]){ transition:color .15s ease, background .15s ease, border-color .15s ease }
  :is(button, [data-slot="button"], [data-pulsa]):active:not(:disabled){ transform:none }
  .onda{ display:none }
}
