/* ==========================================================================
   Franco Pérez Osuna — Portfolio
   Archetype: Mouse-Reactive Gradient (dark, adapted) — one accent, image-forward
   ========================================================================== */

:root {
  --bg:            #0a0a0d;
  --bg-soft:       #0e0f13;
  --surface:       #131419;
  --surface-2:     #17181e;
  --glass:         rgba(255,255,255,0.045);
  --glass-strong:  rgba(255,255,255,0.075);
  --border:        rgba(255,255,255,0.09);
  --border-soft:   rgba(255,255,255,0.06);

  --ink:           #f3f3f6;
  --ink-soft:      #a7a7b3;
  --ink-faint:     #6c6c78;

  --accent:        #7c6cff;
  --accent-soft:   #a99bff;
  --accent-dim:    rgba(124,108,255,0.14);
  --accent-line:   rgba(124,108,255,0.35);

  --grad-1: #7c6cff;
  --grad-2: #4a3fc4;
  --grad-3: #1c1740;

  --radius-s: 10px;
  --radius-m: 18px;
  --radius-l: 28px;

  --ease-out: cubic-bezier(.16,1,.3,1);
  --ease-in-out: cubic-bezier(.65,0,.35,1);

  --font-display: "Space Grotesk", "Segoe UI", Arial, sans-serif;
  --font-body: "Inter", "Segoe UI", Arial, sans-serif;

  --container: 1220px;
  --nav-h: 76px;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; overflow-x: hidden; }
html, body { background: var(--bg); }

body {
  margin: 0;
  font-family: var(--font-body);
  color: var(--ink);
  background: var(--bg);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
  width: 100%;
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; margin: 0; padding: 0; }
h1, h2, h3, p, dl, dd { margin: 0; }
button { font: inherit; color: inherit; background: none; border: none; cursor: pointer; }
input, textarea, select { font: inherit; color: inherit; }

::selection { background: var(--accent); color: #fff; }

.skip-link {
  position: fixed; top: -60px; left: 16px; z-index: 999;
  background: var(--accent); color: #fff; padding: 10px 16px; border-radius: 8px;
  transition: top .2s var(--ease-out);
}
.skip-link:focus { top: 16px; }

/* ---------- layout helpers ---------- */
.section { padding: 128px 24px; position: relative; }
.section-alt { background: linear-gradient(180deg, transparent, rgba(255,255,255,0.015) 20%, rgba(255,255,255,0.015) 80%, transparent); }
.section-inner { max-width: var(--container); margin: 0 auto; }

.section-head { max-width: 640px; margin-bottom: 64px; }
.section-kicker {
  display: inline-block; font-family: var(--font-display); font-size: 13px; font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase; color: var(--accent-soft); margin-bottom: 16px;
}
.section-title {
  font-family: var(--font-display); font-weight: 600; font-size: clamp(28px, 3.6vw, 44px);
  line-height: 1.15; color: var(--ink); letter-spacing: -.01em;
}
.section-text { margin-top: 16px; font-size: 17px; line-height: 1.65; color: var(--ink-soft); max-width: 54ch; }

/* ---------- policy / legal content ---------- */
.policy-body { max-width: 68ch; margin-top: 48px; }
.policy-body h2 { font-family: var(--font-display); font-weight: 600; font-size: 20px; color: var(--ink); margin: 40px 0 12px; }
.policy-body h2:first-child { margin-top: 0; }
.policy-body p { font-size: 15.5px; line-height: 1.7; color: var(--ink-soft); margin-bottom: 14px; }
.policy-body a { color: var(--accent-soft); text-decoration: underline; text-underline-offset: 2px; }
.policy-body a:hover { color: var(--accent); }
.policy-body code { font-family: var(--font-mono, monospace); font-size: .9em; background: var(--glass); border: 1px solid var(--border-soft); border-radius: 4px; padding: 1px 6px; color: var(--ink); }
.policy-body strong { color: var(--ink); font-weight: 600; }

/* ---------- background layers ---------- */
.bg-gradient {
  position: fixed; inset: 0; z-index: 0; pointer-events: none;
  background:
    radial-gradient(560px circle at var(--mx,50%) var(--my,30%), rgba(124,108,255,.16), transparent 60%),
    radial-gradient(900px circle at 15% 0%, rgba(124,108,255,.10), transparent 55%),
    radial-gradient(700px circle at 100% 30%, rgba(74,63,196,.05), transparent 55%);
  transition: background .5s ease;
}
.bg-grain {
  position: fixed; inset: 0; z-index: 0; pointer-events: none; opacity: .035; mix-blend-mode: overlay;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)'/></svg>");
}

/* ---------- custom cursor ---------- */
.cursor { position: fixed; top: 0; left: 0; z-index: 999; pointer-events: none; opacity: 0; transition: opacity .25s var(--ease-out); }
.cursor.is-ready { opacity: 1; }
.cursor-dot, .cursor-ring { position: fixed; top: 0; left: 0; border-radius: 50%; transform: translate3d(-50%,-50%,0); }
.cursor-dot { width: 6px; height: 6px; background: var(--accent); }
.cursor-ring { width: 34px; height: 34px; border: 1px solid var(--border); transition: border-color .2s, background .2s; }
.cursor-ring.is-active { border-color: var(--accent-line); background: var(--accent-dim); }
@media (hover: none), (pointer: coarse) { .cursor { display: none; } }

/* ---------- nav ---------- */
.nav {
  position: fixed; top: 0; left: 0; right: 0; z-index: 100; height: var(--nav-h);
  display: flex; align-items: center;
  background: transparent; border-bottom: 1px solid transparent;
  transition: background .35s var(--ease-out), border-color .35s var(--ease-out), backdrop-filter .35s;
}
.nav.is-scrolled {
  background: rgba(10,10,13,0.72); backdrop-filter: blur(16px) saturate(140%); -webkit-backdrop-filter: blur(16px) saturate(140%);
  border-bottom-color: var(--border-soft);
}
.nav-inner {
  width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 24px;
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
}
.nav-brand { font-family: var(--font-display); font-weight: 600; font-size: 17px; letter-spacing: -.01em; }
.nav-brand span { color: var(--ink-soft); }
.nav-links { display: flex; gap: 32px; }
.nav-links a { font-size: 14.5px; color: var(--ink-soft); position: relative; padding: 4px 0; transition: color .2s; }
.nav-links a::after {
  content: ""; position: absolute; left: 0; right: 100%; bottom: -2px; height: 1px; background: var(--accent);
  transition: right .3s var(--ease-out);
}
.nav-links a:hover { color: var(--ink); }
.nav-links a:hover::after { right: 0; }
.nav-cta { display: inline-flex; }
.nav-back { font-size: 14.5px; color: var(--ink-soft); transition: color .2s; }
.nav-back:hover { color: var(--ink); }

.nav-burger { display: none; flex-direction: column; justify-content: center; align-items: center; gap: 5px; width: 44px; height: 44px; }
.nav-burger span { display: block; width: 26px; height: 1.5px; background: var(--ink); transition: transform .3s var(--ease-out), opacity .3s; }
.nav-burger[aria-expanded="true"] span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-burger[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-burger[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

.mobile-menu {
  position: fixed; inset: 0; z-index: 95; background: rgba(9,9,12,0.98); backdrop-filter: blur(20px);
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 36px;
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity .35s var(--ease-out), transform .35s var(--ease-out), visibility .35s;
}
.mobile-menu.is-open { opacity: 1; visibility: visible; transform: translateY(0); }
.mobile-menu nav { display: flex; flex-direction: column; align-items: center; gap: 26px; }
.mobile-menu nav a { font-family: var(--font-display); font-size: 26px; font-weight: 600; }

/* ---------- buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  padding: 15px 28px; border-radius: 100px; font-size: 14.5px; font-weight: 600;
  font-family: var(--font-body); letter-spacing: .01em;
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out), background .25s, color .25s, border-color .25s;
  will-change: transform;
}
.btn-primary { background: var(--accent); color: #fff; box-shadow: 0 8px 24px -8px rgba(124,108,255,.55); }
.btn-primary:hover { transform: translateY(-2px); box-shadow: 0 14px 30px -8px rgba(124,108,255,.65); }
.btn-outline { border: 1px solid var(--border); color: var(--ink); background: var(--glass); }
.btn-outline:hover { border-color: var(--accent-line); transform: translateY(-2px); background: var(--glass-strong); }
.btn-ghost { border: 1px solid var(--border); color: var(--ink-soft); background: transparent; }
.btn-ghost:hover { color: var(--ink); border-color: var(--accent-line); background: var(--accent-dim); }
.btn-small { padding: 9px 16px; font-size: 13px; }
.btn-full { width: 100%; }

/* ---------- hero ---------- */
.hero {
  position: relative; z-index: 1; min-height: 100vh; overflow-x: clip;
  display: flex; flex-direction: column; justify-content: center;
  padding: calc(var(--nav-h) + 40px) 24px 60px;
}
.hero-inner {
  max-width: var(--container); margin: 0 auto; width: 100%;
  display: grid; grid-template-columns: 1.05fr .95fr; gap: 60px; align-items: center;
}
.eyebrow {
  display: inline-flex; align-items: center; gap: 8px;
  font-size: 13px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase;
  color: var(--accent-soft); padding: 8px 16px; border: 1px solid var(--border);
  border-radius: 100px; background: var(--glass); margin-bottom: 28px;
}
.hero-title {
  font-family: var(--font-display); font-weight: 600; letter-spacing: -.02em;
  font-size: clamp(32px, 4.2vw, 52px); line-height: 1.14; color: var(--ink); margin-bottom: 24px;
}
.hero-title em { font-style: normal; background: linear-gradient(100deg, var(--accent-soft), var(--accent) 60%); -webkit-background-clip: text; background-clip: text; color: transparent; }
.hero-subtitle { font-size: clamp(17px, 1.6vw, 21px); line-height: 1.55; color: var(--ink-soft); max-width: 46ch; margin-bottom: 18px; }
.hero-actions { display: flex; gap: 16px; flex-wrap: wrap; }
.hero-signature { font-size: 13.5px; color: var(--ink-faint); letter-spacing: .01em; margin-top: 30px; }

.hero-scroll-hint {
  position: absolute; bottom: 36px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 10px;
  font-size: 11px; letter-spacing: .12em; text-transform: uppercase; color: var(--ink-faint);
}
.hero-scroll-hint span { width: 1px; height: 34px; background: linear-gradient(var(--accent), transparent); animation: scrollHint 2.2s ease-in-out infinite; }
@keyframes scrollHint { 0% { opacity: 0; transform: scaleY(0); transform-origin: top; } 50% { opacity: 1; transform: scaleY(1); transform-origin: top; } 100% { opacity: 0; transform: scaleY(1); transform-origin: bottom; } }

/* hero visual composition */
.hero-visual { position: relative; }
.hv-glow {
  position: absolute; inset: -18px; z-index: 0; filter: blur(38px);
  background: radial-gradient(circle at 60% 40%, var(--grad-1), var(--grad-2) 45%, transparent 70%);
  opacity: .24; border-radius: 50%; animation: hvGlow 12s ease-in-out infinite;
}
@keyframes hvGlow { 0%,100% { transform: scale(1); } 50% { transform: scale(1.12); } }

.hv-card {
  position: relative; background: var(--glass); border: 1px solid var(--border);
  border-radius: var(--radius-m); backdrop-filter: blur(18px) saturate(160%); -webkit-backdrop-filter: blur(18px) saturate(160%);
  box-shadow: 0 30px 60px -20px rgba(0,0,0,.55);
}
.hv-browser { z-index: 1; width: 100%; padding: 0; overflow: hidden; animation: hvFloat1 7s ease-in-out infinite; }
.hv-browser-bar { display: flex; align-items: center; gap: 6px; padding: 12px 16px; border-bottom: 1px solid var(--border-soft); }
.hv-browser-bar span { width: 8px; height: 8px; border-radius: 50%; background: var(--ink-faint); opacity: .5; }
.hv-url { margin-left: 10px; font-size: 11px; color: var(--ink-faint); font-family: var(--font-body); background: rgba(255,255,255,.04); padding: 3px 10px; border-radius: 6px; }
.hv-browser img { display: block; width: 100%; height: auto; }
/* Visual de marca del hero: la imagen ya trae su propio marco/glow/chrome
   incorporado, así que no se envuelve en .hv-card/.hv-browser (evitaría un
   doble marco) -- solo se le suma el float y la sombra ambiente. */
.hv-brand {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius-m);
  animation: hvFloat1 7s ease-in-out infinite;
  filter: drop-shadow(0 30px 60px rgba(0,0,0,.55));
}

@keyframes hvFloat1 { 0%,100% { transform: translateY(0); } 50% { transform: translateY(-10px); } }

/* ---------- reveal on scroll ----------
   Progressive enhancement: content is visible by default (JS off, or JS
   fails). Only once html.js is present (set by an inline script in <head>,
   before first paint) do .reveal elements start hidden and animate in. */
html.js .reveal { opacity: 0; transform: translateY(28px); transition: opacity .8s var(--ease-out), transform .8s var(--ease-out); }
html.js .reveal.is-visible { opacity: 1; transform: translateY(0); }
html.js .reveal[data-split] { opacity: 1; transform: none; }

/* Entrada escalonada del hero: mismo mecanismo de .reveal de arriba (misma
   transición, mismo observer), solo con transition-delay creciente por
   elemento -- no es una animación nueva, así que no compite por opacity/transform. */
.hero .eyebrow.reveal { transition-delay: 0ms; }
.hero .hero-title.reveal { transition-delay: 90ms; }
.hero .hero-subtitle.reveal { transition-delay: 180ms; }
.hero .hero-actions.reveal { transition-delay: 260ms; }
.hero .hero-signature.reveal { transition-delay: 340ms; }
.hero .hero-visual.reveal { transition-delay: 420ms; }

/* Mismo mecanismo para grupos que hoy entran todos a la vez: stagger de 50ms
   por nth-child, sin keyframes nuevos -- solo transition-delay sobre el
   .reveal que ya tienen. */
.services .service-card.reveal:nth-child(1) { transition-delay: 0ms; }
.services .service-card.reveal:nth-child(2) { transition-delay: 50ms; }
.services .service-card.reveal:nth-child(3) { transition-delay: 100ms; }
.services .service-card.reveal:nth-child(4) { transition-delay: 150ms; }

.pillars .pillar.reveal:nth-child(1) { transition-delay: 0ms; }
.pillars .pillar.reveal:nth-child(2) { transition-delay: 50ms; }
.pillars .pillar.reveal:nth-child(3) { transition-delay: 100ms; }

.timeline .timeline-item.reveal:nth-child(1) { transition-delay: 0ms; }
.timeline .timeline-item.reveal:nth-child(2) { transition-delay: 50ms; }
.timeline .timeline-item.reveal:nth-child(3) { transition-delay: 100ms; }
.timeline .timeline-item.reveal:nth-child(4) { transition-delay: 150ms; }
.timeline .timeline-item.reveal:nth-child(5) { transition-delay: 200ms; }

/* ---------- projects ---------- */
.projects { display: flex; flex-direction: column; gap: 32px; }
.project-card {
  display: grid; grid-template-columns: 1.1fr 1fr; gap: 0;
  background: var(--surface); border: 1px solid var(--border-soft); border-radius: var(--radius-l);
  overflow: hidden; transition: transform .35s var(--ease-out), border-color .4s, box-shadow .35s var(--ease-out);
  position: relative;
}
/* .project-card también es .reveal, y "html.js .reveal" (specificity 0,2,1)
   le gana a ".project-card" (0,1,0) en la propiedad transition -- sin esto,
   el hover heredaba los .8s del reveal en vez de sus propios .35s. Se deja
   opacity con la misma duración del reveal para no tocar el fade de entrada. */
html.js .project-card.reveal { transition: opacity .8s var(--ease-out), transform .35s var(--ease-out), border-color .4s, box-shadow .35s var(--ease-out); }
.project-card:nth-child(even) { grid-template-columns: 1fr 1.1fr; }
.project-card:nth-child(even) .project-media { order: 2; }
.project-media { position: relative; overflow: hidden; min-height: 260px; background: var(--surface-2); }
.project-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .45s var(--ease-out); }
@media (hover: hover) and (pointer: fine) {
  /* ".project-card:hover" solo (specificity 0,2,0) pierde contra
     "html.js .reveal.is-visible" (0,3,1), que fija transform: translateY(0)
     una vez la card ya entró en viewport -- el lift nunca se veía. El
     segundo selector iguala esa specificity para las visitas con JS;
     el primero queda como fallback sin JS (donde .reveal no interviene). */
  .project-card:hover, html.js .project-card:hover { transform: translateY(-6px); border-color: var(--accent-line); box-shadow: 0 40px 80px -30px rgba(124,108,255,.25); }
  .project-card:hover .project-media img { transform: scale(1.05); }
}
.project-tag {
  position: absolute; left: 18px; bottom: 18px; font-size: 12px; font-weight: 600; letter-spacing: .02em;
  padding: 8px 14px; border-radius: 100px; background: rgba(10,10,13,.6); backdrop-filter: blur(10px);
  border: 1px solid rgba(255,255,255,.14); color: var(--ink);
}
.project-body { padding: 40px; display: flex; flex-direction: column; gap: 20px; }
.project-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; }
.project-head h3 { font-family: var(--font-display); font-size: 26px; font-weight: 600; letter-spacing: -.01em; }
.project-category { font-size: 13px; color: var(--accent-soft); margin-top: 4px; }
.project-desc { font-size: 15px; line-height: 1.65; color: var(--ink-soft); }
.project-tech { display: flex; gap: 8px; flex-wrap: wrap; }
.project-tech span { font-size: 12px; padding: 6px 12px; border-radius: 100px; border: 1px solid var(--border); color: var(--ink-faint); }
.project-case { display: grid; gap: 16px; padding-top: 16px; border-top: 1px solid var(--border-soft); }
.project-case dt { font-family: var(--font-display); font-size: 12.5px; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--ink); margin-bottom: 5px; }
.project-case dd { font-size: 14px; line-height: 1.6; color: var(--ink-soft); margin: 0; }

/* ---------- proyecto piloto: ALBA ----------
   Rediseño de prueba para un solo proyecto (propuesta "mini caso de estudio").
   Todo queda bajo .project-pilot / .pilot-* para no tocar AMORA ni Duarte & Vega,
   que siguen usando .project-card / .project-media tal cual. */
.project-pilot { display: block; }

.pilot-visual { position: relative; }
.pilot-window {
  position: relative; background: var(--glass); border: 1px solid var(--border);
  backdrop-filter: blur(18px) saturate(160%); -webkit-backdrop-filter: blur(18px) saturate(160%);
  overflow: hidden;
}
.pilot-window img { display: block; width: 100%; height: auto; }
.pilot-window-hero { border: none; border-radius: 0; }
.pilot-window .hv-browser-bar { border-bottom: 1px solid var(--border-soft); }

/* Acento teal muy sutil, tomado de la paleta real de ALBA -- solo en el tag y en el hover de la card */
.pilot-tag { border-color: rgba(79,184,173,.4); }
.project-pilot:hover, html.js .project-pilot:hover {
  border-color: rgba(79,184,173,.45);
  box-shadow: 0 40px 80px -30px rgba(79,184,173,.22);
}

.pilot-flow { display: grid; grid-template-columns: repeat(3, 1fr); gap: 16px; padding: 20px 40px 0; }
.pilot-window-flow { border-radius: var(--radius-s); }
.pilot-window-flow .hv-url { font-size: 10.5px; }
/* Mismo mecanismo de stagger que servicios/pillars/timeline: transition-delay
   creciente sobre el .reveal que cada item ya trae -- refuerza la lectura
   "paso a paso" del flujo, sin animación nueva. */
.pilot-flow .pilot-flow-item.reveal:nth-child(1) { transition-delay: 0ms; }
.pilot-flow .pilot-flow-item.reveal:nth-child(2) { transition-delay: 90ms; }
.pilot-flow .pilot-flow-item.reveal:nth-child(3) { transition-delay: 180ms; }

.pilot-body { padding: 36px 40px 40px; }
.pilot-case { grid-template-columns: repeat(3, 1fr); gap: 28px; }
.pilot-cta-bottom { display: none; }

@media (max-width: 860px) {
  /* Scroll horizontal nativo para los 3 pasos -- sin carrusel, sin JS nuevo */
  .pilot-flow {
    display: flex; overflow-x: auto; scroll-snap-type: x proximity; gap: 12px;
    padding: 16px 20px 0; -webkit-overflow-scrolling: touch;
  }
  .pilot-flow-item { flex: 0 0 78%; scroll-snap-align: start; }
  .pilot-case { grid-template-columns: 1fr; gap: 16px; }
  .pilot-body { padding: 26px 24px 28px; }
  .pilot-cta-bottom { display: inline-flex; margin-top: 6px; }
}

/* ---------- proyecto editorial: AMORA ----------
   Segunda composición de prueba, distinta a la de ALBA: visual grande
   dominante (~60%) + columna de contenido compacta (~40%), en vez del
   layout full-width + grilla de ALBA. Todo bajo .project-editorial /
   .amora-* -- no toca ALBA ni Duarte & Vega. */
.project-editorial { display: grid; grid-template-columns: 3fr 2fr; gap: 0; align-items: stretch; }

.amora-visual { position: relative; display: flex; flex-direction: column; }
.amora-window {
  position: relative; background: var(--glass); border: 1px solid var(--border);
  backdrop-filter: blur(18px) saturate(160%); -webkit-backdrop-filter: blur(18px) saturate(160%);
  overflow: hidden;
}
.amora-window img { display: block; width: 100%; height: 100%; object-fit: cover; }
.amora-window-hero { flex: 1 1 auto; min-height: 380px; border: none; border-radius: 0; }
.amora-window .hv-browser-bar { border-bottom: 1px solid var(--border-soft); }

/* Acento oliva muy sutil, tomado del verde real de AMORA -- solo tag y hover */
.amora-tag { border-color: rgba(74,87,58,.4); }
.project-editorial:hover, html.js .project-editorial:hover {
  border-color: rgba(74,87,58,.45);
  box-shadow: 0 40px 80px -30px rgba(74,87,58,.22);
}

.amora-detail-row { display: grid; grid-template-columns: 1.4fr 1fr; gap: 12px; padding: 12px; background: var(--surface); }
.amora-window-detail { border-radius: var(--radius-s); }
.amora-window-detail img { height: 130px; }
.amora-window-mobile img { object-position: top; }
.amora-window-detail .hv-url { font-size: 10px; }

.amora-body { padding: 40px; display: flex; flex-direction: column; gap: 18px; justify-content: center; }
.amora-case { gap: 16px; }
.amora-cta { margin-top: 2px; }

/* AMORA ya no usa .project-head para su título (el CTA se movió al final),
   así que pierde la regla ".project-head h3" -- se repone acá con los mismos
   valores exactos que usa ALBA, para que los tres títulos queden idénticos. */
.amora-body h3 { font-family: var(--font-display); font-size: 26px; font-weight: 600; letter-spacing: -.01em; }

/* Reveal escalonado entre visual y contenido -- misma transición de siempre,
   solo con un delay chico en el contenido para que entre un instante después
   que la foto (la protagonista). */
.amora-body.reveal { transition-delay: 120ms; }

@media (max-width: 860px) {
  .project-editorial { grid-template-columns: 1fr; }
  .amora-window-hero { min-height: 280px; }
  .amora-body { padding: 26px 24px 28px; }
}

/* ---------- proyecto editorial: Duarte & Vega ----------
   Tercera composición de prueba, distinta a ALBA (full-width + flujo) y a
   AMORA (60% visual dominante): acá el contenido manda (~60%) y el visual
   acompaña (~40%), con menos movimiento que las otras dos -- el tono es
   sobrio/editorial, no interactivo. Todo bajo .project-editorial-dv /
   .dv-* -- no toca AMORA ni ALBA. */
.project-editorial-dv { display: grid; grid-template-columns: 3fr 2fr; gap: 0; align-items: stretch; }
.dv-content { order: 1; }
.dv-visual { order: 2; display: flex; flex-direction: column; position: relative; }

.dv-window {
  position: relative; background: var(--glass); border: 1px solid var(--border);
  backdrop-filter: blur(18px) saturate(160%); -webkit-backdrop-filter: blur(18px) saturate(160%);
  overflow: hidden;
}
.dv-window img { display: block; width: 100%; height: auto; }
.dv-window .hv-browser-bar { border-bottom: 1px solid var(--border-soft); }
.dv-window-main { border-top: none; border-right: none; border-radius: 0; }
.dv-window-inset { margin: 16px 24px 24px; border-radius: var(--radius-s); }

/* Acento mostaza muy sutil, tomado del color real del sitio -- tag, línea del
   pull-quote y borde/glow al hover. Sin transform en el hover: es el
   proyecto más quieto de los tres a propósito. */
.dv-tag { border-color: rgba(184,144,47,.4); }
.project-editorial-dv:hover, html.js .project-editorial-dv:hover {
  transform: none;
  border-color: rgba(184,144,47,.4);
  box-shadow: 0 30px 60px -25px rgba(184,144,47,.16);
}

.dv-content.project-body { padding: 40px; gap: 18px; justify-content: center; }
.dv-case { gap: 16px; }
.dv-pullquote { border-left: 2px solid rgba(184,144,47,.5); padding-left: 20px; margin: 2px 0; }
.dv-pullquote p { font-family: var(--font-display); font-size: 17px; font-weight: 500; font-style: italic; color: var(--ink); line-height: 1.5; margin: 0 0 8px; }
.dv-pullquote cite { font-size: 12.5px; font-style: normal; color: var(--ink-faint); }
.dv-cta { margin-top: 6px; align-self: flex-start; }

/* Título sin ".project-head": mismos valores que ALBA para que los tres
   títulos compartan tamaño, fuente y peso. */
.dv-content h3 { font-family: var(--font-display); font-size: 26px; font-weight: 600; letter-spacing: -.01em; }

@media (max-width: 860px) {
  .project-editorial-dv { grid-template-columns: 1fr; }
  .dv-content, .dv-visual { order: 0; }
  .dv-content.project-body { padding: 26px 24px 28px; }
  .dv-window-inset { margin: 14px 20px 20px; }
}

/* ---------- proyecto editorial: HogarBit ----------
   Cuarta composición, distinta a las otras tres: nada de split 60/40 ni
   columna de contenido lateral -- ancho completo de punta a punta, con una
   fila de proceso (pipeline) que expone la arquitectura del sitio, un grid
   de 2 capturas comparativas y el cuerpo del caso abajo, también a ancho
   completo. Todo bajo .project-editorial-hb / .hb-* -- no toca AMORA,
   Duarte & Vega ni ALBA. */
.project-editorial-hb { display: block; }

.hb-visual { position: relative; }
.hb-window {
  position: relative; background: var(--glass); border: 1px solid var(--border);
  backdrop-filter: blur(18px) saturate(160%); -webkit-backdrop-filter: blur(18px) saturate(160%);
  overflow: hidden;
}
.hb-window img { display: block; width: 100%; height: auto; }
.hb-window .hv-browser-bar { border-bottom: 1px solid var(--border-soft); }
.hb-window-hero { border: none; border-radius: 0; }

/* En mobile el hero ya es bajo por su propio ancho (aspect ratio natural de
   la captura); en desktop se lo recorta a un formato panorámico para que no
   domine el alto de la card -- misma imagen, sin reencuadrar el archivo. */
@media (min-width: 861px) {
  .hb-window-hero { aspect-ratio: 21 / 9; }
  .hb-window-hero img { height: 100%; object-fit: cover; object-position: top; }
}

/* Acento slate-azulado, tomado de la paleta real de HogarBit -- solo tag,
   nodo activo del pipeline y hover de la card. */
.hb-tag { border-color: rgba(120,132,156,.4); }
.project-editorial-hb:hover, html.js .project-editorial-hb:hover {
  border-color: rgba(120,132,156,.45);
  box-shadow: 0 40px 80px -30px rgba(120,132,156,.22);
}

.hb-pipeline {
  display: flex; gap: 4px; padding: 22px 40px;
  background: var(--surface); border-top: 1px solid var(--border-soft); border-bottom: 1px solid var(--border-soft);
}
.hb-pipeline-step {
  position: relative; flex: 1 1 0; text-align: center;
  font-family: var(--font-display); font-size: 12.5px; font-weight: 600; letter-spacing: .02em;
  color: var(--ink-soft); padding: 4px 6px;
}
.hb-pipeline-step:first-child { color: var(--ink); }
.hb-pipeline-step:not(:last-child)::after {
  content: "→"; position: absolute; right: -4px; top: 50%; transform: translate(50%, -50%);
  color: var(--ink-faint); font-size: 13px; font-weight: 400;
}
.hb-scale { padding: 14px 40px 0; text-align: center; font-size: 12.5px; color: var(--ink-faint); }

.hb-compare { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; padding: 24px 40px 0; }
.hb-window-compare { border-radius: var(--radius-s); }
.hb-window-compare .hv-url { font-size: 10.5px; }

.hb-body h3 { font-family: var(--font-display); font-size: 26px; font-weight: 600; letter-spacing: -.01em; }
.hb-lede { font-size: 14px; line-height: 1.6; color: var(--ink-faint); }
.hb-case { grid-template-columns: repeat(2, 1fr); gap: 24px; }
.hb-status { font-size: 13.5px; color: var(--ink); padding-top: 14px; border-top: 1px solid var(--border-soft); }
.hb-status-label { font-family: var(--font-display); font-weight: 600; font-size: 11.5px; letter-spacing: .05em; text-transform: uppercase; color: var(--accent-soft); }
.hb-status-note { margin-top: 4px; font-size: 12.5px; line-height: 1.5; color: var(--ink-faint); }
.hb-concept { font-size: 14.5px; font-style: italic; color: var(--ink-soft); border-left: 2px solid rgba(120,132,156,.5); padding-left: 20px; margin: 2px 0; }
.hb-stack-secondary { font-size: 11.5px; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-faint); }
.hb-ctas { display: flex; gap: 12px; flex-wrap: wrap; margin-top: 2px; }

@media (max-width: 860px) {
  .hb-pipeline {
    justify-content: flex-start; overflow-x: auto; scroll-snap-type: x proximity;
    padding: 18px 20px; gap: 30px; -webkit-overflow-scrolling: touch;
  }
  .hb-pipeline-step { flex: 0 0 auto; scroll-snap-align: start; }
  .hb-scale { padding: 12px 24px 0; }
  .hb-compare { grid-template-columns: 1fr; padding: 20px 24px 0; }
  .hb-case { grid-template-columns: 1fr; gap: 16px; }
  .hb-body { padding: 26px 24px 28px; }
}

/* ---------- services ---------- */
.services { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.service-card {
  padding: 32px 26px; background: var(--glass); border: 1px solid var(--border-soft); border-radius: var(--radius-m);
  transition: transform .4s var(--ease-out), border-color .3s, background .3s;
}
/* Mismo conflicto de specificity que ".project-card" (ver comentario ahí):
   "html.js .reveal" (0,2,1) le gana a ".service-card" (0,1,0) en transition,
   y "html.js .reveal.is-visible" (0,3,1) fija transform: translateY(0) por
   encima de ".service-card:hover" (0,2,0) una vez la card ya entró en
   viewport. Mismo timing/easing de siempre, solo con specificity suficiente
   para que realmente se aplique. */
html.js .service-card.reveal { transition: opacity .8s var(--ease-out), transform .4s var(--ease-out), border-color .3s, background .3s; }
.service-icon {
  display: inline-flex; align-items: center; justify-content: center; width: 46px; height: 46px;
  border-radius: 12px; background: var(--accent-dim); color: var(--accent-soft); margin-bottom: 22px;
  transition: transform .4s var(--ease-out), background .3s;
}
.service-icon svg { width: 22px; height: 22px; }
@media (hover: hover) and (pointer: fine) {
  .service-card:hover, html.js .service-card:hover { transform: translateY(-6px); border-color: var(--accent-line); background: var(--glass-strong); }
  .service-card:hover .service-icon { transform: rotate(-8deg) scale(1.08); background: var(--accent); color: #fff; }
}
.service-card h3 { font-family: var(--font-display); font-size: 18px; font-weight: 600; margin-bottom: 12px; }
.service-card p { font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }

.ai-highlight {
  margin-top: 20px; display: flex; align-items: flex-start; gap: 22px;
  padding: 32px; border-radius: var(--radius-l); border: 1px solid var(--accent-line);
  background: linear-gradient(135deg, var(--accent-dim), var(--glass) 65%);
  position: relative; overflow: hidden;
}
.ai-highlight::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(460px 240px at 10% 0%, rgba(124,108,255,.18), transparent 70%);
}
.ai-highlight-icon {
  position: relative; z-index: 1; flex-shrink: 0; width: 50px; height: 50px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 13px; background: var(--accent-dim); color: var(--accent-soft); border: 1px solid var(--accent-line);
}
.ai-highlight-icon svg { width: 22px; height: 22px; }
.ai-highlight-body { position: relative; z-index: 1; }
.ai-highlight-tag {
  display: inline-block; font-size: 11px; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: #fff; background: var(--accent); padding: 3px 11px; border-radius: 999px; margin-bottom: 12px;
}
.ai-highlight-body h3 { font-family: var(--font-display); font-size: 19px; font-weight: 600; margin-bottom: 10px; color: var(--ink); }
.ai-highlight-body p { font-size: 14.5px; line-height: 1.65; color: var(--ink-soft); max-width: 62ch; }
.ai-highlight-cta {
  margin-top: 18px; display: inline-flex; align-items: center; gap: 7px;
  font: inherit; font-size: 14px; font-weight: 600; color: var(--accent-soft);
  background: transparent; border: none; padding: 0; cursor: pointer;
}
.ai-highlight-cta span { display: inline-block; transition: transform .25s var(--ease-out); }
.ai-highlight-cta:hover { color: var(--ink); }
.ai-highlight-cta:hover span { transform: translateX(4px); }

/* ---------- pillars ---------- */
.pillars { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
.pillar { padding-top: 28px; border-top: 1px solid var(--border); }
.pillar-num { font-family: var(--font-display); font-size: 13px; color: var(--accent-soft); font-weight: 600; }
.pillar h3 { font-family: var(--font-display); font-size: 21px; font-weight: 600; margin: 16px 0 12px; }
.pillar p { font-size: 15px; line-height: 1.65; color: var(--ink-soft); }

/* ---------- timeline ---------- */
.timeline { display: flex; flex-direction: column; }
.timeline-item {
  display: grid; grid-template-columns: 90px 1fr; gap: 28px; padding: 30px 0;
  border-bottom: 1px solid var(--border-soft); position: relative;
}
.timeline-item:first-child { border-top: 1px solid var(--border-soft); }
.timeline-num { font-family: var(--font-display); font-size: 34px; font-weight: 600; color: var(--ink-faint); transition: color .3s; }
.timeline-item:hover .timeline-num { color: var(--accent-soft); }
.timeline-item h3 { font-family: var(--font-display); font-size: 20px; font-weight: 600; margin-bottom: 8px; }
.timeline-item p { font-size: 15px; line-height: 1.6; color: var(--ink-soft); max-width: 56ch; }

/* ---------- nova (sección propia) ---------- */
.nova-grid { display: grid; grid-template-columns: 1.15fr .85fr; gap: 60px; align-items: center; }
.nova-feature { max-width: 640px; }
.nova-tags { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 28px; }
.nova-tags span { font-size: 12px; padding: 6px 12px; border-radius: 100px; border: 1px solid var(--border); color: var(--ink-faint); }
.nova-feature-hook { margin-top: 20px; font-size: 15.5px; font-style: italic; color: var(--ink-soft); }
.nova-feature-actions { margin-top: 28px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }
.nova-feature-powered { font-size: 12px; color: var(--ink-faint); }

/* Preview ambiental de conversación -- decorativo (aria-hidden en el HTML),
   no es una réplica del panel real: sin header, sin avatar, sin input, sin
   contenedor con scroll. Solo burbujas sueltas para dar contexto visual
   mientras Nova está cerrada. */
.nova-preview { display: flex; flex-direction: column; gap: 14px; }
.nova-preview-bubble {
  margin: 0; width: fit-content; max-width: 85%; padding: 12px 18px; border-radius: 16px;
  font-size: 14px; line-height: 1.5;
}
.nova-preview-q {
  align-self: flex-end; background: var(--accent-dim); border: 1px solid var(--accent-line);
  color: var(--ink); border-bottom-right-radius: 4px;
}
.nova-preview-a {
  align-self: flex-start; background: var(--glass); border: 1px solid var(--border-soft);
  color: var(--ink); border-bottom-left-radius: 4px;
}
.nova-preview-a span { color: var(--accent-soft); margin-right: 2px; }

/* ---------- about ---------- */
.about-grid { display: grid; grid-template-columns: .8fr 1.2fr; gap: 72px; align-items: center; }
.about-photo {
  border-radius: var(--radius-l); overflow: hidden; border: 1px solid var(--border);
  aspect-ratio: 3/4; background: var(--surface);
  box-shadow: 0 40px 80px -30px rgba(0,0,0,.6);
}
.about-photo img { width: 100%; height: 100%; object-fit: cover; }
.about-copy p { font-size: 16.5px; line-height: 1.75; color: var(--ink-soft); margin-top: 18px; }
.about-copy .section-title { margin-top: 6px; }
/* Mismo acento en gradiente que ya usa el hero (.hero-title em) -- se
   reutiliza el mismo lenguaje visual, no se inventa uno nuevo. */
.about-copy .section-title em { font-style: normal; background: linear-gradient(100deg, var(--accent-soft), var(--accent) 60%); -webkit-background-clip: text; background-clip: text; color: transparent; }
/* Línea editorial para el párrafo con la propuesta de valor -- mismo recurso
   que ya usa el pull-quote de Duarte & Vega, reaplicado acá. */
.about-copy p.about-copy-highlight { border-left: 2px solid var(--accent-line); padding-left: 20px; color: var(--ink); }
.about-facts { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 30px; }
.about-facts li { font-size: 13.5px; padding: 10px 18px; border-radius: 100px; border: 1px solid var(--border); color: var(--ink-soft); background: var(--glass); }

/* ---------- stack ---------- */
.stack-groups { display: grid; grid-template-columns: repeat(3, 1fr); gap: 32px; }
.stack-group { padding-top: 28px; border-top: 1px solid var(--border); }
.stack-group h3 { font-family: var(--font-display); font-size: 19px; font-weight: 600; margin-bottom: 14px; }
.stack-group-list { font-family: var(--font-display); font-size: 14px; font-weight: 600; color: var(--accent-soft); margin-bottom: 10px; }
.stack-group-desc { font-size: 14.5px; line-height: 1.6; color: var(--ink-soft); }
.stack-closing { margin-top: 40px; font-size: 15.5px; font-style: italic; color: var(--ink-soft); }

/* ---------- contact ---------- */
.contact-trust {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-top: 24px;
}

.contact-trust span {
  font-size: 12px;
  padding: 6px 12px;
  border-radius: 100px;
  border: 1px solid var(--border);
  color: var(--ink-soft);
}
.contact-grid { display: grid; grid-template-columns: 1fr .95fr; gap: 60px; align-items: start; }
.contact-copy .hero-actions { margin-top: 32px; }
.contact-direct { margin-top: 44px; display: flex; flex-direction: column; gap: 14px; }
.contact-direct-item {
  display: inline-flex; align-items: center; gap: 12px; font-size: 15px; color: var(--ink-soft);
  transition: color .25s;
}
.contact-direct-item:hover { color: var(--ink); }
.cd-icon { display: inline-flex; width: 22px; height: 22px; color: var(--accent-soft); }
.cd-icon svg { width: 100%; height: 100%; }

.contact-form {
  background: var(--glass); border: 1px solid var(--border); border-radius: var(--radius-l);
  padding: 36px; display: flex; flex-direction: column; gap: 18px;
  backdrop-filter: blur(20px) saturate(160%); -webkit-backdrop-filter: blur(20px) saturate(160%);
}
.field { display: flex; flex-direction: column; gap: 8px; }
.field-hp {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; margin: -1px; padding: 0; border: 0;
}
.field label { font-size: 13px; color: var(--ink-soft); }
.field input, .field select, .field textarea {
  background: rgba(255,255,255,.03); border: 1px solid var(--border); border-radius: var(--radius-s);
  padding: 13px 16px; color: var(--ink); font-size: 14.5px; transition: border-color .25s, background .25s;
}
.field input:focus, .field select:focus, .field textarea:focus {
  outline: none; border-color: var(--accent-line); background: rgba(255,255,255,.05);
}
.field textarea { resize: vertical; min-height: 96px; }
.form-note {
  font-size: 13.5px;
  color: var(--ink-soft);
  min-height: 18px;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 8px;
}

.form-note-icon {
  flex-shrink: 0;
  width: 15px;
  height: 15px;
}

.form-note.is-success {
  color: #8fe0b0;
}

.form-note.is-error {
  color: #f5a3a3;
}

.form-note-link {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.form-note-link:hover {
  color: var(--ink);
}

/* ---------- footer ---------- */
.footer { border-top: 1px solid var(--border-soft); padding: 64px 24px 28px; position: relative; z-index: 1; }
.footer-inner {
  max-width: var(--container); margin: 0 auto; display: flex; flex-wrap: wrap; justify-content: space-between; gap: 32px; padding-bottom: 40px;
}
.footer-brand { display: flex; flex-direction: column; gap: 6px; }
.footer-name { font-family: var(--font-display); font-size: 18px; font-weight: 600; }
.footer-role { font-size: 13.5px; color: var(--ink-faint); }
.footer-links { display: flex; gap: 26px; flex-wrap: wrap; }
.footer-links a, .footer-contact a { font-size: 14px; color: var(--ink-soft); transition: color .2s; }
.footer-links a:hover, .footer-contact a:hover { color: var(--accent-soft); }
.footer-contact { display: flex; flex-direction: column; gap: 8px; align-items: flex-end; text-align: right; }
.footer-bottom {
  max-width: var(--container); margin: 0 auto; display: flex; align-items: center; justify-content: space-between;
  border-top: 1px solid var(--border-soft); padding-top: 24px;
}
.footer-bottom p { font-size: 12.5px; color: var(--ink-faint); }
.back-to-top {
  width: 44px; height: 44px; border-radius: 50%; border: 1px solid var(--border); color: var(--ink-soft);
  display: flex; align-items: center; justify-content: center; transition: transform .3s var(--ease-out), border-color .3s, color .3s;
}
@media (hover: hover) and (pointer: fine) {
  .back-to-top:hover { transform: translateY(-3px); border-color: var(--accent-line); color: var(--accent-soft); }
}

/* ---------- asistente IA "Nova" ---------- */
.assistant { position: fixed; right: 20px; bottom: 20px; z-index: 300; }

.assistant-fab {
  width: 58px; height: 58px; border-radius: 50%; background: var(--accent); color: #fff;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 14px 34px -10px rgba(124,108,255,.65), 0 0 0 1px rgba(255,255,255,.08);
  transition: transform .35s var(--ease-out), box-shadow .35s var(--ease-out);
  position: relative;
}
.assistant-fab:hover { transform: translateY(-3px) scale(1.04); }
.assistant-fab::after {
  content: ""; position: absolute; inset: -4px; border-radius: 50%; border: 1px solid var(--accent-line);
  opacity: .6; animation: assistantPulse 2.6s ease-out infinite;
}
@keyframes assistantPulse { 0% { transform: scale(.9); opacity: .55; } 100% { transform: scale(1.35); opacity: 0; } }
.assistant-fab svg { width: 24px; height: 24px; position: absolute; transition: opacity .25s, transform .25s; }
.assistant-fab .ico-close { opacity: 0; transform: scale(.6) rotate(-45deg); }
.assistant-fab .ico-chat { opacity: 1; transform: scale(1) rotate(0); }
.assistant.is-open .assistant-fab .ico-chat { opacity: 0; transform: scale(.6) rotate(45deg); }
.assistant.is-open .assistant-fab .ico-close { opacity: 1; transform: scale(1) rotate(0); }

.assistant-panel {
  position: absolute; right: 0; bottom: 76px; width: min(380px, calc(100vw - 40px)); max-height: min(560px, 70vh);
  display: flex; flex-direction: column;
  background: rgba(15,16,21,.86); border: 1px solid var(--border); border-radius: var(--radius-l);
  backdrop-filter: blur(24px) saturate(160%); -webkit-backdrop-filter: blur(24px) saturate(160%);
  box-shadow: 0 40px 90px -25px rgba(0,0,0,.7);
  opacity: 0; visibility: hidden; transform: translateY(16px) scale(.97); transform-origin: bottom right;
  transition: opacity .3s var(--ease-out), transform .3s var(--ease-out), visibility .3s;
}
.assistant.is-open .assistant-panel { opacity: 1; visibility: visible; transform: translateY(0) scale(1); }

.assistant-header { display: flex; align-items: center; gap: 12px; padding: 18px 20px; border-bottom: 1px solid var(--border-soft); }
.assistant-avatar {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  background: linear-gradient(135deg, var(--accent-soft), var(--accent));
  display: flex; align-items: center; justify-content: center; color: #fff; font-size: 15px;
}
.assistant-header-text { flex: 1; min-width: 0; }
.assistant-name { font-family: var(--font-display); font-weight: 600; font-size: 15px; }
.assistant-status { font-size: 12px; color: var(--ink-faint); margin-top: 1px; }
.assistant-close {
  flex-shrink: 0; width: 44px; height: 44px; border-radius: 50%; color: var(--ink-soft);
  display: flex; align-items: center; justify-content: center; transition: color .2s, background .2s;
}
.assistant-close:hover { color: var(--ink); background: var(--glass); }
.assistant-close svg { width: 16px; height: 16px; }

.assistant-messages { flex: 1; overflow-y: auto; padding: 18px 20px; display: flex; flex-direction: column; gap: 12px; }
.msg {
  max-width: 88%; font-size: 13.5px; line-height: 1.55; padding: 11px 14px; border-radius: 14px;
  opacity: 0; transform: translateY(6px) scale(.98);
  transition: opacity .2s var(--ease-out), transform .2s var(--ease-out);
}
.msg.is-visible { opacity: 1; transform: translateY(0) scale(1); }
.msg p { margin: 0; }
.msg-bot { align-self: flex-start; background: var(--glass); border: 1px solid var(--border-soft); color: var(--ink); border-bottom-left-radius: 4px; }
.msg-user { align-self: flex-end; background: var(--accent); color: #fff; border-bottom-right-radius: 4px; }
.msg-typing { align-self: flex-start; display: flex; gap: 4px; padding: 13px 16px; }
.msg-typing span { width: 6px; height: 6px; border-radius: 50%; background: var(--ink-faint); animation: typingDot 1.1s ease-in-out infinite; }
.msg-typing span:nth-child(2) { animation-delay: .15s; } .msg-typing span:nth-child(3) { animation-delay: .3s; }
@keyframes typingDot { 0%, 60%, 100% { opacity: .3; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-3px); } }

.assistant-suggestions { display: flex; flex-wrap: wrap; gap: 8px; }
.chip {
  min-height: 44px; display: inline-flex; align-items: center;
  font-size: 12px; padding: 8px 16px; border-radius: 100px; border: 1px solid var(--border);
  color: var(--ink-soft); background: var(--glass); transition: border-color .2s, color .2s, background .2s;
}
.chip:hover { border-color: var(--accent-line); color: var(--ink); background: var(--accent-dim); }

.assistant-input { display: flex; gap: 8px; padding: 14px; border-top: 1px solid var(--border-soft); }
.assistant-input input {
  flex: 1; background: rgba(255,255,255,.03); border: 1px solid var(--border); border-radius: 100px;
  padding: 11px 16px; color: var(--ink); font-size: 13.5px;
}
.assistant-input input:focus { outline: none; border-color: var(--accent-line); }
.assistant-input button {
  width: 44px; height: 44px; border-radius: 50%; background: var(--accent); color: #fff; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center; transition: transform .25s var(--ease-out);
}
.assistant-input button:hover { transform: scale(1.06); }
.assistant-input button svg { width: 17px; height: 17px; }

@media (max-width: 560px) {
  .assistant { right: 14px; bottom: 14px; }
  .assistant-panel { position: fixed; right: 14px; left: 14px; bottom: 84px; width: auto; }
}

/* ---------- progress bar ---------- */
.progress-bar { position: fixed; top: 0; left: 0; height: 2px; width: 0%; background: var(--accent); z-index: 200; transition: width .1s linear; }

/* ---------- consent banner ---------- */
.consent-banner {
  position: fixed; left: 20px; bottom: 20px; z-index: 250; width: min(380px, calc(100vw - 40px));
  background: rgba(15,16,21,.92); border: 1px solid var(--border); border-radius: var(--radius-m);
  backdrop-filter: blur(24px) saturate(160%); -webkit-backdrop-filter: blur(24px) saturate(160%);
  box-shadow: 0 40px 90px -25px rgba(0,0,0,.7);
  padding: 18px 20px;
  display: flex; flex-direction: column; gap: 14px;
  opacity: 0; transform: translateY(12px);
  transition: opacity .3s var(--ease-out), transform .3s var(--ease-out);
}
.consent-banner[hidden] { display: none; }
.consent-banner.is-visible { opacity: 1; transform: translateY(0); }
.consent-banner p { font-size: 13.5px; line-height: 1.55; color: var(--ink-soft); }
.consent-actions { display: flex; gap: 10px; justify-content: flex-end; }
.consent-actions .btn { min-height: 44px; }
@media (max-width: 860px) {
  .consent-banner { left: 14px; right: 14px; bottom: 18px; width: auto; }
  /* Antes, mientras el banner estaba visible, el FAB de Nova se ocultaba
     por completo -- si alguien no tocaba "Aceptar"/"Rechazar", Nova quedaba
     invisible indefinidamente. Ahora en cambio se corre hacia arriba, lo
     suficiente para no superponerse con el banner (que sigue siendo lo
     prioritario abajo), pero sin desaparecer nunca. Reacciona al mismo
     atributo [hidden] que ya alterna main.js -- no toca la lógica de
     consentimiento. */
  .consent-banner:not([hidden]) ~ .assistant { bottom: 210px; }
}

/* ==========================================================================
   Responsive
   ========================================================================== */

@media (max-width: 1080px) {
  .hero-inner { grid-template-columns: 1fr; gap: 64px; }
  .hero-visual { max-width: 560px; }
  .services { grid-template-columns: repeat(2, 1fr); }
  .about-grid { grid-template-columns: 1fr; }
  .about-photo { max-width: 360px; margin: 0 auto; }
  .contact-grid { grid-template-columns: 1fr; }
  .nova-grid { grid-template-columns: 1fr; gap: 40px; }
  .nova-preview { max-width: 480px; }
}

@media (max-width: 860px) {
  .nav-links, .nav-cta { display: none; }
  .nav-burger { display: flex; }
  .project-card, .project-card:nth-child(even) { grid-template-columns: 1fr; }
  .project-card:nth-child(even) .project-media { order: 0; }
  .project-body { padding: 30px 26px; }
  .pillars { grid-template-columns: 1fr; gap: 40px; }
  .stack-groups { grid-template-columns: 1fr; gap: 40px; }
  .services { grid-template-columns: 1fr 1fr; }
  .timeline-item { grid-template-columns: 56px 1fr; gap: 18px; }
  .timeline-num { font-size: 24px; }
  .ai-highlight { flex-direction: column; padding: 26px 24px; }
  .footer-inner { flex-direction: column; }
  .footer-contact { align-items: flex-start; text-align: left; }
}

@media (max-width: 560px) {
  .section { padding: 88px 20px; }
  .section-head { margin-bottom: 44px; }
  .hero { padding-top: calc(var(--nav-h) + 20px); }
  .hero-actions { flex-direction: column; align-items: stretch; }
  .hero-actions .btn { width: 100%; }
  .services { grid-template-columns: 1fr; }
  .hv-glow { inset: -20px; }
  .footer-bottom { flex-direction: column; gap: 16px; align-items: flex-start; }
}

/* ==========================================================================
   Reduced motion — only intrusive effects are gated
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  .hv-glow, .hv-browser, .hv-brand, .hero-scroll-hint span { animation: none !important; }
  html { scroll-behavior: auto; }
  .hero .eyebrow.reveal, .hero .hero-title.reveal, .hero .hero-subtitle.reveal,
  .hero .hero-actions.reveal, .hero .hero-signature.reveal, .hero .hero-visual.reveal,
  .services .service-card.reveal, .pillars .pillar.reveal, .timeline .timeline-item.reveal {
    transition-delay: 0ms;
  }
  /* Reveal: se mantiene el fade de opacity, se retira el desplazamiento */
  html.js .reveal, html.js .reveal.is-visible { transform: none; transition: opacity .8s var(--ease-out); }
  /* Microinteracciones nuevas: mismo criterio -- opacity sí, movimiento no */
  .consent-banner, .consent-banner.is-visible { transform: none; transition: opacity .3s var(--ease-out); }
  .msg, .msg.is-visible { transform: none; transition: opacity .2s var(--ease-out); }
}
