/* ============================================================
   APEX — Auth gate + landing pública (hero, secciones, responsive)
   Extraído de index.html sin cambios de estilo. El ORDEN de
   carga de las hojas (ver <link> en index.html) es significativo:
   las reglas posteriores refinan a las anteriores.
   ============================================================ */

/* ---- Campaña APEX MAX: banda compacta, separada del hero ---- */
.campaign-banner{padding:18px clamp(18px,4vw,56px) 0;}
.campaign-banner-inner,.campaign-banner-ended{
  width:min(1180px,100%);margin:0 auto;border:1px solid color-mix(in srgb,var(--blue) 34%,var(--border-soft));
  border-radius:var(--r-lg);background:linear-gradient(110deg,color-mix(in srgb,var(--blue-soft) 55%,var(--surface)),var(--surface));
  box-shadow:0 18px 45px -30px color-mix(in srgb,var(--blue) 45%,transparent);padding:clamp(22px,3.5vw,34px) clamp(22px,4vw,48px);
}
.campaign-banner-inner{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:clamp(26px,6vw,90px);align-items:center;}
.campaign-banner-copy{max-width:710px;}
.campaign-eyebrow{display:inline-flex;align-items:center;gap:8px;color:var(--blue);font:700 10px/1 var(--font-mono);letter-spacing:.11em;text-transform:uppercase;}
.campaign-pulse{width:7px;height:7px;border-radius:50%;background:var(--blue);box-shadow:0 0 0 4px var(--blue-soft);}
.campaign-banner h2{margin:12px 0 9px;font:650 clamp(22px,3vw,32px)/1.12 var(--font-display);letter-spacing:-.035em;color:var(--text);}
.campaign-banner p{margin:0;color:var(--muted);font-size:13.5px;line-height:1.55;max-width:650px;}
.campaign-disclaimer{margin-top:9px!important;color:var(--muted2)!important;font-size:11px!important;}
.campaign-cta{width:auto;margin-top:17px;}
.campaign-countdown{min-width:270px;border-left:1px solid var(--border-soft);padding-left:clamp(24px,4vw,52px);}
.campaign-countdown-label{display:block;color:var(--muted2);font:700 9px/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;margin-bottom:13px;}
.campaign-countdown-grid{display:grid;grid-template-columns:repeat(4,minmax(48px,1fr));gap:8px;}
.campaign-unit{text-align:center;}
.campaign-unit strong{display:block;color:var(--text);font:600 clamp(25px,3.2vw,38px)/1 var(--font-mono);letter-spacing:-.08em;font-variant-numeric:tabular-nums;}
.campaign-unit span{display:block;color:var(--muted2);font:700 8px/1 var(--font-mono);letter-spacing:.08em;margin-top:8px;}
.campaign-countdown-end{display:block;color:var(--muted2);font-size:10px;text-align:center;margin-top:16px;white-space:nowrap;}
.campaign-banner-ended{padding-block:26px;}
.campaign-banner-ended h2{margin-bottom:7px;}
.campaign-banner-ended p{max-width:680px;}
@media(max-width:720px){
  .campaign-banner{padding-top:12px;}
  .campaign-banner-inner{grid-template-columns:1fr;gap:23px;}
  .campaign-countdown{border-left:0;border-top:1px solid var(--border-soft);padding:20px 0 0;min-width:0;}
  .campaign-countdown-label{text-align:center;}
  .campaign-countdown-grid{max-width:380px;margin:0 auto;}
  .campaign-countdown-end{white-space:normal;}
  .campaign-cta{width:100%;}
}
@media(max-width:400px){
  .campaign-banner-inner,.campaign-banner-ended{padding-inline:18px;}
  .campaign-unit strong{font-size:22px;}
  .campaign-unit span{font-size:7px;}
}
@media(prefers-reduced-motion:reduce){.campaign-pulse{box-shadow:0 0 0 3px var(--blue-soft);}}

/* ============================================================
   RESEÑAS — social proof real, carrusel y composer guiado
   ============================================================ */
.reviews-public-section{border-top:1px solid var(--border-soft);}
.reviews-public-feedback,.review-loading{display:flex;align-items:center;justify-content:center;gap:10px;max-width:560px;margin:0 auto;padding:32px 22px;border:1px solid var(--border-soft);border-radius:var(--r-lg);background:var(--surface);color:var(--muted);font-size:13px;line-height:1.5;text-align:center;}
.reviews-public-feedback[hidden],.review-loading[hidden],.reviews-public-carousel[hidden]{display:none;}
.reviews-public-feedback.is-error{flex-direction:column;border-color:var(--red-soft-border);color:var(--red);}
.reviews-public-feedback strong,.review-loading strong{color:var(--text);font-size:14px;}
.reviews-public-feedback .btn{width:auto;margin-top:4px;}
.review-loading-dot{width:9px;height:9px;flex:0 0 9px;border-radius:50%;background:var(--blue);box-shadow:0 0 0 5px var(--blue-soft);}
.reviews-public-carousel{overflow:hidden;max-width:1180px;margin:0 auto;padding:4px 2px 12px;touch-action:pan-y;}
.reviews-public-track{display:flex;gap:var(--space-5);transition:transform .55s var(--ease);will-change:transform;}
.review-card{box-sizing:border-box;flex:0 0 calc((100% - 48px)/3);min-width:0;padding:24px;border:1px solid var(--border-soft);border-radius:var(--r-lg);background:var(--surface);box-shadow:var(--shadow-sm);}
.review-card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;}
.review-card-person{display:flex;align-items:center;gap:11px;min-width:0;}
.review-card-person strong{display:block;overflow:hidden;color:var(--text);font-size:13px;text-overflow:ellipsis;white-space:nowrap;}
.review-card-sub{margin-top:4px;color:var(--muted2);font-size:11px;}
.review-card-top-right{display:flex;align-items:center;gap:7px;}
.review-avatar{display:grid;place-items:center;width:38px;height:38px;flex:0 0 38px;border-radius:50%;object-fit:cover;background:var(--blue-soft);color:var(--blue);font:700 11px/1 var(--font-mono);}
.review-featured{color:var(--amber);font-size:16px;}
.review-card-rating{margin:20px 0 0;}
.review-stars{color:var(--amber);font:700 15px/1 var(--font-mono);letter-spacing:.08em;white-space:nowrap;}
.review-no-rating{color:var(--muted2);font-size:11px;}
.review-card-text{margin:14px 0 18px;color:var(--text);font-size:15px;line-height:1.65;}
.review-card-media{display:grid;gap:10px;margin:0 0 16px;}
.review-photo,.review-video{display:block;width:100%;max-height:260px;aspect-ratio:16/10;object-fit:cover;border:0;border-radius:var(--r-md);background:#0e0b09;}
.review-video-secondary{max-height:180px;}
.review-categories{display:flex;flex-wrap:wrap;gap:5px;}
.review-category{padding:5px 8px;border-radius:var(--r-pill);background:var(--surface2);color:var(--muted);font-size:10px;}
.review-details{margin-top:14px;border-top:1px solid var(--border-soft);padding-top:10px;color:var(--muted2);font-size:11px;}.review-details summary{cursor:pointer;color:var(--blue);}.review-details div{display:flex;flex-wrap:wrap;gap:5px 14px;margin-top:8px;}.review-details span{display:block;}
.reviews-public-controls{display:flex;align-items:center;justify-content:center;gap:15px;margin-top:12px;color:var(--muted2);font:11px/1 var(--font-mono);}
.reviews-public-controls[hidden]{display:none;}
.reviews-public-controls .btn{width:34px;height:34px;padding:0;border-radius:50%;}
.reviews-public-empty,.review-empty{display:flex;flex-direction:column;align-items:center;text-align:center;gap:9px;max-width:560px;margin:0 auto;padding:36px 22px;border:1px dashed var(--border);border-radius:var(--r-lg);background:color-mix(in srgb,var(--surface) 72%,transparent);}
.reviews-public-empty[hidden]{display:none;}
.reviews-public-empty strong,.review-empty strong{color:var(--text);font-size:15px;}
.reviews-public-empty p,.review-empty span{margin:0;color:var(--muted);font-size:13px;line-height:1.55;}
.review-empty-mark{color:var(--blue);font:600 24px/1 var(--font-mono);}
.review-eyebrow{display:inline-flex;color:var(--blue);font:700 10px/1 var(--font-mono);letter-spacing:.12em;text-transform:uppercase;}
.review-modal{position:fixed;inset:0;z-index:700;display:grid;place-items:center;padding:20px;}
.review-modal[hidden]{display:none;}
.review-modal-backdrop{position:absolute;inset:0;background:rgba(20,12,8,.62);backdrop-filter:blur(7px);}
.review-modal-card{position:relative;width:min(620px,100%);max-height:min(92vh,800px);overflow:auto;padding:32px;border:1px solid var(--border);border-radius:var(--r-xl);background:var(--surface);box-shadow:var(--shadow-lg);}
.review-modal-card h2{margin:12px 36px 8px 0;color:var(--text);font:700 clamp(24px,4vw,32px)/1.12 var(--font-display);letter-spacing:-.03em;}
.review-modal-card h3{margin:0 0 18px;color:var(--text);font:700 22px/1.2 var(--font-display);letter-spacing:-.02em;}
.review-modal-card h3 small{color:var(--muted2);font:400 11px/1 var(--font-body);}
.review-modal-sub,.review-step-help{margin:0 0 25px;color:var(--muted);font-size:13px;line-height:1.55;max-width:520px;}
.review-step-help{margin-top:-9px;font-size:12px;}
.review-modal-close{position:absolute;right:20px;top:18px;width:34px;height:34px;border:1px solid var(--border-soft);border-radius:50%;background:transparent;color:var(--muted);font-size:24px;line-height:1;cursor:pointer;}
.review-wizard-head{display:flex;justify-content:space-between;margin-top:21px;color:var(--muted2);font:10px/1 var(--font-mono);text-transform:uppercase;}
.review-step[hidden]{display:none;}
.review-progress{height:5px;overflow:hidden;margin:4px 0 24px;border-radius:var(--r-pill);background:var(--surface2);}
.review-progress span{display:block;width:16.666%;height:100%;border-radius:inherit;background:var(--blue);transition:width .35s var(--ease);}
.review-emotions{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;}
.review-emotion{display:flex;flex-direction:column;align-items:center;gap:7px;padding:13px 4px;border:1px solid var(--border-soft);border-radius:var(--r-md);color:var(--muted);font-size:10px;text-align:center;cursor:pointer;transition:border-color .2s,background .2s,transform .2s;}
.review-emotion:hover{transform:translateY(-2px);}
.review-emotion:has(input:checked){border-color:var(--blue);background:var(--blue-soft);color:var(--blue);}
.review-emotion input,.review-choice input{position:absolute;opacity:0;pointer-events:none;}
.review-emotion-face{font-size:28px;line-height:1;}
.review-category-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:8px;}
.review-choice{display:flex;align-items:center;min-height:43px;padding:0 12px;border:1px solid var(--border-soft);border-radius:var(--r-sm);color:var(--muted);font-size:12px;cursor:pointer;}
.review-choice:has(input:checked){border-color:var(--blue);background:var(--blue-soft);color:var(--blue);}
.review-field{display:block;margin:0;}
.review-field textarea{box-sizing:border-box;width:100%;min-height:150px;resize:vertical;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--bg);color:var(--text);font:inherit;font-size:14px;line-height:1.6;padding:13px;outline:none;}
.review-field textarea:focus{border-color:var(--blue);box-shadow:var(--shadow-focus);}
.review-counter{display:flex;justify-content:space-between;margin-top:8px;color:var(--muted2);font-size:11px;}
.review-upload{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;min-height:125px;border:1px dashed var(--border);border-radius:var(--r-md);background:var(--surface2);color:var(--blue);font-size:13px;text-align:center;cursor:pointer;}
.review-upload input{position:absolute;width:1px;height:1px;opacity:0;}
.review-upload small{color:var(--muted2);font-size:11px;}
.review-media-preview{display:flex;align-items:center;gap:10px;margin-top:12px;}
.review-media-preview img{width:100px;height:72px;object-fit:cover;border-radius:var(--r-sm);}
.review-video-preview{margin-top:12px;max-height:220px;}
.review-identity-card{display:flex;align-items:center;gap:11px;padding:14px;border:1px solid var(--border-soft);border-radius:var(--r-md);background:var(--surface2);}
.review-identity-card strong,.review-identity-card span{display:block;}
.review-identity-card strong{color:var(--text);font-size:13px;}.review-identity-card span,.review-identity-note{margin-top:5px;color:var(--muted2);font-size:11px;line-height:1.45;}.review-identity-note{margin-bottom:20px;}
.review-consent{display:flex;align-items:flex-start;gap:10px;padding:13px;border:1px solid var(--border);border-radius:var(--r-md);color:var(--muted);font-size:11px;line-height:1.5;cursor:pointer;}.review-consent input{position:relative;flex:0 0 22px;width:22px;height:22px;margin:0;appearance:none;border:1px solid var(--muted2);border-radius:6px;background:var(--bg);opacity:1;pointer-events:auto;cursor:pointer;}.review-consent input:checked{border-color:var(--blue);background:var(--blue);}.review-consent input:checked::after{content:'✓';display:block;color:#fff;font:700 16px/20px var(--font-body);text-align:center;}.review-consent input:focus-visible{outline:none;box-shadow:0 0 0 3px var(--blue-soft-border);}.review-consent:has(input:checked){border-color:var(--blue);background:var(--blue-soft);}
.review-form-status{min-height:20px;margin:18px 0 8px;color:var(--muted);font-size:12px;line-height:1.45;}.review-form-status.is-error{color:var(--red);}
.review-other-field{display:block;grid-column:1/-1;margin-top:4px;padding:13px;border:1px solid var(--blue-soft-border);border-radius:var(--r-md);background:var(--blue-soft);color:var(--text);font-size:12px;}.review-other-field[hidden],.review-wizard-actions button[hidden]{display:none!important;}.review-other-field>span,.review-other-field small{display:block;}.review-other-field>span{margin-bottom:8px;font-weight:650;}.review-other-field textarea{box-sizing:border-box;width:100%;min-height:78px;resize:vertical;padding:10px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--bg);color:var(--text);font:inherit;font-size:13px;line-height:1.5;}.review-other-field textarea:focus{outline:none;border-color:var(--blue);box-shadow:var(--shadow-focus);}.review-other-field small{margin-top:7px;color:var(--muted2);font-size:11px;}.review-wizard-actions{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;}.review-wizard-actions.is-single-action{grid-template-columns:minmax(0,1fr);}.review-wizard-actions button{width:100%;min-width:0!important;margin:0;}.review-wizard-actions button:disabled{opacity:.55;cursor:wait;}
.review-rating-stars{display:flex;justify-content:center;gap:8px;}.review-rating-stars .review-emotion{display:grid;place-items:center;width:58px;height:58px;padding:0;border:0;background:transparent;color:var(--muted2);font-size:0;transform:none;}.review-rating-stars .review-emotion:hover{color:var(--amber);transform:scale(1.08);}.review-rating-stars .review-emotion-face{display:block!important;font-size:42px;line-height:1;transition:color .18s var(--ease),transform .18s var(--ease);}.review-rating-stars .review-emotion.is-active{color:var(--amber);}.review-rating-stars .review-emotion.is-selected .review-emotion-face{transform:scale(1.12);filter:drop-shadow(0 4px 9px rgba(238,178,67,.26));}.review-rating-stars .review-emotion:has(input:checked){border:0;background:transparent;color:var(--amber);}
.review-success{text-align:center;padding:35px 12px 15px;}.review-success-mark{display:grid;place-items:center;width:48px;height:48px;margin:0 auto 18px;border-radius:50%;background:var(--green-soft);color:var(--green);font-size:25px;}.review-success h2{margin:12px 0;color:var(--text);}.review-success p{color:var(--muted);font-size:13px;line-height:1.55;}.review-reward,.review-reward-account{display:flex;align-items:center;gap:13px;padding:15px;text-align:left;border:1px solid var(--blue-soft-border);border-radius:var(--r-md);background:var(--blue-soft);}.review-reward-icon{font-size:24px;}.review-reward strong,.review-reward span,.review-reward-account strong,.review-reward-account span{display:block;}.review-reward strong,.review-reward-account strong{color:var(--text);font-size:13px;}.review-reward span,.review-reward-account span{margin-top:4px;color:var(--muted);font-size:11px;}.review-reward .btn{display:inline-block;margin-top:12px;}.review-reward-account{margin:0 0 22px;}.review-reward-account>div{flex:1;}.review-reward-account .btn{white-space:nowrap;}
.review-app-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;margin-bottom:28px;}.review-app-head .btn{width:auto;min-width:220px;margin:0;}.review-app-list{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--space-5);}.review-error{border-color:var(--red-soft-border);}
.review-status{padding:4px 8px;border-radius:var(--r-pill);font:700 9px/1 var(--font-mono);letter-spacing:.07em;white-space:nowrap;}.review-status-pending{background:var(--amber-soft);color:var(--amber);}.review-status-approved{background:var(--green-soft);color:var(--green);}.review-status-rejected,.review-status-hidden,.review-status-archived{background:var(--red-soft);color:var(--red);}
.review-admin-panel{margin:0 0 22px;padding:18px;border:1px solid var(--blue-soft-border);border-radius:var(--r-lg);background:linear-gradient(135deg,var(--blue-soft),transparent 72%);}.review-admin-panel-head{display:flex;align-items:flex-start;justify-content:space-between;gap:14px;margin-bottom:16px;}.review-admin-panel-head strong,.review-admin-panel-head span{display:block;}.review-admin-panel-head strong{color:var(--text);font-size:15px;}.review-admin-panel-head span{margin-top:4px;color:var(--muted);font-size:12px;}.review-admin-badge{flex:0 0 auto;padding:6px 9px;border-radius:var(--r-pill);background:var(--surface);color:var(--blue);font:700 10px/1 var(--font-mono);letter-spacing:.08em;}.review-admin-summary{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;}.review-admin-metric{padding:12px;border:1px solid var(--border-soft);border-radius:var(--r-md);background:var(--surface);}.review-admin-metric strong,.review-admin-metric span{display:block;}.review-admin-metric strong{color:var(--text);font:700 22px/1 var(--font-display);}.review-admin-metric span{margin-top:5px;color:var(--muted2);font-size:10px;}.review-admin-filters{display:grid;grid-template-columns:1.5fr .8fr .8fr;gap:8px;margin:0 0 18px;}.review-admin-filters input,.review-admin-filters select{box-sizing:border-box;width:100%;padding:10px 11px;border:1px solid var(--border);border-radius:var(--r-sm);background:var(--bg);color:var(--text);font:inherit;font-size:12px;}.review-admin-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:20px;padding-top:16px;border-top:1px solid var(--border-soft);}.review-admin-actions .btn{width:auto;margin:0;font-size:11px;padding:8px 11px;}
@media(max-width:980px){.review-card{flex-basis:calc((100% - 24px)/2);}.review-app-list{grid-template-columns:1fr;}}
@media(max-width:640px){.reviews-public-track{gap:12px;}.review-card{flex-basis:100%;padding:20px;}.review-app-head{align-items:flex-start;flex-direction:column;}.review-app-head .btn{width:100%;}.review-admin-summary{grid-template-columns:repeat(2,minmax(0,1fr));}.review-admin-panel-head{flex-direction:column;}.review-admin-filters{grid-template-columns:1fr;}.review-modal{padding:0;align-items:end;}.review-modal-card{max-height:94vh;padding:25px 20px;border-radius:var(--r-xl) var(--r-xl) 0 0;}.review-category-grid{grid-template-columns:1fr;}.review-emotions{gap:4px;}.review-emotion{padding:11px 2px;font-size:9px;}.review-rating-stars{gap:1px;}.review-rating-stars .review-emotion{width:49px;height:52px;}.review-rating-stars .review-emotion-face{font-size:35px;}.review-wizard-actions{justify-content:stretch;}.review-wizard-actions button{flex:1;}}
@media(prefers-reduced-motion:reduce){.reviews-public-track,.review-progress span{transition:none;}.review-emotion:hover{transform:none;}}

/* ============================================================
   AUTH GATE — splash mínimo mostrado mientras se resuelve el
   estado de sesión (evita parpadeo entre landing/app). Usa los
   mismos tokens de color/spin que el resto del sistema.
   ============================================================ */
.auth-gate{
  position:fixed;inset:0;z-index:500;display:flex;align-items:center;justify-content:center;
  background:var(--bg);opacity:1;visibility:visible;
  transition:opacity var(--dur-med) var(--ease-out),visibility 0s linear var(--dur-med);
}
.auth-gate.is-hidden{opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--dur-med) var(--ease-out);}
.auth-gate .spin{
  width:26px;height:26px;border-radius:50%;
  border:2.5px solid var(--border);border-top-color:var(--blue);
  animation:spin .7s linear infinite;
}

/* ============================================================
   LANDING — página de presentación previa al login. Reutiliza
   íntegramente el sistema visual existente (colores, radios,
   sombras, tipografías, botones) sin introducir tokens nuevos,
   salvo las variables de "glow" que sólo se usan aquí.
   ============================================================ */
#landingView{display:none;overflow-x:clip;}
#landingView.is-active{display:block;}

/* ---- Arranque rápido para visitantes anónimos (ver theme-boot.js) ----
   Con <html data-boot="anon"> la landing y su hero se pintan sin esperar
   a que cargue la capa de autenticación: es lo que ve alguien que llega
   desde una búsqueda, y lo que mide el LCP. El hero reproduce su misma
   entrada con una animación CSS (mismo recorrido y misma duración que el
   scroll-reveal por JS) que termina exactamente en el estado que después
   fija .is-visible, así que no hay salto cuando el JS toma el control.
   El router retira la marca en cuanto decide la vista definitiva. */
html[data-boot="anon"] .auth-gate{opacity:0;visibility:hidden;pointer-events:none;transition:none;}
html[data-boot="anon"] #landingView{display:block;}
/* El selector apunta a .lp-hero (el hero del rediseño, ver
   landing-v2.css). Antes nombraba .landing-hero, y cuando ese bloque
   dejó de existir la primera pantalla se quedaba en opacity:0 hasta
   que el JS montaba el scroll-reveal — justo el retraso de LCP que
   este arranque rápido existe para evitar. */
html[data-boot="anon"] #landingView .lp-hero .reveal{animation:revealIn .7s var(--ease-out) both;}
html[data-boot="anon"] #landingView .lp-hero .reveal.reveal-delay-1{animation-delay:.08s;}
html[data-boot="anon"] #landingView .lp-hero .reveal.reveal-delay-2{animation-delay:.16s;}
html[data-boot="anon"] #landingView .lp-hero .reveal.reveal-delay-3{animation-delay:.24s;}
@keyframes revealIn{from{opacity:0;transform:translateY(22px);}to{opacity:1;transform:translateY(0);}}

html[data-theme="dark"]{
  --glow-blue:rgba(226,56,79,.35);
  --glow-red:rgba(226,73,90,.28);
  --grid-line:rgba(245,239,230,.05);
}
:root{
  --glow-blue:rgba(200,16,46,.16);
  --glow-red:rgba(155,15,33,.12);
  --grid-line:rgba(41,20,10,.05);
}

/* ---- Utilidad de aparición al hacer scroll (con fallback si no hay JS) ----
   #landingView tiene prioridad de especificidad sobre la regla genérica
   de .reveal (arriba, con animation:revealUp) para que estos elementos
   no se auto-revelen al cargar y respeten el scroll-reveal via JS
   (is-visible) en cualquier tamaño de pantalla, no solo en móvil. */
#landingView .reveal{opacity:0;transform:translateY(22px);transition:opacity .7s var(--ease-out),transform .7s var(--ease-out);animation:none;}
#landingView .reveal.is-visible{opacity:1;transform:translateY(0);}
.reveal-delay-1{transition-delay:.08s;}
.reveal-delay-2{transition-delay:.16s;}
.reveal-delay-3{transition-delay:.24s;}
.reveal-delay-4{transition-delay:.32s;}

@keyframes floaty{0%,100%{transform:translateY(0) rotate(var(--fr,0deg));}50%{transform:translateY(-10px) rotate(var(--fr,0deg));}}
@keyframes glowPulse{0%,100%{opacity:.55;}50%{opacity:1;}}
@keyframes dashBreathe{0%,100%{transform:scale(1);}50%{transform:scale(1.008);}}
@keyframes tickerFade{0%{opacity:0;transform:translateY(4px);}12%{opacity:1;transform:translateY(0);}88%{opacity:1;transform:translateY(0);}100%{opacity:0;transform:translateY(-4px);}}
@keyframes scanline{0%{transform:translateY(-100%);}100%{transform:translateY(420%);}}

/* ---- Topbar ---- */
.landing-topbar{
  position:sticky;top:12px;z-index:40;padding:0 clamp(14px,3vw,36px);margin:0 auto;
}
.landing-topbar-inner{
  width:min(1320px,100%);min-height:68px;margin:0 auto;padding:10px clamp(16px,2.6vw,30px);
  display:flex;align-items:center;justify-content:space-between;gap:clamp(16px,2.8vw,42px);
  background:color-mix(in srgb,var(--navblur-bg) 88%,transparent);
  backdrop-filter:blur(22px) saturate(180%);-webkit-backdrop-filter:blur(22px) saturate(180%);
  border:1px solid color-mix(in srgb,var(--border-soft) 86%,transparent);border-radius:18px;
  box-shadow:0 10px 26px rgba(0,0,0,.06);
  transition:min-height var(--dur-med) var(--ease-out),padding var(--dur-med) var(--ease-out),background var(--dur-med) var(--ease-out),box-shadow var(--dur-med) var(--ease-out),border-color var(--dur-med) var(--ease-out);
}
.landing-topbar .brand{display:flex;align-items:center;gap:10px;}
.landing-topbar .landing-brand{color:var(--text);text-decoration:none;flex-shrink:0;}
.landing-topbar .landing-brand:focus-visible{outline:2px solid var(--blue);outline-offset:5px;border-radius:6px;}
.landing-topbar .brand .mark{width:30px;height:30px;flex-shrink:0;display:flex;align-items:center;justify-content:center;}
.landing-topbar .brand .mark img{width:100%;height:100%;object-fit:contain;display:block;filter:drop-shadow(0 3px 8px rgba(200,16,46,.22));}
/* Identidad minimalista, igual que .sidebar .brand en la app
   autenticada: solo imagotipo + "APEX", sin tagline. */
.landing-topbar .brand .name{display:block;font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:-0.01em;}
.landing-topbar-links{display:flex;align-items:center;gap:var(--space-6);list-style:none;margin:0;padding:0;}
.landing-topbar-links a{font-size:var(--text-body-sm-size);font-weight:560;color:var(--muted);text-decoration:none;transition:color var(--dur-fast) var(--ease-out);}
.landing-topbar-links a:hover{color:var(--text);}
.landing-topbar-right{display:flex;align-items:center;gap:var(--space-4);}
/* Los dos botones de la topbar comparten base y comparten los recortes
   responsive de más abajo — tienen que declararse en la misma hoja o el
   orden de carga rompe la pareja (ver nota en auth.css).

   El selector lleva `.btn` a propósito: "Iniciar sesión" es
   `.btn.secondary`, cuya regla en components.css tiene dos clases de
   especificidad y ganaba a un `.landing-login-btn` suelto. Por eso el
   botón de login se quedaba clavado en el tamaño de escritorio (13,5px
   / 44px de alto) mientras "Crear cuenta" sí encogía en móvil: la
   pareja nunca coincidía en tamaño ni en línea base. Con `.btn` delante
   se empata en especificidad y gana esta hoja, que se carga después. */
.btn.landing-login-btn,.btn.landing-signup-btn{width:auto;margin-top:0;padding:10px 20px;font-size:var(--text-body-sm-size);}
/* "Crear cuenta" es un .btn sin borde y "Iniciar sesión" un
   .btn.secondary con borde de 1px: a igual padding el primero quedaba
   2px más bajo que el segundo y la pareja se veía desnivelada. Un borde
   transparente iguala las cajas sin cambiar el aspecto. */
.btn.landing-signup-btn{border:1px solid transparent;}
/* La topbar gana borde/sombra propios al hacer scroll (ver initLandingTopbarScroll
   en landing.js): en reposo se apoya solo en el desenfoque para no competir
   con el hero; en cuanto el visitante baja, se separa del contenido como
   cualquier header sticky premium (Linear, Vercel). */
.landing-topbar.is-scrolled .landing-topbar-inner{
  min-height:58px;padding-block:7px;background:color-mix(in srgb,var(--navblur-bg) 96%,var(--surface));
  border-color:var(--border);box-shadow:0 16px 38px rgba(0,0,0,.18),0 1px 0 color-mix(in srgb,var(--text) 5%,transparent);
}
@media(max-width:860px){.landing-topbar-links,.landing-topbar-links-wrap{display:none;}}

/* ---- Botón de menú móvil (hamburguesa) ----
   Solo existe visualmente <860px, el mismo punto de corte en el que
   .landing-topbar-links desaparece: sin esto, un visitante en móvil no
   tenía NINGUNA forma de saltar a una sección desde la cabecera. */
.landing-menu-btn{
  display:none;width:44px;height:44px;border-radius:var(--r-sm);border:1px solid var(--border);
  background:var(--surface);flex-direction:column;align-items:center;justify-content:center;gap:4px;
  flex-shrink:0;cursor:pointer;padding:0;
}
.landing-menu-btn span{width:16px;height:1.5px;border-radius:1px;background:var(--text);transition:transform var(--dur-fast) var(--ease-out),opacity var(--dur-fast) var(--ease-out);}
.landing-menu-btn[aria-expanded="true"] span:nth-child(1){transform:translateY(5.5px) rotate(45deg);}
.landing-menu-btn[aria-expanded="true"] span:nth-child(2){opacity:0;}
.landing-menu-btn[aria-expanded="true"] span:nth-child(3){transform:translateY(-5.5px) rotate(-45deg);}
@media(max-width:860px){
  .landing-menu-btn{display:flex;}
  /* "Iniciar sesión" se repite dentro de #landingMobileMenu (ver
     landing-mobile-menu más abajo): con la hamburguesa ya cubriendo login
     + navegación, mantenerlo también suelto en la topbar apretaba tres
     elementos en una fila que antes solo tenía dos. */
  .btn.landing-login-btn{display:none;}
}

/* ---- Panel del menú móvil ----
   Drawer lateral de pantalla completa (mismo lenguaje que el sidebar de
   una app — Claude, ChatGPT — en vez del acordeón plano de la primera
   versión): cabecera con marca, cuerpo con secciones agrupadas y pie con
   apariencia + legales. position:fixed a la derecha, independiente de la
   topbar, para poder ocupar el alto completo de la pantalla. */
.landing-mobile-menu{
  /* Por ENCIMA de la topbar (z-index:40): sin esto, el propio botón de
     hamburguesa (que sigue en su sitio, ahora como "X") queda apilado
     sobre el botón de cerrar del panel y le roba el click — se detectó
     abriendo/cerrando el menú por script, no a simple vista. */
  position:fixed;top:0;right:0;bottom:0;z-index:42;width:min(340px,86vw);
  background:var(--surface);border-left:1px solid var(--border);box-shadow:var(--shadow-lg);
  flex-direction:column;
  transform:translateX(100%);
  /* visibility (no display) es lo que oculta de verdad el panel cerrado:
     base.css trae una regla global `[aria-hidden="true"]{display:none
     !important}` para el resto del sitio, y este elemento SÍ lleva ese
     atributo (accesibilidad correcta: un lector de pantalla no debe ver
     el contenido mientras está cerrado). El problema es que esa regla
     fuerza display:none Y el JS quita aria-hidden en el MISMO tick en
     que añade .is-open — sin un fotograma "de por medio" con el panel ya
     visible antes de mover el transform, no hay nada de lo que partir y
     el navegador salta directo al estado final: exactamente el motivo
     por el que el panel "aparecía de la nada" en vez de deslizarse. La
     regla de abajo (`[aria-hidden]{display:flex!important}`) neutraliza
     ese short-circuit solo para este panel; `visibility` retrasado hace
     el trabajo de "cerrado = inaccesible/sin foco" que hacía display:none. */
  display:flex;visibility:hidden;
  /* Cerrar es más corto y con una curva de entrada (ease-in): se lee
     como "se retira", rápido y sin protagonismo. Abrir usa una curva
     más larga y de salida (--ease-out, la misma "expo out" del resto
     de APEX) para que el gesto se perciba como un deslizamiento con
     peso, no un salto — la duración única de antes (250ms, la misma
     para entrar y salir, y de hecho nunca visible por el bug de arriba)
     era parte de por qué se sentía aparecer de la nada. */
  transition:transform .22s cubic-bezier(.32,0,.67,0),visibility 0s linear .22s;
  overflow-y:auto;-webkit-overflow-scrolling:touch;
}
.landing-mobile-menu.is-open{
  transform:translateX(0);visibility:visible;
  transition:transform .38s var(--ease-out),visibility 0s linear 0s;
}
/* Neutraliza SOLO para este panel la regla global de base.css
   `[aria-hidden="true"]{display:none!important}` (ver el porqué en el
   comentario de arriba): (0,2,0) + !important le gana a (0,1,0) +
   !important de esa regla por especificidad, sin tocar la regla global
   ni el resto de elementos aria-hidden del sitio. */
.landing-mobile-menu[aria-hidden]{display:flex !important;}

/* Entrada escalonada del contenido: cada fila aparece un poco después
   de la anterior mientras el panel todavía se está deslizando, en vez
   de que todo el contenido esté ya ahí en cuanto el borde del panel
   asoma. Nunca se anima AL CERRAR (solo se define para is-open) para
   no alargar la salida — cerrar debe sentirse inmediato. */
.landing-mobile-menu .lmm-stagger{opacity:0;transform:translateY(8px);transition:opacity .32s var(--ease-out),transform .32s var(--ease-out);}
.landing-mobile-menu.is-open .lmm-stagger{opacity:1;transform:translateY(0);}
.landing-mobile-menu.is-open .lmm-section:nth-of-type(1) nav li:nth-child(1) .lmm-stagger{transition-delay:.06s;}
.landing-mobile-menu.is-open .lmm-section:nth-of-type(1) nav li:nth-child(2) .lmm-stagger{transition-delay:.10s;}
.landing-mobile-menu.is-open .lmm-section:nth-of-type(1) nav li:nth-child(3) .lmm-stagger{transition-delay:.14s;}
.landing-mobile-menu.is-open .lmm-section:nth-of-type(1) nav li:nth-child(4) .lmm-stagger{transition-delay:.18s;}
.landing-mobile-menu.is-open .lmm-section:nth-of-type(1) nav li:nth-child(5) .lmm-stagger{transition-delay:.22s;}
.landing-mobile-menu.is-open .lmm-account-actions > .lmm-stagger:nth-child(1){transition-delay:.24s;}
.landing-mobile-menu.is-open .lmm-account-actions > .lmm-stagger:nth-child(2){transition-delay:.28s;}
@media(prefers-reduced-motion:reduce){.landing-mobile-menu .lmm-stagger{transition-delay:0s !important;}}
.lmm-head{
  display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);
  padding:var(--space-5) var(--space-5) var(--space-4);border-bottom:1px solid var(--border-soft);flex-shrink:0;
}
.lmm-head .brand{display:flex;align-items:center;gap:9px;}
.lmm-head .brand .mark{width:26px;height:26px;flex-shrink:0;display:flex;align-items:center;justify-content:center;}
.lmm-head .brand .mark img{width:100%;height:100%;object-fit:contain;display:block;}
.lmm-head .brand .name{display:block;font-family:var(--font-display);font-weight:700;font-size:15px;letter-spacing:-0.01em;}
.lmm-close{
  width:44px;height:44px;border-radius:50%;border:1px solid var(--border);background:var(--surface2);color:var(--muted);
  display:flex;align-items:center;justify-content:center;flex-shrink:0;cursor:pointer;padding:0;
  transition:background var(--dur-fast) var(--ease-out),color var(--dur-fast) var(--ease-out);
}
.lmm-close:hover{background:var(--surface3);color:var(--text);}
.lmm-body{flex:1;padding:var(--space-5);display:flex;flex-direction:column;gap:var(--space-6);}
.lmm-section-label{
  display:block;font-size:10.5px;font-weight:700;color:var(--muted2);text-transform:uppercase;
  letter-spacing:.07em;margin-bottom:var(--space-3);
}
.lmm-section nav ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px;}
.lmm-section nav a{
  display:flex;align-items:center;gap:12px;padding:11px 10px;border-radius:var(--r-sm);
  font-size:var(--text-body-size);font-weight:600;color:var(--text);text-decoration:none;
  transition:background var(--dur-fast) var(--ease-out);
}
.lmm-section nav a:hover,.lmm-section nav a:active{background:var(--surface2);}
.lmm-ic{flex-shrink:0;color:var(--muted);}
.lmm-account-actions{display:flex;flex-direction:column;gap:var(--space-3);}
.lmm-foot{
  flex-shrink:0;padding:var(--space-4) var(--space-5);border-top:1px solid var(--border-soft);
  display:flex;flex-direction:column;gap:var(--space-3);
}
.lmm-foot .theme-toggle{width:100%;justify-content:flex-start;}
.lmm-legal{display:flex;align-items:center;gap:7px;font-size:11.5px;color:var(--muted2);padding:0 2px;}
.lmm-legal a{color:inherit;text-decoration:none;}
.lmm-legal a:hover{color:var(--text);text-decoration:underline;}
.landing-mobile-menu-backdrop{
  /* También por encima de la topbar, para que se atenúe junto con el
     resto de la página en vez de quedar ella sola nítida por debajo.
     Mismas duraciones asimétricas que el panel (ver .landing-mobile-menu
     más arriba) para que los dos lleguen a su estado final juntos. */
  position:fixed;inset:0;z-index:41;background:rgba(20,10,5,.4);backdrop-filter:blur(2px);opacity:0;pointer-events:none;
  transition:opacity .22s var(--ease-out);
}
.landing-mobile-menu-backdrop.is-open{opacity:1;pointer-events:auto;transition:opacity .38s var(--ease-out);}
/* [aria-hidden] con la misma especificidad + !important que la regla de
   arriba que la neutraliza (misma línea, mismo peso): al empatar,
   decide el orden — esta va DESPUÉS, así que en escritorio gana el
   display:none real y el panel no queda flotando fuera de pantalla. */
@media(min-width:861px){.landing-mobile-menu[aria-hidden],.landing-mobile-menu{display:none !important;}.landing-mobile-menu-backdrop{display:none;}}
@media(prefers-reduced-motion:reduce){.landing-mobile-menu,.landing-mobile-menu.is-open,.landing-mobile-menu-backdrop,.landing-mobile-menu-backdrop.is-open{transition:none;}}

/* ---- Layout base de secciones ---- */
.landing-section{max-width:1160px;margin:0 auto;padding:var(--space-11) var(--space-6);position:relative;}
.landing-section.is-tight{padding-top:var(--space-8);padding-bottom:var(--space-8);}
.landing-eyebrow{
  display:inline-flex;align-items:center;gap:7px;font-size:var(--text-caption-size);font-weight:700;color:var(--blue);
  text-transform:uppercase;letter-spacing:.08em;margin-bottom:var(--space-3);
}
.landing-section-head{text-align:center;max-width:620px;margin:0 auto var(--space-10);}
.landing-section-head .landing-eyebrow{justify-content:center;width:100%;}
.landing-h2{
  font-family:var(--font-display);font-weight:var(--text-h1-weight);font-size:clamp(24px,3.4vw,32px);
  line-height:1.24;letter-spacing:var(--text-h1-ls);margin:0;
}
.landing-section-head p.landing-sub{color:var(--muted);font-size:var(--text-body-size);line-height:1.6;margin:var(--space-3) 0 0;}

/* ---- Grids de tarjetas ---- */
.landing-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:14px;}
.landing-grid.cols-3{grid-template-columns:repeat(3,1fr);}
.landing-grid.cols-4{grid-template-columns:repeat(4,1fr);}
@media(max-width:900px){.landing-grid.cols-3,.landing-grid.cols-4{grid-template-columns:1fr 1fr;}}
@media(max-width:640px){.landing-grid{grid-template-columns:1fr;}.landing-grid.cols-3,.landing-grid.cols-4{grid-template-columns:1fr;}}

.landing-card{
  background:var(--surface);border:1px solid var(--border-soft);border-radius:var(--r-lg);
  padding:var(--space-6);box-shadow:var(--shadow-sm);transition:transform var(--dur-med) var(--ease-out),box-shadow var(--dur-med) var(--ease-out),border-color var(--dur-med) var(--ease-out);
}
.landing-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-md);border-color:var(--border);}
.landing-card .ic{
  width:38px;height:38px;border-radius:var(--r-xs);display:flex;align-items:center;justify-content:center;
  background:var(--blue-soft);color:var(--blue);margin-bottom:var(--space-4);flex-shrink:0;
}
.landing-card h3{font-family:var(--font-display);font-weight:var(--text-h4-weight);font-size:var(--text-h4-size);margin:0 0 6px;}
.landing-card p{font-size:var(--text-body-sm-size);color:var(--muted);line-height:1.55;margin:0;}

/* ---- Sección "Cómo funciona" (3 pasos) — estilo premium alineado ---- */
#como-funciona .landing-section-head{margin-bottom:var(--space-11);}
.landing-steps-row{position:relative;align-items:stretch;}
.landing-steps-row .landing-card{
  position:relative;z-index:1;display:flex;flex-direction:column;align-items:flex-start;
  height:100%;padding:var(--space-7) var(--space-6);
}
.landing-step{position:relative;padding-left:0;display:flex;flex-direction:column;flex:1;width:100%;}
.landing-step .step-num{
  width:34px;height:34px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--red);color:#fff;font-family:var(--font-display);font-weight:700;font-size:var(--text-body-size);
  margin:0 0 var(--space-5);flex-shrink:0;
}
.landing-step h3{margin:0 0 var(--space-2);}
.landing-step p{margin-top:auto;padding-top:var(--space-2);}


/* ============================================================
   LO QUE SE RETIRÓ DE ESTA HOJA (rediseño de la landing)

   Todo el CSS de la landing ANTERIOR —hero con mockup y tarjetas
   flotantes, secciones .landing-section/.landing-card/.landing-grid,
   la demo de análisis, APEX Intelligence, Neural Trader Model, la
   transformación, el bloque de honestidad, el pie y sus tres tandas
   de responsive— se eliminó porque su marcado ya no existe: la
   landing la pintan ahora public/styles/landing-v2.css (prefijo
   .lp-) y public/js/ui/landing-experience.js.

   Antes de borrar se comprobó selector a selector que ningún ancla
   siguiera apareciendo en el HTML ni en el JS del proyecto. Lo que
   SÍ sigue vivo en este archivo, y por eso se queda:

     · el banner de campaña (.campaign-*, lo mueve ui/campaign.js),
     · las reseñas (.review-*, compartidas con la vista de la app),
     · el auth gate (.auth-gate),
     · #landingView, .reveal/.reveal-delay-* y el arranque rápido
       html[data-boot="anon"] (rendimiento/LCP del visitante anónimo),
     · el drawer móvil (.landing-mobile-menu, .lmm-*), que
       landing.js sigue abriendo y cerrando.

   DEUDA DECLARADA: dentro del bloque "LANDING" de arriba quedan
   algunas reglas huérfanas de la landing vieja (.landing-topbar,
   .landing-card, .landing-grid, .landing-section…). Están mezcladas
   línea a línea con las del drawer y las de #landingView, así que
   separarlas es un cambio aparte y con su propia verificación —
   mismo criterio que los bloques .mx-graph-* de max.css.
   ============================================================ */
