Three self-contained blocks ready to drop into GoHighLevel. {{custom_values.*}} tokens are kept verbatim — GHL substitutes them server-side using the values below.
Visual preview: https://www.narratipos.com/terminos-y-condiciones/
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/d227cffa-5467-493a-92de-7bf0108c832b.webp 320w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/1551fed5-f6ff-4638-80ac-f06b4ead82f4.webp 640w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/b6bdee7c-f62f-45e6-9550-41036f760ee3.webp 960w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/1b07a659-9bb3-4930-9e04-69faabbf5712.webp 1280w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/40bc7727-55be-4e49-ad99-7427cdcde257.webp 1920w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/ded830e3-0a3b-4453-b2ef-f56f634760d4.webp 2423w" sizes="(max-width: 640px) 100vw, 2423px" />
<img src="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/e8584731-343d-46a6-89b2-67d541744f9a.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">Términos y Condiciones</h1>
<span class="legal__updated">Última revisión · 23/04/2026</span>
</div>
<div class="legal__body">
<h2>1. Identificación y objeto del contrato</h2>
<p>
Los presentes Términos y Condiciones regulan la adquisición del
programa de formación
<strong>{{custom_values.narratipos_brand_name}}</strong> (en
adelante, el «Programa») ofrecido por
<strong>La Boutique de Mentores SL</strong>, con CIF B16709420 y
domicilio en Camino de los Malatones 63, 28110 Algete, Madrid (en
adelante, el «Proveedor»), al cliente que formaliza su inscripción a
través del sitio web
<a
href="{{custom_values.narratipos_root_url}}"
target="_blank"
rel="noopener noreferrer"
><strong>{{custom_values.narratipos_root_url}}</strong></a
>
(en adelante, el «Cliente»).
</p>
<p>
La inscripción al Programa supone la aceptación plena, expresa e
incondicional de todas las cláusulas recogidas en los presentes
Términos y Condiciones, así como del
<a href="{{custom_values.narratipos_legal_policy_url}}"
>Aviso Legal</a
>, la
<a href="{{custom_values.narratipos_privacy_policy_url}}"
>Política de Privacidad</a
>
y la
<a href="{{custom_values.narratipos_cookies_policy_url}}"
>Política de Cookies</a
>.
</p>
<h2>2. Modalidades de pago</h2>
<h3>2.1. Pago único</h3>
<p>
El Cliente puede optar por abonar la totalidad del importe del
Programa en un único pago a través de la pasarela habilitada en el
sitio web. El precio aplicable será el publicado en la página de
inscripción en el momento de formalizar la compra, con el IVA
incluido.
</p>
<h3>2.2. Pago aplazado mediante seQura</h3>
<p>
El Cliente puede optar por financiar el importe del Programa en
cuotas mensuales mediante el servicio de financiación prestado por
<strong>seQura Worldwide, S.A.</strong> (en adelante, «seQura»),
entidad ajena al Proveedor. La aprobación, las condiciones
financieras y la gestión de los pagos quedan sometidas íntegramente
al contrato suscrito por el Cliente con seQura, conforme a sus
propios términos.
</p>
<p>
Una vez aprobada la financiación, el Proveedor recibe el importe
total del Programa por parte de seQura, y el Cliente queda obligado
frente a seQura al pago de las cuotas conforme al cuadro de
amortización aceptado. El impago o retraso en el abono de cualquier
cuota se rige exclusivamente por las condiciones y consecuencias
previstas en el contrato suscrito con seQura.
</p>
<h3>2.3. Carácter vinculante</h3>
<p>
La elección de cualquiera de las modalidades de pago anteriores
constituye un acuerdo firme de adquisición del Programa, sujeto a la
política de garantía y desistimiento prevista en la cláusula 3 de
los presentes Términos y Condiciones.
</p>
<h2>3. Garantía de satisfacción y derecho de desistimiento</h2>
<p>
El Proveedor ofrece al Cliente una
<strong
>garantía de satisfacción de quince (15) días naturales</strong
>, a contar desde la fecha de formalización de la inscripción.
Durante dicho plazo, el Cliente podrá solicitar la devolución
íntegra del importe abonado, sin necesidad de justificar su
decisión, mediante comunicación escrita dirigida a
<a href="mailto:equipo@laboutiquedementores.es"
>equipo@laboutiquedementores.es</a
>
con el asunto «GARANTÍA NARRATIPOS», incluyendo los siguientes
datos:
</p>
<ul>
<li>Nombre completo</li>
<li>
Correo electrónico o teléfono con el que se realizó la inscripción
</li>
<li>Fecha de compra o número de pedido</li>
<li>Motivo de la solicitud (opcional, no obligatorio)</li>
</ul>
<p>
Una vez validada la solicitud, el Proveedor procederá al reembolso
en un plazo máximo de catorce (14) días naturales, mediante el mismo
método de pago utilizado en la compra.
</p>
<p>
Esta garantía es compatible y, donde resulte más favorable al
Cliente, sustituye al derecho de desistimiento previsto en el
artículo 102 del Real Decreto Legislativo 1/2007, de 16 de
noviembre, por el que se aprueba el texto refundido de la Ley
General para la Defensa de los Consumidores y Usuarios (TRLGDCU).
</p>
<p>
Una vez transcurrido el plazo de quince (15) días naturales desde la
inscripción, no se contemplarán reembolsos ni cancelaciones, dado el
carácter digital del Programa, el acceso inmediato a sus contenidos
y el compromiso firme de adquisición asumido por el Cliente. En el
caso de financiación con seQura, el ejercicio efectivo de la
garantía conllevará la cancelación del préstamo asociado conforme a
las condiciones pactadas con dicha entidad.
</p>
<h2>4. Acceso al Programa y obligaciones del Cliente</h2>
<p>
Una vez confirmado el pago (o, en su caso, aprobada la financiación
por seQura), el Proveedor habilitará al Cliente el acceso al
Programa en las fechas y condiciones anunciadas en la página de
inscripción. El acceso es estrictamente personal, individual e
intransferible.
</p>
<p>
El Cliente se obliga a hacer un uso diligente y leal del Programa y
de sus materiales, absteniéndose de compartir credenciales, grabar
sesiones, distribuir contenidos o ceder su acceso a terceros. El
incumplimiento de esta obligación facultará al Proveedor a suspender
el acceso del Cliente sin derecho a reembolso, sin perjuicio de las
acciones legales que correspondan.
</p>
<h2>5. Propiedad intelectual</h2>
<p>
La totalidad de los contenidos, materiales didácticos, vídeos,
guías, plantillas, herramientas y demás elementos proporcionados
como parte del Programa son propiedad intelectual exclusiva del
Proveedor o de terceros que han autorizado su uso. El Cliente
adquiere únicamente una
<strong
>licencia de uso personal, no exclusiva e intransferible</strong
>, limitada a sus propios fines de aprendizaje.
</p>
<p>
Queda expresamente prohibida la reproducción, distribución,
comunicación pública, transformación, puesta a disposición o cesión
a terceros, total o parcial, de los materiales del Programa sin el
consentimiento previo, expreso y por escrito del Proveedor.
</p>
<h2>6. Limitación de responsabilidad</h2>
<p>
El Proveedor se compromete a impartir el Programa con la máxima
diligencia profesional. No obstante, no garantiza la obtención de
resultados específicos por parte del Cliente, dado que su
efectividad depende, entre otros factores, de la dedicación, el
esfuerzo y las circunstancias individuales de cada Cliente.
</p>
<p>
La responsabilidad máxima del Proveedor frente al Cliente, por
cualquier reclamación derivada de los presentes Términos y
Condiciones, se limitará al importe efectivamente abonado por el
Cliente al Proveedor por el Programa contratado.
</p>
<h2>7. Modificaciones</h2>
<p>
El Proveedor se reserva el derecho a modificar los presentes
Términos y Condiciones para adaptarlos a novedades legislativas,
jurisprudenciales o de su propia operativa comercial. Las
modificaciones serán publicadas en el sitio web con razonable
antelación a su entrada en vigor y resultarán aplicables a las
inscripciones formalizadas con posterioridad a dicha publicación.
</p>
<h2>8. Aceptación de las condiciones</h2>
<p>
La inscripción y el pago, ya sea íntegro o mediante la financiación
con seQura, suponen la aceptación plena e incondicional de todas y
cada una de las cláusulas recogidas en los presentes Términos y
Condiciones de Venta.
</p>
<h2>9. Legislación aplicable y jurisdicción</h2>
<p>
Los presentes Términos y Condiciones se rigen por la legislación
española. Para la resolución de cualquier controversia derivada de
su interpretación o ejecución, las partes se someten a los Juzgados
y Tribunales del domicilio del Proveedor, sin perjuicio del fuero
que pudiera corresponder al Cliente en su condición de consumidor.
</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/71d478e9-8b22-43e0-a77a-ffc26cb836fb.webp 240w" sizes="(max-width: 640px) 100vw, 240px" />
<img src="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/247dd541-7ef2-4eaa-97c5-860ffe1b6b77.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/37e133f4-ca21-4171-8b64-fd8433d3e949.webp 320w, https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/e04ab17d-939e-4a2e-8bad-205151fcdc50.webp 486w" sizes="(max-width: 640px) 100vw, 486px" />
<img src="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/478ec4de-c160-4f49-9ee3-a32132a10cba.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
>
·
<a href="{{custom_values.narratipos_cookies_policy_url}}"
>Política de cookies</a
>
·
<a href="{{custom_values.narratipos_legal_policy_url}}"
>Aviso legal</a
>
·
<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 & Desarrollo</span>
<img
class="site-footer__credit-logo"
src="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/840dcb11-54ae-4dda-bf5b-e3b74785e20b.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>
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"
/>
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>
Términos y Condiciones | {{custom_values.narratipos_brand_name}}
</title>
<meta
name="description"
content="Términos y Condiciones 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}}/terminos-y-condiciones"
/>
<link
rel="icon"
type="image/png"
sizes="32x32"
href="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/23afcf0b-d128-4f23-b765-0e9990bbe6b8.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/e2e465ac-3ee0-4746-8345-bf325795d656.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="https://assets.cdn.filesafe.space/v6bs4AByBa6XPltPfemq/media/c7727de6-cad8-4087-bc74-e08104f764b1.png"
/>
<!-- Schema.org · JSON-LD -->
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}}/terminos-y-condiciones#webpage",
"url": "{{custom_values.narratipos_root_url}}/terminos-y-condiciones",
"name": "Términos y Condiciones | {{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": "Términos y Condiciones",
"item": "{{custom_values.narratipos_root_url}}/terminos-y-condiciones"
}
]
}
]
}
</script>
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/29f4f51c-2146-4624-96e8-b63f6cca84d1.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/29f4f51c-2146-4624-96e8-b63f6cca84d1.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/21137592-bef1-430e-ab6c-dbcf1c30eaf8.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 terminos-y-condiciones (Narratipos). Empty by default. */
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 terminos-y-condiciones (Narratipos). Empty by default.
Configure these in GHL → Settings → Custom Values for this sub-account. The HTML above references each token exactly as {{custom_values.<key>}}.
| Token | Value 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 |