/*
 * Design tokens extraídos del HTML/CSS real de eventyrforbarn.com (2026-08-19).
 * Todo color/tipografía usado en plantillas debe referenciar una custom property
 * de aquí — nunca un hex/font literal dentro de un .php de plantilla.
 * Ver Idea_y_concepto/01-arquitectura-tecnica.md y 08-estrategia-editorial-y-localizacion.md.
 */

:root {
    --font-heading: 'Dosis', sans-serif;
    --font-body: 'Raleway', sans-serif;
    /* Tipografía "display" juguetona (redondeada, no serif) usada para el
       título del hero de cuento, los h2 de capítulo, la letra capital y el
       "THE END" — sustituye a la antigua Playfair Display serif, que leía
       como cabecera de periódico en vez de cuento infantil. */
    --font-story-display: 'Fredoka', var(--font-heading), sans-serif;

    --color-cream:  #FBE0CB;
    --color-brown:  #9A4F1E;
    --color-sky:    #CFE8F3;
    --color-teal:   #1F5E73;
    --color-mint:   #D9EFD9;
    --color-forest: #2F6B3D;
    --color-gold:   #FFCC00;

    --color-bg: var(--color-cream);
    --color-surface: #FFFFFF;
    --color-text: #313131;
    --color-accent: var(--color-teal);
    --color-accent-warm: var(--color-brown);
    --color-border: var(--color-sky);

    /* Formato "cita" de la plantilla de página (bloque quote de WordPress):
       gris oscuro en cursiva sobre un fondo gris claro, no blanco. */
    --color-quote-bg: #F4F3F1;
    --color-quote-text: #4A4A4A;

    /* Cuarto tono pastel (derivado de --color-gold) para la banda de edad
       11-12 — las otras 3 bandas y la etiqueta de categoría reutilizan
       cream/sky/mint ya definidos arriba. */
    --color-gold-tint: #FFF3CC;
    --color-gold-text: #8A6D00;

    /* Colores de fondo por personaje para los bloques de diálogo del cuento
       (ver DialogueColors::decorate) — mismos 5 tonos reales del logo que ya
       rotan en los h2 de capítulo más abajo, pero muy aclarados y desaturados
       (pastel apagado) para poder leerse en un bloque de texto entero sin
       competir con la lectura. El primer personaje que habla en cada cuento
       se queda con el gris estándar (--color-quote-bg/--color-quote-text) de
       siempre — estos 5 son solo para el segundo personaje en adelante. */
    --color-dialogue-orange-bg:     #F6EBE4;
    --color-dialogue-orange-text:   #9B4108;
    --color-dialogue-orange-border: #E5C0A9;

    --color-dialogue-purple-bg:     #EDE9F1;
    --color-dialogue-purple-text:   #512F74;
    --color-dialogue-purple-border: #C7BAD4;

    --color-dialogue-teal-bg:       #E8F3F3;
    --color-dialogue-teal-text:     #1F8484;
    --color-dialogue-teal-border:   #B4DADA;

    --color-dialogue-green-bg:      #EEF2E9;
    --color-dialogue-green-text:    #5A7B28;
    --color-dialogue-green-border:  #CAD7B7;

    --color-dialogue-pink-bg:       #F5E5E9;
    --color-dialogue-pink-text:     #9A092F;
    --color-dialogue-pink-border:   #E2ACBA;

    /* Paleta muestreada directamente de logo.webp (letras de "FabelTales" +
       tapa del libro de la mascota) — para que los acentos de la interfaz
       sean colores reales de la marca, no tonos inventados aparte. */
    --color-logo-orange: #F47C30;
    --color-logo-purple: #885CB6;
    --color-logo-teal:   #32B2B2;
    --color-logo-green:  #8BBA44;
    --color-logo-pink:   #EE5D83;
    --color-logo-navy:   #263A5A;

    /* Azul noche del hero de cuento — la tapa del libro del logo, no un tono
       inventado aparte. Encaja con el naming "Bedtime Stories" de la
       navegación y da contraste real al blanco/dorado del texto encima. */
    --color-night: var(--color-logo-navy);
    --color-card-age: #8A4FBF;
    /* Color plano (sin degradado) con transparencia para que el patrón de
       estrellas del fondo del sitio (ver body::before) se insinúe a través
       del panel, en vez de un bloque de color totalmente aislado. Mismo RGB
       que --color-logo-navy (38,58,90) — repetido en vez de var() porque
       necesita canal alfa. */
    --color-hero-tint: rgba(38, 58, 90, 0.72);
    /* Línea de separación entre la cabecera y el hero del cuento, ahora que
       se tocan sin hueco — acento propio de FabelTales, no del sitio original. */
    --color-hero-divider: #E8791F;

    --radius: 12px;
    --radius-lg: 22px;
    --max-width: 1000px;
    --max-width-narrow: 780px;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font-body);
    background-color: var(--color-bg);
    color: var(--color-text);
    line-height: 1.6;
    position: relative;
}

/* Fondo del sitio en pseudo-elemento propio (no en background-image de body)
   para poder atenuar la imagen con opacity sin afectar al texto/contenido.
   background-attachment: fixed + background-size: cover = estático, cubre
   toda la pantalla del dispositivo sin repetición ni uniones visibles. */
body::before {
    content: "";
    position: fixed;
    inset: 0;
    z-index: -1;
    background-image: url('/assets/img/site/background.webp');
    background-size: cover;
    background-position: center;
    background-repeat: no-repeat;
    background-attachment: fixed;
    opacity: 0.5;
}

h1, h2, h3, h4 {
    font-family: var(--font-heading);
    font-weight: 200;
    color: var(--color-accent-warm);
    line-height: 1.2;
    margin-top: 2rem;
    margin-bottom: 1rem;
    text-align: center;
}

h1 { font-size: 2.6rem; color: var(--color-text); }
h2 { font-size: 1.8rem; }
h3 { font-size: 1.4rem; }

/* Botón flotante "volver arriba" — oculto hasta hacer scroll (ver
   assets/js/back-to-top.js), esquina inferior derecha en toda la web. */
#back-to-top {
    position: fixed;
    right: 1.5rem;
    bottom: 1.5rem;
    width: 3rem;
    height: 3rem;
    border: none;
    border-radius: 0;
    background: var(--color-logo-navy);
    color: var(--color-surface);
    font-size: 1.4rem;
    line-height: 1;
    cursor: pointer;
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
    opacity: 0;
    visibility: hidden;
    transform: translateY(0.5rem);
    transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
    z-index: 500;
}

#back-to-top.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

#back-to-top:hover { filter: brightness(1.2); }

/* Aviso emergente al marcar/desmarcar un favorito (ver favorite-buttons.js) —
   un único elemento reutilizado y recentrado en cada aparición, no uno nuevo
   por click. */
.favorite-toast {
    position: fixed;
    left: 50%;
    bottom: 1.75rem;
    transform: translate(-50%, 0.5rem);
    z-index: 600;
    background: var(--color-logo-navy);
    color: #FFFFFF;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.9rem;
    padding: 0.65rem 1.25rem;
    border-radius: 999px;
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.25);
    opacity: 0;
    visibility: hidden;
    pointer-events: none;
    transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
}

.favorite-toast.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translate(-50%, 0);
}

a { color: var(--color-accent); }
a:hover { color: var(--color-forest); }

/* Cabecera de una sola banda blanca (logo a la izquierda, menú a la derecha)
   en vez de las dos franjas apiladas del sitio original — más compacta en
   altura, misma funcionalidad. Ver .site-header-top y nav.primary-nav para
   los dos "lados" de esta fila; el desglose mobile (logo + hamburguesa) sigue
   viviendo dentro de .site-header-top, ver media query al final del archivo. */
header.site-header {
    position: relative;
    /* .story-hero es position:relative sin z-index propio — un elemento
       posicionado sin z-index igualmente pinta por encima de contenido no
       posicionado más arriba en el DOM (como este header), tapando el
       desplegable del menú. Un z-index explícito aquí saca a todo el header
       (y sus submenús) a su propio nivel de apilamiento, por encima del hero. */
    z-index: 300;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    background: rgba(255, 255, 255, 0.8);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);
    padding: 0.5rem 1.5rem;
}

header.site-header .site-name {
    display: inline-block;
}

header.site-header .site-logo {
    height: 68px;
    width: auto;
    display: block;
}

.site-header-top {
    display: flex;
    align-items: center;
    position: relative;
}

.menu-toggle {
    display: none;
    position: absolute;
    right: 1.5rem;
    top: 50%;
    transform: translateY(-50%);
    flex-direction: column;
    gap: 5px;
    background: none;
    border: none;
    cursor: pointer;
    padding: 0.5rem;
}

.menu-toggle span {
    display: block;
    width: 24px;
    height: 3px;
    background: var(--color-accent-warm);
    border-radius: 2px;
}

nav.primary-nav {
    display: flex;
    align-items: center;
    justify-content: flex-end;
}

ul.primary-menu {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
}

ul.primary-menu > li.menu-item {
    position: relative;
    /* ul.primary-menu es flex sin align-items propio (stretch por defecto):
       cada li se estira a la altura de la fila, y sin este centrado su
       contenido (enlace, botón de búsqueda, selector de idioma — cada uno
       con su propio padding/alto) queda pegado arriba en vez de centrado,
       desalineando unos elementos con otros. */
    display: flex;
    align-items: center;
}

ul.primary-menu > li.menu-item > a {
    display: block;
    padding: 0.9rem 1rem;
    font-family: var(--font-heading);
    font-size: 1.05rem;
    font-weight: 700;
    color: var(--color-logo-orange);
    text-decoration: none;
    white-space: nowrap;
    transition: color 0.15s ease;
}

ul.primary-menu > li.menu-item > a:hover {
    color: var(--color-accent);
}

ul.primary-menu > li.has-children > a::after {
    content: '⌄';
    display: inline-block;
    margin-left: 0.3rem;
    color: var(--color-accent-warm);
}

.nav-lang > a {
    display: flex;
    align-items: center;
    gap: 0.3rem;
    padding: 0.5rem 0.75rem;
    font-size: 1.05rem;
    transition: transform 0.15s ease, color 0.15s ease;
}

.nav-lang > a:hover {
    color: var(--color-accent);
    transform: scale(1.08);
}

.nav-search {
    position: relative;
}

/* Botón (no <a>: no navega, abre el desplegable de búsqueda) — mismo look que
   los enlaces del menú para que no desentone. */
.nav-search-toggle {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 0.5rem 0.75rem;
    background: none;
    border: none;
    font-family: var(--font-heading);
    font-size: 1rem;
    font-weight: 700;
    color: var(--color-logo-orange);
    cursor: pointer;
    transition: transform 0.15s ease, color 0.15s ease;
}

.nav-search-toggle:hover { color: var(--color-accent); transform: scale(1.05); }

/* Mismo lenguaje visual que .story-sticky-related-panel (navy translúcido,
   esquinas cuadradas, despliegue vertical animado) — las tarjetas de
   resultado reutilizan directamente .story-sticky-related-item/-title/
   -placeholder (ver theme.css más abajo) en vez de duplicar ese CSS aquí. */
.nav-search-panel {
    display: grid;
    grid-template-rows: 0fr;
    position: absolute;
    top: 100%;
    right: 0;
    z-index: 10;
    width: min(360px, 92vw);
    background: rgba(38, 58, 90, 0.92);
    box-shadow: 0 16px 32px rgba(0, 0, 0, 0.28);
    opacity: 0;
    visibility: hidden;
    transition: grid-template-rows 0.28s ease, opacity 0.28s ease, visibility 0.28s;
}

.nav-search.is-open .nav-search-panel {
    grid-template-rows: 1fr;
    opacity: 1;
    visibility: visible;
}

.nav-search-panel-inner {
    overflow: hidden;
    padding: 0.75rem;
}

.nav-search-input {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 0.6rem 0.9rem;
    font-family: var(--font-body);
    font-size: 0.95rem;
    color: var(--color-text);
    background: var(--color-surface);
    border: none;
    border-radius: 999px;
}

.nav-search-input:focus { outline: 2px solid var(--color-logo-orange); outline-offset: 1px; }

.nav-search-results {
    list-style: none;
    margin: 0;
    padding: 0.6rem 0 0;
    max-height: 60vh;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

.nav-search-results[hidden] { display: none; }

.nav-search-empty {
    padding: 0.5rem;
    color: #FFFFFF;
    font-size: 0.85rem;
    text-align: center;
}

/* Selector de idioma — la mayoría de idiomas aún no tienen páginas propias (ver
   Idea_y_concepto/06-decisiones.md) y se muestran atenuados como vista previa
   (.is-preview); "no" sí es un enlace real a eventyrforbarn.com (ver nav.php)
   y debe verse con la misma opacidad que "en", no atenuado.
   El padding va en el <span>/<a> (no en el <li>) para que ambos casos midan
   lo mismo y las banderas queden alineadas — el <a> ya recibe su padding de
   la regla genérica "ul.primary-menu .submenu a" de más abajo. */
.submenu-lang li { color: var(--color-text); }

.submenu-lang li > span {
    display: block;
    padding: 0.5rem 1rem;
}

.submenu-lang li.is-preview { opacity: 0.6; }

.submenu-lang li.is-current > span {
    font-weight: 600;
    color: var(--color-accent-warm);
}

ul.primary-menu .submenu {
    display: none;
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 10;
    list-style: none;
    margin: 0;
    padding: 0.5rem 0;
    min-width: 260px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 0 0 var(--radius) var(--radius);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);
}

ul.primary-menu li.has-children:hover > .submenu {
    display: block;
}

ul.primary-menu .submenu li.menu-item {
    position: relative;
}

ul.primary-menu .submenu a {
    display: block;
    padding: 0.5rem 1rem;
    color: var(--color-text);
    text-decoration: none;
    white-space: nowrap;
}

ul.primary-menu .submenu a:hover {
    background: var(--color-bg);
    color: var(--color-accent-warm);
}

ul.primary-menu .submenu-nested {
    position: static;
    border: none;
    box-shadow: none;
    padding-left: 1rem;
    background: transparent;
}

main {
    max-width: var(--max-width);
    margin: 2rem auto;
    padding: 0 1.5rem;
}

/* Título de página — h1 compartido por todas las plantillas de contenido
   (category/story/page), fuera de .content-card, flotando sobre el fondo
   del sitio igual que el h1 del hero de la home. */
.page-title {
    margin: 0 0 1.5rem;
}

/* Cuando el cuento tiene hero, este empieza pegado a la cabecera (sin el
   hueco vertical de 2rem que <main> aplica al resto de plantillas) — el
   propio hero lleva --color-hero-divider como costura visual en su lugar. */
main:has(> .story-hero) {
    margin-top: 0;
}

/* Tarjeta blanca que envuelve el contenido sobre el fondo tileado — el hero
   (título + buscador) queda fuera, flotando directamente sobre el patrón,
   igual que en eventyrforbarn.com. */
.content-card {
    background: var(--color-surface);
    border-radius: var(--radius);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);
    padding: 2rem 1.5rem;
}

/* Imagen destacada de categorías y páginas (equivale al post-thumbnail del
   WordPress): bajo el título, dentro de la tarjeta, centrada y contenida
   (sin recorte) para que no domine la página. */
.featured-image {
    max-width: 520px;
    margin: 0 auto 1.5rem;
}

.featured-image img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: var(--radius);
}

/* Motivo navideño (copos) del WordPress original: fondo atenuado bajo cada h2
   de las landings de Navidad/invierno (.theme-winter), banda
   alta repetida con el título encima (.winter-band en la home,
   .page-title-winter en el h1 de las landings). */
.theme-winter .intro h2 {
    /* Motivo de copos atenuado (velo blanco) como fondo bajo el h2, en vez de tira aparte. */
    background:
        linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.3)),
        url("/assets/img/site/winter-band.webp") center / auto 100% repeat-x;
    border-radius: var(--radius);
    padding: 1.1rem 1rem;
    margin: 2rem 0 1rem;
    text-align: center;
    text-shadow: 0 0 6px #fff, 0 0 12px #fff;
}

.winter-band,
.page-title-winter {
    background:
        linear-gradient(rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0.3)),
        url("/assets/img/site/winter-band.webp") center / auto 100% repeat-x;
    border-radius: var(--radius);
    min-height: 98px;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    padding: 0.75rem 1rem;
}

.winter-band h2,
.page-title-winter {
    margin-top: 0;
    margin-bottom: 0;
    /* Velo blanco del fondo + halo claro para que el título se lea sobre los copos */
    color: #5a3318;
    font-weight: 400;
    text-shadow: 0 0 6px #fff, 0 0 12px #fff;
}

.page-title-winter { font-size: 2rem; }

.winter-band + .showcase-intro { margin-top: 1rem; }
.page-title-winter { margin-bottom: 1.5rem; }

/* Centrado de elementos sueltos en textos editoriales (intro de categorías, páginas):
   imágenes sueltas y párrafos cuyo único contenido es un enlace/CTA
   (ver Support\CenterLoneLinks). */
.intro > img,
.intro > p > img,
.intro figure,
article.page .body > p > img,
article.page .body > figure {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 1.25rem auto;
    border-radius: var(--radius);
}

.intro figure img,
article.page .body > figure img {
    display: block;
    margin: 0 auto;
    max-width: 100%;
    height: auto;
}

.intro .cta-line,
article.page .body .cta-line {
    text-align: center;
}

/* Centrado de elementos sueltos en textos editoriales (intro de categorías, páginas):
   imágenes sueltas y párrafos cuyo único contenido es un enlace/CTA
   (ver Support\CenterLoneLinks). */
.intro > img,
.intro > p > img,
.intro figure,
article.page .body > p > img,
article.page .body > figure {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 1.25rem auto;
    border-radius: var(--radius);
}

.intro figure img,
article.page .body > figure img {
    display: block;
    margin: 0 auto;
    max-width: 100%;
    height: auto;
}

.intro .cta-line,
article.page .body .cta-line {
    text-align: center;
}

article.story {
    max-width: var(--max-width);
    margin: 0 auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 2rem;
}

/* Solo la letra capital lleva color del logo (ver ::first-letter abajo) — el
   párrafo en sí se queda en el gris de lectura habitual, no en morado sólido:
   así se lee como cuerpo de texto normal, y el acento de color queda donde
   más impacto tiene (una letra), igual que en el logo real ningún bloque
   entero de texto es un solo color plano. */
article.story .excerpt {
    color: var(--color-text);
    font-style: italic;
    font-size: 1.15rem;
}

/* Letra capital juguetona (tipografía redondeada, no serifa clásica) —
   sombreada en dorado para dar un toque de chispa sin volver a la rigidez
   editorial de antes. Solo la inicial del primer párrafo del cuento. */
article.story .excerpt::first-letter {
    font-family: var(--font-story-display);
    font-style: normal;
    font-weight: 700;
    font-size: 3.1em;
    float: left;
    line-height: 0.75;
    margin: 0.05em 0.1em 0 0;
    color: var(--color-logo-purple);
    text-shadow: 2px 2px 0 var(--color-gold-tint);
}

/* La letra capital flota dentro de .excerpt — sin esto, el párrafo
   siguiente (TOC o cuerpo del cuento) seguiría envolviéndose alrededor de
   ella en vez de empezar limpio debajo. */
article.story .excerpt + * { clear: left; margin-top: 0.75rem; }

/* Interlineado y tamaño más generosos que el resto del sitio — el cuerpo del
   cuento se lee en voz alta compartido entre adulto y niño, no se escanea
   como un artículo. */
article.story .body p {
    font-size: 1.08rem;
    line-height: 1.85;
}

/* Líneas/párrafos de diálogo del cuento (blockquote de Markdown) — mismo
   tratamiento "cita" que .quote-block (ver más abajo): fondo gris claro,
   texto en cursiva gris oscuro, para separarlos visualmente del resto del
   cuerpo del cuento. */
article.story .body blockquote {
    position: relative;
    background: var(--color-quote-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.25rem 1.5rem;
    margin: 1.5rem 0;
    overflow: hidden;
}

/* Cuando la cita lleva icono de personaje (esquina superior izquierda), se
   tabula todo el texto hacia la derecha para que ninguna línea quede detrás
   del icono — no solo la primera. */
article.story .body blockquote:has(.story-quote-icon) {
    padding-left: 5.5rem;
}

article.story .body blockquote p {
    position: relative;
    z-index: 1;
    color: var(--color-quote-text);
    font-style: italic;
    margin: 0 0 1rem;
}

article.story .body blockquote p:last-child {
    margin-bottom: 0;
}

/* Icono de personaje (ver DialogueColors::decorate) — el emoji etiquetado en
   el Markdown, pintado como una "marca de agua" grande y semitransparente en
   la esquina de la cita, nunca dentro del propio texto. z-index por debajo
   del párrafo (arriba) para que el texto siempre quede legible encima. */
.story-quote-icon {
    position: absolute;
    top: 50%;
    left: 0.5rem;
    transform: translateY(-50%);
    z-index: 0;
    font-size: 3rem;
    line-height: 1;
    opacity: 0.4;
    pointer-events: none;
    user-select: none;
}

/* Variantes de color por personaje (ver DialogueColors::decorate) — el
   primer personaje que habla se queda con el gris de arriba sin clase
   extra; cada personaje nuevo suma una de estas 5. Mismo radio/padding/
   cursiva que el blockquote estándar, solo cambia el tinte. */
article.story .body blockquote.story-quote-orange { background: var(--color-dialogue-orange-bg); border-color: var(--color-dialogue-orange-border); }
article.story .body blockquote.story-quote-orange p { color: var(--color-dialogue-orange-text); }

article.story .body blockquote.story-quote-purple { background: var(--color-dialogue-purple-bg); border-color: var(--color-dialogue-purple-border); }
article.story .body blockquote.story-quote-purple p { color: var(--color-dialogue-purple-text); }

article.story .body blockquote.story-quote-teal { background: var(--color-dialogue-teal-bg); border-color: var(--color-dialogue-teal-border); }
article.story .body blockquote.story-quote-teal p { color: var(--color-dialogue-teal-text); }

article.story .body blockquote.story-quote-green { background: var(--color-dialogue-green-bg); border-color: var(--color-dialogue-green-border); }
article.story .body blockquote.story-quote-green p { color: var(--color-dialogue-green-text); }

article.story .body blockquote.story-quote-pink { background: var(--color-dialogue-pink-bg); border-color: var(--color-dialogue-pink-border); }
article.story .body blockquote.story-quote-pink p { color: var(--color-dialogue-pink-text); }

/* Marcador de fin de cuento (texto en negrita-cursiva tipo THE END o SLUTT
   en el Markdown original), detectado y envuelto en este párrafo por
   StoryEnding::decorate — letra grande, centrada y "corpórea" vía sombra
   escalonada en un tono dorado, con una estrellita decorativa a cada lado. */
article.story .body p.story-end {
    display: block;
    text-align: center;
    font-family: var(--font-story-display);
    font-weight: 700;
    font-size: clamp(2rem, 5.5vw, 3.2rem);
    letter-spacing: 0.1em;
    color: var(--color-logo-pink);
    text-shadow: 3px 3px 0 var(--color-gold), 5px 5px 0 rgba(0, 0, 0, 0.1);
    margin: 2.5rem 0 1.5rem;
}

.story-end-star {
    display: inline-block;
    margin: 0 0.6rem;
    font-size: 0.55em;
    vertical-align: middle;
    text-shadow: none;
}

/* Imágenes dentro del cuerpo del cuento (mapa, ilustraciones de capítulo...):
   centradas y nunca más anchas que el propio contenedor del cuento. */
article.story .body img {
    display: block;
    max-width: 100%;
    height: auto;
    margin: 1.5rem auto;
    border-radius: var(--radius);
}

/* Versión completa de la imagen destacada (ver FeaturedImage::insertAfterFirstHeading)
   — algo más de aire que una ilustración de capítulo cualquiera, es el "reveal"
   grande de la historia. */
article.story .body img.story-featured-inline {
    margin: 2rem auto;
}

/* Los h2/h3 de capítulo dentro del cuerpo del cuento necesitan más presencia
   que un heading de sección normal (categoría, footer...) — de ahí este
   tamaño específico en vez de tocar el h2/h3 global. Cada capítulo rota por
   los 5 tonos reales del logo en vez de un único marrón fijo — como las
   letras de "FabelTales", cada título destaca con su propio color a lo largo
   del cuento (notorio sobre todo en los calendarios de adviento de 24
   capítulos). La primera letra usa el siguiente tono de la rueda y un peso
   mayor, a modo de mini letra capital de cada capítulo. */
article.story .body h2,
article.story .body h3 {
    font-family: var(--font-story-display);
    font-weight: 500;
}

article.story .body h2 { font-size: clamp(1.8rem, 4vw, 2.35rem); }
article.story .body h3 { font-size: clamp(1.45rem, 3vw, 1.85rem); }

article.story .body h2::first-letter,
article.story .body h3::first-letter {
    font-weight: 700;
    font-size: 1.3em;
    text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.08);
}

article.story .body h2:nth-of-type(5n+1),
article.story .body h3:nth-of-type(5n+1) { color: var(--color-logo-purple); }
article.story .body h2:nth-of-type(5n+2),
article.story .body h3:nth-of-type(5n+2) { color: var(--color-logo-orange); }
article.story .body h2:nth-of-type(5n+3),
article.story .body h3:nth-of-type(5n+3) { color: var(--color-logo-teal); }
article.story .body h2:nth-of-type(5n+4),
article.story .body h3:nth-of-type(5n+4) { color: var(--color-logo-green); }
article.story .body h2:nth-of-type(5n+5),
article.story .body h3:nth-of-type(5n+5) { color: var(--color-logo-pink); }

article.story .body h2:nth-of-type(5n+1)::first-letter,
article.story .body h3:nth-of-type(5n+1)::first-letter { color: var(--color-logo-orange); }
article.story .body h2:nth-of-type(5n+2)::first-letter,
article.story .body h3:nth-of-type(5n+2)::first-letter { color: var(--color-logo-teal); }
article.story .body h2:nth-of-type(5n+3)::first-letter,
article.story .body h3:nth-of-type(5n+3)::first-letter { color: var(--color-logo-pink); }
article.story .body h2:nth-of-type(5n+4)::first-letter,
article.story .body h3:nth-of-type(5n+4)::first-letter { color: var(--color-logo-purple); }
article.story .body h2:nth-of-type(5n+5)::first-letter,
article.story .body h3:nth-of-type(5n+5)::first-letter { color: var(--color-logo-green); }

/* Marca de agua translúcida del separador decorativo (copos/filigrana, ver
   StorySeparator::markFirstHeadingBackground) detrás del primer capítulo —
   señala "aquí empieza la historia" tras el bloque introductorio (excerpt +
   TOC). --story-chapter-bg lo pone inline el propio <h2> (varía por cuento:
   invierno vs genérico); el texto del título queda siempre 100% opaco porque
   la imagen vive en un ::before aparte, detrás, no en el propio h2. */
article.story .body h2:first-of-type {
    position: relative;
    z-index: 0;
}

article.story .body h2:first-of-type::before {
    content: "";
    position: absolute;
    top: -1.75rem;
    bottom: -1.75rem;
    left: -1rem;
    right: -1rem;
    z-index: -1;
    background-image: var(--story-chapter-bg);
    background-repeat: no-repeat;
    background-position: center;
    background-size: contain;
    opacity: 0.3;
    pointer-events: none;
}

/* Mini cabecera flotante con el logo + título del cuento — aparece al hacer
   scroll pasado el 50% del alto de pantalla (ver story-sticky-title.js) para
   recordar qué cuento se está leyendo sin depender del header original, que
   ya ha desaparecido de la vista. Banda a todo el ancho con el mismo tono
   (--color-hero-tint) que el panel del hero, para que se sienta como "el
   hero que vuelve" en vez de un elemento aparte. */
.story-sticky-title {
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    z-index: 250;
    display: flex;
    align-items: center;
    gap: 0.85rem;
    padding: 0.6rem 1.5rem;
    /* Propia (no --color-hero-tint compartida con el hero) para poder subir
       la transparencia aquí sin afectar al panel del hero. */
    background: rgba(38, 58, 90, 0.62);
    opacity: 0;
    visibility: hidden;
    transform: translateY(-100%);
    transition: opacity 2s ease, transform 2s ease, visibility 2s;
    pointer-events: none;
}

.story-sticky-title.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
    pointer-events: auto;
}

.story-sticky-logo-link {
    display: flex;
    flex-shrink: 0;
    line-height: 0;
}

.story-sticky-logo {
    height: 38px;
    width: auto;
    display: block;
}

.story-sticky-heading {
    font-family: var(--font-story-display);
    font-weight: 500;
    font-size: 1.15rem;
    color: #FFFFFF;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    max-width: 70vw;
}

@media (max-width: 640px) {
    .story-sticky-heading { max-width: 55vw; font-size: 1rem; }
    .story-sticky-logo { height: 30px; }
}

/* CTA "Want to read more?" a la derecha de la banda flotante — mismo dato de
   afinidad que el módulo de fin de artículo (ver StoryRepository::related()),
   como desplegable en vez de navegar a otra página, para no perder el sitio
   de lectura. margin-left:auto lo empuja al extremo derecho de la banda. */
/* Agrupa la lupa de búsqueda + el CTA "Want to read more?" al extremo
   derecho de la banda — margin-left:auto vive aquí (no en cada hijo por
   separado) para que ambos se empujen juntos como un solo bloque. */
.story-sticky-actions {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin-left: auto;
    flex: none;
}

.story-sticky-search-toggle {
    background: rgba(255, 255, 255, 0.14);
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 999px;
    padding: 0.5rem 0.7rem;
    font-size: 1rem;
    color: #FFFFFF;
}

.story-sticky-search-toggle:hover { background: rgba(255, 255, 255, 0.26); }

.story-sticky-search .nav-search-panel { right: 0; }

.story-sticky-related {
    position: relative;
    flex: none;
}

.story-sticky-related-toggle {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    background: rgba(255, 255, 255, 0.14);
    border: 1px solid rgba(255, 255, 255, 0.35);
    border-radius: 999px;
    padding: 0.45rem 1rem;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.9rem;
    color: #FFFFFF;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease;
}

.story-sticky-related-toggle:hover { background: rgba(255, 255, 255, 0.26); }

.story-sticky-related-arrow {
    display: inline-block;
    transition: transform 0.2s ease;
}

.story-sticky-related.is-open .story-sticky-related-arrow { transform: rotate(180deg); }

/* Mismo tono translúcido que la propia banda flotante (no una tarjeta blanca
   aparte) y sin esquinas redondeadas, a juego con el resto de cajas "planas"
   de esta pasada (TOC, separador). display:grid + grid-template-rows anima
   de 0fr a 1fr en vez de display:none/block, para un despliegue vertical
   real en lugar de un cambio brusco. */
.story-sticky-related-panel {
    display: grid;
    grid-template-rows: 0fr;
    position: absolute;
    top: calc(100% + 0.6rem);
    right: 0;
    z-index: 10;
    width: min(340px, 88vw);
    background: rgba(38, 58, 90, 0.86);
    border-radius: 0;
    box-shadow: 0 16px 32px rgba(0, 0, 0, 0.28);
    opacity: 0;
    visibility: hidden;
    /* 1500ms a petición del usuario ("el desplegable sale demasiado rápido") --
       antes 0.28s. */
    transition: grid-template-rows 1.5s ease, opacity 1.5s ease, visibility 1.5s;
}

.story-sticky-related.is-open .story-sticky-related-panel {
    grid-template-rows: 1fr;
    opacity: 1;
    visibility: visible;
}

.story-sticky-related-panel-inner {
    overflow: hidden;
    max-height: 70vh;
    overflow-y: auto;
    padding: 0.5rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Tarjeta = la miniatura entera, título superpuesto en blanco sobre un velo
   degradado (no icono + texto al lado) — se lee como un mini-póster de cada
   cuento relacionado. */
.story-sticky-related-item {
    position: relative;
    display: block;
    /* 50% más alta que antes (era 84px) -- a petición del usuario, las
       tarjetas se veían demasiado estrechas. */
    height: 126px;
    text-decoration: none;
    overflow: hidden;
}

.story-sticky-related-item img,
.story-sticky-related-item-placeholder {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    border-radius: 0;
    object-fit: cover;
}

.story-sticky-related-item-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.14);
    font-size: 1.6rem;
}

.story-sticky-related-item::after {
    content: "";
    position: absolute;
    inset: 0;
    background: linear-gradient(to top, rgba(14, 24, 48, 0.88) 0%, rgba(14, 24, 48, 0.15) 65%, transparent 100%);
}

.story-sticky-related-item:hover::after { background: linear-gradient(to top, rgba(14, 24, 48, 0.95) 0%, rgba(14, 24, 48, 0.3) 65%, transparent 100%); }

.story-sticky-related-item-title {
    position: absolute;
    left: 0.75rem;
    right: 0.75rem;
    bottom: 0.5rem;
    z-index: 1;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.9rem;
    color: #FFFFFF;
}

/* Cierre del desplegable: no otro cuento suelto, sino la salida hacia "ver
   todos" de la propia categoría del cuento — separado del listado por un
   filete sutil para que se lea como un cierre, no como una tarjeta más. */
.story-sticky-related-cta {
    display: block;
    text-align: center;
    margin-top: 0.25rem;
    padding: 0.65rem 0.5rem 0.4rem;
    border-top: 1px solid rgba(255, 255, 255, 0.2);
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.85rem;
    color: var(--color-logo-orange);
    text-decoration: none;
}

.story-sticky-related-cta:hover { color: #FFFFFF; }

@media (max-width: 480px) {
    .story-sticky-related { display: none; }
}

/* Módulo "También te puede gustar" al final del artículo — mismo dato de
   afinidad y las mismas clases .story-grid/.story-card que category.php, así
   se ve como el resto del catálogo en vez de un widget aparte. */
.related-stories {
    max-width: var(--max-width);
    margin: 3rem auto 0;
}

.related-stories-heading {
    font-family: var(--font-heading);
    font-size: 1.75rem;
    text-align: center;
    margin-bottom: 1.5rem;
}

/* "You might also like" — título integrado sobre la imagen en vez de debajo (el
   extracto se queda tal cual, fuera de la imagen); el nº de columnas (2 en
   móvil / 3 en desktop) lo pone la regla general de .story-grid más abajo. */
.related-stories .story-grid {
    gap: 2rem;
}

/* height fija en el propio media (no solo en la img) para que una historia sin
   cover_image (p.ej. "Little Red Riding Hood" hoy) siga reservando el mismo
   alto y el título en blanco no quede ilegible sobre fondo transparente. */
.related-stories .story-card-media {
    position: relative;
    height: 220px;
    background: var(--color-sky);
}

.related-stories .story-card-link img {
    height: 220px;
}

.related-stories .story-card-title {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2.5rem 1rem 0.75rem;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));
    color: #FFFFFF;
    font-size: 1.1rem;
}

/* Página /favorites/ — favorites.php es solo la carcasa, favorites-page.js
   pinta el contenido real desde localStorage (ver favorites-store.js). */
.continue-reading {
    margin-bottom: 3rem;
    padding-bottom: 2rem;
    border-bottom: 1px solid var(--color-border);
}

.favorites-section-heading {
    font-family: var(--font-heading);
    font-size: 1.5rem;
    margin: 0 0 1.25rem;
    text-align: left;
}

.favorites-list-header {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
    margin-bottom: 1.25rem;
}

.favorites-list-header .favorites-section-heading { margin-bottom: 0; }

.favorites-sort {
    display: flex;
    gap: 0.5rem;
}

.favorites-sort-btn {
    background: var(--color-bg);
    border: none;
    border-radius: 999px;
    padding: 0.45rem 1rem;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.85rem;
    color: var(--color-text);
    cursor: pointer;
}

.favorites-sort-btn.is-active {
    background: var(--color-logo-navy);
    color: #FFFFFF;
}

.favorites-empty {
    color: var(--color-text);
    opacity: 0.7;
    padding: 1.5rem 0;
}

.favorites-empty[hidden] { display: none; }

/* Barra "sigue aquí" — solo en la tarjeta más reciente de "Continue where
   you left off" cuando el cuento se quedó a medias (ver favorites-page.js).
   .story-card-link necesita position:relative solo cuando la lleva. */
.story-card-link:has(.story-card-progress) { position: relative; }

.story-card-progress {
    position: absolute;
    left: 0;
    right: 0;
    top: 134px;
    height: 6px;
    background: rgba(0, 0, 0, 0.18);
}

.story-card-progress-fill {
    height: 100%;
    background: var(--color-logo-orange);
}

/* Hero de cuento a todo el ancho de pantalla, sin margen lateral (rompe el
   max-width de <main> con el truco left/margin-left 50vw) — pegado a la
   cabecera arriba (ver main:has(> .story-hero)) y a los bordes izquierdo/
   derecho de la ventana, separado del menú solo por --color-hero-divider.
   Panel de texto a la izquierda (52%), imagen destacada a la derecha (48%),
   con una zona de transición donde el panel se desvanece en degradado hasta
   transparente. Solo se renderiza si el cuento tiene cover_image; si no,
   story.php cae al encabezado simple de siempre dentro de la tarjeta. */
.story-hero {
    position: relative;
    left: 50%;
    right: 50%;
    width: 100vw;
    margin-left: -50vw;
    margin-right: -50vw;
    display: flex;
    height: clamp(260px, 25vw, 380px);
    overflow: hidden;
    margin-bottom: 2rem;
    border-top: 4px solid var(--color-hero-divider);
    border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

/* Estrella de favorito del hero — más grande y con más presencia que la
   píldora "Save" de la cabecera de respaldo (ver .story-badge.favorite-toggle),
   al nivel del propio título en vez de mezclada entre los demás badges. */
.story-hero-favorite {
    position: absolute;
    top: 1rem;
    right: 1rem;
    z-index: 2;
    width: 52px;
    height: 52px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.9);
    border-radius: 50%;
    color: var(--color-logo-orange);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
}

.story-hero-favorite:hover { background: #FFFFFF; }

.story-hero-favorite .favorite-toggle-icon {
    width: 28px;
    height: 28px;
}

.story-hero-panel {
    flex: 0 0 52%;
    box-sizing: border-box;
    background: var(--color-hero-tint);
    color: var(--color-cream);
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: clamp(1.25rem, 3vw, 2.5rem);
    z-index: 1;
}

/* Envuelve título+autor+tarjetas -- en escritorio es un simple repetidor del
   flex-column con gap que antes vivía en .story-hero-panel (el fondo/padding
   del panel no cambian); en mobile (ver media query) es quien lleva el fondo
   traslúcido, con altura automática pegada a su contenido en vez de un % fijo
   del hero -- así la banda siempre empieza justo encima del título, tenga
   éste una o dos líneas. */
.story-hero-text-block {
    display: flex;
    flex-direction: column;
    gap: 0.75rem;
}

/* Serif editorial (mismo --font-story-display de la letra capital y "THE END")
   solo para el título del hero y los capítulos del cuerpo del cuento — el
   resto de la interfaz (nav, logo, categorías) sigue en Dosis sin tocar. */
.story-hero-title {
    margin: 0;
    text-align: left;
    color: #FFFFFF;
    font-family: var(--font-story-display);
    font-weight: 500;
    font-size: clamp(1.75rem, 3.2vw, 2.7rem);
}

.story-hero-panel .story-badges { margin: 0; }
.story-hero-panel .story-author { margin: 0 0 0.6rem; font-size: 1rem; color: var(--color-cream); opacity: 1; }

/* Fila inferior del hero: tarjetas (tiempo/categoría/edad) a la izquierda,
   fecha empujada al extremo derecho a la misma altura -- antes la fecha
   vivía en su propia línea suelta debajo de las tarjetas. */
.story-hero-bottom-row {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 0.5rem;
    /* Empuja este bloque al borde inferior del panel (flex column) sin
       mover el título/autor de arriba -- solo en escritorio, donde el panel
       es mucho más alto y separar el título de las tarjetas se lee bien.
       En mobile se cancela (ver media query) para que todo el bloque de
       texto quede compacto y pegado abajo, tapando lo menos posible de la
       imagen. */
    margin-top: auto;
}

.story-hero-media {
    position: relative;
    flex: 0 0 48%;
    background: var(--color-hero-tint);
}

/* A todo lo alto del hero (sin margen de letterbox arriba/abajo) — el
   recorte para encajar en una franja tan ancha y baja lo hace object-fit,
   no un hueco explícito. */
.story-hero-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

/* Mobile: en vez de apilar imagen + panel (dos bloques, mucho alto), la
   imagen pasa a ser el fondo directo del panel de texto/tarjetas — un único
   bloque compacto tipo hero clásico, para que se vea contenido real sin
   hacer scroll. El texto ya es claro por defecto (ver arriba), aquí solo
   hace falta quitar el fondo sólido del panel y reforzar el velo. */
@media (max-width: 860px) {
    .story-hero {
        /* Más bajo que antes (era clamp(270px, 66vw, 380px) -- a petición del
           usuario, ocupaba demasiada pantalla nada más entrar en un cuento
           desde el móvil, antes de ver nada de contenido real). */
        height: clamp(200px, 50vw, 300px);
        margin-bottom: 1.5rem;
    }

    .story-hero-media {
        position: absolute;
        inset: 0;
        flex-basis: auto;
    }

    .story-hero-panel {
        position: relative;
        z-index: 2;
        flex-basis: auto;
        width: 100%;
        height: 100%;
        background: none;
        justify-content: flex-end;
        padding: 0;
    }

    /* La banda ya no es un % fijo del hero (.story-hero-media::before, que
       dejaba el título por fuera con títulos largos de 2 líneas) -- ahora es
       el propio fondo de este bloque, con altura automática pegada a su
       contenido real (título de 1 o 2 líneas + autor + tarjetas), así que
       arranca siempre justo encima del título, sea cual sea su longitud.
       Gap más apretado que el 0.75rem de escritorio (y más apretado aún que
       el primer intento en mobile) a petición del usuario. */
    .story-hero-text-block {
        gap: 0.15rem;
        background: rgba(38, 58, 90, 0.72);
        padding: 0.5rem 1.5rem 0.6rem;
    }

    .story-hero-panel .story-author {
        margin-bottom: 0.15rem;
    }

    .story-hero-bottom-row {
        margin-top: 0;
    }

    /* Igual que en escritorio (sin text-shadow -- lo sostiene la banda de
       arriba), solo que más pequeño para caber en una pantalla estrecha. */
    .story-hero-title {
        font-size: clamp(1.35rem, 5.5vw, 1.9rem);
    }

    .story-hero-panel .story-author {
        font-size: 0.85rem;
    }
}

.story-breadcrumb {
    margin: 0 0 1rem;
    font-size: 0.9rem;
}

.story-breadcrumb a {
    text-decoration: none;
    font-weight: 600;
}

.story-cover {
    display: block;
    width: 100%;
    max-height: 360px;
    object-fit: cover;
    border-radius: var(--radius);
    margin-bottom: 1rem;
}

.story-meta {
    margin: 0 0 1rem;
    font-size: 0.85rem;
    color: var(--color-text);
    opacity: 0.7;
}

/* Firma de autor/origen (ver s.author) — pintada justo bajo el título, antes
   de las tarjetas de tiempo/categoría/edad, con más tamaño y peso que la
   fecha para que lea como una firma editorial, no como un dato suelto más. */
.story-author {
    margin: 0 0 0.75rem;
    font-size: 1rem;
    font-weight: 600;
    color: var(--color-text);
    opacity: 0.85;
}

/* Fila de "tarjetas" en la cabecera del cuento: tiempo de lectura, categoría
   (paleta de CategoryBadge) y rango de edad (paleta de AgeRange). Mismo
   tratamiento de chip para las 3, solo cambian bg/text por historia. */
.story-badges {
    display: flex;
    flex-wrap: wrap;
    gap: 0.5rem;
    margin: 0 0 1rem;
}

.story-badge {
    display: inline-flex;
    align-items: center;
    gap: 0.35rem;
    font-size: 0.8rem;
    font-weight: 600;
    padding: 0.35rem 0.85rem;
    border-radius: 999px;
    background: var(--color-quote-bg);
    color: var(--color-text);
    text-decoration: none;
}

.story-badge-link:hover { filter: brightness(0.93); text-decoration: underline; }

.story-badge-value { font-weight: 700; }

/* Iconos de línea propios (reloj, estrella) en vez de emoji — heredan el
   color de texto de cada badge vía currentColor, así funcionan igual con
   cualquier paleta (categoría/edad) sin CSS adicional por variante. */
.story-badge-icon {
    width: 14px;
    height: 14px;
    flex: none;
}

/* TOC — solo se renderiza cuando TableOfContents::build supera el umbral de
   capítulos (ver app/src/Support/TableOfContents.php), para cuentos largos
   tipo calendario de adviento. Caja fría (azul pastel) + texto naranja del
   logo — cálido sobre frío, como alternan las letras del logo real, en vez
   de naranja sobre amarillo (misma familia de color, poco contraste). */
.story-toc {
    background: var(--color-sky);
    border: none;
    border-radius: 0;
    padding: 1.25rem 1.5rem;
    margin: 0 0 1.5rem;
}

.story-toc-heading {
    margin: 0;
    font-family: var(--font-heading);
    font-weight: 600;
    text-transform: none;
    font-size: 1.05rem;
    letter-spacing: 0;
    color: var(--color-logo-orange);
    cursor: pointer;
}

.story-toc[open] .story-toc-heading { margin-bottom: 0.5rem; }

/* Índice de capítulos numerado (contador CSS, sin tocar el <ol> del PHP) —
   número en la serif editorial del cuento, a juego con .story-hero-title y
   los h2 de capítulo, en vez de una simple lista con viñeta. */
.story-toc ol {
    list-style: none;
    counter-reset: story-chapter;
    margin: 0;
    padding: 0;
    columns: 2;
    column-gap: 2rem;
}

.story-toc li {
    counter-increment: story-chapter;
    display: flex;
    align-items: baseline;
    gap: 0.6rem;
    break-inside: avoid;
    margin-bottom: 0.5rem;
}

.story-toc li::before {
    content: counter(story-chapter, decimal-leading-zero);
    flex: none;
    min-width: 1.6rem;
    font-family: var(--font-story-display);
    font-weight: 700;
    font-size: 0.95rem;
    color: var(--color-accent-warm);
    opacity: 0.55;
}

.story-toc li a {
    font-size: 0.85rem;
    text-decoration: none;
}

.story-toc li a:hover { text-decoration: underline; }

/* Ahora se inserta dentro de .body (ver StorySeparator::insert), así que
   necesita más especificidad que la regla general de imágenes del cuerpo
   para quitarle el border-radius y ocupar el ancho completo del contenedor,
   no solo su tamaño natural. */
article.story .body img.story-separator {
    display: block;
    width: 100%;
    max-width: 100%;
    height: auto;
    margin: 2.5rem auto 0.5rem;
    border-radius: 0;
}

/* Intro block de la home — bienvenida + buscador + imagen decorativa, dentro
   de la primera .content-card justo después del h1 (diseño de página normal,
   no un hero flotante independiente). En pantallas pequeñas la imagen cae
   debajo del texto porque flex-wrap sigue el orden del HTML (texto primero). */
.intro-columns {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 2rem;
    margin-bottom: 1.5rem;
}

.intro-text { flex: 1 1 320px; }

.intro-image {
    flex: 1 1 280px;
    max-width: 360px;
    width: 100%;
}

.intro-image img {
    width: 100%;
    max-height: 380px;
    height: auto;
    border-radius: var(--radius);
    object-fit: cover;
    display: block;
}

.intro-mission {
    max-width: none;
    margin: 0;
}

.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Buscador instantáneo — tarjeta propia, bien visible, réplica del "Finn ditt
   favorittventyr" del original. */
.search-card {
    max-width: 420px;
    margin-top: 1.25rem;
    background: var(--color-cream);
    border-radius: var(--radius);
    padding: 1.25rem;
}

.search-card-heading {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    margin-bottom: 1rem;
}

.search-card-icon {
    flex: none;
    width: 40px;
    height: 40px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--color-surface);
    border-radius: 50%;
    font-size: 1.2rem;
}

.search-card-heading strong {
    display: block;
    font-family: var(--font-heading);
    color: var(--color-accent-warm);
}

.search-card-subtitle {
    display: block;
    font-size: 0.85rem;
}

.search-hint {
    margin: 0.6rem 0 0;
    font-size: 0.8rem;
    color: var(--color-accent-warm);
    text-align: center;
}

.search-input-wrapper {
    position: relative;
}

.search-input-icon {
    position: absolute;
    left: 1rem;
    top: 50%;
    transform: translateY(-50%);
    pointer-events: none;
}

.hero-search-input {
    width: 100%;
    padding: 0.75rem 1.1rem 0.75rem 2.5rem;
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--color-text);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: 999px;
}

.hero-search-input:focus {
    outline: 2px solid var(--color-accent);
    outline-offset: 1px;
}

.hero-search-results {
    position: absolute;
    top: calc(100% + 0.5rem);
    left: 0;
    right: 0;
    z-index: 20;
    list-style: none;
    margin: 0;
    padding: 0.5rem;
    max-height: 360px;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.08);
}

.hero-search-result {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    padding: 0.5rem;
    border-radius: 8px;
    text-decoration: none;
    color: var(--color-text);
}

.hero-search-result:hover,
.hero-search-result:focus {
    background: var(--color-bg);
    color: var(--color-text);
}

.hero-search-result-media {
    flex: none;
    width: 44px;
    height: 44px;
    border-radius: 8px;
    overflow: hidden;
}

.hero-search-result-media img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
}

.hero-search-result-title {
    display: block;
    font-family: var(--font-heading);
    color: var(--color-accent-warm);
}

.hero-search-result-category {
    display: block;
    font-size: 0.8rem;
    color: var(--color-accent);
}

.hero-search-empty {
    padding: 0.5rem;
    color: var(--color-accent-warm);
    font-size: 0.9rem;
}

/* Category grid (home) and story grid (category page) share the same card layout */
.category-grid, .story-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;   /* una fila incompleta (1-2 tarjetas sueltas) queda centrada, no pegada a la izquierda */
    gap: 1.5rem;
}

.category-grid > * {
    flex: 1 1 220px;
    max-width: 320px;
    min-width: 0;
}

/* Listados de cuentos (no de categorías/temas) — filas fijas de 2 en móvil y 3
   en desktop, a diferencia del .category-grid genérico de arriba (auto-fill,
   pensado para la cuadrícula de temas de la home, que sí puede variar de
   columnas libremente). Aplica a .story-grid (category.php, "You might also
   like") y a .linked-story-grid (cuentos mencionados dentro del texto
   editorial, ver Support\LinkedStoryCards). */
.story-grid > *,
.linked-story-grid > * {
    flex: 0 0 calc((100% - 1.5rem) / 2);
    max-width: none;
}

@media (min-width: 700px) {
    .story-grid > *,
    .linked-story-grid > * {
        flex-basis: calc((100% - 3rem) / 3);
    }
}

/* Mensaje de "sin cuentos" u otro bloque que no es tarjeta: ocupa toda la fila, centrado. */
.story-grid > p {
    flex: 1 1 100%;
    text-align: center;
}

/* .related-stories usa gap 2rem: ajusta el ancho de las tarjetas a ese hueco. */
.related-stories .story-grid > * {
    flex-basis: calc((100% - 2rem) / 2);
}

@media (min-width: 700px) {
    .related-stories .story-grid > * {
        flex-basis: calc((100% - 4rem) / 3);
    }
}

/* "Ver más" — usado por assets/js/show-more-grid.js en cualquier .story-grid o
   .linked-story-grid con más de 6 elementos (2×3 o 3×2, nunca una fila
   incompleta). Progresivo: el contenido ya está en el HTML servido, el botón
   solo revela lo que ya existe — no es una petición nueva ni paginación. */
.grid-item-hidden { display: none !important; }

.show-more-wrap {
    text-align: center;
    margin: 1.75rem 0 0.5rem;
}

.show-more-btn {
    background: var(--color-accent);
    color: var(--color-surface);
    border: none;
    padding: 0.65rem 1.6rem;
    border-radius: 999px;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.95rem;
    cursor: pointer;
}

.show-more-btn:hover { filter: brightness(1.08); }

/* Ver Support\LinkedStoryCards — cuadrícula insertada dentro del texto editorial
   (intro_html) donde antes había una lista de nombres de cuento enlazados; necesita
   su propio margen vertical porque vive dentro de prosa, no en su propia <section>. */
.linked-story-grid {
    margin: 1.5rem 0;
}

/* Cuento sin cover_image propio todavía (dato de catálogo pendiente, no un fallo
   de esta transformación) — sin esto la tarjeta se queda vacía y desalineada
   junto a las que sí tienen miniatura. */
.linked-story-grid .category-card--no-image {
    min-height: 140px;
    justify-content: center;
    background: var(--color-sky);
}

.linked-story-grid .category-card--no-image .category-card-title {
    text-align: center;
}

.linked-story-more-note {
    margin: 0.5rem 0 0.4rem;
    font-size: 0.85rem;
    font-style: italic;
    color: var(--color-accent-warm);
}

/* .story-card es un <div> (no <a>) porque ahora lleva dos controles propios:
   el enlace .story-card-link (toda la tarjeta) y el botón de favorito en la
   esquina — un <button> no puede anidarse dentro de un <a>. .category-card
   no necesita esto (las categorías no son favoriteables) y sigue siendo un
   <a> directo. */
.category-card, .story-card-link {
    display: flex;
    flex-direction: column;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    text-decoration: none;
    color: var(--color-text);
    height: 100%;
}

.story-card {
    position: relative;
    transition: transform 0.15s ease;
}

.category-card { transition: transform 0.15s ease; }

.category-card:hover, .story-card:hover {
    transform: translateY(-3px);
}

.category-card img, .story-card-link img {
    width: 100%;
    height: 140px;
    object-fit: cover;
}

.category-card-title, .story-card-title {
    font-family: var(--font-heading);
    font-weight: 600;
    color: var(--color-accent-warm);
    padding: 0.75rem 1rem 0.25rem;
}

.story-card-excerpt {
    padding: 0 1rem 1rem;
    font-size: 0.9rem;
    color: var(--color-text);
}

/* Botón de favorito — reutilizado tal cual en la ficha del cuento (dentro de
   .story-badges) y en la esquina de cada .story-card. .is-favorite (la
   marca la añade favorite-buttons.js según localStorage) rellena la
   estrella; sin ella se queda en contorno. */
.favorite-toggle {
    cursor: pointer;
    border: none;
    font-family: inherit;
}

.favorite-toggle.is-favorite .favorite-toggle-icon {
    fill: currentColor;
}

.story-card-favorite {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    z-index: 2;
    width: 32px;
    height: 32px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255, 0.88);
    border: none;
    border-radius: 50%;
    color: var(--color-logo-orange);
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
}

.story-card-favorite:hover { background: #FFFFFF; }

.story-card-favorite .favorite-toggle-icon {
    width: 18px;
    height: 18px;
}

.category-header { margin-bottom: 2rem; }

.home-section { margin-top: 3rem; }
.home-section h2 {
    font-size: 1.95rem;
    margin-bottom: 1.25rem;
}

article.page {
    max-width: var(--max-width-narrow);
    margin: 0 auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 2rem;
}

/* Contact form (app/templates/contact.php) */
.contact-form-card {
    max-width: var(--max-width-narrow);
    margin: 1.5rem auto 0;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 2rem;
}

.contact-form {
    display: flex;
    flex-direction: column;
    gap: 1.1rem;
}

.contact-field label {
    display: block;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.95rem;
    color: var(--color-text);
    margin-bottom: 0.35rem;
}

.contact-field input[type="text"],
.contact-field input[type="email"],
.contact-field textarea {
    width: 100%;
    font-family: var(--font-body);
    font-size: 1rem;
    color: var(--color-text);
    background: var(--color-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 0.65rem 0.9rem;
    box-sizing: border-box;
}

.contact-field textarea {
    resize: vertical;
}

.contact-field input:focus,
.contact-field textarea:focus {
    outline: 2px solid var(--color-accent);
    outline-offset: 1px;
}

/* Señuelo antispam: fuera de la pantalla, pero no display:none (algunos bots
   ignoran los campos ocultos con display:none o visibility:hidden). */
.contact-field-honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

.contact-submit {
    align-self: flex-start;
    background: var(--color-logo-navy);
    color: #FFFFFF;
    border: none;
    border-radius: 999px;
    padding: 0.7rem 1.75rem;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 1rem;
    cursor: pointer;
}

.contact-submit:hover {
    opacity: 0.9;
}

.contact-form-notice {
    border-radius: var(--radius);
    padding: 0.85rem 1.1rem;
    margin: 0 0 1.25rem;
    font-family: var(--font-body);
    font-size: 0.95rem;
}

.contact-form-notice-ok {
    background: var(--color-mint);
    color: var(--color-forest);
}

.contact-form-notice-error {
    background: var(--color-dialogue-orange-bg);
    color: var(--color-dialogue-orange-text);
}

/* Cookie banner */
#cookie-notice {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 100;
    background: #32323a;
    color: #fff;
    padding: 1rem 1.5rem;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 1rem;
    font-size: 0.9rem;
}

#cookie-notice.cookie-notice-hidden { display: none; }

#cookie-notice a { color: var(--color-gold); }

#cookie-notice button {
    background: var(--color-forest);
    color: #fff;
    border: none;
    border-radius: 6px;
    padding: 0.5rem 1.25rem;
    cursor: pointer;
    font-family: var(--font-body);
}

#cookie-notice button:hover { opacity: 0.9; }

/* Quick-nav pastel button grid (home) */
.quick-nav-grid {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.75rem;
    margin: 2rem 0;
}

.quick-nav-grid > * {
    flex: 0 0 calc((100% - 2.25rem) / 4);
    min-width: 0;
}

@media (max-width: 640px) {
    .quick-nav-grid > * { flex-basis: calc((100% - 0.75rem) / 2); }
}

.quick-nav-grid a {
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    /* Altura mínima de dos líneas: todos los botones miden lo mismo tengan una o dos líneas de texto. */
    min-height: 3.6rem;
    line-height: 1.25;
    padding: 0.5rem;
    border-radius: var(--radius);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9rem;
}

/* Paleta pastel alterna (mismos 3 tokens que las badges del carrusel) — el
   original alterna el color de cada pill, no los deja todos iguales. */
.quick-nav-grid a:nth-child(3n+1) { background: var(--color-sky); color: var(--color-teal); }
.quick-nav-grid a:nth-child(3n+2) { background: var(--color-mint); color: var(--color-forest); }
.quick-nav-grid a:nth-child(3n+3) { background: var(--color-cream); color: var(--color-accent-warm); }

.quick-nav-grid a:hover { filter: brightness(0.95); }

.categories-intro {
    text-align: center;
    margin: 2rem 0 -0.5rem;
}

footer.site-footer {
    background: var(--color-surface);
    border-top: 1px solid var(--color-border);
    margin-top: 3rem;
    padding: 2.5rem 1.5rem 1.5rem;
}

.footer-sister-site {
    max-width: var(--max-width);
    margin: 0 auto 2.5rem;
    background: var(--color-sky);
    border-radius: var(--radius);
    padding: 1.25rem 1.5rem;
    display: flex;
    align-items: center;
    gap: 1.5rem;
    flex-wrap: wrap;
}

.footer-sister-logo {
    height: 40px;
    width: auto;
    flex-shrink: 0;
}

.footer-sister-copy { flex: 1 1 320px; }

.footer-sister-eyebrow {
    margin: 0 0 0.2rem;
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 0.85rem;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-teal);
}

.footer-sister-text {
    margin: 0;
    font-size: 0.85rem;
    color: var(--color-text);
}

.footer-sister-cta-block {
    flex-shrink: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.35rem;
}

.footer-sister-cta {
    background: var(--color-accent);
    color: var(--color-surface);
    padding: 0.6rem 1.1rem;
    border-radius: var(--radius);
    text-decoration: none;
    font-weight: 600;
    font-size: 0.9rem;
    white-space: nowrap;
}

.footer-sister-cta:hover { filter: brightness(1.1); }

.footer-sister-cta-hint {
    margin: 0;
    font-size: 0.75rem;
    color: var(--color-text);
    opacity: 0.75;
    text-align: center;
}

@media (max-width: 600px) {
    .footer-sister-site { flex-direction: column; text-align: center; }
    .footer-sister-copy { flex-basis: auto; }
}

.footer-widgets {
    max-width: var(--max-width);
    margin: 0 auto;
    display: grid;
    grid-template-columns: minmax(200px, 260px) minmax(460px, 1fr) minmax(180px, 220px);
    gap: 2.5rem;
}

@media (max-width: 900px) {
    .footer-widgets { grid-template-columns: 1fr; }
}

.footer-widget-about {
    text-align: center;
}

.footer-widget h3 {
    font-family: var(--font-heading);
    font-weight: 700;
    font-size: 1.05rem;
    margin: 0 0 0.6rem;
}

.footer-widget p {
    font-size: 0.88rem;
    margin: 0 0 0.6rem;
}

.footer-logo {
    height: 112px;
    width: auto;
    margin-bottom: 0.75rem;
}

.footer-logo-caption {
    color: #9A9A9A;
    font-size: 0.78rem;
    margin: 0 0 1rem;
}

.footer-widget-divider {
    width: 60px;
    height: 1px;
    margin: 0 auto 1.25rem;
    border: none;
    background: var(--color-border);
}

.footer-contact-prompt a { color: var(--color-accent); }

.footer-gallery {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
    align-content: start;
}

@media (max-width: 560px) {
    .footer-gallery { grid-template-columns: repeat(2, 1fr); }
}

.footer-gallery-item {
    position: relative;
    display: block;
    text-decoration: none;
    border-radius: var(--radius);
    overflow: hidden;
}

.footer-gallery-item img {
    display: block;
    width: 100%;
    height: 170px;
    object-fit: cover;
}

.footer-gallery-caption {
    position: absolute;
    left: 0;
    right: 0;
    bottom: 0;
    padding: 2rem 0.75rem 0.65rem;
    background: linear-gradient(to top, rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0));
    color: #FFFFFF;
    font-family: var(--font-heading);
    font-weight: 600;
    font-size: 0.8rem;
    line-height: 1.25;
}

.footer-gallery-item:hover img { filter: brightness(0.9); }

.footer-legal ul {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
}

.footer-legal a {
    color: var(--color-text);
    font-size: 0.88rem;
    text-decoration: none;
}

.footer-legal a:hover { color: var(--color-accent); }

.footer-credits {
    text-align: center;
    margin-top: 2rem;
    padding-top: 1.5rem;
    border-top: 1px solid var(--color-border);
    color: var(--color-accent-warm);
    font-size: 0.82rem;
}

.footer-credits p { margin: 0.25rem 0; }

/* Showcase sections (home) — replica las ~10 secciones temáticas de eventyrforbarn.com.
   Cabecera (título + intro) centrada como unidad, igual que el carrusel de
   "newest tales" — el contenido de debajo (grid/lista/imagen) sigue su propio
   layout. */
.showcase-section { margin: 2.5rem 0; text-align: center; }
.showcase-section h2 { font-size: 1.95rem; margin-bottom: 0.5rem; }
.showcase-intro { color: var(--color-text); max-width: 65ch; margin: 0 auto 1.25rem; }

.showcase-section .category-grid,
.showcase-section .story-grid,
.showcase-section .showcase-cover,
.showcase-section .showcase-list {
    text-align: left;
}

.showcase-text-image {
    display: block;
    width: 100%;
    max-width: 640px;
    height: auto;
    margin: 1.25rem 0;
    border-radius: var(--radius);
    object-fit: cover;
}

.showcase-divider {
    border: none;
    border-top: 1px solid var(--color-border);
    margin: 2.5rem 0;
}

/* Formato "cita" reutilizable (bloque quote de la plantilla de página de
   WordPress) — sin título, texto en cursiva gris oscuro sobre fondo gris
   claro, a todo el ancho del contenedor. Pensado para reutilizarse en
   cualquier plantilla futura, no solo en esta sección de la home. */
.quote-block {
    background: var(--color-quote-bg);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    padding: 1.75rem 2rem;
}

.quote-block p {
    color: var(--color-quote-text);
    font-style: italic;
    margin: 0 0 1.25rem;
}

.quote-block p:last-child { margin-bottom: 0; }

.quote-block img {
    display: block;
    width: 100%;
    max-width: 640px;
    height: auto;
    margin: 0 auto 1.25rem;
    border-radius: var(--radius);
    object-fit: cover;
}

.showcase-list {
    max-width: 40ch;
    margin: 0 auto;
    padding-left: 1.25rem;
    text-align: left;
}

.showcase-cover {
    background: var(--color-mint);
    border-radius: var(--radius);
    padding: 1.5rem;
    display: flex;
    flex-wrap: wrap;
    justify-content: center;   /* 1-2 tarjetas quedan centradas dentro de la banda */
    gap: 1.5rem;
}

.showcase-cover > * {
    flex: 1 1 220px;
    max-width: 320px;
    min-width: 0;
}

.showcase-image-link {
    display: block;
    max-width: 480px;
    margin: 0 auto;
    text-decoration: none;
    color: var(--color-accent-warm);
    font-weight: 600;
}

.showcase-image-link img {
    width: 100%;
    border-radius: var(--radius);
    display: block;
    margin-bottom: 0.5rem;
}

/* Newest-tales carousel */
.carousel-header { margin-bottom: 1.25rem; text-align: center; }
/* Mismo estilo para el subtítulo de novedades y la línea sobre los botones de categorías (normal, no negrita). */
.carousel-subtitle, .categories-intro { color: var(--color-accent-warm); font-size: 0.9rem; font-weight: 400; }

.carousel-wrapper {
    position: relative;
    display: flex;
    align-items: center;
    gap: 0.5rem;
}

.carousel-track {
    display: flex;
    gap: 1rem;
    overflow-x: auto;
    scroll-snap-type: x mandatory;
    list-style: none;
    margin: 0;
    padding: 0.25rem 0.25rem 0.75rem;
    scrollbar-width: thin;
}

.carousel-track::-webkit-scrollbar { height: 6px; }
.carousel-track::-webkit-scrollbar-track { background: transparent; }
.carousel-track::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 999px; }

.carousel-card {
    position: relative;
    flex: 0 0 240px;
    scroll-snap-align: start;
}

.carousel-card-link {
    display: flex;
    flex-direction: column;
    height: 100%;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
    text-decoration: none;
    color: var(--color-text);
}

.carousel-card-media {
    display: block;
    width: 100%;
    height: 130px;
}

.carousel-card-media img {
    width: 100%;
    height: 130px;
    object-fit: cover;
    display: block;
}

/* Placeholder mientras no hay foto real de la historia — mismo hueco/tamaño
   que la imagen definitiva para que la tarjeta no cambie de forma cuando se
   añadan fotos reales. */
.carousel-card-media-placeholder {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
    font-size: 2.5rem;
}

.carousel-card-body {
    display: flex;
    flex-direction: column;
    gap: 0.35rem;
    padding: 0.75rem 1rem 1rem;
}

.carousel-badge {
    align-self: flex-start;
    font-size: 0.7rem;
    font-weight: 600;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
}

.carousel-card-title {
    font-family: var(--font-heading);
    font-weight: 600;
    color: var(--color-accent-warm);
}

.carousel-card-excerpt {
    font-size: 0.85rem;
    color: var(--color-text);
}

.carousel-arrow {
    flex: 0 0 auto;
    width: 36px;
    height: 36px;
    border-radius: 50%;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    font-size: 1.25rem;
    line-height: 1;
    cursor: pointer;
    color: var(--color-accent-warm);
}

.carousel-arrow:hover { background: var(--color-mint); }

/* Mobile off-canvas menu */
@media (max-width: 860px) {
    /* z-index por encima del overlay de nav-open (200) -- si no, en cuanto el
       menú se abre, su fondo opaco a pantalla completa tapa el propio botón
       de hamburguesa (que se queda en el z-index automático de
       .site-header-top, por debajo) y no queda ninguna forma de volver a
       cerrarlo. Reportado por el usuario: "se te ha olvidado mantener el
       símbolo... para que se pueda plegar de nuevo". */
    .menu-toggle { display: flex; right: 0; z-index: 210; }

    /* El hamburguesa se transforma en una X mientras el menú está abierto --
       mismo icono, doble función (abrir/cerrar), sin añadir un botón nuevo.
       8px = altura de cada línea (3px) + separación (5px, ver .menu-toggle
       gap), la distancia exacta para que las dos líneas exteriores crucen
       por el centro donde estaba la del medio. */
    .menu-toggle span {
        transition: transform 0.2s ease, opacity 0.2s ease;
    }

    body.nav-open .menu-toggle span:nth-child(1) {
        transform: translateY(8px) rotate(45deg);
    }

    body.nav-open .menu-toggle span:nth-child(2) {
        opacity: 0;
    }

    body.nav-open .menu-toggle span:nth-child(3) {
        transform: translateY(-8px) rotate(-45deg);
    }

    .site-header-top { flex: 1 1 100%; }

    nav.primary-nav {
        display: none;
    }

    body.nav-open nav.primary-nav {
        display: block;
        position: fixed;
        inset: 0;
        z-index: 200;
        background: var(--color-surface);
        overflow-y: auto;
        padding: 4rem 1.5rem 2rem;
    }

    /* header.site-header lleva backdrop-filter (efecto cristal esmerilado) --
       eso lo convierte en el "containing block" de cualquier descendiente
       position:fixed (mismo comportamiento que filter/transform/perspective),
       así que nav.primary-nav de arriba (position:fixed;inset:0) quedaba
       encajado dentro de la cajita del header en vez de cubrir la pantalla
       entera: la mayoría del menú quedaba fuera de esa caja, invisible, con
       una barra de scroll intentando alcanzar contenido que nunca se veía.
       Se desactiva el blur solo mientras el menú está abierto (apenas se ve
       el header detrás del overlay a pantalla completa) para que
       nav.primary-nav vuelva a posicionarse contra el viewport real. */
    body.nav-open header.site-header {
        backdrop-filter: none;
        -webkit-backdrop-filter: none;
    }

    ul.primary-menu {
        flex-direction: column;
        align-items: stretch;
        justify-content: center;
    }

    /* ul.primary-menu > li.menu-item es display:flex (fila) + align-items:
       center en la regla base, pensado para alinear un único enlace con su
       badge/icono en el menú horizontal de escritorio. En mobile cada
       li.menu-item pasa a contener DOS cosas apiladas -- el enlace y su
       .submenu completo -- así que sin este cambio a columna, el submenu se
       colocaba en fila AL LADO del enlace padre (empujado fuera de la
       pantalla) en vez de debajo: los hijos "desaparecían" por quedar fuera
       del viewport horizontal, no por un problema de scroll. */
    ul.primary-menu > li.menu-item {
        flex-direction: column;
        align-items: stretch;
    }

    ul.primary-menu .submenu,
    ul.primary-menu .submenu-nested {
        display: block;
        position: static;
        box-shadow: none;
        border: none;
        padding-left: 1rem;
        min-width: 0;
    }

    /* Los enlaces del menú llevan white-space:nowrap pensado para el
       desplegable de escritorio (ancho fijo, nunca se envuelve). En mobile,
       con la pantalla mucho más estrecha, las etiquetas largas (sobre todo
       en .submenu-nested, ya indentado) no cababan y nav.primary-nav (que
       tiene overflow-y:auto) heredaba también overflow-x:auto por la regla
       CSS "un eje visible + un eje con scroll = el visible pasa a auto":
       aparecía una barra de scroll horizontal propia del menú, con el texto
       cortado detrás. */
    ul.primary-menu > li.menu-item > a,
    ul.primary-menu .submenu a {
        white-space: normal;
    }
}

.story-grid-empty { text-align: center; }

/* Fotos dentro de las páginas estáticas: siempre centradas. */
article.page .body figure {
    margin: 1.25rem auto;
    text-align: center;
}

article.page .body figure img {
    display: block;
    margin: 0 auto;
    max-width: 100%;
    height: auto;
    border-radius: var(--radius);
}

/* Franja de campaña estacional (Halloween, Navidad…) — home y landing /no/, ver Content\HomeCampaigns.
   Solo variables de tema: el modo oscuro se hereda de dark-mode.css. */
.campaign-band {
    background: var(--color-gold-tint);
    border: 2px solid var(--color-logo-orange);
    border-radius: var(--radius);
    padding: 1.25rem 1.25rem 1.5rem;
    margin: 2rem 0;
    text-align: center;
}
.campaign-band--christmas { border-color: var(--color-forest); }
.campaign-band h2 { margin-top: 0; }
.campaign-band .story-grid { margin: 1.25rem 0; text-align: left; }
.campaign-cta { margin: 0; }
.campaign-button {
    display: inline-block;
    font-size: 0.85rem;
    padding: 0.4rem 1rem;
    border-radius: 999px;
    background: var(--color-accent);
    color: var(--color-surface);
    font-weight: 600;
    text-decoration: none;
}
.campaign-button:hover { filter: brightness(1.1); }

.more-stories { margin: 0 0 1.25rem; }
.more-stories summary {
    display: inline-block;
    cursor: pointer;
    font-size: 0.85rem;
    padding: 0.35rem 1rem;
    border: 2px solid var(--color-accent);
    border-radius: 999px;
    color: var(--color-accent);
    font-weight: 600;
    list-style: none;
}
.more-stories summary::-webkit-details-marker { display: none; }
.more-stories summary::after { content: " ▾"; }
.more-stories[open] summary::after { content: " ▴"; }
.more-stories .story-grid { margin-top: 1.25rem; }

.campaign-latest { margin: 1.25rem 0 0; }

/* Línea de meta de las tarjetas (Ui::storyCardWithMeta): tiempo de lectura y edad. Compartida por todos los idiomas;
   alineada con el título/extracto (mismo padding lateral). La edad va más pequeña y en otro color. */
.story-card-meta {
    display: block;
    padding: 0 1rem 0.5rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--color-accent);
    text-align: left;
}
.story-card-age {
    font-size: 0.65rem;
    color: var(--color-card-age);
}
.story-card-link, .story-card-title, .story-card-excerpt { text-align: left; }
.more-stories .story-grid { text-align: left; }

.more-stories { text-align: center; margin: 1.25rem 0 0; }

/* Título de las tarjetas de categoría: centrado y con alto fijo de dos líneas, para que todas midan lo mismo
   tengan una o dos líneas de texto (antes crecían al saltar de línea). */
.category-card-title {
    box-sizing: content-box;
    display: flex;
    align-items: center;
    justify-content: center;
    text-align: center;
    min-height: 2.6em;
    line-height: 1.3;
    padding: 0.5rem 1rem;
}

/* Separación entre el desplegable y el botón final de la franja de campaña. */
.campaign-band .more-stories { margin: 1.25rem 0 1.75rem; }
.campaign-band .campaign-cta { margin-top: 0; }
.campaign-button:hover { color: var(--color-surface); }

/* Banderas de idioma como imagen (Ui::flag) — los emoji de bandera no se pintan en Windows. */
.lang-flag {
    display: inline-block;
    width: 20px;
    height: 15px;
    vertical-align: -2px;
    border-radius: 2px;
    box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15);
    object-fit: cover;
}

/* Selector de idioma flotante (partials/lang-float.php, assets/js/lang-float.js): fade-in arriba a la derecha al hacer scroll. */
.lang-float {
    position: fixed;
    top: 0.75rem;
    right: 1rem;
    z-index: 500;
    opacity: 0;
    visibility: hidden;
    transform: translateY(-0.4rem);
    transition: opacity 0.3s ease, transform 0.3s ease, visibility 0.3s;
}

.lang-float.is-visible {
    opacity: 1;
    visibility: visible;
    transform: translateY(0);
}

.lang-float-toggle {
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.4rem 0.75rem;
    border: 1px solid var(--color-border);
    border-radius: 999px;
    background: var(--color-surface);
    color: var(--color-text);
    font-family: inherit;
    font-size: 0.95rem;
    cursor: pointer;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

.lang-float-toggle:hover { color: var(--color-accent); }

.lang-float-list {
    position: absolute;
    top: calc(100% + 0.4rem);
    right: 0;
    min-width: 11rem;
    margin: 0;
    padding: 0.35rem 0;
    list-style: none;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}

.lang-float-list[hidden] { display: none; }

.lang-float-list li { color: var(--color-text); }
.lang-float-list li.is-preview { opacity: 0.6; }
.lang-float-list li.is-current > span { font-weight: 600; color: var(--color-accent-warm); }

.lang-float-list a,
.lang-float-list li > span {
    display: block;
    padding: 0.45rem 1rem;
    color: inherit;
    text-decoration: none;
    white-space: nowrap;
}

.lang-float-list a:hover { color: var(--color-accent); }

/* Tarjeta de categoría sin portada (futuras categorías por país/autor aún sin imagen): bloque neutro, no una tarjeta vacía. */
.category-card--no-image {
    min-height: 140px;
    justify-content: center;
    background: var(--color-sky);
}
