/* ════════════════════════════════════════════════════════════════════════════
   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;
}
html[data-tema="claro"]{
  color-scheme: light;
  --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;
}

*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0 }
*{ border-color: var(--border) }
html,body,#raiz{ min-height:100% }
/* en móvil el teclado cambia la altura: svh evita el salto */
#raiz{ min-height:100svh }
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 }
[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;
  border:1px solid var(--input); 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;
  transition:background-color .15s ease, color .15s ease, border-color .15s ease, box-shadow .15s ease }
[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) }
[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?». */
[data-slot="button"][data-variant="outline"]{ border-color:var(--input);
  background:color-mix(in srgb, var(--input) 30%, transparent);
  box-shadow:0 1px 2px 0 rgb(0 0 0/.05) }
[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:var(--border); background:var(--background) }
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 }
[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 }

/* 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 }
}

/* 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 }
[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 }
.conmuta-tema:hover{ color:var(--foreground) }
.conmuta-tema svg{ width:16px; height:16px }

/* 20 px por los cuatro lados, y el CENTRADO ÓPTICO abajo.
   El ojo lee como centrado lo que está un poco por encima del centro
   geométrico: centrado exacto se percibe caído. Los 9vh empujan el bloque
   hacia arriba, y los 20 px siguen siendo el suelo mínimo. */
.acceso{ position:relative; z-index:10; display:grid; min-height:100svh; place-items:center;
  padding:20px; padding-bottom:calc(20px + 9vh) }
.acceso-caja{ width:100%; max-width:356px }

.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" */
.fila-recuerda{ display:flex; align-items:center; gap:12px; margin-top:4px }
.olvide{ margin-left:auto; font-size:12.5px; text-align:right;
  color:var(--muted-foreground); text-underline-offset:4px }
.olvide:hover{ color:var(--foreground); text-decoration:underline }

/* 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 }
.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) }
.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 }
.pie .enlace:hover{ color:#e100ff }
.pie .que-es{ display:inline-block; margin-top:32px }

/* ══ 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 }
.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.

   Y el centrado óptico se apaga aquí. Los 9vh de abajo son 60 px en una
   pantalla de 667: exactamente el aire que este bloque acaba de recuperar, y
   más. En una pantalla que va justa no hay hueco de sobra que regalarle al
   ojo, así que el bloque se centra a secas.  (Medido: con los 9vh puestos
   sobran 26 px y sale scroll; sin ellos caben con 34 px de margen.)
   ═══════════════════════════════════════════════════════════════════════════ */
@media (max-height: 720px){
  .acceso{ padding-bottom:20px }
  [data-slot="card"]{ padding-top:20px; padding-bottom:20px }
  [data-slot="field-group"]{ gap:16px }
  .marca{ margin-bottom:14px }
}
