← narratipos  /  politica-de-cookies  /  paste

politica-de-cookies | GHL paste bundles

Three self-contained blocks ready to drop into GoHighLevel. {{custom_values.*}} tokens are kept verbatim — GHL substitutes them server-side using the values below.

HTML · body

13.3KB
Download

Pega esto dentro del elemento Custom HTML de la página GHL. Es solo lo que va dentro de <body> — GHL ya pone <!doctype>, <html>, <head> y <body>. Los tokens {{custom_values.*}} quedan literales: GHL los sustituye server-side con los valores listados al final.

<main class="legal">
      <div class="col-narrow">
        <a
          href="{{custom_values.narratipos_root_url}}"
          class="legal__logo"
          aria-label="Narratipos"
        >
          <picture>
  <source type="image/webp" srcset="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/986abb1d-6e8a-4626-a5ed-2b0a84e36a01.webp 320w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/0ee19287-b857-4718-a277-121a2abc6eae.webp 640w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/693995f5-2495-42ea-8e14-d2136b9bb413.webp 960w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/1d35007c-ac24-471c-8a56-842e17ce06d2.webp 1280w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/269ebd29-5e37-48af-bd27-0891fa508766.webp 1920w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/d7b051ea-f3a6-4e04-9663-e212e6db21df.webp 2423w" sizes="(max-width: 640px) 100vw, 2423px" />
  <img src="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/53c84427-4673-45a1-8edb-dfede0facb48.png" alt="" width="2423" height="2423" decoding="async" />
</picture>
          <span>Narratipos</span>
        </a>
        <div class="legal__head">
          <p class="eyebrow">Legal</p>
          <div class="rule">
            <span class="l"></span><span class="d"></span
            ><span class="l"></span>
          </div>
          <h1 class="h-title" style="margin: 0">
            Política de Cookies
            <span style="opacity: 0.55; font-size: 0.7em">(UE)</span>
          </h1>
          <span class="legal__updated">Última revisión · 23/04/2026</span>
        </div>

        <div class="legal__body">
          <h2>Inicio</h2>
          <p>
            Nuestra página web
            <a
              href="{{custom_values.narratipos_root_url}}"
              target="_blank"
              rel="noopener noreferrer"
              ><strong>{{custom_values.narratipos_root_url}}</strong></a
            >
            (en adelante, la «página web») utiliza cookies y otras tecnologías
            relacionadas (para mayor comodidad, todas las tecnologías se
            denominan «cookies»).
          </p>
          <p>
            Las cookies también son colocadas por proveedores (terceros) a los
            que hemos contratado.
          </p>
          <p>
            En el siguiente documento te informamos sobre el uso de las cookies
            en nuestra página web.
          </p>

          <h2>¿Qué son las cookies?</h2>
          <p>
            Una cookie es un pequeño registro / archivo que se envía junto al
            acceder a las páginas de esta web y que tu navegador almacena en el
            dispositivo (sea ordenador, móvil, tablet…).
          </p>
          <p>
            La información almacenada puede ser devuelta a nuestros servidores o
            a los servidores de terceros relevantes durante una visita
            posterior.
          </p>

          <h2>¿Qué son los scripts?</h2>
          <p>
            Un script es un fragmento de código de un programa que se utiliza
            para hacer que la página web funcione correctamente y de forma
            interactiva y dinámica.
          </p>
          <p>
            Este código puede ejecutarse en nuestros servidores o en tu
            dispositivo.
          </p>

          <h2>¿Qué son las balizas web?</h2>
          <p>
            Una baliza web (o etiqueta de píxel) es una pequeña pieza (texto o
            imagen) que está insertada de forma invisible en la página web para
            hacer seguimiento del tráfico. Para ello, se almacenan varios datos
            sobre el usuario mediante esta técnica.
          </p>

          <h2>Cookies</h2>

          <h3>Cookies Técnicas o Funcionales</h3>
          <p>
            Algunas cookies aseguran que ciertas partes de la página web
            funcionen correctamente y que las preferencias como usuario sigan
            recordándose.
          </p>
          <p>
            Al colocar cookies funcionales, facilitamos la visita a nuestra
            página web. De esta manera, no hay necesidad de introducir de manera
            repetida la misma información cuando visitas nuestra web y, por
            ejemplo, los artículos permanecen en tu cesta de compra hasta que se
            hayan pagado. Estas cookies se pueden colocar sin el consentimiento
            por parte del usuario.
          </p>

          <h3>Cookies Analíticas</h3>
          <p>
            Usamos cookies analíticas para optimizar la experiencia en la página
            web para nuestros usuarios. Con estas cookies analíticas obtenemos
            conocimientos del uso de nuestra página web. Te pediremos tu
            consentimiento para insertar este tipo de cookies.
          </p>

          <h3>Cookies de Marketing y de Seguimiento</h3>
          <p>
            Las cookies de marketing y de seguimiento son cookies usadas para
            crear perfiles de usuario y se utilizan para mostrar publicidad o
            hacer el seguimiento del usuario en esta página web o en varias webs
            con fines de marketing. Te pediremos tu consentimiento para insertar
            este tipo de cookies.
          </p>

          <h2>Cookies utilizadas en esta página web</h2>
          <ul>
            <li>
              <a
                href="https://www.gohighlevel.com/"
                target="_blank"
                rel="noopener noreferrer"
                ><strong>Go High Level</strong></a
              >
            </li>
            <li><strong>Google</strong> (YouTube, Analytics, Fonts)</li>
            <li><strong>Stripe</strong></li>
            <li><strong>PayPal</strong></li>
            <li><strong>Facebook</strong></li>
          </ul>

          <h2>Consentimiento</h2>
          <p>
            Cuando visites nuestra página web por primera vez, te mostraremos
            una ventana emergente con una explicación sobre las cookies.
          </p>
          <p>
            Tan pronto como aceptes, consientes que usemos las cookies y los
            complementos que has seleccionado en la ventana emergente, tal y
            como se describe en esta política de cookies.
          </p>
          <p>
            Puedes desactivar el uso de cookies a través de tu navegador, pero
            ten en cuenta que nuestra página web puede dejar de funcionar
            correctamente.
          </p>

          <h2>Tus derechos con respecto a los datos personales</h2>
          <ul>
            <li>
              <strong>Tienes derecho a saber</strong> por qué se necesitan tus
              datos personales, qué sucederá con ellos y durante cuánto tiempo
              se conservarán.
            </li>
            <li>
              <strong>Tienes derecho a acceder y solicitar</strong> los datos
              personales que estamos conservando.
            </li>
            <li>
              <strong
                >Tienes derecho a completar, rectificar, borrar o
                bloquear</strong
              >
              tus datos personales cuando lo desees. Si nos das tu
              consentimiento para procesar tus datos, tienes derecho a revocar
              dicho consentimiento y a que se eliminen tus datos personales.
            </li>
            <li>
              <strong>Tienes derecho a oponerte al tratamiento</strong> de tus
              datos. Cumplimos con esto, a menos que existan motivos
              justificados para el procesamiento.
            </li>
          </ul>
          <p>
            Para ejercer estos derechos, por favor ponte en contacto con
            nosotros en los datos del final de esta página.
          </p>
          <p>
            Si tienes alguna queja sobre cómo gestionamos tus datos, nos
            gustaría que nos la hicieras saber, pero también tienes derecho a
            enviar una queja a la autoridad supervisora (la Agencia Española de
            Protección de Datos).
          </p>

          <h2>Activación, desactivación y eliminación de cookies</h2>
          <p>
            Puedes utilizar tu navegador web para eliminar las cookies de manera
            automática o manual. También puedes especificar que ciertas cookies
            no pueden ser colocadas. Otra opción es cambiar los ajustes de tu
            navegador para que recibas un mensaje cada vez que se coloca una
            cookie.
          </p>
          <p>
            Para obtener más información sobre estas opciones, consulta las
            instrucciones de la sección «Ayuda» de tu navegador.
          </p>
          <p>
            Ten en cuenta que nuestra página web no puede funcionar
            correctamente si todas las cookies están desactivadas. Si borras las
            cookies de tu navegador, se volverán a colocar después de repetir el
            proceso de consentimiento cuando vuelvas a visitar nuestra página
            web.
          </p>

          <h2>Datos de contacto</h2>
          <div class="legal__contact">
            <p>
              <strong>Denominación social:</strong> La Boutique de Mentores SL
            </p>
            <p><strong>CIF:</strong> B16709420</p>
            <p>
              <strong>Domicilio social:</strong> Camino de los Malatones 63,
              28110 Algete, Madrid, España
            </p>
            <p>
              <strong>Correo electrónico:</strong>
              <a href="mailto:equipo@laboutiquedementores.es"
                >equipo@laboutiquedementores.es</a
              >
            </p>
            <p>
              <strong>Sitio web:</strong>
              <a
                href="{{custom_values.narratipos_root_url}}"
                target="_blank"
                rel="noopener noreferrer"
                >{{custom_values.narratipos_root_url}}</a
              >
            </p>
          </div>

          <a href="{{custom_values.narratipos_root_url}}" class="legal__back"
            >← Volver a Narratipos</a
          >
        </div>
      </div>
    </main>

    <footer class="site-footer">
      <div class="site-footer__stars" aria-hidden="true"></div>
      <div class="col site-footer__top">
        <a
          href="https://www.laboutiquedementores.es"
          target="_blank"
          rel="noopener noreferrer"
          class="site-footer__brand-mark"
          aria-label="La Boutique de Mentores"
        >
          <picture>
  <source type="image/webp" srcset="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/90744ff4-817c-4cf5-822d-10539b1f04cc.webp 240w" sizes="(max-width: 640px) 100vw, 240px" />
  <img src="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/0ecf07bb-965b-4515-b527-6ba9c05a14c1.png" alt="La Boutique de Mentores" loading="lazy" decoding="async" />
</picture>
        </a>
        <a
          href="https://www.davidsobrino.es"
          target="_blank"
          rel="noopener noreferrer"
          aria-label="David Sobrino"
        >
          <picture>
  <source type="image/webp" srcset="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/f16c5e05-4e2a-4c8d-8b9a-df1f6ac0a8a7.webp 320w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/ac9ec4df-c683-4685-b9e8-d66111b6b09b.webp 486w" sizes="(max-width: 640px) 100vw, 486px" />
  <img src="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/3c3b1c96-166a-43e3-baa8-dbe0cca1dcf7.png" alt="Firma de David Sobrino" class="site-footer__signature" loading="lazy" decoding="async" />
</picture>
        </a>
      </div>
      <div class="col site-footer__center">
        <div class="site-footer__legal">
          <span
            >Todos los derechos reservados · La Boutique de Mentores SL ·
            2026</span
          >
          <span>
            <a href="{{custom_values.narratipos_privacy_policy_url}}"
              >Política de privacidad</a
            >
            &nbsp;·&nbsp;
            <a href="{{custom_values.narratipos_cookies_policy_url}}"
              >Política de cookies</a
            >
            &nbsp;·&nbsp;
            <a href="{{custom_values.narratipos_legal_policy_url}}"
              >Aviso legal</a
            >
            &nbsp;·&nbsp;
            <a href="{{custom_values.narratipos_terms_and_conditions_url}}"
              >Términos y condiciones</a
            >
          </span>
        </div>
        <a
          class="site-footer__credit"
          href="https://www.innki.tech"
          target="_blank"
          rel="noopener noreferrer"
          aria-label="Diseño y Desarrollo por Innki Tech"
        >
          <span class="site-footer__credit-label">Diseño &amp; Desarrollo</span>
          <img
            class="site-footer__credit-logo"
            src="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/08b7577d-9d84-450f-9dc7-66a86e5dac94.svg"
            alt="Innki Tech"
            loading="lazy"
            decoding="async"
          />
        </a>
      </div>
    </footer>

    <!-- VOLVER AL INICIO — hooked by branding/narratipos/includes/script.js -->
    <button
      type="button"
      class="back-to-top"
      id="back-to-top"
      aria-label="Volver arriba"
    >
      <svg class="back-to-top__ring" viewBox="0 0 48 48" aria-hidden="true">
        <circle class="back-to-top__ring-track" cx="24" cy="24" r="22"></circle>
        <circle class="back-to-top__ring-fill" cx="24" cy="24" r="22"></circle>
      </svg>
      <i class="icon icon--arrow-up" aria-hidden="true"></i>
    </button>

Fonts · Google Fonts links

334B
Download

Pega esto en el campo 'Fonts' del Page Builder (o en 'Tracking Code Header' si tu plantilla no tiene un slot dedicado). Son los <link> de preconnect a Google Fonts + la hoja de estilos que carga las familias (Cinzel, Poppins, Allura).

<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
  href="https://fonts.googleapis.com/css2?family=Cinzel:wght@400;500;600&family=Poppins:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400;1,500;1,600&family=Allura&display=swap"
  rel="stylesheet"
/>

Head · favicons + meta + canonical

1.1KB
Download

Pega esto en 'Tracking Code Header' del Page Builder (Settings → Tracking Code). Incluye favicons, meta tags y la <link rel="canonical"> — revisa que la URL coincida con tu dominio en producción.

<title>
      Política de Cookies (UE) | {{custom_values.narratipos_brand_name}}
    </title>
    <meta
      name="description"
      content="Política de Cookies (UE) de {{custom_values.narratipos_brand_name}}"
    />
    <meta name="robots" content="index,follow" />
    <meta
      name="theme-color"
      content="{{custom_values.narratipos_brand_color}}"
    />
    <meta name="color-scheme" content="dark" />
    <link
      rel="canonical"
      href="{{custom_values.narratipos_root_url}}/politica-de-cookies"
    />

    <link
      rel="icon"
      type="image/png"
      sizes="32x32"
      href="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/63f58c81-4ff1-4b39-8157-59f51cc08205.png"
    />
    <link
      rel="icon"
      type="image/png"
      sizes="16x16"
      href="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/4d046512-417a-481c-bb22-96a70cf316bb.png"
    />
    <link
      rel="apple-touch-icon"
      sizes="180x180"
      href="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/120e018c-84a4-4b8a-bc06-dead5410cc65.png"
    />

<!-- Schema.org · JSON-LD -->

JSON-LD · schema.org

2.9KB
Download

Pega esto también en 'Tracking Code Header' (debajo del bloque Head). Es metadata estructurada (Person / Organization / WebPage) que mejora cómo aparece la página en Google. Inocuo si lo olvidas — pero ayuda al SEO.

<script type="application/ld+json">
      {
        "@context": "https://schema.org",
        "@graph": [
          {
            "@type": "Person",
            "@id": "{{custom_values.narratipos_root_url}}#david-sobrino",
            "name": "David Sobrino",
            "jobTitle": "Mentor y creador de Narratipos®",
            "url": "{{custom_values.narratipos_root_url}}"
          },
          {
            "@type": "Organization",
            "@id": "{{custom_values.la_boutique_de_mentores_root_url}}#organization",
            "name": "{{custom_values.la_boutique_de_mentores_brand_name}}",
            "url": "{{custom_values.la_boutique_de_mentores_root_url}}",
            "logo": "{{custom_values.la_boutique_de_mentores_brand_image}}",
            "founder": {
              "@id": "{{custom_values.narratipos_root_url}}#david-sobrino"
            }
          },
          {
            "@type": "Organization",
            "@id": "https://www.innki.tech#organization",
            "name": "Innki Tech",
            "url": "https://www.innki.tech"
          },
          {
            "@type": "WebSite",
            "@id": "{{custom_values.narratipos_root_url}}#website",
            "url": "{{custom_values.narratipos_root_url}}",
            "name": "{{custom_values.narratipos_brand_name}}",
            "inLanguage": "es-ES",
            "publisher": {
              "@id": "{{custom_values.la_boutique_de_mentores_root_url}}#organization"
            }
          },
          {
            "@type": "WebPage",
            "@id": "{{custom_values.narratipos_root_url}}/politica-de-cookies#webpage",
            "url": "{{custom_values.narratipos_root_url}}/politica-de-cookies",
            "name": "Política de Cookies (UE) | {{custom_values.narratipos_brand_name}}",
            "isPartOf": {
              "@id": "{{custom_values.narratipos_root_url}}#website"
            },
            "inLanguage": "es-ES",
            "author": {
              "@id": "{{custom_values.narratipos_root_url}}#david-sobrino"
            },
            "creator": { "@id": "https://www.innki.tech#organization" },
            "creditText": "Diseño y desarrollo web por Innki Tech",
            "publisher": {
              "@id": "{{custom_values.la_boutique_de_mentores_root_url}}#organization"
            }
          },
          {
            "@type": "BreadcrumbList",
            "itemListElement": [
              {
                "@type": "ListItem",
                "position": 1,
                "name": "{{custom_values.narratipos_brand_name}}",
                "item": "{{custom_values.narratipos_root_url}}"
              },
              {
                "@type": "ListItem",
                "position": 2,
                "name": "Política de Cookies",
                "item": "{{custom_values.narratipos_root_url}}/politica-de-cookies"
              }
            ]
          }
        ]
      }
    </script>

CSS

125.6KB
Download

Pega esto en el campo Custom CSS de la página GHL.

/* ===== brand | design system ===== */
/* =========================================================
   NARRATIPOS | LANDING
   ---------------------------------------------------------
   Main stylesheet.

   File outline:
     | Variables and reset
     | Typography and base layout
     | Icons
     | CTA system
     | Header and navigation
     | Hero
     | Sections (audience, what it is, modules, pricing, ...)
     | FAQ, footer and utilities
     | Media queries and motion
========================================================= */

:root {
  /* --- Core: ink, paper and rules --- */
  --ink: #0a0a0c;
  --ink-2: #13131a;
  --ink-3: #1a1a22;
  --navy: #1f4d7a;
  --navy-deep: #163655;
  --navy-mist: #2c5e8c;
  --line: rgba(255, 255, 255, 0.08);
  --line-strong: rgba(255, 255, 255, 0.18);
  --paper: #efeae0;
  --paper-2: #c9c2b3;
  --mute: #7b7568;
  --white: #ffffff;

  /* --- Accents: terra, blue, book purple and wine --- */
  --terra: #d4845f;
  --terra-deep: #b86a48;
  --sky: #9dc4e0;
  --azul: #7b9bbe;
  --azul-deep: #5a7ba0;
  --azul-soft: rgba(123, 155, 190, 0.16);
  --morado-libro: #4f032a;
  --morado-libro-deep: #2e021a;
  --accent: var(--terra);
  --accent-deep: var(--terra-deep);
  --accent-soft: rgba(212, 132, 95, 0.18);
  --wine: #1a0508;
  --wine-2: #240810;
  --wine-3: #330b16;
  --wine-line: rgba(212, 132, 95, 0.16);

  /* --- Narratipos: color identificativo de cada uno --- */
  --narratipo-visionario: #163655;
  --narratipo-motivador: #2a6fb5;
  --narratipo-conector: #2a8fce;
  --narratipo-transformador: #5ba85a;
  --narratipo-investigador: #e8b23a;
  --narratipo-previsor: #e89a2a;
  --narratipo-singular: #c9102c;
  --narratipo-sensitivo: #8c2d5e;

  /* --- Fonts --- */
  --serif: "Cinzel", "Trajan Pro", "EB Garamond", Georgia, serif;
  --sans: "Poppins", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --script: "Allura", "Great Vibes", cursive;

  /* --- Grid system --- */
  --col: min(1180px, 92vw);
  --col-narrow: min(820px, 92vw);
}

/* =========================================================
   RESET MÍNIMO
========================================================= */

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 80px;
  background: var(--ink);
}

body {
  background: var(--ink);
  color: var(--paper);
  font-family: var(--sans);
  font-weight: 300;
  font-size: 17px;
  line-height: 1.7;
  -webkit-font-smoothing: subpixel-antialiased;
  -moz-osx-font-smoothing: auto;
  text-rendering: optimizeLegibility;
}

/* Font-smoothing belt-and-suspenders — FLIPPED (R29).
   Earlier rounds set this to `antialiased` / `grayscale` (the
   thinner grayscale rendering). User confirmed the heavier
   subpixel rendering reads better and that production was showing
   the THINNER look — so we force `subpixel-antialiased` /
   `auto` everywhere with !important, surviving any GHL page-level
   CSS that would try to revert to antialiased / grayscale. */
html,
body,
body * {
  -webkit-font-smoothing: subpixel-antialiased !important;
  -moz-osx-font-smoothing: auto !important;
}

body.anim-paused *,
body.anim-paused *::before,
body.anim-paused *::after {
  animation-play-state: paused !important;
}

img {
  max-width: 100%;
  display: block;
}

a {
  color: inherit;
  text-decoration: none;
}

/* =========================================================
   TIPOGRAFÍA
   Utility classes for font, size and hierarchy.
========================================================= */

.serif {
  font-family: var(--serif);
  font-weight: 400;
}

.script {
  font-family: var(--script);
  font-weight: 400;
}

.h-display {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(2.6rem, 7vw, 5.4rem);
  line-height: 1.05;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--white);
  margin: 0;
}

.h-title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.8rem, 3.6vw, 3rem);
  line-height: 1.18;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--white);
  margin: 0 0 0.8em;
}

.eyebrow {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.72rem;
  letter-spacing: 0.42em;
  text-transform: uppercase;
  color: var(--accent);
  transition: color 1.2s ease;
}

.eyebrow--mute {
  color: var(--paper-2);
}

.eyebrow--edition {
  color: var(--paper);
}

.lede {
  font-family: var(--sans);
  font-weight: 300;
  font-size: clamp(1.05rem, 1.4vw, 1.22rem);
  color: var(--paper-2);
  line-height: 1.6;
}

.italic {
  font-style: italic;
}

/* =========================================================
   LAYOUT BASE
   Containers and section padding.
========================================================= */

.col {
  width: var(--col);
  margin-inline: auto;
}

.col-narrow {
  width: var(--col-narrow);
  margin-inline: auto;
}

section {
  padding: clamp(56px, 6.5vw, 96px) 0;
  position: relative;
}

/* =========================================================
   SECTION BLEND | true transition between sections.
   Each section declares --from (its color) and --to (the next
   next). El degradado mantiene plano el 70% central
   one), blending into the next color over the final 30%.
========================================================= */

.blend {
  background: linear-gradient(
    180deg,
    var(--from) 0%,
    var(--from) 25%,
    var(--to) 75%,
    var(--to) 100%
  ) !important;
}

/* compatibility: bleed-* classes are neutralized */

.bleed-top,
.bleed-bot,
.bleed-y {
  box-shadow: none;
}

.center {
  text-align: center;
}

/* Rule | brochure ornament (thin line with dot) */

.rule {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  margin: 1.2rem auto;
  color: var(--paper-2);
}

.rule .l {
  width: 46px;
  height: 1px;
  background: currentColor;
  opacity: 0.45;
}

.rule .d {
  width: 5px;
  height: 5px;
  background: currentColor;
  border-radius: 50%;
}

.rule--left {
  justify-content: flex-start;
  margin-left: 0;
}

/* Line break visible only on mobile */
br.br-mobile {
  display: none;
}

/* Helper inverso: visible en desktop, hidden en mobile */
.hide-mobile {
  display: inline;
}

@media (max-width: 720px) {
  br.br-mobile {
    display: initial;
  }

  .hide-mobile {
    display: none;
  }

  /* On mobile, rule--left becomes symmetric (-- | --) same as .rule */
  .rule--left {
    justify-content: center;
  }

  .rule--left::after {
    content: "";
    display: block;
    width: 46px;
    height: 1px;
    background: currentColor;
    opacity: 0.45;
  }
}

/* =========================================================
   ICONOS
   ---------------------------------------------------------
   Icons vectoriales servidos como mask-image from data URIs.
   Heredan el color del text (currentColor) y animatesn como
   cualquier elemento con transform/opacity.

   Usage en HTML:
     <i class="icon icon--arrow" aria-hidden="true"></i>
========================================================= */

.icon {
  display: inline-block;
  vertical-align: middle;
  background-color: currentColor;

  /* By default the icon adopts its native size; each
     modificador define su propio width/height. */
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}

/* Arrow derecha | CTAs (14×10) */
.icon--arrow {
  width: 14px;
  height: 10px;
  -webkit-mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 10' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='square'%3E%3Cpath d='M1 5h12m0 0L9 1m4 4L9 9'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 10' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='square'%3E%3Cpath d='M1 5h12m0 0L9 1m4 4L9 9'/%3E%3C/svg%3E");
}

/* Up arrow | back-to-top button (14×14) */
.icon--arrow-up {
  width: 14px;
  height: 14px;
  -webkit-mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='square'%3E%3Cpath d='M7 11V3M3 7l4-4 4 4'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14' fill='none' stroke='black' stroke-width='1.4' stroke-linecap='square'%3E%3Cpath d='M7 11V3M3 7l4-4 4 4'/%3E%3C/svg%3E");
}

/* Cruz de cierre | modal de bonos (16×16) */
.icon--close {
  width: 16px;
  height: 16px;
  -webkit-mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M2 2l12 12M14 2L2 14'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml;utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round'%3E%3Cpath d='M2 2l12 12M14 2L2 14'/%3E%3C/svg%3E");
}

/* =========================================================
   CTA | pill-style buttons
   Unified call-to-action system.
========================================================= */

.cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  padding: 18px 38px;
  border-radius: 999px;
  border: 1px solid var(--paper);
  color: var(--white);
  background: transparent;
  transition: all 0.25s ease;
  text-decoration: none;
}

.cta:hover {
  background: var(--white);
  color: var(--ink);
  border-color: var(--white);
}

/* Primario terracota (same as la web actual) */

.cta--terra {
  background: var(--accent);
  color: var(--white);
  border-color: var(--accent);
  transition:
    background 1.2s ease,
    border-color 1.2s ease,
    color 0.25s ease,
    transform 0.25s ease,
    box-shadow 0.35s ease;
}

.cta--terra:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
  color: var(--white);
}

/* Animated CTA (same treatment as the hero): continuous shimmer, sliding arrow, halo and expanded letter-spacing */

.cta--hero-anim {
  position: relative;
  overflow: hidden;
  background: var(--accent);
  color: var(--cta-text);
  border-color: var(--accent);
  box-shadow:
    0 10px 30px -12px color-mix(in oklab, var(--accent) 55%, transparent),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  transition:
    color 1.2s ease,
    transform 0.35s ease,
    box-shadow 1.2s ease,
    letter-spacing 0.35s ease,
    background 1.2s ease,
    border-color 1.2s ease;
}

.cta--hero-anim .icon {
  transition: transform 0.35s cubic-bezier(0.65, 0.05, 0.36, 1);
}

.cta--hero-anim::after {
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: -30%;
  width: 30%;
  background: linear-gradient(
    120deg,
    rgba(255, 255, 255, 0) 25%,
    rgba(255, 255, 255, 0.55) 50%,
    rgba(255, 255, 255, 0) 75%
  );
  transform: skewX(-25deg);
  pointer-events: none;
  animation: ctaBrillo 5s ease-in-out infinite;
}

.cta--hero-anim:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
  color: var(--cta-text);
  box-shadow:
    0 18px 44px -14px color-mix(in oklab, var(--accent) 95%, transparent),
    0 0 0 6px color-mix(in oklab, var(--accent) 18%, transparent);
  transform: translateY(-2px);
  letter-spacing: 0.36em;
}

.cta--hero-anim:hover .icon {
  transform: translateX(6px);
}

@media (prefers-reduced-motion: reduce) {
  .cta--hero-anim::after {
    display: none;
  }
}

/* Featured variant — closing block: more volume, warm halo and visual weight */

.cta--xl {
  /* force terra palette regardless of the active theme */

  background: #d4845f;
  border-color: #d4845f;
  color: #fff;
  padding: 22px 52px;
  font-size: 0.82rem;
  letter-spacing: 0.36em;
  font-weight: 600;
  text-shadow: 0 1px 0 rgba(0, 0, 0, 0.18);
  box-shadow:
    0 22px 50px -14px rgba(212, 132, 95, 0.75),
    0 0 0 1px rgba(212, 132, 95, 0.55),
    0 0 0 6px rgba(212, 132, 95, 0.18),
    inset 0 1px 0 rgba(255, 255, 255, 0.28);
}

.cta--xl:hover {
  background: #b86a47;
  border-color: #b86a47;
  color: #fff;
  transform: translateY(-2px);
  box-shadow:
    0 30px 64px -14px rgba(212, 132, 95, 0.9),
    0 0 0 1px rgba(212, 132, 95, 0.75),
    0 0 0 8px rgba(212, 132, 95, 0.22),
    inset 0 1px 0 rgba(255, 255, 255, 0.32);
}

.cta-row {
  margin-top: 2.4rem;
  display: flex;
  gap: 14px;
  justify-content: center;
  flex-wrap: wrap;
}

/* =========================================================
   THEME PIVOT | terra ⇄ blue breath (HERO only)
   Las custom properties se registran como <color> so that
   so the animation actually interpolates (without @property they would be toggles).
   The rest of the page stays on static burgundy.
========================================================= */

@property --accent {
  syntax: "<color>";
  inherits: true;
  initial-value: #d4845f;
}

@property --accent-deep {
  syntax: "<color>";
  inherits: true;
  initial-value: #b86a48;
}

@property --cta-text {
  syntax: "<color>";
  inherits: true;
  initial-value: #1a0508;
}

.hero {
  animation: brandPivot 30s ease-in-out infinite;
}

.hero.is-out,
.hero.is-out *,
.hero.is-out *::before,
.hero.is-out *::after {
  animation-play-state: paused !important;
}

@keyframes brandPivot {
  0%,
  100% {
    --accent: #d4845f;
    --accent-deep: #b86a48;
    --cta-text: #1a0508;
  }

  /* Dark text until the crossover — background still legible */
  24% {
    --cta-text: #1a0508;
  }

  /* Fast flip (0.6 s): from here on the background is dark enough */
  26% {
    --cta-text: #f4e9dc;
  }

  50% {
    --accent: #4f032a;
    --accent-deep: #2e021a;
    --cta-text: #f4e9dc;
  }

  /* Mismo dot de cruce en el retorno */
  74% {
    --cta-text: #f4e9dc;
  }

  76% {
    --cta-text: #1a0508;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero {
    animation: none;
  }
}

/* Spot override: force blue palette on a section if desired */

.theme-azul {
  --accent: #7b9bbe;
  --accent-deep: #5a7ba0;
  --wine: #0b1622;
  --wine-2: #101f30;
  --wine-3: #162a3f;
}

section {
  transition:
    background 1.2s ease,
    border-color 1.2s ease;
}

/* =========================================================
   HEADER | banda fina superior tipo brochure
========================================================= */

.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 10;
  padding: 22px 0;
  background: transparent;
  backdrop-filter: none;
  -webkit-backdrop-filter: none;
  transition:
    padding 0.35s ease,
    background 0.35s ease,
    backdrop-filter 0.35s ease,
    box-shadow 0.35s ease,
    border-color 0.35s ease;
  border-bottom: 1px solid transparent;
}

.site-header.is-scrolled {
  padding: 14px 0;
  background: rgba(10, 3, 6, 0.88);
  backdrop-filter: blur(16px) saturate(130%);
  -webkit-backdrop-filter: blur(16px) saturate(130%);
  border-bottom-color: color-mix(in oklab, var(--accent) 18%, transparent);
  box-shadow: 0 10px 30px -20px rgba(0, 0, 0, 0.7);
}

.site-header .col {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
}

.site-header__brand {
  display: flex;
  align-items: center;
  gap: 14px;
  text-decoration: none;
}

.site-header__mark {
  height: 32px;
  width: auto;
  display: block;
  filter: brightness(0) invert(1) opacity(0.92);
  transition:
    height 0.35s ease,
    opacity 0.35s ease,
    transform 0.35s ease;
}

.site-header.is-scrolled .site-header__mark {
  height: 26px;
  opacity: 1;
}

.site-header__brand:hover .site-header__mark {
  transform: scale(1.06);
}

.site-header__wordmark {
  font-family: var(--serif);
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: #f4e9dc;
  font-size: 0.92rem;
  line-height: 1;
  white-space: nowrap;
  /* hidden in the hero, appears on scroll with horizontal expansion */

  display: inline-block;
  max-width: 0;
  opacity: 0;
  overflow: hidden;
  transform: translateX(-6px);
  transition:
    max-width 0.55s cubic-bezier(0.65, 0.05, 0.36, 1),
    opacity 0.35s ease 0.05s,
    transform 0.55s cubic-bezier(0.65, 0.05, 0.36, 1),
    font-size 0.35s ease;
}

.site-header.is-scrolled .site-header__wordmark {
  max-width: 280px;
  opacity: 1;
  transform: translateX(0);
  font-size: 0.82rem;
}

.site-header nav {
  display: flex;
  gap: 30px;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(244, 233, 220, 0.85);
}

.site-header nav a {
  position: relative;
  color: inherit;
  text-decoration: none;
  padding: 6px 0;
  transition: color 0.25s ease;
}

.site-header nav a::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 1px;
  /* Gradient with a brighter "highlight" in the center that travels
     gracias al shimmer; al estar al 200% del wide podemos animate
     background-position de -100% a 100% sin romper los borders. */
  background: linear-gradient(
    90deg,
    rgba(212, 132, 95, 0.65) 0%,
    rgba(212, 132, 95, 0.95) 35%,
    #f4e9dc 50%,
    rgba(212, 132, 95, 0.95) 65%,
    rgba(212, 132, 95, 0.65) 100%
  );
  background-size: 200% 100%;
  background-position: 100% 0;
  box-shadow: 0 0 0 rgba(212, 132, 95, 0);
  transition:
    opacity 0.5s ease,
    box-shadow 0.6s ease;
  opacity: 0;
}

.site-header nav a:hover {
  color: #f4e9dc;
}

.site-header nav a:hover::after,
.site-header nav a.is-active::after {
  opacity: 1;
  box-shadow:
    0 0 6px rgba(212, 132, 95, 0.55),
    0 0 14px rgba(212, 132, 95, 0.25);
  animation: navUnderlineShimmer 7.5s ease-in-out infinite;
}

@keyframes navUnderlineShimmer {
  0% {
    background-position: 100% 0;
  }
  50% {
    background-position: -100% 0;
  }
  100% {
    background-position: 100% 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .site-header nav a:hover::after,
  .site-header nav a.is-active::after {
    animation: none;
  }
}

.site-header nav a.is-active {
  color: #f4e9dc;
}

/* Acceso siempre featured en cream */

.site-header nav a[style*="font-weight:600"] {
  color: #f4e9dc;
}

/* =========================================================
   MOBILE NAV | hamburger button + burgundy overlay
========================================================= */

.nav-toggle {
  display: none;
  position: relative;
  z-index: 21;
  width: 42px;
  height: 42px;
  padding: 0;
  background: transparent;
  border: 0;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.nav-toggle__bars {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 22px;
  height: 14px;
  transform: translate(-50%, -50%);
}

.nav-toggle__bars::before,
.nav-toggle__bars::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  height: 1.4px;
  background: #f4e9dc;
  transition:
    transform 0.35s cubic-bezier(0.65, 0.05, 0.36, 1),
    top 0.25s ease,
    opacity 0.25s ease;
  transform-origin: center;
}

.nav-toggle__bars::before {
  top: 0;
}

.nav-toggle__bars::after {
  bottom: 0;
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before {
  top: 50%;
  transform: translateY(-50%) rotate(45deg);
}

.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after {
  bottom: auto;
  top: 50%;
  transform: translateY(-50%) rotate(-45deg);
}

.nav-overlay {
  position: fixed;
  inset: 0;
  z-index: 19;
  background: rgba(10, 3, 6, 0.96);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.35s ease,
    visibility 0.35s ease;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 80px 24px 40px;
  overflow: hidden;
}

.nav-overlay.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  backdrop-filter: blur(20px) saturate(140%);
  -webkit-backdrop-filter: blur(20px) saturate(140%);
}

/* Star layer inside the overlay to keep the hero atmosphere */

.nav-overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    radial-gradient(
      1px 1px at 12% 18%,
      rgba(244, 233, 220, 0.6) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 82% 12%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.4px 1.4px at 26% 76%,
      rgba(244, 233, 220, 0.7) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 60% 32%,
      rgba(244, 233, 220, 0.4) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 90% 58%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 8% 50%,
      rgba(244, 233, 220, 0.4) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.2px 1.2px at 44% 8%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 70% 88%,
      rgba(244, 233, 220, 0.45) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 36% 44%,
      rgba(212, 132, 95, 0.4) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.3px 1.3px at 76% 72%,
      rgba(212, 132, 95, 0.5) 50%,
      transparent 100%
    );
  -webkit-mask: radial-gradient(
    ellipse 60% 60% at 50% 50%,
    transparent 0%,
    #000 75%
  );
  mask: radial-gradient(ellipse 60% 60% at 50% 50%, transparent 0%, #000 75%);
  opacity: 0.7;
}

.nav-overlay::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: min(620px, 80vmin);
  aspect-ratio: 1/1;
  background: radial-gradient(
    ellipse 50% 50% at 50% 50%,
    rgba(212, 132, 95, 0.18) 0%,
    transparent 70%
  );
  pointer-events: none;
}

.nav-overlay__inner {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  text-align: center;
}

.nav-overlay__mark {
  display: block;
  height: 42px;
  width: auto;
  margin-bottom: 24px;
  filter: brightness(0) invert(1);
}

.nav-overlay__list {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  list-style: none;
  padding: 0;
  margin: 0;
}

.nav-overlay__list a {
  display: inline-block;
  padding: 14px 12px;
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.35rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #f4e9dc;
  text-decoration: none;
  position: relative;
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.5s ease,
    transform 0.5s cubic-bezier(0.65, 0.05, 0.36, 1),
    color 0.25s ease;
}

.nav-overlay.is-open .nav-overlay__list a {
  opacity: 1;
  transform: translateY(0);
}

.nav-overlay__list li:nth-child(1) a {
  transition-delay: 0.1s;
}

.nav-overlay__list li:nth-child(2) a {
  transition-delay: 0.16s;
}

.nav-overlay__list li:nth-child(3) a {
  transition-delay: 0.22s;
}

.nav-overlay__list li:nth-child(4) a {
  transition-delay: 0.28s;
}

.nav-overlay__list li:nth-child(5) a {
  transition-delay: 0.34s;
}

.nav-overlay__list li:nth-child(6) a {
  transition-delay: 0.4s;
}

.nav-overlay__list li:nth-child(7) a {
  transition-delay: 0.46s;
}

.nav-overlay__list li:nth-child(8) a {
  transition-delay: 0.52s;
}

.nav-overlay__list li:nth-child(9) a {
  transition-delay: 0.58s;
}

.nav-overlay__list a::after {
  content: "";
  position: absolute;
  left: 12px;
  right: 12px;
  bottom: 8px;
  height: 1px;
  background: #d4845f;
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.35s cubic-bezier(0.65, 0.05, 0.36, 1);
}

.nav-overlay__list a:hover::after,
.nav-overlay__list a.is-active::after {
  transform: scaleX(1);
}

.nav-overlay__list a.is-acceso {
  margin-top: 14px;
  padding: 14px 32px;
  border: 1px solid rgba(244, 233, 220, 0.5);
  border-radius: 999px;
  font-size: 0.78rem;
  letter-spacing: 0.32em;
}

.nav-overlay__list a.is-acceso::after {
  display: none;
}

.nav-overlay__list a.is-acceso:hover {
  background: #d4845f;
  border-color: #d4845f;
  color: #1a0508;
}

body.nav-locked {
  overflow: hidden;
}

/* When the overlay is open, the header becomes transparent and lifts above
   so the "X" button stays accessible and the header isotype blurs */

body.nav-locked .site-header {
  z-index: 22;
  background: transparent !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
  box-shadow: none !important;
  border-bottom-color: transparent !important;
}

body.nav-locked .site-header__brand {
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

/* =========================================================
   HERO | portada del libro | dark como brochure
   exact 100vh, no overflow, with expanding octagons
   The hero pivots cyclically between burgundy and slate blue (24s),
   y arrastra al --accent (botones, shine, halo) en el mismo ciclo.
========================================================= */

.hero {
  position: relative;
  height: 100vh;
  min-height: 640px;
  max-height: 100vh;
  display: flex;
  flex-direction: column;
  background: #000;
  overflow: hidden;
  padding: 0;
}

/* Mask to fade ALL hero visuals (bg, stars, rings, grain) to transparent
   at the bottom 22%, so it dissolves seamlessly into the next section. */

.hero__bg,
.hero__rings,
.hero__stars,
.hero__veil-azul {
  -webkit-mask-image: linear-gradient(
    180deg,
    #000 0%,
    #000 70%,
    transparent 100%
  );
  mask-image: linear-gradient(180deg, #000 0%, #000 70%, transparent 100%);
}

/* Dark deep-burgundy background + warm central halo where the rosette sits.
   La capa base stays dark, sobre ella se cruzan dos veils
   (burgundy y azul) que opacan/desopacan en bucle para dar el pivote. */

.hero__bg {
  position: absolute;
  inset: 0;
  z-index: 0;
  background:
    radial-gradient(
      ellipse 140% 90% at 50% 100%,
      rgba(10, 2, 4, 0.85) 0%,
      transparent 70%
    ),
    linear-gradient(180deg, #1a0810 0%, #120612 50%, #0c0610 100%);
}

/* BURGUNDY veil (visible at the start of the cycle) */

.hero__bg::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 38% 38% at 50% 48%,
      rgba(212, 132, 95, 0.55) 0%,
      rgba(184, 106, 72, 0.25) 25%,
      rgba(92, 15, 27, 0.1) 55%,
      transparent 75%
    ),
    radial-gradient(
      ellipse 140% 90% at 50% 0%,
      rgba(92, 15, 27, 0.55) 0%,
      transparent 65%
    );
  opacity: 1;
  /* Promote a capa GPU: opacity se compone en GPU sin repaint. */
  will-change: opacity;
  transform: translateZ(0);
  animation: heroVeilWine 30s ease-in-out infinite;
}

/* PURPLE BOOK veil (visible at the middle of the cycle) */

.hero__veil-azul {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 38% 38% at 50% 48%,
      rgba(79, 3, 42, 0.7) 0%,
      rgba(79, 3, 42, 0.4) 25%,
      rgba(46, 2, 26, 0.18) 55%,
      transparent 75%
    ),
    radial-gradient(
      ellipse 140% 90% at 50% 0%,
      rgba(46, 2, 26, 0.65) 0%,
      transparent 65%
    );
  opacity: 0;
  will-change: opacity;
  transform: translateZ(0);
  animation: heroVeilAzul 30s ease-in-out infinite;
}

@keyframes heroVeilWine {
  0%,
  100% {
    opacity: 1;
  }

  50% {
    opacity: 0;
  }
}

@keyframes heroVeilAzul {
  0%,
  100% {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }
}

/* Subtle octagons that expand outward like a wave */

.hero__rings {
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

.hero__rings svg {
  width: min(2400px, 200vmax);
  height: min(2400px, 200vmax);
  display: block;
  overflow: visible;
}

.hero__rings polygon {
  fill: color-mix(in oklab, var(--accent) 2.5%, transparent);
  stroke: var(--accent);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
  transform-origin: center;
  transform-box: fill-box;
  opacity: 0;
  will-change: transform, opacity;
  animation: ringWave 22s cubic-bezier(0.22, 0.61, 0.36, 1) infinite;
  transition: stroke 1.2s ease;
}

.hero__rings polygon:nth-of-type(1) {
  animation-delay: 0s;
}

.hero__rings polygon:nth-of-type(2) {
  animation-delay: 4.4s;
}

.hero__rings polygon:nth-of-type(3) {
  animation-delay: 8.8s;
}

.hero__rings polygon:nth-of-type(4) {
  animation-delay: 13.2s;
}

.hero__rings polygon:nth-of-type(5) {
  animation-delay: 17.6s;
}

@keyframes ringWave {
  0% {
    transform: scale(0.22);
    opacity: 0;
    stroke-opacity: 0.32;
  }

  18% {
    opacity: 0.55;
  }

  65% {
    opacity: 0.28;
    stroke-opacity: 0.16;
  }

  100% {
    transform: scale(2.4);
    opacity: 0;
    stroke-opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__rings polygon {
    animation: none;
    opacity: 0.4;
    transform: scale(1);
  }
}

/* Granulado sutil */

.hero__bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    radial-gradient(
      circle at 20% 20%,
      rgba(244, 233, 220, 0.04) 0,
      transparent 1px
    ),
    radial-gradient(
      circle at 70% 60%,
      rgba(244, 233, 220, 0.03) 0,
      transparent 1px
    ),
    radial-gradient(
      circle at 40% 80%,
      rgba(244, 233, 220, 0.03) 0,
      transparent 1px
    );
  background-size:
    3px 3px,
    5px 5px,
    4px 4px;
  opacity: 0.7;
  pointer-events: none;
}

/* Background stars | layer between background and rings */

.hero__stars {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  /* Multiple layers of tiny dots in pseudo-random positions */

  background-image:
    radial-gradient(
      1px 1px at 12% 18%,
      rgba(244, 233, 220, 0.85) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 82% 12%,
      rgba(244, 233, 220, 0.7) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.4px 1.4px at 26% 76%,
      rgba(244, 233, 220, 0.95) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 60% 32%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 90% 58%,
      rgba(244, 233, 220, 0.65) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 8% 50%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.2px 1.2px at 44% 8%,
      rgba(244, 233, 220, 0.75) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 70% 88%,
      rgba(244, 233, 220, 0.6) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 36% 44%,
      rgba(212, 132, 95, 0.45) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 18% 92%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 96% 30%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 52% 62%,
      rgba(244, 233, 220, 0.45) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.3px 1.3px at 76% 72%,
      rgba(212, 132, 95, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 4% 28%,
      rgba(244, 233, 220, 0.6) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 32% 22%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 64% 18%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 88% 84%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 22% 36%,
      rgba(244, 233, 220, 0.4) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 56% 80%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.5px 1.5px at 14% 64%,
      rgba(244, 233, 220, 0.85) 50%,
      transparent 100%
    );
  /* Dim the stars in the central area where the brand sits */

  -webkit-mask: radial-gradient(
    ellipse 38% 38% at 50% 50%,
    transparent 0%,
    rgba(0, 0, 0, 0.45) 45%,
    #000 75%
  );
  mask: radial-gradient(
    ellipse 38% 38% at 50% 50%,
    transparent 0%,
    rgba(0, 0, 0, 0.45) 45%,
    #000 75%
  );
  will-change: opacity;
  transform: translateZ(0);
  animation: starsTwinkle 6s ease-in-out infinite alternate;
}

/* Extra layer of "flash" stars that appear and disappear at
   different positions, simulating a breathing sky. */
.hero__stars::before,
.hero__stars::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  -webkit-mask: inherit;
  mask: inherit;
}

.hero__stars::before {
  background-image:
    radial-gradient(1.6px 1.6px at 16% 30%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.4px 1.4px at 78% 22%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.8px 1.8px at 40% 70%, #f4e9dc 50%, transparent 100%),
    radial-gradient(
      1.2px 1.2px at 92% 48%,
      rgba(212, 132, 95, 0.95) 50%,
      transparent 100%
    ),
    radial-gradient(1.4px 1.4px at 6% 78%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.5px 1.5px at 62% 12%, #f4e9dc 50%, transparent 100%);
  opacity: 0;
  will-change: opacity;
  transform: translateZ(0);
  animation: starsBlink 7s ease-in-out infinite;
}

.hero__stars::after {
  background-image:
    radial-gradient(1.4px 1.4px at 28% 14%, #f4e9dc 50%, transparent 100%),
    radial-gradient(
      1.6px 1.6px at 70% 60%,
      rgba(212, 132, 95, 0.9) 50%,
      transparent 100%
    ),
    radial-gradient(1.2px 1.2px at 50% 28%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.5px 1.5px at 86% 82%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.3px 1.3px at 12% 56%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.4px 1.4px at 34% 88%, #f4e9dc 50%, transparent 100%);
  opacity: 0;
  will-change: opacity;
  transform: translateZ(0);
  animation: starsBlink 9s ease-in-out infinite 2.4s;
  filter: drop-shadow(0 0 2px rgba(244, 233, 220, 0.55));
}

@keyframes starsTwinkle {
  from {
    opacity: 0.55;
  }

  to {
    opacity: 0.95;
  }
}

@keyframes starsBlink {
  0%,
  100% {
    opacity: 0;
  }
  20% {
    opacity: 0.95;
  }
  45% {
    opacity: 0.2;
  }
  65% {
    opacity: 0.85;
  }
  85% {
    opacity: 0.1;
  }
}

@media (prefers-reduced-motion: reduce) {
  .hero__stars::before,
  .hero__stars::after,
  .site-footer__stars::before,
  .site-footer__stars::after {
    animation: none;
    opacity: 0.4;
  }
}

.hero__inner {
  position: relative;
  z-index: 2;
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  padding: 90px clamp(20px, 4vw, 60px) 40px;
  text-align: center;
  gap: 0.7rem;
  min-height: 0;
}

.hero__date {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 0.74rem;
  letter-spacing: 0.55em;
  text-transform: uppercase;
  color: rgba(244, 233, 220, 0.75);
  margin: 0;
}

.hero__eyebrow {
  font-family: var(--serif);
  font-style: italic;
  font-size: clamp(0.95rem, 1.25vw, 1.15rem);
  letter-spacing: 0.04em;
  color: rgba(244, 233, 220, 0.85);
  margin: 0;
}

/* Central composition: key + Narratipos wordmark */

.hero__brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: clamp(14px, 2vh, 24px);
  margin: 0.4rem auto;
  animation: heroFloat 6s ease-in-out infinite alternate;
}

.hero__key {
  display: block;
  width: auto;
  height: clamp(180px, 32vh, 300px);
  filter: drop-shadow(
      0 0 24px color-mix(in oklab, var(--accent) 45%, transparent)
    )
    drop-shadow(0 12px 30px rgba(0, 0, 0, 0.55));
  transition: filter 1.2s ease;
}

.hero__wordmark {
  display: block;
  width: auto;
  height: clamp(38px, 7vh, 72px);
  max-width: 78vw;
  object-fit: contain;
  filter: drop-shadow(0 4px 16px rgba(0, 0, 0, 0.5));
}

@keyframes heroFloat {
  from {
    transform: translateY(0);
  }

  to {
    transform: translateY(-8px);
  }
}

.hero__sub {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.95rem, 1.2vw, 1.1rem);
  color: rgba(244, 233, 220, 0.88);
  line-height: 1.5;
  max-width: 46ch;
  margin: 0.2rem auto 0;
}

.hero__meta {
  margin-top: 0.3rem;
  font-family: var(--sans);
  font-weight: 400;
  font-size: 0.82rem;
  color: rgba(244, 233, 220, 0.7);
}

.hero__meta b {
  color: var(--accent);
  font-weight: 500;
  transition: color 1.2s ease;
}

.hero .cta-row {
  margin-top: 1.1rem;
}

/* ===== Hero CTAs | editorial pair ===== */

/* Primary: solid accent (pivots terra⇄blue) with continuous shimmer */

.hero .cta--terra {
  position: relative;
  overflow: hidden;
  background: var(--accent);
  color: var(--cta-text);
  border-color: var(--accent);
  box-shadow:
    0 10px 30px -12px color-mix(in oklab, var(--accent) 55%, transparent),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  transition:
    transform 0.35s ease,
    box-shadow 1.2s ease,
    letter-spacing 0.35s ease,
    background 1.2s ease,
    border-color 1.2s ease;
}

.hero .cta--terra .icon {
  transition: transform 0.35s cubic-bezier(0.65, 0.05, 0.36, 1);
}

/* Diagonal brightness that travels across the button every 5s */

.hero .cta--terra::after {
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: -30%;
  width: 30%;
  background: linear-gradient(
    120deg,
    rgba(255, 255, 255, 0) 25%,
    rgba(255, 255, 255, 0.55) 50%,
    rgba(255, 255, 255, 0) 75%
  );
  transform: skewX(-25deg);
  pointer-events: none;
  animation: ctaBrillo 5s ease-in-out infinite;
}

.hero .cta--terra:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
  color: var(--cta-text);
  box-shadow:
    0 18px 44px -14px color-mix(in oklab, var(--accent) 95%, transparent),
    0 0 0 6px color-mix(in oklab, var(--accent) 18%, transparent);
  transform: translateY(-2px);
  letter-spacing: 0.36em;
}

.hero .cta--terra:hover .icon {
  transform: translateX(6px);
}

@keyframes ctaBrillo {
  0% {
    left: -30%;
    opacity: 0;
  }

  10% {
    opacity: 1;
  }

  60% {
    left: 130%;
    opacity: 1;
  }

  100% {
    left: 130%;
    opacity: 0;
  }
}

/* Secundario: ghost con underline animated */

.hero .cta:not(.cta--terra) {
  background: transparent;
  border-color: transparent;
  color: rgba(244, 233, 220, 0.85);
  padding: 18px 14px;
  letter-spacing: 0.32em;
  position: relative;
  border-radius: 0;
  transition:
    color 0.25s ease,
    letter-spacing 0.35s ease;
}

.hero .cta:not(.cta--terra)::after {
  content: "";
  position: absolute;
  left: 14px;
  right: 14px;
  bottom: 12px;
  height: 1px;
  background: rgba(244, 233, 220, 0.35);
  transform-origin: left center;
  transition:
    background 0.25s ease,
    transform 0.45s cubic-bezier(0.65, 0.05, 0.36, 1);
}

.hero .cta:not(.cta--terra):hover {
  color: #f4e9dc;
  background: transparent;
  border-color: transparent;
  letter-spacing: 0.36em;
}

.hero .cta:not(.cta--terra):hover::after {
  background: #d4845f;
  transform: scaleX(1.04);
}

@media (prefers-reduced-motion: reduce) {
  .hero .cta--terra::after {
    display: none;
  }
}

/* =========================================================
   AMBIENTE | eco del hero en otras secciones
   - .amb-wine   → superficie burgundy profundo (continuidad del hero)
   - .amb-stars  → capa de stars + halo terra sutil
   - .amb-mark   → rotating brand watermark octagon, very slow
   All three can be combined. Designed not to compete with the content.
========================================================= */

.amb-wine {
  background: var(--wine);
}

.amb-wine + .amb-wine {
  /* dos secciones burgundy seguidas: rule terra entre ambas */

  border-top: 1px solid var(--wine-line);
}

/* Layer de stars tenue (much less dense than the hero, to avoid stealing focus) */

.amb-stars {
  position: relative;
  isolation: isolate;
}

.amb-stars > * {
  position: relative;
  z-index: 2;
}

.amb-stars::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(
      1px 1px at 14% 22%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 78% 14%,
      rgba(244, 233, 220, 0.45) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.2px 1.2px at 32% 78%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 62% 36%,
      rgba(244, 233, 220, 0.35) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 88% 64%,
      rgba(244, 233, 220, 0.4) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 6% 56%,
      rgba(244, 233, 220, 0.35) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.2px 1.2px at 46% 8%,
      rgba(244, 233, 220, 0.45) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 72% 90%,
      rgba(244, 233, 220, 0.35) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 38% 48%,
      rgba(212, 132, 95, 0.3) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 18% 92%,
      rgba(244, 233, 220, 0.3) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 94% 32%,
      rgba(244, 233, 220, 0.35) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.3px 1.3px at 76% 70%,
      rgba(212, 132, 95, 0.4) 50%,
      transparent 100%
    );
  /* attenuation toward the center (does not compete with text) and fade on top/bottom borders so the seam between sections is not visible */

  -webkit-mask:
    radial-gradient(
      ellipse 60% 60% at 50% 50%,
      rgba(0, 0, 0, 0.35) 0%,
      #000 75%
    ),
    linear-gradient(
      180deg,
      transparent 0%,
      transparent 8%,
      #000 30%,
      #000 70%,
      transparent 92%,
      transparent 100%
    );
  -webkit-mask-composite: source-in;
  mask:
    radial-gradient(
      ellipse 60% 60% at 50% 50%,
      rgba(0, 0, 0, 0.35) 0%,
      #000 75%
    ),
    linear-gradient(
      180deg,
      transparent 0%,
      transparent 8%,
      #000 30%,
      #000 70%,
      transparent 92%,
      transparent 100%
    );
  mask-composite: intersect;
  opacity: 0.55;
  animation: ambStars 9s ease-in-out infinite alternate;
}

@keyframes ambStars {
  from {
    opacity: 0.4;
  }

  to {
    opacity: 0.7;
  }
}

/* Halo warm (accent) very wide, as a continuation of the hero warmth.
   Usa --accent en color-mix so that pivote al cambiar de theme. */

.amb-stars.amb-glow::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 70% 50% at 50% 0%,
      color-mix(in oklab, var(--accent) 18%, transparent) 0%,
      transparent 60%
    ),
    radial-gradient(
      ellipse 70% 50% at 50% 100%,
      rgba(92, 15, 27, 0.3) 0%,
      transparent 65%
    );
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 6%,
    #000 28%,
    #000 72%,
    transparent 94%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 6%,
    #000 28%,
    #000 72%,
    transparent 94%,
    transparent 100%
  );
  transition: background 1.2s ease;
}

/* Brand watermark octagon: subtle but perceptible, giant, slowly rotating */

.amb-mark {
  position: relative;
  isolation: isolate;
}

.amb-mark > * {
  position: relative;
  z-index: 2;
}

.amb-mark::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(900px, 90vmax);
  aspect-ratio: 1/1;
  z-index: 0;
  pointer-events: none;
  transform: translate(-50%, -50%);
  /* the octagon is drawn with a double border via clip-path + box-shadow inset */

  border: 1.5px solid color-mix(in oklab, var(--accent) 32%, transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in oklab, var(--accent) 8%, transparent),
    inset 0 0 80px color-mix(in oklab, var(--accent) 6%, transparent);
  clip-path: polygon(
    50% 0,
    85.36% 14.64%,
    100% 50%,
    85.36% 85.36%,
    50% 100%,
    14.64% 85.36%,
    0 50%,
    14.64% 14.64%
  );
  animation: ambMark 60s linear infinite;
  opacity: 0.95;
  transition:
    border-color 1.2s ease,
    box-shadow 1.2s ease;
}

/* Inner concentric octagon to reinforce the brand motif */

.amb-mark::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(560px, 56vmax);
  aspect-ratio: 1/1;
  z-index: 0;
  pointer-events: none;
  transform: translate(-50%, -50%);
  border: 1px solid color-mix(in oklab, var(--accent) 18%, transparent);
  clip-path: polygon(
    50% 0,
    85.36% 14.64%,
    100% 50%,
    85.36% 85.36%,
    50% 100%,
    14.64% 85.36%,
    0 50%,
    14.64% 14.64%
  );
  animation: ambMarkInner 90s linear infinite reverse;
  opacity: 0.85;
  transition: border-color 1.2s ease;
}

@keyframes ambMark {
  from {
    transform: translate(-50%, -50%) rotate(0);
  }

  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}

@keyframes ambMarkInner {
  from {
    transform: translate(-50%, -50%) rotate(0);
  }

  to {
    transform: translate(-50%, -50%) rotate(360deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .amb-stars::before,
  .amb-mark::after,
  .amb-mark::before {
    animation: none;
  }
}

/* =========================================================
   MANIFIESTO
========================================================= */

#para-quien {
  content-visibility: auto;
  contain-intrinsic-size: 1px 1200px;
}

.manifiesto {
  background: var(--wine);
  text-align: center;
  padding-block: clamp(72px, 9vw, 120px);
}

.manifiesto h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.9rem, 4vw, 3.2rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.32;
  color: var(--white);
  margin: 0 auto;
  max-width: 24ch;
}

.manifiesto h2 .br {
  display: block;
  margin-top: 0.45em;
}

.manifiesto h2 em {
  font-style: italic;
  color: var(--paper-2);
  font-weight: 500;
  letter-spacing: 0.16em;
}

/* =========================================================
   EDITORIAL (foto + text)
========================================================= */

#que-es {
  content-visibility: auto;
  contain-intrinsic-size: 1px 1200px;
}

.editorial {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(40px, 7vw, 110px);
  align-items: center;
}

.editorial__photo {
  position: relative;
  aspect-ratio: 3/4;
  overflow: hidden;
  border-radius: 4px; /* discreet, not organic */

  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.5);
}

.editorial__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.editorial__photo-credit {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 28px 20px 14px;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: rgba(244, 233, 220, 0.82);
  text-align: left;
  background: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.55) 100%);
  pointer-events: none;
  z-index: 2;
}

@media (max-width: 720px) {
  .editorial__photo-credit {
    padding: 20px 14px 10px;
    font-size: 0.62rem;
    letter-spacing: 0.02em;
  }
}

.editorial p {
  color: var(--paper);
  margin: 0 0 0.9rem;
  text-align: justify;
  hyphens: auto;
  font-size: 0.95rem;
  line-height: 1.65;
}

.editorial p.eyebrow {
  color: var(--accent);
  margin: 0 0 0.8em;
  text-align: left;
  font-size: 0.72rem;
  line-height: 1.4;
}

.editorial .lede {
  margin: 0 0 1.6rem;
  text-align: left;
}

.editorial .h-title {
  text-align: left;
}

.autor__body p {
  text-align: justify;
  hyphens: auto;
}

/* Cierre resaltado de bloques editoriales (para-quien, que-es)
   — quote block with an accent top rule, serif typography,
   more visual weight to anchor the key idea. */

.editorial__cierre {
  position: relative;
  margin-top: 2.2rem;
  padding: 1.4rem 0 1.4rem 1.4rem;
  border-left: 2px solid var(--accent);
  /* Block normal (no flex) so that los text nodes y el <em> respeten
     el word-spacing/letter-spacing y no quede el "ser patrimonio" pegado. */
  display: block;
  color: var(--white);
  font-family: var(--serif);
  font-size: clamp(1.05rem, 1.45vw, 1.25rem);
  line-height: 1.45;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  text-align: left;
  hyphens: none;
  transition: border-color 1.2s ease;
}

.editorial__cierre em {
  font-style: italic;
  color: var(--accent);
  letter-spacing: 0.04em;
  transition: color 1.2s ease;
}

.editorial__cierre--serif {
  letter-spacing: 0.04em;
  text-transform: none;
  font-style: italic;
}

/* =========================================================
   QUE APRENDERAS
========================================================= */

.aprenderas {
  background: var(--wine-2);
  position: relative;
  overflow: hidden;
  isolation: isolate;
}

/* Brand watermark giant octagon in the background (full size, clamped so
   nunca se recorte por la altura del viewport) */

.aprenderas {
  min-height: min(100vh, 1080px);
}

.aprenderas::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 0;
  pointer-events: none;
  width: min(980px, 92vw, 92vh);
  height: min(980px, 92vw, 92vh);
  transform: translate(-50%, -50%);
  border: 1.5px solid color-mix(in oklab, var(--accent) 22%, transparent);
  box-shadow:
    inset 0 0 0 1px color-mix(in oklab, var(--accent) 8%, transparent),
    inset 0 0 120px color-mix(in oklab, var(--accent) 10%, transparent);
  clip-path: polygon(
    50% 0,
    85.36% 14.64%,
    100% 50%,
    85.36% 85.36%,
    50% 100%,
    14.64% 85.36%,
    0 50%,
    14.64% 14.64%
  );
  animation: ambMark 80s linear infinite;
  transition:
    border-color 1.2s ease,
    box-shadow 1.2s ease;
}

@media (prefers-reduced-motion: reduce) {
  .aprenderas::before {
    animation: none;
  }
}

/* Veladuras radiales laterales tipo hero */

.aprenderas::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 38% 55% at 0% 50%,
      color-mix(in oklab, var(--accent) 16%, transparent) 0%,
      transparent 65%
    ),
    radial-gradient(
      ellipse 38% 55% at 100% 50%,
      rgba(92, 15, 27, 0.35) 0%,
      transparent 65%
    ),
    radial-gradient(
      ellipse 70% 40% at 50% 100%,
      rgba(10, 2, 4, 0.55) 0%,
      transparent 65%
    );
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 6%,
    #000 28%,
    #000 72%,
    transparent 94%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 6%,
    #000 28%,
    #000 72%,
    transparent 94%,
    transparent 100%
  );
  transition: background 1.2s ease;
}

.aprenderas > * {
  position: relative;
  z-index: 2;
}

.aprenderas .col-narrow {
  width: var(--col);
}

.aprenderas__list {
  margin-top: 3.2rem;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(26px, 2.8vw, 42px);
}

.aprende {
  position: relative;
  padding: 44px 40px 38px;
  background: rgba(10, 3, 6, 0.45);
  border: 1px solid var(--wine-line);
  border-radius: 4px;
  display: flex;
  flex-direction: column;
  gap: 20px;
  transition:
    border-color 1.2s ease,
    background 1.2s ease,
    transform 0.35s ease;
}

.aprende:hover {
  transform: translateY(-3px);
  border-color: color-mix(in oklab, var(--accent) 55%, transparent);
  background: rgba(10, 3, 6, 0.7);
}

.aprende__num {
  font-family: var(--serif);
  font-style: italic;
  font-weight: 400;
  font-size: 2.2rem;
  color: var(--accent);
  letter-spacing: 0.08em;
  line-height: 1;
  transition: color 1.2s ease;
}

.aprende__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.15rem, 1.5vw, 1.35rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--white);
  line-height: 1.3;
  margin: 0;
}

.aprende__lead {
  font-family: var(--sans);
  font-weight: 400;
  font-size: clamp(0.95rem, 1.05vw, 1.02rem);
  color: var(--white);
  line-height: 1.6;
  letter-spacing: 0.01em;
  margin: 0;
  text-align: justify;
  hyphens: auto;
}

.aprende__lead strong {
  font-family: var(--serif);
  color: var(--accent);
  font-weight: 500;
  letter-spacing: 0.01em;
  transition: color 1.2s ease;
}

.aprende__note {
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.92rem;
  color: var(--paper-2);
  line-height: 1.55;
  padding-top: 14px;
  border-top: 1px solid var(--wine-line);
  margin: 0;
  text-align: justify;
  hyphens: auto;
  transition: border-color 1.2s ease;
}

@media (max-width: 900px) {
  .aprenderas__list {
    grid-template-columns: 1fr;
    gap: 18px;
  }
}

/* =========================================================
   8 NARRATIPOS | brand rosette tinted by color
========================================================= */

.narratipos {
  background: var(--wine);
  text-align: center;
}

.narratipos__grid {
  margin-top: 4.5rem;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 50px 30px;
  max-width: 1040px;
  margin-inline: auto;
}

.narratipo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  padding: 14px 8px;
}

.narratipo__icon {
  width: 128px;
  height: 128px;
  background: var(--c);
  display: grid;
  place-items: center;
  border-radius: 6px;
  transition: transform 0.35s ease;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.45);
  position: relative;
  overflow: hidden;
}

.narratipo__icon::after {
  /* subtle vignette to add depth */

  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at 30% 25%,
    rgba(255, 255, 255, 0.18),
    transparent 65%
  );
  pointer-events: none;
}

.narratipo__icon img {
  width: 78%;
  height: auto;
  position: relative;
  z-index: 1;
}

.narratipo:hover .narratipo__icon {
  transform: scale(1.06);
}

.narratipo__name {
  font-family: var(--serif);
  font-size: 0.92rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--paper);
}

/* =========================================================
   CERTIFICACION | 8 MÓDULOS (cintas de color)
========================================================= */

.certificacion {
  background: var(--wine);
  position: relative;
}

.modulos {
  margin-top: 0;
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
  background: transparent;
}

.modulo {
  position: relative;
  padding: 48px 40px 48px 78px;
  background: linear-gradient(
    180deg,
    color-mix(in oklab, color-mix(in oklab, var(--wine-2) 88%, #000) 28%, transparent) 0%,
    color-mix(in oklab, color-mix(in oklab, var(--wine) 92%, #000) 28%, transparent) 100%
  );
  border: 1px solid var(--wine-line);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.08),
    0 18px 40px rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(12px) saturate(140%) brightness(115%);
  transition:
    background 0.35s ease,
    border-color 0.35s ease,
    transform 0.35s ease;
}

.modulo::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    color-mix(in oklab, var(--c) 18%, transparent) 0%,
    color-mix(in oklab, var(--c) 6%, transparent) 100%
  );
  opacity: 0;
  transition: opacity 0.35s ease;
  pointer-events: none;
}

.modulo:hover {
  border-color: color-mix(in oklab, var(--c) 35%, var(--wine-line));
}

.modulo:hover::before {
  opacity: 1;
}

.modulo > * {
  position: relative;
  z-index: 1;
}

.modulo__band {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 5px;
  background: var(--c);
}

.modulo__mockup {
  display: block;
  width: 100%;
  max-width: 240px;
  height: auto;
  margin: 0 auto 18px;
  aspect-ratio: 1 / 1;
  object-fit: contain;
  object-position: center;
  filter: drop-shadow(0 14px 32px rgba(0, 0, 0, 0.4));
  opacity: 1;
  transition:
    opacity 0.35s ease,
    filter 0.35s ease;
}

.modulo:hover .modulo__mockup {
  opacity: 0.7;
  filter: drop-shadow(0 10px 24px rgba(0, 0, 0, 0.55));
}

@media (max-width: 720px) {
  .modulo__mockup {
    max-width: 200px;
    margin-bottom: 10px;
  }
}

.modulo__num {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.7rem;
  letter-spacing: 0.4em;
  text-transform: uppercase;
  color: var(--c);
  margin-bottom: 0.6rem;
}

.modulo__title {
  font-family: var(--serif);
  font-weight: 400;
  font-size: 1.4rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--white);
  margin: 0 0 0.9rem;
}

.modulo__sub {
  font-size: 0.9rem;
  color: var(--paper-2);
  display: flex;
  flex-wrap: wrap;
  gap: 6px 14px;
  margin-bottom: 1.1rem;
}

.modulo__sub span + span::before {
  content: "|";
  color: var(--c);
  margin-right: 14px;
  opacity: 0.7;
}

.modulo__desc {
  color: var(--paper);
  font-size: 0.95rem;
  line-height: 1.65;
  margin: 0;
}

/* =========================================================
   MOMENTOS NARRATIPOS (calendario)
   - banda navy como en la brochure
========================================================= */

.momentos {
  background: var(--navy);
  position: relative;
  overflow: hidden;
}

.momentos::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/3765c2e7-6585-4030-aa02-5ac926b4853b.jpg")
    center/cover no-repeat;
  opacity: 0.45;
  mix-blend-mode: multiply;
  filter: brightness(0.5) contrast(1.05);
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0%,
    #000 14%,
    #000 86%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0%,
    #000 14%,
    #000 86%,
    transparent 100%
  );
}

.momentos::after {
  /* veil dark adicional para reforce la profundidad */

  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(5, 8, 16, 0.55) 0%,
    rgba(5, 8, 16, 0.25) 50%,
    rgba(5, 8, 16, 0.65) 100%
  );
  pointer-events: none;
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 8%,
    #000 30%,
    #000 70%,
    transparent 92%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 8%,
    #000 30%,
    #000 70%,
    transparent 92%,
    transparent 100%
  );
}

.momentos > * {
  position: relative;
  z-index: 2;
}

.momentos__list {
  margin-top: 4rem;
  border-top: 1px solid rgba(255, 255, 255, 0.18);
}

.momento {
  display: grid;
  grid-template-columns: 160px 160px 1fr;
  gap: 30px;
  align-items: center;
  padding: 28px 0;
  border-bottom: 1px solid rgba(255, 255, 255, 0.18);
}

.momento__day {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.7);
}

.momento__date {
  font-family: var(--serif);
  font-size: 1.4rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--white);
}

.momento__title {
  font-family: var(--serif);
  font-size: 1.1rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--paper);
}

.momento__title em {
  color: var(--white);
  font-style: italic;
  letter-spacing: 0.08em;
}

/* =========================================================
   BONOS | mockups reales de la brochure
========================================================= */

.bonos {
  background: var(--wine);
  position: relative;
}

.bonos__grid {
  margin-top: 5rem;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 28px;
}

.bono {
  position: relative;
  display: flex;
  flex-direction: column;
  background: color-mix(in oklab, var(--ink) 85%, transparent);
  border: 1px solid rgba(255, 255, 255, 0.08);
  border-radius: 4px;
  overflow: hidden;
  cursor: pointer;
  backdrop-filter: blur(8px) saturate(120%);
  transition:
    transform 0.35s ease,
    border-color 0.35s ease,
    box-shadow 0.35s ease;
}

/* Overlay dark uniforme sobre la image para nivelar tarjetas con
   images de tones muy distintos (ej. documentos blancos vs. fotos darks) */
.bono::before {
  content: "";
  position: absolute;
  inset: 0;
  background: rgba(5, 10, 20, 0.28);
  pointer-events: none;
  z-index: 1;
}

.bono:hover {
  transform: translateY(-4px);
  border-color: color-mix(in oklab, var(--accent) 60%, transparent);
  box-shadow:
    0 24px 48px -24px rgba(0, 0, 0, 0.8),
    0 0 0 1px color-mix(in oklab, var(--accent) 30%, transparent);
}

.bono:focus-visible {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in oklab, var(--accent) 35%, transparent);
}

.bono__visual {
  display: block;
  width: 100%;
  aspect-ratio: 3/4;
  background: var(--ink);
  object-fit: cover;
  object-position: center top;
  transition: transform 0.8s cubic-bezier(0.65, 0.05, 0.36, 1);
}

.bono:hover .bono__visual {
  transform: scale(1.03);
}

.bono__caption {
  padding: 18px 20px 22px;
  text-align: center;
  background: var(--ink);
  position: relative;
  z-index: 2;
}

.bono__label {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.66rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 0.3rem;
  transition: color 1.2s ease;
}

.bono__name {
  font-family: var(--serif);
  font-size: 1.05rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--white);
  /* Reservamos altura de 2 l\u00edneas reales (line-height heredado) para
     que todos los cards de la fila tengan la misma altura final y no
     quede hueco entre la image y el caption en cards de una sola l\u00ednea. */
  min-height: 2lh;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Variant para first names largos que no caben con el tracking est\u00e1ndar */
.bono__name--tight {
  letter-spacing: 0.1em;
  white-space: nowrap;
}

.bono__hint {
  display: block;
  margin-top: 0.6rem;
  font-family: var(--sans);
  font-size: 0.62rem;
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.4);
}

/* =========================================================
   BONO MODAL | popup con vista ampliada de la brochure
========================================================= */

.bono-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 5vh 4vw;
  background: rgba(5, 2, 4, 0.88);
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
  transition:
    opacity 0.4s ease,
    visibility 0s linear 0.4s;
}

.bono-modal.is-open {
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  backdrop-filter: blur(14px) saturate(120%);
  -webkit-backdrop-filter: blur(14px) saturate(120%);
  transition:
    opacity 0.4s ease,
    visibility 0s linear 0s;
}

.bono-modal__dialog {
  position: relative;
  max-width: min(620px, 90vw);
  max-height: 90vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 18px;
  transform: translateY(24px) scale(0.97);
  transition: transform 0.5s cubic-bezier(0.65, 0.05, 0.36, 1);
}

.bono-modal.is-open .bono-modal__dialog {
  transform: translateY(0) scale(1);
}

.bono-modal__image {
  display: block;
  max-width: 100%;
  max-height: 78vh;
  width: auto;
  height: auto;
  object-fit: contain;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 40px 80px -30px rgba(0, 0, 0, 0.9);
}

.bono-modal__caption {
  font-family: var(--serif);
  font-size: 0.95rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--paper);
  text-align: center;
}

.bono-modal__caption b {
  color: var(--sky);
  font-weight: 500;
  transition: color 1.2s ease;
}

.bono-modal__close {
  position: absolute;
  top: -44px;
  right: 0;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid rgba(255, 255, 255, 0.3);
  color: var(--paper);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  transition:
    background 0.25s ease,
    border-color 0.25s ease,
    transform 0.25s ease;
}

@media (hover: hover) {
  .bono-modal__close:hover {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--ink);
    transform: rotate(90deg);
  }
}

@media (max-width: 720px) {
  .bono-modal {
    padding: 16px;
    align-items: flex-start;
    /* Blocka scroll touch insidel modal */
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: auto;
  }

  .bono-modal__dialog {
    max-width: 100%;
    max-height: calc(100vh - 32px);
    width: 100%;
    margin-top: 56px;
    gap: 14px;
  }

  .bono-modal__image {
    max-height: calc(100vh - 200px);
    width: 100%;
  }

  .bono-modal__close {
    /* Dentro del dialog, esquina superior derecha de la propia image,
       always visible and at a tap-friendly size (44x44) */
    top: 10px;
    right: 10px;
    width: 44px;
    height: 44px;
    font-size: 1.5rem;
    background: rgba(10, 10, 12, 0.78);
    border-color: rgba(255, 255, 255, 0.5);
    color: var(--white);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    transform: none;
  }

  /* Anula cualquier hover heredado (el tap deja hover sticky en iOS) */
  .bono-modal__close:hover,
  .bono-modal__close:focus {
    background: rgba(10, 10, 12, 0.78);
    border-color: rgba(255, 255, 255, 0.5);
    color: var(--white);
    transform: none;
  }

  .bono-modal__close:active {
    background: var(--accent);
    border-color: var(--accent);
    color: var(--ink);
  }

  .bono-modal__caption {
    font-size: 0.8rem;
    padding: 0 8px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .bono-modal,
  .bono-modal__dialog,
  .bono-modal__close {
    transition: none;
  }
}

/* =========================================================
   INVESTMENT (pricing) | now in navy blue with constellation,
   mismo look-and-feel que la antigua banda Momentos
========================================================= */

.inversion {
  background: var(--navy);
  text-align: center;
  position: relative;
  overflow: hidden;
}

.inversion::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/3765c2e7-6585-4030-aa02-5ac926b4853b.jpg")
    center/cover no-repeat;
  opacity: 0.45;
  mix-blend-mode: multiply;
  filter: brightness(0.5) contrast(1.05);
  pointer-events: none;
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 6%,
    #000 28%,
    #000 72%,
    transparent 94%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 6%,
    #000 28%,
    #000 72%,
    transparent 94%,
    transparent 100%
  );
}

.inversion::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    180deg,
    rgba(5, 8, 16, 0.55) 0%,
    rgba(5, 8, 16, 0.25) 50%,
    rgba(5, 8, 16, 0.65) 100%
  );
  pointer-events: none;
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 8%,
    #000 30%,
    #000 70%,
    transparent 92%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0%,
    transparent 8%,
    #000 30%,
    #000 70%,
    transparent 92%,
    transparent 100%
  );
}

.inversion > * {
  position: relative;
  z-index: 2;
}

.inversion .silver {
  color: var(--white);
}

.inversion .eyebrow {
  color: rgba(255, 255, 255, 0.78);
}

.inversion .lede {
  color: rgba(255, 255, 255, 0.82);
}

/* Bonuses inside the Investment block: same navy palette */

.inversion .bono {
  background: rgba(8, 16, 28, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.18);
  backdrop-filter: blur(14px) saturate(150%) brightness(115%);
  -webkit-backdrop-filter: blur(14px) saturate(150%) brightness(115%);
}

.inversion .bono:hover {
  border-color: rgba(255, 255, 255, 0.32);
  box-shadow:
    0 24px 48px -24px rgba(0, 0, 0, 0.6),
    0 0 0 1px rgba(255, 255, 255, 0.18);
}

.inversion .bono:focus-visible {
  border-color: rgba(255, 255, 255, 0.5);
  box-shadow: 0 0 0 3px rgba(157, 196, 224, 0.25);
}

.inversion .bono__visual {
  background: rgba(8, 16, 28, 0.55);
}

.inversion .bono__caption {
  background: rgba(8, 16, 28, 0.55);
}

.inversion .bono__caption::before {
  background: rgba(255, 255, 255, 0.4);
}

.inversion .bono:hover .bono__caption::before {
  background: var(--sky);
}

.inversion .bono__label {
  color: var(--sky);
}

.inversion .bono__hint {
  color: rgba(255, 255, 255, 0.5);
}

/* Main CTA inside Investment: navy/sky tone */

.inversion .cta--terra {
  background: var(--sky);
  color: var(--navy-deep);
  border-color: var(--sky);
  box-shadow:
    0 10px 30px -12px rgba(157, 196, 224, 0.6),
    inset 0 0 0 1px rgba(255, 255, 255, 0.12);
}

.inversion .cta--terra:hover {
  background: #bfd8ec;
  border-color: #bfd8ec;
  color: var(--navy-deep);
  box-shadow:
    0 18px 44px -14px rgba(157, 196, 224, 0.85),
    0 0 0 6px rgba(157, 196, 224, 0.2);
}

.precio-card {
  margin: 3rem auto 0;
  max-width: 580px;
  padding: clamp(40px, 5vw, 56px) clamp(28px, 4vw, 52px);
  background: rgba(8, 16, 28, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.14);
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  border-radius: 4px;
  transition:
    background 1.2s ease,
    border-color 1.2s ease;
  text-align: center;
}

.precio-card .cta-row {
  margin-top: 1.8rem;
}

.precio__breakdown {
  text-align: left;
  margin: 0 auto 1.8rem;
  max-width: 380px;
  padding: 0;
  list-style: none;
  font-family: var(--sans);
  font-size: 0.92rem;
  color: var(--paper-2);
}

.precio__breakdown li {
  display: flex;
  justify-content: space-between;
  padding: 8px 0;
  border-bottom: 1px dashed rgba(255, 255, 255, 0.18);
}

.precio__breakdown li span:last-child {
  color: var(--white);
  font-weight: 500;
}

.precio__headline {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  margin: 1.2rem 0 1.6rem;
  position: relative;
}

.precio__headline::before,
.precio__headline::after {
  content: "";
  flex: 0 0 48px;
  height: 1px;
  background: rgba(255, 255, 255, 0.18);
}

.precio__strike {
  font-family: var(--serif);
  font-size: 1.05rem;
  letter-spacing: 0.16em;
  color: rgba(255, 255, 255, 0.45);
  text-decoration: line-through;
  text-decoration-thickness: 1px;
}

.precio__split {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: clamp(18px, 3vw, 40px);
  margin: 0.4rem auto 1.2rem;
  max-width: 460px;
}

.precio__col {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
}

.precio__amount {
  font-family: var(--serif);
  font-size: clamp(2.2rem, 4.6vw, 3.2rem);
  letter-spacing: 0.05em;
  color: var(--white);
  line-height: 1;
}

.precio__cap {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.62rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
}

.precio__divider {
  width: 1px;
  align-self: stretch;
  background: linear-gradient(
    to bottom,
    transparent 0%,
    rgba(255, 255, 255, 0.35) 22%,
    rgba(255, 255, 255, 0.35) 78%,
    transparent 100%
  );
}

.precio__iva {
  margin-top: 6px;
  display: block;
  font-size: 0.58rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.45);
  font-weight: 400;
}

@media (max-width: 520px) {
  .precio__split {
    grid-template-columns: 1fr;
    gap: 18px;
  }

  .precio__divider {
    height: 1px;
    width: 60%;
    justify-self: center;
    background: linear-gradient(
      to right,
      transparent,
      rgba(255, 255, 255, 0.35),
      transparent
    );
  }
}

.precio__providers {
  margin-top: 1.6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 18px;
}

.precio__providers img {
  display: block;
  height: 20px;
  width: auto;
  opacity: 0.78;
  object-fit: contain;
}

.precio__providers img[alt="seQura"] {
  height: 22px;
}

.precio__providers-sep {
  width: 1px;
  height: 18px;
  background: rgba(255, 255, 255, 0.22);
  display: inline-block;
}

/* Footer wordmark La Boutique de Mentores (typographic lockup) */

.site-footer__wordmark {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  font-family: var(--serif);
  text-transform: uppercase;
  letter-spacing: 0.32em;
  color: rgba(255, 255, 255, 0.92);
  line-height: 1.05;
}

.site-footer__wordmark-line {
  font-size: 0.78rem;
  font-weight: 400;
}

.site-footer__wordmark-line:first-child {
  font-size: 0.92rem;
  font-weight: 500;
}

.site-footer__brand-mark:hover .site-footer__wordmark {
  color: var(--white);
}

/* =========================================================
   AUTOR
========================================================= */

.autor {
  background: var(--wine);
}

.autor .editorial__photo {
  aspect-ratio: 4/5;
}

.autor__body p {
  font-size: 0.92rem;
  line-height: 1.65;
}

.autor__body p + p {
  margin-top: 1rem;
}

/* Hyperlink inline en cuerpo editorial: blanco + bold + underline accent.
   Inspired by the treatment of the "Certificación" strong in the next paragraph. */
.autor__body a.link-inline,
.link-inline {
  color: var(--white);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, var(--accent) 70%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition:
    text-decoration-color 0.25s ease,
    color 0.25s ease;
}

.autor__body a.link-inline:hover,
.link-inline:hover {
  text-decoration-color: var(--accent);
  color: #fff;
}

/* Hyperlink inline en cuerpo editorial: blanco + bold + underline accent.
   Inspired by the treatment of the "Certificación" strong in the next paragraph. */
.autor__body a.link-inline,
.link-inline {
  color: var(--white);
  text-decoration: underline;
  text-decoration-color: color-mix(in oklab, var(--accent) 70%, transparent);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  transition:
    text-decoration-color 0.25s ease,
    color 0.25s ease;
}

.autor__body a.link-inline:hover,
.link-inline:hover {
  text-decoration-color: var(--accent);
  color: #fff;
}

/* =========================================================
   CIERRE
========================================================= */

#acceso {
  content-visibility: auto;
  contain-intrinsic-size: 1px 1200px;
}

.cierre {
  position: relative;
  overflow: hidden;
  text-align: center;
  padding-block: clamp(70px, 8vw, 110px);
  background: #000;
}

.cierre::before {
  content: "";
  position: absolute;
  inset: 0;
  background: url("https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/ce5c0e3f-a2a5-423f-a42c-6d0997a7f1bb.jpg")
    center/cover no-repeat;
  opacity: 0.28;
  -webkit-mask-image: linear-gradient(
    180deg,
    transparent 0%,
    #000 14%,
    #000 86%,
    transparent 100%
  );
  mask-image: linear-gradient(
    180deg,
    transparent 0%,
    #000 14%,
    #000 86%,
    transparent 100%
  );
}

.cierre::after {
  content: "";
  position: absolute;
  inset: 0;
  background: radial-gradient(
    ellipse 70% 55% at 50% 50%,
    rgba(0, 0, 0, 0.55) 0%,
    rgba(0, 0, 0, 0.72) 70%,
    rgba(0, 0, 0, 0.88) 100%
  );
  pointer-events: none;
}

.cierre > * {
  position: relative;
  z-index: 2;
}

.cierre__symbol {
  display: block;
  margin: 0 auto 2.4rem;
  height: 64px;
  width: auto;
  opacity: 0.92;
}

.cierre__claim {
  margin: 0 auto;
  max-width: none;
  font-family: var(--sans);
  font-weight: 400;
  color: rgba(255, 255, 255, 0.9);
}

.cierre__line {
  display: block;
  font-size: clamp(0.82rem, 1.1vw, 0.96rem);
  letter-spacing: 0.22em;
  line-height: 2;
  text-transform: uppercase;
}

.cierre__unico {
  display: block;
  margin-top: 0.4rem;
  font-family: var(--sans);
  font-weight: 500;
  font-size: clamp(0.86rem, 1.15vw, 1rem);
  letter-spacing: 0.22em;
  line-height: 2;
  text-transform: uppercase;
  color: var(--white);
}

.cierre__unico em {
  font-style: normal;
  font-weight: 500;
  color: var(--white);
  position: relative;
  padding: 0 0.08em 0.22em;
  background-image: linear-gradient(
    to right,
    transparent,
    var(--accent) 18%,
    var(--accent) 82%,
    transparent
  );
  background-repeat: no-repeat;
  background-size: 100% 1px;
  background-position: 0 100%;
}

.cierre .cta-row {
  margin-top: 3rem;
}

/* =========================================================
   FAQ
========================================================= */

#faq {
  content-visibility: auto;
  contain-intrinsic-size: 1px 1200px;
}

.faq {
  background: #000;
}

.faq__list {
  margin-top: 3.5rem;
  border-top: 1px solid var(--wine-line);
}

.faq__item {
  border-bottom: 1px solid var(--wine-line);
}

.faq__item summary {
  list-style: none;
  cursor: pointer;
  padding: 26px 0;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 24px;
  font-family: var(--serif);
  font-size: 1.05rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--white);
  transition: color 0.25s ease;
}

.faq__item summary:hover {
  color: var(--accent);
}

.faq__item summary::-webkit-details-marker {
  display: none;
}

.faq__item summary::after {
  content: "+";
  color: var(--paper-2);
  font-family: var(--serif);
  font-size: 1.6rem;
  font-weight: 300;
  line-height: 1;
  display: inline-block;
  transition:
    transform 0.45s cubic-bezier(0.65, 0.05, 0.36, 1),
    color 0.25s ease;
  transform-origin: center;
}

.faq__item[open] summary::after {
  transform: rotate(45deg);
  color: var(--accent);
}

/* nota: el estado .is-open lo aplica JS para poder animate height */

/* Animation de despliegue: el panel anima su altura via JS
   (height 0 ↔ scrollHeight) to guarantee a cross-browser transition. */

.faq__panel {
  overflow: hidden;
  height: 0;
  transition: height 0.55s cubic-bezier(0.65, 0.05, 0.36, 1);
  will-change: height;
}

.faq__item.is-open .faq__panel {
  /* height set inline by JS */
}

.faq__panel > .faq__answer {
  opacity: 0;
  transform: translateY(-12px) scale(0.985);
  transition:
    opacity 0.45s ease 0.08s,
    transform 0.55s cubic-bezier(0.65, 0.05, 0.36, 1) 0.08s;
}

.faq__item.is-open .faq__panel > .faq__answer {
  opacity: 1;
  transform: translateY(0) scale(1);
}

.faq__answer {
  padding: 0 0 26px;
  color: var(--paper-2);
  max-width: 62ch;
  margin-inline: auto;
  text-align: justify;
  text-align-last: center;
  hyphens: auto;
  font-size: 0.98rem;
  line-height: 1.7;
  position: relative;
}

.faq__answer::before {
  content: "";
  position: absolute;
  left: 0;
  top: -4px;
  width: 24px;
  height: 1px;
  background: var(--accent);
  transform-origin: left center;
  transform: scaleX(0);
  transition: transform 0.55s cubic-bezier(0.65, 0.05, 0.36, 1) 0.12s;
}

.faq__item.is-open .faq__answer::before {
  transform: scaleX(1);
}

.faq__item summary {
  transition:
    color 0.25s ease,
    padding-left 0.35s cubic-bezier(0.65, 0.05, 0.36, 1),
    background 0.35s ease;
}

.faq__item.is-open summary {
  padding-left: 14px;
  color: var(--accent);
}

.faq__item.is-open summary::after {
  transform: rotate(45deg);
  color: var(--accent);
}

@media (prefers-reduced-motion: reduce) {
  .faq__panel,
  .faq__panel > .faq__answer,
  .faq__item summary::after,
  .faq__answer::before,
  .faq__item summary {
    transition: none;
  }
}

/* =========================================================
   FOOTER | hero-like atmosphere
========================================================= */

.site-footer {
  position: relative;
  background: #000;
  padding: clamp(40px, 5.5vw, 68px) 0 clamp(22px, 2.4vw, 36px);
  overflow: hidden;
  isolation: isolate;
}

/* Layer de stars tipo hero */

.site-footer__stars {
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background-image:
    radial-gradient(
      1px 1px at 12% 18%,
      rgba(244, 233, 220, 0.85) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 82% 12%,
      rgba(244, 233, 220, 0.7) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.4px 1.4px at 26% 76%,
      rgba(244, 233, 220, 0.95) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 60% 32%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 90% 58%,
      rgba(244, 233, 220, 0.65) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 8% 50%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.2px 1.2px at 44% 8%,
      rgba(244, 233, 220, 0.75) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 70% 88%,
      rgba(244, 233, 220, 0.6) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 36% 44%,
      rgba(212, 132, 95, 0.45) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 18% 92%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 96% 30%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 52% 62%,
      rgba(244, 233, 220, 0.45) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.3px 1.3px at 76% 72%,
      rgba(212, 132, 95, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 4% 28%,
      rgba(244, 233, 220, 0.6) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 32% 22%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 64% 18%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 88% 84%,
      rgba(244, 233, 220, 0.55) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 22% 36%,
      rgba(244, 233, 220, 0.4) 50%,
      transparent 100%
    ),
    radial-gradient(
      1px 1px at 56% 80%,
      rgba(244, 233, 220, 0.5) 50%,
      transparent 100%
    ),
    radial-gradient(
      1.5px 1.5px at 14% 64%,
      rgba(244, 233, 220, 0.85) 50%,
      transparent 100%
    );
  /* Atenuar las stars justo low los logos/text central, pero mantenerlas visibles en los flancos */

  -webkit-mask: radial-gradient(
    ellipse 32% 55% at 50% 50%,
    rgba(0, 0, 0, 0.3) 0%,
    #000 70%
  );
  mask: radial-gradient(
    ellipse 32% 55% at 50% 50%,
    rgba(0, 0, 0, 0.3) 0%,
    #000 70%
  );
  opacity: 0.85;
  animation: starsTwinkle 6s ease-in-out infinite alternate;
}

/* Layers extra de stars \u201cdestello\u201d para el footer:
   appearsn y desappearsn con un shine sutil, como respiraciones del cielo. */
.site-footer__stars::before,
.site-footer__stars::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  -webkit-mask: inherit;
  mask: inherit;
}

.site-footer__stars::before {
  background-image:
    radial-gradient(1.6px 1.6px at 14% 26%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.4px 1.4px at 80% 18%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.5px 1.5px at 38% 70%, #f4e9dc 50%, transparent 100%),
    radial-gradient(
      1.2px 1.2px at 92% 52%,
      rgba(212, 132, 95, 0.95) 50%,
      transparent 100%
    ),
    radial-gradient(1.4px 1.4px at 8% 80%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.5px 1.5px at 60% 14%, #f4e9dc 50%, transparent 100%);
  opacity: 0;
  animation: starsBlink 8s ease-in-out infinite 1.2s;
  filter: drop-shadow(0 0 2px rgba(244, 233, 220, 0.5));
}

.site-footer__stars::after {
  background-image:
    radial-gradient(1.4px 1.4px at 26% 12%, #f4e9dc 50%, transparent 100%),
    radial-gradient(
      1.6px 1.6px at 72% 62%,
      rgba(212, 132, 95, 0.9) 50%,
      transparent 100%
    ),
    radial-gradient(1.2px 1.2px at 50% 30%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.5px 1.5px at 86% 84%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.3px 1.3px at 12% 56%, #f4e9dc 50%, transparent 100%),
    radial-gradient(1.4px 1.4px at 34% 90%, #f4e9dc 50%, transparent 100%);
  opacity: 0;
  animation: starsBlink 11s ease-in-out infinite 3.5s;
}

/* Subtle hero-like veil — warm brown like the rest of the piece */

.site-footer::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    radial-gradient(
      ellipse 32% 30% at 50% 50%,
      rgba(80, 32, 20, 0.18) 0%,
      transparent 70%
    ),
    radial-gradient(
      ellipse 120% 60% at 50% 100%,
      rgba(26, 5, 8, 0.55) 0%,
      transparent 60%
    );
}

/* Granulado tenue */

.site-footer::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background-image:
    radial-gradient(
      circle at 20% 20%,
      rgba(244, 233, 220, 0.04) 0,
      transparent 1px
    ),
    radial-gradient(
      circle at 70% 60%,
      rgba(244, 233, 220, 0.03) 0,
      transparent 1px
    ),
    radial-gradient(
      circle at 40% 80%,
      rgba(244, 233, 220, 0.03) 0,
      transparent 1px
    );
  background-size:
    3px 3px,
    5px 5px,
    4px 4px;
  opacity: 0.5;
}

.site-footer > * {
  position: relative;
  z-index: 2;
}

.site-footer > .site-footer__stars {
  position: absolute;
  z-index: 0;
}

@media (prefers-reduced-motion: reduce) {
  .site-footer__stars {
    animation: none;
  }
}

.site-footer__top {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 36px;
  flex-wrap: wrap;
}

.site-footer__brand-mark {
  display: flex;
  align-items: center;
}

.site-footer__brand-mark img {
  display: block;
  height: 30px;
  width: auto;
  opacity: 0.5;
  filter: brightness(0) invert(1);
  transition: opacity 0.3s ease;
}

.site-footer__brand-mark img:hover {
  opacity: 0.8;
}

.site-footer__signature {
  display: block;
  height: 30px;
  width: auto;
  opacity: 0.5;
  filter: brightness(0) invert(1);
  transition: opacity 0.3s ease;
}

.site-footer__signature:hover {
  opacity: 0.8;
}

/* Block central | rights centrados verticalmente entre logos e Innki */

.site-footer__center {
  margin-top: clamp(16px, 2vw, 24px);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(16px, 2vw, 24px);
}

.site-footer__legal {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  font-size: 0.62rem;
  letter-spacing: 0.18em;
  color: rgba(255, 255, 255, 0.45);
  text-transform: uppercase;
}

.site-footer__legal a {
  color: rgba(255, 255, 255, 0.45);
  transition: color 0.25s ease;
}

.site-footer__legal a:hover {
  color: #fff;
}

.site-footer__sites {
  font-size: 0.66rem;
  letter-spacing: 0.24em;
}

.site-footer__sites a {
  color: rgba(255, 255, 255, 0.6);
}

.site-footer__sites a:hover {
  color: var(--accent);
}

@media (max-width: 640px) {
  .site-footer__top {
    /* Mantener los logos de La Boutique y David Sobrino en la misma line
       en mobile, con menos gap pero sin saltar a columna. */
    flex-direction: row;
    gap: 24px;
  }
}

/* Credit row | just below the Boutique and David Sobrino logos */
.site-footer__credit-row {
  margin-top: clamp(20px, 2.5vw, 28px);
  display: flex;
  justify-content: center;
}

/* Innki Tech credit | pill with full logo */

.site-footer__rule {
  display: none;
}

.site-footer__credit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  text-decoration: none;
  margin-top: 0;
  padding: 9px 18px;
  border: 1px solid rgba(255, 255, 255, 0.28);
  border-radius: 999px;
  background: transparent;
  transition:
    opacity 0.35s ease,
    transform 0.35s ease,
    border-color 0.35s ease,
    background 0.35s ease;
  opacity: 0.5;
}

.site-footer__credit:hover,
.site-footer__credit:focus-visible {
  opacity: 0.8;
  transform: translateY(-1px);
  border-color: rgba(255, 255, 255, 0.5);
  background: rgba(255, 255, 255, 0.04);
  outline: none;
}

.site-footer__credit-label {
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.55rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.78);
}

.site-footer__credit-sep {
  display: none;
}

.site-footer__credit-logo {
  display: block;
  height: 22px;
  width: auto;
  filter: brightness(0) invert(1);
  transition: transform 0.55s cubic-bezier(0.65, 0.05, 0.36, 1);
}

.site-footer__credit-stage {
  position: relative;
  display: inline-block;
  height: 22px;
  min-width: 88px;
}

.site-footer__credit-stage .site-footer__credit-logo {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%) scale(0.92);
  opacity: 0;
  transition:
    opacity 0.9s cubic-bezier(0.65, 0.05, 0.36, 1),
    transform 0.9s cubic-bezier(0.65, 0.05, 0.36, 1);
}

.site-footer__credit-stage .site-footer__credit-logo.is-active {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}

.site-footer__credit:hover .site-footer__credit-stage .is-active {
  transform: translate(-50%, -50%) scale(1.04);
}

/* =========================================================
   HERO | CTA stack (programa belowl primario)
========================================================= */

.hero .cta-row {
  flex-direction: column;
  align-items: center;
  gap: 14px;
}

.hero .cta-row .cta--ghost {
  background: transparent;
  border: none;
  padding: 6px 12px;
  font-size: 0.74rem;
  letter-spacing: 0.34em;
  color: rgba(244, 233, 220, 0.78);
  position: relative;
  transition:
    color 0.3s ease,
    letter-spacing 0.3s ease;
}

.hero .cta-row .cta--ghost::after {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -2px;
  height: 1px;
  width: 32px;
  background: color-mix(in oklab, var(--accent) 70%, transparent);
  transform: translateX(-50%) scaleX(0.5);
  transform-origin: center;
  transition:
    transform 0.35s ease,
    background 1.2s ease,
    width 0.35s ease;
}

.hero .cta-row .cta--ghost:hover {
  color: var(--white);
  letter-spacing: 0.4em;
}

.hero .cta-row .cta--ghost:hover::after {
  transform: translateX(-50%) scaleX(1);
  width: 56px;
}

/* =========================================================
   BACK TO TOP | arrow sutil flotante
========================================================= */

.back-to-top {
  position: fixed;
  right: 24px;
  bottom: 24px;
  z-index: 90;
  width: 48px;
  height: 48px;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(10, 3, 6, 0.55);
  border: 0;
  padding: 0;
  color: var(--paper);
  backdrop-filter: blur(10px) saturate(120%);
  -webkit-backdrop-filter: blur(10px) saturate(120%);
  cursor: pointer;
  opacity: 0;
  visibility: hidden;
  transform: translateY(8px);
  transition:
    opacity 0.35s ease,
    transform 0.35s ease,
    visibility 0s linear 0.35s,
    background 0.25s ease,
    color 0.25s ease;
}

/* Scroll progress — SVG ring (mirrors lesp02-registro's geh-clc-btt).
   The track is a faint white circle that draws the full perimeter;
   the fill is a terra circle whose stroke-dashoffset animates from
   the full circumference (empty) to 0 (full) as JS feeds it the
   scroll percentage. Rotated -90° so the fill starts at 12 o'clock
   and grows clockwise. */
.back-to-top__ring {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  transform: rotate(-90deg);
  overflow: visible;
}

.back-to-top__ring circle {
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
}

.back-to-top__ring-track {
  stroke: rgba(255, 255, 255, 0.12);
}

.back-to-top__ring-fill {
  stroke: var(--accent);
  /* Circumference for r=22 ≈ 138.23. JS writes stroke-dashoffset =
     138.23 × (1 - progress) so the arc fills as you scroll down. */
  stroke-dasharray: 138.23;
  stroke-dashoffset: 138.23;
  transition: stroke-dashoffset 0.1s linear;
}

.back-to-top.is-visible {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
  transition:
    opacity 0.35s ease,
    transform 0.35s ease,
    visibility 0s linear 0s,
    background 0.25s ease,
    border-color 1.2s ease,
    color 0.25s ease;
}

.back-to-top:hover {
  background: var(--accent);
  border-color: var(--accent);
  color: var(--ink);
}

.back-to-top .icon {
  width: 14px;
  height: 14px;
  display: block;
  transition: transform 0.35s ease;
}

.back-to-top:hover .icon {
  transform: translateY(-2px);
}

@media (max-width: 720px) {
  .back-to-top {
    right: 16px;
    bottom: 16px;
    width: 38px;
    height: 38px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .back-to-top {
    transition:
      opacity 0.2s ease,
      visibility 0s;
  }
}

/* =========================================================
   NARRATIPOS RADAR | concentric octagon with axes
   (sustituye al grid de 8 llaves: una sola llave al center)
========================================================= */

.narra-radar {
  position: relative;
  max-width: 480px;
  margin: 3.5rem auto 0;
  aspect-ratio: 1/1;
}

.narra-radar svg {
  width: 100%;
  height: 100%;
  display: block;
  overflow: visible;
}

.narra-radar__ring,
.narra-radar__axis {
  fill: none;
  stroke: rgba(244, 233, 220, 0.14);
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

.narra-radar__ring--outer {
  stroke: color-mix(in oklab, var(--accent) 55%, rgba(244, 233, 220, 0.25));
  stroke-width: 1.4;
  transition: stroke 1.2s ease;
}

.narra-radar__dot {
  fill: rgba(244, 233, 220, 0.28);
}

.narra-radar__sector {
  fill: var(--c);
  opacity: 0.1;
  transition: opacity 0.35s ease;
}

.narra-radar__vertex:hover .narra-radar__sector {
  opacity: 0.22;
}

.narra-radar__label {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  fill: var(--c);
  pointer-events: none;
}

.narra-radar__center {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  width: 18%;
  height: auto;
  filter: drop-shadow(
    0 0 18px color-mix(in oklab, var(--accent) 60%, transparent)
  );
  transition:
    filter 1.2s ease,
    transform 0.6s ease;
  pointer-events: none;
  opacity: 0.95;
}

.narra-radar:hover .narra-radar__center {
  transform: translate(-50%, -50%) scale(1.04);
}

.narra-radar__caption {
  margin-top: 1.4rem;
  text-align: center;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  color: var(--paper-2);
}

@media (max-width: 720px) {
  .narra-radar {
    max-width: 92vw;
  }

  .narra-radar__label {
    font-size: 9px;
    letter-spacing: 0.2em;
  }
}

/* =========================================================
   Animaciones sutiles
========================================================= */

.fade-up {
  opacity: 0;
  transform: translateY(36px);
  transition:
    opacity 0.95s cubic-bezier(0.2, 0.7, 0.2, 1),
    transform 0.95s cubic-bezier(0.2, 0.7, 0.2, 1);
  will-change: opacity, transform;
}

.fade-up.in {
  opacity: 1;
  transform: none;
  will-change: auto;
}

.fade-up.delay-1 {
  transition-delay: 0.12s;
}

.fade-up.delay-2 {
  transition-delay: 0.22s;
}

.fade-up.delay-3 {
  transition-delay: 0.32s;
}

.modulo,
.bono {
  transition:
    background 0.35s ease,
    transform 0.45s ease,
    border-color 0.35s ease;
}

.modulo:hover {
  transform: translateY(-2px);
}

@media (max-width: 720px) {
  /* On mobile we trim duration and scroll a bit
     so the animation feels agile without losing presence. */
  .fade-up {
    transform: translateY(28px);
    transition:
      opacity 0.7s cubic-bezier(0.2, 0.7, 0.2, 1),
      transform 0.7s cubic-bezier(0.2, 0.7, 0.2, 1);
  }

  .fade-up.delay-1 {
    transition-delay: 0.06s;
  }
  .fade-up.delay-2 {
    transition-delay: 0.12s;
  }
  .fade-up.delay-3 {
    transition-delay: 0.18s;
  }
}

@media (prefers-reduced-motion: reduce) {
  .fade-up {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .hero__brand {
    animation: none;
  }
}

/* =========================================================
   Responsive
========================================================= */

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

  /* En mobile la foto siempre va al final del bloque editorial,
     independientemente del orden DOM (en "qu\u00e9 es" la foto va primero
     en HTML para alternar el layout en desktop). */
  .editorial__photo {
    order: 2;
  }

  .modulos {
    grid-template-columns: 1fr;
    gap: 18px;
  }

  .bonos__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .narratipos__grid {
    grid-template-columns: repeat(2, 1fr);
  }

  .momento {
    grid-template-columns: 1fr;
    gap: 6px;
    text-align: left;
  }

  .site-header nav {
    display: none;
  }

  .nav-toggle {
    display: block;
  }

  /* Editorial photos: more natural aspect ratio on mobile */

  .editorial__photo {
    aspect-ratio: 4/5;
  }

  .autor .editorial__photo {
    aspect-ratio: 4/5;
  }

  /* Editorial: center headings and give text more breathing room */

  .editorial .h-title,
  .editorial p.eyebrow,
  .editorial .lede {
    text-align: center;
  }

  .editorial .rule {
    justify-content: center;
  }

  .editorial p {
    font-size: 1rem;
    line-height: 1.7;
  }

  /* Modules: menos padding interior forzado */

  .modulo {
    padding: 36px 24px 36px 40px;
  }

  /* Investment: prices vertically stacked for better readability */

  .precio__split {
    flex-direction: column;
    gap: 18px;
  }

  .precio__divider {
    width: 40%;
    height: 1px;
    margin-inline: auto;
  }

  .precio-card {
    padding: 36px 22px;
  }

  /* Bonuss: force 1 columna so that no se aprieten */

  .bonos__grid {
    grid-template-columns: 1fr;
  }

  /* Hero mobile */

  .hero {
    height: 100vh;
    max-height: 100vh;
  }

  .hero__inner {
    padding: 80px 18px 30px;
    gap: 0.55rem;
  }

  .hero__brand {
    gap: 10px;
  }

  .hero__key {
    height: clamp(140px, 28vh, 220px);
  }

  .hero__wordmark {
    height: clamp(28px, 5.5vh, 48px);
    max-width: 84vw;
  }

  .hero__meta {
    font-size: 0.74rem;
  }

  .hero .cta-row {
    margin-top: 0.8rem;
    gap: 10px;
  }

  .hero .cta {
    padding: 14px 22px;
    font-size: 0.66rem;
  }
}

/* Logo La Boutique de Mentores en footer (paridad visual con firma-david) */

.site-footer__brand-mark {
  display: inline-flex;
  align-items: center;
}

.site-footer__brand-mark img {
  height: 36px;
  width: auto;
  opacity: 0.5;
  filter: none;
  transition: opacity 0.3s ease;
}

.site-footer__brand-mark img:hover {
  opacity: 0.8;
}

/* =========================================================
   LEGAL PAGES (Privacy / Cookies policy)
========================================================= */

.legal {
  background: var(--ink);
  padding-block: clamp(64px, 8vw, 120px);
}

.legal .col-narrow {
  width: min(760px, 92vw);
}

.legal__head {
  text-align: center;
  margin-bottom: clamp(40px, 5vw, 64px);
}

.legal__updated {
  display: block;
  margin-top: 1rem;
  font-family: var(--sans);
  font-weight: 300;
  font-size: 0.7rem;
  letter-spacing: 0.34em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.5);
}

.legal__body {
  font-family: var(--sans);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.8;
  color: var(--paper-2);
  /* Legal copy reads with justified text — the dense long-form
     prose looks heavier and more "official" with both edges aligned. */
  text-align: justify;
  text-justify: inter-word;
  hyphens: auto;
  -webkit-hyphens: auto;
}

/* But: tighten last lines so we don't get a single orphan word in
   the final paragraph of each section, and never justify headings or
   list bullets — those stay left-aligned. */
.legal__body h2,
.legal__body h3,
.legal__body li {
  text-align: left;
}

.legal__body h2 {
  font-family: var(--serif);
  font-weight: 400;
  font-size: clamp(1.2rem, 2vw, 1.55rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--white);
  margin: 3rem 0 1rem;
}

.legal__body h2:first-of-type {
  margin-top: 0;
}

.legal__body h3 {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.92rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--paper);
  margin: 2rem 0 0.6rem;
}

.legal__body p {
  margin: 0 0 1rem;
  text-align: justify;
  text-justify: inter-word;
  hyphens: auto;
}

.legal__body ul {
  list-style: none;
  padding: 0;
  margin: 0 0 1.4rem;
}

.legal__body ul li {
  position: relative;
  padding-left: 1.4rem;
  margin-bottom: 0.5rem;
}

.legal__body ul li::before {
  content: "·";
  position: absolute;
  left: 0.4rem;
  top: 0;
  color: var(--accent);
  font-weight: 600;
}

.legal__body a {
  color: var(--accent);
  border-bottom: 1px solid rgba(212, 132, 95, 0.3);
  transition: border-color 0.3s ease;
}

.legal__body a:hover {
  border-bottom-color: var(--accent);
}

.legal__body strong {
  color: var(--white);
  font-weight: 500;
}

.legal__body em {
  color: var(--paper);
  font-style: italic;
}

.legal__contact {
  margin-top: 2rem;
  padding: 1.6rem 1.8rem;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid var(--line);
  border-radius: 4px;
}

.legal__contact p {
  margin: 0.3rem 0;
  text-align: left;
  hyphens: none;
}

.legal__back {
  display: inline-flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 3rem;
  font-family: var(--sans);
  font-size: 0.72rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--paper-2);
  border-bottom: none !important;
}

.legal__back:hover {
  color: var(--accent);
}

/* ── Static logo on legal pages ── */

.legal__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 40px 0 32px;
  text-decoration: none;
}

.legal__logo img {
  width: 44px;
  height: auto;
  opacity: 0.9;
}

.legal__logo span {
  font-family: var(--serif);
  font-size: 1.35rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--paper);
  text-transform: uppercase;
}

/* ─────────────────────────────────────────────────────────────────────────
   .lp — Generic layout for simple landing pages
   Estructura paralela a .legal, reutilizable en cualquier landing
   ───────────────────────────────────────────────────────────────────────── */

.lp {
  background: transparent;
  flex: 1;
  padding-block: clamp(64px, 8vw, 120px);
}

.lp .col-narrow {
  width: min(760px, 92vw);
}

.lp__logo {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 40px 0 32px;
  text-decoration: none;
}

.lp__logo img {
  width: 44px;
  height: auto;
  opacity: 0.9;
}

.lp__logo span {
  font-family: var(--serif);
  font-size: 1.35rem;
  font-weight: 500;
  letter-spacing: 0.12em;
  color: var(--paper);
  text-transform: uppercase;
}

.lp__head {
  text-align: center;
  margin-bottom: clamp(40px, 5vw, 64px);
}

.lp__body {
  font-family: var(--sans);
  font-weight: 300;
  font-size: 1rem;
  line-height: 1.8;
  color: var(--paper-2);
}

/* Tweaks mobile — usa !important para vencer estilos inline ad-hoc */
@media (max-width: 640px) {
  .lp {
    padding-block: clamp(40px, 10vw, 64px) !important;
  }

  .lp .col-narrow {
    width: min(760px, 94vw);
  }

  .lp__head .h-title {
    font-size: 1.65rem !important;
    line-height: 1.2 !important;
  }

  .lp__head p:not(.eyebrow) {
    font-size: 0.95rem !important;
    line-height: 1.6 !important;
  }

  .lp__head p br {
    display: none;
  }

  .lp__body .form-section,
  .lp__body section.form-section {
    padding: 1.2rem 0.75rem !important;
  }

  .lp__body .form-section .h-title {
    font-size: 1.25rem !important;
  }

  .lp__body .form-header {
    margin-bottom: 1.25rem !important;
  }

  .lp__body .form-header p {
    font-size: 0.92rem !important;
  }
}

/* =========================================================
   MEDIA-CARD | bordered media frame
   Reusable container for either a portrait image (poster) or
   a 16:9 video iframe. Same shadow + border treatment as the
   other terra cards in the system. Introduced for the
   crea-tu-narrativa variants but generic enough for any
   landing that needs to feature a single piece of media.
   ========================================================= */

.media-card {
  position: relative;
  width: 100%;
  max-width: min(540px, 92%);
  margin: clamp(20px, 2.4vw, 36px) auto clamp(28px, 3vw, 44px);
  /* `.media-card` lives on a <section> element; the brand
     `section { padding: clamp(56px, 6.5vw, 96px) 0 }` rule would
     otherwise add 56-96px top/bottom padding INSIDE the card,
     creating dark bars above and below the iframe (the "marco"
     the user reported on mobile). Force padding to 0 so the
     iframe wrapper fills the card edge-to-edge. */
  padding: 0;
  border-radius: 10px;
  overflow: hidden;
  box-shadow:
    0 30px 80px rgba(0, 0, 0, 0.55),
    0 0 0 1px color-mix(in oklab, var(--accent) 22%, transparent);
}

/* Portrait variant — uses the image's own aspect ratio (typically
   2:3 for posters). Caps width tighter than the default. */
.media-card--poster {
  max-width: min(420px, 88%);
}

.media-card--poster img {
  display: block;
  width: 100%;
  height: auto;
  filter: saturate(1.05);
}

/* 16:9 variant — for video iframes. Uses padding-top hack AS WELL
   AS aspect-ratio so it stays a strict 16:9 on older mobile Safari. */
.media-card--video { background: #000; }

.media-card__frame {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: #000;
  overflow: hidden;
}

/* Fallback for browsers that don't support aspect-ratio
   (Chrome <88, Firefox <89, Safari <15 — Mar 2021 cutoff).
   `@supports not (aspect-ratio: 1)` only matches in those engines. */
@supports not (aspect-ratio: 1) {
  .media-card__frame {
    height: 0;
    padding-top: 56.25%;     /* 9 / 16 */
  }
}

.media-card__frame iframe {
  position: absolute !important;
  inset: 0 !important;
  width: 100% !important;
  height: 100% !important;
  border: 0 !important;
  display: block !important;
}

@media (max-width: 640px) {
  .media-card {
    margin: clamp(16px, 4vw, 28px) auto clamp(20px, 4vw, 32px);
  }
}

/* =========================================================
   EDITORIAL-PHOTO | portrait + corner credit
   Vertical portrait inside a soft-shadowed frame with a
   bottom-left credit caption and a top-edge fade-in that
   blends into the surrounding wine background. Introduced
   for the David Sobrino bio, generic enough for any author
   or testimonial portrait.
   ========================================================= */

.editorial-photo {
  position: relative;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: 6px;
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.55);
  margin: 0;
  max-width: 420px;
}

.editorial-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Top fade — blends the photo's first ~14% into the surrounding
   wine background so the section seam doesn't read as a hard edge.
   The gradient is tuned to wine-2 (#240810). */
.editorial-photo::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(
    180deg,
    rgba(36, 8, 16, 0.9) 0%,
    rgba(36, 8, 16, 0.35) 8%,
    transparent 16%
  );
  border-radius: inherit;
}

.editorial-photo__credit {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 28px 20px 14px;
  font-family: var(--serif);
  font-style: italic;
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  color: rgba(244, 233, 220, 0.82);
  text-align: left;
  background: linear-gradient(180deg, transparent 0%, rgba(0, 0, 0, 0.6) 100%);
  pointer-events: none;
  z-index: 2;
}

/* =========================================================
   IS-* | viewport visibility helpers
   Generic state classes for hiding elements above/below
   the 960px breakpoint. Used by landings that ship a single
   element in two positions (one for mobile, one for desktop)
   to avoid duplicating media or splitting layouts.
   ========================================================= */

.is-mobile-only { display: none; }

@media (max-width: 960px) {
  .is-mobile-only { display: block; }
  .is-desktop-only { display: none; }
}

/* =========================================================
   AUDIO-PLAYER | custom <audio> with brand controls
   Wraps a native <audio> element (kept hidden) and exposes
   three controls: a round terra play/pause button, a
   clickable progress bar with current/duration time, and
   a mute toggle. JS init runs automatically from the brand
   behaviour bundle on every `.audio-player` figure.
   ========================================================= */

/* Layout: [▶ play] [current time] [progress] [duration]
            [🔊 mute toggle] [volume slider] — single row.
   Mobile (≤480px): the volume slider hides; mute toggle stays. */
.audio-player {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 18px;
  margin: 0;
  max-width: 560px;
  width: 100%;
  position: relative;
  background:
    repeating-linear-gradient(45deg,
      rgba(255, 255, 255, 0.012) 0 6px,
      transparent 6px 14px),
    rgba(10, 3, 6, 0.55);
  border: 1px solid var(--wine-line);
  border-radius: 10px;
  box-shadow:
    0 16px 40px rgba(0, 0, 0, 0.4),
    inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.audio-player__el {
  /* The native <audio> is the source of truth — we use the JS
     API but hide its native chrome so only our controls show. */
  display: none;
}

.audio-player__play {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: var(--accent);
  border: 1px solid var(--accent);
  color: #fff;
  cursor: pointer;
  box-shadow: 0 6px 20px -6px color-mix(in oklab, var(--accent) 70%, transparent);
  transition: background 0.2s ease, transform 0.18s ease, box-shadow 0.2s ease;
}

.audio-player__play:hover {
  background: var(--accent-deep);
  border-color: var(--accent-deep);
  transform: scale(1.04);
}

.audio-player__play svg {
  width: 18px;
  height: 18px;
  display: block;
}

.audio-player__play .audio-player__pause-icon { display: none; }
.audio-player__play.is-playing .audio-player__play-icon { display: none; }
.audio-player__play.is-playing .audio-player__pause-icon { display: block; }

/* Progress row — current time · bar · duration, all on one line. */
.audio-player__progress-row {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

.audio-player__current,
.audio-player__duration {
  font-family: var(--sans);
  font-size: 0.78rem;
  color: var(--paper-2);
  letter-spacing: 0.04em;
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
}

.audio-player__progress {
  flex: 1;
  position: relative;
  height: 6px;
  background: rgba(255, 255, 255, 0.08);
  border-radius: 999px;
  cursor: pointer;
  overflow: hidden;
  min-width: 0;
}

.audio-player__progress-fill {
  position: absolute;
  inset: 0;
  width: 0%;
  background: linear-gradient(90deg, var(--accent), var(--accent-deep));
  border-radius: inherit;
  transition: width 0.1s linear;
}

/* Volume group — speaker mute toggle + tiny horizontal volume bar.
   Bar hides on mobile to save room; toggle stays. */
.audio-player__volume-group {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.audio-player__volume {
  appearance: none;
  -webkit-appearance: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 32px;
  height: 32px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid transparent;
  color: var(--paper-2);
  cursor: pointer;
  transition: color 0.2s ease, background 0.2s ease;
}

.audio-player__volume:hover {
  color: var(--accent);
  background: rgba(255, 255, 255, 0.04);
}

.audio-player__volume svg {
  width: 18px;
  height: 18px;
  display: block;
}

.audio-player__volume .audio-player__mute-icon { display: none; }
.audio-player__volume.is-muted .audio-player__volume-icon { display: none; }
.audio-player__volume.is-muted .audio-player__mute-icon { display: block; }

.audio-player__volume-bar {
  position: relative;
  width: 64px;
  height: 4px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 999px;
  cursor: pointer;
  overflow: hidden;
}

.audio-player__volume-fill {
  position: absolute;
  inset: 0;
  width: 100%;
  background: var(--accent);
  border-radius: inherit;
  transition: width 0.1s linear;
}

@media (max-width: 560px) {
  .audio-player { padding: 12px 14px; gap: 10px; }
  .audio-player__play { width: 38px; height: 38px; }
  .audio-player__play svg { width: 15px; height: 15px; }
  .audio-player__current,
  .audio-player__duration { font-size: 0.7rem; }
  /* The volume slider doesn't fit comfortably — keep the mute
     toggle, drop the slider. */
  .audio-player__volume-bar { display: none; }
}

@media (max-width: 380px) {
  .audio-player__current,
  .audio-player__duration { display: none; }
}

/* =========================================================
   MEDIA-TOGGLE | tabs to switch between video / audio
   Pair of segmented buttons (Vídeo · Audio) with the active
   one highlighted in terra. Used by the pildora landings to
   let the user choose how to consume the content. Designed
   to live above any `.media-card--video` or `.audio-player`.
   ========================================================= */

.media-toggle {
  display: inline-flex;
  padding: 4px;
  margin: 0 auto clamp(16px, 2vw, 24px);
  background: rgba(10, 3, 6, 0.55);
  border: 1px solid var(--wine-line);
  border-radius: 999px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  gap: 2px;
}

.media-toggle__btn {
  appearance: none;
  -webkit-appearance: none;
  border: 0;
  background: transparent;
  color: var(--paper-2);
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.74rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  padding: 9px 22px;
  border-radius: 999px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  transition: background 0.25s ease, color 0.25s ease;
}

.media-toggle__btn:hover {
  color: var(--paper);
}

.media-toggle__btn.is-active {
  background: var(--accent);
  color: var(--cta-text, #1a0508);
  box-shadow: 0 4px 14px -4px color-mix(in oklab, var(--accent) 60%, transparent);
}

.media-toggle__btn svg {
  width: 14px;
  height: 14px;
  display: block;
}

/* The two panels the toggle switches between. Hide all by
   default; only `.is-active` shows. JS sets is-active on load
   based on ?t= or defaults to "video". Width is 100% so the
   panel doesn't collapse when its parent is a flex column with
   `align-items: center` (the typical pildora layout). */
.media-panel { display: none; }
.media-panel.is-active {
  display: flex;
  justify-content: center;
  width: 100%;
}

/* =========================================================
   FOLLOW-UP PAGE | shared styles for gracias / pildora
   Shared building blocks for any post-conversion landing
   (gracias, pildoras, confirmaciones). Each of these used to
   live in landings/narratipos/crea-tu-narrativa-gracias/
   includes/style.css; promoted here so the pildora landings
   inherit them without duplicating CSS.
   ========================================================= */

/* Every CTA inside a `.ctng-page` keeps its label on one line. */
.ctng-page .cta { white-space: nowrap; }

@media (max-width: 640px) {
  .ctng-page .cta {
    letter-spacing: 0.2em !important;
    padding: 16px 22px !important;
    font-size: 0.68rem !important;
    gap: 10px !important;
  }
}

/* =========================================================
   PILDORA PROGRESS | 3-card series indicator
   Compact row of 3 cards (one per pildora) that shows where
   the user is in the series. Each card carries one of three
   modifiers:

     --current   The pildora being viewed. Terra outline + glow,
                 no link, slightly heavier label.
     --unlocked  A pildora the user has already passed through.
                 Rendered as <a>, full-colour icon, hover lift.
     --locked    A future pildora not yet unlocked. Greyscale,
                 lock icon, opacity 0.5, cursor not-allowed.

   The HTML in each landing decides which modifier each card
   wears — no JS detection. Rule of thumb: pildora N unlocks
   cards 1..N (current = N, all earlier = unlocked).
   ========================================================= */

.pil-progress {
  display: flex;
  gap: clamp(6px, 1.2vw, 12px);
  justify-content: center;
  width: 100%;
  max-width: 340px;
  margin: 0 auto;
  padding: 0;
  list-style: none;
}

.pil-progress__card {
  flex: 1 1 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 10px 8px;
  border-radius: 10px;
  border: 1px solid rgba(212, 132, 95, 0.18);
  background: rgba(239, 234, 224, 0.04);
  color: var(--paper-2);
  text-decoration: none;
  text-align: center;
  position: relative;
  transition:
    border-color 0.35s ease,
    background 0.35s ease,
    transform 0.35s ease,
    box-shadow 0.35s ease,
    color 0.35s ease;
}

.pil-progress__icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  color: var(--paper-2);
}

.pil-progress__icon-svg {
  width: 100%;
  height: 100%;
  display: block;
}

/* Default: show the pill icon, hide the lock. The `--locked`
   modifier (applied by JS based on localStorage state) flips
   the visibility — see below. Both SVGs are baked into the
   HTML at render time so JS doesn't have to inject any markup. */
.pil-progress__card .pil-progress__icon-svg--lock { display: none; }

.pil-progress__card--locked .pil-progress__icon-svg--pill { display: none; }
.pil-progress__card--locked .pil-progress__icon-svg--lock { display: block; }

.pil-progress__label {
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.66rem;
  letter-spacing: 0.22em;
  color: var(--paper-2);
}

/* ── Unlocked: a past pildora the user has already seen ──── */
a.pil-progress__card--unlocked { cursor: pointer; }

a.pil-progress__card--unlocked:hover {
  border-color: rgba(212, 132, 95, 0.55);
  background: rgba(239, 234, 224, 0.08);
  transform: translateY(-2px);
  box-shadow: 0 8px 20px -14px rgba(212, 132, 95, 0.5);
}

a.pil-progress__card--unlocked:hover .pil-progress__label,
a.pil-progress__card--unlocked:hover .pil-progress__icon {
  color: var(--paper);
}

/* ── Current: the pildora being viewed ──────────────────── */
.pil-progress__card--current {
  border-color: var(--accent);
  background: rgba(212, 132, 95, 0.14);
  box-shadow:
    0 0 0 1px var(--accent) inset,
    0 10px 24px -16px rgba(212, 132, 95, 0.65);
  cursor: default;
}

.pil-progress__card--current .pil-progress__label,
.pil-progress__card--current .pil-progress__icon {
  color: var(--accent);
}

.pil-progress__card--current .pil-progress__label {
  font-weight: 600;
}

/* ── Locked: a future pildora the user hasn't reached yet ── */
.pil-progress__card--locked {
  cursor: not-allowed;
  opacity: 0.5;
  background: rgba(239, 234, 224, 0.02);
  border-color: rgba(239, 234, 224, 0.08);
}

.pil-progress__card--locked .pil-progress__icon,
.pil-progress__card--locked .pil-progress__label {
  color: rgba(201, 194, 179, 0.55);
}

@media (max-width: 480px) {
  .pil-progress {
    gap: 6px;
    max-width: 100%;
  }
  .pil-progress__card {
    padding: 8px 6px;
    border-radius: 8px;
  }
  .pil-progress__icon { width: 12px; height: 12px; }
  .pil-progress__label {
    font-size: 0.6rem;
    letter-spacing: 0.18em;
  }
}

@media (max-width: 380px) {
  .ctng-page .cta {
    letter-spacing: 0.14em !important;
    padding: 14px 16px !important;
    font-size: 0.62rem !important;
  }
}

/* Logo block — the Narratipos mark only (no Cinzel wordmark),
   sized for a follow-up page header. */
.ctng-logo {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 0 24px;
  text-decoration: none;
}

.ctng-logo img {
  width: clamp(38px, 3.2vw, 48px);
  height: auto;
  opacity: 0.92;
  filter: drop-shadow(0 4px 14px rgba(0, 0, 0, 0.5))
    drop-shadow(0 0 14px color-mix(in oklab, var(--accent) 30%, transparent));
}

/* Intro paragraph under the page hero (eyebrow + rule + title). */
.ctng-intro {
  text-align: center;
  margin-top: 1.2rem;
  margin-inline: auto;
  color: var(--paper-2);
  font-size: clamp(0.9rem, 1.1vw, 1rem);
  line-height: 1.6;
  max-width: 56ch;
}

/* WhatsApp CTA wrapper — sits directly under the video / audio. */
.ctng-wa-cta {
  display: flex;
  justify-content: center;
  padding: 0;
  margin-top: 0.4rem;
}

/* =========================================================
   WHATSAPP CTA | green button + envelope mask icon
   Shimmer animation matches .cta--hero-anim (uses ctaBrillo).
   ========================================================= */

.cta--whatsapp {
  --wa-green: #25d366;
  --wa-green-deep: #128c7e;
  background: var(--wa-green);
  border-color: var(--wa-green);
  color: #fff;
  letter-spacing: 0.34em;
  white-space: nowrap;
  box-shadow:
    0 10px 30px -12px color-mix(in oklab, var(--wa-green) 55%, transparent),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08);
  transition:
    background 1.2s ease,
    border-color 1.2s ease,
    color 0.25s ease,
    transform 0.35s ease,
    box-shadow 1.2s ease,
    letter-spacing 0.35s ease;
  position: relative;
  overflow: hidden;
}

.cta--whatsapp::after {
  content: "";
  position: absolute;
  top: -20%;
  bottom: -20%;
  left: -30%;
  width: 30%;
  background: linear-gradient(
    120deg,
    rgba(255, 255, 255, 0) 25%,
    rgba(255, 255, 255, 0.45) 50%,
    rgba(255, 255, 255, 0) 75%
  );
  transform: skewX(-25deg);
  pointer-events: none;
  animation: ctaBrillo 5s ease-in-out infinite;
}

.cta--whatsapp:hover {
  background: var(--wa-green-deep);
  border-color: var(--wa-green-deep);
  color: #fff;
  box-shadow:
    0 18px 44px -14px color-mix(in oklab, var(--wa-green) 95%, transparent),
    0 0 0 6px color-mix(in oklab, var(--wa-green) 18%, transparent);
  transform: translateY(-2px);
  letter-spacing: 0.36em;
}

.cta--whatsapp .wa-icon {
  display: inline-block;
  width: 21px;
  height: 21px;
  background-color: currentColor;
  /* The WhatsApp icon stays static on hover — it's a logo, not
     an arrow. Animating it left/right would look unintentional. */
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51-.173-.008-.371-.01-.57-.01-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 01-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 01-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 012.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0012.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 005.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 00-3.48-8.413z'/%3E%3C/svg%3E");
  -webkit-mask-size: contain;
  mask-size: contain;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  flex-shrink: 0;
}

/* =========================================================
   GHL IFRAME WRAPPER | shared form embed chrome + loader
   Used by every landing that embeds a GoHighLevel form via
   <iframe src="https://ghl.../widget/form/…">. The wrapper
   centers the iframe at 440px max and the three-dot loader
   animates while form_embed.js hands control over to the iframe.
   ========================================================= */

.ghl-iframe-wrap {
  width: 100%;
  max-width: 440px;
  margin: 0 auto;
  position: relative;
  background: transparent;
}

.ghl-iframe-wrap iframe {
  width: 100%;
  border: none;
  border-radius: 0;
  display: block;
  background: transparent;
  color-scheme: dark;
  /* Iframe starts invisible and fades in once the loader hides
     (the wrap gets `.is-ready` from the brand JS Form loader init).
     Avoids the abrupt "snap" of the form replacing the dots. */
  opacity: 0;
  transition: opacity 0.5s ease;
}

.ghl-iframe-wrap.is-ready iframe {
  opacity: 1;
}

.ghl-loader {
  position: absolute;
  inset: 0;
  z-index: 10;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 280px;
  background: transparent;
  border-radius: inherit;
  transition: opacity 0.4s ease;
}

.ghl-loader.ghl-loader--out {
  opacity: 0;
  pointer-events: none;
}

.ghl-loader span {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: rgba(201, 194, 179, 0.3);
  animation: ghlDotPulse 1.4s ease-in-out infinite;
}

.ghl-loader span:nth-child(2) { animation-delay: 0.22s; }
.ghl-loader span:nth-child(3) { animation-delay: 0.44s; }

@keyframes ghlDotPulse {
  0%, 80%, 100% { transform: scale(0.65); opacity: 0.35; background: rgba(201, 194, 179, 0.3); }
  40%           { transform: scale(1);    opacity: 1;    background: #d4845f; }
}

/* =========================================================
   PIL-BADGE | pildora narrativa header
   Single badge-style header for the píldora landings.
   Same dot+pill treatment as .event-card__badge but a
   touch larger so it reads as the page title.
   ========================================================= */

.pil-badge {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 11px 24px;
  margin: 1rem auto 0;
  border: 1px solid color-mix(in oklab, var(--accent) 45%, transparent);
  border-radius: 999px;
  font-family: var(--sans);
  font-weight: 500;
  font-size: 0.78rem;
  letter-spacing: 0.32em;
  text-transform: uppercase;
  color: var(--accent);
  background: rgba(10, 3, 6, 0.5);
}

.pil-badge::before {
  content: "";
  width: 7px;
  height: 7px;
  background: var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 0 4px color-mix(in oklab, var(--accent) 22%, transparent);
}

@media (max-width: 480px) {
  .pil-badge {
    font-size: 0.7rem;
    letter-spacing: 0.24em;
    padding: 9px 18px;
  }
}


/* ===== landing | overrides ===== */

/* Landing-specific styles for politica-de-cookies (Narratipos). Empty by default. */

JS

19.2KB
Download

Pega esto en el campo Custom JS de la página GHL. No hace falta vars.js — GHL ya sustituyó los tokens antes de que corra el script.

/* ===== brand | behaviours ===== */
// =============================================================
// NARRATIPOS | brand global behaviours
// =============================================================
// Generic helpers safe to load on every landing of the brand.
// Each IIFE is guarded by an early return when its target
// element is absent — the file does nothing on landings that
// don't need it. Landing-specific behaviour (cert nav, bonos
// modal, price counter, etc.) lives in the landing's own
// includes/script.js.
//
// New helpers added recently:
//   - back-to-top button (universal)
//   - audio-player custom controls
//   - media-toggle (video / audio) for pildora landings
// =============================================================

// =============================================================
// FAQ | Height animation via CSS transition
// =============================================================
// Native <details> elements do not animate height:auto.
// We measure the actual content, animate in px and release to
// auto when the transition ends so it stays responsive.
// =============================================================
(function () {
  document.querySelectorAll(".faq__item").forEach((item) => {
    const summary = item.querySelector("summary");
    const panel = item.querySelector(".faq__panel");
    if (!summary || !panel) return;

    const open = () => {
      item.open = true;
      item.classList.add("is-open");

      panel.style.height = "0px";
      panel.getBoundingClientRect();

      const target = panel.scrollHeight;
      panel.style.height = target + "px";

      const onEnd = (e) => {
        if (e.propertyName !== "height") return;
        panel.style.height = "auto";
        panel.removeEventListener("transitionend", onEnd);
      };
      panel.addEventListener("transitionend", onEnd);
    };

    const close = () => {
      const start = panel.scrollHeight;
      panel.style.height = start + "px";
      panel.getBoundingClientRect();

      panel.style.height = "0px";
      item.classList.remove("is-open");

      const onEnd = (e) => {
        if (e.propertyName !== "height") return;
        item.open = false;
        panel.style.height = "";
        panel.removeEventListener("transitionend", onEnd);
      };
      panel.addEventListener("transitionend", onEnd);
    };

    summary.addEventListener("click", (e) => {
      e.preventDefault();
      if (item.open) close();
      else open();
    });

    if (item.open) {
      item.classList.add("is-open");
      panel.style.height = "auto";
    }
  });
})();

// =============================================================
// Reveal on scroll
// =============================================================
// Adds the .in class to .fade-up elements as they enter
// the viewport. The initial double rAF prevents the elements
// in the first fold from snapping without transition on load.
// =============================================================
(function () {
  const targets = document.querySelectorAll(".fade-up");
  if (!targets.length || !("IntersectionObserver" in window)) return;

  const io = new IntersectionObserver(
    (entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add("in");
          io.unobserve(e.target);
        }
      });
    },
    { rootMargin: "0px 0px -10% 0px", threshold: 0.05 },
  );

  requestAnimationFrame(() =>
    requestAnimationFrame(() => targets.forEach((t) => io.observe(t))),
  );
})();

// =============================================================
// Header | is-scrolled state
// =============================================================
// Adds the is-scrolled class to a fixed/sticky header when the
// user scrolls more than 40px. Uses rAF to avoid blocking the
// main thread.
// =============================================================
(function () {
  const header = document.querySelector(".site-header");
  if (!header) return;

  let ticking = false;

  function check() {
    header.classList.toggle("is-scrolled", window.scrollY > 40);
    ticking = false;
  }

  window.addEventListener(
    "scroll",
    () => {
      if (!ticking) {
        requestAnimationFrame(check);
        ticking = true;
      }
    },
    { passive: true },
  );

  check();
})();

// =============================================================
// Scroll direction | body class for nav animations
// =============================================================
// Adds scroll-up or scroll-down to <body> so the nav can
// animate based on direction. Ignores movements under 4px
// to prevent trackpad jitter.
// =============================================================
(function () {
  let lastY = window.scrollY;
  let ticking = false;

  function check() {
    const y = window.scrollY;
    const delta = y - lastY;
    if (Math.abs(delta) > 4) {
      document.body.classList.toggle("scroll-down", delta > 0);
      document.body.classList.toggle("scroll-up", delta < 0);
      lastY = y;
    }
    ticking = false;
  }

  window.addEventListener(
    "scroll",
    () => {
      if (!ticking) {
        requestAnimationFrame(check);
        ticking = true;
      }
    },
    { passive: true },
  );
})();

// =============================================================
// Back to top | #back-to-top button + SVG ring progress
// =============================================================
// Mirrors the lesp02-registro pattern (geh-clc-btt): SVG circle
// whose `stroke-dashoffset` shrinks from the full circumference
// to 0 as the user scrolls, drawing a terra ring around the
// button. Cleaner than a conic-gradient — crisp anti-aliased
// 2px stroke, no mask needed.
// =============================================================
(function () {
  const btn = document.getElementById("back-to-top");
  if (!btn) return;

  const fill = btn.querySelector(".back-to-top__ring-fill");
  /* Must match the stroke-dasharray declared in CSS for r=22. */
  const CIRC = 138.23;

  let ticking = false;
  const update = () => {
    const y = window.scrollY;
    const max = Math.max(
      1,
      document.documentElement.scrollHeight - window.innerHeight,
    );
    const ratio = Math.max(0, Math.min(1, y / max));
    btn.classList.toggle("is-visible", y > 480);
    if (fill) fill.style.strokeDashoffset = (CIRC * (1 - ratio)).toFixed(2);
    ticking = false;
  };

  window.addEventListener(
    "scroll",
    () => {
      if (!ticking) {
        requestAnimationFrame(update);
        ticking = true;
      }
    },
    { passive: true },
  );
  window.addEventListener("resize", update, { passive: true });
  update();

  btn.addEventListener("click", () => {
    const reduce = window.matchMedia("(prefers-reduced-motion:reduce)").matches;
    window.scrollTo({ top: 0, behavior: reduce ? "auto" : "smooth" });
  });
})();

// =============================================================
// Pause animations when the tab is not visible
// =============================================================
// Adds anim-paused to <body> when the tab is hidden so CSS
// rules can opt elements out of expensive animations.
// =============================================================
(function () {
  const sync = () => {
    document.body.classList.toggle("anim-paused", document.hidden);
  };

  document.addEventListener("visibilitychange", sync);
  sync();
})();

// =============================================================
// Pause hero animations when it leaves the viewport
// =============================================================
// Adds is-out on a .hero section when it scrolls off-screen
// so the hero's own animations can pause. Early-returns on
// landings without a .hero.
// =============================================================
(function () {
  const hero = document.querySelector(".hero");
  if (!hero || !("IntersectionObserver" in window)) return;

  const io = new IntersectionObserver(
    (entries) => {
      const e = entries[0];
      hero.classList.toggle("is-out", !e.isIntersecting);
    },
    { threshold: 0 },
  );

  io.observe(hero);
})();

// =============================================================
// Form loader | three-dot fade-out on GHL form iframe load
// =============================================================
// Pattern ported from guillermoechegaray's geh-clc.js (initFormLoader).
// Each form-using landing ships a `<div id="ghlLoader" class="ghl-loader">`
// with three pulsing dots BEFORE the GHL form iframe. This block listens
// for the iframe's native `load` event and fades the loader out, with a
// 6s safety fallback in case `load` never fires.
// =============================================================
(function () {
  const loader = document.getElementById("ghlLoader");
  if (!loader) return;

  const wrap = loader.closest(".ghl-iframe-wrap");
  let hidden = false;
  const hide = () => {
    if (hidden) return;
    hidden = true;
    /* Two parallel transitions for a clean cross-fade:
       1. The iframe was hidden via `opacity: 0` (brand CSS); adding
          `.is-ready` to the wrap fades it in over 0.5s.
       2. The loader gets `--out` (opacity 0 in CSS) and is removed
          from the DOM 450ms later. */
    if (wrap) wrap.classList.add("is-ready");
    loader.classList.add("ghl-loader--out");
    setTimeout(() => {
      if (loader.parentNode) loader.parentNode.removeChild(loader);
    }, 450);
  };

  const iframe = document.querySelector('iframe[src*="widget/form"]');
  if (iframe) {
    // Tiny delay after load so the form has a beat to paint before we
    // pull the loader away — avoids a brief blank flash.
    iframe.addEventListener("load", () => setTimeout(hide, 200));
  }

  // Safety net — never leave the loader stuck if `load` doesn't fire.
  setTimeout(hide, 6000);
})();

// =============================================================
// Audio player | custom controls for <figure class="audio-player">
// =============================================================
// Wraps a native <audio> element (kept hidden via CSS). Wires
// up play/pause, click-to-seek progress bar, time display, and
// mute toggle. Auto-inits on every .audio-player in the DOM.
// =============================================================
(function () {
  function format(sec) {
    if (!isFinite(sec)) return "0:00";
    const m = Math.floor(sec / 60);
    const s = Math.floor(sec % 60).toString().padStart(2, "0");
    return `${m}:${s}`;
  }

  function init(fig) {
    const audio = fig.querySelector(".audio-player__el");
    const playBtn = fig.querySelector(".audio-player__play");
    const progress = fig.querySelector(".audio-player__progress");
    const fill = fig.querySelector(".audio-player__progress-fill");
    const current = fig.querySelector(".audio-player__current");
    const duration = fig.querySelector(".audio-player__duration");
    const muteBtn = fig.querySelector(".audio-player__volume");
    const volumeBar = fig.querySelector(".audio-player__volume-bar");
    const volumeFill = fig.querySelector(".audio-player__volume-fill");
    if (!audio || !playBtn || !progress || !fill) return;

    const updateDuration = () => {
      if (duration) duration.textContent = format(audio.duration);
    };
    audio.addEventListener("loadedmetadata", updateDuration);
    updateDuration();

    playBtn.addEventListener("click", () => {
      if (audio.paused) audio.play();
      else audio.pause();
    });
    audio.addEventListener("play", () => playBtn.classList.add("is-playing"));
    audio.addEventListener("pause", () => playBtn.classList.remove("is-playing"));
    audio.addEventListener("ended", () => playBtn.classList.remove("is-playing"));

    audio.addEventListener("timeupdate", () => {
      const ratio = audio.duration ? audio.currentTime / audio.duration : 0;
      fill.style.width = `${ratio * 100}%`;
      progress.setAttribute("aria-valuenow", Math.round(ratio * 100));
      if (current) current.textContent = format(audio.currentTime);
    });

    const seek = (e) => {
      const rect = progress.getBoundingClientRect();
      const ratio = Math.max(
        0,
        Math.min(1, (e.clientX - rect.left) / rect.width),
      );
      audio.currentTime = ratio * audio.duration;
    };
    progress.addEventListener("click", seek);

    // Volume slider — click anywhere on the bar to set volume. The
    // bar's fill mirrors `audio.volume` (or 0 if muted). Mute toggle
    // (the speaker button) and the bar stay in sync: muting via the
    // button drops the fill to 0; dragging the bar to >0 unmutes.
    const setVolumeFill = () => {
      if (!volumeFill) return;
      const v = audio.muted ? 0 : audio.volume;
      volumeFill.style.width = `${v * 100}%`;
    };

    if (volumeBar) {
      const setVol = (e) => {
        const rect = volumeBar.getBoundingClientRect();
        const ratio = Math.max(
          0,
          Math.min(1, (e.clientX - rect.left) / rect.width),
        );
        audio.volume = ratio;
        audio.muted = ratio === 0;
        if (muteBtn) muteBtn.classList.toggle("is-muted", audio.muted);
        setVolumeFill();
      };
      volumeBar.addEventListener("click", setVol);
    }

    audio.addEventListener("volumechange", setVolumeFill);
    setVolumeFill();

    if (muteBtn) {
      muteBtn.addEventListener("click", () => {
        audio.muted = !audio.muted;
        muteBtn.classList.toggle("is-muted", audio.muted);
        setVolumeFill();
      });
    }
  }

  document.querySelectorAll(".audio-player").forEach(init);
})();

// =============================================================
// Media toggle | switch between video and audio
// =============================================================
// Wires up <div class="media-toggle"> with two .media-toggle__btn
// children (one with data-target="video", the other "audio")
// to swap the visibility of the two media panels (.media-panel
// with data-media="video" / "audio"). Reads the initial state
// from the ?t= query param (?t=video or ?t=audio); defaults to
// "video" if absent.
// =============================================================
(function () {
  const toggle = document.querySelector(".media-toggle");
  if (!toggle) return;

  const buttons = toggle.querySelectorAll(".media-toggle__btn");
  const panels = document.querySelectorAll(".media-panel");
  if (!buttons.length || !panels.length) return;

  const params = new URLSearchParams(window.location.search);
  const requested = params.get("t");
  const initial = requested === "audio" ? "audio" : "video";

  function pauseAllMedia() {
    document
      .querySelectorAll(".media-panel audio")
      .forEach((el) => {
        try {
          el.pause();
        } catch (_) {}
      });
    // Pause Bunny iframes by reloading the src (Bunny exposes
    // postMessage controls but reloading is the most reliable
    // cross-domain "pause" we can do without extra dependencies).
    document
      .querySelectorAll(".media-panel iframe[data-bunny-pause]")
      .forEach((el) => {
        if (el.dataset.bunnyPaused === "true") return;
        // Lazy approach: do nothing — Bunny pauses when offscreen
        // anyway because of `loading="lazy"`. We just hide the panel.
      });
  }

  function setActive(target) {
    buttons.forEach((b) =>
      b.classList.toggle("is-active", b.dataset.target === target),
    );
    panels.forEach((p) =>
      p.classList.toggle("is-active", p.dataset.media === target),
    );
    pauseAllMedia();

    // Sync the URL so the user can deep-link / refresh and land
    // on the same view. Use replaceState so it doesn't pollute
    // history.
    const url = new URL(window.location.href);
    url.searchParams.set("t", target);
    window.history.replaceState({}, "", url);
  }

  buttons.forEach((b) =>
    b.addEventListener("click", () => setActive(b.dataset.target)),
  );

  setActive(initial);
})();

// =============================================================
// Pildora progress | visited-tracking unlock
// =============================================================
// The `.pil-progress` nav lives on each pildora landing. The
// HTML is rendered with every card as an <a> (no manual lock /
// unlock state); this IIFE computes the right state at runtime:
//
//   - Visiting pildora N marks every pildora 1..N as visited
//     (the series is sequential — reaching N implies the user
//     earned 1..N, even if they were dropped directly at N via
//     a WhatsApp / email link).
//   - The visited set is persisted in localStorage under
//     `narratipos.pildoras.visited`.
//   - Any card whose index is in that set renders as --unlocked
//     (full colour, clickable link).
//   - The card matching the current index is --current (no click,
//     terra glow).
//   - Every other card is --locked (lock icon, no click).
//
// So landing on 3/3 from anywhere unlocks 1, 2 and 3 forever;
// landing on 2/3 unlocks 1 and 2; landing on 1/3 unlocks only 1.
// =============================================================
(function () {
  const navs = document.querySelectorAll(".pil-progress[data-pil-current]");
  if (!navs.length) return;

  const KEY = "narratipos.pildoras.visited";

  // Read the visited set safely (corrupted storage / private mode
  // should never break the page).
  let visited = [];
  try {
    const raw = window.localStorage.getItem(KEY);
    if (raw) {
      const parsed = JSON.parse(raw);
      if (Array.isArray(parsed)) {
        visited = parsed.filter((n) => Number.isInteger(n));
      }
    }
  } catch (_) { /* swallow — fall back to in-memory only */ }

  navs.forEach((nav) => {
    const current = parseInt(nav.dataset.pilCurrent, 10);
    if (!Number.isInteger(current)) return;

    // Mark every pildora 1..current as visited. Sequential unlock:
    // reaching N means the user has earned 1..N. Persist once.
    let mutated = false;
    for (let i = 1; i <= current; i++) {
      if (visited.indexOf(i) === -1) {
        visited.push(i);
        mutated = true;
      }
    }
    if (mutated) {
      visited.sort((a, b) => a - b);
      try { window.localStorage.setItem(KEY, JSON.stringify(visited)); } catch (_) {}
    }

    nav.querySelectorAll(".pil-progress__card").forEach((card) => {
      const idx = parseInt(card.dataset.pilIndex, 10);
      if (!Number.isInteger(idx)) return;

      // Wipe any class the HTML shipped with — JS is the source
      // of truth for state from here on.
      card.classList.remove(
        "pil-progress__card--current",
        "pil-progress__card--unlocked",
        "pil-progress__card--locked",
      );
      card.removeAttribute("aria-current");
      card.removeAttribute("aria-disabled");

      if (idx === current) {
        card.classList.add("pil-progress__card--current");
        card.setAttribute("aria-current", "page");
        // Don't navigate when the user clicks the page they're on.
        card.addEventListener("click", (e) => e.preventDefault());
      } else if (visited.indexOf(idx) !== -1) {
        card.classList.add("pil-progress__card--unlocked");
        // Default <a> click + href takes care of navigation.
      } else {
        card.classList.add("pil-progress__card--locked");
        card.setAttribute("aria-disabled", "true");
        card.addEventListener("click", (e) => e.preventDefault());
      }
    });
  });
})();


/* ===== landing | overrides ===== */

// Landing-specific JS for politica-de-cookies (Narratipos). Empty by default.

Required custom values (10)

Configure these in GHL → Settings → Custom Values for this sub-account. The HTML above references each token exactly as {{custom_values.<key>}}.

TokenValue to configure in GHL
{{custom_values.la_boutique_de_mentores_brand_image}} https://www.laboutiquedementores.es/og-image.jpg
{{custom_values.la_boutique_de_mentores_brand_name}} La Boutique de Mentores
{{custom_values.la_boutique_de_mentores_root_url}} https://www.laboutiquedementores.es
{{custom_values.narratipos_brand_color}} #0A0A0C
{{custom_values.narratipos_brand_name}} Narratipos®
{{custom_values.narratipos_cookies_policy_url}} politica-de-cookies
{{custom_values.narratipos_legal_policy_url}} aviso-legal
{{custom_values.narratipos_privacy_policy_url}} politica-de-privacidad
{{custom_values.narratipos_root_url}} https://www.narratipos.com
{{custom_values.narratipos_terms_and_conditions_url}} terminos-y-condiciones