/* =========================================================================
   SCORT — Base y primitivas
   =========================================================================
   Reset acotado, tipografia y los componentes que usa TODA la aplicacion.
   Los componentes de una pantalla concreta van en su propia hoja.
   ========================================================================= */

*,
*::before,
*::after {
    box-sizing: border-box;
}

html {
    -webkit-text-size-adjust: 100%;
}

body {
    margin: 0;
    min-height: 100vh;

    /* Columna: navbar, contenido, pie. Es lo que permite que `main` crezca y el pie se
       apoye SIEMPRE abajo, en vez de quedarse a media pantalla en una página corta con un
       vacío negro debajo. */
    display: flex;
    flex-direction: column;

    background: var(--scort-bg);
    color: var(--scort-text);
    font-family: var(--font-sans);
    font-size: var(--font-size-base);
    line-height: var(--line-normal);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;

    /* Halo ambiental fijo. Es lo que evita que el fondo negro se vea plano y
       barato: dos focos muy difusos del color de acento, sin coste de imagen. */
    background-image:
        radial-gradient(ellipse 80% 50% at 75% -5%, rgba(var(--scort-accent-rgb), 0.16), transparent 60%),
        radial-gradient(ellipse 60% 40% at 10% 0%, rgba(var(--scort-accent-rgb), 0.07), transparent 55%);
    background-attachment: fixed;
    background-repeat: no-repeat;
}

h1, h2, h3, h4, h5, h6 {
    margin: 0;
    font-weight: var(--weight-bold);
    line-height: var(--line-tight);
    letter-spacing: -0.02em;
}

p { margin: 0; }

a {
    color: var(--scort-accent);
    text-decoration: none;
    transition: color var(--duration-fast) var(--ease-out);
}

a:hover { color: var(--scort-accent-hover); }

img, svg { display: block; max-width: 100%; }

/* `[hidden]` TIENE QUE GANARLE A LO DE ARRIBA, y por eso lleva `!important`.

   El `display:none` de `[hidden]` lo pone la hoja del NAVEGADOR, y CUALQUIER
   regla de autor le gana — incluida la linea de aqui arriba. Consecuencia: un
   `<img hidden>` se seguia viendo. Paso dos veces en la misma tarde: las tomas
   del visor de estados se pintaban las tres a la vez, y la vista previa de
   subir un estado salia como un rectangulo negro.

   Se arregla una vez y aqui, no caso por caso: quien escriba `hidden` en un
   elemento manana no tiene por que saber que este reset existe.

   Es de los pocos `!important` justificados: no gana una pelea de estilos, le
   devuelve a un atributo del HTML el significado que el navegador le da. */
[hidden] { display: none !important; }

button { font-family: inherit; }

/* El foco visible NO se quita. Es la unica forma de navegar con teclado. */
:focus-visible {
    outline: 2px solid var(--scort-accent);
    outline-offset: 2px;
    border-radius: var(--radius-sm);
}

/* --- Disposicion ------------------------------------------------------ */

.scort-container {
    width: 100%;
    max-width: var(--container-max);
    margin-inline: auto;
    padding-inline: var(--space-5);
}

@media (max-width: 768px) {
    .scort-container { padding-inline: var(--space-4); }
}

/* `main` crece para empujar el pie al fondo. Va con el flex del body. */
main { flex: 1 0 auto; }

.scort-section { padding-block: var(--space-7); }

/* --- Encabezado de seccion -------------------------------------------- */

.scort-section-header {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-4);
    margin-bottom: var(--space-5);
    flex-wrap: wrap;
}

/* La cabecera que ya NO lleva título: solo la etiqueta de «Espacio promocionado».

   Sin el título, `space-between` dejaba la etiqueta pegada a la izquierda —no hay con
   quién repartir el espacio—, justo donde empieza la primera tarjeta. A la derecha se lee
   como lo que es: el sello de la sección, no un rótulo que la presenta. Y el margen baja,
   porque una línea pequeña no necesita el aire de un titular. */
.scort-section-header--solo-marca {
    justify-content: flex-end;
    margin-bottom: var(--space-3);
}

/* El pie de una sección SIN cabecera.

   Nace cuando la portada se queda sin rótulos: «Ver todos» vivía en la cabecera, a la
   derecha del título, y al quitar el título se quedaba solo arriba, flotando sobre una
   rejilla que aún no se ha visto. Al final se lee como lo que es: lo que se hace
   DESPUÉS de mirar los perfiles. */
.scort-section-footer {
    display: flex;
    justify-content: center;
    margin-top: var(--space-5);
}

.scort-section-header__title {
    font-size: var(--font-size-lg);
    font-weight: var(--weight-bold);
}

.scort-section-header__subtitle {
    color: var(--scort-text-muted);
    font-size: var(--font-size-sm);
    margin-top: var(--space-1);
}

/* Palabra acentuada dentro de un titular. En las referencias la ultima parte
   del claim va en color: es lo que da el aire premium al hero. */
.scort-accent { color: var(--scort-accent); }

/* --- Botones ----------------------------------------------------------- */

.scort-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    padding: 0.7rem 1.35rem;

    /* Suelo táctil. Medido: los botones de propina salían a 39px de alto en un móvil, por
       debajo de lo que se puede pulsar sin acertar de casualidad. El mínimo va en la clase
       BASE y no en cada variante, para que ninguna que se añada mañana nazca por debajo. */
    min-height: 44px;

    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    font-size: var(--font-size-base);
    font-weight: var(--weight-semibold);
    line-height: 1;
    cursor: pointer;
    white-space: nowrap;
    transition:
        background-color var(--duration-base) var(--ease-out),
        border-color var(--duration-base) var(--ease-out),
        box-shadow var(--duration-base) var(--ease-out),
        transform var(--duration-fast) var(--ease-out);
}

.scort-btn:active { transform: translateY(1px); }

/* ===========================================================================
   EL REFLECTOR: una banda de luz que cruza cada botón cada dos segundos

   Lo pidio el propietario, con esas palabras: «como si pasara un reflector cada
   2 segundos». Cruza en DOS segundos y descansa otros dos — lo primero que probe
   fue un barrido de 0,7 s y se leia como un chispazo: pasaba antes de que el ojo
   lo siguiera. Un reflector se reconoce porque se le ve recorrer.

   SE ANIMA `transform` Y NADA MÁS. Animar `background-position` o `left` obliga
   al navegador a recalcular y repintar el botón en cada fotograma; una
   transformación la resuelve la tarjeta gráfica sin tocar el diseño de la
   página. Con decenas de botones a la vez, ésa es la diferencia entre un
   adorno y un teléfono caliente.

   VA EN `::after` Y EL BOTÓN RECORTA. Sin `overflow: hidden` la banda se saldría
   por los lados; con él queda dentro de la píldora. El recorte no afecta al
   anillo de foco ni al halo, que se dibujan fuera de la caja y no son hijos.

   `pointer-events: none` porque la banda cubre el botón entero: sin eso se
   comería los clics del propio botón sobre el que pasa.

   LO QUE ESTO CUESTA, dicho aquí y no descubierto luego:

   1. La WCAG 2.2.2 pide poder PARAR cualquier animación automática que dure más
      de cinco segundos. Ésta no para nunca. El respiro es `prefers-reduced-
      motion`, más abajo, que la apaga entera para quien lo tenga puesto en su
      sistema — y ése es justo quien la sufre. No es un cumplimiento completo:
      es lo que se puede hacer sin meter un interruptor en la interfaz.

   2. Si brillan TODOS los botones, ninguno destaca. El reflector llama la
      atención por contraste con lo que está quieto, y aquí no queda nada
      quieto. Se hace como se pidió; acotarlo a los botones principales es un
      cambio de una línea el día que se quiera.

   NO hay riesgo de fotosensibilidad: la WCAG 2.3.1 habla de más de tres
   destellos por segundo y esto es uno cada dos. */
@keyframes scort-reflector {
    0% { transform: translateX(-140%) skewX(-18deg); }

    /* EL BARRIDO DURA DOS SEGUNDOS —la mitad del ciclo de cuatro— y después
       descansa otros dos. Lo pidió el propietario: «que sea de 2 segundos
       pasando, está muy rápido».

       Iba a 0,7 s y se leía como un chispazo: pasaba antes de que el ojo lo
       siguiera, y un reflector se reconoce porque se le ve recorrer. A dos
       segundos se sigue con la vista, que es lo que se buscaba.

       El descanso se queda: sin él la banda estaría cruzando siempre y dejaría
       de ser «algo que pasa cada tanto» para ser una cinta en movimiento. */
    50%, 100% { transform: translateX(320%) skewX(-18deg); }
}

.scort-btn,
.scort-audience__option {
    position: relative;
    overflow: hidden;
}

.scort-btn::after,
.scort-audience__option::after {
    content: "";
    position: absolute;
    inset-block: 0;
    inset-inline-start: 0;
    inline-size: 45%;
    pointer-events: none;

    /* Blanco a la ida y a la vuelta, con el filo suave: una banda de borde duro
       se lee como una raya pintada, no como luz. Al 38 % se ve sobre los
       rellenos de color y no llega a lavar el texto que hay debajo. */
    background: linear-gradient(
        100deg,
        transparent,
        rgba(255, 255, 255, 0.38),
        transparent);

    /* CUATRO segundos de ciclo: dos de barrido y dos de descanso. Ver el
       `@keyframes`, donde esta explicado por que se reparte asi. */
    animation: scort-reflector 4s linear infinite;
}

/* Quien pidió menos movimiento no ve ningún reflector. Y no es una preferencia
   estética: para alguien con trastorno vestibular, algo que cruza la pantalla
   cada dos segundos —y aquí serían veinte cosas a la vez— produce mareo real.
   Se quita el elemento entero, no solo la animación: parado a mitad de camino
   dejaría una banda blanca fija atravesando el botón. */
@media (prefers-reduced-motion: reduce) {
    .scort-btn::after,
    .scort-audience__option::after { display: none; }
}

/* EL BOTON MAS REPETIDO DEL SITIO.
   «Explorar perfiles», «Ver perfil», «Crear perfil», «Crear cuenta», «Continuar».

   Iba de `--scort-accent` a `--scort-accent-hover`, que es el acento ACLARADO, con
   texto blanco encima. Medido: entre 2,54 y 3,96:1 segun el tema, cuando AA pide 4,5.
   El hover, ademas, era el extremo mas claro de los dos --el peor--.

   Ahora usa el degradado profundo del tema: mismo color de familia, suficientemente
   oscuro para que el blanco se lea. Va de 4,6 a 7,1.

   El brillo no se pierde: sigue en el halo, que esta DETRAS del boton y no debajo del
   texto, asi que puede ser todo lo vivo que quiera. */
.scort-btn--primary {
    background: linear-gradient(135deg, var(--scort-cta-de), var(--scort-cta-a));
    color: var(--scort-accent-contrast);
    box-shadow: var(--shadow-glow);
}

.scort-btn--primary:hover {
    color: var(--scort-accent-contrast);
    box-shadow: var(--shadow-glow-strong);

    /* El hover NO aclara el degradado. Se probo con `brightness(1.08)` y en el tema
       magenta bajaba el blanco de 4,60 a 4,00: por debajo de AA justo al pasar el raton,
       que es cuando alguien esta a punto de pulsar. La senal de hover la dan el halo y el
       levantamiento, que no tocan el contraste. */
    transform: translateY(-1px);
}

/* ===========================================================================
   EL COLOR DE CADA NIVEL, DECLARADO UNA SOLA VEZ

   La referencia del propietario: gris sin verificar, azul verificado, MORADO el
   VIP, VERDE el PRO VIP y DORADO el de arriba. Cada nivel es un color y ese color
   manda en TODO lo suyo —marco, brillo, sello, distintivo y botón—, así que se
   declara aquí en tres variables y nadie más escribe un color de nivel a mano:

     --nivel-rgb    el color en canales, para los rgba() de marcos y brillos
     --nivel-boton  el relleno del botón y del sello (un degradado en el dorado)
     --nivel-tinta  el texto que va ENCIMA de ese relleno

   La tinta está elegida por contraste, no por gusto: blanco sobre gris (7,6:1),
   azul (5,2:1) y morado (5,4:1); oscura sobre verde (6,5:1) y dorado (10:1). En
   blanco, el verde se quedaba en 2,3:1 — ilegible justo en el botón que se paga.

   Se engancha por `data-vip` (la tarjeta del listado y la pequeña de la tira),
   por `data-verificado` (la tarjeta sin membresía) y por las clases `es-vip`,
   `es-pro` y `es-ultra` (la pantalla de planes, la ficha y los distintivos),
   que es lo que genera PlanesPremium en el servidor.
   =========================================================================== */
[data-verificado="si"] {
    --nivel-rgb: 59, 130, 246;
    --nivel-boton: #2563eb;
    --nivel-tinta: #fff;
}

[data-vip="vip"],
.es-vip {
    --nivel-rgb: 168, 85, 247;
    --nivel-boton: #9333ea;
    --nivel-tinta: #fff;
}

[data-vip="pro"],
.es-pro {
    --nivel-rgb: 34, 197, 94;
    --nivel-boton: #22c55e;
    --nivel-tinta: #052e16;
}

[data-vip="ultra"],
.es-ultra {
    --nivel-rgb: 245, 184, 46;
    --nivel-boton: linear-gradient(135deg, #ffe08a, #f5b82e 55%, #e59a12);
    --nivel-tinta: #1a1204;
}

/* EL BOTÓN DE UN PLAN: el de la tarjeta de pago y los de la pantalla de planes. Toma
   el color del nivel que lo contiene; fuera de uno, cae en el dorado de siempre.

   El halo va en la sombra y no en el fondo, para no aclarar el relleno bajo el texto. */
.scort-btn--vip {
    background: var(--nivel-boton, linear-gradient(135deg, #f3c869, var(--scort-vip)));
    border-color: transparent;
    color: var(--nivel-tinta, #14100a);
    font-weight: var(--weight-bold);
    box-shadow: 0 0 20px -6px rgba(var(--nivel-rgb, var(--scort-vip-rgb)), 0.9);
}

.scort-btn--vip:hover {
    color: var(--nivel-tinta, #14100a);
    box-shadow: 0 0 26px -4px rgba(var(--nivel-rgb, var(--scort-vip-rgb)), 1);
    transform: translateY(-1px);
}

.scort-btn--ghost {
    background: transparent;
    border-color: var(--scort-border-strong);
    color: var(--scort-text);
}

.scort-btn--ghost:hover {
    background: var(--scort-surface-hover);
    border-color: var(--scort-accent);
    color: var(--scort-text);
}

.scort-btn--subtle {
    background: var(--scort-surface);
    border-color: var(--scort-border);
    color: var(--scort-text-muted);
}

.scort-btn--subtle:hover {
    background: var(--scort-surface-hover);
    color: var(--scort-text);
}

/* Lo destructivo se ve destructivo.
   El lenguaje de peligro existía en el sistema —`--scort-danger`, los chips de estado, el
   menú de usuario— pero no llegaba a los botones: «Dar de baja mi cuenta», «Suspender»,
   «Aplicar sanción» y «Aplicar consecuencia» se pintaban con la MISMA variante fantasma
   que «Volver». Una acción irreversible y una de cortesía no pueden ser el mismo botón.

   Contorno y no relleno a propósito: el relleno lo tiene la acción PRIMARIA de cada
   pantalla, y sancionar no es la acción primaria de ninguna — es la excepcional. */
.scort-btn--danger {
    background: rgba(255, 77, 94, 0.08);
    border-color: rgba(255, 77, 94, 0.45);
    color: var(--scort-danger);
}

.scort-btn--danger:hover {
    background: rgba(255, 77, 94, 0.16);
    border-color: var(--scort-danger);
    color: var(--scort-danger);
}

.scort-btn--block { width: 100%; }
.scort-btn--lg { padding: 0.9rem 1.9rem; min-height: 52px; font-size: var(--font-size-md); }

/* La variante pequeña baja a 36px, y solo en escritorio.
   Existe para filas densas —una tabla de administración con una acción por fila—, donde
   44px por botón convierte una lista en un acordeón. En un móvil no hay filas densas: hay
   dedos, así que ahí vuelve al suelo común. */
.scort-btn--sm { padding: 0.45rem 0.9rem; min-height: 36px; font-size: var(--font-size-sm); }

@media (max-width: 900px) {
    .scort-btn--sm { min-height: 44px; }
}

/* --- Superficies ------------------------------------------------------- */

.scort-surface {
    background: var(--scort-surface);
    border: 1px solid var(--scort-border);
    border-radius: var(--radius-lg);
}

/* --- Aviso de resultado tras una operación ------------------------------- */

/* Vive AQUÍ y no en la hoja del wallet: es el aviso de CUALQUIER operación —wallet,
   reservas, panel de creador, «Mi cuenta»— y las tres últimas no cargan esa hoja. Sin
   estas reglas, «Cambios guardados» y «La contraseña actual no es correcta» se pintan
   exactamente igual: un párrafo suelto sin caja. */
.scort-notice {
    margin-block: var(--space-4);
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid var(--scort-border);
    background: var(--scort-surface);
    font-size: var(--font-size-sm);
}

.scort-notice--ok {
    border-color: var(--scort-success);
    color: var(--scort-text);
}

/* Un fallo se distingue del éxito por el COLOR y por el texto, no solo por el color:
   quien no distinga rojo de verde tiene que poder leerlo. */
.scort-notice--error {
    border-color: var(--scort-danger);
    color: var(--scort-text);
}

/* --- Valoración ----------------------------------------------------------- */

/* También aquí: el parcial _Rating lo usan la ficha pública, la portada, «mis
   reseñas», la moderación, la reputación del creador y «Mi cuenta», y solo las dos
   primeras cargaban scort-cards.css. Sin `display: inline-flex` la regla global
   «svg { display: block }» apila las estrellas en columna, y sin los dos colores las
   cinco se pintan encendidas: una reseña de 2/5 se lee como 5/5. */
.scort-rating { display: inline-flex; align-items: center; gap: 0.3rem; }

.scort-rating__stars { display: inline-flex; gap: 2px; }

/* Las estrellas APAGADAS tienen que verse.
   Estaban en --scort-border-strong, que es blanco al 14%: prácticamente invisible sobre la
   superficie. El resultado era que 2/5 se leía como «dos estrellas» a secas, sin
   denominador — y dos de cinco y dos de tres son valoraciones muy distintas. Ahora se ven
   las cinco y el color dice cuántas están encendidas. */
/* 0,34 y no 0,28: sobre la superficie oscura da 3,0:1, que es el mínimo que WCAG 1.4.11
   pide a un objeto gráfico que transmite información. Con 0,28 se quedaba en 2,49:1 —la
   dirección era correcta y el valor insuficiente—. */
.scort-rating__star { color: rgba(255, 255, 255, 0.34); }
.scort-rating__star--on { color: var(--scort-warning); }

.scort-rating__value {
    font-size: var(--font-size-sm);
    font-weight: var(--weight-semibold);
    color: var(--scort-text);
}

/* --- Aviso que bloquea una acción ---------------------------------------- */

/* «Saldo insuficiente» y similares. Vive AQUÍ, en la base, y no en la hoja de la ficha:
   el mismo aviso aparece en la ficha de perfil (que carga scort-profile.css) y en la
   pantalla de reserva (que NO la carga). Estaba definido solo allí, así que en la pantalla
   de reserva era texto suelto sin ningún estilo — y el modificador `--warn`, que es lo que
   debía darle el color de aviso, no existía en ninguna hoja: el mensaje que impide
   completar la operación se pintaba MÁS apagado que el texto normal. */
.scort-hint {
    font-size: var(--font-size-xs);
    color: var(--scort-text-muted);
    text-wrap: pretty;
}

/* El color acompaña; la palabra informa. Quien no distinga el ámbar tiene el texto. */
.scort-hint--warn {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2);
    padding: var(--space-2) var(--space-3);
    border-radius: var(--radius-sm);
    border: 1px solid rgba(255, 176, 32, 0.35);
    background: rgba(255, 176, 32, 0.08);
    font-size: var(--font-size-sm);
    font-weight: var(--weight-medium);
    color: var(--scort-warning);
}

/* --- Estado vacío --------------------------------------------------------- */

/* Una lista vacía tiene que PARECER una lista vacía, no una página que no cargó.
   Estaban resueltos con un `<p class="scort-muted">` suelto: una frase gris flotando en un
   panel por lo demás vacío es indistinguible de un fallo de carga, y quien lo ve no sabe si
   esperar, recargar o irse. Una caja con su borde punteado dice «aquí no hay nada TODAVÍA»,
   que es una información distinta.

   Sin ilustración: un dibujo por estado son ocho SVG que mantener y que nadie mira dos
   veces. El icono opcional lo pone quien lo necesite. */
.scort-empty {
    display: grid;
    justify-items: center;
    gap: var(--space-2);
    padding: var(--space-6) var(--space-5);
    border: 1px dashed var(--scort-border-strong);
    border-radius: var(--radius-lg);
    background: rgba(255, 255, 255, 0.015);
    text-align: center;
    text-wrap: pretty;
}

.scort-empty__title {
    font-size: var(--font-size-base);
    font-weight: var(--weight-semibold);
    color: var(--scort-text);
}

.scort-empty__hint {
    max-width: 44ch;
    font-size: var(--font-size-sm);
    color: var(--scort-text-muted);
}

.scort-empty__icon {
    display: grid;
    place-items: center;
    width: 44px;
    height: 44px;
    margin-bottom: var(--space-1);
    border-radius: var(--radius-md);
    border: 1px solid var(--scort-border);
    background: var(--scort-surface);
    color: var(--scort-text-dim);
}

.scort-empty .scort-btn { margin-top: var(--space-2); }

/* --- Distintivo de estado ----------------------------------------------- */

/* Neutro por defecto; el color acompaña y la palabra informa. Vive AQUÍ y no en una hoja
   de página porque lo usan el panel de creador, «Mi cuenta» y la lista de reservas — y esa
   última no carga scort-dashboard.css. Un primitivo compartido en una hoja por página
   acaba, antes o después, pintándose sin estilo en alguna pantalla. */
.scort-state-chip {
    display: inline-flex;
    align-items: center;
    font-size: var(--font-size-xs);
    font-weight: var(--weight-semibold);
    padding: var(--space-1) var(--space-2);
    border-radius: var(--radius-sm);
    border: 1px solid var(--scort-border-strong);
    color: var(--scort-text-muted);
    white-space: nowrap;
}

.scort-state-chip--ok,
.scort-state-chip--excellent,
.scort-state-chip--reliable {
    border-color: var(--scort-success);
    color: var(--scort-success);
}

.scort-state-chip--warn,
.scort-state-chip--caution {
    border-color: var(--scort-warning);
    color: var(--scort-warning);
}

.scort-state-chip--danger,
.scort-state-chip--low,
.scort-state-chip--suspended {
    border-color: var(--scort-danger);
    color: var(--scort-danger);
}

.scort-state-chip--accent {
    border-color: var(--scort-accent);
    color: var(--scort-accent);
}

/* --- Badges ------------------------------------------------------------ */

.scort-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.3rem 0.7rem;
    border-radius: var(--radius-pill);
    border: 1px solid var(--scort-border-strong);

    /* 0.07 y no 0.04: con el 4% el distintivo era prácticamente el fondo con un borde, y
       «TOP» o «PREMIUM» —que existen justo para destacar— se perdían en la tarjeta. Sigue
       siendo discreto; lo que cambia es que ahora se ve que es una pieza. */
    background: rgba(255, 255, 255, 0.07);
    font-size: var(--font-size-xs);
    font-weight: var(--weight-semibold);
    letter-spacing: 0.04em;
    text-transform: uppercase;

    /* Texto normal, no atenuado. Un distintivo con el color de «dato secundario» se
       contradice a sí mismo. */
    color: var(--scort-text);
    line-height: 1;
    white-space: nowrap;
}

.scort-badge--accent {
    background: var(--scort-accent-soft);
    border-color: rgba(var(--scort-accent-rgb), 0.45);
    color: var(--scort-accent);
}

.scort-badge--top {
    background: linear-gradient(135deg, rgba(var(--scort-accent-rgb), 0.22), rgba(var(--scort-accent-rgb), 0.05));
    border-color: rgba(var(--scort-accent-rgb), 0.5);
    color: var(--scort-accent);
}

/* El distintivo del PLAN en la ficha. Mismo color que la tarjeta del listado —lo
   pone su clase `es-*`—: quien vea una cuenta en la portada y luego abra su ficha
   tiene que reconocerlo.

   Iba en `--accent`, el morado del sitio, y encima salía del nivel de verificación
   y no del pago. */
.scort-badge--vip {
    background: var(--nivel-boton, var(--scort-vip));
    border-color: transparent;
    color: var(--nivel-tinta, #14100a);
}

.scort-badge--verified {
    background: rgba(46, 209, 154, 0.12);
    border-color: rgba(46, 209, 154, 0.4);
    color: var(--scort-success);
}

.scort-badge--demo {
    background: rgba(255, 176, 32, 0.12);
    border-color: rgba(255, 176, 32, 0.45);
    color: var(--scort-warning);
}

/* --- Indicador de conexion --------------------------------------------- */

.scort-online-dot {
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--scort-online);
    box-shadow: 0 0 8px rgba(46, 209, 154, 0.8);
    flex: none;
}

/* --- Panel: la caja de sección ------------------------------------------
   Vive AQUI y no en scort-profile.css porque la usan diecinueve vistas de
   siete zonas distintas —wallet, reservas, ofertas, resenas, panel de
   creador— y solo se cargaba con la hoja del perfil. Cualquier pantalla que
   no la enlazara pintaba bloques de texto sin fondo ni borde: parecia una
   pagina sin CSS. Una primitiva compartida va en la hoja que carga siempre. */

/* EL PANEL. La superficie de la que cuelga casi todo el sitio: 43 vistas.

   Lleva marco del color del tema, no un blanco al 7 % que sobre el fondo negro no
   se distingue. Es el nivel 1 de los tres del marco de acento; el 2 lo tiene la
   tarjeta de perfil y el 3 lo que esta elegido. Ver scort-tokens.css. */
.scort-panel {
    background: var(--scort-surface);
    border: 1px solid var(--marco-panel);
    border-radius: var(--radius-lg);
    padding: var(--space-5);
    box-shadow: var(--marco-panel-halo);
}

.scort-panel__head {
    display: flex;
    align-items: baseline;
    gap: var(--space-3);
    margin-bottom: var(--space-4);
    flex-wrap: wrap;
}

.scort-panel__title {
    font-size: var(--font-size-lg);
    font-weight: var(--weight-semibold);
    line-height: var(--line-snug);
}

.scort-panel__hint {
    font-size: var(--font-size-sm);
    color: var(--scort-text-muted);
}

@media (max-width: 640px) {
    .scort-panel { padding: var(--space-4); }
}

/* --- Formularios -------------------------------------------------------- */

.scort-field { margin-bottom: var(--space-4); }

.scort-label,
.scort-field__label {
    display: block;
    margin-bottom: var(--space-2);
    font-size: var(--font-size-sm);
    font-weight: var(--weight-medium);
    color: var(--scort-text-muted);
}

.scort-input,
.scort-select,
.scort-field__input {
    width: 100%;
    padding: 0.75rem 1rem;
    background: var(--scort-bg-deep);
    border: 1px solid var(--scort-border-control);
    border-radius: var(--radius-md);
    color: var(--scort-text);
    font-family: inherit;
    font-size: var(--font-size-base);
    transition:
        border-color var(--duration-base) var(--ease-out),
        box-shadow var(--duration-base) var(--ease-out);
}

.scort-input::placeholder,
.scort-field__input::placeholder { color: var(--scort-text-dim); }

/* El hover del control lo tiñe de acento antes de tocarlo. Es la señal de «esto se
   puede usar» que separa un formulario vivo de una maqueta. */
.scort-input:hover,
.scort-select:hover,
.scort-field__input:hover { border-color: rgba(var(--scort-accent-rgb), 0.40); }

.scort-input:focus,
.scort-select:focus,
.scort-field__input:focus {
    outline: none;
    border-color: var(--scort-accent);
    box-shadow: 0 0 0 3px rgba(var(--scort-accent-rgb), 0.18);
}

.scort-select,
select.scort-field__input {
    appearance: none;
    padding-right: 2.4rem;
    /* Flecha en SVG embebido: sin peticion extra y sin depender de una fuente
       de iconos. El color se fija porque un data-uri no hereda currentColor. */
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%2394a3b8' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 1rem center;
}

.scort-checkbox {
    display: flex;
    align-items: center;
    gap: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--scort-text-muted);
    cursor: pointer;
}

.scort-checkbox input {
    width: 16px;
    height: 16px;
    accent-color: var(--scort-accent);
    cursor: pointer;
}

/* Validacion. El color solo no basta: quien no distingue rojo de gris no
   veria nada, asi que el mensaje siempre lleva texto. */
.scort-validation {
    display: block;
    margin-top: var(--space-2);
    font-size: var(--font-size-sm);
    color: var(--scort-danger);
}

.scort-validation:empty { display: none; }

.scort-alert {
    padding: var(--space-3) var(--space-4);
    border-radius: var(--radius-md);
    border: 1px solid;
    font-size: var(--font-size-sm);
    margin-bottom: var(--space-4);
}

.scort-alert--danger {
    background: rgba(255, 77, 94, 0.1);
    border-color: rgba(255, 77, 94, 0.35);
    color: #ffb3ba;
}

.scort-alert--success {
    background: rgba(46, 209, 154, 0.1);
    border-color: rgba(46, 209, 154, 0.35);
    color: #9fe8cf;
}

.scort-alert--info {
    background: rgba(255, 255, 255, 0.04);
    border-color: var(--scort-border-strong);
    color: var(--scort-text-muted);
}

/* --- Utilidades --------------------------------------------------------- */

.scort-visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

.scort-muted { color: var(--scort-text-muted); }
.scort-dim { color: var(--scort-text-dim); }

/* =========================================================================
   Anchuras de barra: utilidades
   =========================================================================
   Clases y no style="width:N%": la CSP es style-src 'self' 'nonce-…' y un
   nonce NO autoriza atributos style en línea. Se redondea al 5 % más cercano,
   que en una barra de 190 px son 9 px — invisible, y evita 101 clases.

   Viven en la hoja BASE y no en la de tarjetas porque las usan tres zonas
   —perfil, tarjetas y panel de creador— y una pantalla que no enlazara la
   hoja correcta pintaba TODAS las barras llenas: un Trust de 40 se veía como
   un 100. Una barra que miente es peor que no tener barra.
   ========================================================================= */

.scort-w-0 { width: 0%; }
.scort-w-5 { width: 5%; }
.scort-w-10 { width: 10%; }
.scort-w-15 { width: 15%; }
.scort-w-20 { width: 20%; }
.scort-w-25 { width: 25%; }
.scort-w-30 { width: 30%; }
.scort-w-35 { width: 35%; }
.scort-w-40 { width: 40%; }
.scort-w-45 { width: 45%; }
.scort-w-50 { width: 50%; }
.scort-w-55 { width: 55%; }
.scort-w-60 { width: 60%; }
.scort-w-65 { width: 65%; }
.scort-w-70 { width: 70%; }
.scort-w-75 { width: 75%; }
.scort-w-80 { width: 80%; }
.scort-w-85 { width: 85%; }
.scort-w-90 { width: 90%; }
.scort-w-95 { width: 95%; }
.scort-w-100 { width: 100%; }

/* Bloqueo de desplazamiento del fondo mientras hay una capa modal encima —hoy, la
   puerta de edad—.

   Es una CLASE y no `element.style.overflow` porque la política es
   `style-src 'self' 'nonce-…'`, y un nonce NO autoriza atributos style en línea: la
   escritura la bloqueaba el navegador y el fondo seguía desplazándose por detrás de
   la puerta. Debilitar la CSP con 'unsafe-inline' para conseguir un `overflow`
   habría sido cambiar una protección real por una comodidad. */
.scort-scroll-locked {
    overflow: hidden;
}

/* --- El ojo de ver la contraseña --------------------------------------- */

/* El botón y su caja los inyecta scort.js; aquí solo va dónde se colocan. La
   clase --con-ojo la pone el propio script, así que sin JavaScript el campo no
   reserva un hueco para un botón que no existe.

   La referencia de posición es la CAJA, que envuelve solo al input. El campo
   entero no sirve: lleva la etiqueta encima y el mensaje de validación debajo,
   así que su mitad no es la mitad del input —el botón salía 14px alto— y además
   se movería al aparecer un error. */
.scort-password__box {
    position: relative;
    display: block;
}

/* Las dos clases de campo que hay: `scort-input` en las pantallas de acceso y
   `scort-field__input` en «Mi cuenta». Cambiarlas para unificar es otro trabajo;
   aquí basta con cubrir las dos. */
.scort-password--con-ojo .scort-input,
.scort-password--con-ojo .scort-field__input {
    /* Sitio para el botón. Sin esto, una contraseña larga pasa por debajo. */
    padding-right: 3rem;
}

.scort-password__toggle {
    position: absolute;
    right: 6px;

    /* El 50% es del input, porque la caja no contiene nada más. */
    top: 50%;
    transform: translateY(-50%);

    display: grid;
    place-items: center;
    inline-size: 40px;
    block-size: 40px;

    border: 0;
    border-radius: var(--radius-md);
    background: transparent;
    color: var(--scort-text-dim);
    cursor: pointer;

    transition:
        color var(--duration-base) var(--ease-out),
        background-color var(--duration-base) var(--ease-out);
}

.scort-password__toggle:hover { color: var(--scort-text); background: var(--scort-surface-hover); }

.scort-password__toggle:focus-visible {
    outline: none;
    color: var(--scort-accent);
    box-shadow: 0 0 0 2px rgba(var(--scort-accent-rgb), 0.45);
}

/* Cuando está enseñando la contraseña, el ojo va del color del acento: es un
   estado que conviene que se note, porque deja el texto a la vista de quien
   pase por detrás. */
.scort-password__toggle[aria-pressed="true"] { color: var(--scort-accent); }

/* ===========================================================================
   LA FUENTE DE LAS BANDERAS

   Vive AQUÍ y no en la hoja del perfil porque las banderas salen en dos sitios:
   la ficha y las tarjetas del directorio. Estaba declarada en scort-profile.css,
   que solo se carga en la ficha, así que en el directorio la bandera se quedaba
   en dos letras — el mismo defecto de Windows que esta fuente vino a arreglar,
   otra vez y en otro sitio.

   `unicode-range` ES LA PIEZA CLAVE, no un adorno de rendimiento: acota la
   fuente a los 26 indicadores regionales, así que el navegador solo la descarga
   si hay una bandera en la página y NUNCA la usa para ninguna otra letra. Sin
   eso, una fuente de emojis se comería la tipografía del sitio entero — y ahora
   que se carga en todas las pantallas, eso importa el doble.

   78 KB, subconjunto de Twemoji Mozilla. Dibujos de Twemoji, CC-BY 4.0; el
   empaquetado, MIT. Atribución en docs/TERCEROS.md.
   =========================================================================== */
@font-face {
    font-family: "Twemoji Country Flags";
    src: url("../fonts/TwemojiCountryFlags.woff2") format("woff2");
    unicode-range: U+1F1E6-1F1FF;

    /* `swap` y no `block`: mientras llega se ven las dos letras —que es
       exactamente lo que se veía antes— en vez de un hueco en blanco. */
    font-display: swap;
}

/* La clase compartida para cualquier bandera, aquí o en una tarjeta. La fuente
   va DELANTE, pero solo puede ganar en los 26 caracteres de su `unicode-range`;
   detrás queda la del sitio para todo lo demás. */
.scort-bandera {
    font-family: "Twemoji Country Flags", var(--font-sans);
    line-height: 1;
}

/* --------------------------------------------------------------------------
   EL BOTON DE REGISTRARSE, EN ROJO

   Lo pidio el propietario. Es el unico boton de su pantalla, no compite con
   nada, y el rojo lo separa del morado que el resto del sitio usa para «siguiente
   paso»: aqui no hay siguiente paso, aqui se termina el alta.

   NO reutiliza el rojo de «contratar servicio» de la ficha ni ningun token de
   peligro: son cosas distintas y el dia que una cambie de tono la otra no tiene
   por que seguirla. Aqui hay un rojo y esta escrito una vez.

   CONTRASTE: blanco sobre #dc2626 da 4,9:1, por encima del 4,5 que pide AA para
   texto normal. El hover NO aclara el degradado —eso bajaria el contraste justo
   cuando alguien esta a punto de pulsar—: la senal la dan el halo y el
   levantamiento, igual que en el boton primario.
   -------------------------------------------------------------------------- */
.scort-btn--registro {
    background: linear-gradient(135deg, #ef4444, #b91c1c);
    color: #fff;
    border-color: transparent;
    box-shadow: 0 8px 24px -8px rgb(220 38 38 / 65%);
}

.scort-btn--registro:hover {
    color: #fff;
    box-shadow: 0 12px 30px -8px rgb(220 38 38 / 85%);
    transform: translateY(-1px);
}

@media (prefers-reduced-motion: reduce) {
    .scort-btn--registro:hover { transform: none; }
}
