/*
 * Cazador App — design system (tweed / English country).
 * Soporta light + dark mode vía [data-bs-theme].
 * Tokens canónicos en /Users/.../memory/project_design_system.md
 */

:root,
[data-bs-theme="light"] {
    /* Neutros */
    --canvas: #f5efe1;
    --surface: #ebe2cf;
    --surface-soft: #faf5e8;
    --ink: #1f2419;
    --charcoal: #2c2c24;
    --steel: #544f43;
    --stone: #8b8472;
    --muted: #756f61;
    --hairline: #d4c9b0;
    --hairline-soft: #e6dec7;
    --hairline-strong: #b8ac90;

    /* Acentos */
    --mustard: #c9a227;
    --mustard-deep: #a17a14;
    --mustard-soft: #ebd587;
    --moss: #4a5d3a;
    --moss-soft: #c2cfae;
    --oxblood: #7b2d2d;
    --oxblood-soft: #c79e9e;
    --heather: #867591;
    --heather-soft: #d6cce0;
    --tan: #a0825c;
    --tan-soft: #e2cfb1;
    --rose: #b88a8a;
    --rose-soft: #e8d0d0;
    --sky: #6f8294;
    --sky-soft: #c8d2dc;

    /* Sombras (tinte forest) */
    --shadow-sm: rgba(31, 36, 25, 0.04) 0 1px 2px;
    --shadow-md: rgba(31, 36, 25, 0.06) 0 4px 12px;
    --shadow-lg: rgba(31, 36, 25, 0.08) 0 12px 32px -4px;

    /* Bootstrap overrides */
    --bs-body-font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    --bs-body-font-size: 1.0625rem; /* 17px (base un poco más generosa) */
    --bs-body-line-height: 1.55;
    --bs-body-color: var(--ink);
    --bs-body-bg: var(--canvas);
    --bs-secondary-color: var(--steel);
    --bs-border-color: var(--hairline);
    --bs-border-color-translucent: var(--hairline-soft);
    --bs-link-color: var(--ink);
    --bs-link-hover-color: var(--mustard-deep);
}

[data-bs-theme="dark"] {
    --canvas: #1a1d17;
    --surface: #22251e;
    --surface-soft: #2a2d25;
    --ink: #ede4cd;
    --charcoal: #d4c9b0;
    --steel: #a59c89;
    --stone: #8b8472;
    --muted: #9c937c;
    --hairline: #3a3d34;
    --hairline-soft: #2e3128;
    --hairline-strong: #4d5042;

    --mustard: #d4a425;
    --mustard-deep: #b88c1a;
    --mustard-soft: #7a601a;
    --moss: #8aa074;
    --moss-soft: #3a4a2e;
    --oxblood: #b56262;
    --oxblood-soft: #5a2020;
    --heather: #b3a3be;
    --heather-soft: #48405c;
    --tan: #c5a47c;
    --tan-soft: #5a4730;
    --rose: #d6a8a8;
    --rose-soft: #6b3f3f;
    --sky: #a8b8c4;
    --sky-soft: #384452;

    --shadow-sm: rgba(0, 0, 0, 0.2) 0 1px 2px;
    --shadow-md: rgba(0, 0, 0, 0.3) 0 4px 12px;
    --shadow-lg: rgba(0, 0, 0, 0.45) 0 12px 32px -4px;

    --bs-body-color: var(--ink);
    --bs-body-bg: var(--canvas);
    --bs-secondary-color: var(--steel);
    --bs-border-color: var(--hairline);
    --bs-link-color: var(--ink);
    --bs-link-hover-color: var(--mustard);
}

body {
    font-family: var(--bs-body-font-family);
    font-size: 17px;
    line-height: 1.55;
    color: var(--ink);
    background: var(--canvas);
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    transition: background-color 200ms ease, color 200ms ease;
}

h1, h2, h3, h4, h5, h6,
.section-title {
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--ink);
    line-height: 1.15;
}

.text-steel {
    color: var(--steel) !important;
}

.text-ink {
    color: var(--ink) !important;
}

.text-mustard {
    color: var(--mustard) !important;
}

.text-moss {
    color: var(--moss) !important;
}

.text-oxblood {
    color: var(--oxblood) !important;
}

/* ---------- Promo banner ---------- */
.promo-banner {
    background: var(--ink);
    color: var(--canvas);
    text-align: center;
    padding: 8px 16px;
    font-size: 15px;
    font-weight: 500;
    display: flex;
    justify-content: center;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}
/* Shell vacío hidratado por JS desde /api/promo: ocultar mientras
   no haya match (visitante fuera de España o sin curso para su CCAA). */
.promo-banner:empty {
    display: none;
}

.promo-banner .promo-pill {
    background: var(--mustard);
    color: #1f2419;
    padding: 4px 10px;
    border-radius: 9999px;
    font-size: 13px;
    font-weight: 600;
}

/* ---------- Navbar ---------- */
.app-navbar {
    background: var(--canvas);
    border-bottom: 1px solid var(--hairline-soft);
    padding-top: 0.75rem;
    padding-bottom: 0.75rem;
}

.app-navbar .navbar-brand {
    font-weight: 600;
    font-size: 1.15rem; /* ~19.5px */
    color: var(--ink);
    letter-spacing: -0.01em;
    display: inline-flex;
    align-items: center;
    gap: 8px;
}

.app-navbar .navbar-brand .brand-mark {
    background: var(--mustard);
    color: #1f2419;
    border-radius: 6px;
    padding: 2px 8px;
    font-weight: 700;
    font-size: 1.05rem; /* ~17.85px */
}

.app-navbar .nav-link {
    color: var(--charcoal) !important;
    font-size: 16px;
    font-weight: 500;
    padding: 0.4rem 0.85rem;
}

.app-navbar .nav-link:hover {
    color: var(--ink) !important;
}

.app-navbar .navbar-toggler {
    border-color: var(--hairline);
}

/* ---------- Theme toggle ---------- */
.theme-toggle {
    background: transparent;
    border: 1px solid var(--hairline-strong);
    color: var(--ink);
    /* WCAG 2.5.5 touch target ≥ 44×44. Icon visual size stays 16px via the
       inner <i>; the box itself is the click area. */
    min-width: 44px;
    min-height: 44px;
    border-radius: 9999px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    cursor: pointer;
    transition: background-color 150ms ease;
}

.theme-toggle:hover {
    background: var(--surface);
}

.theme-toggle .icon-light {
    display: inline-flex;
}

.theme-toggle .icon-dark {
    display: none;
}

[data-bs-theme="dark"] .theme-toggle .icon-light {
    display: none;
}

[data-bs-theme="dark"] .theme-toggle .icon-dark {
    display: inline-flex;
}

/* ---------- Buttons (pill) ---------- */
.btn-pill {
    border-radius: 9999px;
    padding: 0.7rem 1.4rem;
    font-weight: 500;
    font-size: 16px;
    border: none;
    line-height: 1.2;
    transition: transform 120ms ease, background-color 120ms ease, color 120ms ease;
}

.btn-pill:hover {
    transform: translateY(-1px);
}

.btn-ink {
    background: var(--ink);
    color: var(--canvas);
}

.btn-ink:hover, .btn-ink:focus {
    background: var(--charcoal);
    color: var(--canvas);
}

.btn-mustard {
    /* Variante warm que cumple WCAG 2.1 AA en todos los planos:
       - Fondo crema #fff5d4 + texto var(--ink) → ~14.5:1 (AAA).
       - Borde var(--mustard-deep) #a17a14 → 3.45:1 contra canvas y
         3.96:1 contra el propio fondo del botón (>3:1, 1.4.11 OK).
       Visualmente sigue dentro de la gama mustard — sólo un tono más
       profundo que el --mustard puro, manteniendo la identidad warm. */
    background: #fff5d4;
    color: var(--ink);
    border: 1.5px solid var(--mustard-deep);
}

.btn-mustard:hover, .btn-mustard:focus {
    background: var(--mustard-soft);
    color: var(--ink);
    border-color: var(--mustard-deep);
}

.btn-mustard:focus-visible {
    /* Anillo de foco accesible (≥3:1 contra cualquier fondo claro). */
    outline: 3px solid var(--ink);
    outline-offset: 2px;
}

[data-bs-theme="dark"] .btn-mustard {
    background: var(--surface-soft);
    color: var(--ink);
    border-color: var(--mustard);
}
[data-bs-theme="dark"] .btn-mustard:hover,
[data-bs-theme="dark"] .btn-mustard:focus {
    background: var(--mustard-soft);
    color: var(--ink);
    border-color: var(--mustard-deep);
}

.btn-outline-ink {
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--hairline-strong);
}

.btn-outline-ink:hover {
    background: var(--surface);
    color: var(--ink);
}

.btn-outline-on-dark {
    background: transparent;
    color: #f5efe1;
    border: 1px solid rgba(245, 239, 225, 0.35);
}

.btn-outline-on-dark:hover {
    background: rgba(245, 239, 225, 0.08);
    color: #f5efe1;
}

.btn-link-ink {
    background: transparent;
    color: var(--mustard-deep);
    border: none;
    font-weight: 500;
    font-size: 15px;
    padding: 0;
    text-decoration: none;
}

.btn-link-ink:hover {
    text-decoration: underline;
}

/* ---------- Cards ---------- */
/* card-soft is deliberately HIGH-CONTRAST against the tinted page background:
   - light mode: pure white on cream → strong elevation read.
   - dark mode: visibly lighter than canvas → cards stand out from the page.
   Both layers carry a small shadow so the elevation works even when the card
   sits against a same-colored section background (e.g. /precios block). */
.card-soft {
    background: #ffffff;
    border: 1px solid var(--hairline-soft);
    border-radius: 16px;
    padding: 1.5rem;
    color: var(--ink);
    box-shadow: 0 1px 2px rgba(31, 36, 25, 0.04),
    0 4px 12px rgba(31, 36, 25, 0.04);
}

[data-bs-theme="dark"] .card-soft {
    background: #2f3329;
    border-color: rgba(255, 255, 255, 0.06);
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.4),
    0 6px 18px rgba(0, 0, 0, 0.25);
}

.card-pastel {
    border: none;
    border-radius: 28px;
    padding: 2rem;
    min-height: 260px;
    color: #1f2419;
    display: flex;
    flex-direction: column;
    justify-content: space-between;
    position: relative;
    transition: transform 180ms ease, box-shadow 180ms ease;
}

.card-pastel:hover {
    transform: translateY(-4px);
    box-shadow: var(--shadow-lg);
}

/* Non-interactive variant (informational tiles, e.g. home stats): kill
   the hover transform so we don't promise an interaction that isn't
   there. Mark with class .card-pastel--static or with role="group". */
.card-pastel--static:hover,
.card-pastel[role="group"]:hover {
    transform: none;
    box-shadow: none;
    cursor: default;
}

.card-pastel a.stretched-link {
    color: inherit;
}

.card-pastel h3 {
    font-size: 24px;
    font-weight: 500;
    line-height: 1.2;
    letter-spacing: -0.3px;
    color: inherit;
}

.card-pastel p {
    font-size: 16px;
    opacity: 0.95;
    margin: 0;
    line-height: 1.5;
}

/* En dark mode, los pastel cards quedan oscuros y el texto pasa a cream */
[data-bs-theme="dark"] .card-pastel {
    color: #ede4cd;
}

.bg-pastel-mustard {
    background: var(--mustard-soft);
}

.bg-pastel-moss {
    background: var(--moss-soft);
}

.bg-pastel-heather {
    background: var(--heather-soft);
}

.bg-pastel-tan {
    background: var(--tan-soft);
}

.bg-pastel-rose {
    background: var(--rose-soft);
}

.bg-pastel-sky {
    background: var(--sky-soft);
}

/* ---------- Sticky note (mnemotecnia) ---------- */
.sticky-note {
    background: var(--mustard-soft);
    color: #1f2419;
    border-radius: 8px;
    padding: 1.1rem 1.35rem;
    box-shadow: var(--shadow-sm);
    font-size: 16px;
    line-height: 1.5;
}

.sticky-note .label {
    font-size: 12px;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    font-weight: 700;
    color: var(--mustard-deep);
    display: block;
    margin-bottom: 4px;
}

[data-bs-theme="dark"] .sticky-note {
    background: var(--mustard-soft);
    color: #ede4cd;
}

[data-bs-theme="dark"] .sticky-note .label {
    color: var(--mustard);
}

/* ---------- Sections / heroes ---------- */
section.section {
    padding: 4.5rem 0;
}

@media (max-width: 768px) {
    section.section {
        padding: 2.5rem 0;
    }
}

.hero-light {
    background: var(--surface-soft);
    padding: 4rem 0;
    border-bottom: 1px solid var(--hairline-soft);
}

.hero-light h1 {
    font-size: clamp(2.25rem, 4.4vw, 4.5rem);
    font-weight: 500;
    line-height: 1.05;
    letter-spacing: -0.02em;
    color: var(--ink);
    max-width: 900px;
}

.hero-light .lead {
    font-size: 20px;
    line-height: 1.55;
    color: var(--steel);
    max-width: 680px;
    margin-top: 1.25rem;
}

.hero-light .breadcrumb a {
    color: var(--steel);
    text-decoration: none;
}

.hero-light .breadcrumb a:hover {
    color: var(--mustard-deep);
}

.hero-light .breadcrumb .breadcrumb-item.active {
    color: var(--muted);
}

/* "Dark island" hero — same pattern as the footer: a constant dark block in
   both themes, so cream-translucent breadcrumb / lead / badges stay readable.
   Using --ink / --canvas here would invert the bg+text in dark mode and the
   cream-on-cream content (breadcrumb links, outline buttons, badges) would
   vanish. Hardcoded values keep the contract. */
.hero-dark {
    background: #1f2419;
    color: rgba(245, 239, 225, 0.92);
    padding: 4rem 0;
}

@media (max-width: 768px) {
    .hero-dark {
        padding: 3rem 0;
    }
}

[data-bs-theme="dark"] .hero-dark {
    background: #242821; /* a touch lighter than dark canvas (#1a1d17) for separation */
    border-bottom: 1px solid rgba(255, 255, 255, 0.06);
}

.hero-dark h1 {
    color: rgba(245, 239, 225, 0.96);
}

.hero-dark .lead {
    color: rgba(245, 239, 225, 0.85);
    max-width: 680px;
    font-size: 20px;
    line-height: 1.55;
}

.hero-dark .breadcrumb a {
    color: rgba(245, 239, 225, 0.72);
    text-decoration: none;
}

.hero-dark .breadcrumb a:hover {
    color: var(--mustard);
}

.hero-dark .breadcrumb .breadcrumb-item.active {
    color: rgba(245, 239, 225, 0.55);
}

.hero-dark .breadcrumb-item + .breadcrumb-item::before {
    color: rgba(245, 239, 225, 0.4);
}

/* ---------- Badges (pill) ---------- */
.badge-soft {
    display: inline-block;
    padding: 4px 11px;
    border-radius: 9999px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.4;
}

.badge-mustard {
    background: var(--mustard-soft);
    color: var(--mustard-deep);
}

.badge-moss {
    background: var(--moss-soft);
    color: var(--moss);
}

.badge-heather {
    background: var(--heather-soft);
    color: var(--heather);
}

.badge-tan {
    background: var(--tan-soft);
    color: #6b4423;
}

.badge-rose {
    background: var(--rose-soft);
    color: var(--oxblood);
}

.badge-sky {
    background: var(--sky-soft);
    color: var(--sky);
}

.badge-ink {
    background: var(--ink);
    color: var(--canvas);
}

.badge-outline {
    background: transparent;
    color: var(--ink);
    border: 1px solid var(--hairline-strong);
}

[data-bs-theme="dark"] .badge-mustard,
[data-bs-theme="dark"] .badge-moss,
[data-bs-theme="dark"] .badge-heather,
[data-bs-theme="dark"] .badge-tan,
[data-bs-theme="dark"] .badge-rose,
[data-bs-theme="dark"] .badge-sky {
    color: #ede4cd;
}

/* ---------- Progress ---------- */
.progress.progress-thin {
    height: 4px;
    background: var(--hairline-soft);
    border-radius: 9999px;
    overflow: hidden;
}

.progress.progress-thin .progress-bar {
    background: var(--mustard);
}

/* ---------- Markdown body (lecciones) ---------- */
.lesson-body {
    font-size: 17px;
    line-height: 1.7;
    color: var(--ink);
}

.lesson-body h1,
.lesson-body h2,
.lesson-body h3,
.lesson-body h4 {
    font-weight: 500;
    letter-spacing: -0.01em;
    color: var(--ink);
    margin-top: 2.25rem;
    margin-bottom: 0.75rem;
    line-height: 1.2;
}

.lesson-body h1 {
    font-size: 2rem;
}

/* The lesson's title is already rendered by the page hero. The markdown body
   keeps its leading `# Title` for editorial readability of the .md file, but
   in the rendered page we hide it to avoid duplication. */
.lesson-body > h1:first-child {
    display: none;
}

.lesson-body h2 {
    font-size: 1.55rem;
    padding-bottom: 0.4rem;
    border-bottom: 1px solid var(--hairline-soft);
}

.lesson-body h3 {
    font-size: 1.25rem;
}

.lesson-body h4 {
    font-size: 1.1rem;
}

.lesson-body p {
    margin-bottom: 1.1rem;
}

.lesson-body ul,
.lesson-body ol {
    margin-bottom: 1.1rem;
    padding-left: 1.4rem;
}

.lesson-body li {
    margin-bottom: 0.3rem;
}

.lesson-body strong {
    font-weight: 600;
}

.lesson-body code {
    background: var(--surface);
    padding: 0.1rem 0.35rem;
    border-radius: 4px;
    font-size: 0.92em;
    font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
}

.lesson-body pre {
    background: var(--surface);
    padding: 1rem 1.25rem;
    border-radius: 10px;
    overflow-x: auto;
    margin-bottom: 1.1rem;
}

.lesson-body pre code {
    background: transparent;
    padding: 0;
    border-radius: 0;
}

.lesson-body blockquote {
    border-left: 3px solid var(--mustard);
    padding: 0.4rem 1.1rem;
    margin: 1.25rem 0;
    color: var(--steel);
    font-style: italic;
}

.lesson-body a {
    color: var(--mustard-deep);
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
}

.lesson-body a:hover {
    color: var(--mustard);
}

.lesson-body table {
    width: 100%;
    margin-bottom: 1.25rem;
    border-collapse: collapse;
    font-size: 16px;
}

.lesson-body th,
.lesson-body td {
    padding: 0.6rem 0.9rem;
    border-bottom: 1px solid var(--hairline-soft);
    text-align: left;
}

.lesson-body th {
    font-weight: 600;
    background: var(--surface);
}

.lesson-body hr {
    border: 0;
    border-top: 1px solid var(--hairline);
    margin: 2rem 0;
}

/* ---------- Accordion (FAQ) ---------- */
.accordion-flush .accordion-button {
    background: transparent;
    color: var(--ink);
    font-weight: 500;
    padding: 1.1rem 0;
    box-shadow: none !important;
}

.accordion-flush .accordion-button:not(.collapsed) {
    background: transparent;
    color: var(--mustard-deep);
}

.accordion-flush .accordion-item {
    background: transparent;
    border: 0;
    border-bottom: 1px solid var(--hairline-soft);
}

.accordion-flush .accordion-button::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%231f2419'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

[data-bs-theme="dark"] .accordion-flush .accordion-button::after {
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='%23ede4cd'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e");
}

.accordion-body {
    padding: 0 0 1.1rem;
}

/* ---------- Footer ----------
   "Dark island" — same dark-forest background in light AND dark mode. We don't
   use the theme-aware --ink/--canvas tokens here because they invert in dark
   mode (background would become cream, text dark → invisible). The footer is
   intentionally branded and constant; only its top border bumps slightly so it
   reads as a separate block when the page is already dark.                  */
.app-footer {
    background: #1f2419;
    color: rgba(245, 239, 225, 0.92);
    padding: 4rem 0 2rem;
}

[data-bs-theme="dark"] .app-footer {
    /* Page is also dark (#1a1d17); a thin top hairline + a touch lighter bg
       give the footer its own visual lane. */
    background: #242821;
    border-top: 1px solid rgba(255, 255, 255, 0.06);
}

.app-footer a {
    color: rgba(245, 239, 225, 0.78);
    text-decoration: none;
}

.app-footer a:hover {
    color: var(--mustard);
}

.app-footer .wordmark {
    display: inline-block;
    background: var(--mustard);
    color: #1f2419;
    font-weight: 700;
    border-radius: 6px;
    padding: 4px 10px;
}

.app-footer .footer-credit {
    border-top: 1px solid rgba(245, 239, 225, 0.1);
    padding-top: 1.5rem;
    margin-top: 2rem;
    color: rgba(245, 239, 225, 0.7);
    font-size: 13px;
}

/* ── Área de estudio: audio del bloque sticky-within-details ──────────
   Cada <details> contiene su propio reproductor. position: sticky lo
   pega al borde superior del viewport (debajo del navbar) mientras
   el scroll sigue dentro del bloque. Como el contenedor sticky es
   el propio <details>, cuando el scroll lo deja atrás el reproductor
   sale con su contenedor — y el del siguiente bloque toma el relevo
   (efecto "header swap" tipo Instagram). Sin JS.

   El navbar mide ~64 px; sumamos 8 px de respiración. En móvil bajamos
   un pelín porque el header del navbar también lo hace. */
.block-audio-sticky {
    position: sticky;
    top: 72px;
    z-index: 5;
    background: var(--canvas);
    /* full-bleed dentro del details: el padding lateral compensa el
       margin negativo que iguala el padding del card-soft (1.5rem). */
    padding: 0.65rem 1.5rem;
    margin: 0 -1.5rem 1rem;
    border-top: 1px solid var(--hairline-soft);
    border-bottom: 1px solid var(--hairline-soft);
    box-shadow: 0 2px 8px rgba(31, 36, 25, 0.04);
}
[data-bs-theme="dark"] .block-audio-sticky {
    background: #2f3329;
    border-color: rgba(255, 255, 255, 0.08);
}
@media (max-width: 767.98px) {
    .block-audio-sticky {
        top: 60px;
        /* En móvil el card-soft tiene padding 1rem 0.85rem, así que
           el margin negativo iguala 0.85rem. */
        margin: 0 -0.85rem 0.75rem;
        padding: 0.55rem 0.85rem;
    }
}

/* ── /account: lista de cursos matriculados en una sola columna ────────
   - card-soft con padding reducido para que la lista se lea como tabla.
   - En desktop: nombre/descripción/progreso a la izquierda; tags y
     botones alineados a la derecha (column align-items-end).
   - En móvil: stack vertical, tags y botones por debajo. */
.enrolled-list .enrolled-row {
    padding: 1.1rem 1.25rem;
}
.enrolled-list .enrolled-row .enrolled-desc {
    /* Truncar descripciones largas a 2 líneas — la lista debe escanearse
       de arriba abajo, no leerse linealmente. */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}
@media (max-width: 767.98px) {
    .enrolled-list .enrolled-row {
        padding: 0.9rem 1rem;
    }
}

/* ── Truncado por el medio para enlaces largos del footer ──────────────
   Cuando "Examen de caza en la Comunidad Foral de Navarra" no cabe en
   la columna, queremos cortarlo POR EL MEDIO ("Examen de caza…de
   Navarra"), no por el final, para preservar la CCAA al final.

   Técnica: dos spans dentro del `<a>` con `display: inline-flex`.
   El head recibe `flex: 0 1 auto` + ellipsis y se encoge cuando hace
   falta. El tail tiene `flex: none` y se mantiene siempre completo.
   Cuando la columna es ancha (hay espacio para todo el texto), se
   ve la frase entera sin ellipsis. */
.trunc-middle {
    display: inline-flex;
    max-width: 100%;
    min-width: 0;
    vertical-align: bottom;
}
.trunc-middle .trunc-head {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.trunc-middle .trunc-tail {
    flex: none;
    white-space: nowrap;
}

/* ── Tabs de /account: altura mínima del panel ─────────────────────────
   Sin esto, las pestañas con pocas filas (Pagos vacío, Perfil corto)
   colapsan a 100-150 px y el footer "salta" hacia arriba cuando
   cambias de pestaña. 30vh evita el salto manteniendo el contenido
   centrado verticalmente cuando es corto. */
.tab-content {
    min-height: 30vh;
}

/* ── Presentación especial de receta en /study/{course}/lessons/{slug} ─
   Layout dedicado cuando la lección tiene `ingredients_json` +
   `instructions_json` en frontmatter. Hero con foto, stats en grid,
   ingredientes (sticky en >=lg) + pasos anchos, y print-CSS que
   esconde chrome para llevarse la receta a la cocina. */
.recipe-mode .recipe-hero {
    background: var(--surface-soft);
    position: relative;
}
.recipe-mode .recipe-hero-img {
    aspect-ratio: 21 / 9;
    overflow: hidden;
}
.recipe-mode .recipe-hero-body {
    padding: 1.25rem 1.5rem;
}
.recipe-mode .recipe-stat {
    padding: 1rem 0.5rem;
    background: var(--canvas);
}
[data-bs-theme="dark"] .recipe-mode .recipe-stat {
    background: var(--canvas);
}
@media (min-width: 992px) {
    .recipe-mode .recipe-ingredients .card-soft {
        position: sticky;
        top: 80px;
    }
}
.recipe-mode .recipe-step {
    align-items: flex-start;
}
.recipe-mode .recipe-step:last-child {
    margin-bottom: 0;
}
.recipe-mode .recipe-step-num {
    font-size: 14px;
}

/* Print: la receta se imprime sin navegación ni sidebar, sólo el
   contenido relevante (hero + stats + ingredientes + pasos). El
   botón de imprimir, el quiz, las referencias legales, etc. quedan
   ocultos. Sin colores de fondo para ahorrar tinta. */
@media print {
    body { background: #fff !important; color: #000 !important; }
    .app-navbar, .app-footer,
    nav[aria-label="breadcrumb"],
    .recipe-print-btn,
    .lesson-block-audio, .block-audio-sticky,
    .lesson-nav, .lesson-quiz, .lesson-refs,
    .premium-locked, .card-soft.mt-4 {
        display: none !important;
    }
    .recipe-mode .recipe-hero-img { max-height: 300px; }
    .recipe-mode .recipe-stat,
    .recipe-mode .recipe-ingredients .card-soft {
        background: #fff !important;
        border: 1px solid #ccc !important;
        box-shadow: none !important;
        page-break-inside: avoid;
    }
    .recipe-mode .recipe-step-num {
        background: #f3f3f3 !important;
        color: #000 !important;
    }
    .recipe-mode .recipe-ingredients .card-soft {
        position: static !important;
    }
    .recipe-mode .recipe-step {
        page-break-inside: avoid;
    }
    .recipe-notes {
        page-break-before: always;
    }
}

/* ── Tarjeta de pregunta de muestra en /cursos/{slug} ──────────────────
   Va dentro de una `.section` con background `--surface-soft`. Queremos
   contraste claro: blanco puro en light theme (pop sobre cream), y el
   canvas oscuro en dark theme — porque si dejásemos `white` hardcoded,
   el texto `--ink` (que en dark es crema-claro) quedaría sobre fondo
   blanco y se haría invisible. */
.sample-question-card {
    background: #ffffff;
}
[data-bs-theme="dark"] .sample-question-card {
    background: var(--canvas);
    border-color: var(--hairline);
}

/* ── Lección: audio del bloque sticky en el cuerpo del artículo ────────
   Mismo principio que .block-audio-sticky pero como bloque "flotado"
   dentro de <article>, no full-bleed. Acompaña la lectura sin tapar
   contenido. */
.lesson-block-audio {
    position: sticky;
    /* En >=md el navbar deja 62 px de margen útil. A 72 px el borde
       redondeado superior del bloque quedaba justo por debajo del
       navbar y se "comía" la curvatura. 62 px lo deja completamente
       visible. La media-query de móvil más abajo lo ajusta a 60 px. */
    top: 62px;
    z-index: 4;
    background: var(--canvas);
    padding: 0.7rem 0.9rem;
    border-radius: 10px;
    border: 1px solid var(--hairline-soft);
    box-shadow: 0 2px 8px rgba(31, 36, 25, 0.04);
}
[data-bs-theme="dark"] .lesson-block-audio {
    background: #2f3329;
    border-color: rgba(255, 255, 255, 0.08);
}
@media (max-width: 767.98px) {
    .lesson-block-audio {
        top: 60px;
        padding: 0.6rem 0.8rem;
    }
    .lesson-block-audio p:last-child {
        display: none; /* "Repasa el bloque entero…" — fuera en móvil */
    }
}

/* ── Área de estudio: hero compacto ──────────────────────────────────── */
.hero-dark.study-hero {
    padding: 3.5rem 0 2.5rem;
}
@media (max-width: 767.98px) {
    .hero-dark.study-hero {
        padding: 2rem 0 1.5rem;
    }
    .hero-dark.study-hero h1 {
        font-size: 1.5rem !important;
    }
    .hero-dark.study-hero .lead {
        font-size: 0.95rem;
    }
}

/* ── Área de estudio: filas de lección en /study/{slug} ─────────────── */
.study-lesson-row {
    padding: 0.6rem 0.75rem;
    border-radius: 8px;
    transition: background 0.12s;
    color: inherit;
}

.study-lesson-row:hover {
    background: var(--surface);
}

.study-lesson-mark {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    font-size: 18px;
    color: var(--hairline);
}

.study-lesson-row.is-visited .study-lesson-mark {
    color: var(--moss);
}

.study-lesson-row.is-current {
    background: var(--mustard-soft);
}

.study-lesson-row.is-current .study-lesson-mark {
    color: var(--mustard);
}

.study-lesson-row.is-current .text-ink {
    font-weight: 600;
}

/* Móvil: compacta el dashboard de estudio.
   - card-soft pierde padding lateral para ganar superficie.
   - is-current se sangra negativamente para llegar de borde a borde
     del card (full-bleed), reforzando visualmente la lección activa
     sin desperdiciar margen.
   - El resto de filas se quedan flush con el contenido del card
     (padding-x = 0 propio del row + padding del card como respiración). */
@media (max-width: 767.98px) {
    details.card-soft {
        padding: 1rem 0.85rem;
    }
    .study-lesson-row {
        padding: 0.55rem 0;
        border-radius: 6px;
    }
    .study-lesson-row.is-current {
        /* margen negativo igual al padding lateral del card-soft */
        margin-left: -0.85rem;
        margin-right: -0.85rem;
        padding-left: 0.85rem;
        padding-right: 0.85rem;
        border-radius: 0;
    }
}

/* details > summary marker reset (queremos chevron propio) */
details.card-soft > summary::-webkit-details-marker {
    display: none;
}

details.card-soft > summary {
    list-style: none;
}

details.card-soft[open] > summary .bi-chevron-down {
    transform: rotate(180deg);
}

details.card-soft > summary .bi-chevron-down {
    transition: transform 0.15s;
}

/* ── Landing: bloques expandibles del temario ────────────────────────── */
.landing-block > summary::-webkit-details-marker {
    display: none;
}

.landing-block > summary {
    list-style: none;
}

.landing-block > summary .landing-block-chevron {
    transition: transform 0.15s ease-out;
}

.landing-block[open] > summary .landing-block-chevron {
    transform: rotate(180deg);
}

/* ── Landing: preguntas de ejemplo desplegables al final del bloque ─── */
.landing-sample-q > summary::-webkit-details-marker {
    display: none;
}

.landing-sample-q > summary {
    list-style: none;
}

.landing-sample-q > summary .landing-sample-chevron {
    transition: transform 0.15s ease-out;
}

.landing-sample-q[open] > summary .landing-sample-chevron {
    transform: rotate(180deg);
}

/* ── CTA con countdown para abrir el modal del quiz ──────────────────── */
[data-quiz-cta] [data-quiz-cta-button][disabled] {
    opacity: 0.85;
    cursor: default;
    /* Mientras está bloqueado se ve apagado en gris para que se vea que
       aún no se puede pulsar; tras desbloquearse vuelve al mustard. */
    background: var(--surface);
    color: var(--steel);
    border-color: transparent;
}

[data-quiz-cta].is-unlocked [data-quiz-cta-button] {
    animation: quiz-unlock-pulse 0.6s ease-out 1;
}

@keyframes quiz-unlock-pulse {
    0% {
        transform: scale(1);
    }
    40% {
        transform: scale(1.05);
    }
    100% {
        transform: scale(1);
    }
}

/* ── Quiz inline en la lección ─────────────────────────────────────────
   Cada pregunta es un card-soft. Las opciones son <button> con tres
   estados visibles: por defecto, correcta (verde), incorrecta (roja).
   También revelamos la correcta cuando el usuario eligió mal. */
.quiz-option {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    width: 100%;
    padding: 0.75rem 1rem;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: 12px;
    color: var(--ink);
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: background 0.12s, border-color 0.12s, color 0.12s;
}

.quiz-option:hover:not([disabled]) {
    background: var(--mustard-soft);
    border-color: var(--mustard);
}

.quiz-option[disabled] {
    cursor: default;
    opacity: 0.85;
}

.quiz-option-letter {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    width: 28px;
    height: 28px;
    background: rgba(0, 0, 0, 0.04);
    border-radius: 8px;
    font-weight: 600;
    font-size: 13px;
    color: var(--ink);
}

.quiz-option-text {
    flex-grow: 1;
}

.quiz-option-icon {
    margin-left: auto;
    flex-shrink: 0;
    font-size: 18px;
    display: none;
}

.quiz-option.is-correct,
.quiz-option.is-correct-revealed {
    background: rgba(74, 93, 58, 0.12);
    border-color: var(--moss);
    color: var(--ink);
}

.quiz-option.is-correct .quiz-option-letter,
.quiz-option.is-correct-revealed .quiz-option-letter {
    background: var(--moss);
    color: #fff;
}

.quiz-option.is-correct .quiz-icon-correct,
.quiz-option.is-correct-revealed .quiz-icon-correct {
    display: inline-block;
    color: var(--moss);
}

.quiz-option.is-wrong {
    background: rgba(123, 45, 45, 0.10);
    border-color: var(--oxblood);
    color: var(--ink);
}

.quiz-option.is-wrong .quiz-option-letter {
    background: var(--oxblood);
    color: #fff;
}

.quiz-option.is-wrong .quiz-icon-wrong {
    display: inline-block;
    color: var(--oxblood);
}

.quiz-explanation {
    background: var(--surface);
    border-left: 3px solid var(--mustard);
    padding: 0.75rem 1rem;
    border-radius: 0 8px 8px 0;
}

/* Dark mode: rebajar fondo de surface dentro de cards */
[data-bs-theme="dark"] .quiz-option {
    background: rgba(245, 239, 225, 0.04);
}

[data-bs-theme="dark"] .quiz-option-letter {
    background: rgba(245, 239, 225, 0.08);
    color: var(--canvas);
}

[data-bs-theme="dark"] .quiz-explanation {
    background: rgba(245, 239, 225, 0.05);
}

/* ── Input group con floating labels ───────────────────────────────────
   Bootstrap 5.3 ya trae estas reglas, pero las redeclaramos como defensa
   para que un override accidental de --bs-border-width o un cambio
   futuro de Bootstrap no rompa el aspecto del bloque nombre+apellidos
   del perfil. Resultado: los dos campos comparten borde, sin gap, y el
   conjunto queda redondeado solo en los extremos exteriores. */
.input-group > .form-floating {
    flex: 1 1 auto;
    min-width: 0;
    width: 1%;
}

.input-group > .form-floating:not(:first-child) > .form-control,
.input-group > .form-floating:not(:first-child) > .form-select {
    border-top-left-radius: 0;
    border-bottom-left-radius: 0;
    /* NO añadir margin-left negativo aquí: Bootstrap ya lo aplica al
       .form-floating padre. Si lo duplicamos, el segundo input se mete
       2px dentro del primero y aparece una "doble línea" en los bordes
       interiores cuando los campos tienen valor (sólo se ocultaba
       visualmente cuando los labels estaban centrados). */
}

.input-group > .form-floating:not(:last-child) > .form-control,
.input-group > .form-floating:not(:last-child) > .form-select {
    border-top-right-radius: 0;
    border-bottom-right-radius: 0;
}

/* El input enfocado se pone por encima de su vecino para que su borde
   azul/mustard no quede cortado por el del campo de al lado. */
.input-group > .form-floating:focus-within {
    position: relative;
    z-index: 5;
}

/* Buscador de cursos en la home (`.course-search-input`).
   En light theme el `--canvas` (cream `#f5efe1`) se mezcla con la
   sección hero — el input se diluye visualmente. Forzamos blanco
   puro para que destaque como elemento accionable. En dark theme se
   queda en `--canvas` (un gris oscuro) que ya contrasta con el
   surface circundante. */
.course-search-input {
    background: #ffffff;
}
.course-search-input:focus {
    background: #ffffff;
    border-color: var(--mustard);
    box-shadow: 0 0 0 3px rgba(255, 208, 47, 0.15);
}
[data-bs-theme="dark"] .course-search-input,
[data-bs-theme="dark"] .course-search-input:focus {
    background: var(--canvas);
}

/* ── Utilidades flexbox que el build estándar de Bootstrap omite ──────
   Bootstrap 5.3 incluye min-w-25/50/75/100 pero NO `.min-w-0`. Sin
   esta clase, un flex item con `flex-grow-1` no puede encogerse por
   debajo del ancho intrínseco de su contenido, así que `.text-truncate`
   no recorta texto largo dentro de flex containers. La añadimos aquí
   junto con su contrapartida vertical y la versión max-w-100 que
   también falta a veces. */
.min-w-0 { min-width: 0 !important; }
.min-h-0 { min-height: 0 !important; }
