/* ==========================================================================
   Boda Sayra & Omar — hoja de estilos única.

   Organización:
     1. Tokens de diseño
     2. Reset y base
     3. Composición (contenedores, secciones, rejillas)
     4. Tipografía
     5. Componentes
     6. Utilidades
     7. Accesibilidad y preferencias del usuario
   ========================================================================== */

/* ==========================================================================
   1. TOKENS DE DISEÑO
   ========================================================================== */

:root {
    /* --- Color --- */
    --color-ink: #1a1a1a;          /* Texto principal */
    --color-ink-soft: #5c5750;     /* Texto secundario */
    --color-gold: #b39b78;         /* Acento (contraste AA sobre blanco) */
    --color-gold-deep: #8a7355;    /* Acento para texto pequeño */
    --color-gold-light: #d4c3a8;   /* Acento claro, solo decorativo */
    --color-paper: #ffffff;
    --color-cream: #fbf8f8;        /* Fondo de tarjetas */
    --color-line: #e6ded2;
    --color-dark: #1a1a1a;         /* Fondo de secciones oscuras */
    --color-on-dark: #f4efe9;
    --color-on-dark-soft: #c9c0b6;

    /* Estados */
    --color-error: #a3282f;
    --color-error-bg: #fdf2f2;
    --color-success: #2f6b46;
    --color-success-bg: #f1f8f3;

    /* --- Tipografía ---
       Tres familias con papeles bien separados. Para cambiarle el carácter al
       sitio basta con tocar estas tres líneas y el <link> de Google Fonts del
       HTML; el resto de la hoja va por variables.

         · display → titulares y cifras grandes. Cormorant es elegantísima a
                     tamaño grande, pero tiene la altura de x muy pequeña y el
                     trazo fino: en texto corrido obliga a forzar la vista, y
                     por eso ya no se usa ahí.
         · body    → todo el texto seguido, el formulario y los botones. Lora
                     está dibujada para pantalla (altura de x alta y grosor más
                     parejo) y mantiene el aire de serif clásica.
         · script  → solo los nombres y los remates. Nunca en texto largo. */
    --font-display: 'Cormorant Garamond', Georgia, 'Times New Roman', serif;
    --font-body: 'Lora', Georgia, 'Times New Roman', serif;
    --font-script: 'Great Vibes', 'Segoe Script', cursive;

    /* Las etiquetas en versalitas y los botones piden `--font-ui` en media
       hoja. Ahora también es Lora: a tamaño pequeño y con letterspacing se lee
       mejor que la sans del sistema y no rompe la unidad tipográfica. */
    --font-ui: var(--font-body);

    /* Escala fluida: se adapta al ancho sin saltos bruscos.
       Los mínimos están puestos para que nada baje de 15 px salvo las
       micro-etiquetas: por debajo de ahí el texto empieza a costarle a los
       invitados de más edad, que en una boda son bastantes. */
    --text-xs: clamp(0.8125rem, 0.15vw + 0.78rem, 0.875rem);
    --text-sm: clamp(0.9375rem, 0.25vw + 0.88rem, 1rem);
    --text-base: clamp(1.0625rem, 0.45vw + 0.97rem, 1.1875rem);
    --text-lg: clamp(1.1875rem, 0.7vw + 1.05rem, 1.375rem);
    --text-xl: clamp(1.375rem, 1vw + 1.15rem, 1.625rem);
    --text-script-md: clamp(2.25rem, 4vw + 1rem, 3.25rem);
    --text-script-lg: clamp(2.75rem, 6vw + 1rem, 4.5rem);
    --text-hero: clamp(2.25rem, 6vw + 0.5rem, 4rem);
    --text-counter: clamp(2.25rem, 5vw + 0.75rem, 3.75rem);

    /* --- Espaciado (escala de 4 px) --- */
    --space-2xs: 0.25rem;
    --space-xs: 0.5rem;
    --space-sm: 0.75rem;
    --space-md: 1rem;
    --space-lg: 1.5rem;
    --space-xl: 2rem;
    --space-2xl: 3rem;
    --space-3xl: 4rem;
    --space-4xl: 6rem;

    /* --- Layout --- */

    /* Alto de la barra fija. Es el desfase exacto con el que tiene que llegar
       cada sección al pulsar un enlace del menú (ver `scroll-margin-top`).
       El valor real lo mide el JavaScript al cargar y lo reescribe aquí, así
       que este es solo el punto de partida: la barra en móvil, donde el botón
       de menú (2.75rem) es lo más alto que hay dentro. */
    --header-height: 4.75rem;

    --container-width: 72rem;
    --container-narrow: 46rem;
    --container-pad: clamp(1rem, 4vw, 2rem);
    --section-pad: clamp(1.75rem, 4.5vw, 3.25rem);

    /* --- Otros --- */
    --radius-sm: 6px;
    --radius-md: 10px;
    --radius-pill: 999px;
    --shadow-sm: 0 1px 3px rgb(26 26 26 / 8%);
    --shadow-md: 0 6px 20px rgb(26 26 26 / 10%);
    --shadow-lg: 0 12px 36px rgb(26 26 26 / 14%);
    --transition: 200ms ease;

    /* Imagen del hero. Sustitúyela por una foto de la pareja si lo prefieres:
       basta con cambiar la ruta aquí. Si la nueva tiene el motivo descentrado,
       ajusta también `--hero-focus` (ver `.hero__media`). */
    --hero-image: url('../img/hero-image.jpg');

    /* Punto de la foto que nunca debe recortarse. En hero-image.jpg la pareja
       está en el tercio izquierdo, así que el encuadre se ancla ahí: centrada,
       en móvil vertical el recorte se la comía entera. */
    --hero-focus: 22% 50%;
}

/* ==========================================================================
   2. RESET Y BASE
   ========================================================================== */

*,
*::before,
*::after {
    box-sizing: border-box;
}

* {
    margin: 0;
}

html {
    /* El desplazamiento suave de los enlaces del menú se desactiva más abajo
       para quien prefiere movimiento reducido. */
    scroll-behavior: smooth;
    -webkit-text-size-adjust: 100%;
}

/* Destinos de los enlaces del menú. El desfase va en el destino
   (`scroll-margin-top`) y no en el contenedor (`scroll-padding-top`): así no
   depende de quién sea el elemento que hace scroll, que con `overflow-x` en el
   <body> no siempre es el mismo.

   La medida es justo el alto de la barra, ni un píxel más: el borde superior de
   la sección queda pegado al borde inferior de la barra. Si el desfase se pasa
   —antes eran 5rem fijos, unos 16px de más en escritorio— asoma por debajo una
   franja del final de la sección anterior. */
section[id],
#contenido,
.form__status {
    scroll-margin-top: var(--header-height);
}

/* Lo mismo para lo que recibe el foco con el teclado: al tabular, el navegador
   trae el elemento a la vista y sin esto la barra puede taparlo. Va con
   `:where()` para no añadir especificidad a nada. */
:where(a, button, input, select, textarea, [tabindex]) {
    scroll-margin-top: var(--header-height);
}

body {
    background-color: var(--color-paper);
    color: var(--color-ink);
    font-family: var(--font-body);
    font-size: var(--text-base);
    /* Lora tiene la altura de x alta, así que agradece algo más de aire entre
       líneas del que necesitaba Cormorant. */
    line-height: 1.7;
    min-height: 100vh;
    overflow-x: hidden;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
}

/* Los titulares heredaban la familia del cuerpo. Ahora tienen la suya, con el
   interlineado ceñido y el tracking ligeramente negativo que pide una serif de
   display: a tamaño grande abre demasiado y la palabra se deshilacha. */
h1,
h2,
h3,
h4 {
    font-family: var(--font-display);
    font-weight: 600;
    line-height: 1.15;
    letter-spacing: -0.01em;
    /* Reparte las palabras entre las líneas en lugar de dejar una suelta al
       final, que es lo que más afea un titular a dos líneas en móvil. */
    text-wrap: balance;
    text-rendering: optimizeLegibility;
}

/* Evita la línea final con una sola palabra en los párrafos. */
p {
    text-wrap: pretty;
}

img,
svg,
picture {
    display: block;
    max-width: 100%;
    height: auto;
}

/* El atributo `hidden` debe ganar siempre. Sin esta regla, cualquier clase que
   fije `display` (grid, flex…) lo anula por especificidad y el elemento sigue
   viéndose pese a estar marcado como oculto. */
[hidden] {
    display: none !important;
}

input,
button,
select,
textarea {
    font: inherit;
    color: inherit;
}

button {
    cursor: pointer;
}

a {
    color: var(--color-gold-deep);
    text-underline-offset: 0.2em;
}

a:hover {
    color: var(--color-ink);
}

/* Anillo de foco visible y consistente en todo el sitio. Nunca se elimina
   sin sustituirlo: es la única guía para quien navega con teclado. */
:where(a, button, input, [tabindex]):focus-visible {
    outline: 3px solid var(--color-gold-deep);
    outline-offset: 3px;
    border-radius: var(--radius-sm);
}

/* ==========================================================================
   3. COMPOSICIÓN
   ========================================================================== */

.container {
    width: 100%;
    max-width: var(--container-width);
    margin-inline: auto;
    padding-inline: var(--container-pad);
}

.container--narrow {
    max-width: var(--container-narrow);
}

.section {
    padding-block: var(--section-pad);
}

.section--cream {
    background-color: var(--color-cream);
}

/* Secciones que ocupan el alto completo de la pantalla.
   `svh` usa el alto visible más pequeño, así la sección no «salta» cuando el
   navegador móvil oculta o muestra su barra; `vh` queda como reserva para
   navegadores que aún no entienden la unidad.
   El centrado se hace con `margin-block: auto` en el hijo y no con
   `justify-content`, porque los márgenes automáticos se anulan solos cuando el
   contenido es más alto que la pantalla (móvil en horizontal, tipografía
   grande) y entonces nada queda recortado fuera del área con scroll. */
.section--full {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    min-height: 100svh;
}

.section--full > .container {
    width: 100%;
    margin-block: auto;
}

.section--dark {
    background-color: var(--color-dark);
    color: var(--color-on-dark);
}

.section__header {
    text-align: center;
    margin-bottom: var(--space-2xl);
}

.section__intro {
    max-width: 42rem;
    margin-inline: auto;
    color: var(--color-ink-soft);
}

.section--dark .section__intro {
    color: var(--color-on-dark-soft);
}

/* Rejilla auto-ajustable: pasa de una a dos columnas sin media queries. */
.grid-cards {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: var(--space-xl);
}

/* ==========================================================================
   4. TIPOGRAFÍA
   ========================================================================== */

.script-title {
    font-family: var(--font-script);
    font-size: var(--text-script-lg);
    font-weight: 400;
    line-height: 1.2;
    color: var(--color-gold-deep);
    /* La fuente caligráfica tiene descendentes largos que se recortarían. */
    padding-bottom: 0.15em;
}

.script-title--sm {
    font-size: var(--text-script-md);
}

.section--dark .script-title {
    color: var(--color-on-dark);
}

.eyebrow {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    /* En versalitas la serif necesita algo de peso para no verse desvaída, y
       menos tracking que una sans: sus remates ya separan las letras. */
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-gold-deep);
}

.section--dark .eyebrow {
    color: var(--color-gold-light);
}

.lead {
    font-size: var(--text-lg);
}

.text-muted {
    color: var(--color-ink-soft);
}

/* Filete decorativo entre bloques. */
.rule {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-sm);
    margin-block: var(--space-lg);
    color: var(--color-gold);
}

.rule::before,
.rule::after {
    content: '';
    height: 1px;
    width: min(5rem, 18vw);
    background-color: currentcolor;
}

.rule__dot {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background-color: currentcolor;
}

/* ==========================================================================
   5. COMPONENTES
   ========================================================================== */

/* --- 5.1 Barra de navegación --------------------------------------------- */

.site-header {
    position: fixed;
    inset-block-start: 0;
    inset-inline: 0;
    z-index: 50;
    /* Sobre el hero arranca transparente; al hacer scroll el JS añade
       `.site-header--solid`. */
    background-color: transparent;
    transition: background-color var(--transition), box-shadow var(--transition);
}

.site-header--solid {
    background-color: rgb(26 26 26 / 92%);
    box-shadow: var(--shadow-md);
}

.site-header__bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-md);
    padding-block: var(--space-md);
}

.site-header__brand {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.2em;
    text-transform: uppercase;
    color: var(--color-paper);
    text-decoration: none;
    text-shadow: 0 1px 4px rgb(0 0 0 / 55%);
}

.site-header__brand:hover {
    color: var(--color-gold-light);
}

.nav__list {
    display: flex;
    gap: clamp(var(--space-md), 2.5vw, var(--space-xl));
    list-style: none;
    padding: 0;
}

.nav__link {
    color: var(--color-paper);
    font-size: var(--text-base);
    text-decoration: none;
    text-shadow: 0 1px 4px rgb(0 0 0 / 55%);
    transition: color var(--transition);
}

.nav__link:hover,
.nav__link:focus-visible {
    color: var(--color-gold-light);
}

/* Botón hamburguesa: solo en móvil. */
.nav-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem; /* Objetivo táctil mínimo recomendado. */
    padding: 0;
    background: none;
    border: 0;
    color: var(--color-paper);
    filter: drop-shadow(0 1px 3px rgb(0 0 0 / 55%));
}

.nav-toggle__icon {
    width: 1.75rem;
    height: 1.75rem;
    stroke: currentcolor;
    stroke-width: 1.75;
    fill: none;
}

/* Menú desplegable móvil. */
.nav--mobile {
    background-color: rgb(26 26 26 / 96%);
    border-top: 1px solid rgb(255 255 255 / 12%);
    /* Con siete destinos la lista puede pasar de la altura de la pantalla en un
       móvil apaisado; así los últimos siguen alcanzándose. */
    max-height: calc(100dvh - var(--header-height));
    overflow-y: auto;
    overscroll-behavior: contain;
}

.nav--mobile .nav__list {
    flex-direction: column;
    gap: 0;
    padding-block: var(--space-xs);
}

.nav--mobile .nav__link {
    display: block;
    padding-block: var(--space-sm);
    border-bottom: 1px solid rgb(255 255 255 / 10%);
    text-shadow: none;
}

.nav--mobile .nav__item:last-child .nav__link {
    border-bottom: 0;
}

/* El menú cambia a hamburguesa antes que el resto de la página (60em en vez de
   los 48em habituales de la hoja) porque son siete destinos: en una tablet, con
   los nombres y el logotipo en la misma línea, no caben sin apelotonarse. */
@media (width < 60em) {
    .nav--desktop {
        display: none;
    }
}

@media (width >= 60em) {
    /* Sin el botón de menú la barra encoge, y con ella el desfase de los
       enlaces del menú. Valor de partida: el JavaScript mide el alto real. */
    :root {
        --header-height: 4rem;
    }

    .nav-toggle,
    .nav--mobile {
        display: none;
    }
}

/* --- 5.2 Hero ------------------------------------------------------------ */

.hero {
    position: relative;
    display: grid;
    place-items: center;
    min-height: 100svh; /* `svh` evita el salto por la barra del navegador móvil. */
    padding: var(--space-4xl) var(--container-pad) var(--space-2xl);
    text-align: center;
    color: var(--color-paper);
    overflow: hidden;
}

.hero__media {
    position: absolute;
    inset: 0;
    background-image: var(--hero-image);
    background-size: cover;
    background-position: var(--hero-focus);
    z-index: 0;
}

/* Capa oscura: garantiza el contraste del texto sobre cualquier foto.
   El tono no es negro puro sino un pardo muy oscuro: sobre un atardecer, el
   negro apaga los dorados y deja la foto gris, mientras que este mantiene la
   temperatura. Y el peso está en el centro, donde cae el texto, en vez de
   repartido: la loma inferior de la foto ya es casi negra y oscurecerla más
   solo la convertía en una mancha. */
.hero__media::after {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(
            125% 85% at 50% 52%,
            rgb(26 18 12 / 52%) 0%,
            rgb(26 18 12 / 30%) 50%,
            rgb(26 18 12 / 0%) 100%
        ),
        linear-gradient(
            to bottom,
            rgb(26 18 12 / 50%) 0%,
            rgb(26 18 12 / 18%) 38%,
            rgb(26 18 12 / 30%) 100%
        );
}

.hero__content {
    position: relative;
    z-index: 1;
    max-width: 48rem;
}

/* Móvil en vertical: el único encuadre que da problemas.
   `cover` amplía tanto la foto que la pareja acaba en el centro exacto, justo
   debajo del texto, y los nombres quedaban sobre el vestido —la zona más clara
   de la imagen— en lugar de sobre la loma. Se arregla en el fondo, sin tocar la
   tipografía: se amplía un poco más y se ancla por abajo, con lo que la pareja
   sube al cielo y libera la loma, y el bloque de texto baja a apoyarse en ella,
   que es casi negra y da el mejor contraste de toda la foto.

   Solo en vertical: en horizontal `auto 125%` podría no cubrir el ancho, y
   además no hace falta porque el recorte se parece al de escritorio. */
@media (width < 48em) and (orientation: portrait) {
    .hero {
        align-items: end;
        padding-bottom: var(--space-3xl);
    }

    .hero__media {
        background-size: auto 125%;
        background-position: 18% 100%;
    }
}

/* La cita de apertura es decorativa, no texto de lectura: aquí la cursiva de
   Cormorant luce, y a este tamaño se lee sin problema. */
.hero__quote {
    font-family: var(--font-display);
    font-style: italic;
    font-size: var(--text-xl);
    line-height: 1.4;
    color: var(--color-on-dark);
    margin-bottom: var(--space-xl);
}

.hero__ornament {
    width: min(150px, 40vw);
    margin: 0 auto var(--space-xl);
    color: var(--color-paper);
}

.hero__title {
    font-size: var(--text-hero);
    font-weight: 600;
    line-height: 1.12;
    text-shadow: 0 2px 16px rgb(0 0 0 / 45%);
}

.hero__names {
    display: block;
    font-family: var(--font-script);
    font-size: var(--text-script-lg);
    font-weight: 400;
    line-height: 1.25;
    padding-bottom: 0.1em;
    margin-top: var(--space-sm);
}

.hero__date {
    margin-top: var(--space-xl);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    letter-spacing: 0.22em;
    text-transform: uppercase;
}

/* --- 5.3 Botones --------------------------------------------------------- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    min-height: 2.875rem;
    padding: var(--space-sm) var(--space-xl);
    border: 1px solid transparent;
    border-radius: var(--radius-pill);
    background-color: var(--color-gold-deep);
    color: var(--color-paper);
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
    text-align: center;
    transition: background-color var(--transition), transform var(--transition);
}

.btn:hover:not(:disabled) {
    background-color: var(--color-ink);
    color: var(--color-paper);
    transform: translateY(-1px);
}

.btn:disabled {
    background-color: #b9b3ab;
    color: #f3f1ee;
    cursor: not-allowed;
    transform: none;
}

.btn--outline {
    background-color: transparent;
    border-color: currentcolor;
    color: var(--color-gold-light);
}

.btn--outline:hover:not(:disabled) {
    background-color: var(--color-gold-light);
    color: var(--color-ink);
}

.btn--block {
    display: flex;
    width: 100%;
    padding-block: var(--space-md);
}

.btn__icon {
    width: 1.125rem;
    height: 1.125rem;
    stroke: currentcolor;
    stroke-width: 1.75;
    fill: none;
}

/* --- 5.4 Cuenta regresiva ------------------------------------------------ */

.countdown {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: clamp(var(--space-md), 5vw, var(--space-3xl));
    margin-block: var(--space-2xl);
}

.countdown__unit {
    display: flex;
    flex-direction: column;
    align-items: center;
    min-width: 4rem;
}

.countdown__value {
    font-family: var(--font-display);
    font-size: var(--text-counter);
    font-weight: 600;
    line-height: 1;
    /* Evita que el ancho baile al cambiar los dígitos cada segundo. */
    font-variant-numeric: tabular-nums;
}

.countdown__label {
    margin-top: var(--space-xs);
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    font-weight: 500;
    letter-spacing: 0.16em;
    text-transform: uppercase;
    color: var(--color-on-dark-soft);
}

.countdown__done {
    font-family: var(--font-script);
    font-size: var(--text-script-lg);
}

/* --- 5.5 Tarjetas de lugar ----------------------------------------------- */

.venue-card {
    display: flex;
    flex-direction: column;
    background-color: var(--color-cream);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    overflow: hidden;
    box-shadow: var(--shadow-sm);
    transition: box-shadow var(--transition), transform var(--transition);
}

.venue-card:hover {
    box-shadow: var(--shadow-lg);
    transform: translateY(-2px);
}

.venue-card__image {
    width: 100%;
    height: 20rem;
    object-fit: cover;
}

.venue-card__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    gap: var(--space-md);
    padding: var(--space-xl);
    text-align: center;
}

.venue-card__type {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    letter-spacing: 0.18em;
    text-transform: uppercase;
    color: var(--color-gold-deep);
}

.venue-card__name {
    font-family: var(--font-script);
    font-size: var(--text-script-md);
    font-weight: 400;
    line-height: 1.2;
    padding-bottom: 0.1em;
}

.venue-card__meta {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: var(--space-lg);
    padding-block: var(--space-md);
    border-block: 1px solid var(--color-line);
}

.venue-card__meta-item {
    display: flex;
    align-items: center;
    gap: var(--space-xs);
    text-align: left;
    font-size: var(--text-sm);
}

.venue-card__meta-item svg {
    flex-shrink: 0;
    width: 1.25rem;
    height: 1.25rem;
    stroke: var(--color-gold-deep);
    stroke-width: 1.6;
    fill: none;
}

.venue-card__meta-value {
    font-weight: 600;
    letter-spacing: 0.04em;
}

.venue-card__address {
    color: var(--color-ink-soft);
    font-size: var(--text-sm);
}

.venue-card__cta {
    /* Empuja el botón al pie de la tarjeta para que todas se alineen. */
    margin-top: auto;
    align-self: center;
}

/* --- 5.6 Línea de tiempo (itinerario) ------------------------------------ */

.timeline {
    position: relative;
    list-style: none;
    padding: 0;
    margin-inline: auto;
    max-width: 56rem;
}

/* Riel vertical. */
.timeline::before {
    content: '';
    position: absolute;
    inset-block: 0.75rem;
    inset-inline-start: 1.5rem;
    width: 1px;
    background-color: var(--color-line);
}

.timeline__item {
    position: relative;
    display: grid;
    grid-template-columns: 3rem 1fr;
    align-items: start;
    gap: var(--space-lg);
    padding-bottom: var(--space-2xl);
}

.timeline__item:last-child {
    padding-bottom: 0;
}

.timeline__marker {
    display: grid;
    place-items: center;
    width: 3rem;
    height: 3rem;
    border: 1px solid var(--color-gold);
    border-radius: 50%;
    background-color: var(--color-paper);
    color: var(--color-gold-deep);
}

.timeline__marker svg {
    width: 1.5rem;
    height: 1.5rem;
    stroke: currentcolor;
    stroke-width: 1.5;
    fill: none;
}

.timeline__card {
    background-color: var(--color-cream);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    padding: var(--space-lg);
    box-shadow: var(--shadow-sm);
}

.timeline__time {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.14em;
    color: var(--color-gold-deep);
}

.timeline__title {
    font-family: var(--font-script);
    font-size: var(--text-script-md);
    font-weight: 400;
    line-height: 1.2;
    padding-bottom: 0.08em;
}

.timeline__place {
    color: var(--color-ink-soft);
}

/* A partir de tablet: alternado a dos columnas con el riel centrado. */
@media (width >= 48em) {
    .timeline::before {
        inset-inline-start: 50%;
        transform: translateX(-50%);
    }

    .timeline__item {
        grid-template-columns: 1fr 3rem 1fr;
        gap: var(--space-xl);
        align-items: center;
    }

    .timeline__marker {
        grid-column: 2;
        grid-row: 1;
    }

    .timeline__card {
        grid-column: 1;
        grid-row: 1;
        text-align: right;
    }

    /* Los elementos pares se colocan a la derecha del riel. */
    .timeline__item:nth-child(even) .timeline__card {
        grid-column: 3;
        text-align: left;
    }
}

/* --- 5.7 Código de vestimenta -------------------------------------------- */

.dress-code {
    text-align: center;
}

.dress-code__values {
    font-family: var(--font-display);
    font-size: var(--text-xl);
    margin-bottom: var(--space-xl);
}

.dress-code__icons {
    display: flex;
    justify-content: center;
    gap: var(--space-2xl);
}

.dress-code__icon {
    width: clamp(5rem, 18vw, 8rem);
    height: auto;
}

/* --- Paleta sugerida --- */

.palette__title {
    margin-top: var(--space-2xl);
}

/* Rejilla y no `flex-wrap`: el corte tiene que caer siempre en el mismo sitio.
   En móvil, dos filas de cuatro; en cuanto hay ancho, los ocho en una línea. */
.palette {
    display: grid;
    grid-template-columns: repeat(4, auto);
    justify-content: center;
    gap: var(--space-md);
    margin-top: var(--space-md);
    padding: 0;
    list-style: none;
}

@media (width >= 48em) {
    .palette {
        grid-template-columns: repeat(8, auto);
    }
}

.palette__dot {
    width: clamp(2.75rem, 9vw, 3.5rem);
    aspect-ratio: 1;
    border-radius: 50%;
    /* Dos capas: un filo claro por dentro para que los tonos casi negros no se
       fundan con el de al lado, y la sombra suave del resto de la página. */
    box-shadow:
        inset 0 0 0 1px rgb(255 255 255 / 20%),
        var(--shadow-sm);
}

/* Los ocho tonos. Son contenido, no colores del sistema de diseño, así que
   viven aquí y no entre los tokens: cámbialos sin miedo. */
.palette__dot--negro {
    background-color: #1a1a1a;
}

.palette__dot--marino {
    background-color: #1c2a4a;
}

.palette__dot--petroleo {
    background-color: #163b41;
}

.palette__dot--botella {
    background-color: #1f3d2b;
}

.palette__dot--pizarra {
    background-color: #454c55;
}

.palette__dot--chocolate {
    background-color: #3b2a20;
}

.palette__dot--ciruela {
    background-color: #3d2440;
}

.palette__dot--vino {
    background-color: #5a1a2b;
}

/* --- 5.8 Regalos --------------------------------------------------------- */

.registry {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(15rem, 100%), 1fr));
    gap: var(--space-xl);
    /* Aire respecto al texto de introducción, que sólo aporta el margen
       normal de párrafo y dejaba los iconos muy pegados. */
    margin-top: var(--space-2xl);
    margin-bottom: var(--space-2xl);
}

.registry__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-xs);
    text-align: center;
}

.registry__icon {
    width: 2.5rem;
    height: 2.5rem;
    stroke: var(--color-gold-deep);
    stroke-width: 1.5;
    fill: none;
}

.registry__name {
    font-size: var(--text-lg);
    font-weight: 600;
}

.bank-details {
    max-width: 26rem;
    margin-inline: auto;
    padding-top: var(--space-xl);
    border-top: 1px solid var(--color-line);
    text-align: center;
}

.bank-details__icon {
    margin-inline: auto;
    margin-bottom: var(--space-sm);
}

.bank-details__list {
    display: grid;
    gap: var(--space-xs);
    margin-block: var(--space-md);
    text-align: left;
}

.bank-details__row {
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    gap: var(--space-sm);
    padding-block: var(--space-2xs);
    border-bottom: 1px dashed var(--color-line);
}

.bank-details__label {
    color: var(--color-ink-soft);
    font-size: var(--text-sm);
    letter-spacing: 0.06em;
    text-transform: uppercase;
}

.bank-details__value {
    font-family: var(--font-ui);
    font-weight: 600;
    /* Los números largos (CLABE) no deben desbordar en móvil. */
    overflow-wrap: anywhere;
}

/* --- 5.9 Hospedaje ------------------------------------------------------- */

/* Mismas medidas que .grid-cards para que las tarjetas de hotel se vean como
   las de la ceremonia y la recepción. */
.lodging {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(20rem, 100%), 1fr));
    gap: var(--space-xl);
}

.lodging__item {
    display: flex;
    flex-direction: column;
    background-color: var(--color-paper);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    /* La foto llega hasta el borde, así que el relleno vive en el cuerpo. */
    overflow: hidden;
    text-align: center;
    box-shadow: var(--shadow-sm);
}

.lodging__image {
    width: 100%;
    /* Las fotos de hotel son casi 3:2, así que con esta proporción se ven
       enteras en vez de recortadas por una altura fija. */
    aspect-ratio: 3 / 2;
    height: auto;
    object-fit: cover;
}

.lodging__body {
    display: flex;
    flex-direction: column;
    flex: 1;
    padding: var(--space-xl);
}

.lodging__name {
    font-size: var(--text-lg);
    font-weight: 600;
    margin-bottom: var(--space-2xs);
}

.lodging__detail {
    color: var(--color-ink-soft);
    font-size: var(--text-sm);
    margin-bottom: var(--space-md);
}

.lodging__body .btn {
    /* Empuja el botón al pie de la tarjeta para que todas se alineen. */
    margin-top: auto;
    align-self: center;
}

/* --- 5.10 Galería --------------------------------------------------------- */

/* Mosaico. La geometría la pone la rejilla y no las fotos: cada hueco es un
   cuadrado y la imagen se recorta con `object-fit` para llenarlo, así da igual
   que las fotos vengan en vertical, apaisadas o mezcladas. */
.gallery {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-sm);
    list-style: none;
    padding: 0;
}

.gallery__item {
    aspect-ratio: 1 / 1;
}

/* En pantallas grandes la foto destacada ocupa un bloque de 2×2, que es lo que
   le da al mosaico su ritmo. La rejilla cierra sin huecos cuando el número de
   fotos es 3 (destacada + 2 en la tercera columna) o 6 (esas más una fila
   completa de 3). Con otras cantidades queda un cuadro vacío al final.

   En móvil no se destaca ninguna: a dos columnas, una foto a lo ancho deja
   sobrando un cuadro suelto al final de la rejilla. */
@media (width >= 48em) {
    .gallery {
        grid-template-columns: repeat(3, 1fr);
        gap: var(--space-md);
    }

    .gallery__item--feature {
        grid-column: span 2;
        grid-row: span 2;
    }
}

.gallery__link {
    display: block;
    width: 100%;
    height: 100%;
    /* Recorta el zoom del hover contra las esquinas redondeadas. */
    overflow: hidden;
    border-radius: var(--radius-md);
    background-color: rgb(255 255 255 / 6%);
}

.gallery__image {
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 400ms ease, opacity var(--transition);
}

.gallery__link:hover .gallery__image,
.gallery__link:focus-visible .gallery__image {
    transform: scale(1.06);
    opacity: 0.92;
}

/* --- Ventana ampliada (lightbox) --- */

/* El <dialog> ocupa la ventana entera y se apoya en la capa superior del
   navegador, así que no hace falta z-index ni bloquear el scroll a mano. */
.lightbox {
    width: 100%;
    max-width: 100%;
    height: 100%;
    max-height: 100%;
    margin: 0;
    padding: var(--space-lg);
    border: 0;
    background-color: transparent;
    color: var(--color-on-dark);
    overscroll-behavior: contain;
}

.lightbox[open] {
    display: grid;
    grid-template-columns: 1fr;
    place-content: center;
    justify-items: center;
    gap: var(--space-sm);
}

.lightbox::backdrop {
    background-color: rgb(12 10 8 / 92%);
}

.lightbox__image {
    /* `dvh` para que la barra del navegador móvil no recorte la foto. */
    max-height: 74dvh;
    width: auto;
    max-width: 100%;
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-lg);
}

.lightbox__caption {
    font-size: var(--text-sm);
    text-align: center;
    text-wrap: balance;
}

.lightbox__counter {
    font-family: var(--font-ui);
    font-size: var(--text-xs);
    letter-spacing: 0.16em;
    color: var(--color-gold-light);
}

/* Botones flotantes: mismo tamaño de objetivo táctil que la hamburguesa. */
.lightbox__close,
.lightbox__nav {
    position: fixed;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    padding: 0;
    border: 0;
    border-radius: var(--radius-pill);
    background-color: rgb(255 255 255 / 10%);
    color: var(--color-on-dark);
    transition: background-color var(--transition);
}

.lightbox__close:hover,
.lightbox__nav:hover {
    background-color: rgb(255 255 255 / 22%);
}

.lightbox__close svg,
.lightbox__nav svg {
    width: 1.5rem;
    height: 1.5rem;
    stroke: currentcolor;
    stroke-width: 1.75;
    fill: none;
}

.lightbox__close {
    inset-block-start: var(--space-md);
    inset-inline-end: var(--space-md);
}

.lightbox__nav {
    inset-block-start: 50%;
    translate: 0 -50%;
}

.lightbox__nav--prev {
    inset-inline-start: var(--space-xs);
}

.lightbox__nav--next {
    inset-inline-end: var(--space-xs);
}

@media (width >= 48em) {
    .lightbox__nav--prev {
        inset-inline-start: var(--space-lg);
    }

    .lightbox__nav--next {
        inset-inline-end: var(--space-lg);
    }
}

/* --- 5.11 Formulario RSVP ------------------------------------------------ */

/* Visita sin enlace personal: la invitación no se dirige a nadie en concreto,
   así que la sección de confirmación y sus enlaces del menú desaparecen. La
   clase la pone un script en línea del <head> (ver index.html). */
.sin-invitacion #rsvp,
.sin-invitacion .nav__item--rsvp {
    display: none;
}

/* Esta sección no lleva `.container` dentro, así que el margen lateral lo pone
   ella: sin él la tarjeta llega a los bordes de la pantalla en cualquier móvil
   (mide como mucho 34rem) y el borde redondeado queda pegado al canto. */
.rsvp {
    display: grid;
    place-items: center;
    padding-inline: var(--container-pad);
}

.rsvp__card {
    width: 100%;
    max-width: 34rem;
    padding: clamp(var(--space-lg), 5vw, var(--space-2xl));
    background-color: var(--color-cream);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-md);
    text-align: center;
}

.rsvp__title {
    font-family: var(--font-script);
    font-size: var(--text-script-lg);
    font-weight: 400;
    line-height: 1.1;
    padding-bottom: 0.1em;
    color: var(--color-gold-deep);
}

.rsvp__intro {
    color: var(--color-ink-soft);
    margin-bottom: var(--space-xl);
}

/* Los cuatro estados de la tarjeta: cargando, enlace no válido, formulario y
   respuesta ya registrada. El JavaScript deja visible solo uno. */
.rsvp__state {
    display: block;
}

.rsvp__greeting {
    font-size: var(--text-lg);
    margin-bottom: var(--space-xs);
}

.rsvp__greeting strong {
    font-family: var(--font-script);
    font-size: var(--text-script-md);
    font-weight: 400;
    display: block;
    line-height: 1.2;
    padding-bottom: 0.08em;
    color: var(--color-gold-deep);
}

.form {
    display: grid;
    gap: var(--space-lg);
    text-align: left;
}

.field {
    display: grid;
    gap: var(--space-2xs);
}

.field__label {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.04em;
}

/* Las ayudas son frases que el invitado tiene que leer de verdad (el cupo de su
   invitación, por ejemplo), no una etiqueta decorativa: se quedan en `sm`. El
   tamaño `xs` es solo para las versalitas del contador. */
.field__hint {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    line-height: 1.5;
    color: var(--color-ink-soft);
}

.field__input {
    width: 100%;
    min-height: 3rem;
    padding: var(--space-sm) var(--space-md);
    background-color: var(--color-paper);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    color: var(--color-ink);
    transition: border-color var(--transition), box-shadow var(--transition);
}

.field__input::placeholder {
    color: #9a938a;
}

.field__input:focus-visible {
    outline: none;
    border-color: var(--color-gold-deep);
    box-shadow: 0 0 0 3px rgb(179 155 120 / 30%);
}

.field__input:disabled {
    background-color: #f0ece7;
    color: #8d867e;
    cursor: not-allowed;
}

/* Campo de solo lectura: el dato es importante y debe leerse bien, así que no
   se atenúa como un campo deshabilitado, pero sí se distingue del resto. */
.field__input--locked {
    background-color: #f4efe7;
    border-style: dashed;
    font-weight: 600;
    cursor: default;
}

.field__input--locked:focus-visible {
    box-shadow: none;
}

.field__input[type='number'] {
    text-align: center;
    font-size: var(--text-lg);
    font-variant-numeric: tabular-nums;
}

/* Marca de campo con error, sincronizada con `aria-invalid`. */
.field__input[aria-invalid='true'] {
    border-color: var(--color-error);
}

/* Autocompletado accesible (patrón combobox). */
.combobox {
    position: relative;
}

.combobox__list {
    position: absolute;
    inset-inline: 0;
    top: calc(100% + 4px);
    z-index: 20;
    max-height: 15rem;
    overflow-y: auto;
    margin: 0;
    padding: 0;
    list-style: none;
    background-color: var(--color-paper);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-lg);
}

.combobox__list[hidden] {
    display: none;
}

.combobox__option {
    padding: var(--space-sm) var(--space-md);
    cursor: pointer;
    border-bottom: 1px solid var(--color-line);
}

.combobox__option:last-child {
    border-bottom: 0;
}

.combobox__option:hover,
.combobox__option[aria-selected='true'] {
    background-color: var(--color-gold-deep);
    color: var(--color-paper);
}

.combobox__empty {
    padding: var(--space-sm) var(--space-md);
    color: var(--color-ink-soft);
    font-size: var(--text-sm);
}

/* Grupo de opciones sí/no. */
.choice-group {
    border: 0;
    padding: 0;
    margin: 0;
}

.choice-group__legend {
    font-family: var(--font-ui);
    font-size: var(--text-sm);
    font-weight: 600;
    letter-spacing: 0.04em;
    margin-bottom: var(--space-sm);
    padding: 0;
}

.choice-group__options {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr));
    gap: var(--space-sm);
}

/* La etiqueta completa es el objetivo clicable, no solo el círculo. */
.choice {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-xs);
    min-height: 3rem;
    padding: var(--space-sm) var(--space-md);
    background-color: var(--color-paper);
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: border-color var(--transition), background-color var(--transition);
}

.choice__input {
    width: 1.125rem;
    height: 1.125rem;
    accent-color: var(--color-gold-deep);
    cursor: inherit;
}

.choice:has(.choice__input:checked) {
    border-color: var(--color-gold-deep);
    background-color: #f6f1e9;
}

.choice:has(.choice__input:focus-visible) {
    outline: 3px solid var(--color-gold-deep);
    outline-offset: 2px;
}

.choice:has(.choice__input:disabled) {
    opacity: 0.55;
    cursor: not-allowed;
}

/* Mensaje de resultado del envío. Va fuera del formulario, de ahí el margen
   superior que lo separa del botón de enviar. */
.form__status {
    margin-top: var(--space-lg);
    padding: var(--space-md);
    border-radius: var(--radius-sm);
    border: 1px solid transparent;
    font-size: var(--text-sm);
    text-align: center;
}

/* El foco se lleva aquí tras enviar; sin esto se dibujaría un anillo
   inesperado alrededor del mensaje. */
.form__status:focus {
    outline: none;
}

.form__status--error {
    background-color: var(--color-error-bg);
    border-color: var(--color-error);
    color: var(--color-error);
}

.form__status--success {
    background-color: var(--color-success-bg);
    border-color: var(--color-success);
    color: var(--color-success);
}

/* --- 5.12 Pie ------------------------------------------------------------ */

.site-footer {
    padding-block: var(--space-2xl);
    background-color: var(--color-dark);
    color: var(--color-on-dark-soft);
    text-align: center;
}

.site-footer__names {
    font-family: var(--font-script);
    font-size: var(--text-script-md);
    color: var(--color-on-dark);
    padding-bottom: 0.1em;
}

.site-footer__note {
    font-size: var(--text-sm);
}

/* ==========================================================================
   6. UTILIDADES
   ========================================================================== */

.stack > * + * {
    margin-top: var(--space-md);
}

.text-center {
    text-align: center;
}

.parents {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(min(16rem, 100%), 1fr));
    gap: var(--space-xl);
    margin-block: var(--space-2xl);
    text-align: center;
}

.parents__name {
    font-size: var(--text-lg);
    font-weight: 600;
}

.blessing {
    max-width: var(--container-narrow);
    margin-inline: auto;
    padding-block: var(--space-lg);
    border-block: 1px solid var(--color-line);
    font-style: italic;
}

/* ==========================================================================
   7. ACCESIBILIDAD Y PREFERENCIAS DEL USUARIO
   ========================================================================== */

/* Oculta visualmente sin ocultar a los lectores de pantalla. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
    border: 0;
}

/* Enlace para saltar directo al contenido con el teclado. */
.skip-link {
    position: absolute;
    inset-inline-start: var(--space-md);
    inset-block-start: -100%;
    z-index: 100;
    padding: var(--space-sm) var(--space-md);
    background-color: var(--color-paper);
    color: var(--color-ink);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-md);
    text-decoration: none;
}

.skip-link:focus-visible {
    inset-block-start: var(--space-md);
}

/* Respeta la configuración del sistema de quien prefiere menos animación. */
@media (prefers-reduced-motion: reduce) {
    html {
        scroll-behavior: auto;
    }

    *,
    *::before,
    *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
    }

    .btn:hover:not(:disabled),
    .venue-card:hover,
    .gallery__link:hover .gallery__image,
    .gallery__link:focus-visible .gallery__image {
        transform: none;
    }
}

/* Modo de alto contraste. */
@media (prefers-contrast: more) {
    :root {
        --color-ink-soft: #3a3630;
        --color-line: #8a8378;
    }
}

/* Impresión: la invitación como recordatorio en papel. */
@media print {
    .site-header,
    .nav-toggle,
    .hero__media,
    .rsvp,
    .skip-link,
    .btn {
        display: none !important;
    }

    body {
        color: #000;
        background: #fff;
        font-size: 11pt;
    }

    .section {
        padding-block: 1rem;
        break-inside: avoid;
    }
}
