/* ══════════════════════════════════════════════════════════════
   SANTIAGO HERMOSILLA — PORTFOLIO
   Dirección: brutalismo editorial. Grises azulados + un acento rosa.
   Bordes de 1px, sombras duras con offset. Cero blur decorativo.
   ══════════════════════════════════════════════════════════════ */

/* ─────────── TOKENS ─────────── */
:root{
  /* paleta — TEMA OSCURO (default) */
  --bg:        #0C0F16;
  --bg-alt:    #10141D;
  --surface:   #141924;
  --surface-2: #1A2030;
  --line:      #262E40;
  --line-soft: #1C2231;
  --fg:        #E8EBF2;
  --fg-mid:    #9BA3B8;
  --fg-dim:    #858DA3;        /* 5,78:1 sobre --bg — AA en texto chico */

  --accent:    #F7A8C4;
  --accent-2:  #FFC2D4;
  --accent-fg: #0C0F16;
  --accent-wash:rgba(247,168,196,.11);

  --pending:   #E8C547;         /* cert sin verificar */
  --pending-wash: rgba(232,197,71,.10);

  /* tipografía */
  --f-display: 'Bricolage Grotesque', ui-sans-serif, system-ui, sans-serif;
  --f-body:    'Inter Tight', ui-sans-serif, system-ui, sans-serif;
  --f-mono:    'JetBrains Mono', ui-monospace, 'SF Mono', monospace;

  /* forma */
  --r:      2px;               /* radio casi nulo: lenguaje impreso */
  --r-lg:   4px;
  --bw:     1px;
  --shadow:      4px 4px 0 var(--line);
  --shadow-hit:  6px 6px 0 var(--accent);
  --shadow-tight:3px 3px 0 var(--line);

  /* ritmo */
  --wrap:  1180px;
  --gut:   clamp(20px, 5vw, 64px);
  --sec-y: clamp(80px, 11vw, 160px);

  --ease: cubic-bezier(.22,1,.36,1);
  --t:    .45s var(--ease);
}

/* ─────────── TEMA CLARO: papel, no blanco plano ─────────── */
[data-theme="light"]{
  --bg:        #F4F6F9;
  --bg-alt:    #EBF0F5;
  --surface:   #FFFFFF;
  --surface-2: #E9EEF4;
  --line:      #D3DAE4;
  --line-soft: #E2E8F0;
  --fg:        #0C0F16;
  --fg-mid:    #565E6E;
  --fg-dim:    #666E7E;        /* 4,73:1 sobre --bg claro */

  --accent:    #C33A69;        /* rosa viejo: 4,70:1 como texto, 5,09:1 como fondo de boton */
  --accent-2:  #A82C57;
  --accent-fg: #FFFFFF;
  --accent-wash:rgba(195,58,105,.09);

  --pending:   #9A7B00;
  --pending-wash: rgba(154,123,0,.10);

  --shadow:      4px 4px 0 var(--line);
  --shadow-hit:  6px 6px 0 var(--accent);
}

/* ─────────── RESET ─────────── */
*,*::before,*::after{ box-sizing:border-box; margin:0; padding:0; }

html{ scroll-behavior:smooth; -webkit-text-size-adjust:100%; }

body{
  background:var(--bg);
  color:var(--fg);
  font-family:var(--f-body);
  font-size:clamp(15px,1.05vw,17px);
  line-height:1.62;
  font-weight:400;
  overflow-x:hidden;
  transition:background .5s var(--ease), color .5s var(--ease);
  -webkit-font-smoothing:antialiased;
}

body.locked{ overflow:hidden; }

img{ max-width:100%; display:block; }
a{ color:inherit; text-decoration:none; }
button{ font:inherit; color:inherit; background:none; border:0; cursor:pointer; }
ul{ list-style:none; }

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

.mono{
  font-family:var(--f-mono);
  font-size:.72rem;
  letter-spacing:.1em;
  text-transform:uppercase;
  font-weight:500;
}

.wrap{
  width:100%;
  max-width:var(--wrap);
  margin-inline:auto;
  padding-inline:var(--gut);
}

/* ══════════════════════════════════════════════════════════════
   LOADER
   ══════════════════════════════════════════════════════════════ */
.loader{
  position:fixed; inset:0; z-index:9000;
  background:var(--bg);
  display:grid; place-items:center;
  padding-inline:var(--gut);
}
.loader__inner{ width:min(560px,100%); }

.loader__name{
  font-family:var(--f-display);
  font-size:clamp(2rem,8.5vw,5.2rem);
  font-weight:700;
  line-height:1.02;
  letter-spacing:-.035em;
  display:flex; flex-wrap:wrap;
  column-gap:.28em;
  margin-bottom:26px;
}
/* la palabra es el bloque que hace wrap; las letras nunca se separan */
.loader__word{ display:inline-flex; white-space:nowrap; }
.loader__name .ch{
  display:inline-block;
  transform:translateY(105%);
  opacity:0;
  animation:letterIn .68s var(--ease) forwards;
}
@keyframes letterIn{ to{ transform:translateY(0); opacity:1; } }

.loader__meta{
  display:flex; justify-content:space-between; align-items:baseline;
  color:var(--fg-dim);
  margin-bottom:10px;
}
.loader__meta #loaderPct{ color:var(--accent); font-weight:700; }

.loader__track{
  height:2px; width:100%;
  background:var(--line);
  overflow:hidden;
}
.loader__bar{
  height:100%; width:0%;
  background:var(--accent);
  transition:width .18s linear;
}

/* wipe — un único barrido continuo: cubre desde la izquierda y descubre
   hacia la derecha sin corte entre medio. El cambio de transform-origin
   ocurre durante el hold, con la pantalla tapada: es invisible. */
.wipe{
  position:fixed; inset:0; z-index:9500;
  background:var(--accent);
  transform:scaleX(0);
  transform-origin:left center;
  pointer-events:none;
  will-change:transform;
}
.wipe.sweep{ animation:sweep .78s forwards; }

@keyframes sweep{
  0%{
    transform:scaleX(0); transform-origin:left center;
    animation-timing-function:cubic-bezier(.55,0,.35,1);   /* entra acelerando */
  }
  46%{ transform:scaleX(1); transform-origin:left center; }
  56%{
    transform:scaleX(1); transform-origin:right center;    /* hold: swap de origen */
    animation-timing-function:cubic-bezier(.16,1,.3,1);    /* sale disparado */
  }
  100%{ transform:scaleX(0); transform-origin:right center; }
}

/* ══════════════════════════════════════════════════════════════
   CURSOR
   ══════════════════════════════════════════════════════════════ */
.cursor-dot,.cursor-ring{
  position:fixed; top:0; left:0; z-index:9990;
  pointer-events:none;
  border-radius:50%;
  opacity:0;
}
.cursor-dot{
  width:6px; height:6px;
  background:var(--accent);
  transform:translate(-50%,-50%);
  transition:opacity .25s, width .2s var(--ease), height .2s var(--ease);
}
.cursor-ring{
  width:30px; height:30px;
  border:1px solid var(--fg-dim);
  transform:translate(-50%,-50%);
  transition:opacity .25s, width .3s var(--ease), height .3s var(--ease),
             border-color .3s, background .3s;
}
body.cursor-on .cursor-dot,
body.cursor-on .cursor-ring{ opacity:1; }

body.cur-link .cursor-ring{ width:52px; height:52px; border-color:var(--accent); background:var(--accent-wash); }
body.cur-link .cursor-dot{ width:0; height:0; }

body.cur-card .cursor-ring{ width:78px; height:78px; border-color:var(--accent); background:var(--accent-wash); }
body.cur-card .cursor-dot{ width:4px; height:4px; }

/* En pantallas táctiles el cursor de adorno no existe, así que el velo ya
   se muestra fijo (más abajo). Esto es sólo para mouse. */

body.cur-hidden .cursor-ring{ width:96px; height:96px; border-color:transparent; background:var(--accent); mix-blend-mode:difference; }
body.cur-hidden .cursor-dot{ width:0; height:0; }

@media (hover:none),(pointer:coarse){
  .cursor-dot,.cursor-ring{ display:none; }

  /* Sin mouse no hay :hover, así que la señal de "esto se toca" tiene que
     estar siempre a la vista. Abajo de 860px ya pasaba por ancho, pero una
     tablet de 1024px se quedaba sin hover Y sin señal. */
  .proj__veil{ opacity:1; }
  .proj__veil .btn{ transform:none; }
  .proj__title::after{ opacity:1; transform:none; }
}

/* ══════════════════════════════════════════════════════════════
   NAV
   ══════════════════════════════════════════════════════════════ */
.nav{
  position:fixed; top:0; left:0; right:0; z-index:800;
  display:flex; align-items:center; justify-content:space-between;
  gap:20px;
  padding:16px var(--gut);
  border-bottom:var(--bw) solid transparent;
  transition:background .35s var(--ease), border-color .35s var(--ease), padding .35s var(--ease);
}
.nav.solid{
  background:var(--bg);
  border-bottom-color:var(--line);
  padding-block:11px;
}

.nav__logo{ display:flex; align-items:center; gap:9px; flex-shrink:0; position:relative; z-index:3; }
.nav__logo-mark{
  display:grid; place-items:center;
  width:28px; height:28px;
  background:var(--accent); color:var(--accent-fg);
  font-family:var(--f-display); font-weight:800; font-size:16px;
  border-radius:var(--r);
  transition:transform .35s var(--ease);
}
.nav__logo:hover .nav__logo-mark{ transform:rotate(-8deg) scale(1.08); }
.nav__logo-text{
  font-family:var(--f-display);
  font-weight:600; font-size:1.02rem; letter-spacing:-.02em;
}

.nav__links{ display:flex; gap:26px; }
.nav__links a{
  font-size:.86rem; font-weight:500;
  color:var(--fg-mid);
  position:relative;
  padding-block:4px;
  transition:color .25s;
}
.nav__links a::after{
  content:''; position:absolute; left:0; bottom:0;
  width:100%; height:1px; background:var(--accent);
  transform:scaleX(0); transform-origin:right;
  transition:transform .38s var(--ease);
}
.nav__links a:hover,.nav__links a.on{ color:var(--fg); }
.nav__links a:hover::after,.nav__links a.on::after{ transform:scaleX(1); transform-origin:left; }

.nav__tools{ display:flex; align-items:center; gap:10px; flex-shrink:0; position:relative; z-index:3; }

.toggle{
  position:relative;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface);
  display:flex; align-items:center;
  transition:border-color .3s;
}
.toggle:hover{ border-color:var(--accent); }

.toggle--lang{ padding:3px; }
.toggle__opt{
  position:relative; z-index:2;
  font-family:var(--f-mono); font-size:.66rem; font-weight:700; letter-spacing:.06em;
  padding:4px 9px;
  color:var(--fg-dim);
  transition:color .3s var(--ease);
}
.toggle__opt.on{ color:var(--accent-fg); }
.toggle__pill{
  position:absolute; z-index:1;
  top:3px; bottom:3px; left:3px;
  width:calc(50% - 3px);
  background:var(--accent);
  border-radius:1px;
  transition:transform .38s var(--ease);
}
.toggle--lang.en .toggle__pill{ transform:translateX(100%); }

.toggle--theme{
  width:34px; height:31px;
  justify-content:center;
  color:var(--fg-mid);
}
.toggle--theme:hover{ color:var(--accent); }
.ico{ width:16px; height:16px; position:absolute; transition:opacity .3s, transform .4s var(--ease); }
.ico--sun { opacity:1; transform:rotate(0); }
.ico--moon{ opacity:0; transform:rotate(-90deg); }
[data-theme="light"] .ico--sun { opacity:0; transform:rotate(90deg); }
[data-theme="light"] .ico--moon{ opacity:1; transform:rotate(0); }

.nav__burger{ display:none; flex-direction:column; gap:5px; width:34px; height:31px;
  align-items:center; justify-content:center; border:var(--bw) solid var(--line); border-radius:var(--r); }
.nav__burger span{ display:block; width:15px; height:1.5px; background:var(--fg); transition:transform .35s var(--ease), opacity .25s; }
.nav__burger.on span:nth-child(1){ transform:translateY(3.25px) rotate(45deg); }
.nav__burger.on span:nth-child(2){ transform:translateY(-3.25px) rotate(-45deg); }

/* ══════════════════════════════════════════════════════════════
   HERO
   ══════════════════════════════════════════════════════════════ */
.hero{
  position:relative;
  min-height:100svh;
  display:flex; align-items:center;
  padding-top:110px; padding-bottom:90px;
  overflow:hidden;
}
.hero__grid{
  position:absolute; inset:0;
  background-image:
    linear-gradient(to right, var(--line-soft) 1px, transparent 1px),
    linear-gradient(to bottom, var(--line-soft) 1px, transparent 1px);
  background-size:clamp(48px,7vw,92px) clamp(48px,7vw,92px);
  -webkit-mask-image:radial-gradient(ellipse 80% 62% at 50% 42%, #000 20%, transparent 78%);
          mask-image:radial-gradient(ellipse 80% 62% at 50% 42%, #000 20%, transparent 78%);
  opacity:.9;
  pointer-events:none;
}
.hero__wrap{ position:relative; z-index:2; }

.status{
  display:inline-flex; align-items:center; gap:9px;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface);
  padding:6px 13px;
  color:var(--fg-mid);
  margin-bottom:28px;
}
.status__dot{
  width:7px; height:7px; border-radius:50%;
  background:var(--accent);
  position:relative; flex-shrink:0;
}
.status__dot::after{
  content:''; position:absolute; inset:0;
  border-radius:50%; background:var(--accent);
  animation:ping 1.9s var(--ease) infinite;
}
@keyframes ping{ 0%{ transform:scale(1); opacity:.7; } 70%,100%{ transform:scale(3); opacity:0; } }

.hero__name{
  font-family:var(--f-display);
  font-size:clamp(3rem,12.5vw,9.5rem);
  font-weight:700;
  line-height:.86;
  letter-spacing:-.045em;
  margin-bottom:22px;
}
.hero__line{ display:block; }
.hero__line--out{
  color:transparent;
  -webkit-text-stroke:1.5px var(--fg-mid);
  padding-left:.06em;
}

.hero__type{
  font-family:var(--f-mono);
  font-size:clamp(.95rem,2.1vw,1.4rem);
  font-weight:500;
  color:var(--accent);
  min-height:1.7em;
  margin-bottom:26px;
  letter-spacing:-.01em;
}
.caret{
  display:inline-block;
  width:.58em; height:1.05em;
  background:var(--accent);
  vertical-align:-.16em;
  margin-left:.12em;
  animation:blink 1s steps(2,start) infinite;
}
@keyframes blink{ 0%,50%{ opacity:1; } 50.01%,100%{ opacity:0; } }

.hero__bio{
  max-width:63ch;
  color:var(--fg-mid);
  font-size:1.02rem;
  margin-bottom:36px;
}

.hero__cta{ display:flex; flex-wrap:wrap; gap:12px; margin-bottom:36px; }

.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:8px;
  font-family:var(--f-mono);
  font-size:.76rem; font-weight:700;
  letter-spacing:.08em; text-transform:uppercase;
  padding:14px 26px;
  border:var(--bw) solid var(--fg);
  border-radius:var(--r);
  transition:transform .28s var(--ease), box-shadow .28s var(--ease),
             background .28s, color .28s, border-color .28s;
}
.btn--solid{ background:var(--accent); color:var(--accent-fg); border-color:var(--accent); box-shadow:var(--shadow-tight); }
.btn--solid:hover{ transform:translate(-2px,-2px); box-shadow:5px 5px 0 var(--fg); }
.btn--ghost{ background:transparent; color:var(--fg); border-color:var(--line); }
.btn--ghost:hover{ border-color:var(--accent); color:var(--accent); transform:translate(-2px,-2px); box-shadow:4px 4px 0 var(--accent); }
.btn svg{ width:15px; height:15px; flex-shrink:0; }
.btn--sm{ padding:11px 20px; font-size:.7rem; }
.btn--full{ width:100%; }

.hero__pills{ display:flex; flex-wrap:wrap; gap:9px; }
.pill{
  display:inline-flex; align-items:center; gap:8px;
  font-family:var(--f-mono); font-size:.72rem; letter-spacing:.05em;
  padding:9px 15px;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  color:var(--fg-mid);
  background:var(--surface);
  transition:color .25s, border-color .25s, transform .25s var(--ease), background .25s;
}
.pill svg{ width:14px; height:14px; }
.pill:hover{ color:var(--accent); border-color:var(--accent); transform:translateY(-2px); }

.hero__scroll{
  position:absolute; right:var(--gut); bottom:34px; z-index:2;
  color:var(--fg-dim);
  writing-mode:vertical-rl;
  display:flex; align-items:center; gap:12px;
}
.hero__scroll::after{
  content:''; width:1px; height:52px;
  background:linear-gradient(var(--fg-dim),transparent);
}

/* ══════════════════════════════════════════════════════════════
   SECCIONES
   ══════════════════════════════════════════════════════════════ */
.sec{ padding-block:var(--sec-y); position:relative; }
.sec--alt{ background:var(--bg-alt); border-block:var(--bw) solid var(--line-soft); }

.sec__head{
  display:flex; align-items:center; gap:18px;
  margin-bottom:clamp(38px,5vw,66px);
}
.sec__num{ color:var(--accent); font-weight:700; }
.sec__title{
  font-family:var(--f-display);
  font-size:clamp(1.9rem,5vw,3.4rem);
  font-weight:700; letter-spacing:-.035em; line-height:1;
}
.sec__rule{ flex:1; height:1px; background:var(--line); }

/* reveal
   Se oculta SOLO si el JS esta vivo: script.js pone .js en <html> apenas
   arranca. Sin eso, un error de JS o los scripts bloqueados dejarian las 28
   secciones invisibles para siempre. Mas abajo, el bloque @supports revela
   todo por CSS en los navegadores que soportan scroll-driven animations, asi
   que el JS solo hace falta en Firefox y en navegadores viejos. */
.js .reveal{ opacity:0; transform:translateY(26px); transition:opacity .8s var(--ease), transform .8s var(--ease); }
.js .reveal.vis{ opacity:1; transform:none; }

/* ─────────── ABOUT ─────────── */
.about{
  display:grid;
  grid-template-columns:1.25fr .95fr;
  gap:clamp(30px,5vw,68px);
  align-items:start;
}
.about__text p{ color:var(--fg-mid); font-size:1.03rem; }
.about__text p + p{ margin-top:19px; }

.specs{ border-top:var(--bw) solid var(--line); }
.specs__row{
  display:grid; grid-template-columns:96px 1fr;
  gap:14px; align-items:baseline;
  padding:13px 2px;
  border-bottom:var(--bw) solid var(--line);
  transition:background .3s, padding-left .3s var(--ease);
}
.specs__row:hover{ background:var(--accent-wash); padding-left:10px; }
.specs__row dt{ color:var(--fg-dim); }
.specs__row dd{ font-size:.94rem; word-break:break-word; }
.specs__row dd a{ border-bottom:1px solid var(--line); transition:color .25s, border-color .25s; }
.specs__row dd a:hover{ color:var(--accent); border-color:var(--accent); }
.specs__live{ display:flex; align-items:center; gap:9px; }

/* ─────────── STACK ─────────── */
.stack{
  display:grid;
  grid-template-columns:repeat(auto-fill,minmax(238px,1fr));
  gap:14px;
}
.sk{
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface);
  padding:20px;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s;
}
.sk:hover{ transform:translate(-3px,-3px); box-shadow:var(--shadow-hit); border-color:var(--accent); }

.sk__top{ display:flex; align-items:center; gap:12px; margin-bottom:16px; }
.sk__logo{ line-height:1; flex-shrink:0; }
/* Los logos son SVG inline con su color de marca propio. Antes venian de
   devicon por CDN: 130 KB bloqueantes, y apuntados a @latest, o sea que un
   cambio de ellos podia romper esta seccion sin tocar nada del sitio. */
.sk__logo svg{ display:block; width:28px; height:28px; }
.sk__name{ font-family:var(--f-display); font-weight:600; font-size:1.02rem; letter-spacing:-.015em; }
.sk__level{ font-family:var(--f-mono); font-size:.63rem; letter-spacing:.09em; text-transform:uppercase; color:var(--fg-dim); }
.sk__pct{ margin-left:auto; font-family:var(--f-mono); font-size:.82rem; font-weight:700; color:var(--accent); }

.sk__track{ height:3px; background:var(--surface-2); border-radius:0; overflow:hidden; }
[data-theme="light"] .sk__track{ background:var(--line-soft); }
.sk__bar{
  height:100%; width:0;
  background:var(--accent);
  transition:width 1.15s var(--ease);
}

/* ─────────── CERTIFICADOS ─────────── */
.cert-pair{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:16px;
  margin-bottom:16px;
  align-items:stretch;
}
.cert-pair--rev .cert{ order:2; }
.cert-pair--rev .pdf{ order:1; }
.cert-solo{ display:grid; grid-template-columns:1fr 1fr; gap:16px; }
.cert-solo .cert{ grid-column:1 / -1; max-width:none; }

.cert{
  position:relative;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface);
  padding:clamp(24px,3.2vw,36px);
  overflow:hidden;
  transition:transform .35s var(--ease), box-shadow .35s var(--ease), border-color .35s;
}
.cert:hover{ transform:translate(-3px,-3px); box-shadow:var(--shadow-hit); border-color:var(--accent); }

.cert__corner{
  position:absolute; width:13px; height:13px;
  border:2px solid var(--accent);
  transition:width .35s var(--ease), height .35s var(--ease);
}
.cert__corner--tl{ top:9px;  left:9px;  border-right:0; border-bottom:0; }
.cert__corner--tr{ top:9px;  right:9px; border-left:0;  border-bottom:0; }
.cert__corner--bl{ bottom:9px; left:9px; border-right:0; border-top:0; }
.cert__corner--br{ bottom:9px; right:9px; border-left:0; border-top:0; }
.cert:hover .cert__corner{ width:22px; height:22px; }

/* ─────────── LA DIPLOMATURA, DESTACADA ───────────
   Es el título más pesado que hay acá: 186 horas contra las 93 del curso, y
   emitido por una universidad nacional. Se distingue por estructura y por
   datos duros —carga horaria, modalidad, resultado— más que por adornos:
   lo que convence a quien lee es el número, no el brillo. */
.cert--destacada{
  border-color:var(--accent);
  box-shadow:0 0 0 1px var(--accent-wash), 0 22px 60px -34px var(--accent);
}
[data-theme="light"] .cert--destacada{ box-shadow:0 0 0 1px var(--accent-wash), 0 18px 44px -30px var(--accent); }

/* Filo superior encendido. */
.cert--destacada::after{
  content:"";
  position:absolute; inset:0 0 auto 0; height:2px;
  background:linear-gradient(90deg, var(--accent), var(--accent-2), var(--accent));
  z-index:4;
}

/* Un reflejo que cruza cada tanto. Lento y espaciado a propósito: si pasa
   seguido deja de leerse como un detalle y se vuelve ruido. */
.cert--destacada::before{
  content:"";
  position:absolute; inset:0;
  background:linear-gradient(115deg, transparent 38%, var(--accent-wash) 47%, transparent 58%);
  transform:translateX(-115%);
  animation:reflejoDiploma 9s var(--ease) infinite;
  pointer-events:none; z-index:1;
}
@keyframes reflejoDiploma{
  0%, 78%{ transform:translateX(-115%); }
  100%   { transform:translateX(115%); }
}

.cert--destacada .cert__ring{ border-color:var(--accent); opacity:.55; }

/* ─────────── EL CURSO, COMO MÓDULO DE LA DIPLOMATURA ───────────
   No son dos títulos sueltos: según la propia UTN la diplomatura se compone
   de dos cursos nivelados, y este es el primero. Los 93 h de acá están
   incluidos en los 186 h de arriba, no se suman. Se marca con un riel de
   acento a la izquierda, que ata visualmente esta ficha con la de arriba
   sin robarle protagonismo. */
.cert--modulo{
  border-left-width:3px;
  border-left-color:var(--accent);
}
.cert--modulo .cert__ring{ border-color:var(--accent); opacity:.3; }

/* Cinta en tono apagado: es un módulo, no el título principal. */
.cert__cinta--modulo{
  color:var(--accent);
  background:var(--accent-wash);
  border-left:var(--bw) solid var(--accent);
  border-bottom:var(--bw) solid var(--accent);
}

/* La frase que explica de qué se compone la diplomatura. */
.cert__trayecto{
  position:relative; z-index:2;
  margin:-6px 0 16px;
  padding-left:13px;
  border-left:2px solid var(--accent);
  font-size:.68rem; line-height:1.6;
  color:var(--fg-mid);
}

/* Cinta: dice de qué categoría es el título antes de leer nada más. */
.cert__cinta{
  position:absolute; z-index:3;
  top:0; right:0;
  padding:6px 13px 7px;
  font-size:.6rem; font-weight:700;
  letter-spacing:.14em; text-transform:uppercase;
  color:var(--accent-fg); background:var(--accent);
  border-bottom-left-radius:var(--r);
}

/* Medalla. Es un sello académico genérico, no el escudo de la UTN: el
   nombre de la casa ya está escrito abajo y no hace falta imitar su marca. */
.cert__medalla{
  position:relative; z-index:2;
  display:inline-flex; color:var(--accent);
}
.cert__medalla svg{ width:30px; height:30px; }

.cert__facu{
  display:block;
  margin-top:3px;
  font-family:var(--f-mono); font-size:.68rem; letter-spacing:.02em;
  color:var(--fg-dim); font-weight:400;
}

/* Los datos del propio diploma, en fila. */
.cert__datos{
  position:relative; z-index:2;
  display:flex; flex-wrap:wrap; gap:10px;
  margin:0 0 16px;
}
.cert__datos > div{
  flex:1 1 96px;
  padding:9px 11px;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--bg);
}
.cert__datos dt{
  font-size:.56rem; letter-spacing:.12em; text-transform:uppercase;
  color:var(--fg-dim); margin-bottom:4px;
}
.cert__datos dd{
  margin:0;
  font-size:.86rem; font-weight:700; color:var(--accent);
}

@media (prefers-reduced-motion:reduce){
  .cert--destacada::before{ animation:none; opacity:0; }
}

.cert__ring{
  position:absolute; right:-70px; top:-70px;
  width:200px; height:200px;
  border:1px dashed var(--line);
  border-radius:50%;
  animation:spin 26s linear infinite;
  pointer-events:none;
}
.cert__ring::before{
  content:''; position:absolute; inset:26px;
  border:1px solid var(--accent-wash); border-radius:50%;
}
.cert__ring::after{
  content:''; position:absolute; top:-3px; left:calc(50% - 3px);
  width:6px; height:6px; border-radius:50%;
  background:var(--accent);
}
@keyframes spin{ to{ transform:rotate(360deg); } }

.cert__top{ position:relative; z-index:2; display:flex; align-items:center; gap:11px; margin-bottom:16px; flex-wrap:wrap; }
/* ─────────── SELLO DE LA UTN ───────────
   Es el logotipo real, sacado del propio certificado que está embebido acá
   al lado: el PDF trae el diseño como imagen, así que se rasterizó a 3200px
   y se recortó el bloque UTN.BA. No es una reproducción dibujada a mano.

   El PNG es una silueta con transparencia y el color lo pone el CSS por
   máscara. Así el mismo archivo sirve en los dos temas sin recuadro blanco
   de por medio. Va en crema y no en el rojo institucional porque ese rojo
   da 3,38:1 contra el fondo oscuro y la letra chica del logo —"universidad
   tecnológica nacional / facultad regional buenos aires"— quedaría
   ilegible. El rojo entra como luz, que se ve y no estorba. */
.cert__sello-utn{
  position:relative; z-index:2;
  display:block;
  width:132px; height:37px;
  background-color:var(--fg);
  -webkit-mask:url(images/utn-ba.png) left center/contain no-repeat;
          mask:url(images/utn-ba.png) left center/contain no-repeat;
  filter:drop-shadow(0 0 5px rgba(191,47,39,.65))
         drop-shadow(0 0 13px rgba(191,47,39,.35));
}

/* En la ficha destacada, un poco más grande y con la luz más encendida. */
.cert--destacada .cert__sello-utn{
  width:152px; height:43px;
  filter:drop-shadow(0 0 6px rgba(191,47,39,.8))
         drop-shadow(0 0 16px rgba(191,47,39,.45));
}

/* En papel el resplandor rojo se ensucia sobre el fondo claro: se apaga y
   queda la marca en tinta. */
[data-theme="light"] .cert__sello-utn{
  filter:drop-shadow(0 1px 0 rgba(191,47,39,.35));
}

@media (prefers-reduced-motion:reduce){
  .cert__sello-utn{ filter:none; }
}

.cert__badge{
  background:var(--accent); color:var(--accent-fg);
  padding:5px 11px; border-radius:var(--r);
  font-weight:700; font-size:.68rem;
}
.cert__year{ color:var(--fg-dim); }

.cert__title{
  position:relative; z-index:2;
  font-family:var(--f-display);
  font-size:clamp(1.3rem,2.6vw,1.85rem);
  font-weight:700; letter-spacing:-.03em; line-height:1.08;
  margin-bottom:5px;
}
.cert__org{ position:relative; z-index:2; color:var(--accent); font-size:.9rem; font-weight:500; margin-bottom:14px; }
.cert__desc{ position:relative; z-index:2; color:var(--fg-mid); font-size:.94rem; margin-bottom:18px; max-width:52ch; }

.cert__seal{
  position:relative; z-index:2;
  display:inline-flex; align-items:center; gap:9px;
  margin-top:18px;
  font-family:var(--f-mono); font-size:.67rem; letter-spacing:.06em; text-transform:uppercase;
  padding:8px 13px; border-radius:var(--r);
  border:var(--bw) solid;
}
.cert__seal svg{ width:13px; height:13px; }
.cert__seal--ok  { color:var(--accent);  border-color:var(--accent);  background:var(--accent-wash); }
.cert__seal--wait{ color:var(--pending); border-color:var(--pending); background:var(--pending-wash); }
.cert__hourglass{ animation:tilt 2.6s var(--ease) infinite; display:inline-block; }
@keyframes tilt{ 0%,60%,100%{ transform:rotate(0); } 70%{ transform:rotate(180deg); } }

/* cert pendiente: acento propio */
.cert--pending{ border-color:var(--pending); background:linear-gradient(var(--pending-wash),var(--pending-wash)) var(--surface); }
.cert--pending:hover{ box-shadow:6px 6px 0 var(--pending); border-color:var(--pending); }
.cert--pending .cert__corner{ border-color:var(--pending); }
.cert--pending .cert__badge{ background:var(--pending); color:var(--accent-fg); }
.cert--pending .cert__org{ color:var(--pending); }
.cert--pending .cert__ring::after{ background:var(--pending); }

/* PDF embed */
.pdf{
  display:flex; flex-direction:column;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface-2);
  overflow:hidden;
  min-height:420px;
  transition:border-color .35s, box-shadow .35s var(--ease);
}
.pdf:hover{ border-color:var(--accent); box-shadow:var(--shadow-tight); }
.pdf__bar{
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:11px 15px;
  border-bottom:var(--bw) solid var(--line);
  background:var(--surface);
}
.pdf__bar .mono{ color:var(--fg-dim); font-size:.65rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.pdf__dl{
  display:inline-flex; align-items:center; gap:7px; flex-shrink:0;
  font-family:var(--f-mono); font-size:.65rem; letter-spacing:.07em; text-transform:uppercase; font-weight:700;
  color:var(--accent-fg); background:var(--accent);
  padding:6px 12px; border-radius:var(--r);
  transition:transform .25s var(--ease), box-shadow .25s var(--ease);
}
.pdf__dl svg{ width:12px; height:12px; }
.pdf__dl:hover{ transform:translate(-2px,-2px); box-shadow:3px 3px 0 var(--fg); }
.pdf__frame{ flex:1; width:100%; border:0; background:var(--surface-2); min-height:380px; }

/* tags */
.tags{ display:flex; flex-wrap:wrap; gap:7px; position:relative; z-index:2; }
.tag{
  font-family:var(--f-mono); font-size:.64rem; letter-spacing:.06em; text-transform:uppercase;
  padding:5px 10px;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  color:var(--fg-mid);
  transition:color .25s, border-color .25s;
}
.tag:hover{ color:var(--accent); border-color:var(--accent); }

/* ─────────── PROYECTOS / EXPERIENCIA ─────────── */
.proj{
  /* Sin esto la tarjeta entera se comporta como un clic pero muestra la
     flecha normal del sistema: no hay forma de saber que se puede tocar. */
  cursor:pointer;
  display:grid;
  grid-template-columns:1.05fr 1fr;
  gap:clamp(22px,3.4vw,46px);
  align-items:center;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface);
  padding:clamp(18px,2.4vw,26px);
  margin-bottom:20px;
  transition:transform .38s var(--ease), box-shadow .38s var(--ease), border-color .38s;
}
.proj:last-child{ margin-bottom:0; }
.proj:hover{ transform:translate(-4px,-4px); box-shadow:var(--shadow-hit); border-color:var(--accent); }


/* ─────────── GRILLA DE PROYECTOS ───────────
   Las seis en dos columnas. Esta sección se sale del ancho de lectura del
   resto del sitio: con tarjetas de una columna, 1180px dejaba 250px muertos
   a cada lado y las imágenes quedaban chicas para lo que tienen que mostrar. */
#projects .wrap{ max-width:1560px; }

.proj-grid{
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:22px;
}

.proj-grid .proj{
  /* Imagen arriba, texto abajo. */
  grid-template-columns:1fr;
  gap:14px;
  margin-bottom:0;
  padding:clamp(14px,1.3vw,18px);
  align-items:start;
}

.proj-grid .proj__title{ font-size:clamp(1.2rem,1.7vw,1.62rem); }
.proj-grid .proj__idx{ margin-bottom:7px; }
.proj-grid .proj__desc{
  font-size:.9rem;
  margin-bottom:12px;
  /* Tres líneas y corta: con seis tarjetas en grilla, los bloques de texto
     desparejos hacen que las filas se vean rotas. El texto completo sigue
     estando en el modal. */
  display:-webkit-box; -webkit-line-clamp:3; -webkit-box-orient:vertical;
  overflow:hidden;
}
.proj-grid .tag{ font-size:.62rem; }

/* ─────────── ENLACES DIRECTOS DE CADA PROYECTO ───────────
   Están en el HTML y no sólo en el modal porque los filtros de currículums
   y los buscadores leen el marcado; el modal lo arma JavaScript y para ellos
   no existe. De paso el visitante llega al código sin un clic de más. */
.proj__links{
  display:flex; flex-wrap:wrap; gap:8px 14px;
  margin-top:2px;
}
.proj__link{
  font-family:var(--f-mono); font-size:.64rem;
  letter-spacing:.06em; text-transform:uppercase;
  color:var(--fg-dim); text-decoration:none;
  border-bottom:1px solid transparent;
  transition:color var(--t), border-color var(--t);
}
.proj__link::after{ content:" \2197"; }
.proj__link:hover,
.proj__link:focus-visible{ color:var(--accent); border-bottom-color:var(--accent); }

@media (max-width:900px){
  #projects .wrap{ max-width:var(--wrap); }
  .proj-grid{ grid-template-columns:1fr; gap:20px; }
  .proj-grid .proj__desc{ -webkit-line-clamp:none; display:block; overflow:visible; }
}

.proj__media{
  position:relative;
  /* 2:1. Todas las portadas están exportadas exactamente en esta proporción,
     así object-fit:cover no recorta nada en ninguna. */
  aspect-ratio:2/1;
  overflow:hidden;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--bg);
}
.proj__media img{
  width:100%; height:100%; object-fit:cover; object-position:top center;
  transition:transform .7s var(--ease), filter .45s var(--ease);
}
.proj:hover .proj__media img{ transform:scale(1.045); filter:brightness(.32) saturate(.7); }

.proj__veil button{ font:inherit; cursor:pointer; }
.proj__veil{
  position:absolute; inset:0;
  display:grid; place-items:center;
  opacity:0;
  transition:opacity .38s var(--ease);
}
.proj:hover .proj__veil{ opacity:1; }
.proj__veil .btn{ transform:translateY(10px); transition:transform .42s var(--ease); }
.proj:hover .proj__veil .btn{ transform:translateY(0); }

/* poster fallback (proyectos sin captura) */
.poster{
  width:100%; height:100%;
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:12px;
  background:
    repeating-linear-gradient(-45deg, var(--line-soft) 0 1px, transparent 1px 13px),
    var(--surface-2);
  transition:filter .45s var(--ease);
}
.proj:hover .poster{ filter:brightness(.4); }
.poster__num{
  font-family:var(--f-display);
  font-size:clamp(3rem,7vw,5.4rem);
  font-weight:800; line-height:1; letter-spacing:-.05em;
  color:transparent; -webkit-text-stroke:1.5px var(--accent);
}
.poster__label{ color:var(--fg-dim); }

.proj__idx{ color:var(--accent); font-weight:700; display:block; margin-bottom:12px; }
.proj__kicker{ color:var(--fg-dim); margin-bottom:8px; }
.proj__title{
  font-family:var(--f-display);
  font-size:clamp(1.45rem,3.2vw,2.3rem);
  font-weight:700; letter-spacing:-.035em; line-height:1.04;
  margin-bottom:12px;
}
.proj__desc{ color:var(--fg-mid); font-size:.97rem; margin-bottom:18px; }

/* Al pasar por encima, el título se tiñe y le aparece una flecha. En las
   tarjetas chicas el cartel "Ver proyecto" queda sobre la imagen, arriba
   del todo, así que si estás leyendo el texto no ves ninguna señal. Esta sí
   aparece justo donde tenés la vista. */
.proj__title{ transition:color .28s var(--ease); }
.proj__title::after{
  content:"↗";
  display:inline-block;
  margin-left:.32em;
  opacity:0; transform:translate(-4px,3px);
  transition:opacity .3s var(--ease), transform .3s var(--ease);
}
.proj:hover .proj__title,
.proj:focus-within .proj__title{ color:var(--accent); }
.proj:hover .proj__title::after,
.proj:focus-within .proj__title::after{ opacity:1; transform:translate(0,0); }

.proj--link .proj__title{ display:inline-flex; align-items:baseline; gap:.3em; flex-wrap:wrap; }
.proj--link:hover .proj__title{ color:var(--accent); }

/* ─────────── CONTACTO ─────────── */
.contact{
  display:grid;
  grid-template-columns:1fr 1.05fr;
  gap:clamp(26px,4vw,56px);
  align-items:start;
}
.contact__lead{ color:var(--fg-mid); font-size:1.03rem; margin-bottom:24px; max-width:40ch; }

.ccard{
  display:flex; align-items:center; gap:15px;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface);
  padding:16px 18px;
  margin-bottom:11px;
  transition:transform .3s var(--ease), box-shadow .3s var(--ease), border-color .3s;
}
.ccard:hover{ transform:translate(-3px,-3px); box-shadow:var(--shadow-hit); border-color:var(--accent); }
.ccard__ico{
  display:grid; place-items:center; flex-shrink:0;
  width:38px; height:38px;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  color:var(--accent);
  transition:background .3s, color .3s, border-color .3s;
}
.ccard:hover .ccard__ico{ background:var(--accent); color:var(--accent-fg); border-color:var(--accent); }
.ccard__ico svg{ width:17px; height:17px; }
.ccard__txt{ display:flex; flex-direction:column; gap:2px; min-width:0; }
.ccard__label{ color:var(--fg-dim); font-size:.62rem; }
.ccard__val{ font-size:.92rem; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.ccard__arrow{ margin-left:auto; color:var(--fg-dim); font-size:1.05rem; transition:transform .3s var(--ease), color .3s; }
.ccard:hover .ccard__arrow{ color:var(--accent); transform:translate(3px,-3px); }

.contact__form{
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface);
  padding:clamp(22px,3vw,32px);
}
.field{ margin-bottom:17px; }
.field label{ display:block; color:var(--fg-dim); margin-bottom:7px; }
.field input,.field textarea{
  width:100%;
  font-family:var(--f-body); font-size:.95rem;
  color:var(--fg);
  background:var(--bg);
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  padding:12px 14px;
  transition:border-color .28s, box-shadow .28s var(--ease);
  resize:vertical;
}
.field input::placeholder,.field textarea::placeholder{ color:var(--fg-dim); }
.field input:focus,.field textarea:focus{
  outline:0;
  border-color:var(--accent);
  box-shadow:3px 3px 0 var(--accent);
}
.field input:user-invalid,.field textarea:user-invalid{ border-color:#E0553B; }

.form__note{
  font-family:var(--f-mono); font-size:.7rem; letter-spacing:.05em;
  margin-top:13px; min-height:1.2em;
  color:var(--fg-dim);
}
.form__note.ok  { color:var(--accent); }
.form__note.err { color:#E0553B; }

/* ─────────── FOOTER ─────────── */
.foot{ border-top:var(--bw) solid var(--line); padding-block:28px; }
.foot__wrap{ display:flex; align-items:center; justify-content:space-between; gap:16px; flex-wrap:wrap; }
.foot .mono{ color:var(--fg-dim); font-size:.68rem; }
.foot__right{ text-align:right; }

/* ══════════════════════════════════════════════════════════════
   MODAL
   ══════════════════════════════════════════════════════════════ */
.modal{
  position:fixed; inset:0; z-index:9700;
  display:grid; place-items:center;
  padding:var(--gut);
  opacity:0; visibility:hidden;
  transition:opacity .35s var(--ease), visibility .35s;
}
.modal.open{ opacity:1; visibility:visible; }
.modal__backdrop{ position:absolute; inset:0; background:rgba(0,0,0,.72); }
[data-theme="light"] .modal__backdrop{ background:rgba(20,20,15,.55); }

.modal__panel{
  position:relative;
  width:min(880px,100%);
  max-height:88vh;
  overflow-y:auto;
  background:var(--bg-alt);
  border:var(--bw) solid var(--accent);
  border-radius:var(--r-lg);
  box-shadow:8px 8px 0 var(--accent);
  transform:translateY(24px) scale(.985);
  transition:transform .42s var(--ease);
}
.modal.open .modal__panel{ transform:none; }

.modal__x{
  position:absolute; top:12px; right:12px; z-index:3;
  width:34px; height:34px;
  display:grid; place-items:center;
  background:var(--bg); color:var(--fg);
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  font-size:.9rem;
  transition:background .25s, color .25s, transform .3s var(--ease);
}
.modal__x:hover{ background:var(--accent); color:var(--accent-fg); border-color:var(--accent); transform:rotate(90deg); }

.modal__media{ border-bottom:var(--bw) solid var(--line); background:var(--surface-2); }
.modal__media img{ width:100%; max-height:46vh; object-fit:cover; object-position:top center; }
.modal__media .poster{ aspect-ratio:16/8; }

.modal__body{ padding:clamp(24px,3.5vw,38px); }
.modal__title{
  font-family:var(--f-display);
  font-size:clamp(1.6rem,3.6vw,2.4rem);
  font-weight:700; letter-spacing:-.035em; line-height:1.05;
  margin-bottom:14px;
}
.modal__desc{ color:var(--fg-mid); font-size:1rem; margin-bottom:20px; }
/* Aviso de la demo (arranque en frio del plan gratuito). Ambar, no rojo:
   no es un error, es algo que conviene saber antes de hacer clic. */
.modal__note{
  display:flex; gap:9px; align-items:flex-start;
  font-family:var(--f-mono); font-size:.72rem; line-height:1.55;
  color:var(--pending);
  background:var(--pending-wash);
  border-left:2px solid var(--pending);
  padding:11px 13px; margin-bottom:4px;
}
.modal__note[hidden]{ display:none; }
.modal__note::before{ content:"!"; font-weight:700; flex-shrink:0; }
.modal__cta{ display:flex; flex-wrap:wrap; gap:11px; margin-top:22px; }

/* ══════════════════════════════════════════════════════════════
   RESPONSIVE
   ══════════════════════════════════════════════════════════════ */
@media (max-width:1000px){
  .about{ grid-template-columns:1fr; }
  .contact{ grid-template-columns:1fr; }
  .cert-pair,.cert-pair--rev,.cert-solo{ grid-template-columns:1fr; }
  .cert-pair--rev .cert{ order:0; }
  .cert-pair--rev .pdf{ order:0; }
  .pdf{ min-height:520px; }
}

@media (max-width:860px){
  .nav__links{
    position:fixed; inset:0 0 auto 0;
    top:0; padding:96px var(--gut) 40px;
    flex-direction:column; gap:4px;
    background:var(--bg);
    border-bottom:var(--bw) solid var(--line);
    transform:translateY(-102%);
    transition:transform .5s var(--ease);
    z-index:1;
  }
  .nav__links.open{ transform:translateY(0); }
  .nav__links a{ font-size:1.5rem; font-family:var(--f-display); font-weight:600; color:var(--fg); padding-block:11px; border-bottom:var(--bw) solid var(--line-soft); }
  .nav__links a::after{ display:none; }
  .nav__burger{ display:flex; }
  .nav{ background:var(--bg); border-bottom-color:var(--line); }

  .proj{ grid-template-columns:1fr; }
      .proj__veil{ opacity:1; background:transparent; align-items:end; padding-bottom:14px; }
  .proj__veil .btn{ transform:none; }
  .proj:hover .proj__media img{ filter:none; transform:none; }
  .proj:hover .poster{ filter:none; }
  .proj:hover{ transform:none; box-shadow:none; }

  .hero__scroll{ display:none; }
  .foot__wrap{ justify-content:center; text-align:center; }
  .foot__right{ text-align:center; }
}

@media (max-width:560px){
  .stack{ grid-template-columns:1fr; }
  .specs__row{ grid-template-columns:1fr; gap:3px; }
  .hero__cta .btn{ flex:1 1 100%; }
  .sec__head{ flex-wrap:wrap; gap:11px; }
  .sec__rule{ flex-basis:100%; }
  .pdf{ min-height:440px; }
  .modal__panel{ max-height:92vh; }
}

@media (max-width:360px){
  :root{ --gut:16px; }
  .btn{ padding:12px 18px; font-size:.7rem; }
}

/* pantallas grandes */
@media (min-width:1700px){
  :root{ --wrap:1360px; }
}

/* accesibilidad */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{
    animation-duration:.01ms !important;
    animation-iteration-count:1 !important;
    transition-duration:.01ms !important;
    scroll-behavior:auto !important;
  }
  .js .reveal, .reveal{ opacity:1; transform:none; }
}

:focus-visible{ outline:2px solid var(--accent); outline-offset:3px; }

/* ---------------------------------------------- descarga de CV en 2 idiomas */
.cvdl{ position:relative; }
.cvdl > summary{
  list-style:none;
  cursor:pointer;
  user-select:none;
}
.cvdl > summary::-webkit-details-marker{ display:none; }
.cvdl__caret{
  width:13px; height:13px;
  transition:transform .28s var(--ease);
}
.cvdl[open] .cvdl__caret{ transform:rotate(180deg); }

.cvdl__menu{
  position:absolute;
  top:calc(100% + 8px);
  left:0;
  z-index:40;
  min-width:100%;
  display:flex;
  flex-direction:column;
  background:var(--surface);
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  box-shadow:var(--shadow);
  overflow:hidden;
  animation:cvdlIn .26s var(--ease) both;
}
@keyframes cvdlIn{
  from{ opacity:0; transform:translateY(-6px); }
  to  { opacity:1; transform:none; }
}
.cvdl__menu a{
  display:flex; align-items:center; gap:10px;
  font-family:var(--f-mono);
  font-size:.72rem; letter-spacing:.06em; text-transform:uppercase;
  padding:12px 18px;
  color:var(--fg-mid);
  white-space:nowrap;
  transition:background .22s, color .22s;
}
.cvdl__menu a + a{ border-top:var(--bw) solid var(--line-soft); }
.cvdl__menu a:hover{ background:var(--surface-2); color:var(--accent); }
.cvdl__code{
  font-weight:700;
  color:var(--accent);
  min-width:2ch;
}

/* ══════════════════ EXPERIENCIA — línea de tiempo ══════════════════════════
   A propósito NO usa tarjetas: la sección de proyectos ya está llena de
   ellas y repetir el recurso aplana la página. Acá manda el texto, sobre un
   riel vertical. */

.exp__lead{
  font-family:var(--f-display);
  font-size:clamp(1.5rem, 3.4vw, 2.5rem);
  font-weight:400; line-height:1.22; letter-spacing:-.02em;
  color:var(--fg); max-width:20ch;
  margin-bottom:clamp(48px, 7vw, 78px);
  text-wrap:balance;
}

.tl{ list-style:none; margin:0; padding:0; position:relative; }
/* El riel arranca y termina en el primer y último punto, no en el borde. */
.tl::before{
  content:""; position:absolute; left:7px; top:10px; bottom:10px;
  width:var(--bw); background:var(--line);
}

.tl__item{
  position:relative;
  display:grid;
  grid-template-columns:150px minmax(0,1fr);
  gap:0 clamp(24px, 4vw, 56px);
  padding:0 0 clamp(38px, 5vw, 58px) 42px;
}
.tl__item:last-child{ padding-bottom:0; }

.tl__dot{
  position:absolute; left:0; top:6px;
  width:15px; height:15px; border-radius:50%;
  background:var(--bg); border:var(--bw) solid var(--line);
  transition:border-color var(--t), background var(--t), box-shadow var(--t);
}
/* El punto lleno marca el hito que importa: el primer cliente. */
.tl__dot--hl{
  background:var(--accent); border-color:var(--accent);
  box-shadow:0 0 0 5px var(--accent-wash);
}
.tl__item:hover .tl__dot{ border-color:var(--accent); }

.tl__when{
  font-size:.78rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--fg-dim); padding-top:8px; white-space:nowrap;
}

/* ─────────── LA ESCALA DEL PRIMER CLIENTE ───────────
   El dato que cambia cómo se lee este trabajo no es el stack: es para
   cuánta gente está esa tienda. Va de fondo, en grande y tenue, para que
   se perciba la magnitud sin que el bloque se convierta en un cartel. */
.tl__body--cliente{ position:relative; }

.tl__escala{
  position:absolute; z-index:0;
  right:0; top:-14px;
  font-family:var(--f-display);
  font-size:clamp(3.4rem, 7vw, 5.6rem);
  font-weight:800; letter-spacing:-.04em; line-height:1;
  color:var(--accent);
  opacity:.09;
  pointer-events:none; user-select:none;
}
[data-theme="light"] .tl__escala{ opacity:.13; }

.tl__body--cliente > *:not(.tl__escala){ position:relative; z-index:1; }

/* Enlace al perfil: el número acá sí se lee, y es el que da la referencia. */
/* Las tecnologías del trabajo para cliente, con el mismo aire que las de
   los proyectos pero un poco más contenidas. */
.tl__tags{ margin-top:12px; }
.tl__tags .tag{ font-size:.6rem; }

.tl__ig{
  display:inline-flex; align-items:center; gap:9px;
  margin-top:12px; padding:7px 12px;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  background:var(--surface);
  color:var(--fg-mid);
  font-size:.72rem;
  transition:border-color var(--t), color var(--t), transform var(--t);
}
.tl__ig:hover{ border-color:var(--accent); color:var(--fg); transform:translate(-2px,-2px); }
.tl__ig svg{ width:15px; height:15px; flex-shrink:0; }
.tl__ig-num{
  padding-left:9px;
  border-left:var(--bw) solid var(--line);
  color:var(--accent); font-weight:700;
}

@media (max-width:560px){
  .tl__escala{ top:auto; bottom:-6px; opacity:.07; }
  .tl__ig{ flex-wrap:wrap; }
}

.tl__role{
  font-family:var(--f-display);
  font-size:clamp(1.12rem, 1.9vw, 1.42rem);
  font-weight:600; letter-spacing:-.015em; color:var(--fg);
  margin:0 0 12px;
}
.tl__role a{
  color:var(--accent);
  text-decoration:none;
  border-bottom:var(--bw) solid transparent;
  transition:border-color var(--t);
}
.tl__role a:hover{ border-bottom-color:var(--accent); }
.tl__sep{ color:var(--fg-dim); margin:0 6px; font-weight:400; }

.tl__txt{
  font-size:1rem; line-height:1.72; color:var(--fg-mid);
  max-width:62ch; margin:0;
}

@media (max-width:780px){
  .exp__lead{ max-width:none; }
  .tl__item{
    grid-template-columns:1fr;
    gap:8px; padding-left:34px;
  }
  .tl::before{ left:6px; }
  .tl__dot{ width:13px; height:13px; top:4px; }
  .tl__when{ padding-top:0; }
}

/* ══════════════════ DEMO EN VIVO DENTRO DE LA TARJETA ═════════════════════
   La captura es una foto; esto deja probar la app sin salir del portfolio.
   Solo en los proyectos que permiten ser embebidos: la tienda de Eugenia
   manda frame-ancestors y no se puede. */

.proj__media{ position:relative; }

.proj__live{
  position:absolute; z-index:3; left:14px; bottom:14px;
  display:inline-flex; align-items:center; gap:9px;
  padding:9px 15px;
  font-family:var(--f-mono); font-size:.68rem; font-weight:700;
  letter-spacing:.1em; text-transform:uppercase;
  color:var(--fg);
  background:rgba(13,13,11,.72);
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  -webkit-backdrop-filter:saturate(150%) blur(14px);
          backdrop-filter:saturate(150%) blur(14px);
  cursor:pointer;
  opacity:0; transform:translateY(6px);
  transition:opacity var(--t), transform var(--t), border-color var(--t), color var(--t);
}
.proj:hover .proj__live,
.proj__live:focus-visible{ opacity:1; transform:none; }
.proj__live:hover{ border-color:var(--accent); color:var(--accent); }
.proj__live-dot{
  width:7px; height:7px; border-radius:50%; background:var(--accent); flex:none;
  animation:livePulse 2s var(--ease) infinite;
}
@keyframes livePulse{
  0%,100%{ box-shadow:0 0 0 0 var(--accent-wash) }
  55%{ box-shadow:0 0 0 6px transparent }
}

/* mientras corre la demo */
.proj--live .proj__media img,
.proj--live .proj__veil{ opacity:0; pointer-events:none; }
.proj__frame{
  position:absolute; inset:0; z-index:2;
  width:100%; height:100%;
  border:0; background:var(--bg);
  opacity:0; transition:opacity .45s var(--ease);
}
.proj__frame.on{ opacity:1; }
.proj__close{
  position:absolute; z-index:4; right:12px; top:12px;
  width:34px; height:34px; display:grid; place-items:center;
  border-radius:50%; cursor:pointer;
  color:var(--fg);
  background:rgba(13,13,11,.78);
  border:var(--bw) solid var(--line);
  -webkit-backdrop-filter:blur(12px); backdrop-filter:blur(12px);
  transition:border-color var(--t), color var(--t), transform var(--t);
}
.proj__close:hover{ border-color:var(--accent); color:var(--accent); transform:rotate(90deg); }
.proj__close svg{ width:15px; height:15px; }
.proj__loading{
  position:absolute; inset:0; z-index:3; display:grid; place-items:center;
  font-family:var(--f-mono); font-size:.72rem; letter-spacing:.16em;
  text-transform:uppercase; color:var(--fg-dim);
  background:var(--bg);
  transition:opacity .4s var(--ease);
}
.proj__loading.off{ opacity:0; pointer-events:none; }

@media (max-width:760px){
  /* En touch no hay hover: el botón queda siempre visible. */
  .proj__live{ opacity:1; transform:none; left:10px; bottom:10px; padding:8px 12px; }
}

/* ══════════════════ SCROLL NATIVO ═════════════════════════════════════════
   Donde el navegador lo soporta, la aparición la maneja el compositor con
   animation-timeline en vez de un IntersectionObserver en JS. El .vis que
   sigue agregando el script queda inofensivo: la animación gana. */
@supports (animation-timeline: view()){
  /* .js .reveal (0,2,0) le gana a .reveal (0,1,0), asi que aca hay que
     igualar la especificidad o este bloque no aplica nunca. */
  .js .reveal, .reveal{
    opacity:1; transform:none;
    animation:revealScroll linear both;
    animation-timeline:view();
    animation-range:entry 4% cover 26%;
  }
  @keyframes revealScroll{
    from{ opacity:0; transform:translateY(26px); }
    to{ opacity:1; transform:none; }
  }
  /* El hero ya entra visible: animarlo con scroll lo haría parpadear. */
  .js .hero .reveal, .hero .reveal{ animation:none; }
}
@media (prefers-reduced-motion:reduce){
  @supports (animation-timeline: view()){
    .js .reveal, .reveal{ animation:none; opacity:1; transform:none; }
  }
}

/* ══════════════════════════ MODO CAOS ══════════════════════════════════════
   Las tarjetas del stack se sueltan y caen. Es un modo opcional: por defecto
   la grilla se mantiene, porque ahí las tarjetas informan nivel y porcentaje. */

.caos-btn{
  margin-left:auto;
  display:inline-flex; align-items:center; gap:9px;
  padding:10px 16px;
  font-family:var(--f-mono); font-size:.68rem; font-weight:700;
  letter-spacing:.1em; text-transform:uppercase;
  color:var(--fg-mid);
  background:transparent;
  border:var(--bw) solid var(--line);
  border-radius:var(--r);
  cursor:pointer; white-space:nowrap;
  transition:color var(--t), border-color var(--t), transform var(--t), box-shadow var(--t);
}
.caos-btn:hover{ color:var(--accent); border-color:var(--accent); transform:translate(-2px,-2px); box-shadow:3px 3px 0 var(--accent); }
.caos-btn.on{ color:var(--accent-fg); background:var(--accent); border-color:var(--accent); }
.caos-btn[disabled]{ opacity:.55; cursor:progress; }
.caos-ico{
  width:9px; height:9px; border-radius:2px; flex:none;
  background:currentColor;
  transition:transform var(--t);
}
.caos-btn:hover .caos-ico{ transform:rotate(45deg); }
.caos-btn.on .caos-ico{ animation:caosGira 1.6s linear infinite; }
.caos-btn.cargando .caos-ico{ animation:caosGira .7s linear infinite; }
@keyframes caosGira{ to{ transform:rotate(360deg) } }

/* Al soltar, las tarjetas salen del flujo y las posiciona el motor físico. */
.stack.caos{
  position:relative;
  overflow:hidden;
  display:block;
  border:var(--bw) dashed var(--line);
  border-radius:var(--r-lg);
  cursor:grab;
}
.stack.caos:active{ cursor:grabbing; }
.stack.caos .sk{
  position:absolute; top:0; left:0;
  margin:0;
  will-change:transform;
  transition:none;
  /* Las tarjetas llevan .reveal, que bajo animation-timeline anima transform.
     Una animación CSS le gana al estilo inline, así que sin esto pisaría la
     posición que escribe el motor físico y quedarían todas en la esquina. */
  animation:none !important;
  opacity:1 !important;
  transform-origin:center center;
  user-select:none;
}
.stack.caos .sk:hover{ transform-origin:center center; }
/* El texto no se selecciona mientras se arrastra. */
.stack.caos .sk *{ pointer-events:none; user-select:none; }

@media (prefers-reduced-motion:reduce){
  .caos-btn{ display:none; }
}

/* ══════════════════════════ CAOS TOTAL ═════════════════════════════════════ */

.caos-total-btn{
  position:fixed; right:16px; bottom:16px; z-index:9000;
  display:inline-flex; align-items:center; gap:7px;
  padding:8px 13px;
  font-family:var(--f-mono); font-size:.58rem; font-weight:700;
  letter-spacing:.12em; text-transform:uppercase;
  color:var(--fg);
  background:var(--surface);
  border:var(--bw) solid var(--line);
  border-radius:var(--pill);
  cursor:pointer;
  box-shadow:0 6px 18px rgba(0,0,0,.45);
  transition:color var(--t), border-color var(--t), transform var(--t), box-shadow var(--t), background var(--t);
}
.caos-total-btn:hover{
  color:var(--accent); border-color:var(--accent);
  transform:translateY(-2px);
  box-shadow:0 9px 22px rgba(0,0,0,.5);
}
.caos-total-btn.on{ background:var(--accent); color:var(--accent-fg); border-color:var(--accent); }
.caos-total-btn[disabled]{ opacity:.6; cursor:progress; }
.ctb-ico{
  width:8px; height:8px; flex:none; border-radius:2px;
  background:currentColor;
  transition:transform var(--t);
}
.caos-total-btn:hover .ctb-ico{ transform:rotate(45deg) scale(1.15); }
.caos-total-btn.on .ctb-ico{ animation:ctbGira 1.1s linear infinite; }
@keyframes ctbGira{ to{ transform:rotate(360deg) } }

/* el sacudón previo */
@keyframes caosTiembla{
  0%,100%{ transform:translate3d(0,0,0) }
  10%{ transform:translate3d(-9px,4px,0) rotate(-.35deg) }
  20%{ transform:translate3d(8px,-6px,0) rotate(.3deg) }
  30%{ transform:translate3d(-11px,-3px,0) rotate(-.25deg) }
  40%{ transform:translate3d(10px,5px,0) rotate(.32deg) }
  50%{ transform:translate3d(-7px,-7px,0) rotate(-.2deg) }
  60%{ transform:translate3d(9px,3px,0) rotate(.22deg) }
  70%{ transform:translate3d(-6px,5px,0) rotate(-.15deg) }
  80%{ transform:translate3d(5px,-4px,0) rotate(.1deg) }
  90%{ transform:translate3d(-3px,2px,0) rotate(-.06deg) }
}
body.caos-temblor{ animation:caosTiembla .62s cubic-bezier(.36,.07,.19,.97) both; }

/* mientras dura: la página queda quieta debajo */
body.caos-total{ overflow:hidden; }

.caos-capa{
  position:fixed; inset:0; z-index:8500;
  overflow:hidden;
  cursor:grab;
}
.caos-capa:active{ cursor:grabbing; }

.caos-pieza{
  position:absolute; top:0; left:0;
  margin:0 !important;
  will-change:transform;
  /* Los clones heredan .reveal y sus transiciones: sin cortarlas, la animación
     de scroll le gana al inline y quedan todos apilados en la esquina. */
  animation:none !important;
  transition:none !important;
  opacity:1 !important;
  visibility:visible !important;
  transform-origin:center center;
  pointer-events:none;
  user-select:none;
}
.caos-pieza *{ pointer-events:none !important; user-select:none; animation:none !important; }
/* Los clones no navegan ni abren nada. */
.caos-pieza a{ pointer-events:none; }

@media (prefers-reduced-motion:reduce){
  .caos-total-btn{ display:none; }
  body.caos-temblor{ animation:none; }
}
@media (max-width:760px){
  .caos-total-btn{ right:12px; bottom:12px; padding:7px 11px; font-size:.54rem; }
}
