/* ═══════════════════════════════════════════════════════════════════
   HUB V2 — EL PORTAL (index.html) — 2026-09-16
   Fuentes: DEMIN_CONSCIENTE_MOTION_SYSTEM_V1_MASTER_BRIEF (principios) +
   DEMIN_HUB_V2_CLAUDE_CODE_IMPLEMENTATION_SPEC (decisiones del hub).
   Ambos .docx viven en material-fuente/specs-docx/.

   Solo la carga index.html, y todo va escopado a body.page-portal:
   css/style-registro.css (tokens, reset, .pill, .skip-link, Time Check)
   la comparten 8 páginas y no se toca.

   ESTRUCTURA = UN UMBRAL
   01 umbral ..... PAUSE → BREATH   halo que respira, sigue al puntero y se
                                    abre al hacer scroll (cruzar el umbral)
   02 identidad .. REVEAL           palabra por palabra; los verbos se doran
   03 portales ... REVEAL + dibujo  el arco se traza; un relevo pasa la
                                    respiración de un umbral a otro
                   PULSE  matraz (burbujas) · BREATH pulmones · FLOW raíces
   04 comunidad .. REVEAL + PULSE   dos latidos y quieto
   05 cierre ..... PAUSE → BREATH   eco del halo del inicio

   REGLAS
   - Todo lo que se mueve vive bajo html.has-motion (script inline del
     <head>, solo sin prefers-reduced-motion). Sin esa clase, lectura
     estática completa.
   - Los loops infinitos solo corren en regiones .is-live (en pantalla).
   - Solo transform / scale / translate / opacity / clip-path /
     stroke-dashoffset, y blur de 4px en la entrada de texto.
   - Un solo glifo en movimiento a la vez (relevo en desktop, línea
     central en touch).
   ═══════════════════════════════════════════════════════════════════ */

.page-portal {
  --dark: #1C1A18;
  --gold: #C9A84C;
  --cream: #F2EDE4;
  --warm-gray: #6B6259;
  --off-white: #EDE8DF;

  --ink-muted: rgba(242, 237, 228, 0.62);
  --ink-quiet: rgba(242, 237, 228, 0.42);
  --rule: rgba(201, 168, 76, 0.2);
  --rule-strong: rgba(201, 168, 76, 0.55);

  /* ── Motion tokens (Motion System V1) ── */
  --breath-dur: 6s;                               /* BREATH 5–7 s */
  --breath-scale-min: 0.98;                       /* 0.98 → 1 → 0.98 (spec HUB) */
  --pulse-scale: 1.025;                           /* PULSE 1 → 1.025 → 1 */
  --reveal-dur: 900ms;                            /* REVEAL 600–1000 ms */
  --reveal-y: 20px;
  --reveal-blur: 4px;
  --ease-breath: cubic-bezier(0.45, 0, 0.55, 1);
  --ease-reveal: cubic-bezier(0.22, 1, 0.36, 1);

  background-color: var(--dark);
  color: var(--cream);
}

.page-portal ::selection { background: rgba(201, 168, 76, 0.35); color: var(--cream); }
.page-portal :focus-visible { outline: 2px solid var(--gold); outline-offset: 4px; }
.page-portal .skip-link { background-color: var(--gold); color: var(--dark); }

/* Loops infinitos: pausados fuera de pantalla. */
.has-motion [data-live]:not(.is-live) * { animation-play-state: paused !important; }

/* ─── REVEAL ─────────────────────────────────────────────────────── */
.has-motion .page-portal .pr,
.has-motion .page-portal .pr-words .w {
  opacity: 0;
  transform: translate3d(0, var(--reveal-y), 0);
  filter: blur(var(--reveal-blur));
  transition:
    opacity var(--reveal-dur) var(--ease-reveal) calc(var(--d, 0ms) + var(--wd, 0ms)),
    transform var(--reveal-dur) var(--ease-reveal) calc(var(--d, 0ms) + var(--wd, 0ms)),
    filter var(--reveal-dur) var(--ease-reveal) calc(var(--d, 0ms) + var(--wd, 0ms)),
    color 1400ms var(--ease-reveal) calc(var(--d, 0ms) + var(--wd, 0ms) + 500ms);
}
.has-motion .page-portal .pr-words .w { display: inline-block; transform: translate3d(0, 0.35em, 0); }
.has-motion .page-portal .pr.is-in,
.has-motion .page-portal .pr-words.is-in .w {
  opacity: 1;
  transform: none;
  filter: none;
}

/* ═══ 01 — UMBRAL ═══════════════════════════════════════════════════ */
.threshold {
  --px: 0;
  --py: 0;
  position: relative;
  min-height: 100vh;
  min-height: 100svh;
  display: grid;
  place-items: center;
  padding: 6rem 1.5rem 7rem;
  /* clip, no hidden: overflow:hidden convierte al umbral en contenedor de
     scroll y la animación ligada a view() dejaría de ver el scroll real. */
  overflow: hidden;
  overflow: clip;
  isolation: isolate;
}

.threshold__halo {
  position: absolute;
  top: 50%;
  left: 50%;
  width: min(620px, 118vw);
  aspect-ratio: 1;
  translate: -50% -52%;
  z-index: -1;
  pointer-events: none;
}
.threshold__halo-move {
  width: 100%;
  height: 100%;
  translate: calc(var(--px) * 1px) calc(var(--py) * 1px);
  transition: translate 1.2s var(--ease-reveal);
}
.threshold__halo svg { width: 100%; height: 100%; overflow: visible; }
.threshold__halo circle { stroke: var(--gold); stroke-width: 0.35; vector-effect: non-scaling-stroke; }
.threshold__halo circle:nth-child(1) { opacity: 0.18; }
.threshold__halo circle:nth-child(2) { opacity: 0.12; }
.threshold__halo circle:nth-child(3) { opacity: 0.08; }
.threshold__halo::before {
  content: '';
  position: absolute;
  inset: 22%;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(201, 168, 76, 0.08) 0%, transparent 70%);
}

.threshold__inner { text-align: center; }

.page-portal .threshold__title {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(2.6rem, 11.5vw, 6.25rem);
  line-height: 0.98;
  letter-spacing: 0.06em;
  padding-left: 0.06em;
  margin: 0;
}
.threshold__title span { display: block; }

.threshold__statement {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15em;
  margin-top: clamp(1.75rem, 5vw, 2.75rem);
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.2rem, 3.6vw, 1.625rem);
  line-height: 1.3;
  color: var(--ink-muted);
}
.threshold__statement span:last-child { color: var(--cream); }

.threshold__enter {
  position: absolute;
  bottom: clamp(1.75rem, 5vh, 3rem);
  left: 50%;
  translate: -50% 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.75rem;
  padding: 0.5rem 1rem;
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--ink-quiet);
  transition: color 400ms var(--ease-reveal);
}
.threshold__enter-line {
  position: relative;
  display: block;
  width: 1px;
  height: 2.5rem;
  background: linear-gradient(to bottom, var(--rule-strong), transparent);
}
@media (hover: hover) and (pointer: fine) {
  .threshold__enter:hover { color: var(--gold); }
}

/* BREATH — empieza después de la entrada (PAUSE primero). */
.has-motion .threshold__halo svg {
  transform-origin: 50% 50%;
  animation: portalBreath var(--breath-dur) var(--ease-breath) 3.6s infinite both;
}
@keyframes portalBreath {
  0%, 100% { transform: scale(var(--breath-scale-min)); opacity: 0.8; }
  50%      { transform: scale(1); opacity: 1; }
}
.has-motion .threshold__halo { animation: portalHaloIn 2.4s var(--ease-reveal) 0.2s both; }
@keyframes portalHaloIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* FLOW — un punto de luz baja por la línea de "Entrar". */
.has-motion .threshold__enter-line::after {
  content: '';
  position: absolute;
  top: 0;
  left: 50%;
  width: 3px;
  height: 3px;
  margin-left: -1.5px;
  border-radius: 50%;
  background: var(--gold);
  opacity: 0;
  animation: enterDrop 3.2s var(--ease-breath) 4.2s infinite;
}
@keyframes enterDrop {
  0%   { transform: translateY(0); opacity: 0; }
  15%  { opacity: 1; }
  70%  { transform: translateY(2.5rem); opacity: 0; }
  100% { transform: translateY(2.5rem); opacity: 0; }
}

/* Cruzar el umbral: al salir por arriba, el halo se abre y el título se
   disuelve. Ligado al scroll sin secuestrarlo (scroll-driven animations;
   donde no hay soporte, simplemente no ocurre). */
@supports (animation-timeline: view()) {
  .has-motion .threshold__halo-move svg { will-change: transform; }
  .has-motion .threshold__halo-move {
    animation: haloOpen linear both;
    animation-timeline: view();
    animation-range: exit 0% exit 100%;
  }
  @keyframes haloOpen {
    to { scale: 1.6; opacity: 0; }
  }
  .has-motion .threshold__inner {
    animation: innerDissolve linear both;
    animation-timeline: view();
    animation-range: exit 0% exit 100%;
  }
  @keyframes innerDissolve {
    to { translate: 0 -6vh; opacity: 0; }
  }
}

/* ═══ 02 — IDENTIDAD ════════════════════════════════════════════════ */
.identity {
  padding: clamp(5rem, 16vw, 10rem) 1.5rem;
  display: flex;
  justify-content: center;
}
.identity__text {
  max-width: 21ch;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.75rem, 5.6vw, 3.25rem);
  line-height: 1.18;
  letter-spacing: -0.01em;
  color: var(--cream);
}
.identity__text > span { display: block; }
.identity__text em { font-style: italic; color: var(--gold); }
/* Con movimiento, los verbos llegan en crema y se doran después. */
.has-motion .page-portal .identity__text em { color: var(--cream); }
.has-motion .page-portal .identity__text .is-in em { color: var(--gold); }
@media (min-width: 900px) {
  .identity { justify-content: flex-start; padding-left: max(1.5rem, calc((100vw - 1120px) / 2 + 2.5rem)); }
}

/* ═══ 03 — PORTALES ═════════════════════════════════════════════════ */
.doors-section {
  padding: 0 1.25rem clamp(4rem, 12vw, 7rem);
  max-width: 1120px;
  margin-inline: auto;
}
@media (min-width: 768px) { .doors-section { padding-inline: 2.5rem; } }

.doors { display: grid; }

/* Mobile-first: fila editorial — arco pequeño con su glifo, verbo grande,
   destino en mono, frase. Separadas por una línea, nunca por cajas. */
.door {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 1.25rem;
  padding: 1.75rem 0.25rem;
  border-top: 1px solid var(--rule);
  color: inherit;
  text-decoration: none;
  isolation: isolate;
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
  transition:
    transform 700ms var(--ease-reveal),
    border-color 700ms var(--ease-reveal);
}
.doors__item:last-child .door { border-bottom: 1px solid var(--rule); }

/* Contorno del arco grande (solo desktop) */
.door__frame { display: none; }

.door__arch {
  position: relative;
  display: grid;
  place-items: center;
  width: 3.5rem;
  height: 4.5rem;
}
.door__arch-line {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  overflow: visible;
}
/* Sin vector-effect a propósito: con non-scaling-stroke el trazo de
   pathLength deja de cerrar (el dash se mide en espacio de pantalla y el
   contorno se queda incompleto). Ambos SVG respetan la proporción de su
   caja, así que el grosor escala parejo. */
.door__arch-line path,
.door__frame path {
  stroke: var(--rule-strong);
  stroke-width: 1;
  fill: none;
  transition: stroke 700ms var(--ease-reveal);
}
/* El arco se traza al aparecer. */
.has-motion .doors__item .door__arch-line path,
.has-motion .doors__item .door__frame path {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 1;
  transition:
    stroke-dashoffset 1800ms cubic-bezier(0.65, 0, 0.35, 1) calc(var(--d, 0ms) + 250ms),
    stroke 700ms var(--ease-reveal);
}
.has-motion .doors__item.is-in .door__arch-line path,
.has-motion .doors__item.is-in .door__frame path { stroke-dashoffset: 0; }

.door__glyph { position: relative; width: 2.375rem; height: 2.375rem; overflow: visible; }
.door__glyph path,
.door__glyph circle {
  stroke: var(--gold);
  stroke-width: 1.2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  transform-box: fill-box;
  transform-origin: center;
}

.door__body { display: flex; flex-direction: column; gap: 0.3rem; min-width: 0; }
.door__verb {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: clamp(1.75rem, 7vw, 2.5rem);
  line-height: 1;
  letter-spacing: -0.01em;
  transition: letter-spacing 700ms var(--ease-reveal);
}
.door__place {
  font-family: var(--font-mono);
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
}
.door__line {
  margin-top: 0.35rem;
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1rem;
  line-height: 1.4;
  color: var(--ink-muted);
}
.door__line br { display: none; }
.door__arrow {
  font-size: 1.25rem;
  color: var(--ink-quiet);
  transition: transform 700ms var(--ease-reveal), color 700ms var(--ease-reveal);
}

/* Luz interior: el umbral se ilumina cuando responde. */
.door::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(80% 60% at 12% 50%, rgba(201, 168, 76, 0.09), transparent 70%);
  opacity: 0;
  transition: opacity 900ms var(--ease-reveal);
}

/* Estados de respuesta */
@media (hover: hover) and (pointer: fine) {
  .door:hover { border-color: var(--rule-strong); }
  .door:hover::before { opacity: 1; }
  .door:hover .door__arch-line path,
  .door:hover .door__frame path { stroke: var(--gold); }
  .door:hover .door__verb { letter-spacing: 0.01em; }
  .door:hover .door__arrow { transform: translateX(6px); color: var(--gold); }
}
.door:focus-visible { outline-offset: 6px; border-color: var(--rule-strong); }
.door:focus-visible::before { opacity: 1; }
.door:focus-visible .door__arch-line path,
.door:focus-visible .door__frame path { stroke: var(--gold); }
.door:focus-visible .door__arrow { transform: translateX(6px); color: var(--gold); }
.door:active { transform: scale(0.985); transition-duration: 120ms; }
.door.is-present::before { opacity: 0.6; }
.door.is-present .door__arch-line path,
.door.is-present .door__frame path { stroke: var(--gold); }
.door.is-present .door__arrow { color: var(--gold); }

/* ── Glifos en reposo ── */
.glyph-bubble { opacity: 0.55; }
.glyph-flask__liquid { opacity: 0.7; }
.glyph-lungs__lobe { transform-origin: 50% 12% !important; }
.glyph-root__ground { opacity: 0.45; }
.glyph-root__root { opacity: 0.8; }
.glyph-root__sprout { transform-origin: 50% 100% !important; }

.door--pulse, .door--breath, .door--flow { --glyph-on: paused; }
.door:is(:hover, :focus-visible, .is-present) { --glyph-on: running; }

/* PULSE — matraz: las burbujas suben; el matraz late una vez por ciclo. */
.has-motion .door--pulse .glyph-bubble {
  animation: bubbleRise 2.6s var(--ease-reveal) infinite;
  animation-play-state: var(--glyph-on);
}
.has-motion .door--pulse .glyph-bubble--2 { animation-delay: -0.9s; }
.has-motion .door--pulse .glyph-bubble--3 { animation-delay: -1.7s; }
@keyframes bubbleRise {
  0%   { transform: translateY(0) scale(0.6); opacity: 0; }
  25%  { opacity: 0.9; }
  100% { transform: translateY(-15px) scale(1.15); opacity: 0; }
}
.has-motion .door--pulse .glyph-flask {
  transform-box: fill-box;
  transform-origin: 50% 100%;
  animation: flaskPulse 2.6s var(--ease-breath) infinite;
  animation-play-state: var(--glyph-on);
}
@keyframes flaskPulse {
  0%, 40%, 100% { transform: scale(1); }
  20%           { transform: scale(1.06); }
}
/* En reposo las burbujas se ven, quietas. */
.has-motion .door--pulse:not(:hover, :focus-visible, .is-present) .glyph-bubble { animation: none; }

/* BREATH — pulmones: expansión / contracción lenta. */
.has-motion .door--breath .glyph-lungs__lobe {
  animation: lungsBreath var(--breath-dur) var(--ease-breath) infinite;
  animation-play-state: var(--glyph-on);
}
@keyframes lungsBreath {
  0%, 100% { transform: scale(0.9); }
  45%, 55% { transform: scale(1.06); }
}
.has-motion .door--breath .glyph-lungs__lobe--l { transform-origin: 90% 12% !important; }
.has-motion .door--breath .glyph-lungs__lobe--r { transform-origin: 10% 12% !important; }

/* FLOW — raíces que crecen hacia abajo; el brote se mece. */
.has-motion .door--flow .glyph-root__root {
  stroke-dasharray: 1 1;
  stroke-dashoffset: 0;
}
.has-motion .door--flow:is(:hover, :focus-visible, .is-present) .glyph-root__root {
  animation: rootGrow 5.5s var(--ease-breath) infinite;
}
.has-motion .door--flow:is(:hover, :focus-visible, .is-present) .glyph-root__root--2 { animation-delay: 0.35s; }
.has-motion .door--flow:is(:hover, :focus-visible, .is-present) .glyph-root__root--3 { animation-delay: 0.7s; }
.has-motion .door--flow:is(:hover, :focus-visible, .is-present) .glyph-root__root--4 { animation-delay: 1.05s; }
@keyframes rootGrow {
  0%        { stroke-dashoffset: 1; opacity: 0.8; }
  55%       { stroke-dashoffset: 0; opacity: 0.8; }
  85%       { stroke-dashoffset: 0; opacity: 0.8; }
  100%      { stroke-dashoffset: 0; opacity: 0; }
}
.has-motion .door--flow .glyph-root__sprout {
  animation: sproutSway 5.5s var(--ease-breath) infinite;
  animation-play-state: var(--glyph-on);
}
@keyframes sproutSway {
  0%, 100% { transform: rotate(-3deg); }
  50%      { transform: rotate(3deg); }
}

/* Desktop: tres arcos altos lado a lado. El descenso escalonado dibuja
   el recorrido: experimentar → respirar → profundizar. */
@media (min-width: 960px) {
  .doors {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: clamp(1.5rem, 3vw, 3rem);
    align-items: start;
  }
  .doors__item:nth-child(2) { margin-top: 3rem; }
  .doors__item:nth-child(3) { margin-top: 6rem; }

  .door,
  .doors__item:last-child .door {
    grid-template-columns: 1fr;
    grid-template-rows: auto 1fr auto;
    justify-items: center;
    text-align: center;
    gap: 1.5rem;
    aspect-ratio: 2 / 3;
    padding: 4.25rem 1.5rem 2.25rem;
    border: none;
  }
  /* El contorno es un SVG (no un border) para poder trazarlo. Mismo
     2:3 que el umbral, así el semicírculo no se deforma. */
  .door__frame path { stroke-width: 0.32; }
  .door__frame {
    display: block;
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
  }
  .door::before {
    border-radius: 999px 999px 2px 2px;
    background: radial-gradient(70% 45% at 50% 22%, rgba(201, 168, 76, 0.12), transparent 70%);
  }
  .door__arch { width: auto; height: auto; }
  .door__arch-line { display: none; }
  .door__glyph { width: 3.75rem; height: 3.75rem; }
  .door__body { align-items: center; gap: 0.5rem; }
  .door__verb { font-size: clamp(1.875rem, 2.8vw, 2.625rem); }
  .door__line br { display: inline; }
  .door__arrow { align-self: end; }

  @media (hover: hover) and (pointer: fine) {
    .door:hover { transform: scale(1.02); }
    .door:hover .door__arrow { transform: translateY(4px); }
  }
  .door:focus-visible .door__arrow { transform: translateY(4px); }
  .door:active { transform: scale(0.99); }
}

/* Estado "abriéndose" (antes de navegar) */
.door.is-opening { transform: scale(var(--pulse-scale)); transition-duration: 380ms; }
.door.is-opening::before { opacity: 1; }
.door.is-opening .door__frame path,
.door.is-opening .door__arch-line path { stroke: var(--gold); }
.door.is-opening .door__arrow { color: var(--gold); }

/* ── Próxima experiencia en vivo (Time Check, subordinado) ── */
.next-session {
  margin-top: clamp(2.5rem, 6vw, 4rem);
  display: flex;
  justify-content: center;
}
.page-portal .next-session .time-check {
  margin-top: 0;
  min-height: 0;
  max-width: 36rem;
  text-align: center;
  color: var(--ink-muted);
}
.page-portal .next-session .time-check:empty { display: none; }
.page-portal .next-session .time-check__label-row { display: none; }
.page-portal .next-session .time-check__question {
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 0.6875rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--gold);
  margin-bottom: 0.625rem;
}
.page-portal .next-session .time-check__session {
  font-family: var(--font-display);
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--cream);
  opacity: 1;
  margin-bottom: 0.75rem;
}
.page-portal .next-session .pill {
  font-size: 0.6875rem;
  border-color: var(--rule);
  background-color: transparent;
}
.page-portal .next-session .time-check__cta { font-size: 0.8125rem; color: var(--ink-muted); padding-block: 0.75rem; margin-top: 0.25rem; }
@media (hover: hover) and (pointer: fine) {
  .page-portal .next-session .time-check__cta:hover { color: var(--gold); opacity: 1; }
}

/* ═══ 04 — COMUNIDAD (puerta secundaria) ════════════════════════════ */
.community {
  padding: clamp(3.5rem, 10vw, 6rem) 1.5rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 1.25rem;
  border-top: 1px solid rgba(107, 98, 89, 0.35);
  max-width: 1120px;
  margin-inline: auto;
}
.community__q {
  font-family: var(--font-display);
  font-size: clamp(1.125rem, 3.2vw, 1.375rem);
  color: var(--ink-muted);
}
.community__cta {
  display: inline-flex;
  align-items: center;
  gap: 0.625rem;
  min-height: 44px;
  padding: 0.75rem 1.5rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  text-decoration: none;
  color: var(--cream);
  border: 1px solid var(--rule-strong);
  border-radius: 999px;
  touch-action: manipulation;
  transition: border-color 500ms var(--ease-reveal), color 500ms var(--ease-reveal), background-color 500ms var(--ease-reveal);
}
.community__icon { width: 1.125rem; height: 1.125rem; flex-shrink: 0; }
.community__icon path { stroke: var(--gold); stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round; }
.community__icon-dots { stroke-width: 2 !important; }
@media (hover: hover) and (pointer: fine) {
  .community__cta:hover { border-color: var(--gold); color: var(--gold); }
}
.community__cta:active { background-color: rgba(201, 168, 76, 0.1); transition-duration: 100ms; }
.community__note { font-size: 0.8125rem; color: var(--ink-quiet); }

/* PULSE sutil: dos latidos al aparecer, y quieto después. */
.has-motion .community__cta.is-in {
  animation: communityPulse 1.6s var(--ease-breath) calc(var(--reveal-dur) + 200ms) 2;
}
@keyframes communityPulse {
  0%, 100% { scale: 1; }
  50%      { scale: var(--pulse-scale); }
}
/* Los tres puntos de la conversación, escribiendo — solo con hover/focus. */
.has-motion .community__cta:is(:hover, :focus-visible) .community__icon-dots {
  animation: typingDots 1.4s var(--ease-breath) infinite;
}
@keyframes typingDots {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.25; }
}

/* ═══ 05 — CIERRE ═══════════════════════════════════════════════════ */
.closing {
  padding: clamp(5rem, 16vw, 10rem) 1.5rem 2.5rem;
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
}
/* Eco del halo del umbral: se recupera el principio. */
.closing__orb {
  width: 5rem;
  height: 5rem;
  margin-bottom: clamp(2rem, 6vw, 3rem);
}
.closing__orb svg { width: 100%; height: 100%; overflow: visible; }
.closing__orb circle { stroke: var(--gold); stroke-width: 1; vector-effect: non-scaling-stroke; transform-box: fill-box; transform-origin: center; }
.closing__orb circle:nth-child(1) { opacity: 0.25; }
.closing__orb circle:nth-child(2) { opacity: 0.45; }
.closing__orb-core { fill: var(--gold); stroke: none !important; }
.has-motion .closing__orb circle:nth-child(1) { animation: orbBreath var(--breath-dur) var(--ease-breath) infinite; }
.has-motion .closing__orb circle:nth-child(2) { animation: orbBreath var(--breath-dur) var(--ease-breath) -0.5s infinite; }
@keyframes orbBreath {
  0%, 100% { transform: scale(0.82); opacity: 0.2; }
  50%      { transform: scale(1); opacity: 0.55; }
}

.closing__statement {
  display: flex;
  flex-direction: column;
  font-family: var(--font-display);
  font-style: italic;
  font-size: clamp(1.75rem, 6vw, 3rem);
  line-height: 1.15;
}
.closing__statement span:first-child { color: var(--ink-muted); }
.closing__begin {
  margin-top: 1.75rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--gold);
}
.closing__links {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.5rem 1.75rem;
  margin-top: clamp(5rem, 14vw, 8rem);
  font-size: 0.8125rem;
}
.closing__links a {
  display: inline-block;
  padding: 0.5rem 0.25rem;
  color: var(--ink-muted);
  text-underline-offset: 4px;
  text-decoration-color: var(--rule-strong);
  transition: color 300ms var(--ease-reveal);
}
.closing__links .closing__facilitador { color: var(--ink-quiet); }
@media (hover: hover) and (pointer: fine) {
  .closing__links a:hover { color: var(--gold); }
}
.closing__mark {
  margin-top: 1.5rem;
  font-family: var(--font-mono);
  font-size: 0.625rem;
  letter-spacing: 0.22em;
  color: var(--ink-quiet);
}

/* ═══ VELO DE TRANSICIÓN (HUB → destino) ════════════════════════════
   Círculo que se expande desde el umbral elegido (clip-path) con el
   glifo del umbral creciendo dentro (MORPH). La duración la fija el JS
   por personalidad (PULSE < BREATH < FLOW). */
.portal-veil {
  position: fixed;
  inset: 0;
  z-index: 300;
  pointer-events: none;
  background-color: var(--dark);
  visibility: hidden;
  clip-path: circle(0 at var(--vx, 50%) var(--vy, 50%));
}
.portal-veil__glyph {
  position: absolute;
  left: var(--vx, 50%);
  top: var(--vy, 50%);
  width: 3.75rem;
  height: 3.75rem;
  translate: -50% -50%;
  scale: 0.8;
  opacity: 0;
}
.portal-veil__glyph svg { width: 100%; height: 100%; overflow: visible; }
.portal-veil__glyph path,
.portal-veil__glyph circle { stroke: var(--gold); stroke-width: 1.2; stroke-linecap: round; stroke-linejoin: round; vector-effect: non-scaling-stroke; fill: none; }
.portal-veil.is-open {
  visibility: visible;
  clip-path: circle(150vmax at var(--vx, 50%) var(--vy, 50%));
  transition: clip-path var(--veil-ms, 500ms) cubic-bezier(0.65, 0, 0.35, 1);
}
.portal-veil.is-open .portal-veil__glyph {
  scale: 1.7;
  opacity: 1;
  transition: scale var(--veil-ms, 500ms) var(--ease-reveal), opacity calc(var(--veil-ms, 500ms) * 0.6) ease-out;
}
.portal-veil[data-portal="flow"].is-open { transition-timing-function: cubic-bezier(0.37, 0, 0.23, 1); }

/* ═══ REDUCED MOTION ═══════════════════════════════════════════════
   has-motion no se aplica con esta preferencia; esto cubre el caso de
   que se active con la página abierta. */
@media (prefers-reduced-motion: reduce) {
  .page-portal .pr, .page-portal .pr-words .w { opacity: 1 !important; transform: none !important; filter: none !important; }
  .page-portal *, .page-portal *::before, .page-portal *::after { animation: none !important; }
  .door__arch-line path, .door__frame path { stroke-dashoffset: 0 !important; }
  .door, .door:hover { transform: none !important; }
  .portal-veil { display: none; }
}
