/* ===================================================================
   CardMagic · Día del Padre — estilos de tarjeta (compartido)
   =================================================================== */
:root {
  --bg: #0d0b08;
  --bg-2: #15110b;
  --cream: #f0e8d8;
  --cream-dim: #b8af9e;
  --cream-faint: #6e6757;
  --accent: #c9a06a;
  --line: rgba(240, 232, 216, 0.1);
  --line-strong: rgba(240, 232, 216, 0.2);
  --font-display: "Playfair Display", Georgia, serif;
  --font-mono: "DM Mono", ui-monospace, monospace;
  --font-body: "DM Sans", system-ui, sans-serif;
}

/* ---------- Escenario (full-screen en carta.html) ----------------- */
.cm-stage {
  display: flex; align-items: center; justify-content: center;
  width: 100%; min-height: 100vh; min-height: 100dvh;
  padding: 4vh 5vw;
  perspective: 1400px;
  position: relative;
}

/* ---------- La carta (contenedor base) ---------------------------- */
.cm-card {
  position: relative;
  z-index: 1;
  width: min(440px, 90%);
  aspect-ratio: 3 / 4;
  max-height: 92%;
  cursor: pointer;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
  outline: none;
  /* inclinación 3D que sigue al cursor (las vars las setea card.js) */
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  transition: transform .35s cubic-bezier(.2,.7,.2,1);
  will-change: transform;
}
.cm-card.is-tilting { transition: transform .1s ease-out; }
.cm-card:active { transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg)) scale(.975); }
.cm-card:focus-visible { box-shadow: 0 0 0 2px color-mix(in oklab, var(--accent), transparent 40%); border-radius: 8px; }

.cm-hint {
  position: absolute; left: 50%; bottom: -2.4rem; transform: translateX(-50%);
  font-family: var(--font-mono); font-size: 0.66rem; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--cream-faint); white-space: nowrap;
  transition: opacity 0.5s ease;
  animation: cm-breathe 2.8s ease-in-out infinite;
}
.cm-card.is-open .cm-hint { opacity: 0; pointer-events: none; animation: none; }
@keyframes cm-breathe { 0%,100%{opacity:.35} 50%{opacity:.8} }

/* ---------- Contenido de la carta (común) ------------------------- */
.cm-letter-inner { width: 100%; }
.cm-occ {
  font-family: var(--font-mono); font-size: 0.6rem; letter-spacing: 0.28em;
  text-transform: uppercase; color: var(--accent);
  margin-bottom: 1.1rem;
}
.cm-to {
  font-family: var(--card-display); font-style: italic;
  font-size: clamp(1.5rem, 6vw, 2rem); color: var(--cream);
  margin-bottom: 1.1rem; line-height: 1.1;
}
.cm-msg {
  font-family: var(--card-body); font-weight: 300;
  font-size: clamp(0.95rem, 3.6vw, 1.08rem); line-height: 1.75;
  color: var(--cream); white-space: normal;
}
.cm-from {
  margin-top: 1.4rem; font-family: var(--font-mono);
  font-size: 0.8rem; letter-spacing: 0.1em; color: var(--cream-dim);
}

/* ---------- Música: botón de nota al pie + audio oculto ----------- */
/* contenedor del audio: para YouTube llena la tarjeta pero invisible
   (opacity 0, detrás del contenido) → suena sin mostrar video */
.cm-audio-host {
  position: absolute; inset: 0; z-index: 0; opacity: 0;
  pointer-events: none; overflow: hidden; border-radius: 6px;
}
.cm-audio-host iframe { display: block; width: 100%; height: 100%; border: 0; }
/* Spotify no se puede ocultar: su reproductor va como barra al pie */
.cm-audio-host--show {
  inset: auto 5% 4% 5%; height: auto; opacity: 1; z-index: 8; pointer-events: auto;
}
.cm-audio-host--show iframe { height: 80px; }

/* botón flotante de nota musical, al pie de la tarjeta */
.cm-music-toggle {
  position: absolute; left: 50%; bottom: 3.5%; z-index: 9;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center; cursor: pointer;
  background: color-mix(in oklab, var(--accent), transparent 8%); color: #2a1d0c;
  border: 1px solid color-mix(in oklab, var(--accent), white 12%);
  box-shadow: 0 6px 18px -6px rgba(0,0,0,.6);
  opacity: 0; pointer-events: none;
  transform: translateX(-50%) translateY(8px);
  transition: opacity .5s ease .55s, transform .5s ease .55s, background .25s ease;
}
.cm-card.is-open .cm-music-toggle { opacity: 1; pointer-events: auto; transform: translateX(-50%) translateY(0); }
.cm-music-toggle .cm-mnote { position: relative; font-size: 1.05rem; line-height: 1; }
.cm-music-toggle.is-on { animation: cm-mpulse 2.2s ease-in-out infinite; }
@keyframes cm-mpulse {
  0%,100% { box-shadow: 0 6px 18px -6px rgba(0,0,0,.6), 0 0 0 0 color-mix(in oklab, var(--accent), transparent 55%); }
  60%     { box-shadow: 0 6px 18px -6px rgba(0,0,0,.6), 0 0 0 9px color-mix(in oklab, var(--accent), transparent 100%); }
}
.cm-music-toggle.is-off {
  background: color-mix(in oklab, var(--accent), transparent 75%);
  color: var(--cream); animation: none;
}
.cm-music-toggle.is-off .cm-mnote::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: 24px; height: 2px; background: currentColor; border-radius: 2px;
  transform: translate(-50%, -50%) rotate(-45deg);
}

/* ---------- Burbuja de recuerdos (3 fotos + mensaje) -------------- */
.cm-bubble {
  position: absolute; left: 12%; bottom: 13%; z-index: 9; padding: 0;
  width: 52px; height: 52px; border-radius: 50%; cursor: pointer; overflow: hidden;
  border: 2px solid color-mix(in oklab, var(--accent), white 10%);
  background: var(--card-bg2);
  box-shadow: 0 8px 22px -6px rgba(0,0,0,.7);
  opacity: 0; pointer-events: none;
  transition: opacity .5s ease .7s;
}
.cm-card.is-open .cm-bubble { opacity: 1; pointer-events: auto; }
.cm-bubble-thumb { width: 100%; height: 100%; object-fit: cover; display: block; }
.cm-bubble-ring {
  position: absolute; inset: -3px; border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--accent), transparent 40%);
}
.cm-card.is-open .cm-bubble-ring { animation: cm-bubble-ring 2.6s ease-out infinite; }
@keyframes cm-bubble-ring { 0% { transform: scale(.82); opacity: .8; } 100% { transform: scale(1.55); opacity: 0; } }

/* movimientos (solo con la carta abierta) */
.cm-card.is-open .cm-bmove-float { animation: cm-bmove-float 4s ease-in-out infinite; }
.cm-card.is-open .cm-bmove-drift { animation: cm-bmove-drift 9s ease-in-out infinite; }
.cm-card.is-open .cm-bmove-orbit { animation: cm-bmove-orbit 7s linear infinite; }
.cm-card.is-open .cm-bmove-pulse { animation: cm-bmove-pulse 2.4s ease-in-out infinite; }
@keyframes cm-bmove-float { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-12px); } }
@keyframes cm-bmove-drift {
  0%,100% { transform: translate(0,0); }
  25% { transform: translate(34px,-16px); }
  50% { transform: translate(86px,-6px); }
  75% { transform: translate(46px,-26px); }
}
@keyframes cm-bmove-orbit {
  from { transform: rotate(0deg) translateX(30px) rotate(0deg); }
  to   { transform: rotate(360deg) translateX(30px) rotate(-360deg); }
}
@keyframes cm-bmove-pulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.14); } }

/* el revelado de las fotos */
.cm-photos {
  position: absolute; inset: 0; z-index: 10; border-radius: 6px;
  opacity: 0; pointer-events: none; transition: opacity .3s ease;
}
.cm-photos.is-shown { opacity: 1; pointer-events: auto; }
.cm-photos-bd {
  position: absolute; inset: 0; border-radius: 6px;
  background: rgba(8,6,4,.74); -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
}
.cm-photo {
  position: absolute; margin: 0; width: 42%; aspect-ratio: 4 / 5;
  background: #f4eddd; padding: 5px; border-radius: 3px;
  box-shadow: 0 12px 28px -8px rgba(0,0,0,.85);
  opacity: 0; transform: scale(.55) rotate(var(--rot, 0deg));
  transition: opacity .45s ease, transform .55s cubic-bezier(.2,.7,.2,1);
}
.cm-photos.is-shown .cm-photo {
  opacity: 1; transform: scale(1) rotate(var(--rot, 0deg));
  transition-delay: calc(var(--i, 0) * .12s);
}
.cm-photo img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: 2px; }
.cm-photo-tl { top: 6%;  left: 5%;  --rot: -5deg; }
.cm-photo-cr { top: 33%; right: 5%; --rot: 4deg; }
.cm-photo-bl { bottom: 15%; left: 8%; --rot: -3deg; }
.cm-photos-msg {
  position: absolute; left: 8%; right: 8%; bottom: 5%; z-index: 1; text-align: center;
  font-family: var(--card-body, var(--font-body)); font-size: .95rem; line-height: 1.4;
  color: var(--cream); text-shadow: 0 2px 10px rgba(0,0,0,.85);
}
.cm-photos-close {
  position: absolute; top: 3.5%; right: 4%; z-index: 2;
  width: 30px; height: 30px; border-radius: 50%; cursor: pointer; line-height: 1;
  border: 1px solid var(--line-strong); background: rgba(0,0,0,.5); color: var(--cream); font-size: 1.2rem;
}

/* =================================================================
   ESTILO 1 · SOBRE — sobre compacto CENTRADO en la tarjeta.
   Secuencia: 1) la solapa se abre del todo y pasa atrás; 2) recién
   entonces la hoja (que parte ≈ del tamaño del sobre) sube por la
   boca y, ya afuera, se acerca y se agranda al frente.
   Geometría: sobre = 80% ancho × 52% alto, centrado (24%–76%).
   Ratio ~1.15 (estilo invitación clásica), se ve bien en mobile.
   ================================================================= */
/* OJO: sin perspective aquí — crearía stacking context y el bolsillo (z3)
   dejaría de tapar la hoja (z2); la perspectiva va en el transform de la solapa */
.cm-style-sobre .cm-cover { position: absolute; inset: 0; }
.cm-style-sobre.is-open .cm-cover { pointer-events: none; }

/* sombra suave en el piso, bajo el sobre (lo asienta en la escena) */
.cm-style-sobre .env-shadow {
  position: absolute; left: 13%; right: 13%; top: 73.5%; height: 5%;
  border-radius: 50%; z-index: 0; filter: blur(5px);
  background: radial-gradient(50% 100% at 50% 50%, rgba(0,0,0,.5), transparent 70%);
}

/* dorso del sobre (el interior asoma en la boca) */
.cm-style-sobre .env-back {
  position: absolute; left: 10%; right: 10%; top: 24%; height: 52%;
  border-radius: 6px; z-index: 1; overflow: hidden;
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--card-bg2), black 30%) 0%,
    var(--card-bg) 35%, var(--card-bg2) 100%);
  border: 1px solid var(--line-strong);
}
/* forro interior con rayas diagonales al acento (lujo clásico de sobre) */
.cm-style-sobre .env-liner {
  position: absolute; left: 0; right: 0; top: 0; height: 36%;
  background: repeating-linear-gradient(45deg,
    color-mix(in oklab, var(--accent), transparent 72%) 0 5px, transparent 5px 11px);
  -webkit-mask-image: linear-gradient(180deg, #000 50%, transparent);
          mask-image: linear-gradient(180deg, #000 50%, transparent);
}
/* bolsillo frontal: su borde superior es una V con vértice ABAJO que
   COINCIDE con la punta de la solapa (47% del card = 44% local) → la
   solapa cerrada calza exacto y NO queda franja del dorso a los costados */
.cm-style-sobre .env-front {
  position: absolute; left: 10%; right: 10%; top: 24%; height: 52%;
  border-radius: 0 0 6px 6px; z-index: 3;
  background: linear-gradient(180deg, var(--card-bg) 0%, var(--card-bg2) 100%);
  border: 1px solid var(--line-strong);
  clip-path: polygon(0 0, 50% 44%, 100% 0, 100% 100%, 0 100%);
  box-shadow: 0 -8px 24px -10px rgba(0,0,0,.7) inset;
}
.cm-style-sobre .env-front::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(120% 80% at 50% 120%, color-mix(in oklab, var(--accent), transparent 86%), transparent 55%);
}
/* estampilla con borde perforado, apenas girada */
.cm-style-sobre .env-stamp {
  position: absolute; top: 32.5%; right: 14%; width: 9%; aspect-ratio: 4 / 5; z-index: 3;
  display: grid; place-items: center; transform: rotate(3.5deg);
  background: color-mix(in oklab, var(--accent), transparent 84%);
  border: 1px dashed color-mix(in oklab, var(--accent), transparent 30%);
  border-radius: 2px;
  color: color-mix(in oklab, var(--accent), transparent 15%);
  font-size: clamp(.5rem, 2vw, .75rem); line-height: 1;
}
.cm-style-sobre .env-label {
  position: absolute; left: 14%; right: 14%; top: 56%;
  text-align: center; display: flex; flex-direction: column; gap: 0.4rem;
  transition: opacity .4s ease;
}
.cm-style-sobre .env-occ {
  font-family: var(--font-mono); font-size: 0.56rem; letter-spacing: 0.26em;
  text-transform: uppercase; color: color-mix(in oklab, var(--accent), transparent 25%);
}
.cm-style-sobre .env-to {
  font-family: var(--font-display); font-style: italic; font-size: 1.15rem; color: var(--cream);
}
/* sello de lacre en la punta de la solapa (hijo del cover para
   quedar por encima de la solapa — env-front crea stacking context) */
.cm-style-sobre .env-seal {
  position: absolute; top: 47%; left: 50%; transform: translate(-50%, -50%);
  width: 10%; height: auto; aspect-ratio: 1; border-radius: 50%; z-index: 5;
  display: grid; place-items: center;
  background: radial-gradient(circle at 35% 30%, color-mix(in oklab, var(--accent), white 18%), var(--accent) 70%, #8a6a3e);
  color: #2a1d0c; font-family: var(--font-display); font-weight: 700; font-size: clamp(.7rem, 3vw, 1rem);
  box-shadow: 0 6px 16px -4px rgba(0,0,0,.7);
  transition: transform .45s ease, opacity .4s ease;
}
/* solapa: cuelga sobre el bolsillo y bate hacia arriba al abrir.
   Sin clip-path propio (aplanaría el 3D de las caras): cada cara
   lleva el triángulo; la interior muestra el forro al quedar abierta */
.cm-style-sobre .env-flap {
  position: absolute; left: 10%; right: 10%; top: 24%; height: 23%;
  transform-origin: top center; z-index: 4;
  transform-style: preserve-3d;
  transform: perspective(900px) rotateX(0deg);
}
.cm-style-sobre .ef-face {
  position: absolute; inset: 0; backface-visibility: hidden;
  clip-path: polygon(0 0, 100% 0, 50% 100%);
}
/* cara exterior (la que se ve cerrada) */
.cm-style-sobre .ef-out {
  background: linear-gradient(180deg, color-mix(in oklab, var(--card-bg), white 7%) 0%, var(--card-bg2) 100%);
  box-shadow: inset 0 1px 0 var(--line-strong), inset 0 -10px 16px -10px rgba(0,0,0,.55);
}
/* cara interior: el mismo forro a rayas del sobre. Clip INVERTIDO
   (punta arriba) para que, tras el rotateX(180) propio + el rotateX(-180)
   del padre, el triángulo abierto apunte hacia ARRIBA (lejos del sobre),
   no hacia el sobre como pasaba antes */
.cm-style-sobre .ef-in {
  transform: rotateX(180deg);
  clip-path: polygon(0 100%, 100% 100%, 50% 0);
  background:
    repeating-linear-gradient(45deg, color-mix(in oklab, var(--accent), transparent 74%) 0 5px, transparent 5px 11px),
    linear-gradient(180deg, color-mix(in oklab, var(--card-bg), black 12%), var(--card-bg2));
}
.cm-style-sobre.is-open .env-flap {
  transform: perspective(900px) rotateX(-180deg); z-index: 1;
  animation: cm-sobre-flap 2.3s forwards;
}
/* 1) la solapa abre del todo (33%) y recién ahí pasa a z1 (atrás) */
@keyframes cm-sobre-flap {
  0%   { transform: perspective(900px) rotateX(0deg);   z-index: 4; animation-timing-function: cubic-bezier(.5,.05,.3,1); }
  33%  { transform: perspective(900px) rotateX(-180deg); z-index: 4; }
  34%  { transform: perspective(900px) rotateX(-180deg); z-index: 1; }
  100% { transform: perspective(900px) rotateX(-180deg); z-index: 1; }
}

/* la carta: cerrada ocupa ≈ el sobre (scale .5, z2 tapada por el
   bolsillo). Espera a que la solapa abra; luego sube (aún detrás del
   bolsillo) y, ya con la base fuera, pasa al frente (z6) y se agranda. */
.cm-style-sobre .cm-letter {
  position: absolute; left: 6%; right: 6%; top: 7%; bottom: 7%;
  overflow: auto;
  background: linear-gradient(180deg, #f7f0e1 0%, #efe6cf 55%, #e6dcc4 100%);
  color: #2a2318; border-radius: 4px;
  padding: 1.6rem 1.5rem; z-index: 2;
  box-shadow: 0 16px 34px -16px rgba(0,0,0,.85), inset 0 0 46px rgba(140,105,55,.12);
  transform: translateY(0) scale(.5);
}
/* marcas del doblez en tres (la carta venía plegada dentro del sobre) */
.cm-style-sobre .cm-letter::before {
  content: ""; position: absolute; left: 0; right: 0; top: 0; height: 100%;
  pointer-events: none;
  background:
    linear-gradient(180deg, transparent calc(33.4% - 1.5px), rgba(96,74,40,.12) calc(33.4% - .5px), rgba(255,255,255,.5) 33.4%, transparent calc(33.4% + 1.5px)),
    linear-gradient(180deg, transparent calc(66.7% - 1.5px), rgba(96,74,40,.12) calc(66.7% - .5px), rgba(255,255,255,.5) 66.7%, transparent calc(66.7% + 1.5px));
}
.cm-style-sobre.is-open .cm-letter {
  transform: translateY(0) scale(1); z-index: 6;
  animation: cm-sobre-letter 2.3s forwards;
}
/* 2) espera (0–38%), sube creciendo aún detrás (38–72%), cambia de
      plano ya afuera (74%) y se acerca a tamaño completo, centrada */
@keyframes cm-sobre-letter {
  0%   { transform: translateY(0) scale(.5) rotate(0deg); z-index: 2; }
  38%  { transform: translateY(0) scale(.5) rotate(0deg); z-index: 2; animation-timing-function: cubic-bezier(.3,.6,.25,1); }
  72%  { transform: translateY(-14%) scale(.72) rotate(-2.4deg); z-index: 2; animation-timing-function: cubic-bezier(.4,0,.2,1); }
  74%  { transform: translateY(-15%) scale(.74) rotate(-2.2deg); z-index: 6; }
  100% { transform: translateY(0) scale(1) rotate(0deg); z-index: 6; }
}
.cm-style-sobre .cm-letter .cm-occ { color: #9a7b46; margin-bottom: .7rem; }
.cm-style-sobre .cm-letter .cm-to { color: #2a2318; font-size: 1.45rem; margin-bottom: .7rem; }
.cm-style-sobre .cm-letter .cm-msg { color: #2a2318; font-size: .92rem; line-height: 1.6; }
.cm-style-sobre .cm-letter .cm-from { color: #2a2318; margin-top: 1rem; }
.cm-style-sobre .cm-letter .cm-music-cue { color: #8a7a5a; }

/* el contenido aparece escalonado cuando la hoja ya se posó al frente */
.cm-style-sobre .cm-letter-inner > * { opacity: 0; transform: translateY(6px); transition: opacity .5s ease, transform .5s ease; }
.cm-style-sobre.is-open .cm-letter-inner > * { opacity: 1; transform: none; }
.cm-style-sobre.is-open .cm-letter-inner > :nth-child(1) { transition-delay: 1.9s; }
.cm-style-sobre.is-open .cm-letter-inner > :nth-child(2) { transition-delay: 2.02s; }
.cm-style-sobre.is-open .cm-letter-inner > :nth-child(3) { transition-delay: 2.14s; }
.cm-style-sobre.is-open .cm-letter-inner > :nth-child(4) { transition-delay: 2.26s; }

.cm-style-sobre.is-open .env-label { opacity: 0; }
/* el lacre se QUIEBRA: pequeño pop con giro y desaparece al abrir */
.cm-style-sobre.is-open .env-seal { animation: cm-seal-pop .55s ease forwards; }
@keyframes cm-seal-pop {
  0%   { transform: translate(-50%, -50%) scale(1) rotate(0deg); opacity: 1; }
  40%  { transform: translate(-50%, -50%) scale(1.18) rotate(-7deg); opacity: 1; }
  100% { transform: translate(-50%, -50%) scale(.45) rotate(5deg); opacity: 0; }
}

/* =================================================================
   ESTILO 2 · QUEMADA — la carta llega DOBLADA en 2 (paquete centrado,
   mitad de alto). Al tocar, la mitad superior se DESDOBLA HACIA EL
   FRENTE desde el pliegue central (bisagra en el medio, no en los
   bordes) mientras el papel se extiende desde el centro; al terminar,
   el mensaje aparece escrito sobre la hoja (cross-fade de pergaminos).
   ================================================================= */
/* color de la hoja quemada = la paleta elegida (tinte OPACO del acento, claro
   para legibilidad). Todas las superficies usan el MISMO papel → el cross-fade
   cover→hoja no salta de color. --qchar = borde carbonizado (oscuro tintado). */
.cm-style-quemada {
  --qpaper:  color-mix(in oklab, var(--accent), #f5edd9 56%);
  --qpaper2: color-mix(in oklab, var(--accent), #e6d6af 48%);
  --qchar:   color-mix(in oklab, var(--accent), #1c0e04 24%);
}
.cm-style-quemada .cm-cover {
  position: absolute; inset: 0; z-index: 3;
  perspective: 1100px;
  /* cerrado: el paquete (la mitad inferior del pliego) queda centrado */
  transform: translateY(-25%);
  transition: transform 1.6s cubic-bezier(.6,.05,.2,1), opacity .5s ease;
}
.cm-style-quemada.is-open .cm-cover {
  transform: translateY(0); opacity: 0; pointer-events: none;
  transition: transform 1.6s cubic-bezier(.6,.05,.2,1), opacity .8s ease 1.5s;
}

/* textos sobre la cara exterior del paquete (pergamino claro) */
.cm-style-quemada .env-occ {
  font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.3em;
  text-transform: uppercase; color: #8a5a28;
}
.cm-style-quemada .env-to {
  font-family: var(--card-display); font-style: italic; font-size: 1.5rem; color: #34281a;
}

/* mitad inferior del pliego: fija; se revela cuando la solapa se levanta */
.cm-style-quemada .fold-static {
  position: absolute; left: 0; right: 0; top: 50%; bottom: 0;
}
/* mitad superior: la solapa, plegada hacia el FRENTE sobre la inferior
   (bisagra = su borde inferior, el pliegue central) */
.cm-style-quemada .fold-flap {
  position: absolute; left: 0; right: 0; top: 0; height: 50%;
  transform-origin: bottom center; transform-style: preserve-3d;
  transform: rotateX(-180deg);
  transition: transform 1.6s cubic-bezier(.6,.05,.2,1);
  z-index: 2;
}
/* al abrir: barre hacia el espectador (de -180° a 0°) — hacia afuera */
.cm-style-quemada.is-open .fold-flap { transform: rotateX(0deg); }

.cm-style-quemada .ff-face { position: absolute; inset: 0; backface-visibility: hidden; }
/* las dos mitades del pliego = la MISMA hoja (background 200% de alto):
   relleno OPACO + viñeta quemada SOLO en los bordes externos (oscurece, no
   transparenta) → sin huecos al abrir y sin línea en el pliegue central */
.cm-style-quemada .fold-static,
.cm-style-quemada .ff-in {
  background:
    radial-gradient(140% 122% at 50% 50%, transparent 60%, var(--qchar) 96%),
    linear-gradient(180deg, var(--qpaper) 0%, var(--qpaper2) 100%);
  background-size: 100% 200%;
  filter: url(#cm-burn);
}
.cm-style-quemada .fold-static { background-position: 50% 100%; }
.cm-style-quemada .ff-in       { background-position: 50% 0%; }
/* cara exterior del paquete (lo que se ve cerrado): mismo papel, algo más
   curtido, con los bordes comidos por el fuego y la dedicatoria encima */
.cm-style-quemada .ff-out {
  transform: rotateX(180deg);
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .55rem; text-align: center; padding: 1.2rem;
  background:
    radial-gradient(130% 130% at 50% 50%, transparent 56%, var(--qchar) 92%),
    linear-gradient(180deg, color-mix(in oklab, var(--qpaper), black 5%), var(--qpaper2));
  filter: url(#cm-burn);
}
/* marca del pliegue en la base de la cara exterior */
.cm-style-quemada .ff-out::after {
  content: ""; position: absolute; left: 10%; right: 10%; bottom: 7%;
  height: 2px; border-radius: 2px;
  background: linear-gradient(90deg, transparent, rgba(70,40,12,.45), transparent);
}

/* marco carbonizado de la portada (turbulencia → borde irregular) */
.cm-style-quemada .burn-edge {
  position: absolute; inset: -4px; border-radius: 4px; pointer-events: none; z-index: 5;
  box-shadow:
    inset 0 0 0 5px #1a0d03,
    inset 0 0 22px 7px rgba(70,32,8,.95),
    inset 0 0 44px 14px rgba(120,60,18,.4);
  filter: url(#cm-burn);
}

/* la hoja con el mensaje, detrás de la portada (z1): aparece al FINAL,
   cuando el pliego ya se extendió — como el cover desplegado es el mismo
   pergamino en blanco, el cross-fade se lee como el mensaje escribiéndose */
.cm-style-quemada .cm-letter {
  position: absolute; inset: 0; border-radius: 3px; overflow: hidden; z-index: 1;
  background: transparent;
  opacity: 0; transition: opacity .5s ease;
}
.cm-style-quemada.is-open .cm-letter { opacity: 1; transition: opacity .8s ease 1.4s; }
/* capa de papel pergamino con SILUETA carbonizada: el pergamino se
   desvanece a transparente en el borde y el filtro de turbulencia desplaza
   ese borde alfa → quemado irregular. Ya no se ve la hoja cuadrada clara. */
.cm-style-quemada .burn-edge--paper {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(130% 130% at 50% 50%, transparent 60%, var(--qchar) 94%),
    linear-gradient(180deg, var(--qpaper) 0%, var(--qpaper2) 100%);
  filter: url(#cm-burn);
}
.cm-style-quemada .cm-letter-inner {
  position: relative; z-index: 1; max-height: 100%; overflow-y: auto;
  padding: 3rem 2.6rem;   /* más margen: el texto queda dentro del área no quemada */
}
.cm-style-quemada .cm-letter .cm-occ { color: #8a5a28; }
.cm-style-quemada .cm-letter .cm-to,
.cm-style-quemada .cm-letter .cm-msg { color: #34281a; }
.cm-style-quemada .cm-letter .cm-from { color: #5a4326; }
.cm-style-quemada .cm-letter .cm-music-cue { color: #8a6a40; }

/* =================================================================
   ESTILO 3 · CLÁSICA — tarjeta limpia que se desvanece al abrir
   ================================================================= */
.cm-style-clasica .cm-cover { position: absolute; inset: 0; z-index: 3; transition: opacity .8s ease, transform .8s ease; }
.cm-style-clasica .cls-cover {
  position: absolute; inset: 0; border-radius: 8px;
  background: linear-gradient(180deg, var(--card-bg) 0%, var(--card-bg2) 100%);
  border: 1px solid var(--line-strong);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 1rem;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.8);
}
.cm-style-clasica .cls-cover::before {
  content: ""; position: absolute; inset: 12px; border: 1px solid var(--line); border-radius: 4px;
}
.cm-style-clasica .cls-mono {
  font-family: var(--font-display); font-weight: 700; font-size: 2rem;
  color: var(--accent); letter-spacing: .05em;
}
.cm-style-clasica .env-occ {
  font-family: var(--font-mono); font-size: 0.58rem; letter-spacing: 0.26em;
  text-transform: uppercase; color: color-mix(in oklab, var(--accent), transparent 25%);
}
.cm-style-clasica .env-to {
  font-family: var(--font-display); font-style: italic; font-size: 1.5rem; color: var(--cream);
}
.cm-style-clasica .cm-letter {
  position: absolute; inset: 0; border-radius: 8px;
  background: linear-gradient(180deg, var(--card-bg) 0%, var(--card-bg2) 100%);
  border: 1px solid var(--line-strong);
  padding: 2.2rem 2rem; overflow: auto; z-index: 2;
  box-shadow: 0 30px 80px -20px rgba(0,0,0,.8);
  opacity: 0; transform: translateY(8px);
  transition: opacity .8s ease .15s, transform .8s ease .15s;
}
.cm-style-clasica.is-open .cm-cover { opacity: 0; transform: scale(1.04); pointer-events: none; }
.cm-style-clasica.is-open .cm-letter { opacity: 1; transform: translateY(0); }

/* =================================================================
   ESTILO 4 · MAPA — mapa de expedición que se despliega en 3D.
   Las alas se abren con perspectiva real (bisagra en los bordes) y
   la brújula/ruta flotan en translateZ → el tilt produce parallax.
   ================================================================= */
.cm-style-mapa,
.cm-style-mapa .cm-cover,
.cm-style-mapa .map-deco { transform-style: preserve-3d; }

.cm-style-mapa .cm-cover { position: absolute; inset: 0; z-index: 3; }
.cm-style-mapa.is-open .cm-cover { pointer-events: none; }

/* alas plegadas: bisagra en cada borde de la tarjeta */
.cm-style-mapa .map-gate {
  position: absolute; top: 0; bottom: 0; width: 50.5%;
  transform-style: preserve-3d;
  transform: translateZ(1.2px) rotateY(0deg);
  transition: transform 1.05s cubic-bezier(.6,.05,.25,1), opacity .35s ease .85s;
}
.cm-style-mapa .map-gate-l { left: 0; transform-origin: left center; }
.cm-style-mapa .map-gate-r { right: 0; transform-origin: right center; z-index: 1; transition-delay: .12s, .92s; }
.cm-style-mapa .mg-face {
  position: absolute; inset: 0; backface-visibility: hidden;
}
/* cara exterior: carpeta oscura (toma el color de la tarjeta) */
.cm-style-mapa .mg-out {
  background: linear-gradient(160deg, color-mix(in oklab, var(--card-bg), white 6%) 0%, var(--card-bg2) 100%);
  border: 1px solid var(--line-strong);
}
.cm-style-mapa .map-gate-l .mg-out { border-right-color: rgba(0,0,0,.55); border-radius: 6px 0 0 6px; }
.cm-style-mapa .map-gate-r .mg-out { border-left-color: rgba(0,0,0,.55); border-radius: 0 6px 6px 0; }
/* cara interior: el mapa continúa al batirse el ala */
.cm-style-mapa .mg-in {
  transform: rotateY(180deg);
  background:
    repeating-linear-gradient(0deg, rgba(122,90,48,.08) 0 1px, transparent 1px 30px),
    repeating-linear-gradient(90deg, rgba(122,90,48,.08) 0 1px, transparent 1px 30px),
    linear-gradient(160deg, #e8dabb 0%, #d9c89e 100%);
  box-shadow: inset 0 0 36px rgba(90,60,20,.3);
}
.cm-style-mapa.is-open .map-gate-l { transform: translateZ(1.2px) rotateY(-158deg); opacity: 0; }
.cm-style-mapa.is-open .map-gate-r { transform: translateZ(1.2px) rotateY(158deg); opacity: 0; }

/* la banda de papel que cierra el mapa plegado */
.cm-style-mapa .map-band {
  position: absolute; left: -2.5%; right: -2.5%; top: 50%;
  transform: translateY(-50%) translateZ(2px);
  display: flex; flex-direction: column; align-items: center; gap: .5rem;
  padding: 1.1rem .8rem; text-align: center; z-index: 2;
  background: linear-gradient(180deg, #221a0f 0%, #140f09 100%);
  border: 1px solid var(--line-strong);
  box-shadow: 0 12px 30px -8px rgba(0,0,0,.6);
  transition: opacity .4s ease .1s, transform .4s ease .1s;
}
.cm-style-mapa .env-occ {
  font-family: var(--font-mono); font-size: .58rem; letter-spacing: .26em;
  text-transform: uppercase; color: color-mix(in oklab, var(--accent), transparent 25%);
}
.cm-style-mapa .env-to {
  font-family: var(--font-display); font-style: italic; font-size: 1.45rem; color: var(--cream);
}
.cm-style-mapa .map-band-hint {
  font-family: var(--font-mono); font-size: .56rem; letter-spacing: .22em;
  text-transform: uppercase; color: var(--cream-faint);
}
.cm-style-mapa.is-open .map-band { opacity: 0; transform: translateY(-50%) translateZ(2px) scale(.94); }

/* la hoja: pergamino cartográfico con graticulado */
.cm-style-mapa .cm-letter {
  position: absolute; inset: 0; border-radius: 4px;
  padding: 2rem 1.8rem; overflow: auto; z-index: 2;
  background:
    repeating-linear-gradient(0deg, rgba(122,90,48,.07) 0 1px, transparent 1px 34px),
    repeating-linear-gradient(90deg, rgba(122,90,48,.07) 0 1px, transparent 1px 34px),
    radial-gradient(120% 100% at 30% 0%, #ecdfbe 0%, #e0d0a6 55%, #d4c294 100%);
  box-shadow: inset 0 0 50px rgba(90,60,20,.35);
  filter: brightness(.9);
  transition: filter .8s ease .3s;
}
.cm-style-mapa.is-open .cm-letter { filter: brightness(1); }
.cm-style-mapa .cm-letter .cm-occ { color: #8a5a28; }
.cm-style-mapa .cm-letter .cm-to,
.cm-style-mapa .cm-letter .cm-msg { color: #34281a; }
.cm-style-mapa .cm-letter .cm-from { color: #5a4326; }
.cm-style-mapa .cm-letter .cm-music-cue { color: #8a6a40; }

/* el contenido aparece escalonado al desplegar */
.cm-style-mapa .cm-letter-inner > *,
.cm-style-mapa .cm-letter .cm-music {
  opacity: 0; transform: translateY(8px);
  transition: opacity .5s ease, transform .5s ease;
}
.cm-style-mapa.is-open .cm-letter-inner > *,
.cm-style-mapa.is-open .cm-letter .cm-music { opacity: 1; transform: none; }
.cm-style-mapa.is-open .cm-letter-inner > :nth-child(1) { transition-delay: .5s; }
.cm-style-mapa.is-open .cm-letter-inner > :nth-child(2) { transition-delay: .62s; }
.cm-style-mapa.is-open .cm-letter-inner > :nth-child(3) { transition-delay: .74s; }
.cm-style-mapa.is-open .cm-letter-inner > :nth-child(4) { transition-delay: .86s; }
.cm-style-mapa.is-open .cm-letter .cm-music { transition-delay: .95s; }
/* el mensaje aparece de inmediato (se va tecleando) y la firma al final,
   cuando la ruta llega al cofre */
.cm-style-mapa.is-open .cm-msg  { transition-delay: 0s; }
.cm-style-mapa.is-open .cm-from { transition-delay: var(--route-dur, 2500ms); }
.cm-style-mapa .cm-caret {
  color: #9a4a1e; font-weight: 400; margin-left: 1px;
  animation: cm-blink 1s steps(1) infinite;
}
@keyframes cm-blink { 0%,50% { opacity: 1; } 50.01%,100% { opacity: 0; } }
/* en el estilo mapa las fotos se abren SOLO desde el cofre */
.cm-style-mapa .cm-bubble { display: none; }

/* capa 3D: ruta y brújula flotando sobre el mapa (parallax con tilt) */
.cm-style-mapa .map-deco {
  position: absolute; inset: 0; z-index: 4; pointer-events: none;
  opacity: 0; transition: opacity .6s ease .55s;
}
.cm-style-mapa.is-open .map-deco { opacity: 1; }
.map-route { position: absolute; inset: 0; width: 100%; height: 100%; transform: translateZ(12px); overflow: visible; }
/* guía punteada tenue (siempre) + trazo sólido que se DIBUJA con --route-dur */
.mr-guide {
  fill: none; stroke: #7a5226; stroke-width: 1.1; vector-effect: non-scaling-stroke;
  stroke-linecap: round; stroke-dasharray: 2.2 2.6; opacity: .28;
}
.mr-line {
  fill: none; stroke: #9a4a1e; stroke-width: 1.9; vector-effect: non-scaling-stroke;
  stroke-linecap: round; stroke-dasharray: 100; stroke-dashoffset: 0; opacity: .9;
}
.cm-style-mapa.is-open .mr-line { animation: cm-draw var(--route-dur, 2500ms) ease forwards; }
@keyframes cm-draw { from { stroke-dashoffset: 100; } to { stroke-dashoffset: 0; } }
.mr-start { fill: #9a4a1e; opacity: .9; }
.mr-lbl { font-family: var(--font-mono); font-size: 3.4px; fill: #8a5a28; opacity: .85; letter-spacing: .06em; }
.mr-lbl-start { font-style: normal; }
.mr-lbl-chest { fill: #b06a1e; opacity: .9; font-size: 3px; }

/* el cofre al final de la ruta (clickeable → abre las fotos) */
.map-chest { pointer-events: auto; cursor: pointer; opacity: 1; }
.map-chest .mc-shadow { fill: rgba(0,0,0,.35); }
.map-chest .mc-body { fill: #8a5a28; stroke: #3a2410; stroke-width: .55; }
.map-chest .mc-lid  { fill: #9c6a30; stroke: #3a2410; stroke-width: .55; }
.map-chest .mc-band { fill: #3a2410; }
.map-chest .mc-lock { fill: #ffd24a; stroke: #5a3a12; stroke-width: .3; }
/* el cofre y su rótulo aparecen al terminar la ruta (delay = --route-dur).
   fill-mode both → antes quedan ocultos; en no-anim (preview) quedan visibles */
.cm-style-mapa.is-open .map-chest {
  animation: cm-chest-in .5s ease var(--route-dur, 2500ms) both,
             cm-chest-glow 2.2s ease-in-out calc(var(--route-dur, 2500ms) + .5s) infinite;
}
.cm-style-mapa.is-open .mr-lbl-chest { animation: cm-chest-in .5s ease var(--route-dur, 2500ms) both; }
@keyframes cm-chest-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes cm-chest-glow {
  0%,100% { filter: drop-shadow(0 0 1.5px rgba(255,210,74,.5)); }
  50%     { filter: drop-shadow(0 0 6px rgba(255,210,74,.95)); }
}
.map-compass { position: absolute; top: 5.5%; right: 6.5%; width: 22%; transform: translateZ(26px); }
.mc-ring { fill: none; stroke: #7a5226; stroke-width: 1.2; opacity: .55; }
.mc-dot { fill: #7a5226; opacity: .8; }
.mc-needle { transform-origin: 40px 40px; animation: cm-needle 4.5s ease-in-out infinite alternate; }
.mc-needle polygon { fill: #8a5a28; opacity: .8; }
@keyframes cm-needle { from { transform: rotate(-11deg); } to { transform: rotate(11deg); } }
.mc-n { font-family: var(--font-mono); font-size: 8px; fill: #7a5226; opacity: .7; }

/* =================================================================
   COLOR DE LA TARJETA (bg) — tonos ricos dark-luxury
   ================================================================= */
.cm-card { --card-bg: #1a1610; --card-bg2: #110d07; }
.cm-bg-noche      { --card-bg:#1a1610; --card-bg2:#110d07; }
.cm-bg-carbon     { --card-bg:#1c1c20; --card-bg2:#0e0e12; }
.cm-bg-medianoche { --card-bg:#172741; --card-bg2:#0b1326; }
.cm-bg-esmeralda  { --card-bg:#152a1f; --card-bg2:#0a160f; }
.cm-bg-vino       { --card-bg:#2c1119; --card-bg2:#15080c; }
.cm-bg-ciruela    { --card-bg:#241530; --card-bg2:#120a18; }

/* =================================================================
   TIPOGRAFÍA DE LA TARJETA (font)
   ================================================================= */
.cm-card { --card-display: var(--font-display); --card-body: var(--font-body); }
.cm-font-editorial { --card-display: var(--font-display); --card-body: var(--font-body); }
.cm-font-romantica { --card-display: "Great Vibes", cursive; --card-body: "Cormorant Garamond", Georgia, serif; }
.cm-font-clasica   { --card-display: "Cinzel", Georgia, serif; --card-body: "EB Garamond", Georgia, serif; }
.cm-font-maquina   { --card-display: "Special Elite", "Courier New", monospace; --card-body: "Special Elite", "Courier New", monospace; }
/* ajustes finos por familia (sistema viejo whole-card; se mantiene inofensivo) */
.cm-font-romantica .cm-to { font-size: clamp(2.1rem, 9vw, 3rem); font-style: normal; line-height: 1.05; }
.cm-font-clasica .cm-to { font-style: normal; text-transform: uppercase; letter-spacing: .05em; font-size: clamp(1.3rem, 5vw, 1.7rem); }
.cm-font-maquina .cm-to { font-style: normal; font-size: clamp(1.3rem, 5vw, 1.7rem); }
.cm-font-romantica .cm-msg { font-size: clamp(1.05rem, 4vw, 1.22rem); }
.cm-font-clasica .cm-msg { font-size: clamp(1rem, 3.8vw, 1.15rem); }

/* --- Fuente POR ELEMENTO (Título=occ+nombre · Mensaje=msg · Firma=from).
   Estas clases (cm-ff-*) van DESPUÉS de las reglas base de .cm-occ/.cm-to/
   .cm-msg/.cm-from para ganar por orden (misma especificidad). ----------- */
.cm-ff-editorial { font-family: var(--font-display); }
.cm-ff-romantica { font-family: "Great Vibes", cursive; }
.cm-ff-clasica   { font-family: "Cinzel", Georgia, serif; }
.cm-ff-maquina   { font-family: "Special Elite", "Courier New", monospace; }

/* nombre grande (.cm-to) — ajustes por familia */
.cm-to.cm-ff-romantica { font-size: clamp(2.1rem, 9vw, 3rem); font-style: normal; line-height: 1.05; }
.cm-to.cm-ff-clasica   { font-style: normal; text-transform: uppercase; letter-spacing: .05em; font-size: clamp(1.3rem, 5vw, 1.7rem); }
.cm-to.cm-ff-maquina   { font-style: normal; font-size: clamp(1.3rem, 5vw, 1.7rem); }
/* mensaje (.cm-msg) */
.cm-msg.cm-ff-romantica { font-size: clamp(1.05rem, 4vw, 1.22rem); }
.cm-msg.cm-ff-clasica   { font-size: clamp(1rem, 3.8vw, 1.15rem); }
/* kicker (.cm-occ) y firma (.cm-from): el script no luce en mayúsculas
   con tracking — se ajustan */
.cm-occ.cm-ff-romantica  { text-transform: none; letter-spacing: .02em; font-size: 1.05rem; }
.cm-from.cm-ff-romantica { text-transform: none; letter-spacing: 0; font-size: 1.15rem; }

/* =================================================================
   ESCENA / FONDO detrás de la tarjeta (scene)
   ================================================================= */
.cm-scene { position: absolute; inset: 0; z-index: 0; pointer-events: none; overflow: hidden; }
.cm-scene-liso { background: transparent; }
.cm-scene-glow { background: radial-gradient(45% 40% at 50% 42%, color-mix(in oklab, var(--accent, #c9a06a), transparent 82%), transparent 70%); }
.cm-scene-aurora {
  background:
    linear-gradient(160deg, color-mix(in oklab, var(--accent), transparent 85%), transparent 45%),
    radial-gradient(55% 45% at 82% 8%, color-mix(in oklab, #6a86c9, transparent 80%), transparent 60%),
    radial-gradient(55% 45% at 12% 88%, color-mix(in oklab, var(--accent), transparent 84%), transparent 60%);
}
.cm-scene-bokeh {
  background:
    radial-gradient(circle 70px at 22% 28%, color-mix(in oklab, var(--accent), transparent 78%), transparent 70%),
    radial-gradient(circle 100px at 76% 62%, color-mix(in oklab, var(--accent), transparent 86%), transparent 70%),
    radial-gradient(circle 46px at 62% 18%, color-mix(in oklab, var(--accent), transparent 80%), transparent 70%),
    radial-gradient(circle 60px at 35% 78%, color-mix(in oklab, var(--accent), transparent 88%), transparent 70%);
  filter: blur(2px);
}
.cm-scene-vineta { background: radial-gradient(72% 72% at 50% 48%, transparent 38%, rgba(0,0,0,.6) 100%); }
.cm-scene-estrellas { background: radial-gradient(50% 50% at 50% 38%, color-mix(in oklab, var(--accent), transparent 88%), transparent 70%); }
.cm-scene-estrellas b {
  position: absolute; width: var(--sz, 2px); height: var(--sz, 2px); border-radius: 50%;
  background: #fff; opacity: var(--o, .6); box-shadow: 0 0 4px #fff;
  animation: cm-star 3s ease-in-out var(--d, 0s) infinite;
}
@keyframes cm-star { 0%,100%{ opacity: calc(var(--o, .6) * .25); } 50%{ opacity: var(--o, .6); } }

/* --- Movimiento del fondo (deriva/pulso/giro) — anima la capa .cm-scene.
   Parten de un scale base para no descubrir bordes al transformar. -------- */
.cm-scenemv-deriva { transform: scale(1.16); animation: cm-bgdrift 22s ease-in-out infinite alternate; will-change: transform; }
.cm-scenemv-pulso  { animation: cm-bgpulse 8s ease-in-out infinite; will-change: transform; }
.cm-scenemv-giro   { transform: scale(1.45); transform-origin: center; animation: cm-bgspin 70s linear infinite; will-change: transform; }
@keyframes cm-bgdrift { from { transform: scale(1.16) translate(-3%, -2%); } to { transform: scale(1.2) translate(3%, 2%); } }
@keyframes cm-bgpulse { 0%,100% { transform: scale(1); } 50% { transform: scale(1.12); } }
@keyframes cm-bgspin  { from { transform: scale(1.45) rotate(0deg); } to { transform: scale(1.45) rotate(360deg); } }

/* =================================================================
   EFECTOS (fx) — partículas y barrido
   ================================================================= */
.cm-fx { position: absolute; inset: 0; z-index: 7; pointer-events: none; overflow: hidden; border-radius: 6px; }
.cm-fx i { position: absolute; width: var(--sz, 3px); height: var(--sz, 3px); }
.cm-fx-destellos i {
  border-radius: 50%; background: radial-gradient(circle, #fff 0%, var(--accent) 55%, transparent 70%);
  box-shadow: 0 0 6px var(--accent); opacity: 0;
  animation: cm-twinkle var(--t, 4s) ease-in-out var(--d, 0s) infinite;
}
@keyframes cm-twinkle { 0%,100%{ opacity:0; transform:scale(.3); } 50%{ opacity:.95; transform:scale(1); } }
.cm-fx-brasas i {
  top: auto; bottom: -8px; border-radius: 50%;
  background: radial-gradient(circle, #ffe1b0, #e8742a 55%, transparent 70%);
  box-shadow: 0 0 7px #e8742a; opacity: 0;
  animation: cm-ember var(--t, 5s) linear var(--d, 0s) infinite;
}
@keyframes cm-ember {
  0%{ transform: translateY(0) translateX(0) scale(1); opacity:0; }
  12%{ opacity:.95; } 85%{ opacity:.5; }
  100%{ transform: translateY(-520px) translateX(14px) scale(.3); opacity:0; }
}
.cm-fx-corazones i {
  top: auto; bottom: -16px; width: auto; height: auto; line-height: 1;
  color: var(--accent); font-size: var(--sz, 12px); opacity: 0;
  animation: cm-heart var(--t, 6s) ease-in var(--d, 0s) infinite;
}
@keyframes cm-heart {
  0%{ transform: translateY(0) rotate(-6deg); opacity:0; }
  16%{ opacity:.85; }
  100%{ transform: translateY(-520px) rotate(8deg); opacity:0; }
}
.cm-fx-brillo .cm-fx::after {
  content: ""; position: absolute; inset: 0; z-index: 7; pointer-events: none; border-radius: 6px;
  background: linear-gradient(115deg, transparent 38%, color-mix(in oklab, var(--accent), white 35%) 50%, transparent 62%);
  background-size: 280% 280%; mix-blend-mode: screen;
  animation: cm-shimmer 5s ease-in-out infinite;
}
@keyframes cm-shimmer {
  0%{ background-position: 130% 0; opacity:0; }
  35%{ opacity:.4; } 70%{ opacity:0; }
  100%{ background-position: -130% 0; opacity:0; }
}

/* ---------- Grano sutil global (opcional, brand) ------------------ */
.cm-grain {
  position: fixed; inset: 0; pointer-events: none; z-index: 0; opacity: .04;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

@media (prefers-reduced-motion: reduce) {
  .cm-card, .cm-card *, .cm-card::after, .cm-hint,
  .cm-scene, .cm-scene * { transition: none !important; animation: none !important; }
}
