:root {
    --pp-accent: #1296E8;
    --pp-accent-600: #0f7fc7;
    --pp-ink: #0F172A;
    --pp-muted: #64748B;
    --pp-bg: #F7F9FC;
    --pp-border: #E2E8F0;
    /* Superficies del formulario. Van tokenizadas porque un tema oscuro TIENE que poder cambiarlas y no
       todas se alcanzan desde el CSS del evento: la lista que abre un desplegable vive en la capa superior
       del navegador y solo llega por herencia. El valor por omisión es el claro de siempre. */
    --pp-surface: #fff;
    --pp-surface-sunken: #F8FAFC;
    --pp-success: #10B981;
    --pp-danger: #DC2626;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--pp-font, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif);
    background: var(--pp-bg);
    color: var(--pp-ink);
}

/* Imagen de cabecera (hero) del formulario de inscripción: full-width dentro del contenedor, responsive. */
.hero {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 14px;
    margin-bottom: 14px;
}

/* El FocusOnNavigate enfoca el <h1> tras navegar; se oculta ese anillo de foco solo en elementos
   enfocados por programa (headings / tabindex=-1). No afecta el foco de teclado en botones/inputs. */
h1:focus, h2:focus, h3:focus,
[tabindex="-1"]:focus, [tabindex="-1"]:focus-visible {
    outline: none;
    box-shadow: none;
}

/* Opciones tipo radio (campos de selección Sí/No). */
.opciones { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 4px; }
.opciones .radio { display: inline-flex; align-items: center; gap: 6px; font-weight: normal; cursor: pointer; }
.opciones .radio input { margin: 0; }

.portal-shell { min-height: 100dvh; display: flex; flex-direction: column; }
.portal-header {
    background: var(--pp-ink); color: #fff; padding: 14px 18px;
    font-weight: 800; letter-spacing: .3px;
}
.portal-brand { font-size: 1.05rem; }
.portal-main { flex: 1; width: 100%; max-width: 640px; margin: 0 auto; padding: 18px; }
.portal-footer { text-align: center; color: var(--pp-muted); font-size: .8rem; padding: 18px; }

.card { background: var(--pp-surface); border: 1px solid var(--pp-border); border-radius: 16px; padding: 20px; margin-bottom: 16px; box-shadow: 0 1px 2px rgba(15,23,42,.04); }
h1 { font-size: 1.4rem; margin: 0 0 4px; }
h2 { font-size: 1.1rem; margin: 0 0 10px; }
.muted { color: var(--pp-muted); font-size: .9rem; }

label.field { display: block; margin-bottom: 14px; }
label.field > span { display: block; font-size: .85rem; font-weight: 600; margin-bottom: 4px; }
.campo-error { display: block; margin-top: 6px; color: var(--pp-danger); font-size: .82rem; font-weight: 500; }
/* Bloque de datos de salud: se separa visualmente porque tambien se separa legalmente (consentimiento
   expreso y aparte). El borde y el fondo le dicen a la persona «esto es otra cosa, y es opcional». */
.bloque-sensible { border: 1px solid var(--pp-border); border-radius: 12px; padding: 14px 14px 2px; margin: 0 0 14px; background: var(--pp-surface-sunken); }
.bloque-sensible > legend { padding: 0 6px; font-size: .85rem; font-weight: 700; color: var(--pp-ink); }
.nota-sensible { margin: 0 0 12px; font-size: .82rem; line-height: 1.5; color: var(--pp-muted); }
/* La autorizacion de los datos de salud va en su propia caja dentro del bloque. Antes era una casilla
   desnuda debajo de dos interruptores: ni se leia como parte del mismo grupo ni se veia, porque una
   casilla sin estilo la dibuja el sistema. Es un interruptor como los de arriba —mismo elemento y misma
   semantica— dentro de un recuadro que la separa de las preferencias sin sacarla del bloque. */
.pp-autoriza { margin: 2px 0 14px; padding: 12px 13px; border: 1px solid var(--pp-border); border-radius: 10px;
    /* Se apoya sobre el fondo del bloque, no lo repite: mezclar la tinta da un escalon de profundidad
       que funciona igual en un tema claro (tinta oscura) que en uno oscuro (tinta clara). */
    background: color-mix(in srgb, var(--pp-ink) 5%, transparent); }
.pp-autoriza .campo-error { display: block; margin-top: 8px; }

.input, select.input { width: 100%; padding: 11px 12px; border: 1px solid var(--pp-border); border-radius: 10px; font-size: 1rem; background: var(--pp-surface); }
.input:focus, select.input:focus { outline: 2px solid var(--pp-accent); border-color: var(--pp-accent); }

.btn { display: inline-block; width: 100%; padding: 12px 16px; border: 0; border-radius: 10px; font-size: 1rem; font-weight: 700; cursor: pointer; text-align: center; }
.btn-primary { background: var(--pp-accent); color: var(--pp-on-accent, #fff); }
.btn-primary:hover { background: var(--pp-accent-600); }
.btn-ghost { background: transparent; color: var(--pp-muted); width: auto; padding: 8px 0; text-decoration: none; }
/* «¿No eres tú? Cerrar sesión», bajo el saludo del portal de confirmación. Discreto: es una salida, no una
   acción del flujo. El área táctil se agranda con padding sin cambiar cómo se ve. */
.saludo-salir { margin: 0 0 8px; font-size: .875rem; color: var(--pp-muted); }
.link-salir {
    display: inline-flex; align-items: center; gap: 4px; padding: 10px 2px; margin: -10px 0;
    color: var(--pp-ink); font-weight: 600;
    /* Texto oscuro + subrayado del color del evento: el color de marca puede no dar 4.5:1 sobre blanco. */
    text-decoration: underline; text-decoration-color: var(--pp-accent); text-decoration-thickness: 2px; text-underline-offset: 3px;
}
.link-salir:hover { color: var(--pp-accent-600); }
.link-salir:focus-visible { outline: 2px solid var(--pp-accent); outline-offset: 2px; border-radius: 4px; }
.link-salir svg { flex: none; }

.alert { border-radius: 10px; padding: 10px 12px; font-size: .9rem; margin-bottom: 14px; }
.alert-error { background: #fef2f2; border: 1px solid #fecaca; color: var(--pp-danger); }
.alert-ok { background: #ecfdf5; border: 1px solid #a7f3d0; color: #047857; }
.alert-info { background: #eff6ff; border: 1px solid #bfdbfe; color: #1e40af; }

.persona { border: 1px solid var(--pp-border); border-radius: 12px; padding: 12px; margin-bottom: 10px; }
.persona-nombre { font-weight: 700; }
.persona-sub { color: var(--pp-muted); font-size: .85rem; }
.row-check { display: flex; align-items: center; gap: 8px; margin: 8px 0; }
/* Variante para etiquetas de varias líneas (consentimientos): la casilla se alinea con la PRIMERA línea;
   centrada quedaba flotando a media altura del párrafo. */
.row-check-top { align-items: flex-start; }
.row-check-top input[type=checkbox] { margin-top: 2px; }
/* Los textos legales de consentimiento vienen con párrafos: respetarlos (sin esto, el span colapsa los saltos). */
.row-check-top > span { white-space: pre-line; }
/* Declaración de consentimiento larga: completa y legible, pero en una caja desplazable que no domina la
   pantalla. El degradado inferior insinúa que hay más texto. La casilla va aparte, debajo. */
.consent-box {
    max-height: 9.5rem; overflow-y: auto; margin: 2px 0 10px; padding: 10px 12px;
    border: 1px solid var(--pp-border); border-radius: 10px;
    font-size: .8rem; line-height: 1.5; color: var(--pp-ink);
    white-space: pre-line; background: color-mix(in srgb, var(--pp-border) 12%, transparent);
    scrollbar-width: thin;
}
.consent-box:focus-visible { outline: 2px solid var(--pp-accent); outline-offset: 1px; }
/* INTERRUPTOR. La casilla nativa sigue siendo una casilla —mismo elemento, misma semántica, el espacio
   la alterna igual—, solo que se dibuja como interruptor: en una pantalla donde lo que se marca es «¿viene
   esta persona?», un interruptor dice mejor «encendido / apagado» que un tick.
   Solo afecta a .row-check, que existe únicamente en la confirmación; el formulario público de inscripción
   usa .field.checkbox y no se toca. */
.row-check input[type=checkbox] {
    appearance: none;
    -webkit-appearance: none;
    flex-shrink: 0;
    width: 46px;
    height: 27px;
    margin: 0;
    border: 0;
    border-radius: 999px;
    background: #CBD1D4;
    position: relative;
    cursor: pointer;
    transition: background .16s ease;
}

.row-check input[type=checkbox]::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 21px;
    height: 21px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 3px rgba(15, 23, 42, .3);
    transition: transform .16s ease;
}

.row-check input[type=checkbox]:checked { background: var(--pp-accent); }
.row-check input[type=checkbox]:checked::after { transform: translateX(19px); }

/* El foco de teclado tiene que verse: es la única forma de usar esto sin ratón. */
.row-check input[type=checkbox]:focus-visible {
    outline: 2px solid var(--pp-accent);
    outline-offset: 3px;
}

/* Un desplegable deshabilitado debe PARECER deshabilitado, no roto. */
.input:disabled, select.input:disabled {
    background: #F1F3F4;
    color: #8A9094;
    cursor: not-allowed;
}

.chip { display: inline-block; background: #eff6ff; color: var(--pp-accent); border-radius: 999px; padding: 2px 10px; font-size: .8rem; font-weight: 600; }

/* Columna de referencia de la confirmación (quién eres, tu fecha, tu QR). En móvil NO existe: sus tarjetas
   se comportan como hijas directas de .portal-main, así que el orden y el aspecto quedan igual que si el
   contenedor no estuviera. Solo cobra forma en escritorio, abajo. */
.pp-columna-lateral { display: contents; }

/* ============================================================================
   ESCRITORIO DE LA PANTALLA DE CONFIRMACIÓN (dos columnas, desde 1100px)

   En una columna de 640px sobre una pantalla de 1440 el portal parece una app
   de teléfono estirada. Acá se parte en dos:

     izquierda  quién eres, tu fecha, el QR y las acciones secundarias
     derecha    la tarea: a quién confirmas

   Aplica SOLO a /e/{slug}/confirmar. El gancho es el campo oculto que Blazor
   le pone al EditForm con FormName="confirmar": `.portal-main` lo comparten
   también Inscribir y Gracias, y el formulario de inscripción está EN VIVO con
   clientes — convertirlo en dos columnas sin que nadie lo pida sería romperlo.

   No hace falta envolver nada en el .razor porque ese <form> es hijo DIRECTO de
   .portal-main: se le fija la columna 2 y todo lo demás cae solo en la 1. Las
   tarjetas que viven DENTRO del form no son ítems de esta grilla.

   Si el evento no tiene fecha asignada no se renderiza el form, el :has() no
   engancha y la pantalla se queda en una columna. Degrada sola. */
@media (min-width: 1100px) {
    .portal-main:has(> form input[name="_handler"][value="confirmar"]) {
        max-width: 1320px;
        padding: 28px 24px 10px;
        display: grid;
        grid-template-columns: minmax(0, 440px) minmax(0, 1fr);
        column-gap: 24px;
        /* row-gap en 0 a propósito: las dos columnas abarcan muchas filas y, con separación entre filas,
           cada fila vacía sumaría un hueco. El aire vertical lo pone el margin-bottom de cada tarjeta. */
        row-gap: 0;
        align-items: start;
        /* .portal-main es flex:1 dentro de .portal-shell y recibe todo el alto de la ventana. Sin esto, la
           grilla reparte ese sobrante entre las filas y las tarjetas se estiran. */
        align-content: start;
    }

    /* Las dos columnas abarcan las mismas filas. Así la lateral tiene RECORRIDO para quedarse fija: si
       ocupara solo su fila, position:sticky no tendría dónde desplazarse y la columna izquierda quedaría
       vacía apenas se baja un poco — que es justo como se veía antes. */
    .portal-main > .pp-columna-lateral {
        display: block;
        grid-column: 1;
        grid-row: 1 / span 20;
        align-self: start;
        position: sticky;
        top: 20px;
    }

    .portal-main > form:has(input[name="_handler"][value="confirmar"]) {
        grid-column: 2;
        grid-row: 1 / span 20;
    }

    /* «¿Necesitas otra fecha?» y «Mis datos» son cosas que se HACEN, como el formulario: van a su lado. */
    .portal-main:has(> form input[name="_handler"][value="confirmar"]) > .card:has(h2) {
        grid-column: 2;
    }

    /* Los avisos cruzan las dos columnas arriba de todo. Van primeros en el marcado, así que el acomodo
       automático los deja en la fila 1 sin tener que fijarla a mano. */
    .portal-main:has(> form input[name="_handler"][value="confirmar"]) > .alert {
        grid-column: 1 / -1;
    }

    /* Grupo familiar de a dos. Con cuatro integrantes, uno debajo de otro, la tarjeta se hacía larguísima. */
    .portal-main > form .card:has(.persona:nth-of-type(2)) {
        display: grid;
        grid-template-columns: 1fr 1fr;
        column-gap: 14px;
        row-gap: 12px;
    }

    .portal-main > form .card:has(.persona:nth-of-type(2)) > h2,
    .portal-main > form .card:has(.persona:nth-of-type(2)) > p {
        grid-column: 1 / -1;
        margin-bottom: 0;
    }

    .portal-main > form .card:has(.persona:nth-of-type(2)) > .persona {
        margin-bottom: 0;
    }

    /* Una persona sola en su tarjeta: asistencia a la izquierda, alimentación a la derecha, en vez de dejar
       medio ancho vacío. Aplica al titular y también al grupo familiar cuando trae UN solo acompañante.
       El nombre —y el parentesco, que solo traen los acompañantes— cruzan las dos columnas. */
    .portal-main > form .card:not(:has(.persona:nth-of-type(2))) .persona {
        display: grid;
        grid-template-columns: auto minmax(0, 340px);
        column-gap: 28px;
        align-items: end;
    }

    .portal-main > form .card:not(:has(.persona:nth-of-type(2))) .persona > .persona-nombre,
    .portal-main > form .card:not(:has(.persona:nth-of-type(2))) .persona > .persona-sub {
        grid-column: 1 / -1;
        margin-bottom: 4px;
    }

    .portal-main > form .card:not(:has(.persona:nth-of-type(2))) .persona > .row-check {
        margin-bottom: 0;
    }

    /* Un desplegable que dice «Normal» no necesita 600px, y un párrafo a todo el ancho cansa de leer. */
    .portal-main > form .input,
    .portal-main > form select.input {
        max-width: 460px;
    }

    .portal-main > form .card p,
    .portal-main > form .card .row-check span {
        max-width: 68ch;
    }

    /* El botón que cierra la tarea tampoco necesita 700px de ancho. */
    .portal-main > form .card:has(button.btn-primary:only-child) .btn {
        max-width: 420px;
        margin-inline: auto;
    }
}

/* Dos campos lado a lado (correo y su repetición). Debajo de 640px se apilan solos: un correo escrito en
   media pantalla de teléfono es justamente donde se cometen los errores de tipeo que esto quiere evitar. */
.pp-dos-columnas {
    display: grid;
    grid-template-columns: 1fr;
    gap: 0 16px;
}

@media (min-width: 640px) {
    .pp-dos-columnas { grid-template-columns: 1fr 1fr; }
}

/* ===== Avisos flotantes (toasts) =====
   portal.js ELEVA los .alert de página a este contenedor fijo (arriba y al centro): el mensaje se ve
   aunque el usuario esté lejos del punto del formulario que lo generó. Los .alert-fijo no se elevan
   (estado contextual que debe quedarse donde está). Sin JavaScript nada de esto corre y los .alert
   quedan inline como siempre. */
#pp-avisos { position: fixed; top: 14px; left: 50%; transform: translateX(-50%); z-index: 1000;
    width: min(560px, calc(100vw - 32px)); display: flex; flex-direction: column; gap: 8px; }
#pp-avisos .alert { margin: 0; display: flex; align-items: flex-start; gap: 10px;
    box-shadow: 0 10px 30px rgba(22, 35, 62, .22); border-left-width: 5px;
    animation: pp-aviso-entra .25s ease-out; }
#pp-avisos .pp-aviso-texto { flex: 1; }
.pp-aviso-cerrar { background: none; border: 0; font-size: 1.25rem; line-height: 1; cursor: pointer;
    color: inherit; opacity: .55; padding: 0 2px; }
.pp-aviso-cerrar:hover { opacity: 1; }
@keyframes pp-aviso-entra { from { opacity: 0; transform: translateY(-10px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { #pp-avisos .alert { animation: none; } }

/* Texto de apoyo del evento (Markdown del cliente): condiciones y links de ayuda, dentro de la tarjeta del colaborador. */
.pp-apoyo-caja {
    margin-top: 14px; padding: 14px 6px 0 0; border-top: 1px solid var(--pp-border);
    max-height: 380px; overflow-y: auto; overscroll-behavior: contain;
    scrollbar-width: thin; scrollbar-color: var(--pp-accent) transparent;   /* Firefox */
}
.pp-apoyo-caja::-webkit-scrollbar { width: 8px; }
.pp-apoyo-caja::-webkit-scrollbar-track { background: transparent; }
.pp-apoyo-caja::-webkit-scrollbar-thumb { background: var(--pp-accent); border-radius: 999px; border: 2px solid #fff; }
.pp-apoyo-caja:focus-visible { outline: 2px solid var(--pp-accent); outline-offset: 2px; border-radius: 8px; }
.pp-apoyo { line-height: 1.55; font-size: .95rem; }
.pp-apoyo > :first-child { margin-top: 0; }
.pp-apoyo > :last-child { margin-bottom: 0; }
.pp-apoyo ul, .pp-apoyo ol { padding-left: 1.25rem; }
.pp-apoyo li + li { margin-top: .4rem; }
.pp-apoyo a { color: inherit; font-weight: 600; text-decoration: underline; text-decoration-color: var(--pp-accent); text-decoration-thickness: 2px; text-underline-offset: 3px; }
.pp-apoyo a:focus-visible { outline: 2px solid var(--pp-accent); outline-offset: 2px; border-radius: 4px; }
/* Un enlace en NEGRITA y solo en su párrafo —**[texto](url)**— se dibuja como botón, centrado y separado del texto.
   Es explícito a propósito: un enlace común dentro de una frase («Debes ingresar a [Mi Portal](…)») sigue siendo texto. */
.pp-apoyo p:has(> strong:only-child > a:only-child) { text-align: center; margin: 22px 0 8px; }
.pp-apoyo p:has(> strong:only-child > a:only-child) a {
    display: inline-block; padding: 12px 24px; border-radius: 999px; text-decoration: none; font-weight: 700;
    background: var(--pp-accent); color: var(--pp-on-accent, #fff);
}
.pp-apoyo p:has(> strong:only-child > a:only-child) a:hover { background: var(--pp-accent-600); }

/* Escritorio: la tarjeta del colaborador (con el texto) toma el alto de la columna del formulario y solo el texto scrollea. */
@media (min-width: 1100px) {
    .portal-main:has(.pp-apoyo-caja) > .pp-columna-lateral { align-self: stretch; position: static; display: flex; flex-direction: column; }
    .portal-main:has(.pp-apoyo-caja) > .pp-columna-lateral > .card:has(.pp-apoyo-caja) { flex: 1 1 0; min-height: 0; display: flex; flex-direction: column; }
    .portal-main:has(.pp-apoyo-caja) > .pp-columna-lateral > .card:has(.pp-apoyo-caja) > img { align-self: flex-start; }
    .portal-main:has(.pp-apoyo-caja) > .pp-columna-lateral .pp-apoyo-caja { flex: 1 1 0; min-height: 160px; max-height: none; }
}

/* ============================================================================
   Selector desplegable con estilo (TODOS los eventos). «appearance: base-select» deja dar estilo a la lista que se abre
   (Chrome/Edge 135+). Donde no existe —Safari, Firefox— se ignora el bloque entero y queda el desplegable nativo, que
   sigue funcionando igual: es una mejora, no un requisito. Los colores salen de --pp-accent, así que cada evento y cada
   empresa lo ve con su marca.
   ========================================================================= */
@supports (appearance: base-select) {
    select.input,
    select.input::picker(select) { appearance: base-select; }

    select.input { display: flex; align-items: center; justify-content: space-between; gap: 8px; cursor: pointer; }
    select.input::picker-icon { color: var(--pp-accent); transition: rotate .18s ease; }
    select.input:open::picker-icon { rotate: 180deg; }

    /* La lista */
    select.input::picker(select) {
        box-sizing: border-box;
        margin-top: 6px;
        padding: 6px;
        background: var(--pp-surface);
        border: 1px solid var(--pp-border);
        border-radius: 14px;
        box-shadow: 0 14px 34px rgba(15, 23, 42, .16);
    }

    /* Cada opción */
    select.input option {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 11px 12px;
        border-radius: 10px;
        font: inherit;
        color: var(--pp-ink);
        cursor: pointer;
    }
    select.input option::checkmark { order: 2; margin-left: auto; color: var(--pp-accent); }
    select.input option:hover,
    select.input option:focus-visible { background: color-mix(in srgb, var(--pp-accent) 12%, var(--pp-surface)); outline: none; }
    select.input option:checked { font-weight: 700; background: color-mix(in srgb, var(--pp-accent) 18%, var(--pp-surface)); }
    select.input option:disabled { color: var(--pp-muted); cursor: default; }
}

/* ===== Sección «Gracias» tras confirmar la asistencia (GENÉRICA, la usan todos los eventos). El color y la
   tipografía salen del tema del evento (--pp-accent / --pp-font): para Walmart queda azul, para Fluor su paleta,
   etc. No poner colores de un cliente aquí (ver CLAUDE.md §9). ===== */
.pp-gracias { text-align: center; max-width: 520px; margin-left: auto; margin-right: auto; }
.pp-gracias-icono {
    width: 72px; height: 72px; margin: 2px auto 12px; border-radius: 50%;
    display: flex; align-items: center; justify-content: center;
    background: color-mix(in srgb, var(--pp-accent) 14%, #fff); color: var(--pp-accent);
}
.pp-gracias-icono svg { width: 40px; height: 40px; }
.pp-gracias-titulo { color: var(--pp-accent); margin: 0 0 6px; }
.pp-gracias-sub { font-size: 1.05rem; margin: 0 0 2px; }
.pp-gracias-fecha { text-transform: capitalize; font-weight: 600; color: var(--pp-ink); margin: 2px 0 14px; }
.pp-gracias-qr {
    display: inline-block; padding: 14px; margin: 4px auto 12px; background: #fff;
    border: 1px solid var(--pp-border); border-radius: 16px; box-shadow: 0 1px 3px rgba(15, 23, 42, .08);
}
.pp-gracias-qr img { display: block; width: 240px; max-width: 70vw; height: auto; }
.pp-gracias-nota { margin: 0 auto 18px; max-width: 420px; }
.pp-gracias-btn { width: auto; }
/* Botón «Descargar QR»: va bajo el QR (pantalla de gracias y tarjeta «Tu QR familiar»). El atributo download
   del <a> fuerza la descarga del PNG que sirve /e/{slug}/qr (mismo origen). Genérico: lo usan todos los eventos. */
.pp-qr-descargar {
    display: flex; width: fit-content; align-items: center; gap: 7px;
    margin: 0 auto 16px; padding: 9px 18px; min-height: 40px;
    font-size: .85rem; font-weight: 600; line-height: 1;
    color: var(--pp-accent); background: var(--pp-surface);
    border: 1.5px solid var(--pp-border); border-radius: 999px;
    text-decoration: none; cursor: pointer; transition: background-color .14s ease, border-color .14s ease;
}
/* El hover tiene que teñir sobre la superficie, sea cual sea. Antes decia var(--pp-surface, #f7f9fc)
   cuando --pp-surface no existia: al definirla con valor #fff —el mismo fondo del boton— el hover dejo
   de verse en todos los portales. Un color-mix siempre se separa del fondo, en claro y en oscuro. */
.pp-qr-descargar:hover { background: color-mix(in srgb, var(--pp-accent) 10%, var(--pp-surface)); border-color: var(--pp-accent); }
.pp-qr-descargar svg { width: 17px; height: 17px; flex: none; }

/* Texto bajo el botón «Ingresar» (condiciones del beneficio) y ayuda del RUT. Los temas de evento pueden reemplazarlos. */
.pp-pie-ingreso { margin-top: 14px; font-size: .82rem; line-height: 1.45; color: var(--pp-muted); }
.pp-pie-ingreso p { margin: 0; }
.ayuda-rut { display: block; margin-top: 4px; }
/* Aviso del acompañante de libre elección: apagado por omisión; lo activa el tema del evento que lo necesita. */
.pp-acomp-libre { display: none; }
.pp-gracias-texto { margin: 4px auto 14px; max-width: 420px; line-height: 1.5; }
.pp-gracias-texto p { margin: 0 0 10px; }
/* Aviso de tratamiento de datos (Markdown seguro): respeta párrafos y negritas de las secciones. Genérico. */
.pp-aviso-datos { font-size: .875rem; line-height: 1.55; }
.pp-aviso-datos p { margin: 0 0 10px; }
.pp-aviso-datos p:last-child { margin-bottom: 0; }
.pp-aviso-datos strong { color: var(--pp-ink); font-weight: 600; }
.pp-aviso-datos ul { margin: 4px 0 10px; padding-left: 20px; }

/* --- Grupo familiar del formulario público -------------------------------------
   El servidor dibuja todas las tarjetas que el evento permite y portal.js deja una
   visible. Sin JavaScript se ven todas, que es un formulario más largo pero entero. */
.pp-grupo { margin: 22px 0 18px; }
.pp-grupo > h2 { margin: 0 0 4px; }
.pp-grupo > .muted { margin: 0 0 14px; }

.pp-acompanante { position: relative; }
.pp-acompanante .persona-nombre { display: flex; align-items: center; justify-content: space-between; gap: 12px; }

.pp-quitar {
    background: none;
    border: 0;
    padding: 4px;
    font: inherit;
    font-size: .82rem;
    font-weight: 400;
    color: var(--pp-muted);
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
}
.pp-quitar:hover { color: var(--pp-danger); }

.pp-agregar {
    display: inline-block;
    width: auto;
    margin-top: 4px;
    padding: 10px 16px;
    border: 1.5px dashed var(--pp-border);
    border-radius: 10px;
    background: transparent;
    color: var(--pp-accent);
    font: inherit;
    font-size: .9rem;
    font-weight: 600;
    cursor: pointer;
}
.pp-agregar:hover { border-style: solid; background: rgba(0, 0, 0, .02); }

.pp-tope { margin: 10px 0 0; font-size: .82rem; }

/* --- Ícono de las pantallas de cierre -------------------------------------------
   Lo usan «cupos agotados» y «plazo vencido». Sin esto el SVG no trae medidas y se
   estira hasta el ancho de la tarjeta en cualquier evento SIN tema propio. El tema
   del cliente puede redefinir tamaño y color. */
.icono-cerrado {
    display: block;
    margin: 4px auto 14px;
    color: var(--pp-accent);
}

.icono-cerrado svg {
    width: 56px;
    height: 56px;
    display: block;
    margin: 0 auto;
}

.eyebrow-cerrado {
    margin: 0 0 4px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--pp-muted);
}

/* --- Icono de la pantalla de registro fallido ------------------------------------
   Mismo hueco y mismo tamano que las pantallas de cierre: las tres dicen «esto no
   siguio» y tienen que parecer de la misma familia. Faltaban por completo, asi que el
   SVG se dibujaba sin medidas y la equis se estiraba hasta el ancho de la tarjeta.

   A diferencia del cierre, que va en el acento del evento, este usa --pp-danger dentro
   de un circulo tenido al 12%: es el mismo tratamiento que .alert-error, asi que el
   color ya esta elegido y verificado en cada tema. El circulo le quita dureza a la
   equis pelada sin disfrazar que algo fallo. */
.icono-error {
    display: grid;
    place-items: center;
    width: 72px;
    height: 72px;
    margin: 4px auto 14px;
    border-radius: 50%;
    color: var(--pp-danger);
    background: color-mix(in srgb, var(--pp-danger) 12%, transparent);
}

.icono-error svg {
    width: 30px;
    height: 30px;
    display: block;
}

.eyebrow-error {
    margin: 0 0 4px;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .1em;
    text-transform: uppercase;
    color: var(--pp-muted);
}

/* --- «Cómo llegar» ---------------------------------------------------------------
   Enlace al mapa en vez de mapa incrustado: ver ConfiguracionPortalEvento.UbicacionEnlaceMapa. */
.pp-ubicacion {
    display: grid;
    gap: 14px;
    align-items: center;
    grid-template-columns: 1fr;
    margin: 0 0 20px;
    padding: 16px;
    border: 1px solid var(--pp-border);
    border-radius: 12px;
    background: rgba(0, 0, 0, .015);
}

@media (min-width: 560px) {
    .pp-ubicacion { grid-template-columns: 1fr auto; }
}

.pp-ubicacion h2 { margin: 0 0 6px; font-size: 1rem; }
.pp-ubicacion p { margin: 0; }
.pp-lugar { font-weight: 600; }

.pp-btn-mapa {
    display: inline-block;
    padding: 12px 20px;
    border: 1.5px solid var(--pp-accent);
    border-radius: 10px;
    color: var(--pp-accent);
    font-weight: 600;
    font-size: .92rem;
    text-decoration: none;
    text-align: center;
    white-space: nowrap;
}
.pp-btn-mapa:hover { background: var(--pp-accent); color: #fff; }

/* ===== Escritorio: la inscripción en dos columnas ==========================================
   Hasta acá el portal era UNA columna a cualquier ancho. En un monitor eso deja una tira angosta
   con dos tercios de pantalla vacíos y obliga a bajar por cosas que caben de sobra una al lado de
   la otra. Desde 1024 px: hero y encabezado a la izquierda, formulario a la derecha.

   Y ojo con el hero: es una imagen de proporción fija, así que ensanchar el contenedor sin moverlo
   lo haría MÁS alto y se comería lo que se gana. Por eso va en una columna, no a todo lo ancho.

   Tres decisiones deliberadas:

   1. Las condiciones van dentro de :where(), que NO suma especificidad. Así esto es un valor por
      defecto de verdad: un tema de cliente que ya resuelva su propio escritorio (hoy el de LoL
      Worlds, evento 1015) sigue mandando con un simple `.portal-main`, sin tener que competir ni
      desactivar nada. Si en vez de :where() se escribe el :has() suelto, este bloque le gana al
      tema del cliente y le cambia la página en vivo.

   2. Solo se activa si hay algo que poner en la columna izquierda (hero o tarjeta de encabezado).
      Un evento sin ninguno de los dos —los de plan gratis suelen ser así— se queda en una columna,
      porque si no el formulario quedaría descolgado a la derecha contra una columna vacía.

   3. `row-gap: 0`: la tarjeta del formulario abarca varias filas y las que quedan vacías en la
      columna izquierda sumarían separación fantasma. La separación la siguen poniendo los
      `margin-bottom` de las tarjetas.
   ========================================================================================= */
@media (min-width: 1024px) {
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])):where(:has(.hero, .card.contenido:not(.pie))) {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, .95fr);
        column-gap: 44px;
        row-gap: 0;
        align-items: start;
        max-width: 1120px;
    }

    /* Columna izquierda: el arte, el texto de contexto y «Cómo llegar» — todo lo que es información
       del evento. El formulario se queda solo con lo que hay que llenar. */
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])) > .hero,
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])) > .card.contenido:not(.pie),
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])) > .pp-ubicacion {
        grid-column: 1;
    }

    /* Columna derecha: el formulario, arrancando arriba del todo y abarcando lo que haga falta. */
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])) > .card:not(.contenido) {
        grid-column: 2;
        grid-row: 1 / span 10;
    }

    /* El pie cruza las dos columnas. */
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])) > .card.contenido.pie {
        grid-column: 1 / -1;
    }
}

/* ===== Interruptores (switch) ==============================================================
   Para preguntas de sí/no donde el checkbox cuadrado se lee como «marca todas las que apliquen» y
   acá la respuesta es una sola: ¿vienes con acompañante?, ¿tienes restricción alimentaria?

   La casilla REAL es el interruptor que se ve: `appearance: none` y se le da forma de pista con su
   perilla en ::after. No hay input escondido detrás de un adorno.
   El primer intento sí lo tenía —casilla de 1px con opacity:0 y un span haciendo de pista— y estaba
   mal: un elemento con opacity 0 sale del árbol de accesibilidad, así que el foco llegaba pero el
   lector de pantalla no anunciaba nada. Quien no ve la pantalla no sabía qué estaba tocando.

   Contraste (WCAG 1.4.11, 3:1 para un control que comunica estado):
   - Apagado: la pista usa --pp-switch-off, no --pp-border. El borde decorativo suele andar por 1.4:1
     y acá el borde ES la información; un tema que lo baje deja el control ilegible.
   - Encendido: pista --pp-accent con la perilla en --pp-on-accent. Ese par ya está verificado en cada
     tema porque es el del botón principal, así que la perilla se ve sí o sí. */
:root {
    --pp-switch-off: #7E8899;
}

.pp-switch {
    display: flex;
    align-items: center;
    gap: 12px;
    cursor: pointer;
    margin-bottom: 12px;
}

.pp-switch input[type="checkbox"] {
    appearance: none;
    -webkit-appearance: none;
    flex: 0 0 auto;
    width: 46px;
    height: 27px;
    margin: 0;
    border: 0;
    border-radius: 999px;
    background: var(--pp-switch-off);
    position: relative;
    cursor: pointer;
    transition: background .15s ease;
}

.pp-switch input[type="checkbox"]::after {
    content: "";
    position: absolute;
    top: 3px;
    left: 3px;
    width: 21px;
    height: 21px;
    border-radius: 50%;
    background: #fff;
    transition: transform .15s ease, background .15s ease;
}

.pp-switch input[type="checkbox"]:checked { background: var(--pp-accent); }
.pp-switch input[type="checkbox"]:checked::after {
    transform: translateX(19px);
    background: var(--pp-on-accent, #fff);
}

.pp-switch input[type="checkbox"]:focus-visible {
    outline: 2px solid var(--pp-accent);
    outline-offset: 3px;
}

.pp-switch-texto { line-height: 1.35; }

/* El interruptor dentro de la caja de autorizacion (.pp-autoriza). Vive aca abajo, DESPUES de la regla
   base, y no junto a .pp-autoriza: el orden importa dos veces. Para el navegador, porque una variante
   tiene que poder pisar la base; y para los resguardos de InterruptorAccesibleTests, que leen la PRIMERA
   regla de `.pp-switch input[type=checkbox]` del archivo para comprobar que el control es accesible.
   Puesta antes, la variante se colaba como si fuera la definicion del control. */
.pp-autoriza .pp-switch { margin-bottom: 0; align-items: flex-start; }
.pp-autoriza .pp-switch input[type="checkbox"] { margin-top: 1px; }
.pp-autoriza .pp-switch-texto { font-size: .85rem; }

@media (prefers-reduced-motion: reduce) {
    .pp-switch input[type="checkbox"],
    .pp-switch input[type="checkbox"]::after { transition: none; }
}

/* El atributo `hidden` tiene que ganar SIEMPRE.
   El navegador trae `[hidden] { display: none }`, pero es una regla de especificidad (0,1,0) y
   cualquier regla nuestra con clase + elemento la pisa: `label.field { display: block }` (0,1,1) deja
   visible un elemento que el JavaScript creyó haber ocultado. Pasó con el detalle de las preferencias:
   `el.hidden = true` no hacía nada a la vista y el campo seguía ahí. Es el único !important del
   archivo y se gana el puesto: `hidden` no es una sugerencia de estilo. */
[hidden] { display: none !important; }

/* ===== Bloques que se revelan al marcar ===================================================
   portal.js oculta los .pp-revelado hasta que el checkbox del .pp-condicional está marcado. Sin
   JavaScript quedan visibles: se ve recargado, pero se puede completar igual. */
.pp-condicional { margin-bottom: 4px; }
.pp-revelado { margin-left: 58px; }

/* ===== Grupo declarado por tramos (recuento, sin datos) ==================================== */
.pp-tramo { padding: 2px 0; }
.pp-tramo + .pp-tramo { margin-top: 2px; }

.pp-contador {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
}

.pp-contador span { margin-bottom: 0; }
.pp-contador .input { width: auto; min-width: 88px; }

.pp-nota-tramo {
    margin: -4px 0 10px 58px;
    font-size: .85rem;
}

/* ===== Escritorio: separación entre secciones =============================================
   En una columna angosta el aire entre tarjetas ayuda a separar los temas. Repartido en dos
   columnas el mismo aire se nota de más y estira la página sin aportar, así que se recorta.

   Acotado a la inscripción, igual que el layout: la pantalla de ingreso sigue en una columna y ahí
   el aire sí hace falta. (Sin acotar, LayoutEscritorioTests falla — y tiene razón.) */
@media (min-width: 1024px) {
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])) .card { margin-bottom: 12px; }
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])) .pp-ubicacion { margin-bottom: 12px; }
    .portal-main:where(:has(form input[name="_handler"][value="inscripcion"])) .pp-grupo { margin-top: 14px; }
}
