:root {
  /* Color */
  --black:      #000000;
  --white:      #FFFFFF;
  --warm-50:    #707070; /* ~4.95:1 on white — passes WCAG AA (4.5:1) */
  --warm-20:    #D8D9DA;
  --warm-10:    #EDEDEE;
  --border:     rgba(155,156,158,0.22);
  --border-mid: rgba(155,156,158,0.45);
  --brand:      #25D366;

  /* Typography */
  --font-primary: 'Barlow', 'Helvetica Neue', Arial, sans-serif;
  --fw-light:     300;
  --fw-normal:    400;
  --fw-medium:    500;
  --fw-bold:      700;
  --text-2xs:     0.75rem;  /* 12px — floor for labels/tags */
  --text-xs:      0.8125rem;/* 13px */
  --text-sm:      0.875rem; /* 14px — buttons/nav */
  --text-base:    1rem;     /* 16px — WCAG min for body */
  --text-md:      1.0625rem;/* 17px */
  --text-lg:      1.125rem; /* 18px */
  --text-xl:      1.25rem;  /* 20px */
  --text-2xl:     1.5rem;   /* 24px */
  --text-3xl:     1.75rem;  /* 28px */
  --text-hero:    min(clamp(2.6rem, 6.5vw, 5rem), 10.5vh);
  --text-hero-sm: 2.6rem;
  --text-section: clamp(1.8rem, 3.5vw, 2.8rem);

  /* Letter-spacing (uppercase labels/buttons) */
  --ls-tight: 0.1em;
  --ls-caps:  0.16em;
  --ls-wide:  0.22em;

  /* Layout */
  --nav-h:      80px;
  --gutter:     150px;
  --gutter-md:  48px;
  --gutter-sm:  40px;

  /* Hero background — grid + logo reveal
     At REF_WIDTH the spacing equals BASE_SPACING; the JS scales the
     spacing proportionally to the viewport width:
       spacing = BASE_SPACING * (viewportWidth / REF_WIDTH) */
  --grid-ref-width: 1400px;
  --grid-base-spacing: 120px;

  /* Line draw + logo segment reveal timing */
  --line-draw-duration: 7s;
  --symbol-reveal-duration: 1.5s;
  --symbol-delay-2: 0.5s;
  --symbol-delay-3: 1s;
  --symbol-reveal-end: calc(var(--symbol-delay-3) + var(--symbol-reveal-duration) - 1s);
  /* --symbol-pulse-duration: 0.6s;
  --symbol-pulse-scale: 1.2; */

  /* Horizontal bounds of the VISIBLE logo within its image box. The brand
     PNG (assets/hero-symbol.png, 2000x1125) has wide transparent margins:
     the opaque glyphs span only ~37.15%–62.85% of the image width, so the
     reveal strips are measured against the visible content band, not the
     padded image box. Re-measure if the logo asset ever changes. */
  --logo-b0: 37.15%;
  --logo-b1: 45.7167%;
  --logo-b2: 54.2833%;
  --logo-b3: 62.85%;

  /* Breakpoints — custom properties can't be used inside @media queries,
     so these are documented here and hardcoded in the queries below:
     xxs 430px · xs 390px · sm 540px · md 640px · lg 900px · xl 1024px
     (v-1.02: xxs cap relaxed 375→430px so the fit-to-fold phone layout also
      covers iPhone 15/16/17 and Plus/Pro-Max-class phones, 393–430px, which
      real iOS Safari otherwise rendered with the looser xs→sm band. The
      xs→sm band floor moved 376→431px in lockstep. See the BREAKPOINT 1 /
      BREAKPOINT xs→sm blocks below for the commented-out old bounds.)
     NOTE: sm's cap was extended 480→540 so the compact phone styling also
     covers the Surface Duo single screen (540×720) and similar foldables,
     which otherwise fell into the md band and overflowed.
     NOTE: queries use fractional caps to catch sub-pixel viewport widths
     (devicePixelRatio rounding / zoom can report e.g. 375.5px, which an
     integer `max-width: 375px` misses). Convention: `max-width: N.98px`,
     and where a `min-width` seam-partner exists it tightens to `(N).99px`
     (376→375.99, 641→640.99, 1025→1024.99) — a 0.01px gap, no overlap.
     Lone top-end mins (1200/1500) keep integer values (no seam to close). */
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html {
  scroll-behavior: smooth;
  scroll-padding-top: var(--nav-h);
}

body {
  font-family: var(--font-primary);
  font-weight: var(--fw-normal);
  background: var(--white);
  color: var(--black);
  overflow-x: hidden;
  /* Keep the arrow cursor over text instead of the I-beam. */
  cursor: default;
}

/* CURSOR */
.cursor {
  width: 6px; height: 6px;
  background: var(--black);
  border-radius: 50%;
  position: fixed; top: 0; left: 0;
  pointer-events: none; z-index: 9999;
}
.cursor-ring {
  width: 28px; height: 28px;
  border: 1px solid rgba(0,0,0,0.3);
  border-radius: 50%;
  position: fixed; top: 0; left: 0;
  pointer-events: none; z-index: 9998;
  transition: all 0.3s cubic-bezier(0.25,0.46,0.45,0.94);
}
.cursor-ring.hovered { transform: scale(2.2); border-color: var(--black); }

/* NAV */
#navbar {
  position: fixed; top: 0; left: 0; right: 0;
  z-index: 100;
  padding: 16px var(--gutter);
  display: flex; align-items: center; justify-content: space-between;
  transition: all 0.4s ease;
  /* Transparency effect commented out — navbar is always white */
  /* background: rgba(255,255,255,0); */
  background: var(--white);
  /* Border visible from the start (previously only after scrolling) */
  border-bottom: 3px solid var(--border);
}
#navbar.scrolled {
  background: var(--white);
  /* backdrop-filter: blur(20px); */
  /* Navbar shrink-on-scroll disabled — keep base padding. */
  /* padding: 12px var(--gutter); */
  /* border-bottom: 2px solid var(--border); — moved to base nav so it shows from the start */
}
.nav-logo {
  display: flex; align-items: center; gap: 14px;
  text-decoration: none;
}
.nav-logo img {
  height: 46px; width: auto; display: block;
}
.nav-logo-name {
  font-size: var(--text-sm); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide); text-transform: uppercase;
  color: var(--warm-50); white-space: nowrap;
  padding-left: 14px; border-left: 1px solid var(--border);
}
@media (max-width: 540.98px) {
  .nav-logo-name {
    font-size: var(--text-2xs); letter-spacing: var(--ls-caps);
    padding-left: 10px; gap: 10px;
  }
  .nav-logo { gap: 10px; }
}
.nav-links {
  display: flex; align-items: center; gap: 24px;
  list-style: none;
  margin-left: auto;
}
.nav-links a {
  font-size: var(--text-sm); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); text-decoration: none;
  transition: color 0.3s;
}
.nav-links a:hover { color: var(--black); }
.nav-cta {
  background: var(--black) !important;
  border: 1px solid var(--black) !important;
  color: var(--white) !important;
  padding: 8px 22px;
  transition: all 0.3s !important;
}
.nav-cta:hover {
  background: var(--white) !important;
  color: var(--black) !important;
}

/* SELECTOR DE IDIOMA */
.lang-switcher {
  display: flex; align-items: center;
  /* gap: 4px; */
  margin-left: 24px;
}
.lang-btn {
  font-family: inherit; font-size: var(--text-xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-tight); color: var(--warm-50);
  background: none; border: none; cursor: pointer;
  padding: 4px 6px; transition: color 0.3s;
}
.lang-btn:hover { color: var(--black); }
.lang-btn.active { color: var(--black); font-weight: var(--fw-bold); }
/* Real-link language switcher (multi-page subpages use <a>, not <button>) */
a.lang-btn { text-decoration: none; display: inline-block; }
@media (max-width: 1024.98px) {
  .lang-switcher { display: none; }
}

/* NAV ACTIONS (idioma expandible + hamburguesa) */
.nav-actions {
  display: flex; align-items: center; gap: 6px;
}
.nav-actions .nav-hamburger { position: relative; z-index: 101; }
.nav-actions .lang-menu { z-index: 210; }

/* SELECTOR DE IDIOMA EXPANDIBLE (móvil / tablet) */
.lang-menu {
  position: relative;
  display: none;
  align-items: center;
}
.nav-lang-toggle {
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; padding: 0;
  background: none; border: 1px solid transparent;
  color: var(--black); /* cursor: none; */
  transition: border-color 0.3s;
}
.nav-lang-toggle svg { width: 24px; height: 24px; }
.nav-lang-toggle:hover { border-color: var(--border-mid); }
.lang-dropdown {
  display: none;
  position: absolute; top: calc(100% + 12px); right: 0;
  flex-direction: column;
  background: var(--white);
  border: 1px solid var(--border);
  box-shadow: 0 18px 40px rgba(0,0,0,0.08);
  min-width: 110px;
}
.lang-dropdown.open { display: flex; }
.lang-dropdown .lang-btn {
  padding: 11px 18px;
  font-size: var(--text-xs);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  text-align: left;
}
.lang-dropdown .lang-btn:hover { color: var(--black); background: var(--warm-10); }
.lang-dropdown .lang-btn.active { color: var(--black); font-weight: var(--fw-bold); }
@media (max-width: 1024.98px) {
  .lang-menu { display: flex; }
}

/* HERO */
#hero {
  min-height: 100svh;
  display: flex; align-items: stretch;
  position: relative; overflow: hidden;
  padding: clamp(48px, 8vh, 72px) var(--gutter) clamp(40px, 6vh, 64px);
  border-bottom: 1px solid var(--border);
  background: var(--white);
}
.hero-grid {
  position: absolute; inset: 0;
  pointer-events: none;
  overflow: hidden;
}
.hero-symbol {
  position: absolute;
  top: 50%; left: 50%;
  transform: translate(-50%, -58%);
  /* Proportional at every width — no px cap, so the backdrop scales with the
     viewport on large screens (was max-width:1200px). Mobile keeps its own
     larger vw override below. */
  width: 85vw;
  opacity: 0.15;
  pointer-events: none;
  user-select: none;
  /* animation: logoPulse var(--symbol-pulse-duration) ease-in-out var(--symbol-reveal-end) 1 forwards; */
}
.hero-symbol img { display: block; width: 100%; }

/* Keep the centring translate in every keyframe so the pulse only scales. */
/* @keyframes logoPulse {
  0%, 100% { transform: translate(-50%, -58%) scale(1); }
  50%      { transform: translate(-50%, -58%) scale(var(--symbol-pulse-scale)); }
} */

/* The logo is duplicated three times, each copy living in one of three
   equally-spaced vertical clipping regions that together cover the full
   logo; each region is revealed in place (no sliding), one after the other,
   with alternating wipe directions. */
.hero-symbol .seg-2,
.hero-symbol .seg-3 {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}
.hero-symbol .seg-2 img,
.hero-symbol .seg-3 img {
  position: absolute;
  top: 0; left: 0;
  width: 100%; height: 100%;
}

/* Vertical clipping regions: three equal strips across the VISIBLE logo
   content (see --logo-b* above). */
.hero-symbol .seg-1 { clip-path: inset(0 calc(100% - var(--logo-b1)) 0 var(--logo-b0)); } /* left third   */
.hero-symbol .seg-2 { clip-path: inset(0 calc(100% - var(--logo-b2)) 0 var(--logo-b1)); } /* middle third */
.hero-symbol .seg-3 { clip-path: inset(0 calc(100% - var(--logo-b3)) 0 var(--logo-b2)); } /* right third  */

/* In-place wipe: each copy stays centred and is masked progressively.
   seg-1 and seg-3 wipe top -> bottom, seg-2 wipes bottom -> top. */
.hero-symbol .seg-1 img,
.hero-symbol .seg-3 img {
  clip-path: inset(0 0 100% 0);
  animation: wipeTopDown var(--symbol-reveal-duration) cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
.hero-symbol .seg-2 img {
  clip-path: inset(100% 0 0 0);
  animation: wipeBottomUp var(--symbol-reveal-duration) cubic-bezier(0.22, 1, 0.36, 1) forwards;
}

/* Sequential: each region starts only after the previous one finished */
.hero-symbol .seg-1 img { animation-delay: 0s; }
.hero-symbol .seg-2 img { animation-delay: var(--symbol-delay-2); }
.hero-symbol .seg-3 img { animation-delay: var(--symbol-delay-3); }

@keyframes wipeTopDown {
  from { clip-path: inset(0 0 100% 0); }
  to   { clip-path: inset(0 0 0 0); }
}
@keyframes wipeBottomUp {
  from { clip-path: inset(100% 0 0 0); }
  to   { clip-path: inset(0 0 0 0); }
}

/* Grid lines — injected into .hero-grid by JS */
.line {
  position: absolute;
  background: var(--border);
  will-change: transform;
}
.line.h { left: 0; width: 100%; height: 1px; }
.line.v { top: 0; width: 1px; height: 100%; }
.line.dyn.h { transform: scaleX(0); }
.line.dyn.v { transform: scaleY(0); }
.line.dyn.h.lr { transform-origin: left center; }
.line.dyn.h.rl { transform-origin: right center; }
.line.dyn.v.tb { transform-origin: center top; }
.line.dyn.v.bt { transform-origin: center bottom; }
.line.dyn.h.play { animation: drawX var(--line-draw-duration) cubic-bezier(0.22, 1, 0.36, 1) forwards; }
.line.dyn.v.play { animation: drawY var(--line-draw-duration) cubic-bezier(0.22, 1, 0.36, 1) forwards; }
@keyframes drawX { to { transform: scaleX(1); } }
@keyframes drawY { to { transform: scaleY(1); } }

/* Respect reduced-motion: show every line immediately, no animation */
@media (prefers-reduced-motion: reduce) {
  .line.dyn.h { transform: scaleX(1); }
  .line.dyn.v { transform: scaleY(1); }
  .line.dyn.h.play,
  .line.dyn.v.play { animation: none; }
  .hero-symbol .seg-1 img,
  .hero-symbol .seg-2 img,
  .hero-symbol .seg-3 img { clip-path: inset(0); animation: none; }
  .hero-symbol { animation: none; }
}

.hero-wrap {
  position: relative;
  z-index: 2;
  width: 100%;
  display: flex; flex-direction: column;
  /* padding-left: clamp(76px, 11vh, 120px)
  padding-right: clamp(76px, 11vh, 120px) */
}

.hero-content {
  position: relative; z-index: 2;
  width: 100%;
  flex: 1;
  display: flex; align-items: center; justify-content: space-between;
  gap: 40px;
  /* padding: clamp(96px, 13vh, 150px) 0; */
  padding-top: clamp(96px, 13vh, 150px);
  padding-bottom: clamp(48px, 6.5vh, 75px);
}
.hero-left { max-width: 720px; }
@media (min-width: 1024.99px) {
  .hero-left { margin-top: -36px; margin-bottom: 48px; }
}

.hero-eyebrow {
  display: flex; align-items: center; gap: 14px;
  margin-bottom: 36px;
  opacity: 0; animation: fadeUp 0.8s 0.2s ease forwards;
}
.hero-eyebrow-line { width: 32px; height: 1px; background: var(--warm-50); }
.hero-eyebrow span {
  font-size: var(--text-xs); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-wide); text-transform: uppercase;
  color: var(--warm-50);
}

.hero-title {
  font-size: var(--text-hero);
  font-weight: var(--fw-light); line-height: 0.95;
  letter-spacing: -0.03em;
  color: var(--black);
  margin-bottom: clamp(18px, 3.5vh, 32px);
  opacity: 0; animation: fadeUp 0.8s 0.35s ease forwards;
}
.hero-title .outline {
  -webkit-text-stroke: 1px var(--black);
  color: transparent;
}

.hero-kicker {
  font-size: var(--text-xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide); text-transform: uppercase;
  color: var(--black); margin-bottom: 12px;
}
.hero-desc {
  font-size: var(--text-lg); font-weight: var(--fw-light); line-height: 1.2;
  color: var(--warm-50);
  max-width: 560px;
  opacity: 0; animation: fadeUp 0.8s 0.5s ease forwards;
}

.hero-right {
  display: flex; flex-direction: column; align-items: flex-end; gap: 40px;
  opacity: 0; animation: fadeIn 1s 0.9s ease forwards;
  flex-shrink: 0;
}
.hero-actions {
  display: flex; flex-direction: column; align-items: flex-end; gap: 14px;
}

/* STATS */
.hero-stats {
  position: absolute; bottom: 0; left: 0; right: 0;
  display: flex; gap: 60px;
    padding-top: clamp(16px, 3vh, 28px);
    /* padding-bottom: clamp(16px, 3vh, 28px); */
  /* padding: clamp(16px, 3vh, 28px) 0; */
  /* border-top: 1px solid var(--border); */
  opacity: 0; animation: fadeIn 1s 1s ease forwards;
  z-index: 2;
}
.stat-num {
  font-size: var(--text-2xl); font-weight: var(--fw-light);
  letter-spacing: -0.02em; color: var(--black); line-height: 1;
}
.stat-trust-title {
  font-size: var(--text-lg); font-weight: var(--fw-medium);
  letter-spacing: 0.01em; color: var(--black); line-height: 1.2;
  margin-bottom: 4px;
}
.stat-label {
  font-size: var(--text-2xs); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); margin-top: 6px;
}

/* BUTTONS */
.btn-primary {
  display: inline-flex; align-items: center; gap: 10px;
  background: var(--black); color: var(--white);
  font-family: inherit; font-size: var(--text-sm); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  text-decoration: none; padding: 14px 32px;
  border: 1px solid var(--black);
  transition: all 0.3s ease; /* cursor: none; */
}
.btn-primary:hover {
  background: transparent; color: var(--black);
}
.btn-primary svg { transition: transform 0.3s; }
.btn-primary:hover svg { transform: translateX(4px); }

.btn-secondary {
  display: inline-flex; align-items: center; gap: 8px;
  color: var(--warm-50); font-size: var(--text-sm); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  text-decoration: none; transition: color 0.3s; /* cursor: none; */
}
.btn-secondary:hover { color: var(--black); }

/* SECTIONS — single page, each fills the screen */
section {
  position: relative;
  min-height: 100svh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 72px var(--gutter);
  border-bottom: 1px solid var(--border);
}

/* Homepage full-screen panels — the SINGLE source of truth for panel height.
   The navbar is position:fixed (height --nav-h) and html { scroll-padding-top:
   var(--nav-h) } snaps each anchored panel's top to just BELOW it. So a panel
   must be one viewport MINUS the navbar for "panel below the navbar" to equal
   exactly one screen; a full 100svh runs --nav-h too tall (its bottom edge and
   the scroll-down cue fall past the fold, and the next panel peeks in). This
   was previously only applied on the xxs and short-desktop breakpoints, so on
   standard phones/tablets/tall desktops these panels were navbar-height too
   tall — the cross-device "taller on some, fits on others" bug. Applies to
   #servicios/#proyectos/#estudio/#contacto on every homepage (ES/EN/IT/FR) at
   every breakpoint. Token-driven, so the xxs --nav-h override (77px) flows
   through automatically. #hero is exempt: it sits at scroll-top with the navbar
   floating over it, so it fills the whole viewport. Standalone pages nest their
   sections in <main> (see the `main section` reset), so this never touches
   them. */
body > section:not(#hero) { min-height: calc(100svh - var(--nav-h)); }

/* Scroll-down arrow (pattern from sample single-page site) */
.scroll-down {
  position: absolute;
  bottom: 28px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 5;
  display: flex; align-items: center; justify-content: center;
  width: 40px; height: 40px;
  color: var(--warm-50);
  animation: scrollBounce 2.4s infinite ease-in-out;
  transition: color 200ms ease;
}
.scroll-down:hover { color: var(--black); }
@keyframes scrollBounce {
  0%,100% { transform: translateX(-50%) translateY(0); }
  50%     { transform: translateX(-50%) translateY(10px); }
}
/* Sections taller than the viewport: pin the cue to the bottom of the screen
   while the section is in view. */
section:not(#hero) .scroll-down {
  position: sticky;
  bottom: 24px;
  left: auto;
  transform: none;
  margin-top: auto;
  align-self: center;
  animation-name: scrollBounceY;
}
@keyframes scrollBounceY {
  0%,100% { transform: translateY(0); }
  50%     { transform: translateY(10px); }
}

.section-label {
  display: flex; align-items: center; gap: 14px; margin-bottom: 20px;
}
.section-label-line { width: 28px; height: 1px; background: var(--warm-50); }
.section-label span {
  font-size: var(--text-2xs); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-wide); text-transform: uppercase;
  color: var(--warm-50);
}
.section-title {
  font-size: var(--text-section);
  font-weight: var(--fw-light); line-height: 1.05;
  letter-spacing: -0.02em; margin-bottom: 20px;
  color: var(--black);
}

/* ABOUT */
#estudio { background: var(--white); }
.about-grid {
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 100px; align-items: start;
}
.about-body {
  font-size: var(--text-md); font-weight: var(--fw-light); line-height: 1.8;
  color: var(--warm-50); margin-bottom: 18px;
}
.about-features { margin-top: 48px; }
.about-feat {
  display: flex; align-items: flex-start; gap: 20px;
  padding: 20px 0; border-top: 1px solid var(--border);
}
.about-feat:last-child { border-bottom: 1px solid var(--border); }
.feat-num {
  font-size: var(--text-2xs); font-weight: var(--fw-medium); letter-spacing: var(--ls-caps);
  color: var(--warm-50); width: 28px; flex-shrink: 0; padding-top: 2px;
}
.feat-text strong {
  font-size: var(--text-md); font-weight: var(--fw-medium); letter-spacing: 0.04em;
  display: block; margin-bottom: 6px; color: var(--black);
}
.feat-text p {
  font-size: var(--text-base); font-weight: var(--fw-light);
  color: var(--warm-50); line-height: 1.6;
}
.about-right { display: flex; flex-direction: column; gap: 1px; background: var(--border); }
.about-card {
  background: var(--white); padding: 36px 32px;
  transition: background 0.3s;
}
.about-card:hover { background: var(--warm-10); }
.about-card-num {
  font-size: var(--text-2xs); font-weight: var(--fw-medium); letter-spacing: var(--ls-caps);
  color: var(--warm-50); margin-bottom: 14px; display: block;
}
.about-card h4 {
  font-size: var(--text-lg); font-weight: var(--fw-medium); letter-spacing: 0.03em;
  margin-bottom: 12px; color: var(--black);
}
.about-card p {
  font-size: var(--text-base); font-weight: var(--fw-light);
  color: var(--warm-50); line-height: 1.65;
}

/* SERVICIOS */
#servicios { background: var(--white); }
.services-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  margin-bottom: 60px; gap: 40px;
}
.services-note {
  max-width: 280px; font-size: var(--text-base); font-weight: var(--fw-light);
  color: var(--warm-50); line-height: 1.7; text-align: right;
}
.services-grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px; background: var(--border);
  border: 1px solid var(--border);
}
.service-card {
  background: var(--white); padding: 36px 28px;
  position: relative; transition: background 0.35s; /* cursor: none; */
}
.service-card:hover { background: var(--warm-10); }
.service-card::after {
  content: ''; position: absolute;
  bottom: 0; left: 0; width: 0; height: 1px;
  background: var(--black); transition: width 0.4s ease;
}
.service-card:hover::after { width: 100%; }
.service-number {
  font-size: var(--text-2xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide); color: var(--warm-50);
  margin-bottom: 20px; display: block;
}
.service-title {
  font-size: var(--text-lg); font-weight: var(--fw-medium);
  letter-spacing: 0.02em; margin-bottom: 14px; line-height: 1.3;
  color: var(--black);
}
.service-desc {
  font-size: var(--text-base); font-weight: var(--fw-light);
  line-height: 1.7; color: var(--warm-50);
}
.service-tags {
  display: flex; flex-wrap: wrap; gap: 6px; margin-top: 20px;
}
.service-tag {
  font-size: var(--text-2xs); letter-spacing: var(--ls-tight); text-transform: uppercase;
  color: var(--warm-50); border: 1px solid var(--border);
  padding: 4px 10px;
}
/* (The xxs service-title fit rule moved into the consolidated
   @media (max-width: 375.98px) block further down — see "SERVICIOS".) */

/* ══════════════════════════════════════════════════════════════
   ESTUDIO hub — 3-column grid (study-grid) + edge-lines effect
   Used by the homepage #estudio section and /estudio/. Three cards
   in a row; a hairline grid identical in look to .services-grid but
   with 3 columns instead of 4, and constrained/centred so the side
   lines have room to travel in from the viewport edges.
  ══════════════════════════════════════════════════════════════ */
.study-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 1px; background: var(--border);
  border: 1px solid var(--border);
  max-width: 1120px; margin-inline: auto;
}
@media (max-width: 900.98px) { .study-grid { grid-template-columns: 1fr; max-width: none; } }

/* Header row: H1 on the left, lead pinned to the right edge + right-aligned. */
.study-head-row {
  display: grid; grid-template-columns: minmax(0,1.05fr) minmax(0,1fr);
  gap: 48px; align-items: end;
}
.study-head-row :is(h1, h2) {
  font-size: clamp(1.7rem, 2.6vw, 2.3rem); line-height: 1.12;
  margin-bottom: 0; max-width: 22ch;
}
.study-head-row .hub-lead {
  font-size: var(--text-base); line-height: 1.5; max-width: 52ch;
  margin-bottom: 4px; justify-self: end; text-align: right;
}
@media (max-width: 900.98px) {
  .study-head-row { grid-template-columns: 1fr; gap: 16px; align-items: start; }
  .study-head-row .hub-lead { justify-self: start; text-align: left; }
}

.study-head-row .hub-lead p { margin: 0 0 10px; }
.study-head-row .hub-lead p:last-child { margin-bottom: 0; }

/* Edge-lines overlay: one line grows in from the left toward the left
   card and one in from the right toward the right card, synced to scroll;
   the moment a line reaches its card the card flashes its hover effect for
   0.5s (handled in JS via .drop-hit). Lines stop exactly on the card edge,
   so they never overlap the card body. The middle card has no line. */
.study-overlay { position: fixed; inset: 0; pointer-events: none; z-index: 1; }
.study-line { position: absolute; background: var(--border-mid); will-change: top, left, width, height; }
.study-grid .service-card { position: relative; z-index: 2; }
.study-grid .service-card.drop-hit { background: var(--warm-10); }
.study-grid .service-card.drop-hit::after { width: 100%; }

/* PROCESO */
#proceso { background: var(--white); }
.proceso-steps {
  display: grid; grid-template-columns: repeat(5, 1fr);
  margin-top: 64px; position: relative;
}
.proceso-steps::before {
  content: ''; position: absolute;
  top: 0; left: 0; right: 0; height: 1px;
  background: var(--border);
}
.proceso-step { padding: 36px 20px 0; }
.step-num {
  font-size: var(--text-2xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide); color: var(--warm-50);
  margin-bottom: 20px; display: block;
}
.step-title {
  font-size: var(--text-md); font-weight: var(--fw-medium);
  letter-spacing: 0.03em; margin-bottom: 12px; color: var(--black);
}
.step-desc {
  font-size: var(--text-base); font-weight: var(--fw-light);
  color: var(--warm-50); line-height: 1.65;
}

/* NORMAS */
#normas { background: var(--white); }
.normas-grid {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: 1px; background: var(--border);
  border: 1px solid var(--border); margin-top: 56px;
}
.norma-card {
  background: var(--white); padding: 40px 36px;
  transition: background 0.3s;
}
.norma-card:hover { background: var(--warm-10); }
.norma-badge {
  font-size: var(--text-2xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); display: block; margin-bottom: 20px;
}
.norma-card h4 {
  font-size: var(--text-lg); font-weight: var(--fw-medium);
  margin-bottom: 12px; color: var(--black);
}
.norma-card p {
  font-size: var(--text-base); font-weight: var(--fw-light);
  color: var(--warm-50); line-height: 1.65;
}

/* CONTACTO */
/* Height comes from the global `body > section:not(#hero)` rule. */
#contacto { background: var(--white); border-bottom: none; position: relative; align-items: center; }

/* Static brand-logo backdrop — the hero symbol at rest (no wipe/pulse),
   sitting faintly behind the contact content. Reused on /contacto/. */
.contacto-bg {
  position: absolute; inset: 0;
  overflow: hidden; pointer-events: none;
  z-index: 0;
}
.section-symbol {
  position: absolute; top: 50%; left: 50%;
  transform: translate(-50%, -52%);
  /* Proportional at every width — no px cap (was max-width:1040px). */
  width: 72vw;
  opacity: 0.06;
  user-select: none; -webkit-user-drag: none;
}
.contacto-grid {
  position: relative; z-index: 1;
  display: grid; grid-template-columns: 1fr 1fr;
  gap: 100px; align-items: start;
}
.contacto-left > p {
  font-size: var(--text-md); font-weight: var(--fw-light);
  color: var(--warm-50); line-height: 1.75; margin-bottom: 20px;
}
.contact-microcopy {
  font-size: var(--text-sm) !important; font-weight: var(--fw-medium) !important;
  letter-spacing: 0.04em; color: var(--black) !important;
  margin-bottom: 40px !important;
}
.whatsapp-btn {
  display: inline-flex; align-items: center; gap: 10px;
  margin-top: 32px;
  background: var(--brand); color: var(--white);
  font-family: inherit; font-size: var(--text-sm); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-tight); text-transform: uppercase;
  text-decoration: none; padding: 14px 28px;
  border: 1px solid var(--brand);
  transition: all 0.3s ease; /* cursor: none; */
}
.whatsapp-btn:hover { background: transparent; color: var(--brand); }
.whatsapp-btn svg { flex-shrink: 0; }

/* Mobile contact CTA — "or" divider + secondary button that opens the contact
   form full-screen. All three are desktop-hidden (the form shows inline there);
   the ≤md rules below reveal them. Same shape as .whatsapp-btn, inverted colours. */
.contact-or { display: none; }
.contact-form-btn {
  display: none; align-items: center; justify-content: center; gap: 10px;
  background: var(--black); color: var(--white);
  font-family: inherit; font-size: var(--text-sm); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-tight); text-transform: uppercase;
  text-decoration: none; padding: 14px 28px; border: 1px solid var(--black);
  cursor: pointer; transition: all 0.3s ease;
}
.contact-form-btn:hover { background: transparent; color: var(--black); }
.contact-form-btn svg { flex-shrink: 0; }
.contact-form-close { display: none; }

@media (max-width: 768.98px) {
  /* contact_desc: tighter line-height + spacing */
  #contacto .contacto-left > p:first-of-type { line-height: 1.4; margin-bottom: 10px; }
  /* microcopy: margin-bottom −50% (was 40px) */
  #contacto .contact-microcopy { margin-bottom: 20px !important; }
  /* contact-item: vertical padding −50% (was 20px) */
  #contacto .contact-item { padding: 10px 0; }
  /* WhatsApp button centred */
  #contacto .whatsapp-btn { display: flex; width: fit-content; margin-left: auto; margin-right: auto; }
  /* "or" divider + secondary button, centred (mobile only) */
  #contacto .contact-or {
    display: block; text-align: center; margin: 14px 0;
    color: var(--warm-50); font-size: var(--text-sm); font-weight: var(--fw-medium);
    letter-spacing: 0.04em; text-transform: uppercase;
  }
  #contacto .contact-form-btn { display: flex; width: fit-content; margin-left: auto; margin-right: auto; }
  /* Form hidden by default; opens full-screen */
  #contacto .contact-form-panel { display: none; }
  #contacto .contact-form-panel.is-open {
    display: block; position: fixed; inset: 0; z-index: 500;
    background: var(--white); overflow-y: auto;
    padding: 60px var(--gutter-sm) 32px;
    opacity: 1; transform: none;   /* neutralise any .reveal transform */
  }
  #contacto .contact-form-panel.is-open .contact-form-close {
    display: flex; position: fixed; top: 12px; right: 12px; z-index: 501;
    width: 36px; height: 36px; align-items: center; justify-content: center;
    background: var(--white); border: 1px solid var(--border); border-radius: 50%;
    font-size: 22px; line-height: 1; color: var(--black); cursor: pointer;
    box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  }
  body.contact-open { overflow: hidden; }

  /* ≤768px = mobile layout (task 2): single-column contact, and the "Mensaje"
     textarea grows proportionally with viewport height. */
  #contacto .contacto-grid,
  .page-wrap .contacto-grid { grid-template-columns: 1fr; gap: 60px; }
  #contacto .form-row,
  .page-wrap .form-row { grid-template-columns: 1fr; }
  #contacto .contact-form-panel .form-group textarea,
  .page-wrap .contact-form-panel .form-group textarea { min-height: clamp(180px, 36vh, 400px); }
}

/* >lg (>900px) = desktop 2-column contact. The 2-column layout is now used ONLY
   above lg; through this narrow-desktop band the left column is tightened and the
   grid gap reduced so the section still fits one screen at widths just above the
   divide. (≤900px collapses to one column — see the min-width:768.99 block below
   and the ≤768.98 mobile block above.) */
@media (min-width: 900.99px) and (max-width: 1024.98px) {
  #contacto .contacto-grid,
  .page-wrap .contacto-grid { gap: 48px; }
  #contacto .contacto-left > p,
  .page-wrap .contacto-left > p { line-height: 1.5; margin-bottom: 12px; }
  #contacto .contact-microcopy,
  .page-wrap .contact-microcopy { margin-bottom: 20px !important; }
  #contacto .contact-item,
  .page-wrap .contact-item { padding: 12px 0; }
  #contacto .whatsapp-btn,
  .page-wrap .whatsapp-btn { margin-top: 20px; }
}

/* Contacto: single column from lg down (769–900px). Together with the ≤768.98px
   mobile block this makes the whole ≤900px range one column, so the 2-column
   contact layout is used ONLY above lg (>900px). Applies to the homepage
   #contacto section and the standalone /contacto/ page. (Was 2-column here.) */
@media (min-width: 768.99px) and (max-width: 900.98px) {
  #contacto .contacto-grid,
  .page-wrap .contacto-grid { grid-template-columns: 1fr; gap: 60px; }
}

/* Botón flotante WhatsApp (toda la web) */
.whatsapp-float {
  position: fixed; bottom: 28px; right: 28px;
  width: 56px; height: 56px;
  background: var(--brand); border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 16px rgba(0,0,0,0.18);
  z-index: 200; /* cursor: none; */
  transition: transform 0.3s ease;
}
.whatsapp-float:hover { transform: scale(1.08); }
.whatsapp-float svg { width: 30px; height: 30px; fill: var(--white); }

.contact-details { display: flex; flex-direction: column; gap: 0; }
.contact-item {
  display: flex; align-items: flex-start; gap: 20px;
  padding: 20px 0; border-top: 1px solid var(--border);
}
.contact-item:last-child { border-bottom: 1px solid var(--border); }
.contact-label {
  font-size: var(--text-2xs); letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); margin-bottom: 5px; width: 70px; flex-shrink: 0; padding-top: 2px;
}
.contact-value {
  font-size: var(--text-md); font-weight: var(--fw-normal);
  color: var(--black); text-decoration: none; transition: color 0.3s;
}
.contact-value:hover { color: var(--warm-50); }

/* FORM */
.contact-form { display: flex; flex-direction: column; gap: 0; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; }
.form-group { display: flex; flex-direction: column; }
.form-group label {
  font-size: var(--text-2xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); padding: 14px 20px 0;
}
.form-group input,
.form-group select,
.form-group textarea {
  background: transparent;
  border: none;
  color: var(--black);
  font-family: inherit; font-size: var(--text-md); font-weight: var(--fw-light);
  padding: 10px 20px 14px;
  outline: none; transition: border-color 0.3s;
  -webkit-appearance: none; appearance: none;
}
/* A focused field draws a hairline accent along its own bottom edge without
   nudging siblings (inset shadow, not a border, so layout never shifts). */
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus { box-shadow: inset 0 -1px 0 0 var(--black); }
.form-group textarea { resize: vertical; min-height: 150px; }
.form-group select {
  cursor: pointer; padding-right: 44px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3 5l4 4 4-4' stroke='%23707070' stroke-width='1.4' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 20px center;
}
.form-group select option { background: var(--white); color: var(--black); }
.form-group input::placeholder,
.form-group textarea::placeholder { color: var(--warm-20); font-weight: var(--fw-light); }

/* Contact-form frame: a single hairline box that divides its fields with
   internal rules (top border on every stacked field; a vertical rule between
   the paired name/company row). The bottom edge is closed by .form-submit. */
.contact-frame {
  position: relative;
  border: 1px solid var(--border); border-bottom: none;
  overflow: hidden;
  transition: border-color 0.4s ease;
}
.contact-frame > .form-group { border-top: 1px solid var(--border); }
.form-row .form-group:first-child { border-right: 1px solid var(--border); }
.form-group.full { border-right: none !important; }
.form-submit {
  display: flex; align-items: center; justify-content: space-between;
  padding: 24px 20px; border-top: 1px solid var(--border);
  border-bottom: 1px solid var(--border);
}

/* Hover / scroll-in reveal: the frame's border deepens and a brand-green
   hairline draws across the top edge — the same architectural line-draw as
   the hero grid. `.frame-lit` is toggled by contact-frame.js when the frame
   scrolls into view; hovering the form produces the identical state. */
/* .contact-frame::before {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: var(--brand);
  transform: scaleX(0); transform-origin: left center;
  transition: transform 0.9s cubic-bezier(0.22, 1, 0.36, 1);
  z-index: 3;
} */
.contact-frame.frame-lit,
.contact-form:hover .contact-frame { border-color: var(--border-mid); }
.contact-frame.frame-lit::before,
.contact-form:hover .contact-frame::before { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .contact-frame::before { transition: none; }
}
.form-note {
  font-size: var(--text-sm); font-weight: var(--fw-light); color: var(--warm-50);
  max-width: 200px; line-height: 1.5;
}

/* CREDIT LINE — below #contacto on all pages */
.credit-line {
  position: relative; z-index: 1;
  margin-top: 48px; text-align: center;
  font-size: var(--text-2xs); color: var(--warm-50);
}
.credit-line a {
  color: var(--warm-50); text-decoration: none;
  vertical-align: middle; margin-left: 6px;
  transition: color 0.2s ease;
}
.credit-line a:hover { color: var(--black); }
.credit-line svg {
  width: 14px; height: 14px; vertical-align: -2px;
  fill: none; stroke: currentColor; stroke-width: 1.5;
  stroke-linecap: round; stroke-linejoin: round;
}

/* ANIMATIONS */
@keyframes fadeUp {
  from { opacity: 0; transform: translateY(28px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes fadeIn {
  from { opacity: 0; } to { opacity: 1; }
}
.reveal {
  opacity: 0; transform: translateY(28px);
  transition: opacity 0.7s ease, transform 0.7s ease;
}
.reveal.visible { opacity: 1; transform: translateY(0); }

/* RESPONSIVE */
@media (max-width: 1024.98px) {
  #navbar { padding: 12px var(--gutter-md); }
  /* Navbar shrink-on-scroll disabled */
  /* nav.scrolled { padding: 10px var(--gutter-md); } */
  #hero { padding: clamp(48px, 8vh, 72px) var(--gutter-md) clamp(40px, 6vh, 64px); }
  section { padding: 48px var(--gutter-md); }
  .about-grid { grid-template-columns: 1fr; gap: 60px; }
  .services-grid { grid-template-columns: repeat(2, 1fr); }
  .proceso-steps { grid-template-columns: repeat(3, 1fr); }
  .normas-grid { grid-template-columns: repeat(2, 1fr); }
  .services-header { flex-direction: column; align-items: flex-start; }
  .services-note { text-align: left !important; }
}
/* HAMBURGER BUTTON */
.nav-hamburger {
  display: none;
  flex-direction: column; justify-content: center;
  gap: 5px; background: none; border: none;
  cursor: pointer; padding: 4px; z-index: 101;
}
.nav-hamburger span {
  display: block; width: 24px; height: 1.5px;
  background: var(--black);
  transition: all 0.3s ease;
  transform-origin: center;
}
.nav-hamburger.open span:nth-child(1) { transform: translateY(6.5px) rotate(45deg); }
.nav-hamburger.open span:nth-child(2) { opacity: 0; }
.nav-hamburger.open span:nth-child(3) { transform: translateY(-6.5px) rotate(-45deg); }

/* MOBILE MENU OVERLAY */
.nav-mobile-menu {
  display: none;
  position: fixed; inset: 0;
  background: var(--white);
  z-index: 99;
  flex-direction: column;
  justify-content: center; align-items: center;
}
.nav-mobile-menu.open { display: flex; }
.nav-mobile-menu a {
  font-size: var(--text-3xl); font-weight: var(--fw-light);
  letter-spacing: -0.01em;
  color: var(--black); text-decoration: none;
  padding: 18px 0;
  border-bottom: 1px solid var(--border);
  width: 80%; text-align: center;
  transition: color 0.2s;
}
.nav-mobile-menu a:first-child { border-top: 1px solid var(--border); }
.nav-mobile-menu a:hover,
.nav-mobile-menu a.nav-active { color: var(--warm-50); }
.nav-mobile-menu a.nav-cta {
  margin-top: 28px; border: 1px solid var(--black) !important;
  padding: 16px 40px; width: auto;
  font-size: var(--text-base); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
}

@media (max-width: 1024.98px) {
  .nav-links { display: none; }
  .nav-hamburger { display: flex; }
}

@media (max-width: 640.98px) {
  #navbar { padding: 10px var(--gutter-sm); }
  /* Navbar shrink-on-scroll disabled */
  /* nav.scrolled { padding: 6px var(--gutter-sm); } */
  .nav-logo img { height: 40px; }
  section { padding-left: var(--gutter-sm); padding-right: var(--gutter-sm); }
  #hero { min-height: 100svh; align-items: flex-start; padding: 56px var(--gutter-sm) 32px; }
  /* Background logo: larger + centred on the hero content (same as xxs, ≤375px) */
  .hero-symbol { width: 183vw; top: calc(54.5vh - 28px); transform: translate(-50%, -50%); }
  .hero-content { flex-direction: column; align-items: flex-start; gap: 20px; margin-bottom: 28px !important; padding: 0; }
  .hero-left { max-width: 100%; }
  .hero-right { width: 100%; align-items: flex-start; gap: 16px; }
  .hero-actions { width: 100%; align-items: stretch; gap: 12px; }
  .btn-primary { width: 100%; justify-content: center; box-sizing: border-box; padding: 12px 20px; }
  .hero-title { font-size: min(var(--text-hero-sm), 9.5vw); line-height: 1; margin-bottom: 20px; }
  .hero-kicker { margin-bottom: 8px; }
  .hero-desc { font-size: var(--text-base); line-height: 1.5; }
  .hero-stats { flex-wrap: wrap; gap: 12px; margin-top: 20px; padding: 10px 0; position: static; }
  .stat-trust-title { font-size: var(--text-base); }
  .stat-label { font-size: var(--text-2xs); }
  .scroll-down { bottom: 12px; }
  .services-grid { grid-template-columns: 1fr; }
  .proceso-steps { grid-template-columns: repeat(2, 1fr); }
  .normas-grid { grid-template-columns: 1fr; }
  .form-row { grid-template-columns: 1fr; }
  .proy-card { grid-template-columns: 1fr; }
  .proy-carousel { min-height: 260px; }
}

/* Short viewports (compact laptops / landscape phones): keep hero within the fold */
/* Short viewport heights: pull the hero content up so it clears the
   bottom-anchored .hero-stats row (prevents desc/stats overlap ~620–860px tall). */
@media (min-width: 1024.99px) and (max-height: 860px) {
  .hero-left { margin-top: -72px; }
}

@media (max-height: 620px) {
  #hero { padding-top: 56px; padding-bottom: 36px; }
  .hero-title { font-size: min(2.6rem, 8vh, 9.5vw); margin-bottom: 16px; }
  .hero-content { margin-bottom: 24px; gap: 24px; padding: 0; }
  .hero-kicker { margin-bottom: 8px; }
  .hero-desc { max-width: 420px; font-size: var(--text-base); line-height: 1.5; }
  .hero-right { gap: 16px; }
  .hero-stats { margin-top: 20px; padding: 12px 0; gap: 20px; position: static; }
  .scroll-down { bottom: 12px; }
}

/* ═══════════════════════════════════════════════════════════════
   COMPACT LAPTOPS — wide viewport, short height (e.g. 14" screens,
   ~640–800px tall). The hero got a short-viewport pass above, but
   every OTHER homepage section and the standalone pages used fixed
   (non-vh) vertical padding tuned for tall desktops — so on a short
   screen their content (lower cards + the scroll-down cue) overran
   the fold. This is why the hero fit but nothing else did.

   Fix: scale the vertical rhythm to the viewport height. The
   `min-width` guard keeps phones/tablets (own width-based blocks)
   untouched; every clamp ceiling equals the property's existing base
   value, so these rules only ever REMOVE space on short screens.
   Selectors are wrapper-scoped (`body > section`, `main.<wrap>`,
   `.<wrap> .<child>`) so they outspecify the per-page inline <style>
   padding that loads after this file — no !important needed.
  ══════════════════════════════════════════════════════════════ */
@media (min-width: 1024.99px) and (max-height: 860px) {
  /* --- Homepage panels (direct <body> children; hero excluded) --- */
  /* Panel HEIGHT (100svh − navbar) is now handled globally by the base
     `body > section:not(#hero)` rule; here we only tighten the vertical padding
     so the (now shorter) content still clears the fold on short screens. */
  body > section:not(#hero) {
    padding-top: clamp(28px, 5vh, 72px);
    padding-bottom: clamp(28px, 5vh, 72px);
  }
  /* Pin the scroll cue to the section's bottom-centre (the sticky/margin-auto
     default drifts once the section fits the fold). */
  body > #servicios > .scroll-down,
  body > #proyectos > .scroll-down,
  body > #estudio > .scroll-down {
    position: absolute;
    bottom: 14px;
    left: 50%; right: auto;
    transform: translateX(-50%);
    margin-top: 0;
  }
  body > section:not(#hero) .hub-head :is(h1, h2),
  body > section:not(#hero) .page-hero :is(h1, h2) { margin-bottom: clamp(10px, 1.8vh, 20px); }
  body > section:not(#hero) .hub-grid-section { padding-top: clamp(14px, 2.6vh, 24px); }
  body > #proyectos .page-hero { padding-bottom: clamp(4px, 1vh, 8px); }

  /* --- Standalone pages (content lives inside <main>) --- */
  main.hub-wrap, main.page-wrap { padding-top: var(--nav-h); }
  main.svc-wrap {
    padding-top: calc(var(--nav-h) + clamp(16px, 3vh, 48px));
    padding-bottom: clamp(40px, 7vh, 96px);
  }
  .hub-wrap .hub-head { padding-top: clamp(16px, 3.5vh, 64px); }
  .page-wrap .page-hero { padding-top: clamp(24px, 4vh, 64px); }
  .hub-wrap .hub-grid-section { padding-top: clamp(16px, 3vh, 40px); }
  .page-wrap .page-section { padding-top: clamp(20px, 3.5vh, 40px); }
  .hub-wrap .hub-cta,
  .page-wrap .page-cta {
    margin-top: clamp(20px, 4vh, 48px);
    margin-bottom: clamp(28px, 5vh, 96px);
  }
  .svc-wrap .svc-cta { margin-top: clamp(28px, 4.5vh, 56px); }

  /* ── Trimming the vertical rhythm above was not enough on the shortest
        screens: the section CONTENT itself (card copy, the proyectos tile
        block, the contact column) still ran past the fold. Below we shrink
        that content per section. These override per-page inline <style>
        font/spacing (which loads after this file), so they need !important. */

  /* SERVICIOS — shrink the headers and tags at BOTH tiers so the section fits.
     Tier-1 = the section H1 + the four category cards (title/tags/padding).
     Tier-2 = the hover-fork leaf boxes (title/tags/padding). */
  /* Tier-1 section header (homepage #servicios + servicios hub). */
  body > #servicios .hub-head-row :is(h1, h2),
  .hub-wrap .hub-head-row h1 { font-size: clamp(1.3rem, 2vw, 1.75rem) !important; }
  /* Tier-1 category cards. */
  .services-grid .service-title,
  .svc-cards .service-title { font-size: var(--text-xs) !important; line-height: 1.2 !important; }
  .services-grid .service-desc,
  .svc-cards .service-desc { font-size: var(--text-2xs) !important; line-height: 1.4 !important; margin-top: 6px !important; }
  .services-grid .service-tags,
  .svc-cards .service-tags { margin-top: 7px !important; }
  .services-grid .service-tag,
  .svc-cards .service-tag { font-size: 0.625rem !important; padding: 2px 6px !important; }
  .services-grid .service-card { padding: 10px 14px !important; }
  .svc-cards .service-card { padding: 12px 14px !important; }
  /* Tier-2 hover-fork leaf boxes — ~20% tighter for this short format:
     padding (10→8px), title font (×0.8), and the gap above "Ver servicio"
     (svc-more margin-top 10→8px). */
  a.svc-fork-box { padding: 5px 10px !important; }
  a.svc-fork-box .service-title { font-size: calc(var(--text-sm) * 0.8) !important; line-height: 1.2 !important; }
  a.svc-fork-box .service-tags { margin-top: 4px !important; }
  a.svc-fork-box .service-tag { font-size: 0.5625rem !important; padding: 1px 3px !important; }
  a.svc-fork-box .svc-more { margin-top: 4px !important; }

  /* PROYECTOS — shrink the desktop showcase container + its margins so the
     tile block fits under the header. `.proy-bg-grid .proy-showcase`
     out-specifies the base `.proy-showcase` desktop rule below. */
  .proy-bg-grid .proy-showcase {
    height: clamp(240px, 39vh, 493px);
    margin-top: clamp(14px, 2.4vh, 48px);
    margin-bottom: clamp(14px, 2.4vh, 48px);
  }

  /* ESTUDIO — tighten the study cards: padding, inner margins and line
     heights (their desktop state uses the generous base .service-card sizes). */
  .study-grid .service-card { padding: 16px 20px !important; }
  .study-grid .service-number { margin-bottom: 8px !important; }
  .study-grid .service-title { font-size: var(--text-base) !important; margin-bottom: 8px !important; line-height: 1.2 !important; }
  .study-grid .service-desc { font-size: var(--text-sm) !important; line-height: 1.45 !important; }
  .study-grid .service-tags { margin-top: 10px !important; }
  .study-grid .svc-more { margin-top: 8px !important; }
  .study-head-row .hub-lead { line-height: 1.4 !important; }
  .study-head-row .hub-lead p { margin-bottom: 6px !important; }

  /* CONTACTO — tighten the left column (intro copy, microcopy, contact rows,
     CTA) so it stays within the fold alongside the form column. */
  #contacto .contacto-left > p,
  .page-wrap .contacto-left > p { line-height: 1.4 !important; margin-bottom: 10px !important; }
  #contacto .contact-microcopy,
  .page-wrap .contact-microcopy { margin-bottom: 16px !important; }
  #contacto .contact-item,
  .page-wrap .contact-item { padding: 8px 0 !important; }
  #contacto .whatsapp-btn,
  .page-wrap .whatsapp-btn { margin-top: 16px !important; }
  /* "Mensaje" textarea ~40% shorter (base min-height 150px → 90px). */
  #contacto .form-group textarea,
  .page-wrap .form-group textarea { min-height: 90px !important; }
}

/* ═══════════════════════════════════════════════════════════════
   TALL PORTRAIT TABLETS — nudge homepage panels toward centre
   The mirror image of the short-laptop block above: on tall portrait
   tablets (e.g. iPad Air 820×1180, iPad mini 768×1024) the full-height
   homepage panels (#servicios/#proyectos/#estudio) have far MORE height
   than their content. Each panel centres via `justify-content:center`,
   but `.scroll-down`'s `margin-top:auto` (see the base rule) absorbs all
   the free space and pins the content to the TOP — leaving a big empty
   band below. Add a height-scaled top padding so the content sits nearer
   the middle. Not a true centre (per request — "just add some padding-
   top"); the scroll-down cue stays pinned at the bottom. #hero fills the
   viewport on its own and #contacto centres its own grid, so both are
   excluded. Width band = portrait tablets (phones have their own blocks
   and desktops are >1024); the min-height guard means only genuinely
   tall screens — where the gap actually shows — are affected.
  ══════════════════════════════════════════════════════════════ */
@media (min-width: 640.99px) and (max-width: 1024.98px) and (min-height: 900px) {
  body > section:not(#hero):not(#contacto) { padding-top: clamp(88px, 16vh, 240px); }
}

/* ═══════════════════════════════════════════════════════════════
   LEVEL-2 CONTENT PAGES (≤768.98px) — servicios + estudio leaves /
   categories. Their long-form .svc-* prose keeps desktop font-sizes +
   loose leading down to phone widths; here we reduce both so the reading
   density matches the homepage and the level-1 hub pages. Scoped to
   .svc-wrap (the content-column pages only) and !important because each
   page's base .svc-* rules live in a per-page inline <style> that loads
   after this file. (task 3)
  ══════════════════════════════════════════════════════════════ */
@media (max-width: 768.98px) {
  .svc-wrap h1 { font-size: clamp(1.6rem, 5.2vw, 2rem) !important; line-height: 1.1 !important; margin-bottom: 16px !important; }
  .svc-lead { font-size: var(--text-base) !important; line-height: 1.5 !important; margin-bottom: 28px !important; }
  .svc-wrap h2 { font-size: var(--text-xl) !important; line-height: 1.2 !important; margin: 32px 0 12px !important; }
  .svc-wrap h3 { font-size: var(--text-md) !important; margin: 22px 0 6px !important; }
  .svc-wrap p,
  .svc-wrap li { font-size: var(--text-base) !important; line-height: 1.55 !important; }
  .svc-wrap p { margin-bottom: 14px !important; }
  .svc-wrap li { margin-bottom: 6px !important; }
  .svc-steps li { padding-left: 44px !important; margin-bottom: 16px !important; }
}

/* ═══════════════════════════════════════════════════════════════
   BREAKPOINT 1 — xxs / small + standard phones (≤430.98px, was ≤375.98px)
   Single consolidated xxs block (merged from the three separate
   max-width:375.98px blocks that used to live here). Site-wide: every
   page links this file across all four language trees. Ordered by page
   section — SHARED, then HERO · SERVICIOS · PROYECTOS · ESTUDIO ·
   CONTACTO — mirroring the homepage's own section order.
   Homepage sections are scoped by #id; standalone pages by their wrapper
   class (.hub-wrap / .page-wrap / .svc-wrap) so these rules never leak
   onto the homepage (which reuses the same inner classes). !important is
   used throughout because each page's own values live in a per-page
   inline <style> that loads AFTER this file (and the ≤540px block below).

   v-1.02 — cap RELAXED 375.98 → 430.98px so iPhone 15/16/17 (393–402px)
   and the Plus/Pro-Max class (430px) get this same fit-to-fold layout.
   Real iOS Safari rendered these 393px+ phones with the looser xs→sm band
   (they missed the ≤375.98 cap), so the hero ran taller than in DevTools
   device-mode and the stats/scroll-cue fell past the fold. The paired
   seam below (was `min-width:375.99px`) is raised to 430.99px in lockstep
   so the two bands still meet with no overlap.
  ══════════════════════════════════════════════════════════════ */
/* OLD (pre-v-1.02): @media (max-width: 375.98px) { */
@media (max-width: 430.98px) {

  /* ══ SHARED ═══════════════════════════════════════════════════ */
  /* Correct --nav-h to the REAL xxs navbar height. Here #navbar is
     padding 10+10 (≤640.98px block) + a 54px logo + a 3px bottom border
     = 77px, but the token still said 80px. That 3px gap made
     scroll-padding-top (80px) overshoot the navbar (77px), so every
     anchored non-hero section landed 3px too low and exposed a sliver of
     the preceding section under the navbar. Overriding the token fixes
     scroll-padding-top, the section min-height calcs (100svh − nav-h) and
     #contacto in one place — all of which had over-reserved by 3px. */
  :root { --nav-h: 77px; }
  .nav-logo img { height: 54px; }
  .credit-line { font-size: 0.6875rem; }
  /* Drop every eyebrow / overline. */
  .hub-eyebrow, .page-eyebrow { display: none !important; }
  /* .page-lead only ever appears in proyectos contexts — drop it. */
  .page-lead { display: none !important; }

  /* Standalone pages — non-hero section padding −50% (homepage sections
     are handled per-#id in their section blocks below). */
  .hub-wrap .hub-head { padding-top: 32px !important; padding-bottom: 0 !important; }
  .hub-wrap .hub-cta { padding: 22px !important; margin-bottom: 48px !important; }
  /* estudio-family hub grid (estudio hub + oficinas): halved again for the
     estudio density pass — was 20/44, now 10/22. */
  .hub-wrap .hub-grid-section { padding-top: 10px !important; padding-bottom: 22px !important; }
  /* Servicios hub is already compact — halve on its own smaller scale. */
  .hub-wrap:has(.services-grid) .hub-head { padding-top: 8px !important; padding-bottom: 0 !important; }
  .hub-wrap:has(.services-grid) .hub-grid-section { padding-top: 8px !important; padding-bottom: 7px !important; }
  .hub-wrap:has(.services-grid) .hub-cta { padding: 9px 28px !important; margin-bottom: 10px !important; }
  /* Content-column pages (service leaves/categories + estudio leaves). */
  .svc-wrap { padding-top: calc(var(--nav-h) + 24px) !important; padding-bottom: 48px !important; }
  .svc-cta { margin-top: 28px !important; padding: 20px !important; }
  /* .page-* pages (proyectos, contacto). */
  .page-wrap .page-hero { padding-top: 32px !important; padding-bottom: 4px !important; }
  .page-wrap .page-section { padding-top: 20px !important; padding-bottom: 12px !important; }
  .page-wrap .page-cta { margin-top: 24px !important; margin-bottom: 48px !important; padding: 22px !important; }

  /* ══ HERO ═════════════════════════════════════════════════════ */
  /* Fit-to-fold: margin above, subtract it from the 100svh box, stats
     hidden, bigger H1, centred bigger background logo. */
  #hero { margin-top: 28px; min-height: calc(100svh - 28px); padding-top: 24px; padding-bottom: 8px; }
  .hero-content { justify-content: center; gap: 12px; margin-bottom: 12px !important; }
  .hero-title { font-size: min(3rem, 12vw); line-height: 1; margin-bottom: 16px; }
  .hero-kicker { margin-bottom: 8px; }
  .hero-actions { gap: 12px; }
  .btn-primary { padding: 12px 20px; }
  .hero-desc { font-size: var(--text-sm); line-height: 1.3; }
  .hero-stats { display: none; }
  .hero-symbol { width: 183vw; top: calc(54.5vh - 28px); transform: translate(-50%, -50%); }

  /* Panel HEIGHT (100svh − navbar, so section + navbar == one screen) is now
     handled globally by the base `body > section:not(#hero)` rule — which picks
     up the xxs --nav-h override (77px) automatically. Here we only pin the
     scroll-down arrow: the sticky arrow is unreliable in a flex column (its
     rendered spot jumps with scroll), so pin it absolutely to each section's
     bottom-centre, where it lands just above the fold. */
  #servicios > .scroll-down,
  #proyectos > .scroll-down,
  #estudio  > .scroll-down {
    position: absolute !important;
    bottom: 16px !important;
    left: 50% !important; right: auto !important;
    transform: translateX(-50%) !important;
    margin-top: 0 !important;
  }

  /* ══ SERVICIOS ════════════════════════════════════════════════ */
  #servicios { padding-top: 28px !important; padding-bottom: 28px !important; }
  #servicios .hub-head { padding-bottom: 0 !important; }
  /* NOTE: service-card + proy-card compact styling (density, borders, tap
     hint, expanded sizing, tag-hide) moved to the "CARDS xxs→sm" block
     below (@media max-width:540.98px) so small AND standard phones share
     the same dense cards. Only the xxs-specific section padding stays here. */

  /* ══ PROYECTOS ════════════════════════════════════════════════ */
  #proyectos { padding-top: 24px !important; padding-bottom: 36px !important; }
  /* Scoped via .proy-bg-grid (homepage #proyectos + /proyectos/ <main>). */
  /* Background-grid spacing is now viewport-scaled at all widths — see the
     shared .proy-bg-grid::before rule. */
  .proy-bg-grid .page-hero { padding-bottom: 0 !important; }
  .proy-bg-grid .proy-showcase { padding-top: 16px !important; }

  /* ══ ESTUDIO ══════════════════════════════════════════════════ */
  #estudio { padding-top: 24px !important; padding-bottom: 36px !important; }
  #estudio .hub-head { padding-bottom: 0 !important; }
  /* hub-grid-section vertical padding −50% (homepage side; standalone estudio
     hub handled by .hub-wrap .hub-grid-section above). */
  #estudio .hub-grid-section { padding-top: 10px !important; }
  /* study-head-row: keep ONLY the row gap — no extra margin below the row. */
  #estudio .study-head-row,
  .hub-wrap .study-head-row { gap: 8px !important; margin-bottom: 0 !important; }
  /* hub-lead: smaller, tighter, no bottom margin (only the row gap spaces it). */
  #estudio .study-head-row .hub-lead,
  .hub-wrap .study-head-row .hub-lead,
  .hub-wrap:has(.office-grid) .hub-head .hub-lead {
    font-size: var(--text-sm) !important;
    line-height: 1.25 !important;
    margin-bottom: 0 !important;
  }
  #estudio .study-head-row .hub-lead p,
  .hub-wrap .study-head-row .hub-lead p,
  .hub-wrap:has(.office-grid) .hub-head .hub-lead p {
    line-height: 1.25 !important;
    margin-bottom: 0 !important;
  }
  /* NOTE: study-grid card density (padding/leading/svc-more) moved to the
     "CARDS xxs→sm" block below so it spans xxs→sm like the other cards. */

  /* ══ CONTACTO ═════════════════════════════════════════════════ */
  /* Homepage (#contacto) + standalone page (.page-wrap) share the classes.
     Inputs stay ≥16px to avoid the iOS focus-zoom. */
  #contacto { padding-top: 24px !important; padding-bottom: 24px !important; }
  #contacto .contacto-grid,
  .page-wrap .contacto-grid { gap: 24px !important; }
  #contacto .contacto-left > p,
  .page-wrap .contacto-left > p { font-size: var(--text-sm) !important; line-height: 1.4 !important; margin-bottom: 10px !important; }
  #contacto .contact-microcopy,
  .page-wrap .contact-microcopy { margin-bottom: 12px !important; }
  #contacto .contact-details,
  .page-wrap .contact-details { gap: 0 !important; }
  #contacto .contact-item,
  .page-wrap .contact-item { gap: 12px !important; padding: 8px 0 !important; }
  #contacto .contact-value,
  .page-wrap .contact-value { font-size: var(--text-base) !important; }
  #contacto .whatsapp-btn,
  .page-wrap .whatsapp-btn { margin-top: 16px !important; padding: 11px 22px !important; }
  #contacto .contact-form-btn,
  .page-wrap .contact-form-btn { padding: 11px 22px !important; }
  /* Contact-form panel (opened on mobile — both #contacto pages carry
     id="contacto"): shrink the panel chrome + fields so the whole form fits
     without overflowing. Previously only the standalone form (.page-wrap) was
     reduced, so the homepage panel used base sizes (150px textarea, big field
     padding) and pushed the submit — and the fixed close button — off short
     screens. Inputs stay ≥16px to avoid the iOS focus-zoom. */
  #contacto .contact-form-panel.is-open { padding: 44px var(--gutter-sm) 14px !important; }
  .contact-form-panel .form-group label { padding: 6px 20px 0 !important; }
  .contact-form-panel .form-group input,
  .contact-form-panel .form-group select,
  .contact-form-panel .form-group textarea { font-size: var(--text-base) !important; padding: 6px 20px 8px !important; }
  .contact-form-panel .form-group textarea { min-height: clamp(160px, 32vh, 300px) !important; }
  .contact-form-panel .form-submit { padding: 12px 20px !important; }
}

/* ═══════════════════════════════════════════════════════════════
   BREAKPOINT xs→sm — Standard small phones up through sm (431–540px)
   Extended from the old xs-only band (376–390px) so standard/large
   phones up to sm share the same hero + estudio hub-lead tightening.
   v-1.02 — floor RAISED 375.99 → 430.99px to match the relaxed xxs cap
   above (was 375.98). Phones ≤430px now take the compact fit-to-fold xxs
   layout instead of this looser band, so this band only covers 431–540px.
   ═══════════════════════════════════════════════════════════════ */
/* OLD (pre-v-1.02): @media (min-width: 375.99px) and (max-width: 540.98px) { */
@media (min-width: 430.99px) and (max-width: 540.98px) {
  /* Push the hero content down from the top instead of reserving space
     below it (overrides the ≤640px margin-bottom). */
  .hero-content { margin-top: 28px; margin-bottom: 0 !important; }

  /* ESTUDIO hub-lead: at this band the ≤375px tightening no longer applies,
     so the lead falls back to the loose base line-height:1.5. Cut it ~20%
     (1.5 → 1.2) on the homepage #estudio section and the estudio hub pages
     to match the density used just below. */
  #estudio .study-head-row .hub-lead,
  .hub-wrap .study-head-row .hub-lead,
  .hub-wrap:has(.office-grid) .hub-head .hub-lead { line-height: 1.2 !important; }
  #estudio .study-head-row .hub-lead p,
  .hub-wrap .study-head-row .hub-lead p,
  .hub-wrap:has(.office-grid) .hub-head .hub-lead p { line-height: 1.2 !important; }
}

/* ═══════════════════════════════════════════════════════════════
   BREAKPOINT 2 — Standard / large phones (390×844, 430×932) up to sm
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 540.98px) {
  /* Logo */
  .nav-logo img { height: 52px; }

  /* Estudio — compact cards */
  .study-grid .service-card { padding: 18px 14px; }
  .study-grid .service-number { margin-bottom: 6px; font-size: 0.6875rem; }
  .study-grid .service-title { font-size: var(--text-base); margin-bottom: 8px; line-height: 1.2; }
  .study-grid .service-desc { font-size: var(--text-xs); line-height: 1.45; margin-top: 6px; }
  .study-grid .service-number,
  .study-grid .service-title { display: inline; margin-right: 8px; }
  .study-grid .service-tags { margin-top: 10px; }
  /* Proyectos mobile cards: moved to the central `≤768.98px` block below
     (one layout for the whole ≤768 phone/tablet-portrait band, tasks 1 & 3). */
}

/* ═══════════════════════════════════════════════════════════════
   CARDS xxs→sm — service-card (servicios + estudio)
   ---------------------------------------------------------------
   The compact card styling below originally lived ONLY in the
   ≤375.98px (xxs) block; it now spans xxs→sm (≤540.98px) so small
   AND standard phones share the same dense cards. !important + the
   high-specificity selectors keep these winning over the per-page
   inline styles that load after this file. (Proyectos cards used to
   live here too; they now have one layout across the whole ≤768.98px
   band — see the central proyectos block further down.)
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 540.98px) {

  /* ══ SERVICIOS ════════════════════════════════════════════════ */
  /* Long category titles stay on one line. */
  #servicios .service-card .service-title,
  .services-grid .service-card .service-title,
  .svc-cards .service-card .service-title { font-size: var(--text-xs); }
  /* Card density −50% (service-card family: homepage + hub + categories). */
  #servicios .service-card,
  .services-grid .service-card { padding: 5px 6px 3px !important; }
  .svc-cards a.service-card { padding: 9px 10px !important; }
  #servicios .service-desc,
  .services-grid .service-desc,
  .svc-cards .service-desc { margin-top: 5px !important; }
  #servicios a.service-card .svc-more,
  .services-grid a.service-card .svc-more { margin-top: 3px !important; }
  .svc-cards a.service-card .svc-more { margin-top: 6px !important; }

  /* PROYECTOS mobile cards moved to the central `≤768.98px` block below
     (the collapsed/dense/tap-to-expand layout now spans the whole ≤768
     band, not just ≤480 — tasks 1 & 3). */

  /* ══ ESTUDIO ══════════════════════════════════════════════════ */
  /* Study cards: padding −50% (18/14 → 9/7), tighter desc leading, and the
     svc-more top margin halved (#estudio 11→5, estudio hub 18→9). */
  .study-grid .service-card { padding: 9px 7px !important; }
  .study-grid .service-desc { line-height: 1.3 !important; }
  #estudio .study-grid .svc-more { margin-top: 5px !important; }
  .hub-wrap .study-grid .svc-more { margin-top: 9px !important; }
}

/* Expandable project cards on phones + small tablets (≤md).
   Tapping a card opens a full-screen overlay with the full info + gallery;
   a floating close (×) button and Escape collapse it (site.js). */
@media (max-width: 768.98px) {
  .proy-showcase > .proy-card,
  .proyectos-grid .proyecto-card {
    cursor: pointer;
  }
  /* Expanded state: full-screen overlay */
  .proy-showcase > .proy-card.is-expanded,
  .proyectos-grid .proyecto-card.is-expanded {
    position: fixed;
    inset: 0;
    z-index: 500;
    display: flex;
    flex-direction: column;
    background: var(--white);
    overflow-y: auto;
    margin: 0 !important;
    border: none;
    min-height: 100vh;
    min-height: 100dvh;
  }
  .proy-showcase > .proy-card.is-expanded .proy-info,
  .proyectos-grid .proyecto-card.is-expanded .proyecto-info {
    border-bottom: 1px solid var(--border);
    flex: none;
  }
  .proy-showcase > .proy-card.is-expanded .proy-gallery,
  .proyectos-grid .proyecto-card.is-expanded .proyecto-gallery {
    flex: 1;
    min-height: 0;
  }
  /* Close button */
  .proy-close {
    display: none;
    position: fixed;
    top: 12px; right: 12px;
    z-index: 501;
    width: 36px; height: 36px;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: 50%;
    cursor: pointer;
    align-items: center;
    justify-content: center;
    font-size: 18px;
    line-height: 1;
    color: var(--black);
    box-shadow: 0 2px 8px rgba(0,0,0,0.12);
  }
  .proy-showcase > .proy-card.is-expanded > .proy-close,
  .proyectos-grid .proyecto-card.is-expanded > .proy-close {
    display: flex;
  }
  body.proy-expanded {
    overflow: hidden;
  }
  /* Expanded-card fix: the homepage #proyectos container is a `.reveal`
     element, and `.reveal.visible` keeps `transform: translateY(0)`. A
     non-`none` transform makes that container the containing block for the
     card's `position: fixed`, so the "full-screen" overlay was trapped inside
     the section, not the viewport — it sat below the fixed navbar, wasn't
     centred, showed the next card at its foot, and pushed its own fixed close
     button out of view. `translateY(0)` is visually identical to `none`, so
     clearing the transform on the proyectos reveal wrappers while a card is
     expanded restores true viewport-fixed behaviour with zero reflow.
     (Applies whenever a card is expanded — the tap-to-expand feature is
     ≤640px only, so no media query is needed.) */
  body.proy-expanded .proy-bg-grid.reveal,
  body.proy-expanded .proy-bg-grid .reveal {
    transform: none !important;
  }
  /* Expanded-card fix, part 2 (the v-0.69 transform fix alone wasn't enough):
     (a) The homepage's inline "force collapsed state" rules use
     `.proy-card:focus-within { position: relative !important }` — and the open
     card IS focus-within (it holds the close button's focus), so that beat the
     non-important `.is-expanded { position: fixed }` and left the overlay stuck
     in flow. Re-assert the full-screen overlay with higher specificity +
     !important so it wins.
     (b) `.proy-bg-grid > *` gives the container `position: relative; z-index: 1`,
     a stacking context capped at 1 — so the card (z-index 500 *inside* it) could
     never rise above the fixed navbar (z-index 100). Lift the container above the
     navbar while a card is open so the overlay actually covers it. */
  body.proy-expanded .proy-bg-grid > .proy-showcase { z-index: 501 !important; }
  .proy-bg-grid .proy-showcase > .proy-card.is-expanded {
    position: fixed !important;
    inset: 0 !important;
    top: 0 !important; right: 0 !important; bottom: 0 !important; left: 0 !important;
    z-index: 500 !important;
    display: flex !important;
    flex-direction: column !important;
    height: auto !important;
    min-height: 100dvh !important;
    margin: 0 !important;
    background: var(--white) !important;
    overflow-y: auto !important;
  }
  /* proy-tags removed on mobile (v-0.73) — hide them in the expanded card too
     (this selector outranks the xxs hide, so it must agree). */
  .proy-bg-grid .proy-showcase > .proy-card.is-expanded .proy-tags { display: none !important; }

  /* Contact-form panel close (×) fix: the panel is position:fixed but lives
     inside `.contacto-grid { z-index: 1 }` (a stacking context), so the panel —
     and its fixed close button — rendered BELOW the fixed navbar (z-index 100),
     which covered the ×. Lift the grid above the navbar while the panel is open
     (body.contact-open, mobile-only) so the overlay covers the navbar and the ×
     is clickable. Covers both #contacto pages (homepage + /contacto/). */
  body.contact-open #contacto .contacto-grid { z-index: 501 !important; }
}

/* ═══════════════════════════════════════════════════════════════
   BREAKPOINT 3 — Tablets (768×1024, 1024×768)
   ═══════════════════════════════════════════════════════════════ */
@media (min-width: 640.99px) and (max-width: 1024.98px) {
  /* Hero — logo + padding + stats below content */
  .nav-logo img { height: 52px; }
  .hero-content { padding-top: clamp(48px, 8vh, 80px); }
  .hero-stats {
    position: static;
    margin-top: 24px;
    padding-top: clamp(12px, 2vh, 20px);
  }

  /* Estudio — compact cards */
  .study-grid .service-card { padding: 22px 18px; }
  .study-grid .service-number { margin-bottom: 6px; font-size: 0.75rem; }
  .study-grid .service-title { font-size: var(--text-md); margin-bottom: 8px; line-height: 1.2; }
  .study-grid .service-desc { font-size: var(--text-sm); line-height: 1.5; margin-top: 8px; }
  .study-grid .service-number,
  .study-grid .service-title { display: inline; margin-right: 8px; }
  .study-grid .service-tags { margin-top: 12px; }
  /* Proyectos layout for this band lives elsewhere (task 1): 641–768px is
     mobile (stacked + tap-to-expand, ≤768.98px blocks), 769–1024px is the
     desktop showcase. Here we only fix the VERTICAL alignment (task 2): the
     homepage #proyectos panel top-aligns its content (inline
     `justify-content: flex-start`), leaving a gap below on tablet heights —
     center it instead. `min-height` (not height) means taller content still
     grows and scrolls normally, so centering never clips. `body > #proyectos`
     (id + child) outspecifies the inline `#proyectos` rule. */
  body > #proyectos { justify-content: center; }
}

/* ═══════════════════════════════════════
   TARJETA PROYECTO — carousel lateral
═══════════════════════════════════════ */
.proy-card {
  display: grid;
  grid-template-columns: 1fr 1.6fr;
  border: 1px solid var(--border);
  margin-top: 56px;
  min-height: 420px;
}

/* Panel izquierdo: info fija */
.proy-info {
  padding: 48px 40px;
  border-right: 1px solid var(--border);
  display: flex; flex-direction: column; justify-content: space-between;
}
.proy-num {
  font-size: var(--text-2xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-wide); text-transform: uppercase;
  color: var(--warm-50); margin-bottom: 20px; display: block;
}
.proy-title {
  font-size: var(--text-xl); font-weight: var(--fw-medium);
  letter-spacing: 0.02em; line-height: 1.35;
  color: var(--black); margin-bottom: 20px;
}
.proy-desc {
  font-size: var(--text-base); font-weight: var(--fw-light);
  color: var(--warm-50); line-height: 1.2; flex: 1;
}
.proy-tags {
  display: flex; flex-wrap: wrap; gap: 4px; margin-top: 14px;
}
.proy-tag {
  font-size: var(--text-2xs); letter-spacing: var(--ls-tight); text-transform: uppercase;
  color: var(--warm-50); border: 1px solid var(--border);
  padding: 4px 10px;
}

/* Panel derecho: carrusel (auto, 3s, dots debajo) */
.proy-gallery {
  display: flex; flex-direction: column;
  min-width: 0;
}
.proy-carousel {
  position: relative; overflow: hidden;
  background: var(--warm-10);
  flex: 1; min-height: 0;
}
.proy-track {
  display: flex;
  transition: transform 0.45s cubic-bezier(0.4,0,0.2,1);
  height: 100%;
}
.proy-slide {
  flex: 0 0 100%; height: 100%;
  position: relative;
}
.proy-slide img {
  width: 100%; height: 100%;
  object-fit: cover; display: block;
}
/* Contador + navegación */
.proy-nav {
  position: absolute; bottom: 0; right: 0; left: 0;
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 20px;
  background: rgba(255,255,255,0.92);
  border-top: 1px solid var(--border);
}
.proy-counter {
  font-size: var(--text-2xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps); color: var(--warm-50);
}
.proy-caption {
  font-size: var(--text-2xs); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-tight); text-transform: uppercase;
  color: var(--black); flex: 1; text-align: center;
}
.proy-arrows { display: flex; gap: 12px; }
.proy-arrow {
  width: 32px; height: 32px;
  background: none; border: 1px solid var(--border);
  cursor: pointer; display: flex; align-items: center; justify-content: center;
  transition: all 0.25s; flex-shrink: 0;
}
.proy-arrow:hover { background: var(--black); border-color: var(--black); }
.proy-arrow:hover svg path { stroke: var(--white); }
.proy-arrow svg { width: 14px; height: 14px; }
.proy-arrow svg path { stroke: var(--black); transition: stroke 0.25s; }

/* Dots (debajo de la imagen) */
.proy-dots {
  display: flex; gap: 8px; align-items: center; justify-content: center;
  padding: 10px 12px;
  background: #fff;
}
.proy-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--warm-20); border: none; cursor: pointer;
  transition: background 0.25s; padding: 0;
}
.proy-dot:hover { background: var(--warm-50); }
.proy-dot.active { background: var(--black); }

@media (max-width: 768.98px) {
  .proy-card { grid-template-columns: 1fr; }
  .proy-info { border-right: none; border-bottom: 1px solid var(--border); }
  .proy-carousel { min-height: 280px; }
}

/* ═══════════════════════════════════════
   PROYECTOS — diagonal (45°) background grid
   Reuses the hero grid look (--border hairlines at --grid-base-spacing),
   rotated 45°. Applied to the homepage #proyectos section and the
   /proyectos/ page <main>. Oversized + clipped so the rotation leaves
   no bare corners.
═══════════════════════════════════════ */
.proy-bg-grid { position: relative; overflow: hidden; }
.proy-bg-grid::before {
  content: "";
  position: absolute;
  top: -50%; left: -50%;
  width: 200%; height: 200%;
  pointer-events: none;
  z-index: 0;
  /* Viewport-scaled spacing — match the hero grid (120px * innerWidth/1400)
     instead of a coarse fixed 120px. Applies at all widths. */
  background-image:
    repeating-linear-gradient(0deg,  var(--border) 0 1px, transparent 1px calc(100vw * 120 / 1400)),
    repeating-linear-gradient(90deg, var(--border) 0 1px, transparent 1px calc(100vw * 120 / 1400));
  transform: rotate(45deg);
}
.proy-bg-grid > * { position: relative; z-index: 1; }

/* ═══════════════════════════════════════
   PROYECTOS SHOWCASE — desktop one-screen layout
   Compact tiles (3 on top row, 2 on bottom) filling the container;
   hover expands a tile to cover the whole container with the full
   info + gallery view. Below 1025px the cards fall back to the normal
   stacked .proy-card layout (rules above), untouched.
═══════════════════════════════════════ */
/* Desktop showcase now begins just above the 768px mobile/desktop divide
   (task 1: >768px = desktop layout). Was min-width:1024.99px. */
@media (min-width: 768.99px) {
  .proy-showcase {
    position: relative;
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    grid-template-rows: repeat(2, 1fr);
    gap: 1px;
    height: clamp(357px, 49.3vh, 493px);
    /* Zero the vertical padding inherited from .page-section so the padding
       box and content box coincide vertically — an expanded card placed with
       position:absolute; inset:0 then fills the container exactly (its grid
       area is the abs-pos containing block). Horizontal gutter is kept so the
       showcase still lines up with the page header. */
    padding-top: 0 !important;
    padding-bottom: 0 !important;
    margin-top: 48px;
    margin-bottom: 48px;
    background: var(--border);
    /* background: #FFFFFF; */
    border: 1px solid var(--border);
    overflow: hidden;
  }
  /* While a card is expanded (clicked open) it grows past the fixed box height
     to fit its copy + image (see the .is-expanded rule below); lift the clip so
     the grown overlay isn't cut off. The compact grid never overflows. */
  .proy-showcase:has(> .proy-card.is-expanded) {
    overflow: visible;
  }

  /* Compact tile — override the base two-column .proy-card.
     Desktop (v-1.06): tiles sit at 50% opacity over the white page; hovering a
     tile brings it to full opacity (it does NOT expand). Expansion happens only
     on click (JS toggles .is-expanded — see the rule further below). */
  .proy-showcase > .proy-card {
    position: relative;
    display: block;
    grid-template-columns: none;
    min-height: 0;
    margin: 0 !important;
    border: none;
    overflow: hidden;
    background: var(--warm-10);
    cursor: pointer;
    opacity: 0.65;
    transition: opacity 0.3s ease, box-shadow 0.3s ease;
  }
  /* Hover a compact tile → fully visible (no expansion). */
  .proy-showcase > .proy-card:not(.is-expanded):hover {
    opacity: 1;
  }
  /* Close (×) button — hidden until the card is expanded */
  .proy-showcase > .proy-card > .proy-close { display: none; }
  /* Row 1: first three tiles (span 2 of 6) · Row 2: last two (span 3 of 6) */
  .proy-showcase > .proy-card:nth-child(1),
  .proy-showcase > .proy-card:nth-child(2),
  .proy-showcase > .proy-card:nth-child(3) { grid-row: 1; grid-column: span 2; }
  .proy-showcase > .proy-card:nth-child(4),
  .proy-showcase > .proy-card:nth-child(5) { grid-row: 2; grid-column: span 3; }
  /* Hide the legacy admin-injected slot in this layout */
  .proy-showcase > #proyectos-admin-container { display: none; }

  /* Gallery = the site.js carousel; it fills the tile as the cover.
     Dots are hidden in the compact state (shown again when expanded). */
  .proy-showcase > .proy-card > .proy-gallery {
    position: absolute; inset: 0;
    z-index: 0;
    min-width: 0;
  }
  /* Homepage fallback: galleries there stay as raw <img> (no carousel JS),
     so show only the first as the cover. On /proyectos/ the images live
     inside .proy-slide, so these `> img` selectors don't match. */
  .proy-showcase > .proy-card > .proy-gallery > img {
    width: 100%; height: 100%; object-fit: cover;
  }
  .proy-showcase > .proy-card > .proy-gallery > img:not(:first-child) { display: none; }
  .proy-showcase > .proy-card > .proy-gallery .proy-dots { display: none; }

  /* Info overlaid on the cover — compact shows only number + title */
  .proy-showcase > .proy-card > .proy-info {
    position: absolute; inset: 0;
    z-index: 1;
    padding: 22px 24px;
    border: none;
    justify-content: flex-end;
    background: linear-gradient(to top,
      rgba(0,0,0,0.92) 0%, rgba(0,0,0,0.72) 28%,
      rgba(0,0,0,0.40) 55%, rgba(0,0,0,0.12) 80%, rgba(0,0,0,0) 100%);
  }
  .proy-showcase > .proy-card > .proy-info .proy-desc,
  .proy-showcase > .proy-card > .proy-info .proy-tags { display: none; }
  .proy-showcase > .proy-card .proy-num {
    color: rgba(255,255,255,0.82); margin-bottom: 8px;
  }
  .proy-showcase > .proy-card .proy-title {
    color: #fff; font-size: var(--text-md); line-height: 1.3; margin-bottom: 0;
  }

  /* ── Expanded (click → .is-expanded): fill the whole container ── */
  .proy-showcase > .proy-card.is-expanded {
    opacity: 1;
    position: absolute;
    top: 0; left: 0; right: 0;
    /* Grow to fit the content instead of being locked to the box: the copy
       (title + 6-line teaser + tags) is often taller than the fixed showcase
       height, and clamping to it clipped the bottom rows. min-height keeps
       short cards filling the box; height:auto lets tall ones extend down over
       the gap below (high z-index + shadow read it as a popover). */
    bottom: auto;
    height: auto;
    min-height: 100%;
    /* Span the whole grid: an abs-pos grid item is otherwise contained by its
       own grid area (its compact row), so the placement must be paired with a
       full-grid placement to anchor at the container's top-left. */
    grid-row: 1 / -1;
    grid-column: 1 / -1;
    z-index: 10;
    display: grid;
    grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.45fr);
    background: var(--white);
    cursor: default;
    box-shadow: 0 24px 70px rgba(0,0,0,0.20);
  }

  /* Desktop close (×) button — top-right of the expanded card. Positioned
     absolute so it sits outside the expanded card's 2-column grid flow. */
  .proy-showcase > .proy-card.is-expanded > .proy-close {
    display: flex;
    position: absolute;
    top: 14px; right: 14px;
    z-index: 12;
    width: 36px; height: 36px;
    align-items: center;
    justify-content: center;
    background: var(--white);
    border: 1px solid var(--border);
    border-radius: 50%;
    cursor: pointer;
    font-size: 20px;
    line-height: 1;
    color: var(--black);
    box-shadow: 0 2px 8px rgba(0,0,0,0.12);
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
  }
  .proy-showcase > .proy-card.is-expanded > .proy-close:hover {
    background: var(--black); color: var(--white); border-color: var(--black);
  }

  /* Expanded info panel — full text, left column */
  .proy-showcase > .proy-card.is-expanded > .proy-info {
    position: relative; inset: auto;
    z-index: 1;
    padding: 32px 36px;
    background: none;
    justify-content: space-between;
    border-right: 1px solid var(--border);
    overflow: hidden;
  }
  .proy-showcase > .proy-card.is-expanded .proy-num { color: var(--warm-50); }
  .proy-showcase > .proy-card.is-expanded .proy-title {
    color: var(--black); font-size: var(--text-xl); margin-bottom: 18px;
  }
  .proy-showcase > .proy-card.is-expanded .proy-desc {
    /* Slightly smaller body + a generous clamp so the full teaser fits
       (the longest project copies ran past the old 6-line clamp). */
    display: -webkit-box; -webkit-line-clamp: 14; -webkit-box-orient: vertical;
    overflow: hidden; margin-top: 4px; font-size: var(--text-sm);
  }
  .proy-showcase > .proy-card.is-expanded .proy-tags { display: flex; margin-top: 6px; }

  /* Expanded gallery — the carousel fills the right column, dots restored */
  .proy-showcase > .proy-card.is-expanded > .proy-gallery {
    position: relative; inset: auto;
  }
  .proy-showcase > .proy-card.is-expanded > .proy-gallery .proy-dots { display: flex; }

  /* Expanded gallery image fit: the project photos have variable aspect ratios,
     so a plain object-fit:cover crops them inconsistently (wide ones lose their
     sides, tall ones lose their top/bottom). Here we instead scale each image to
     the full frame width and show only its vertical-middle band clipped to the
     frame height — a consistent top/bottom crop across ratios. A short/wide image
     may then not reach the full height, letting the --warm-10 frame show as a thin
     band above/below (accepted trade-off for the consistent crop). */
  .proy-showcase > .proy-card.is-expanded .proy-slide { overflow: hidden; }
  .proy-showcase > .proy-card.is-expanded .proy-slide img {
    position: absolute;
    left: 0; top: 50%;
    width: 100%; height: auto;
    transform: translateY(-50%);
  }

  /* ── Standalone /proyectos/ pages only (v-1.07) ──
     On these pages the showcase is immediately followed by the .page-cta, so an
     expanded card that grew PAST the box (the homepage panels' intended
     behaviour, which have empty space beneath) overflowed down onto that CTA.
     Here we instead lock the expanded card to the showcase box (top:0 + bottom:0)
     and clip it; its info column scrolls internally if the copy runs long. The
     homepage #proyectos panels are unaffected — they aren't inside .page-wrap. */
  .page-wrap .proy-showcase:has(> .proy-card.is-expanded) { overflow: hidden; }
  .page-wrap .proy-showcase > .proy-card.is-expanded {
    bottom: 0;
    height: auto;
    min-height: 0;
  }
  .page-wrap .proy-showcase > .proy-card.is-expanded > .proy-info {
    overflow-y: auto;
  }
}

/* ═══════════════════════════════════════════════════════════════
   PROYECTOS — the ONE mobile card layout, ≤768px (tasks 1 & 3)
   ---------------------------------------------------------------
   Single source of truth for the phone/tablet-portrait proyectos
   cards. Everything below 769px (the desktop showcase begins at
   768.99px) renders the SAME dense, collapsed "number + title" card
   with a tap-to-expand fullscreen overlay — the look small phones
   (xxs/xs) always had, now applied uniformly up through sm (480) and
   md (640) to the 768 divide. Previously these rules were split
   across three narrower caps (collapse ≤390.98 per-page, minimalist
   stack + dense card ≤540.98 in styles.css, homepage force-collapse
   ≤430.98) so 481–768px fell back to the two-column .proy-card with
   its 420px min-height and full gallery — which overflowed badly.
   Scoped via `.proy-bg-grid` (homepage #proyectos + every /proyectos/
   <main> in all four languages) and !important so one central block
   beats the base .proy-card rules AND the per-page inline <style>
   that loads after this file. The narrower per-page ≤390.98 collapse
   blocks are now redundant subsets of this rule; they are left in
   place (harmless) rather than editing 8 files.
   ═══════════════════════════════════════════════════════════════ */
@media (max-width: 768.98px) {
  /* Breathing room above the first card in the collapsed card layout
     (was 0 — the tile block sat flush against the header). Only applies
     in this ≤768.98px card layout; the >768.98px carousel layout keeps
     its own showcase spacing. */
  .proy-bg-grid .proy-showcase { padding-top: 24px !important; }
  /* Stack + strip the two-column desktop card geometry (kills the 420px
     min-height that caused the md overflow). */
  .proy-bg-grid .proy-showcase > .proy-card {
    grid-template-columns: 1fr !important;
    margin-top: 0 !important;
    min-height: 0 !important;
  }

  /* Collapsed card (default state): show only number + title. Hide the
     gallery, description and tags until the card is tapped open. */
  .proy-bg-grid .proy-showcase > .proy-card:not(.is-expanded) > .proy-gallery,
  .proy-bg-grid .proy-showcase > .proy-card:not(.is-expanded) .proy-desc,
  .proy-bg-grid .proy-showcase > .proy-card:not(.is-expanded) .proy-tags { display: none !important; }

  /* Collapsed card chrome: service-card border over a 60%-white fill
     (40% transparency — lets more of the diagonal bg-grid show through
     than the previous 20%), −50% padding. */
  .proy-bg-grid .proy-showcase > .proy-card:not(.is-expanded) {
    border: 1px solid #d0d0d0 !important;
    border-radius: 4px !important;
    background: rgba(255, 255, 255, 0.6) !important;
    overflow: clip;
  }
  .proy-bg-grid .proy-showcase > .proy-card:not(.is-expanded) + .proy-card:not(.is-expanded) { margin-top: 1px !important; }
  .proy-bg-grid .proy-showcase > .proy-card:not(.is-expanded) > .proy-info { padding: 8px 7px !important; border-right: none !important; border-bottom: none !important; }
  .proy-bg-grid .proy-showcase > .proy-card:not(.is-expanded) .proy-title { font-size: var(--text-xs) !important; line-height: 1.15 !important; margin-bottom: 4px !important; }
  .proy-bg-grid .proy-showcase > .proy-card:not(.is-expanded) .proy-num { margin-bottom: 3px !important; font-size: 0.6875rem !important; }

  /* Collapsed-card tap hint (localized via <html lang>), right-aligned. */
  .proy-showcase .proy-card:not(.is-expanded) > .proy-info::after {
    content: "Ver proyecto →";
    display: block;
    margin-top: 2px;
    font-size: 0.6875rem;
    letter-spacing: var(--ls-tight);
    text-transform: uppercase;
    text-align: right;
    color: var(--black);
  }
  html[lang="en"] .proy-showcase .proy-card:not(.is-expanded) > .proy-info::after { content: "View project →"; }
  html[lang="it"] .proy-showcase .proy-card:not(.is-expanded) > .proy-info::after { content: "Vedi progetto →"; }
  html[lang="fr"] .proy-showcase .proy-card:not(.is-expanded) > .proy-info::after { content: "Voir le projet →"; }

  /* Expanded (tap-to-fullscreen) card — type + gallery. The overlay
     positioning itself lives in the ≤768.98px block far above. */
  .proy-bg-grid .proy-showcase > .proy-card.is-expanded .proy-title { font-size: calc(var(--text-base) * 0.8) !important; }
  .proy-bg-grid .proy-showcase > .proy-card.is-expanded .proy-desc { font-size: calc(var(--text-base) * 0.85) !important; }
  .proy-bg-grid .proy-showcase > .proy-card.is-expanded .proy-gallery,
  .proy-bg-grid .proy-showcase > .proy-card.is-expanded .proy-carousel { background: transparent !important; }

  /* Project tags dropped on the whole mobile band (collapsed cards already
     hide them; keep the expanded card free of them too). */
  .proy-bg-grid .proy-showcase .proy-card .proy-tags { display: none !important; }
}

/* Nav link activo */
.nav-links a.nav-active:not(.nav-cta) {
  color: var(--black) !important;
  border-bottom: 1px solid var(--black);
  padding-bottom: 2px;
}
.nav-links a.nav-cta.nav-active {
  color: var(--white) !important;
  border-bottom: 1px solid var(--white) !important;
}
/* Active CTA on hover: match the normal CTA hover (white bg → black text),
   otherwise the active white text stays white on the white hover bg and vanishes. */
.nav-links a.nav-cta.nav-active:hover {
  color: var(--black) !important;
  border-bottom-color: var(--black) !important;
}

/* ═══════════════════════════════════════
   SECCIÓN PROYECTOS
═══════════════════════════════════════ */
#proyectos { background: var(--white); }

/* Grid de proyectos */
.proyectos-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  margin-top: 56px;
  box-shadow: 0 24px 70px rgba(0,0,0,0.20);
}
.proyecto-card {
  background: var(--white);
  transition: background 0.3s;
  cursor: default;
  overflow: hidden;
  box-shadow: 0 24px 70px rgba(0,0,0,0.20);
}
.proyecto-card:hover { background: var(--warm-10); }
.proyecto-img {
  width: 100%; aspect-ratio: 16/9;
  object-fit: cover; display: block;
  background: var(--warm-10);
}
.proyecto-img-placeholder {
  width: 100%; aspect-ratio: 16/9;
  background: var(--warm-10);
  display: flex; align-items: center; justify-content: center;
}
.proyecto-img-placeholder span {
  font-size: var(--text-2xs); letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50);
}
.proyecto-info { padding: 28px; }
.proyecto-tag {
  font-size: var(--text-2xs); letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); margin-bottom: 10px; display: block;
}
.proyecto-nombre {
  font-size: var(--text-lg); font-weight: var(--fw-medium);
  letter-spacing: 0.02em; color: var(--black);
  margin-bottom: 10px;
}
.proyecto-desc {
  font-size: var(--text-base); font-weight: var(--fw-light);
  color: var(--warm-50); line-height: 1.65;
}

/* Estado vacío */
.proyectos-empty {
  border: 1px solid var(--border);
  padding: 100px 60px;
  text-align: center;
  margin-top: 56px;
}
.proyectos-empty h3 {
  font-size: var(--text-xl); font-weight: var(--fw-light);
  margin-bottom: 14px; color: var(--black);
}
.proyectos-empty p {
  font-size: var(--text-md); font-weight: var(--fw-light);
  color: var(--warm-50); max-width: 380px;
  margin: 0 auto; line-height: 1.7;
}

/* ═══════════════════════════════════════
   PANEL ADMIN (oculto por defecto)
═══════════════════════════════════════ */
#admin-toggle-btn {
  position: fixed; bottom: 32px; right: 32px;
  background: var(--black); color: var(--white);
  font-family: inherit; font-size: var(--text-2xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  padding: 12px 20px; border: none; cursor: pointer;
  z-index: 200; transition: opacity 0.3s;
  opacity: 0.18;
}
#admin-toggle-btn:hover { opacity: 1; }

#admin-panel {
  display: none;
  position: fixed; inset: 0;
  background: rgba(0,0,0,0.6);
  z-index: 300;
  align-items: center; justify-content: center;
}
#admin-panel.open { display: flex; }

.admin-box {
  background: var(--white);
  width: 560px; max-height: 90vh;
  overflow-y: auto;
  border: 1px solid var(--border);
  padding: 48px;
}
.admin-box h3 {
  font-size: var(--text-xl); font-weight: var(--fw-medium);
  letter-spacing: 0.04em; color: var(--black);
  margin-bottom: 32px;
}
.admin-field { margin-bottom: 20px; }
.admin-field label {
  font-size: var(--text-2xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); display: block; margin-bottom: 8px;
}
.admin-field input,
.admin-field select,
.admin-field textarea {
  width: 100%; background: transparent;
  border: none; border-bottom: 1px solid var(--border);
  color: var(--black); font-family: inherit;
  font-size: var(--text-md); font-weight: var(--fw-light);
  padding: 8px 0 12px; outline: none;
  transition: border-color 0.3s;
}
.admin-field input:focus,
.admin-field select:focus,
.admin-field textarea:focus { border-bottom-color: var(--black); }
.admin-field textarea { resize: vertical; min-height: 80px; }
.admin-field select option { background: var(--white); }

.admin-actions {
  display: flex; gap: 16px;
  margin-top: 32px; justify-content: flex-end;
}
.admin-btn-cancel {
  font-family: inherit; font-size: var(--text-sm); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); background: none; border: none;
  cursor: pointer; transition: color 0.3s;
}
.admin-btn-cancel:hover { color: var(--black); }
.admin-btn-save {
  font-family: inherit; font-size: var(--text-sm); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  background: var(--black); color: var(--white);
  border: 1px solid var(--black); padding: 12px 28px;
  cursor: pointer; transition: all 0.3s;
}
.admin-btn-save:hover {
  background: transparent; color: var(--black);
}

/* Lista de proyectos en panel admin */
.admin-list { margin-bottom: 32px; }
.admin-item {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 0; border-bottom: 1px solid var(--border);
  gap: 16px;
}
.admin-item-info { flex: 1; }
.admin-item-nombre {
  font-size: var(--text-md); font-weight: var(--fw-normal); color: var(--black);
}
.admin-item-tag {
  font-size: var(--text-2xs); letter-spacing: var(--ls-tight); text-transform: uppercase;
  color: var(--warm-50); margin-top: 4px;
}
.admin-item-del {
  font-family: inherit; font-size: var(--text-2xs); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-tight); text-transform: uppercase;
  color: var(--warm-50); background: none; border: none;
  cursor: pointer; transition: color 0.3s; flex-shrink: 0;
}
.admin-item-del:hover { color: var(--black); }

.admin-divider {
  border: none; border-top: 1px solid var(--border);
  margin: 28px 0;
}

@media (max-width: 1024.98px) {
  .proyectos-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640.98px) {
  .proyectos-grid { grid-template-columns: 1fr; }
  .admin-box { width: 100%; max-height: 100vh; padding: 32px 24px; }
}

/* ══════════════════════════════════════════════════════════════
   MULTI-PAGE SHELL — grouped nav dropdowns, mobile accordion, footer
   Added for the multi-page conversion (v-0.04). Additive: does not
   alter the legacy single-page nav rules above.
══════════════════════════════════════════════════════════════ */

/* Neutralise the full-viewport <section> behaviour (single-page design) for
   multi-page content, which lives inside <main>. Homepage sections are direct
   children of <body> and are unaffected. */
main section { min-height: 0; display: block; }

/* --- Desktop dropdown parents (Servicios ▾ / Estudio ▾) --- */
.nav-group { position: relative; }
.nav-group-toggle {
  display: inline-flex; align-items: center; gap: 6px;
  cursor: pointer;
}
.nav-caret {
  width: 9px; height: 9px; flex: 0 0 auto;
  transition: transform 0.25s ease;
}
.nav-group:hover .nav-caret,
.nav-group:focus-within .nav-caret { transform: rotate(180deg); }

.nav-dropdown {
  position: absolute; top: 100%; left: 0;
  margin: 0; padding: 10px 0;
  min-width: 250px;
  list-style: none;
  background: var(--white);
  border: 1px solid var(--border);
  box-shadow: 0 12px 30px rgba(0,0,0,0.08);
  opacity: 0; visibility: hidden; transform: translateY(6px);
  transition: opacity 0.2s ease, transform 0.2s ease, visibility 0.2s;
  z-index: 200;
}
/* Bridge the gap so the menu doesn't close between link and panel */
.nav-dropdown::before {
  content: ""; position: absolute; top: -10px; left: 0; right: 0; height: 10px;
}
.nav-group:hover .nav-dropdown,
.nav-group:focus-within .nav-dropdown {
  opacity: 1; visibility: visible; transform: translateY(0);
}
.nav-dropdown li { margin: 0; }
.nav-dropdown a {
  display: block; padding: 9px 22px;
  font-size: var(--text-xs); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-tight); text-transform: none;
  color: var(--warm-50); white-space: nowrap;
  transition: color 0.2s, background 0.2s;
}
.nav-dropdown a:hover,
.nav-dropdown a:focus-visible { color: var(--black); background: var(--warm-10); }

/* --- Mobile accordion (inside the existing .nav-mobile-menu overlay) --- */
.nav-mobile-menu .m-group { width: 80%; }
.nav-mobile-menu .m-group-head {
  position: relative;
  display: flex; align-items: center; justify-content: center;
  border-bottom: 1px solid var(--border);
}
.nav-mobile-menu .m-group-head > a {
  border: none; width: auto; padding: 18px 0; text-align: center; flex: 0 1 auto;
}
.nav-mobile-menu .m-group-toggle {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer;
  padding: 12px; color: var(--black);
  display: flex; align-items: center;
}
.nav-mobile-menu .m-group-toggle .nav-caret { width: 14px; height: 14px; }
.nav-mobile-menu .m-group.open .m-group-toggle .nav-caret { transform: rotate(180deg); }
.nav-mobile-menu .m-sub {
  list-style: none; margin: 0; padding: 0;
  max-height: 0; overflow: hidden;
  transition: max-height 0.3s ease;
}
.nav-mobile-menu .m-group.open .m-sub { max-height: 520px; }
.nav-mobile-menu .m-sub a {
  font-size: var(--text-lg); font-weight: var(--fw-light);
  padding: 12px 0; width: 100%;
  border-bottom: 1px solid var(--border);
  color: var(--warm-50);
}
.nav-mobile-menu .m-sub a:first-child { border-top: none; }

/* --- Footer (grouped taxonomy → real URLs) --- */
.site-footer {
  border-top: 1px solid var(--border);
  padding: 28px var(--gutter) 40px;
  background: var(--white);
}
@media (max-width: 900.98px){ .site-footer { padding-left: var(--gutter-sm); padding-right: var(--gutter-sm); } }
.site-footer-top {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px; flex-wrap: wrap;
  margin-bottom: 16px;
}
.footer-tagline {
  font-size: var(--text-2xs); letter-spacing: var(--ls-caps);
  text-transform: uppercase; color: var(--warm-50);
}
.footer-grid {
  display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr;
  column-gap: 40px; row-gap: 13px; padding-bottom: 16px;
}
@media (max-width: 900.98px){ .footer-grid { grid-template-columns: 1fr 1fr; row-gap: 13px; } }
@media (max-width: 540.98px){ .footer-grid { grid-template-columns: 1fr; } }
.footer-desc {
  font-size: var(--text-sm); font-weight: var(--fw-light);
  line-height: 1.15; color: var(--warm-50); max-width: 34ch;
}
.footer-col h2 {
  font-size: var(--text-2xs); letter-spacing: var(--ls-caps);
  text-transform: uppercase; color: var(--black);
  font-weight: var(--fw-medium); margin-bottom: 16px;
}
.footer-links { list-style: none; margin: 0; padding: 0; }
.footer-links li { margin-bottom: 0; }
.footer-links a {
  font-size: var(--text-sm); font-weight: var(--fw-light);
  color: var(--warm-50); text-decoration: none; transition: color 0.2s;
}
.footer-links a:hover { color: var(--black); }
.site-footer-bottom {
  margin-top: 0; padding-top: 24px;
  border-top: 1px solid var(--border);
}
.footer-copy { font-size: var(--text-2xs); color: var(--warm-50); }

/* Homepage teaser cards: make the whole .service-card clickable via a stretched link.
   (.service-card is position:relative, so the ::after overlay fills the card.) */
.service-card .svc-more {
  display: block; text-align: right; margin-top: 20px;
  font-size: var(--text-2xs); letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--black); text-decoration: none;
}
.service-card .svc-more::after { content: ""; position: absolute; inset: 0; }

/* ═══════════════════════════════════════════════════════════════
   URL-tree refactor (Phase 3) — mega-menu, mobile nested accordion,
   hub category sections. Additive; extends the existing .nav-* system.
═══════════════════════════════════════════════════════════════ */

/* --- Desktop mega-menu (Servicios): reuses .nav-dropdown reveal, 4 columns.
   Servicios sits on the right half of the navbar (.nav-links is margin-left:auto).
   The panel is pinned (fixed) to the navbar's right gutter and grows LEFTWARD, and
   its columns are sized to content so every category title fits on a single line
   while the whole panel stays on screen — even at the ~1050px min desktop width. --- */
.nav-dropdown.nav-mega {
  position: fixed;
  top: var(--nav-h); left: auto; right: var(--gutter);
  display: grid;
  grid-template-columns: repeat(4, max-content);
  gap: 4px 30px;
  padding: 22px 26px;
  min-width: 0;
  width: max-content;
  max-width: calc(100vw - var(--gutter) - 16px);
}
/* Hover-bridge: the fixed panel drops to the navbar's bottom edge, so the bridge
   must span the full navbar height (and the panel's full width) to keep the pointer
   over a .nav-group descendant while travelling from the toggle down to the panel. */
.nav-dropdown.nav-mega::before {
  left: 0; right: 0; width: auto;
  top: -32px; height: 32px;
}
.nav-mega-col { min-width: 0; }
.nav-mega .nav-mega-head {
  display: block; padding: 6px 0 8px;
  font-size: var(--text-xs); font-weight: var(--fw-medium);
  letter-spacing: var(--ls-tight); color: var(--black);
  border-bottom: 1px solid var(--border); margin-bottom: 6px;
  white-space: nowrap; line-height: 1.25;
}
.nav-mega .nav-mega-head:hover,
.nav-mega .nav-mega-head:focus-visible { color: var(--warm-50); background: none; }
.nav-mega-col ul { list-style: none; margin: 0; padding: 0; }
.nav-mega-col ul a {
  display: block; padding: 7px 0;
  font-size: var(--text-xs); font-weight: var(--fw-normal);
  letter-spacing: var(--ls-tight); color: var(--warm-50);
  white-space: normal; line-height: 1.3;
}
.nav-mega-col ul a:hover,
.nav-mega-col ul a:focus-visible { color: var(--black); background: none; }
/* 2-column mega variant (Estudio: Sobre nosotros + Oficinas).
   Unlike the wide 4-column Servicios mega (pinned to the navbar's right gutter),
   this narrow panel is anchored to its OWN nav-group so it drops directly under the
   "Estudio" title — same title-relative position in every navbar regardless of how
   many language chips are present (4 on the homepage, fewer on inner pages).
   `right: 0` right-aligns it under the title and grows it LEFTWARD, so it can never
   overflow the viewport. `top: calc(100% + 32px)` drops it to the navbar's bottom
   edge, matching where the Servicios mega sits (the 32px == the label-bottom→navbar-
   bottom gap the inherited ::before hover-bridge already spans). */
.nav-dropdown.nav-mega.nav-mega-2 {
  grid-template-columns: repeat(2, max-content);
  position: absolute;
  top: calc(100% + 32px);
  right: 0;
  left: auto;
}
/* Non-link mega heading (a category label with no landing page, e.g. Oficinas) */
.nav-mega .nav-mega-head.is-label { cursor: default; }
.nav-mega .nav-mega-head.is-label:hover,
.nav-mega .nav-mega-head.is-label:focus-visible { color: var(--black); }

/* --- Mobile: 2nd-level nested accordion (category → its leaves) --- */
.nav-mobile-menu .m-subgroup { list-style: none; }
.nav-mobile-menu .m-subgroup-head {
  position: relative;
  display: flex; align-items: center; justify-content: center;
}
.nav-mobile-menu .m-subgroup-head > a {
  border: none; width: auto; padding: 12px 0; text-align: center; flex: 0 1 auto;
  font-size: var(--text-lg); font-weight: var(--fw-normal); color: var(--black);
}
.nav-mobile-menu .m-subgroup-toggle {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  background: none; border: none; cursor: pointer;
  padding: 10px; color: var(--warm-50); display: flex; align-items: center;
}
.nav-mobile-menu .m-subgroup-toggle .nav-caret { width: 12px; height: 12px; }
.nav-mobile-menu .m-subgroup.open .m-subgroup-toggle .nav-caret { transform: rotate(180deg); }
.nav-mobile-menu .m-subsub {
  list-style: none; margin: 0 0 6px; padding: 0;
  max-height: 0; overflow: hidden; transition: max-height 0.3s ease;
}
.nav-mobile-menu .m-subgroup.open .m-subsub { max-height: 360px; }
.nav-mobile-menu .m-subsub a {
  display: block; text-align: center;
  font-size: var(--text-base); font-weight: var(--fw-light);
  padding: 10px 0; width: 100%; border-bottom: none; color: var(--warm-50);
}
/* Parent must accommodate expanded nested subgroups */
.nav-mobile-menu .m-group.open .m-sub#m-servicios { max-height: 1600px; }
.nav-mobile-menu .m-sub .m-subgroup { border-bottom: 1px solid var(--border); }

/* ≤sm (≤540px): tighten mobile-menu spacing so a fully-expanded accordion
   (all categories + their leaves) doesn't overflow the viewport. Extended
   from the old ≤xs (≤390px) bound so standard/large phones up to sm match. */
@media (max-width: 540.98px) {
  .nav-mobile-menu a { padding: 11px 0; }
  .nav-mobile-menu .m-group-head > a { padding: 11px 0; }
  .nav-mobile-menu .m-subgroup-head > a { padding: 8px 0; }
  .nav-mobile-menu .m-subsub a { padding: 6px 0; }
  .nav-mobile-menu .m-subsub { margin-bottom: 2px; }
  .nav-mobile-menu a.nav-cta { margin-top: 16px; padding: 12px 32px; }
}

/* --- Hub: category sections --- */
.hub-cat { padding: 8px var(--gutter) 4px; }
@media (max-width: 900.98px){ .hub-cat { padding-left: var(--gutter-sm); padding-right: var(--gutter-sm); } }
.hub-cat-head {
  display: flex; align-items: baseline; gap: 12px;
  margin: 26px 0 12px; padding-bottom: 8px;
  border-bottom: 1px solid var(--border);
}
.hub-cat-head a {
  font-size: var(--text-lg); font-weight: var(--fw-medium);
  color: var(--black); text-decoration: none; letter-spacing: -0.01em;
}
.hub-cat-head a:hover { color: var(--warm-50); }
.hub-cat-head .hub-cat-more {
  font-size: var(--text-2xs); letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--warm-50); text-decoration: none;
}
.service-card.service-card--secondary { opacity: 0.92; }
.service-card.service-card--secondary .service-title::after {
  content: " · relacionado"; font-size: 0.6875rem; color: var(--warm-50);
  letter-spacing: var(--ls-tight); text-transform: none;
}

/* ═══════════════════════════════════════════════════════════════
   BREAKPOINT xxl — Very large / full-HD+ screens (≥1920px)
   The homepage full-screen sections pin their scroll-down arrow to the
   bottom with margin-top:auto, which absorbs ALL the free space and
   shoves the header + cards to the TOP of the section. On tall ≥1920
   screens that strands the cards high with a big empty band below. Give
   the header its own margin-top:auto so the free space splits evenly
   above and below the content — centering the header+cards block while
   the arrow stays at the bottom.
   ═══════════════════════════════════════════════════════════════ */
@media (min-width: 1920px) {
  #servicios .hub-head { margin-top: auto; }
}
