/* ===========================================================================
   Kaphiy — sitio oficial (kaphiy.app)
   CSS único del sitio. Sin build step, sin preprocesador.

   Orden del archivo:
     1. Tokens          6. Sección: Qué es Kaphiy
     2. Reset y base    7. Sección: Features
     3. Utilidades      8. Sección: Free vs. Premium
     4. Header / nav    9. Sección: FAQ
     5. Sección: Hero  10. Sección: Descarga
                       11. Footer
                       12. Breakpoints (≤1200, ≤1000, ≤760, ≤600, ≤560, ≤420)
                       13. prefers-reduced-motion

   Breakpoints: el layout base está escrito para desktop y se reduce en los
   media queries del bloque 12. Los tres anchos de referencia validados son
   375px (mobile), 768px (tablet) y 1440px (desktop).
   =========================================================================== */

/* ---------------------------------------------------------------- 1. TOKENS */
:root {
  /* Paleta de marca — espejo de lib/theme/app_colors.dart de la app */
  --creamy-latte:  #F3E9D7;
  --caramel-roast: #B08968;
  --mocha-bean:    #7A553A;
  --espresso-shot: #3B2A22;
  --footer-dark:   #2E2019;

  /* Variación tostada del fondo, solo para la sección de planes */
  --toasted-latte: #EADFC8;

  /* Tipografías */
  --font-display: "Poppins", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-body:    "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;
  --font-hand:    "Caveat", "Segoe Script", cursive;

  /* Layout */
  --container:      1200px;
  --gutter:         24px;
  --header-h:       68px;
  --radius-sm:      12px;
  --radius-md:      18px;
  --radius-lg:      26px;

  /* Sombras */
  --shadow-soft:  0 4px 16px rgba(59, 42, 34, .10);
  --shadow-lift:  0 10px 26px rgba(59, 42, 34, .18);
  --shadow-card:  0 14px 40px rgba(59, 42, 34, .22);

  /* Curvas */
  --ease-out:   cubic-bezier(.22, .61, .36, 1);
  --ease-pop:   cubic-bezier(.34, 1.42, .48, 1);
}

/* ------------------------------------------------------------ 2. RESET/BASE */
*, *::before, *::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Evita que el header sticky tape el destino de los links ancla */
  scroll-padding-top: calc(var(--header-h) + 16px);
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--creamy-latte);
  color: var(--espresso-shot);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* Los mockups de teléfono van inclinados y su caja rotada es más ancha que
     la declarada; sin esto el viewport podría ganar scroll horizontal en
     anchos intermedios.
     `clip` en vez de `hidden`: `hidden` convertiría a <body> en contenedor de
     scroll y eso rompe el position:sticky del header. La primera línea queda
     como fallback para navegadores sin soporte de `clip`. */
  overflow-x: hidden;
  overflow-x: clip;
}

h1, h2, h3 { font-family: var(--font-display); font-weight: 500; margin: 0; line-height: 1.2; }
p  { margin: 0; }
ul { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }

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

:focus-visible {
  outline: 2px solid var(--mocha-bean);
  outline-offset: 3px;
  border-radius: 4px;
}

/* ----------------------------------------------------------- 3. UTILIDADES */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

/* Sprite SVG: presente en el DOM, nunca visible */
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }

/* Todos los íconos del sprite son de trazo, salvo los marcados como filled */
svg use { pointer-events: none; }
.icon {
  width: 1em;
  height: 1em;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  flex: none;
}
/* El glifo de "play" del CTA es sólido, no de trazo */
.sprite-filled path { fill: currentColor; stroke: none; }

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

/* Etiqueta chica en mayúsculas que abre cada sección */
/* El letter-spacing baja de .16em a .12em al subir el cuerpo: en versalitas,
   el tracking ancho compensa la falta de altura, y a 15px ya sobra —dejarlo en
   .16em desarmaba la palabra en letras sueltas—. */
.eyebrow {
  font-size: 15px;
  font-weight: 600;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--caramel-roast);
  margin-bottom: 14px;
}
.eyebrow-center { text-align: center; }

.section-title {
  font-size: 36px;
  text-align: center;
  margin-bottom: 56px;
}

/* --- Botones --- */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 15px;
  line-height: 1;
  border: 0;
  border-radius: var(--radius-sm);
  padding: 14px 20px;
  cursor: pointer;
  transition: transform .22s var(--ease-out), box-shadow .22s var(--ease-out),
              background-color .22s var(--ease-out);
}
.btn .icon { font-size: 17px; }

.btn-dark  { background: var(--espresso-shot); color: var(--creamy-latte); }
.btn-light { background: var(--creamy-latte);  color: var(--espresso-shot); }

.btn:hover  { transform: translateY(-2px); box-shadow: var(--shadow-lift); }
.btn:active { transform: translateY(0);    box-shadow: var(--shadow-soft); }

.btn-lg { font-size: 16px; padding: 16px 26px; }
.btn-sm { font-size: 13.5px; padding: 10px 15px; border-radius: 10px; }

/* --- Badge oficial de Google Play ---
   Se usa tal cual viene de play.google.com/intl/es/badges/: la marca no admite
   recolorearlo, recortarlo, cambiarle la tipografía ni ponerle un fondo. Lo
   único que se le aplica es el tamaño y el mismo hover de los botones, que es
   del enlace y no del arte. El PNG ya trae el área de resguardo obligatoria
   alrededor del botón, así que el botón visible es algo más chico que la caja
   —por eso 220px de caja y no los ~180px que mide el botón—. */
.badge-play {
  display: inline-block;
  width: 220px;
  transition: transform .22s var(--ease-out);
}
.badge-play img {
  display: block;
  width: 100%;
  height: auto;
}
@media (hover: hover) and (pointer: fine) {
  .badge-play:hover { transform: translateY(-2px); }
}

/* --- Animación de entrada al cargar (solo el hero) ---
   El estado oculto va condicionado a la clase .js del <html>, igual que el
   reveal por scroll: sin esa guarda, si el JS no corre la clase .is-loaded
   nunca se agrega y el hero entero se queda invisible. */
.js .anim-in {
  opacity: 0;
  transform: translateY(18px);
}
.js .is-loaded .anim-in {
  animation: fade-up .7s var(--ease-out) forwards;
  animation-delay: var(--anim-delay, 0s);
}
@keyframes fade-up {
  to { opacity: 1; transform: translateY(0); }
}

/* --- Reveal por scroll (IntersectionObserver, ver main.js) ---
   El estado oculto está condicionado a la clase .js del <html>, que agrega un
   script inline en el <head>. Si el JS no corre (error, bloqueado, navegador
   viejo), la clase nunca se agrega y el contenido se muestra normalmente:
   nunca puede quedar una sección invisible por culpa de la animación. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .7s var(--ease-out), transform .7s var(--ease-out);
  transition-delay: var(--reveal-delay, 0s);
}
.js [data-reveal][data-reveal-from="left"]  { transform: translateX(-40px); }
.js [data-reveal][data-reveal-from="right"] { transform: translateX(40px); }
.js [data-reveal].is-visible { opacity: 1; transform: none; }

/* --------------------------------------------------------- 4. HEADER / NAV */
.site-header {
  position: sticky;
  top: 0;
  z-index: 100;
  /* Barra oscura sobre el crema de la página. Semitransparente + blur para que
     el contenido que pasa por debajo se insinúe sin llegar a leerse. */
  background: rgba(59, 42, 34, .92);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  border-bottom: 1px solid transparent;
  transition: border-color .25s var(--ease-out), box-shadow .25s var(--ease-out);
}
.site-header.is-stuck {
  /* Con la barra oscura, el borde que la despega al hacer scroll tiene que ser
     claro: el caramelo de antes se perdía contra el espresso. */
  border-bottom-color: rgba(243, 233, 215, .16);
  box-shadow: 0 4px 18px rgba(59, 42, 34, .28);
}

.nav {
  height: var(--header-h);
  display: flex;
  align-items: center;
  gap: 20px;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 23px;
  letter-spacing: -.01em;
  /* Crema tanto en el navbar como en el footer: los dos son oscuros. */
  color: var(--creamy-latte);
}

/* --- Glifo de marca ---
   El glifo viene en negro puro sobre transparente y se usa como MÁSCARA, no
   como imagen: el color lo pone background-color, así el mismo archivo sirve
   sobre el crema, sobre el espresso del navbar y sobre cualquier otro fondo sin
   duplicarlo. Solo se le fija el alto; el ancho sale de su aspect-ratio.

   Va incrustado en base64 y no como url() a un archivo, y no es por ahorrar un
   request: Chrome trata cada archivo local como un origen distinto y bloquea la
   imagen de un mask-image servido por file://, y una máscara que no carga no
   deja el elemento sin máscara, lo ESCONDE entero. Con el data URI no hay nada
   que cargar, así que el glifo se ve igual abriendo el HTML con doble clic que
   servido por HTTP. El archivo sigue en assets/img/brand/ como fuente: si se
   cambia, hay que volver a incrustarlo (base64 de ese .webp). */
:root { --glifo-marca: url("data:image/webp;base64,UklGRpwZAABXRUJQVlA4TI8ZAAAvysA/EP8HJIT/59WICUjcwxu27arttP93P2OMpPEEp5DgwT0J7u7u7v7B3bVevDQUd3eo4dBPcaeGu0MUkuzxjOd+sfeea8w55s7riP5PAPpO8cGh+6j1Dv7tXc+/8+20lKb98NUnr+8Gj95d6O6dYCbWBQ8AQ1c+4obXJ7JXNZIvn7mISC/i0LsLXmZKJDgAw9Y4+ZEv2GNSTSmSfP2UJVFVgAW3O/KoA7Zdbf7+ACDBycyFeA9gvv3u+pwkLcZkJKnktFs38IAE6UUwyw0/ssdpH/zlvM3nBoDgZh4kAJhzr4enkLSoxp5T4vQrlgAQHHoXN+wlUmOMauw+8anTxnnAeZkpcB7w6133LUlVY8VIPrAs4L2gqscdnGHs0ZLGRJJvXbAcAC99nnfAqBPfJKlqrGqJH+wIeIfqHvuyi9VNo5H6l2084Ps08QKsfO1E0tRYXckrZoVz6NC5eX9I1kH3FEm+un9/ONdniQewxd9IxsROIz/fEvDo2ONOKrOaJvKNnQHfR3kg7PZPkmrsOPKp+RAEHXtsSmX2pORDS0JcH+QEYY9XyKTs3CKv64eAzsUNfMdSPjIpp57i4Psa8cD2r5CamNGU50IcMgacQmW9Sj69BELf4oFVnyA1Macpj4EXZHQycnKymmiRE3aEl77DOcx5RaImZrXIIxGQ1eNPjKxfyXMB11cEYI9PSWXmyJPQD1m9LNWVrAE05e2D4fsEJ1j0QTIyd+TFCMiEe6hsZuSLCyD0AQE4ciLVmDvyAQTJ4zE2JTY18rOxCG3nHJZ8nFRmT3xriDjkeojaGConronQbh44cjLVmD2lSYvDI6/HKpbYYOWUNRBaTALme5hU1qjcBQGZHR6mNomJE8fCt5Zz2OpLRmONypsRkNljnCU2W/nlaLiW8pBfkMo6U/p2Tufy3U9tGJX/m02klQJ+/lemxFqVh8Ijs5flNbHxkX93QdpHPNb9mJH1Kl/1XrLhZsbmsYtnIbSOExyqjKxtPXhkdjJ6ulkBFtOq8C3jEa6gJdasvA8euT0uZ2SJyrcHeGmVgLmfpBprtjRjCckmmHOiWRGMPAu+TQKWf5eRtSv/CI/cAScyskxLPy0irj0CtpjIyNrNpowUl0tkwPuWCqHyDvi2EI/DSGX9kb+HR+6AnagsNqUV4NtBHM5hSqzfbNI84rI5PGkFRd7QEuJwKaOxgZEXwyO3xwrJWK5xwuyQFnAi1zOyiWY/LSCuhvGMBTFxC/jynPg7GNnIyGvhkVsw+w+0kqIdh1CcQ//72cVmmi4r+QIOp7Ionl2ew4A/s4vNVP4ZHtnFvVrcGcU5+dlf2MWGJm5Ug8caTCzsmNKc9H+YkQ1NfMsLariesSzl3oU56fcQu9jUyCMRsgnmmkQrK3Fj+JLEuXvYxaYaJ84ByRbwf1QWbdTF4QqSgBvYxcZG3gSP7CIvl5b44c8gBQVcyC42N3F9yeexkhnLjnYTPMrthxMY2dzE//YTqeEPjIUlblZSwG6M1qDIMxCQWzD8a1pZyf7bX1CsxzpdydhcsxkLw2ULsguVZSsPQijGY9HvmNhg5WNwyO7wiBWW7L2BIqU4mfU/VDZrPwnZHOafRitLuTs8ChXvHmNkk40T54BkCziOkUUr/+kcSg0Yz8hGR7sNHtnFvUwtyjSNgy8l4BhGNlu5o4RsHiuasejIS+BR0TXKYxNGa5ZxwmyQbAG/Ziwq8f0hTqo02mHh7y2x2ZH3wSG3oP/7TCVZ5DrwqLpxaI74/q9Q2bh9JGTzWJ+JJXfxbHj0Lpjzg59DmhIwnpENN06bD66GqxlLirwPQSoE7MMdEBoSsAcjm678fzjkFgz/mlaQ8rUhTlDRyfN2K3wzHEZPTta4yDMRsgXZgcpyE79YAA4VPbaifTMc0gTx4UUqG29cGT6bx90Wy0k2dRw8KooLb7CLm8E3IeC3jGx84scDILkEc06iFWNJN0NA1YADqNEuQ2iAxyaMbH7krfDIHWQ/Kku1xN0QUFXcLF+mlPhvL/U5N/vnlgpQ7o+QzeFv5STj3gioHHAplWa6JFxtAXdRWWLXonC5HOafRiskMe2BgMoeY6MaGXkIQl0BezOywMS3nSB3wJGMLFM5fRsEVBbvX6Ky2+3wNTkZNSGlEiL/hJDN4VlqGZHfr4uA6gEnUEky8f3+kHoCHqGyROUe+RxGd5kVEfnRcgio7rD0dLVuRl0crhaPfRhZorFrEbhcAScwssTIF0YhoLr4/q9Q2aNyF4Q6nMzzfUpFJP43QHKJvEAtwJR3DYFHh/1wGSN7jrywHo+7qCwy8lZ4ZHZYSo3NV/IcwKHDgD0Z2avyabgaPLamspQjEXIFnMrYvMiJO8EJOvQY81Oy3oxfD0F+cUM/slSIcTX4XCIvUZtmka8uhYBOHeb+mIkVzZatwePXVJZp/G4EJJPDUmpseCKvG4yATp0b+ByVVZW75nOy+HS1QpRPQZA54BTGhkX+dBDg0Kl43MvIypG/zufxMJWFRv4WIZfIi9RGmfKNMfCCTiXgSkZWV/45m8fmVJaq3CGbw5JqbHIkrxyCgI4l4JeM7DDxPyGTuP7/tmKMXaPhMgWcxNggU365C+DReT+cxshOjd/Pncnj/6gsNfGdfsjt8By1OUrePS+8oPOA4xitI1KXyyNutm9SKibyTvhMDqO7jE1Nyq/2BgIyBhxFNXZu3DCPx+8ZWdDxCJkCjmFsSiRvmRdO0LkEHEU1ZkzcPYuTRaYlKydxbfhMDk9Tm6Hke9sDATkDjqcacyqPzuJxMyOLNU6cHZLHYcHptCaYUn8/Al6QUQJOpRoznZ/Dy/KarBzlcxDkDTiMkQ2M5P+vCnjkFI9zGY25Ls+C+6ksN/JyhEwOf6PWp8avDnMIgpzicCGjMdtNGTxWtsSi9swlmGcqra6k5FXzQByyOsi1jMyufCDLw9SCzNIycHmC7ENlvRbJJ9cEAvJ6/OxuRuZPfKwzj5UtseDETwdC8njcz1iPku/vA3hBXo/ZnmBkLc935vAQtSTlX+CQVTD7BFodKXHqBcMhHpkDFnyDkfW80ZHHSpZYcuS5CHkCdqIyvyl5xxKAR+6AcZ8ysqZ/d+TwILUo5ZbweTxutpjNIvn8JkAQZBaPbSZTWa/xvU68LJ8SSzbOWAAui2DIl0y5lPz4EAfnkNsDx5GJtX3SEW5kLCrx3x55PTZmYt5knPrLWQGP7AFDbmAy1vdVBw4LTDMrKvI2+DwBl1vMkpS8dTHAI7t4LPMa1diAHzoI+CUjCzsWIYug/3tMGSyS/1gPCILsDthjMiMbaJxUTWT4V7SyEteGz+KxCo2dK/nBvgLvkD9gwBWksplTqwUcRGXRxklzQLIEnMfYUUqc/utZIB75xWPpF6nGhk6vJu5VK0z5AgRZRV5m6sAi+eCygEeNHth/MiMbGyt5rM3EsiOvRMjisFg0VlfynZ0AL8gvASOuJ5XN1Q5uZyzuwExBjmSsZMpp5w+Dc6jRA+v+j2pscKriMO9Us8KM4+CzOPyNWiWSf14W8KhRAgb8yhjZaKsScDwjyzZ+OxySw2GuKbTekvGTvYAgqNEDa7xCS2x2qiL+LabClM9CkDPIrlT2bJH84xxwDjWKx6BfJ0Y2XSt4rMHEwiMvRcjicYvFnpR8fQMgoE4PbPgWLbHxMyr9ibE05V55BEO+ZOpmyunnDoQX1Ogc5hxPRhY4tTfB8G9opZktD5fDYwMmklTy6RUBjxrFA3t/SktsvvGH3oLsTGXhxi8HQ3IEXMhImnLCUUAQ5JcArPgXMrJE4xe9OTxosTTl43DIKf5tJir54GiIQ40emOuSLqqxkHd7cRj5I620yN8i5HBYJtGUX+8HBNToBQOP+4JUFpr4Wi8BhzOydOVueQKO43Ty3vnhHPI7B+zyNhmN5Tzai8Mz1OLMloHL4fBo4rf7AQH5nQc2fpZUY7nK23pyWLTLWHriF4MhGQTDJ/L+BeEcsjsPrPYgqYklKy/qKeAExuKUj8MhY8B2Px4IBGR3Dhh7B5mUZSuP7UnwHLW4yAsRcjissRScQ27vgLG3JFJZeuLOPTgs2kUrTrlHnu4emcULsModiVS24eo9BBzJyOLNloPL4xzyigew/gMklS1onLpgDw5/pxZn/HIIJE9mF4CwwzMk1diGiR8P6SaYazKtOOWTcGis98CIw94gk7IlE59H94AdqSw+8mKEhkgQYOHzPiFV2ZqRd/ZytcXylHs1Q7wHsNaNU0lNbNHIX3cT9HuXqTyzFeDqcwHA3Ic9RzImtmrkwd0cVjRj8cavh0JqkuAAv/6135OmxpZN3LhbwLGM5SmfhkOd4j2AxU9/k6QmtrAt2c3jIWp5kZci5BPvAcy9/99nkKbGFjZOmBWAYOjXtPKU+2QT7wEM3/7270nGxHZO/JcD4LEajeUbx8Bl8R7AkM2u+ZykqrGtlQ/DAwHHMpZn/GYYJAswaOMrPyKZ1NjikRchAB53U8tTPgtBRhm45WUfkEzR2O6RByFA0O89pvIiL0fIIG7wvaTGxNZPXBMeDotGWhvslwUCnE1LbH3jpDkh8NiJyvKNY+FzQBz2jdTWU74AAQJ+w1ie8bvhkCxAwHrfUdsucjwC4PAotTzlPyDIHbDUe4ytty8CBIM+o5UXeTlCNgTM8zJju5ktCweHpVI77FMHPIY/ythmiR8PgCBgRyrLN1sBrgZ49L+bscWU98MDAeczlmf8aiikDjiRaxnbK/IkBMDjfmp5yqfgUK9zuJixtYxrwwMibzOVF3kRQk0QjwsYrZ2M388CATDHZFp5yt3rg3icTrVWUj4GBwBjaCzezJaBqw0ScDzV2ijyLIRuO1JbgJ8PgtQHBBxDtRZKXAe+26mM5SkfhUMjA46mWusYvx4G6XZdG0T+CqEjcVkQcDTV2kb5EDy6P0EtT7kdfEfZA05ktJaJPBqhW/93mIozdi0C14FgvpXhsiDgVEZrF0vLwnUbOZFWXOI7AdJBwO8/lEwScC67WiXxfwHSbVxi+ZF3wqNDca9wbfgskIAL2dUm0cYjoPt2tDY4GqEDh9HT7dZckIArGVskcetejqKWZ1wVvoMghzBNnhsuD8TjdsbWME6YDdLDBS2Q+OUQSAcOD3E6T0LIBHH9/s7YFmoPwqHHq1og8l54VBfMPpHKDweKZIKToS9T24L7SujpnlY4AqGDIDtSqdwbIRc8Rn7C1ArGqT+H9PQoU3GWloXrwONmi0z2VpBs8FhxakptoPYwHHp+rrzEd/uhQ8HQr2ikcluEbAjYmtHagHsi9PJ2eZHXwHfgsSkTuz0nLh8CTmAszzhhdkgv79NKU+6K0EHAeIskmbgefD4JuJaxuGi3waPXT4szThsFV00w4GOmbspH4fJBfP9/UktL3LzK18Upn4eguscGTOwx2Wrw+eAw7xdMZSV+PFCktwnFRf4CoYOAPzL2pHwIrgZ4rBXVior8LQJ6/5GlJ64HX00w8FOmnpjSGPE1IOBIxqJMl4GrML004zfDINW8bMLEXiPvQi0IuJmxILVn4FCxqzTlffDoANdZ7M1SXFp8HeIG/4taEPdEqKKlRR6KUE0w/Btab4y8CbXAY4XpaqUkfj4EUsUKM+ricNWC7EBlRbMZi4mrAwFHMJYS+SsEtEfiW05Q3eNui1UYeR18LQh4gFqITV8ErlIsLPIShGqCuSbRKlmaPlpcLSJzfWmpiMh74VF5RmGJm3cScACV1SOvgq8FHlswFpG4XifTyjJOmA1SzeHxjsymLSSuFgSMZyxA7RXnUH1KWcq/wKGywyIzjJ1GjoevR/yQd5gK4D4IHfxAKynyWIRqASczdmT24wLiaoHHWqbWtGSfDRbp4KuyzJaHqybudWpHjLwcvh4EXERtWuQZCOjwk6IS/xtEKnmsbMbOzaaOEleP+EHvWmqW2aS5xXXyflGRlyGgcsAljBkYeSF8PfDYlNqsyMvg0enbTAUlbgxfSTDoU6YcZpPmEVcPAu6gNsnspwXFdfRCScYvhkAqBdmKyqyRv4avycl8k5M1KPJP8Oj4iZKi3QiPyh53W8xjNmFOcfXA4zRqcyz9tJC4zh4sSbktQiWHkVNpeRh5HkJN4ga+a6kxyj/Ao/ObqMUYvx0BqRRwLCMzm30/u0g98NiB2hRLU0eJy3BJQdFug0dlca8x5WLkaQg1weMZakMifwuPjGcWpNxeQiUvq9CYPdmXw0RqW9VSMyx9N4e4HIeWY/x2BKQarmTMR+VRCDXB407GRihPQUDOLWmlRLsZHlUFs35PqyHZhwNFanKy+IxkDUj2yRAnWcYklpq4OUKlgAOorFO5H0JN8LiS2gDlvgjIOnIirYzETwdCKjk8V5f9u5+ry8l8U81qU77mneTp/w5TGZGXIqCqxxgz1qvcEaEmeFzK2IAN4ZH5CWoZiavCd3AFY132knN1ORk1xawm5X3wyH0NYxGJb3tBVcGs39FqYuKG8DXB4xLGeixNW0RctpMLiTwToVLAwYysW/k3uLqczP+jWS3K8+GRfWtqCWZdi8FVEvcKtTamNEZ8TfAYz1hHsvcHO8m3lLFE5RNwqOplDSbWH3kLanMyeobVodwaHvmHfUsrYm+EariZsQFm0xYWVxM8bmPMp3wIHvkF/6Q2z/jtLJAqDqN+NGsAIy+Cr03GppTN0tSFxNUQMJ6xeZFXwqNqwNmMbKLZ97NBaoLDk9RcyhPgUctBJaQ0pprIoE+YGkHlMQh1BeyULfG14KUOj7G0ximfhkPVgL2obGay//aTugRDvqBlMU2rwKNOweAvmJq3PUIl51+zpjBxM/ia4HEJYxbl7xFQr8NfqA1L9p/+gqoemzKxqdHua8IYsxyJ7wzyUlPA6YwNUx6GUMnhMWpjjD+OgqsJIi9TO7No68CjZo91mJqV7IthIlU8VrHE5kYeh1BXwLGMnUX+DgF1C0Z8R2uU8gwEVLuXsUGJrzmpy2G+n2idKN/8mZfa4PA3apPMfphDpIqXpaNZg2i2EnxNcHiE2oHpjBXgUX/ASYxNivwtPCrhekY2OfIShLqC7NtR5NEIaKDHSrQGmU0ZKa6Kk4WnmTUq8dNBkJoc5plKq6R8BEGaIBjwIVNzIi+BR1WP8YxsduLm4muCw5PUKsm+nFscGhlwjcXGmP04v7gqTub70axh0W5CbQEnM1awyI3g0ZRtqI2JvAweVT0uZmTDjd+NgNTksQqtQuR5CGioYNjXtIZYmjSvuCpORk4xaxqVO8DXJBj8OVMvysckSFPgcZ3Fhih/iYCqHhczsvHRbq0NDg9Se0r8bC5xaND6TM1I9u3s4qo4GTnFrHmJXwyG1BRwGmMPproWPBos/d9laoTyaHhU9fgDIwtMXBu+Jo9NqT1EHo6AJgecy9iEZP8b4KSKk0WnJysh8myEmhxGRxrJyPEIaLTDol3WBOX28KjqcRuVJSqfgKtJMOjzbpGPey/NgsPfTOtTPg6Pqh7jNLFI44TZIPVA8BKVyvdmF4eGB2zHVJtp17IdPUUtg4kbwtfkcT812aRl4NF0kQEfMtUVeTE8qnpsR2WhkWch1BTwR3apbYqA5geczFhTss9HOKkibsA7lkpR/g2utvM4nQcjoEAnc040qydyB3hU9TiFkaUavxoCqevExLMRUKTHhYy1RN4Jj6pO5pucrBgax8LVdSQvQpAynIyaalZDsk9nd66Sx21Ulht5MEJd5zwCLyjU4zLGfBZtXXhU9diIyqKuqUuwwhARlOpk5JRk2bp4PAKqih/4v7ISX4LUU7rHrxhzRd6EgMoBFzCyZOMPs0JqclKSuFm/SilP5HMDvFTyGBfViqJxLFxNhXscyJhF+cHccKgqvv+bTCxbuStCm8HLP6gZlN8vBY/KAb9jZOGRZ7Wcw1LT1TpSTl4VAZU9Nma08m5oOQSczNhJ5HerI6Cykzk+s8TSlU/AtZt49wy1kkW+swwCKkvAg1QWn/gvQcs7LDw5pQpqfHgOeFQPOImRbfDFEEi7wWNXxl5U2XUa4FE9YIMUrQWMk37eegi4lF2kpUjy6ZXhBNU9FvjGEltBF4JrO/H+UaqRtMd3Ajw6dBj+OpUtuXT7wcmwv5I/Pnf2CoA4dOgw6Ekq23JMHwABxq0+CoB4dOox8FFGtqRxFfj2gwCABIeOPYY9zsj2WLlPALx3yBjw8xcZ2SLj+ois4rHsO4xskzFwfZQHdp5IZasu0Ud5h9n+RCa2qHHGAn2RCwLs+iGTsV0mzAnpa7wDsN5jpLJdEz/q3/cACx3xDJkSW1b5/xD0rU52+esU0pStG3kVQh/jcQQ5I7GFlXv2OXDYbSpjC5lOWwCur4HHiq8zpbbRyDdF0PcGDPoDGVtFE/n02uL6IHhgq/doqS1MjXxsM0DQJ0vAiMtJtTYwJfnIBoA49NUeWPMfZLTSLJJ695qAePTh4uEO+oSMVpCpklOuXhFwHn28F8x2zg+kpkJSJPnJBQsBzmEm0AMjL/iaVLXGpWhkemq/EYB3mDkUD8x5wn9JRrXmmEYj+dZ5ywPwDjOPEoABO/8tktSYrD7TqCT59m9WD4B4wcylBABLnvzUTySpMVk2SzEmkpz87NmregDBYSZUvABYaK+b/mckaZqSmfVmlpJqYo+Tn79o23kBIHjBzKoLAsAvseflz//A3BPfuPWE9ecGAAleMHPrgkf3ebf89WNvffDFd5OndSUy/vTDZ/9+9rbfHLj2KAEACcGhDwUA"); }
.brand-mark {
  display: inline-block;
  height: 30px;
  aspect-ratio: 906 / 1143;
  background-color: var(--espresso-shot);
  -webkit-mask: var(--glifo-marca) center / contain no-repeat;
  mask: var(--glifo-marca) center / contain no-repeat;
}
/* En la barra oscura el glifo se invierte. Es exactamente para lo que sirve
   usarlo como máscara: el mismo archivo, otro background-color. El del titular
   del hero se queda en espresso, que va sobre el crema de la sección. */
.site-header .brand-mark { background-color: var(--creamy-latte); }

.nav-links {
  display: flex;
  gap: 28px;
  margin-left: auto;
  font-size: 15px;
  font-weight: 500;
}
.nav-links a {
  display: inline-block;
  /* El texto solo mide ~19px de alto: el padding es lo que da un área táctil
     usable en tablet, donde estos links todavía se muestran. */
  padding: 10px 0;
  color: var(--creamy-latte);
  opacity: .82;
  transition: opacity .2s var(--ease-out), color .2s var(--ease-out);
}
.nav-links a:hover { opacity: 1; }

.nav-end {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-left: auto;
}
/* Cuando los links de ancla existen, ellos ya empujaron; el bloque final
   no debe volver a empujar o se separa demasiado. */
.nav-links + .nav-end { margin-left: 24px; }

/* --- Selector de idioma --- */
.lang-switch {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 3px;
  /* .39 y no menos: el contorno de un componente de UI necesita 3:1, y a
     .34 el crema sobre el espresso de la barra se quedaba en 2.66:1. */
  border: 1px solid rgba(243, 233, 215, .39);
  border-radius: 999px;
}
.lang-pill {
  font-size: 11.5px;
  font-weight: 600;
  letter-spacing: .05em;
  padding: 5px 10px;
  border-radius: 999px;
  color: var(--creamy-latte);
  user-select: none;
}
/* El idioma activo se invierte: crema sólido con el texto en espresso. Sobre la
   barra oscura es lo que más se despega, y deja los otros dos como secundarios
   sin necesidad de otro color. */
.lang-pill.is-active {
  background: var(--creamy-latte);
  color: var(--espresso-shot);
}
/* El idioma que SÍ tiene página es un <a>. Sin esto no se distinguiría en nada
   de la pastilla inactiva de al lado, que es un <span> muerto: el cursor lo
   delata al pasar por encima, pero el fondo lo dice antes. */
a.lang-pill:hover,
a.lang-pill:focus-visible { background: rgba(243, 233, 215, .18); }
.site-footer a.lang-pill:hover,
.site-footer a.lang-pill:focus-visible { background: rgba(59, 42, 34, .12); }

/* PT: presente pero todavía sin página detrás */
.lang-pill.is-disabled {
  /* .58 y no menos: por debajo de eso el crema sobre el espresso de la barra
     baja de 4.5:1 y deja de ser legible, aunque el elemento esté inactivo. */
  opacity: .58;
  cursor: not-allowed;
}

/* ------------------------------------------------------------- 5. HERO */
/* Hero editorial: fondo plano de marca, el titular manda y el teléfono entra
   como acento a un costado. Reemplaza al concepto anterior —foto de fondo con
   vignette de rectángulo redondeado— que se descartó entero: con esto ya no
   hay máscara, ni velo, ni --fundido. */
.hero {
  position: relative;
  /* El teléfono se sale del contenedor y sangra hacia el borde: sin esto,
     el documento gana scroll horizontal en los anchos intermedios.
     `clip` y no `hidden`: hidden convertiría al hero en contenedor de scroll,
     que es el mismo mecanismo que ya rompió el position:sticky del header
     cuando se usó en <body>. */
  overflow: clip;
  padding: 88px 0 104px;
}

/* El contenedor es el bloque de referencia del teléfono, que va posicionado.
   container-type lo hace además contenedor de consulta, que es lo que permite
   dimensionar el titular contra el ancho REAL del contenido y no contra el
   viewport (ver .hero-title). */
.hero-inner {
  position: relative;
  display: flex;
  align-items: center;
  container-type: inline-size;
  /* El bloque de texto es más bajo que el teléfono, así que sin un alto mínimo
     el acento se saldría del hero por arriba y por abajo. Va en unidades de
     contenedor para que acompañe al ancho del teléfono, que se calcula igual. */
  min-height: clamp(420px, 62cqi, 720px);
}

.hero-copy {
  position: relative;
  z-index: 1;
  /* Deja libre la banda derecha donde flota el teléfono. En el tramo apilado
     se libera (ver ≤1000px). */
  max-width: 38%;
}

.hero-title {
  /* clamp contra el CONTENEDOR y no contra el viewport, por el mismo motivo
     que el mockup de las filas de funciones: .container está topado en 1200px,
     así que de 1248px de viewport para arriba el texto ya no tiene más lugar y
     con vw seguiría creciendo igual. La primera declaración es el equivalente
     en vw para navegadores sin unidades de contenedor; la segunda la pisa donde
     hay soporte. Las dos coinciden en el tope. */
  font-size: clamp(34px, 5vw, 62px);
  font-size: clamp(34px, 5.4cqi, 62px);
  line-height: 1.08;
  letter-spacing: -.02em;
  /* Reparte las líneas en vez de dejar una huérfana corta al final. Sin <br>
     fijo: el punto de corte cambia con el ancho. */
  text-wrap: balance;
  margin: 8px 0 22px;
}
/* El glifo va en línea, dimensionado en em para que acompañe al titular en
   cada ancho. Un inline-block vacío apoya su borde inferior en la línea base,
   que es donde tiene que quedar, así que no hace falta tocar vertical-align. */
.hero-mark {
  height: .78em;
  margin-right: .2em;
}

.hero-sub {
  font-size: clamp(16.5px, 1.75cqi, 20px);
  line-height: 1.6;
  color: rgba(59, 42, 34, .82);
  max-width: 54ch;
}

.hero-actions { margin-top: 36px; }
.hero-note {
  margin-top: 12px;
  font-size: 13.5px;
  color: rgba(59, 42, 34, .6);
}

/* --- Marco de teléfono (componente compartido) ---
   Lo usan el acento del hero y las 5 filas de funciones. Las tres medidas que
   cambian con el tamaño del marco son variables para que la proporción del
   redondeo se mantenga: un radio fijo se ve desproporcionado al achicarlo.
   El radio de la pantalla es propio y no un calc() sobre los otros dos porque
   el interior de un teléfono real no es concéntrico con el exterior. */
.phone-frame {
  --frame-pad: 12px;
  --frame-radius: 42px;
  --screen-radius: 32px;
  padding: var(--frame-pad);
  background: var(--espresso-shot);
  border-radius: var(--frame-radius);
  box-shadow: var(--shadow-card);
}
.phone-screen {
  position: relative;
  height: 100%;
  border-radius: var(--screen-radius);
  overflow: hidden;
  background: var(--caramel-roast);
}
/* object-position: top — las capturas son de 1080x2280 y entran en un marco
   más corto: lo que importa de cada pantalla está arriba (título, foto, datos
   principales), así que el recorte se come el final del scroll y no el encabezado. */
.phone-shot {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top;
}

/* --- El acento del hero: el abanico de polaroids alrededor del teléfono ---
   Vuelve la distribución original: 2 polaroids a la izquierda y 3 a la derecha,
   radiando desde el centro, detrás del teléfono. El sistema es el de aquella
   versión: cada polaroid se ancla en el centro del contenedor y de ahí se
   desplaza con --tx/--ty y gira con --rot.

   Lo que cambia respecto del original es la UNIDAD: allá los desplazamientos
   iban en px con topes contra vw, y había que recalcular las cinco en cada
   breakpoint —de ahí salieron los cortes de 1315px y 560px—. Acá van en cqi,
   o sea porcentaje del ancho del cluster, así que el abanico entero escala como
   una unidad y el único ajuste por tramo es el ancho del cluster.

   El abanico ocupa 1.286 veces el ancho del cluster (se sale por los dos lados,
   que es lo que le da el aire) y 0.93 de alto; de ahí el aspect-ratio, y por eso
   el cluster se corre a la izquierda del borde: lo que tiene que entrar en el
   viewport no es la caja sino las piezas, y de eso se encarga la suite.

   Ojo con los porcentajes acá adentro, que ya causaron dos regresiones: un
   border-radius en % resuelve el radio horizontal contra el ancho y el vertical
   contra el alto POR SEPARADO, así que en una caja alta la esquina sale
   elíptica; y un padding en % se mide contra el bloque contenedor, no contra el
   propio elemento. Por eso los redondeos van en cqi y el papel de la polaroid
   vive en .polaroid-inner, para que su padding se mida contra la polaroid. */
.hero-cluster {
  position: absolute;
  top: 50%;
  z-index: 0;
  --ancho: clamp(300px, 52%, 640px);
  width: var(--ancho);
  aspect-ratio: 1 / 0.93;
  right: 3%;
  transform: translateY(-50%);
  container-type: inline-size;
}

/* El teléfono, derecho y flotando, en el centro del abanico. Va corrido a la
   izquierda del centro geométrico porque el abanico no es simétrico: hay tres
   polaroids de un lado y dos del otro. */
.hero-phone {
  position: absolute;
  left: 50%;
  top: 50%;
  z-index: 2;
  width: 41.7cqi;
  margin-left: -7.9cqi;
  transform: translate(-50%, -50%);
}
.hero-phone .phone-frame {
  --frame-pad: 1.7cqi;
  --frame-radius: 5.8cqi;
  --screen-radius: 4.5cqi;
  aspect-ratio: 1080 / 2280;
  animation: phone-float 5s ease-in-out infinite;
}
@keyframes phone-float {
  0%, 100% { transform: translateY(-10px); }
  50%      { transform: translateY(10px); }
}

/* --- Las polaroids ---
   Las cinco en una sola capa, siempre por detrás del teléfono. Los modificadores
   --left/--right quedan como referencia de qué lado del abanico está cada una. */
.polaroid {
  position: absolute;
  left: 50%; top: 50%;
  z-index: 1;
  width: var(--w);
  container-type: inline-size;
  transform: translate(calc(-50% + var(--tx)), calc(-50% + var(--ty)))
             rotate(var(--rot));
}
/* La entrada arranca en el centro exacto del teléfono, a escala chica, y sale
   hacia su posición final. El fotograma del 100% repite el transform final, así
   que la animación NO le borra la posición al terminar —que es justo el problema
   que tiene .anim-in y por el que el teléfono se descolgaba—. */
.js .polaroid { opacity: 0; }
.js .is-loaded .polaroid {
  animation: polaroid-emerge .95s var(--ease-pop) forwards;
  animation-delay: var(--delay, 0s);
}
@keyframes polaroid-emerge {
  0%   { opacity: 0; transform: translate(-50%, -50%) scale(.34) rotate(0deg); }
  35%  { opacity: 1; }
  100% { opacity: 1;
         transform: translate(calc(-50% + var(--tx)), calc(-50% + var(--ty)))
                    rotate(var(--rot)); }
}

/* Marco del papel: parejo arriba y a los costados, más ancho abajo para alojar
   la leyenda manuscrita (proporción 8/8/22/8 de una polaroid real). Va en un
   hijo para que el padding se mida contra el ancho de la polaroid. */
.polaroid-inner {
  padding: 5.4cqi 5.4cqi 0;
  background: var(--creamy-latte);
  border-radius: 2.7cqi;
  box-shadow: var(--shadow-lift);
  animation: polaroid-float var(--float-dur, 6s) ease-in-out infinite;
  animation-delay: var(--float-delay, 0s);
}
@keyframes polaroid-float {
  0%, 100% { transform: translateY(-5px); }
  50%      { transform: translateY(5px); }
}
.polaroid-photo {
  display: block;
  width: 100%;
  /* height: auto es obligatorio, no cosmético: los atributos width/height del
     <img> entran como presentational hints, así que sin esto el height del
     atributo gana sobre el aspect-ratio y la foto sale a tamaño natural. */
  height: auto;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 1.4cqi;
  background: var(--caramel-roast);
}
.polaroid-caption {
  display: block;
  min-height: 14.7cqi;
  font-family: var(--font-hand);
  font-weight: 600;
  font-size: 11.3cqi;
  line-height: 1.25;
  padding: 2cqi 1.4cqi 0.7cqi;
  text-align: center;
  text-wrap: balance;
  color: var(--espresso-shot);
}

/* Disposición del abanico, en % del ancho del cluster. Las distancias y los
   ángulos NO son progresivos a propósito: una serie regular se lee como una
   grilla y no como fotos tiradas sobre la mesa. */
/* Las dos de la izquierda van más lejos del centro que las de la derecha
   (-44.5 y -45.5 contra +25 a +34): el teléfono no está centrado en el abanico
   sino corrido a la izquierda, así que de ese lado hay menos aire entre su
   marco y las polaroids. Con los valores del abanico original se le metían 38 y
   50px por debajo. */
.p1 { --w: 20.8cqi; --tx: -44.5cqi; --ty: -15.3cqi; --rot: -18deg; --delay: .72s; --float-dur: 6.1s; --float-delay: .3s; }
.p2 { --w: 23.3cqi; --tx: -45.5cqi; --ty:  22.2cqi; --rot:  10deg; --delay: .96s; --float-dur: 6.6s; --float-delay: 1.1s; }
.p3 { --w: 19.0cqi; --tx:  25.4cqi; --ty: -31.9cqi; --rot: -14deg; --delay: .60s; --float-dur: 5.4s; --float-delay: 0s; }
.p4 { --w: 23.6cqi; --tx:  33.8cqi; --ty:   0cqi;   --rot:  20deg; --delay: .84s; --float-dur: 4.8s; --float-delay: .7s; }
.p5 { --w: 19.2cqi; --tx:  26.8cqi; --ty:  33.3cqi; --rot:  -8deg; --delay: 1.08s; --float-dur: 5.8s; --float-delay: 1.5s; }

/* --------------------------------------------------- 6. QUÉ ES KAPHIY */
.what { padding: 40px 0 96px; }

.what-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  /* `start` y no el `stretch` por defecto: si las tarjetas se estiraran, abrir
     una haría crecer a las otras dos junto con la fila. */
  align-items: start;
  gap: 28px;
  max-width: 980px;
  margin-inline: auto;
}
/* Cada pilar es una tarjeta que se expande sobre sí misma. Reemplaza al
   tooltip flotante anterior, que podía superponerse con el eyebrow de la
   sección cuando se abría hacia arriba. */
.pillar { display: block; }

.pillar-card {
  /* --mocha-bean es el tono con el que venía pintada la tarjeta Premium, y es
     bastante más oscuro que el caramelo que había acá: el texto oscuro que
     funcionaba sobre caramelo (--footer-dark, 4.96:1) se cae a 2.38:1 sobre
     mocha, y ningún oscuro de la paleta lo arregla —el espresso da todavía
     menos, 2.07:1—. Así que la tarjeta se invierte entera y pasa a texto crema,
     que da 5.47:1. */
  background: var(--mocha-bean);
  border: 1px solid rgba(59, 42, 34, .18);
  border-radius: var(--radius-md);
  box-shadow: 0 16px 34px rgba(59, 42, 34, .22);
  padding: 34px 28px;
  text-align: center;
  color: var(--creamy-latte);
  transition: box-shadow .2s var(--ease-out);
}
.pillar-card.is-open,
.pillar-card:focus-within { box-shadow: 0 24px 48px rgba(59, 42, 34, .34); }

/* El disparador es un <button> real para que entre en el orden de tabulación
   y responda a Enter/Espacio; se le saca todo el chrome nativo. El padding
   vive en la tarjeta, no acá. */
.pillar-trigger {
  display: block;
  width: 100%;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  text-align: center;
  cursor: pointer;
}

.pillar-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 60px; height: 60px;
  margin: 0 auto 20px;
  border-radius: 50%;
  /* Sobre el mocha, de los seis tonos de la paleta solo separan los dos claros:
     el espresso se queda en 2.07:1 y el caramelo en 2.08:1, los dos por debajo
     del 3:1 que pide un elemento gráfico. O sea que el círculo tiene que ser
     claro en los DOS estados, y el cambio de estado lo lleva el glifo de
     adentro, no el disco. */
  background: var(--creamy-latte);
  color: var(--mocha-bean);
  transition: transform .25s var(--ease-out), color .25s var(--ease-out);
}
.pillar-icon .icon { font-size: 28px; stroke-width: 1.5; }

.pillar-trigger:hover .pillar-icon,
.pillar-card.is-open .pillar-icon {
  /* El disco se queda en crema (5.47:1 contra la tarjeta) y lo que cambia es el
     glifo: de --mocha-bean, que lo hace eco del fondo de la tarjeta y lo deja en
     sordina a 5.47:1, a --espresso-shot, que lo firma a 11.33:1. */
  color: var(--espresso-shot);
  transform: translateY(-3px);
}

/* Se reserva el alto de DOS líneas aunque el título entre en una: los tres
   títulos no miden lo mismo ("Bolsa y taza, cada una a su manera" envuelve) y
   sin esto las tarjetas cerradas quedarían de alturas distintas. Igualarlas
   con align-items:stretch no sirve, porque entonces abrir una estiraría a las
   otras dos. */
.pillar-title {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.7em;   /* 2 líneas a line-height 1.35 */
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 17px;
  line-height: 1.35;
  color: var(--creamy-latte);
}

/* --- Despliegue del texto ampliado ---
   La altura se anima con grid-template-rows 0fr→1fr en vez de max-height: es
   la única forma de llegar al alto real del contenido sin inventar un tope.
   Este contenedor NO lleva padding ni borde propios a propósito —irían dentro
   del alto animado y producirían el salto visual clásico al cerrar—: viven en
   .pillar-answer, que es hija del clip. */
.pillar-reveal {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .3s var(--ease-out);
}
.pillar-card.is-open .pillar-reveal { grid-template-rows: 1fr; }

.pillar-clip {
  overflow: hidden;
  min-height: 0;   /* sin esto, el hijo del grid no baja de su alto de contenido */
}

.pillar-answer {
  margin-top: 18px;
  padding-top: 16px;
  /* El separador se invierte con la tarjeta: en oscuro sobre mocha quedaba en
     1.18:1, o sea invisible. */
  border-top: 1px solid rgba(243, 233, 215, .28);
  font-size: 14.5px;
  line-height: 1.6;
  color: var(--creamy-latte);
  opacity: 0;
  /* Sin justificar. En la banda de tres columnas por debajo de 1000px la
     columna baja a 114px y justificar ahí abría huecos de hasta 52px entre
     palabras —casi la mitad de la columna en un solo espacio, 13 veces el
     ancho natural—, que se ve peor que los guiones que se sacaron. */
  text-align: left;
  text-wrap: pretty;
  /* Sin corte silábico: en la columna de 114px —lo que le queda a la tarjeta
     justo encima del salto a una columna— hyphens:auto partía una de cada dos
     líneas ("per-sonal", "momen-tos") y el bloque se leía como un borrón. No
     hay overflow-wrap ni word-break en juego en ningún lado: con hyphens en
     none, una palabra que no entra pasa entera a la línea que sigue.
     El precio: "automáticamente:" mide 115.3px y en esa franja (601-610px de
     layout) se pasa 1.0px de la columna. Antes el guion lo tapaba. Cae dentro
     de los 28px de padding, así que no sale de la tarjeta ni genera scroll. */
  hyphens: none;
  transition: opacity .3s var(--ease-out);
}
/* La opacidad final entra en el contraste real, no es cosmética: .82 era el
   valor sobre caramelo, pero sobre mocha el crema atenuado a .82 da 4.28:1 y no
   llega. A .9 da 4.79:1 y la atenúa igual. */
.pillar-card.is-open .pillar-answer { opacity: .9; }

/* ------------------------------------------------------------ 7. FEATURES */
.features { padding: 88px 0 104px; }
/* Aire grande entre el título de la sección y la primera fila: cada fila es
   un teléfono suelto sobre el fondo, sin caja que lo contenga, así que el
   espacio en blanco es lo único que las separa como bloques. */
.features .section-title { margin-bottom: 130px; }

.feature {
  position: relative;
  display: grid;
  align-items: center;
  gap: 56px;
  margin-bottom: 170px;
}
.feature:last-child { margin-bottom: 0; }

/* La columna de la imagen es fija y angosta: adentro flota un teléfono de
   250px sin contenedor visible, así que una columna en fr le dejaría un hueco
   que cambia de ancho fila por fila. Lo que rompe la simetría ahora son las
   inclinaciones (ver .tilt-*), no las proporciones de la grilla —antes eran
   desparejas a propósito por eso mismo, pero con una tarjeta opaca de por
   medio—. */
/* La columna va en porcentaje y no en px: el contenedor está topado en 1200px,
   así que de 1248px de viewport para arriba nada crece más. Atar el tamaño a
   vw lo haría seguir creciendo mientras la columna se queda quieta, y el
   teléfono terminaría saliéndose de su columna. El porcentaje se mide contra
   el contenedor, que es lo que de verdad manda acá. */
.feature--imgleft  { grid-template-columns: 40% 1fr; }
.feature--imgright { grid-template-columns: 1fr 40%; }
.feature--imgright .feature-media { order: 2; }

/* Numeral editorial de fondo.
   Va siempre del lado del TEXTO, nunca del de la imagen: la tarjeta de media
   es opaca y con z-index mayor, así que del otro lado el numeral quedaría
   tapado por completo en vez de leerse como marca de agua. */
.feature-num {
  position: absolute;
  top: -30px;
  z-index: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: 150px;
  line-height: 1;
  color: var(--caramel-roast);
  opacity: .3;
  pointer-events: none;
}
.feature--imgleft  .feature-num { right: -6px; left: auto; }   /* texto a la derecha */
.feature--imgright .feature-num { left: -6px;  right: auto; }  /* texto a la izquierda */

/* Solo centra el teléfono: ya no es una tarjeta. Sin fondo, sin borde y sin
   sombra propia —la única sombra es la del marco del teléfono, que es lo que
   lo hace flotar sobre el crema de la sección—. */
.feature-media {
  position: relative;
  z-index: 1;
  display: grid;
  place-items: center;
}

.feature-phone {
  --frame-pad: 10px;
  --frame-radius: 35px;
  --screen-radius: 27px;
  /* 78% de la columna, con 250px de piso. El 78% no es arbitrario: el teléfono
     va inclinado hasta 7deg y una caja rotada ocupa 1.25 veces su ancho
     (w·cos + h·sen, con la proporción 1080/2280), así que por encima del 80%
     los vértices se saldrían de la columna. El alto no se declara: sale del
     aspect-ratio, que es la proporción real del aparato. */
  width: max(250px, 78%);
  aspect-ratio: 1080 / 2280;
  transform: rotate(var(--tilt, 0deg));
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
}

/* Inclinaciones deliberadamente no correlativas: una progresión regular se
   lee como un efecto aplicado en serie y no como cinco objetos apoyados. */
.tilt-a { --tilt: -7deg; }
.tilt-b { --tilt:  5deg; }
.tilt-c { --tilt:  4deg; }
.tilt-d { --tilt: -5deg; }
.tilt-e { --tilt:  7deg; }

/* El hover se limita a punteros finos: en touch, :hover queda "pegado" tras
   el tap y el teléfono se quedaría derecho hasta tocar otra cosa. */
@media (hover: hover) and (pointer: fine) {
  .feature-phone:hover {
    /* translate antes que rotate: así sube en vertical y no en diagonal
       siguiendo el eje ya girado. Endereza solo hasta un tercio del ángulo,
       que es "levemente hacia 0deg" y no un salto a la vertical. */
    transform: translateY(-10px) rotate(calc(var(--tilt, 0deg) * .32));
    box-shadow: 0 26px 60px rgba(59, 42, 34, .3);
  }
}

.feature-body { position: relative; z-index: 1; }

.feature-badge {
  display: grid;
  place-items: center;
  width: 54px; height: 54px;
  margin-bottom: 18px;
  border-radius: 15px;
  background: var(--caramel-roast);
  color: var(--creamy-latte);
}
.feature-badge .icon { font-size: 27px; stroke-width: 1.5; }

.feature-title {
  font-size: 31px;
  line-height: 1.25;
  margin-bottom: 14px;
}
.feature-text {
  font-size: 17px;
  line-height: 1.85;
  color: rgba(59, 42, 34, .82);
  max-width: 52ch;
}

/* ------------------------------------------------------ 8. FREE VS PREMIUM */
.plans {
  background: var(--toasted-latte);
  padding: 88px 0 96px;
}

.plans-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 28px;
  max-width: 900px;
  margin-inline: auto;
  align-items: stretch;
}

.plan {
  position: relative;
  padding: 36px 32px;
  border-radius: var(--radius-lg);
}

.plan--free {
  background: var(--creamy-latte);
  border: 1px solid rgba(176, 137, 104, .45);
  box-shadow: var(--shadow-soft);
}

/* La foto de granos va DEBAJO de un tinte casi opaco, y el tinte no es una
   decisión de gusto: 0.80 en el extremo claro es el mínimo medido píxel a
   píxel sobre la foto entera para que .plan-sub —crema al 80%, o sea el texto
   más débil de la tarjeta— llegue a 4.5:1. Da 4.91:1 contra el peor píxel de la
   foto, que es un brillo especular de rgb(255,215,176); con 0.70 se quedaba en
   3.87:1. Se conserva el degradado a 150deg que la tarjeta ya tenía, ahora como
   tinte y no como fondo, para no perder la profundidad.
   El background-color de respaldo es --mocha-bean, que es exactamente el tono
   con el que la tarjeta estaba pintada antes de la foto: si el WebP no cargara,
   queda oscura y legible igual (9.87:1) en vez de transparente. */
.plan--premium {
  background-color: var(--mocha-bean);
  background-image:
    linear-gradient(150deg, rgba(59, 42, 34, .80) 0%, rgba(46, 32, 25, .90) 100%),
    url("../img/premium-beans.webp");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
  box-shadow: var(--shadow-card);
  color: var(--creamy-latte);
}

.plan-badge {
  position: absolute;
  top: -14px; right: 26px;
  padding: 7px 16px;
  border-radius: 999px;
  background: var(--espresso-shot);
  color: var(--creamy-latte);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: .04em;
  box-shadow: var(--shadow-soft);
  /* El texto del badge no lo toca la foto —la pastilla tiene fondo opaco y
     se queda en 11.33:1—, pero su SILUETA sí: espresso sobre una tarjeta
     teñida de espresso da 1.00:1 y el badge se disolvería contra el borde de
     la tarjeta. El anillo crema lo devuelve a 3.72:1 contra el peor píxel de
     la foto. Del lado de arriba, donde el badge se monta sobre la sección, no
     hace falta: ahí la pastilla ya se recorta a 10.31:1 contra el
     --toasted-latte. */
  border: 1px solid rgba(243, 233, 215, .7);
}

.plan-name { font-size: 27px; }
.plan--premium .plan-name { color: var(--creamy-latte); }

.plan-sub {
  margin-top: 4px;
  font-size: 14.5px;
  color: rgba(59, 42, 34, .65);
}
.plan--premium .plan-sub { color: rgba(243, 233, 215, .8); }

.plan-list {
  margin-top: 26px;
  display: grid;
  gap: 14px;
}
.plan-list li {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  font-size: 15.5px;
  line-height: 1.5;
}
.plan-list .check {
  font-size: 19px;
  stroke-width: 2.1;
  margin-top: 2px;
  color: var(--caramel-roast);
}
.plan--premium .plan-list .check { color: var(--creamy-latte); }

.plans-note {
  max-width: 560px;
  margin: 40px auto 0;
  text-align: center;
  font-size: 15.5px;
  line-height: 1.6;
  color: rgba(59, 42, 34, .72);
}

/* ----------------------------------------------------------------- 9. FAQ */
.faq { padding: 88px 0 96px; }

.faq-list {
  max-width: 760px;
  margin-inline: auto;
  border-top: 1px solid rgba(176, 137, 104, .35);
}

.faq-item { border-bottom: 1px solid rgba(176, 137, 104, .35); }

.faq-item summary {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 22px 2px;
  cursor: pointer;
  font-family: var(--font-display);
  font-weight: 500;
  font-size: 18px;
  line-height: 1.35;
  list-style: none;
  transition: color .2s var(--ease-out);
}
.faq-item summary::-webkit-details-marker { display: none; }
/* El glifo abre cada pregunta. Va en caramelo y chico —la mitad del cuerpo del
   texto— para que no compita con el +/− de la derecha, que es el que indica el
   estado: el glifo identifica, el signo acciona. */
/* El selector lleva el summary a propósito: `.faq-item summary > span` le
   ganaría en especificidad a una sola clase y le aplicaría el flex:1 del texto,
   estirando el glifo y empujando la pregunta hacia la derecha. */
.faq-item summary .faq-mark {
  height: 20px;
  flex: none;
  /* Mocha y no caramelo: sobre el crema, el caramelo da 2.63:1 y no llega al
     mínimo de 3:1 de elemento gráfico; el mocha da 5.47:1. */
  background-color: var(--mocha-bean);
  transition: background-color .2s var(--ease-out);
}
.faq-item[open] .faq-mark,
.faq-item summary:hover .faq-mark { background-color: var(--espresso-shot); }
.faq-item summary:hover { color: var(--mocha-bean); }
.faq-item summary > span { flex: 1; }

/* Ícono +/− construido con dos barras: la vertical rota 90° al abrir y el
   signo pasa de "+" a "−" sin cambiar de nodo. */
.faq-item summary::before,
.faq-item summary::after {
  content: "";
  position: absolute;
  right: 4px;
  /* transform queda reservado para la rotación, así que el centrado vertical
     se resuelve con top y la mitad del alto de la barra, no con translateY. */
  top: calc(50% - 1px);
  width: 15px;
  height: 2px;
  border-radius: 2px;
  background: var(--caramel-roast);
  transition: transform .3s var(--ease-out);
}
.faq-item summary {
  position: relative;
  padding-right: 34px;
}
.faq-item summary::after { transform: rotate(90deg); }
.faq-item[open] summary::after { transform: rotate(0deg); }
.faq-item[open] summary { color: var(--mocha-bean); }
/* Al cerrar con animación el elemento sigue teniendo [open] hasta que termina
   (si no, el contenido desaparecería de golpe y no habría nada que animar).
   Esta clase, que el JS pone al arrancar el cierre, hace que el signo vuelva
   a "+" desde el primer frame, en el mismo tiempo que tarda el panel. */
.faq-item.is-closing summary::after { transform: rotate(90deg); }
.faq-item.is-closing summary { color: inherit; }

/* Panel animado: sin padding propio y con overflow oculto, para que el JS
   pueda animarle la altura de 0 a su alto real sin saltos. El padding vive en
   el <p> de adentro. Sin JS esto se comporta igual que antes. */
.faq-answer { overflow: hidden; }

.faq-answer-text {
  padding: 0 34px 24px 2px;
  font-size: 15.5px;
  line-height: 1.7;
  color: rgba(59, 42, 34, .82);
}

/* --------------------------------------------------- 10. FRASE DE CIERRE */
/* Un solo renglón entre el acordeón y la franja oscura del CTA. No lleva fondo
   propio: hereda el crema del body, así que lo único que la separa del FAQ es
   el aire. El de arriba lo pone en su mayor parte el padding inferior del FAQ
   (96px); acá se suman 32 para que la frase no quede pegada a la última
   pregunta, y abajo van 96 para que el corte contra el espresso del CTA llegue
   después de un silencio y no encima de la frase. */
.quote { padding: 32px 0 96px; }

/* El clamp se mide contra el CONTENEDOR, no contra el viewport, y para eso el
   .container de esta sección tiene que ser contenedor de consulta. Mismo
   mecanismo que .hero-title. */
.quote .container { container-type: inline-size; }

.quote-text {
  font-family: var(--font-hand);
  /* 600 y no otro peso: de Caveat el sitio carga SOLO el 600 (ver el <link> de
     Google Fonts en el <head>), así que cualquier otro valor se lo inventaría
     el navegador engordando el trazo. */
  font-weight: 600;
  /* Por el mismo motivo que el titular del hero: .container está topado en
     1200px, así que de 1248px de viewport para arriba la frase ya no tiene más
     lugar y con vw seguiría creciendo igual. La primera declaración es el
     equivalente en vw para navegadores sin unidades de contenedor; la segunda
     la pisa donde hay soporte, y las dos coinciden en el tope. */
  /* Los dos coeficientes están calibrados para tocar el tope en el mismo punto,
     y no son el mismo número porque no miden lo mismo: cqi va contra el content
     box del .container (1152px con los 24 de gutter a cada lado) y vw contra el
     viewport (1248px cuando el container llega a su tope). 76/1152 = 6.6cqi,
     76/1248 = 6.1vw. */
  font-size: clamp(32px, 6.1vw, 76px);
  font-size: clamp(32px, 6.6cqi, 76px);
  line-height: 1.15;
  text-align: center;
  /* --caramel-roast sería el acento natural de la paleta, pero sobre el crema
     da 2.63:1 y no llega ni al 3:1 que pide el texto grande. --mocha-bean da
     5.47:1 y conserva el tono cálido que la despega del cuerpo, que va en
     --espresso-shot. */
  color: var(--mocha-bean);
  /* Cuando no entra en un renglón, reparte las dos líneas en vez de dejar una
     palabra suelta al final. */
  text-wrap: balance;
  margin: 0;
}

/* ---------------------------------------------------------- 11. DESCARGA */
.download {
  background: var(--espresso-shot);
  color: var(--creamy-latte);
  /* El padding baja de 96/100 a 56/60: la fila usa el ancho en vez de apilar
     todo centrado, así que la altura sale del contenido y no del relleno. */
  padding: 56px 0 60px;
}
/* Una sola fila: el texto de un lado, las acciones del otro. */
.download-inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 56px;
}
.download-copy { flex: 1 1 auto; }

.download-title {
  font-size: 34px;
  max-width: 18ch;
}
.download-sub {
  margin-top: 14px;
  max-width: 44ch;
  font-size: 17px;
  line-height: 1.6;
  color: rgba(243, 233, 215, .75);
}

.download-actions {
  flex: none;
  display: flex;
  align-items: center;
  gap: 24px;
}
.download-qr {
  width: 96px;
  height: 96px;
  border-radius: 10px;
  background: var(--creamy-latte);
  padding: 4px;
}

/* ------------------------------------------------------------ 12. FOOTER */
/* Las dos franjas finales van en claro. El corte contra la sección de descarga,
   que se queda oscura, es un cambio de banda a todo el ancho: lo que lo hace
   leer como intencional y no como estilos a medio aplicar es que TODO lo de
   adentro cambie de tono con él —wordmark, glifo, enlaces, íconos y el selector
   de idioma, que hasta acá estaban afinados para fondo oscuro—. */
.site-footer {
  background: var(--creamy-latte);
  color: var(--footer-dark);
  padding: 40px 0 18px;
}
.site-footer .wordmark { color: var(--footer-dark); }
.site-footer .brand-mark { background-color: var(--footer-dark); }
/* El selector de idioma es el mismo componente que el del navbar, que ahora es
   oscuro: acá se invierte, sin clase nueva en el HTML. */
/* .53 para el contorno y .65 para las inactivas: sobre el crema, los mismos
   valores que funcionan sobre la barra oscura se quedan cortos —el borde a
   .3 daba 1.77:1 y las pastillas a .58, 3.76:1—. */
.site-footer .lang-switch { border-color: rgba(59, 42, 34, .53); }
.site-footer .lang-pill.is-disabled { opacity: .65; }
.site-footer .lang-pill { color: var(--footer-dark); }
.site-footer .lang-pill.is-active {
  background: var(--footer-dark);
  color: var(--creamy-latte);
}

.footer-inner {
  display: flex;
  align-items: center;
  gap: 28px;
  flex-wrap: wrap;
}

.footer-nav {
  display: flex;
  align-items: center;
  gap: 26px;
  margin-left: auto;
  font-size: 14.5px;
}
.footer-nav a {
  display: inline-block;
  padding: 6px 0;
  color: rgba(59, 42, 34, .82);
  transition: color .2s var(--ease-out);
}
.footer-nav a:hover { color: var(--footer-dark); }

/* Los dos enlaces de redes pasan de texto a glifo. El nombre sigue estando
   para lectores de pantalla en el aria-label del enlace, y el área táctil se
   mantiene con el padding: un ícono de 21px suelto quedaría por debajo del
   mínimo cómodo. */
.footer-social {
  display: inline-grid;
  place-items: center;
  padding: 6px;
  font-size: 21px;
  line-height: 0;
}
.footer-social .icon { width: 1em; height: 1em; }

/* Una línea corta no necesita el alto que tenía: el margen y el padding bajan
   de 30/22 a 20/12, y el footer cierra con 18px en vez de 34. */
.footer-copy {
  margin-top: 20px;
  padding-top: 12px;
  border-top: 1px solid rgba(59, 42, 34, .22);
  text-align: center;
  font-size: 13px;
  color: rgba(59, 42, 34, .68);
}

/* ======================================================= 12. BREAKPOINTS */

/* --- ≤1200px: desktop angosto --- */
@media (max-width: 1200px) {
  .hero { padding: 64px 0 84px; }

  .feature { gap: 40px; margin-bottom: 130px; }
  .features .section-title { margin-bottom: 100px; }
  .feature-num { font-size: 124px; top: -26px; }
  .feature-title { font-size: 27px; }
  .feature-text { font-size: 16.5px; }
  .section-title { font-size: 31px; }
}

/* --- ≤1000px: se apila todo el layout de dos columnas ---
   El corte no está en 760 sino acá arriba porque las dos secciones a dos
   columnas —el hero y las filas de funciones— dejan de entrar cómodas antes:
   el bloque de texto del hero se queda sin medida de lectura y el mockup de
   teléfono se monta sobre el titular. */
@media (max-width: 1000px) {
  :root { --gutter: 20px; }

  /* Con el layout apilado, el desplazamiento lateral de entrada deja de tener
     sentido (ya no hay un lado "de donde viene" la fila) y además empujaba el
     ancho del documento más allá del viewport. Pasa a ser vertical. */
  .js [data-reveal][data-reveal-from="left"],
  .js [data-reveal][data-reveal-from="right"] { transform: translateY(26px); }

  /* Hero apilado: el cluster entero deja de estar posicionado y pasa al
     flujo, debajo del CTA. Es la única forma de garantizar que no tape el
     titular ni el botón: en esta franja no hay ancho para dejarlo a un costado
     sin que se monte encima del texto.
     Como todo adentro del cluster va en % de su propio ancho, no hay que
     recalcular nada de la composición: alcanza con darle otro ancho. */
  .hero { padding: 44px 0 68px; }
  .hero-copy { max-width: none; }
  .hero-actions { margin-top: 28px; }

  .hero-inner {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }
  /* En una sola columna el acento va ARRIBA: entra en pantalla antes que el
     titular y hace de portada. En el HTML sigue despues del texto. */
  .hero-cluster { order: 1; }
  .hero-copy    { order: 2; }
  .hero-cluster {
    /* relative y no static: tiene que seguir siendo el bloque contenedor de
       sus hijos, que van posicionados. Con static se escapan a .hero-inner y
       se montan sobre el titular. */
    position: relative;
    top: auto;
    /* El `right: 3%` de la regla base lo clava contra el borde derecho
       mientras es absolute. Acá pasa a relative y ese mismo `right` deja de
       anclarlo: lo CORRE 3% del ancho del contenedor hacia la izquierda,
       deshaciendo el centrado que hace el margin auto de más abajo. */
    right: auto;
    --ancho: clamp(280px, 64%, 420px);
    margin: 0 auto 38px;
    transform: none;
  }

  /* Qué es Kaphiy — las 3 columnas se conservan hasta 600px (ver más abajo):
     son frases cortas y en tablet entran cómodas lado a lado. */
  .what { padding: 24px 0 68px; }
  .what-grid { gap: 22px; }

  /* Features: media arriba, texto abajo; inclinación a la mitad */
  .features { padding: 64px 0 76px; }
  .section-title { font-size: 27px; margin-bottom: 40px; }
  /* Un poco más que los 40px del resto de las secciones: el numeral de la
     primera fila sobresale 52px hacia arriba. */
  .features .section-title { margin-bottom: 64px; }
  .feature,
  .feature--imgleft,
  .feature--imgright {
    grid-template-columns: 1fr;
    gap: 26px;
    margin-bottom: 80px;
  }
  .feature--imgright .feature-media { order: 0; }
  /* Apilado, la columna pasa a ser el ancho completo del contenedor, así que
     el 78% de arriba daría un teléfono enorme. Acá manda el ancho de pantalla:
     mismo piso de 250px y tope de 340px, que es donde deja de crecer. */
  .feature-phone { width: clamp(250px, 62%, 340px); }
  /* Apilado, el teléfono queda centrado y solo: la inclinación se reduce a la
     mitad para que no se lea como un error de maquetación. */
  .tilt-a { --tilt: -3.5deg; }
  .tilt-b { --tilt:  2.5deg; }
  .tilt-c { --tilt:    2deg; }
  .tilt-d { --tilt: -2.5deg; }
  .tilt-e { --tilt:  3.5deg; }
  /* Apilado, el numeral va siempre a la izquierda. Los tres selectores hacen
     falta por especificidad: `.feature-num` a secas pierde contra los
     `.feature--imgleft/right .feature-num` del tramo ancho, que son de dos
     clases, y el numeral de las filas impares se quedaba a la derecha. */
  .feature-num,
  .feature--imgleft .feature-num,
  .feature--imgright .feature-num {
    font-size: 96px;
    top: -52px;
    left: -6px;
    right: auto;
  }
  .feature-title { font-size: 22px; }
  .feature-text { font-size: 15.5px; }
  .feature-badge { width: 44px; height: 44px; margin-bottom: 14px; }

  /* Planes */
  .plans { padding: 64px 0 72px; }
  .plans-grid { grid-template-columns: 1fr; gap: 34px; }
  /* El tope de 560px no es estético, aunque también mejore cómo se ve: sin él la
     tarjeta se estira hasta los 900px de la grilla, y a 900px de ancho la foto
     de fondo (1200x800) tendría que ampliarse 1.50x en una pantalla 2x. A 560
     el peor caso 2x pide 1120px de origen y entra justo. En teléfonos reales
     —430px de layout o menos— la tarjeta ni se acerca al tope. */
  .plan { padding: 30px 24px; max-width: 560px; margin-inline: auto; }
  .plan-name { font-size: 24px; }

  /* FAQ */
  .faq { padding: 64px 0 72px; }
  .faq-item summary { font-size: 16.5px; padding: 19px 30px 19px 2px; gap: 14px; }
  .faq-answer-text { font-size: 15px; padding-right: 6px; }

  /* Frase de cierre: acompaña el mismo recorte de aire que el FAQ de arriba
     (96→72) y el CTA de abajo, para que el ritmo de la zona no se estire solo
     acá cuando todo lo demás se comprime. */
  .quote { padding: 24px 0 72px; }

  /* Descarga */
  /* La fila horizontal no entra: el texto se quedaría con ~320px y el titular
     se partiría en cinco líneas. Se apila —texto arriba, acciones debajo— y se
     centra, que es como se lee un CTA cuando ocupa todo el ancho. */
  .download { padding: 52px 0 58px; }
  .download-inner { flex-direction: column; gap: 30px; text-align: center; }
  .download-title { font-size: 28px; max-width: none; }
  .download-sub { font-size: 15.5px; margin-inline: auto; }
  .download-actions { justify-content: center; gap: 22px; }

  /* Footer apilado y centrado */
  .footer-inner {
    flex-direction: column;
    gap: 20px;
    text-align: center;
  }
  .footer-nav {
    margin-left: 0;
    flex-direction: column;
    gap: 4px;
  }
  /* Área táctil cómoda: en columna, el texto solo dejaba ~23px de alto */
  .footer-nav a { padding: 8px 4px; }
  .footer-copy { margin-top: 16px; }
}

/* --- ≤760px: se colapsa la navegación ---
   Corte propio, más bajo que el del layout: hasta 760px los tres links de
   ancla todavía entran cómodos junto al selector de idioma y el CTA. */
@media (max-width: 760px) {
  /* Quedan wordmark, idioma y descarga. La página es corta y de una sola
     lectura vertical, no justifica un menú hamburguesa completo. */
  .nav-links { display: none; }
  .nav-end { gap: 10px; }
  .nav-links + .nav-end { margin-left: auto; }
  .wordmark { font-size: 21px; gap: 7px; }
  .wordmark .brand-mark { height: 27px; }
  .lang-pill { padding: 5px 8px; font-size: 11px; }

  /* Footer compacto: tres renglones en vez de cinco.
     Fila 1  wordmark ....... idioma + redes
     Fila 2  política de privacidad
     Fila 3  copyright (que ya vive fuera de .footer-inner)

     El truco es `display: contents` en .footer-nav: disuelve su caja y sus
     tres hijos --privacidad y los dos íconos-- pasan a ser hijos directos
     del flex de .footer-inner, que es lo único que permite mandarlos a
     filas distintas sin tocar el HTML. El <nav> sigue existiendo en el
     árbol de accesibilidad con su aria-label; lo que desaparece es su caja.
     El salto de fila del enlace de privacidad lo fuerza su flex-basis del
     100%, no un <br> ni un contenedor nuevo. */
  .footer-inner {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    text-align: left;
  }
  .footer-nav { display: contents; }
  .site-footer .wordmark { margin-right: auto; }
  /* Primero las redes y despues el selector: el selector es el elemento con
     mas peso visual de los tres (va en una pastilla con borde), asi que
     cierra mejor la fila que abrirla. */
  .footer-social { order: 2; }
  .site-footer .lang-switch { order: 3; }
  /* El único enlace del nav que no es un ícono: se lleva la fila entera. */
  .footer-nav a:not(.footer-social) {
    order: 4;
    flex-basis: 100%;
    padding-top: 0;
  }
}

/* --- 601-700px: la reserva del título de los pilares sube a TRES líneas ---
   En esta franja las tarjetas todavía van en tres columnas pero la columna ya
   bajó a ~115px, y ahí "Bolsa y taza, cada una a su manera" envuelve a tres
   líneas mientras los otros dos títulos entran en dos. Con la reserva de dos
   líneas de siempre, esa tarjeta quedaba 22.9px más alta que sus vecinas.
   Cuesta ~23px de alto en las tres dentro de la franja, que es el precio de
   que la fila se lea como una fila. Fuera de este rango no cambia nada: por
   arriba el título vuelve a entrar en dos líneas, y por debajo de 600px las
   tarjetas pasan a una sola columna y dejan de compararse entre sí. */
@media (max-width: 700px) and (min-width: 601px) {
  .pillar-title { min-height: 4.05em; }   /* 3 líneas a line-height 1.35 */
}

/* --- ≤600px: las 3 frases de "Qué es Kaphiy" pasan a una columna --- */
@media (max-width: 600px) {
  .what-grid { grid-template-columns: 1fr; gap: 34px; }
}

/* --- ≤560px: el abanico se reduce ---
   Con el cluster en su piso de 300px, las cinco quedan de ~62px y la leyenda
   manuscrita deja de leerse. Se muestran tres —una a la izquierda y dos a la
   derecha, conservando la forma del abanico— y se acercan al centro, que es lo
   que permite agrandarlas: el abanico pasa a ocupar 0.91 del ancho del cluster
   en vez de 1.286, y con eso el cluster mismo puede crecer. */
@media (max-width: 560px) {
  /* El titular sube. La regla base da 34px en todo el tramo movil --su cqi
     se mide contra un contenedor chico y nunca supera el minimo-- y el
     tramo de <=420px lo bajaba todavia mas, a 31px. En un telefono queda
     sin peso al lado de como se ve en desktop. El clamp en vw acompana el
     ancho real de la pantalla, que es lo que importa acá, y topa en 40px
     para no despegarse de los 34px que da la regla base apenas por encima
     de este corte. */
  .hero-title { font-size: clamp(35px, 9.8vw, 40px); }

  /* El badge es un inline-block de 220px dentro de una columna que en el
     telefono ronda los 300: pegado a la izquierda queda como colgado del
     borde. Se centra junto con la nota de abajo, que es su pie y tiene que
     acompaniarlo; el titular y el subtitulo siguen alineados a la izquierda,
     que es donde se leen mejor. */
  .hero-actions { text-align: center; }

  /* El abanico es asimétrico por diseño: la p1 se va mucho más a la
     izquierda de lo que la p4 y la p5 se van a la derecha. Con la CAJA del
     cluster centrada, la TINTA queda corrida a la izquierda. Se corre el
     bloque entero a la derecha; no se toca ningún --w/--tx/--ty/--rot.
     16px sale de medir el abanico de CINCO piezas, que no tiene la misma
     asimetría que el de tres que había antes acá. Se optimiza para 375-430px,
     que es donde viven los teléfonos de verdad: ahí deja los dos márgenes a
     menos de 3px uno del otro. A 320px queda 12.9 contra 7.1, desparejo pero
     con las dos piezas adentro.
     Va en `left` a propósito: es el mismo mecanismo que causaba el bug
     --un desplazamiento relativo-- pero en la dirección correcta. */
  .hero-cluster { left: 16px; }

  /* Las CINCO polaroids, tambien en el telefono. Antes se apagaban la p2 y
     la p3 y las tres restantes se reacomodaban con valores propios, para que
     la leyenda manuscrita siguiera siendo legible. Se decidio al reves: el
     abanico completo manda sobre la legibilidad de las leyendas, que a este
     tamano son una textura mas que un texto.
     Con eso el bloque se simplifica: como toda la composicion va en cqi,
     la geometria de la regla base ya es invariante de escala y no hay nada
     que recalcular pieza por pieza. Solo cambia cuanto mide el contenedor.
     El piso de 274px es el que hace entrar el abanico en una pantalla de
     320: ahi la tinta ocupa 300px de los 320 y quedan ~10px por lado. El 92%
     y el techo de 400 lo dejan crecer despues; la polaroid mas chica pasa de
     58px a 89px de ancho entre 320 y 480. */
  .hero-cluster { --ancho: clamp(274px, 92%, 400px); }
}

/* --- ≤420px: teléfonos angostos (375px de referencia) --- */
@media (max-width: 420px) {
  .btn-lg { font-size: 14.5px; padding: 14px 18px; }
  .nav-cta span { display: none; }   /* el botón del nav queda solo con el ícono */
  .nav-cta { padding: 10px 12px; }
  .feature-num { font-size: 80px; }
  .download-qr { width: 84px; height: 84px; }
}

/* ============================================ 13. PREFERS-REDUCED-MOTION */
/* Nada se mueve: todo se muestra directamente en su estado final. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    animation-delay: 0s !important;
    transition-duration: .001ms !important;
    /* Los delays también se anulan: sin esto, cosas escalonadas a propósito
       (el reveal por scroll, o el ocultado diferido del tooltip) seguirían
       esperando su turno aunque la transición ya durara cero. */
    transition-delay: 0s !important;
  }

  .anim-in { opacity: 1; transform: none; }
  .js [data-reveal],
  .js [data-reveal][data-reveal-from="left"],
  .js [data-reveal][data-reveal-from="right"] { opacity: 1; transform: none; }

  /* El acento del hero se queda quieto, pero conserva su inclinación: la
     animación es la que aporta el movimiento, no la rotación. */
  .hero-phone .phone-frame { animation: none; transform: rotate(8deg); }

  .btn:hover { transform: none; }
  .badge-play:hover { transform: none; }
  /* El teléfono no se mueve ni se endereza: solo se intensifica la sombra. */
  .feature-phone:hover { transform: rotate(var(--tilt, 0deg)); }

  /* La tarjeta abre y cierra de una: sin animación de altura y sin fade */
  .pillar-reveal { transition: none; }
  .pillar-answer { transition: none; }
  .pillar-trigger:hover .pillar-icon,
  .pillar-card.is-open .pillar-icon { transform: none; }

  /* El acordeón abre y cierra instantáneo: initFaqAccordion() consulta la
     misma media query y se saltea la animación (ver main.js). */
  .faq-answer { height: auto !important; }
}
