/* ══════════════════════════════════════════════════════════════
   JSDG Portfolio — Jaime Silva
   Módulo 6 | Alkemy 2026
   Font: Lato | Monochrome Dark — Glass Premium
   ══════════════════════════════════════════════════════════════ */

/* ── VARIABLES ─────────────────────────────────────────────── */
:root {
  /* Monochrome palette */
  --bg:             #080808;
  --bg-surface:     #0d0d0d;
  --bg-card:        rgba(255, 255, 255, 0.03);
  --glass-bg:       rgba(255, 255, 255, 0.04);
  --glass-border:   rgba(255, 255, 255, 0.08);
  --glass-inset:    rgba(255, 255, 255, 0.1);
  --text:           #ece8e1;   /* warm off-white */
  --text-mid:       #a8a49e;
  --text-muted:     #5c5a57;
  --text-subtle:    #302e2c;
  --border:         rgba(255, 255, 255, 0.07);
  --border-hover:   rgba(255, 255, 255, 0.16);

  /* Typography */
  --font:           'Lato', system-ui, sans-serif;

  /* Spacing */
  --max-w:          1140px;
  --section-py:     7rem;

  /* Motion */
  --ease-out:       cubic-bezier(0.16, 1, 0.3, 1);
  --dur:            0.3s;

  /* Radii */
  --r-sm:  6px;
  --r-md:  12px;
  --r-lg:  18px;
  --r-xl:  24px;
}

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

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

body {
  font-family: var(--font);
  background-color: var(--bg);
  color: var(--text);
  font-size: 1rem;
  line-height: 1.7;
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

/* Noise grain overlay — fixed, pointer-events none, no GPU repaint on scroll */
body::after {
  content: '';
  position: fixed;
  inset: 0;
  z-index: 9999;
  pointer-events: none;
  opacity: 0.032;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='300' height='300' filter='url(%23n)'/%3E%3C/svg%3E");
  background-size: 200px 200px;
}

img, video { max-width: 100%; display: block; }
ul { list-style: none; }
a  { color: inherit; text-decoration: none; }
button { cursor: pointer; font-family: var(--font); border: none; background: none; }

/* ── TYPOGRAPHY ────────────────────────────────────────────── */
h1, h2, h3 {
  font-weight: 900;
  line-height: 1.05;
  letter-spacing: -0.025em;
  color: var(--text);
}

h1 { font-size: clamp(2.8rem, 7vw, 5.8rem); }
h2 { font-size: clamp(2rem, 4vw, 3rem); }
h3 { font-size: 1.2rem; font-weight: 700; letter-spacing: -0.01em; }

.text-lead {
  font-size: clamp(1.05rem, 2vw, 1.25rem);
  font-weight: 400;
  line-height: 1.55;
  color: var(--text);
  margin-bottom: 1rem;
}

.text-body {
  color: var(--text-muted);
  font-size: 1rem;
  margin-bottom: 0.85rem;
}

/* ── LAYOUT UTILITIES ──────────────────────────────────────── */
.container {
  width: 90%;
  max-width: var(--max-w);
  margin: 0 auto;
}

.section {
  padding: var(--section-py) 0;
}

.section--alt {
  background: var(--bg-surface);
}

/* ── REVEAL ANIMATION ──────────────────────────────────────── */
.reveal {
  opacity: 0;
  transform: translateY(28px);
  transition:
    opacity  0.76s var(--ease-out),
    transform 0.76s var(--ease-out);
}

.reveal.is-visible {
  opacity: 1;
  transform: translateY(0);
}

/* ── BUTTONS ───────────────────────────────────────────────── */
.btn {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.8rem 1.65rem;
  border-radius: var(--r-md);
  font-family: var(--font);
  font-weight: 700;
  font-size: 0.875rem;
  letter-spacing: 0.03em;
  white-space: nowrap;
  transition:
    background   var(--dur) var(--ease-out),
    color        var(--dur) var(--ease-out),
    border-color var(--dur),
    transform    0.14s var(--ease-out),
    box-shadow   var(--dur) var(--ease-out);
}

.btn:active { transform: scale(0.97) translateY(1px); }

/* Primary: solid white, black text — maximum editorial contrast */
.btn--primary {
  background: var(--text);
  color: #080808;
}
.btn--primary:hover {
  background: #fff;
  box-shadow: 0 8px 32px -8px rgba(255, 255, 255, 0.22);
}
.btn--primary.btn--success {
  background: #d4f7e0;
  color: #065f46;
  box-shadow: 0 8px 24px -8px rgba(52, 211, 153, 0.3);
}

/* Ghost */
.btn--ghost {
  background: transparent;
  color: var(--text-mid);
  border: 1px solid var(--border);
}
.btn--ghost:hover {
  border-color: var(--border-hover);
  color: var(--text);
  background: rgba(255, 255, 255, 0.04);
}

/* Outline */
.btn--outline {
  background: transparent;
  color: var(--text-muted);
  border: 1px solid var(--border);
}
.btn--outline:hover {
  border-color: var(--border-hover);
  background: rgba(255, 255, 255, 0.04);
  color: var(--text);
}

.btn--block {
  width: 100%;
  justify-content: center;
}

/* ── HEADER / NAV ──────────────────────────────────────────── */
.header {
  position: fixed;
  inset: 0 0 auto;
  z-index: 500;
  border-bottom: 1px solid transparent;
  transition:
    background      var(--dur) var(--ease-out),
    border-color    var(--dur),
    backdrop-filter var(--dur);
}

.header--scrolled {
  background: rgba(8, 8, 8, 0.78);
  backdrop-filter: blur(32px) saturate(180%);
  -webkit-backdrop-filter: blur(32px) saturate(180%);
  border-bottom-color: var(--border);
}

.nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  height: 72px;
}

.nav__logo-img {
  height: 30px;
  width: auto;
  filter: brightness(0) invert(1);
  opacity: 0.82;
  transition: opacity var(--dur);
}
.nav__logo:hover .nav__logo-img { opacity: 1; }

.nav__links {
  display: flex;
  gap: 2.25rem;
}

.nav__link {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--text-mid);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  transition: color var(--dur);
  position: relative;
}
.nav__link::after {
  content: '';
  position: absolute;
  left: 0;
  bottom: -3px;
  width: 0;
  height: 1px;
  background: var(--text);
  transition: width var(--dur) var(--ease-out);
}
.nav__link:hover,
.nav__link.is-active { color: var(--text); }
.nav__link:hover::after,
.nav__link.is-active::after { width: 100%; }

/* Language toggle — same type treatment as nav links, no accent colour */
.nav__lang {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding-left: 0.25rem;
  border-left: 1px solid var(--border);
}
.lang-toggle__btn {
  font-family: var(--font);
  font-size: 0.68rem;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
  background: none;
  border: none;
  cursor: pointer;
  padding: 0.2rem 0.1rem;
  transition: color var(--dur);
}
.lang-toggle__btn:hover { color: var(--text-mid); }
.lang-toggle__btn.is-active {
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 3px;
}
.lang-toggle__sep {
  color: var(--text-subtle);
  font-size: 0.68rem;
}

/* Hamburger */
.nav__toggle {
  display: none;
  flex-direction: column;
  gap: 5px;
  width: 30px;
  padding: 6px 4px;
}
.nav__bar {
  display: block;
  width: 100%;
  height: 2px;
  background: var(--text);
  border-radius: 2px;
  transform-origin: center;
  transition: transform var(--dur) var(--ease-out), opacity var(--dur);
}
.nav__toggle.is-open .nav__bar:first-child {
  transform: translateY(7px) rotate(45deg);
}
.nav__toggle.is-open .nav__bar:last-child {
  transform: translateY(-7px) rotate(-45deg);
}

/* ── HERO ──────────────────────────────────────────────────── */
.hero {
  position: relative;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  overflow: hidden;
  background-color: var(--bg);
}

.hero__video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  z-index: 0;
}

/* Deeper directional overlay: text-side heavily darkened */
.hero__overlay {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(
      105deg,
      rgba(8, 8, 8, 0.95) 0%,
      rgba(8, 8, 8, 0.78) 42%,
      rgba(8, 8, 8, 0.38) 100%
    ),
    linear-gradient(
      to bottom,
      rgba(8, 8, 8, 0.4) 0%,
      transparent 30%,
      transparent 70%,
      rgba(8, 8, 8, 0.7) 100%
    );
}

.hero__inner {
  position: relative;
  z-index: 2;
  padding-top: 110px;
  padding-bottom: 80px;
}

.hero__content {
  max-width: 640px;
}

.hero__eyebrow {
  font-size: 0.68rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.26em;
  color: var(--text-muted);
  margin-bottom: 1.5rem;
  opacity: 0;
  animation: fadeUp 0.8s var(--ease-out) 0.2s forwards;
}

.hero__title {
  margin-bottom: 1.5rem;
}

.hero__line {
  display: block;
  color: var(--text);
  opacity: 0;
  animation: fadeUp 0.9s var(--ease-out) forwards;
}
.hero__line:nth-child(1) { animation-delay: 0.32s; }
.hero__line:nth-child(2) { animation-delay: 0.46s; }
.hero__line:nth-child(3) { animation-delay: 0.60s; }

/* Outlined stroke — white, editorial */
.hero__line--stroke {
  color: transparent;
  -webkit-text-stroke: 1.5px rgba(236, 232, 225, 0.38);
}
@supports not (-webkit-text-stroke: 1px transparent) {
  .hero__line--stroke { color: var(--text-mid); }
}

.hero__sub {
  font-size: 1rem;
  color: var(--text-muted);
  line-height: 1.75;
  margin-bottom: 2.5rem;
  max-width: 440px;
  opacity: 0;
  animation: fadeUp 0.8s var(--ease-out) 0.76s forwards;
}

.hero__actions {
  display: flex;
  gap: 0.875rem;
  flex-wrap: wrap;
  opacity: 0;
  animation: fadeUp 0.8s var(--ease-out) 0.92s forwards;
}

/* Scroll indicator */
.hero__scroll {
  position: absolute;
  bottom: 2.25rem;
  right: 5%;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.6rem;
  opacity: 0;
  animation: fadeIn 1s var(--ease-out) 1.5s forwards;
}

.hero__scroll-label {
  font-size: 0.58rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.28em;
  color: var(--text-subtle);
  writing-mode: vertical-lr;
  transform: rotate(180deg);
}

.hero__scroll-track {
  width: 1px;
  height: 52px;
  background: rgba(255, 255, 255, 0.1);
  position: relative;
  overflow: hidden;
}

.hero__scroll-dot {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 40%;
  background: linear-gradient(to bottom, transparent, rgba(255, 255, 255, 0.6));
  animation: scrollDrop 2.4s ease-in-out infinite;
}

/* ── KEYFRAMES ─────────────────────────────────────────────── */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(22px); }
  to   { opacity: 1; transform: translateY(0); }
}

@keyframes fadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes scrollDrop {
  0%   { transform: translateY(-100%); opacity: 0; }
  15%  { opacity: 1; }
  85%  { opacity: 1; }
  100% { transform: translateY(280%); opacity: 0; }
}

@keyframes marqueeRun {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

/* ── SECTION HEADER ────────────────────────────────────────── */
.section-header {
  display: flex;
  align-items: flex-start;
  gap: 1.4rem;
  margin-bottom: 3.5rem;
}

/* Section number — typographic, no pill */
.section-num {
  flex-shrink: 0;
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.1em;
  color: var(--text-muted);
  margin-top: 0.65rem;
  font-variant-numeric: tabular-nums;
}

.section-title { color: var(--text); }

.section-sub {
  margin-top: 0.35rem;
  font-size: 1rem;
  color: var(--text-muted);
  font-weight: 400;
}

/* ── SOBRE MÍ ──────────────────────────────────────────────── */
.sobre-mi__layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3rem;
  align-items: start;
}

.sobre-mi__figure {
  position: relative;
  /* perspective sits on figure so tilt-wrap rotates in 3D */
  perspective: 700px;
  will-change: transform;
}

/* The rotating wrapper */
.tilt-wrap {
  position: relative;
  border-radius: var(--r-xl);
  transform-style: preserve-3d;
  transform: perspective(700px) rotateX(0deg) rotateY(0deg);
  transition: box-shadow 0.6s var(--ease-out);
  box-shadow:
    0 4px 48px -8px rgba(0, 0, 0, 0.75),
    0 0 0 1px var(--glass-border);
}

/* Specular highlight layer */
.tilt-shine {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.5s var(--ease-out);
  z-index: 2;
}

.sobre-mi__photo {
  width: 100%;
  max-width: 340px;
  aspect-ratio: 4 / 5;
  object-fit: cover;
  border-radius: var(--r-xl);
  border: 1px solid var(--glass-border);
  display: block;
  /* scroll parallax applied via JS */
  transition: transform 1.2s var(--ease-out);
  will-change: transform;
}

/* iOS gyro permission button — aparece solo en iPhone/iPad */
.tilt-gyro-btn {
  position: absolute;
  bottom: 1rem;
  left: 50%;
  transform: translateX(-50%);
  z-index: 10;
  padding: 0.38rem 1rem;
  font-family: var(--font);
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-mid);
  background: rgba(255, 255, 255, 0.07);
  border: 1px solid var(--glass-border);
  border-radius: 999px;
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur), color var(--dur);
}
.tilt-gyro-btn:hover {
  background: rgba(255, 255, 255, 0.13);
  color: var(--text);
}

.sobre-mi__caption {
  margin-top: 0.75rem;
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-subtle);
}

.sobre-mi__body {
  display: flex;
  flex-direction: column;
  gap: 2rem;
}

/* ── SKILLS BLOCK ──────────────────────────────────────────── */
.skills-block__label {
  font-size: 0.65rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--text-subtle);
  margin-bottom: 0.85rem;
}

.skills-block__list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.5rem;
}

.skills-block__list li {
  padding: 0.3rem 0.9rem;
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--text-mid);
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  border-radius: 999px;
  letter-spacing: 0.03em;
  transition: background var(--dur), border-color var(--dur), color var(--dur), transform 0.14s;
}
.skills-block__list li:hover {
  background: rgba(255, 255, 255, 0.08);
  border-color: rgba(255, 255, 255, 0.2);
  color: var(--text);
  transform: translateY(-2px);
}

/* ── MARQUEE STRIP ─────────────────────────────────────────── */
.marquee-strip {
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 1.1rem 0;
  overflow: hidden;
  background: var(--bg-surface);
}

.marquee { overflow: hidden; }

.marquee__track {
  display: flex;
  align-items: center;
  width: max-content;
  animation: marqueeRun 36s linear infinite;
}

.marquee-strip:hover .marquee__track {
  animation-play-state: paused;
}

.marquee__word {
  font-size: 0.68rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--text-muted);
  padding: 0 1.4rem;
  white-space: nowrap;
  transition: color var(--dur);
}

.marquee__dot {
  color: rgba(255, 255, 255, 0.2);
  font-size: 0.6rem;
  flex-shrink: 0;
}

.marquee__track:hover .marquee__word { color: var(--text-mid); }

/* ── PROJECTS ──────────────────────────────────────────────── */
.projects-grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 1.25rem;
  margin-bottom: 3rem;
}

/* Spotlight card — pseudo element reads CSS custom props from JS */
.project-card {
  position: relative;
  isolation: isolate;
  border-radius: var(--r-xl);
  overflow: hidden;
  background: var(--bg-card);
  border: 1px solid var(--glass-border);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 2px 12px rgba(0, 0, 0, 0.4);
  transition:
    transform    0.44s var(--ease-out),
    box-shadow   0.44s var(--ease-out),
    border-color 0.44s;
}

/* Spotlight gradient — tracks mouse via JS */
.project-card::before {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: radial-gradient(
    500px circle at var(--mouse-x, 50%) var(--mouse-y, 0%),
    rgba(255, 255, 255, 0.055),
    transparent 65%
  );
  opacity: 0;
  transition: opacity 0.4s;
  pointer-events: none;
  z-index: 1;
}

.project-card:hover {
  transform: translateY(-6px);
  border-color: rgba(255, 255, 255, 0.15);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 32px 60px -16px rgba(0, 0, 0, 0.8);
}

.project-card:hover::before {
  opacity: 1;
}

.project-card__link {
  display: flex;
  flex-direction: column;
  height: 100%;
  position: relative;
  z-index: 2;
}

.project-card__media {
  overflow: hidden;
  flex-shrink: 0;
  position: relative;
}

/* Frosted gradient mask at bottom of image */
.project-card__media::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 64px;
  background: linear-gradient(to bottom, transparent, rgba(12, 12, 12, 0.6));
  pointer-events: none;
}

.project-card__media img {
  width: 100%;
  height: 220px;
  object-fit: cover;
  object-position: left top;
  transition: transform 0.65s var(--ease-out);
}

.project-card:hover .project-card__media img {
  transform: scale(1.06);
}

.project-card__body {
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  flex: 1;
}

.project-tag {
  font-size: 0.62rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--text-muted);
}

.project-title { color: var(--text); }

.project-desc {
  font-size: 0.88rem;
  color: var(--text-muted);
  line-height: 1.6;
  flex: 1;
}

.project-cta {
  display: inline-flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--text-subtle);
  margin-top: 0.75rem;
  transition: color var(--dur), gap 0.25s var(--ease-out);
}

.project-card:hover .project-cta {
  color: var(--text-mid);
  gap: 0.55rem;
}

.projects-footer {
  display: flex;
  justify-content: center;
}

/* ── CONTACTO ──────────────────────────────────────────────── */
.contacto__layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: 3.5rem;
  align-items: start;
}

.contacto__email {
  display: inline-block;
  font-size: 1.15rem;
  font-weight: 700;
  color: var(--text);
  margin: 1.25rem 0 2rem;
  letter-spacing: -0.01em;
  transition: color var(--dur), opacity var(--dur);
  opacity: 0.9;
}
.contacto__email:hover { opacity: 1; color: #fff; }

.contacto__social {
  display: flex;
  gap: 1.25rem;
}

.social-link {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  font-size: 0.76rem;
  font-weight: 700;
  color: var(--text-muted);
  letter-spacing: 0.05em;
  transition: color var(--dur), transform 0.14s;
}
.social-link:hover { color: var(--text); transform: translateY(-2px); }

/* Form — glass panel */
.contacto__form {
  display: flex;
  flex-direction: column;
  gap: 1.4rem;
  background: rgba(255, 255, 255, 0.025);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-xl);
  padding: 2rem;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.07),
    0 32px 64px -16px rgba(0, 0, 0, 0.5);
  backdrop-filter: blur(20px);
  -webkit-backdrop-filter: blur(20px);
}

.form-group {
  display: flex;
  flex-direction: column;
  gap: 0.38rem;
}

.form-label {
  font-size: 0.68rem;
  font-weight: 900;
  color: var(--text-mid);
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.form-input {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--glass-border);
  border-radius: var(--r-md);
  padding: 0.85rem 1rem;
  font-family: var(--font);
  font-size: 1rem;
  color: var(--text);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
  transition:
    border-color var(--dur),
    background   var(--dur),
    box-shadow   var(--dur);
}
.form-input::placeholder { color: var(--text-subtle); }
.form-input:focus {
  outline: none;
  border-color: rgba(255, 255, 255, 0.28);
  background: rgba(255, 255, 255, 0.06);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.06),
    0 0 0 3px rgba(255, 255, 255, 0.06);
}

.form-input--textarea {
  resize: vertical;
  min-height: 120px;
}

.form-msg {
  font-size: 0.82rem;
  font-weight: 700;
  min-height: 1.5em;
  transition: color var(--dur);
}
.form-msg--success { color: #6ee7b7; }
.form-msg--error   { color: #fca5a5; }

/* ── FOOTER ────────────────────────────────────────────────── */
.footer {
  border-top: 1px solid var(--border);
  padding: 2.25rem 0;
}

.footer__inner {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  text-align: center;
}

.footer__logo {
  height: 24px;
  width: auto;
  filter: brightness(0) invert(1);
  opacity: 0.38;
  transition: opacity var(--dur);
}
.footer__brand:hover .footer__logo { opacity: 0.7; }

.footer__copy {
  font-size: 0.75rem;
  color: var(--text-subtle);
  letter-spacing: 0.04em;
}

.footer__social {
  display: flex;
  gap: 1.25rem;
}

.footer__social-link {
  color: var(--text-subtle);
  transition: color var(--dur), transform 0.14s;
}
.footer__social-link:hover { color: var(--text-mid); transform: translateY(-2px); }

/* ══════════════════════════════════════════════════════════════
   MEDIA QUERIES — Mobile First
   ══════════════════════════════════════════════════════════════ */

/* ── Mobile: collapse nav ─────────────────────── */
@media (max-width: 767px) {
  .nav__toggle { display: flex; }

  .nav__links {
    position: fixed;
    top: 72px;
    left: 0;
    right: 0;
    background: rgba(8, 8, 8, 0.97);
    backdrop-filter: blur(24px);
    -webkit-backdrop-filter: blur(24px);
    flex-direction: column;
    gap: 0;
    border-bottom: 1px solid var(--border);
    clip-path: inset(0 0 100% 0);
    opacity: 0;
    pointer-events: none;
    transition:
      clip-path 0.4s var(--ease-out),
      opacity   0.4s var(--ease-out);
    z-index: 490;
  }

  .nav__links.is-open {
    clip-path: inset(0 0 0 0);
    opacity: 1;
    pointer-events: auto;
  }

  .nav__links li {
    border-bottom: 1px solid var(--border);
  }

  .nav__link {
    display: block;
    padding: 1.1rem 5%;
    font-size: 0.9rem;
  }
  .nav__link::after { display: none; }

  .nav__lang {
    padding: 1.1rem 5%;
    border-left: none;
  }

  .hero__scroll { display: none; }

  .sobre-mi__photo { max-width: 100%; }

  .contacto__form {
    padding: 1.5rem;
  }
}

/* ── Tablet 640px ─────────────────────────────── */
@media (min-width: 640px) {
  .projects-grid {
    grid-template-columns: 1fr 1fr;
  }

  .project-card--featured {
    grid-column: span 2;
  }

  .project-card--featured .project-card__media img {
    height: 340px;
  }
}

/* ── Tablet 768px ─────────────────────────────── */
@media (min-width: 768px) {
  .sobre-mi__layout {
    grid-template-columns: 260px 1fr;
    gap: 4rem;
  }

  .sobre-mi__photo { max-width: 100%; }

  .contacto__layout {
    grid-template-columns: 1fr 1fr;
  }

  .footer__inner {
    flex-direction: row;
    justify-content: space-between;
    text-align: left;
  }
}

/* ── Desktop 1024px ───────────────────────────── */
@media (min-width: 1024px) {
  /* Asymmetric project grid: featured left (spans 2 rows) + 2 stacked right */
  .projects-grid {
    grid-template-columns: 1.65fr 1fr;
    grid-template-rows: auto auto;
    align-items: stretch;
  }

  .project-card--featured {
    grid-column: 1;
    grid-row: 1 / 3;
    display: flex;
    flex-direction: column;
  }

  .project-card--featured .project-card__link {
    flex: 1;
  }

  .project-card--featured .project-card__media {
    flex: 1;
    min-height: 0;
  }

  .project-card--featured .project-card__media img {
    width: 100%;
    height: 100%;
    min-height: 260px;
    object-fit: cover;
  }
}

/* ── Wide 1280px ──────────────────────────────── */
@media (min-width: 1280px) {
  :root { --section-py: 9rem; }
}

/* ── Reduced motion ───────────────────────────────
   Honours the OS-level "reduce motion" setting: kills the marquee loop,
   the scroll-indicator drop, the 3D tilt and every entrance animation,
   while keeping all content visible and every focus/hover state intact. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* Entrance animations use `forwards` from opacity:0 — force the end state
     so nothing stays invisible when the animation is neutralised. */
  .reveal,
  .hero__eyebrow,
  .hero__line,
  .hero__sub,
  .hero__actions {
    opacity: 1 !important;
    transform: none !important;
  }

  .marquee__track { animation: none !important; transform: none !important; }
  .hero__scroll  { display: none; }
  .tilt-wrap { transform: none !important; }
  .tilt-gyro-btn { display: none; }
  /* The video is never attached under reduced motion (see index.html),
     so the element stays put and renders its static poster frame. */
}

/* ══════════════════════════════════════════════════════════════
   BLOCK 3 — Studio, metrics band, experience timeline
   Monochrome, asymmetric, no accent colour. See DESIGN.md §5.
   ══════════════════════════════════════════════════════════════ */

/* ── ESTUDIO ───────────────────────────────────────────────── */
.estudio__layout {
  display: grid;
  gap: 3rem;
}

.estudio__meta {
  margin-top: 2.25rem;
  border-top: 1px solid var(--border);
}

.estudio__meta-row {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.15rem;
  padding: 0.9rem 0;
  border-bottom: 1px solid var(--border);
}

.estudio__meta-row dt {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.estudio__meta-row dd {
  font-size: 0.95rem;
  color: var(--text-mid);
}

.client-list {
  list-style: none;
  margin-top: 1.1rem;
  border-top: 1px solid var(--border);
}

.client {
  display: grid;
  grid-template-columns: 2.4rem 1fr;
  gap: 0.75rem;
  padding: 1.75rem 0;
  border-bottom: 1px solid var(--border);
  transition: border-color var(--dur) var(--ease-out);
}

.client:hover { border-bottom-color: var(--border-hover); }

.client__index {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  color: var(--text-subtle);
  padding-top: 0.35rem;
  transition: color var(--dur) var(--ease-out);
}

.client:hover .client__index { color: var(--text-muted); }

.client__name {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text);
  line-height: 1.3;
}

.client__place {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 0.3rem;
}

.client__role {
  font-size: 0.95rem;
  color: var(--text-mid);
  margin-top: 0.7rem;
  max-width: 52ch;
}

.client__stack {
  font-size: 0.8rem;
  color: var(--text-muted);
  margin-top: 0.6rem;
}

/* ── BANDA DE METRICAS ─────────────────────────────────────── */
.metrics-band {
  background: var(--bg-surface);
  border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
  padding: 3.25rem 0;
}

.metrics {
  display: grid;
  gap: 2rem;
}

.metric__value {
  font-size: clamp(2.1rem, 5vw, 3rem);
  font-weight: 900;
  letter-spacing: -0.03em;
  line-height: 1;
  color: var(--text);
}

.metric--lead .metric__value {
  font-size: clamp(2.8rem, 7vw, 4.4rem);
}

.metric__label {
  font-size: 0.78rem;
  line-height: 1.55;
  color: var(--text-muted);
  margin-top: 0.7rem;
  max-width: 24ch;
}

/* ── TIMELINE DE EXPERIENCIA ───────────────────────────────── */
.timeline {
  list-style: none;
  margin-top: 1rem;
  border-top: 1px solid var(--border);
}

.timeline__item {
  display: grid;
  gap: 0.65rem;
  padding: 2rem 0;
  border-bottom: 1px solid var(--border);
  transition: border-color var(--dur) var(--ease-out);
}

.timeline__item:hover { border-bottom-color: var(--border-hover); }

.timeline__period {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
  padding-top: 0.3rem;
}

.timeline__org {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text);
  line-height: 1.3;
}

.timeline__role {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-mid);
  margin-top: 0.4rem;
}

.timeline__desc {
  font-size: 0.95rem;
  color: var(--text-muted);
  margin-top: 0.75rem;
  max-width: 62ch;
}

/* ── RESPONSIVE ────────────────────────────────────────────── */
@media (min-width: 640px) {
  /* 2x2 before the asymmetric desktop row */
  .metrics { grid-template-columns: repeat(2, 1fr); gap: 2.5rem 3rem; }
  .estudio__meta-row { grid-template-columns: 8rem 1fr; gap: 1.5rem; align-items: baseline; }
}

@media (min-width: 768px) {
  .timeline__item { grid-template-columns: 11rem 1fr; gap: 2.5rem; }
}

@media (min-width: 1024px) {
  /* Deliberately unequal columns — DESIGN.md bans equal-column bands */
  .estudio__layout { grid-template-columns: 1fr 1.35fr; gap: 4.5rem; }
  .metrics {
    grid-template-columns: 1.7fr 1fr 1fr 1.15fr;
    gap: 0;
  }
  .metric { padding-left: 2.25rem; border-left: 1px solid var(--border); }
  .metric--lead { padding-left: 0; border-left: none; }
}

/* ════════════════════════════════════════════════════════════
   BLOCK 4 - Real case studies
   Four cards replace the three picsum placeholders. Card 01 has
   no live link yet (client domain unpurchased), so it renders as
   a static card with an explicit status line instead of a fake
   CTA. Media slots are typographic plates until Block 5 drops
   real screenshots in.
   ════════════════════════════════════════════════════════════ */

/* Typographic plate standing in for the screenshot */
.project-card__media--plate {
  display: flex;
  align-items: flex-end;
  min-height: 116px;
  padding: 1.25rem 1.5rem;
  background: var(--bg-surface);
  border-bottom: 1px solid var(--glass-border);
}

/* The frosted gradient belongs to photography, not to the plate */
.project-card__media--plate::after { display: none; }

/* Once a real screenshot fills the plate, the flex/padding meant for the
   ghost numeral no longer applies — the image takes the full figure and
   the frosted gradient (photography only) comes back. */
.project-card__media--plate:has(img) {
  display: block;
  padding: 0;
  min-height: 0;
}

.project-card__media--plate:has(img)::after { display: block; }

/* AI-integration angle, set apart from the body copy */
.project-note {
  font-size: 0.82rem;
  line-height: 1.6;
  color: var(--text-mid);
  padding-left: 0.9rem;
  border-left: 1px solid var(--glass-border);
  margin-top: 0.35rem;
}

.project-stack {
  font-size: 0.68rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--text-subtle);
  margin-top: 0.85rem;
}

.project-status {
  font-size: 0.62rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.18em;
  color: var(--text-muted);
  margin-top: 0.75rem;
}

/* Card 01 is not a link: no lift, so nothing invites a click */

/* Tablet 640px - the wide card closes the row instead of orphaning */
@media (min-width: 640px) {
  .project-card--wide { grid-column: span 2; }

  .project-card--featured .project-card__media--plate {
    min-height: 190px;
  }
}

/* Desktop 1024px - featured left, three stacked right */
@media (min-width: 1024px) {
  .projects-grid {
    grid-template-rows: auto auto auto;
  }

  .project-card--featured {
    grid-row: 1 / 4;
  }

  .project-card--wide {
    grid-column: 2;
  }

  .project-card--featured .project-card__media--plate {
    flex: 1;
    min-height: 200px;
  }

  /* The image absorbs the extra height from the 3-row span, not the text —
     otherwise .project-desc's flex:1 (sized for shorter cards) stretches
     into a dead gap between the description and the stack/status lines. */
  .project-card--featured .project-card__body,
  .project-card--featured .project-desc {
    flex: none;
  }
}

/* ════════════════════════════════════════════════════════════
   BLOCK 12 — Archive page (archive.html)

   A wall, not a gallery. The home page claims volume; this page is
   the evidence, so every kept piece is on screen at once and none
   of them opens.

   The tiles were originally desaturated at rest, to hold DESIGN.md §2's
   monochrome rule, with colour returning on hover. Jaime vetoed that:
   the work IS full-colour news graphics, and greying it out sells it
   short. The wall now shows the pieces as they were published, and the
   surrounding chrome carries the monochrome discipline instead.
   ════════════════════════════════════════════════════════════ */

/* The wall breaks wider than the 1140px reading measure. The masthead
   keeps the normal container; the grid does not. */
.container--wide { max-width: 1440px; }

/* ── Masthead — catalogue front matter, not a second hero ──── */
.archive-hero {
  /* clears the 72px fixed header on top of the usual section rhythm */
  padding: calc(72px + var(--section-py)) 0 0;
}

.archive-hero__layout {
  display: grid;
  gap: 3rem;
  align-items: start;
}

.archive-hero__eyebrow {
  font-size: 0.62rem;
  font-weight: 900;
  text-transform: uppercase;
  letter-spacing: 0.22em;
  color: var(--text-muted);
  margin-bottom: 1.35rem;
}

.archive-hero__title {
  font-size: clamp(2.3rem, 5.2vw, 4.1rem);
  max-width: 16ch;
  margin-bottom: 1.6rem;
}

.archive-hero__lead {
  font-size: clamp(1rem, 1.6vw, 1.12rem);
  line-height: 1.65;
  color: var(--text-mid);
  max-width: 58ch;
}

/* Figures use the hairline-row idiom already in the system
   (.estudio__meta, .timeline) rather than the metric band — this is
   front matter for a catalogue, not a stats strip. */
.archive-figures { border-top: 1px solid var(--border); }

.archive-figure {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
  padding: 1.05rem 0;
  border-bottom: 1px solid var(--border);
  transition: border-color var(--dur) var(--ease-out);
}
.archive-figure:hover { border-bottom-color: var(--border-hover); }

.archive-figure__label {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-muted);
}

.archive-figure__value {
  font-size: 1.45rem;
  font-weight: 900;
  letter-spacing: -0.025em;
  line-height: 1;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* The archive's own count outranks the borrowed CV figures */
.archive-figure--lead .archive-figure__value { font-size: 2.1rem; }

/* ── The wall ─────────────────────────────────────────────── */
.archive-wall {
  padding: var(--section-py) 0 calc(var(--section-py) * 0.65);
}

.archive-wall__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  padding-bottom: 1rem;
  margin-bottom: 2.25rem;
  border-bottom: 1px solid var(--border);
}

.archive-wall__label,
.archive-wall__count {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.2em;
  text-transform: uppercase;
}
.archive-wall__label { color: var(--text-muted); }
.archive-wall__count {
  color: var(--text-subtle);
  font-variant-numeric: tabular-nums;
}

/* Masonry via CSS columns — the technique the old build proved out.
   Roughly 88% of the pieces are square, so this reads as a dense grid
   rather than a ragged masonry. That is the intent. */
.archive-grid {
  --archive-gap: 0.6rem;
  column-count: 2;
  column-gap: var(--archive-gap);
}

.archive-tile {
  break-inside: avoid;
  -webkit-column-break-inside: avoid;
  page-break-inside: avoid;
  margin: 0 0 var(--archive-gap);
  position: relative;
}

/* Reveal and hover sit on different elements on purpose: both want to
   write `transform`, and `.reveal.is-visible` would fight a hover lift
   declared on the same node. */
.archive-tile.reveal:not(.is-visible) { transform: translateY(16px); }
.archive-tile:hover { z-index: 3; }

.archive-tile__frame {
  display: block;
  overflow: hidden;
  border-radius: var(--r-sm);
  border: 1px solid var(--glass-border);
  background: var(--bg-surface);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.05);
  transition:
    border-color 0.42s var(--ease-out),
    box-shadow   0.42s var(--ease-out),
    transform    0.42s var(--ease-out);
}

.archive-tile:hover .archive-tile__frame {
  transform: translateY(-3px);
  border-color: var(--border-hover);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.1),
    0 24px 44px -18px rgba(0, 0, 0, 0.85);
}

.archive-tile__img {
  width: 100%;
  height: auto;      /* the width/height attributes hold the ratio — CLS 0 */
  display: block;
  transition: transform 0.65s var(--ease-out);
}

.archive-tile:hover .archive-tile__img {
  transform: scale(1.045);
}

/* ── Outro — Behance demoted to a complement ──────────────── */
.archive-outro { padding-bottom: var(--section-py); }

.archive-outro__inner {
  border-top: 1px solid var(--border);
  padding-top: 2.5rem;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 1.35rem;
}

.archive-outro__text {
  font-size: 0.95rem;
  color: var(--text-muted);
  max-width: 48ch;
}

.archive-outro__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 1.25rem;
  align-items: center;
}

.archive-back {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.76rem;
  font-weight: 700;
  letter-spacing: 0.05em;
  color: var(--text-muted);
  transition: color var(--dur), gap 0.25s var(--ease-out);
}
.archive-back:hover { color: var(--text); gap: 0.62rem; }

/* ── Responsive ───────────────────────────────────────────── */
@media (min-width: 640px) {
  .archive-grid { column-count: 3; }
}

@media (min-width: 1024px) {
  /* Deliberately uneven, matching .estudio__layout */
  .archive-hero__layout {
    grid-template-columns: 1.4fr 1fr;
    gap: 4.5rem;
  }
  .archive-grid {
    column-count: 4;
    --archive-gap: 0.85rem;
  }
}

@media (min-width: 1440px) {
  .archive-grid { column-count: 5; }
}

/* ════════════════════════════════════════════════════════════
   BLOCK 14 — Services (Spanish only)

   Rescued from the old production site's pricing cards, rebuilt as
   hairline rows — the idiom .client and .timeline__item already use.
   DESIGN.md bans equal-width card grids; five price cards side by side
   is exactly that cliché, so the layout is a list instead. No badge,
   no highlighted tier, no accent colour — same restraint as the rest
   of the site.
   ════════════════════════════════════════════════════════════ */
.services-list {
  list-style: none;
  margin-top: 1.1rem;
  border-top: 1px solid var(--border);
}

.service-row {
  padding: 1.75rem 0;
  border-bottom: 1px solid var(--border);
  transition: border-color var(--dur) var(--ease-out);
}
.service-row:hover { border-bottom-color: var(--border-hover); }

.service-row__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1.5rem;
}

.service-row__name {
  font-size: 1.2rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--text);
  line-height: 1.3;
}

.service-row__price {
  flex-shrink: 0;
  text-align: right;
}

.service-row__amount {
  display: block;
  font-size: 1.2rem;
  font-weight: 900;
  letter-spacing: -0.02em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.service-row__unit {
  display: block;
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--text-muted);
  margin-top: 0.15rem;
}

.service-row__desc {
  font-size: 0.95rem;
  color: var(--text-mid);
  margin-top: 0.7rem;
  max-width: 52ch;
}

.service-row__includes {
  list-style: none;
  margin-top: 0.85rem;
}

.service-row__includes li {
  position: relative;
  padding-left: 1.1rem;
  font-size: 0.85rem;
  line-height: 1.65;
  color: var(--text-muted);
}

.service-row__includes li::before {
  content: '—';
  position: absolute;
  left: 0;
  color: var(--text-subtle);
}

.services-footer {
  display: flex;
  justify-content: center;
  margin-top: 3rem;
}

/* ════════════════════════════════════════════════════════════
   Archive card cover — the contact sheet on the home page

   The other three project cards each lead to a single site, so one
   screenshot describes them honestly. This one leads to 356 pieces,
   and a single screenshot undersold that: it looked like the other
   three. The media is a mosaic of real pieces, with the count set in
   the same big-number/small-label idiom the metrics band already uses,
   so it reads as native rather than as a badge stuck on top.
   ════════════════════════════════════════════════════════════ */
.project-card__media--mosaic { position: relative; }

/* A deeper scrim than the standard 64px frosted edge: the count sits
   over live artwork, so it needs its own ground to stay legible. */
.project-card__media--mosaic::after {
  height: 72%;
  background: linear-gradient(
    to top,
    rgba(8, 8, 8, 0.97) 0%,
    rgba(8, 8, 8, 0.88) 22%,
    rgba(8, 8, 8, 0.5) 55%,
    transparent 100%
  );
}

.archive-count {
  position: absolute;
  left: 1.5rem;
  bottom: 1.05rem;
  z-index: 2;
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  pointer-events: none;
}

.archive-count__num {
  font-size: 2.4rem;
  font-weight: 900;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.archive-count__label {
  font-size: 0.62rem;
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--text-mid);
}

@media (min-width: 640px) {
  .service-row__head { align-items: center; }
}
