/* layout.css — page structure, mobile-first.
   Note: media queries use literal breakpoint values because CSS variables
   are not supported in @media feature values. Values match tokens in
   brand-tokens.json → breakpoints.

   Sizing convention: rem for typography, spacing, and layout dimensions —
   1rem = 16px (browser default, never overridden on <html>). px stays for
   1–2px borders/hairlines, micro-transforms, box-shadow blurs, the 999px
   pill idiom, and @media breakpoints (where em is inconsistent across
   browsers). Tokens like --sp-nav-height keep their downstream contract. */

* { box-sizing: border-box; }
html, body { margin: 0; padding: 0; overflow-x: hidden; }
html { scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
}

:root {
  --sp-nav-height: 8rem;
  --sp-nav-height-mobile: 4.5rem;
  /* Widescreen layout envelope: deliberately uncapped so sections stretch
     edge-to-edge on large displays (Tesla.com reference). The brand token
     --spacing-container-max (1200px) is untouched and remains available for
     components that want the legacy narrow column. Centering rules using
     `margin: 0 auto` alongside this var stay harmless when max-width resolves
     to `none`. */
  --sp-content-max: none;
  /* Fluid page-edge gutter: 16px on phones → 48px on desktop+. Caps at
     3rem to match the ~48px subtle gutter visible on Tesla.com sections. */
  --sp-page-gutter: clamp(1rem, 4vw, 3rem);
  /* Nav uses the same 48px ceiling so the wordmark and right-side controls
     line up with section content edges. */
  --sp-nav-gutter: clamp(1rem, 4vw, 3rem);
}

/* In-page anchors (#proyectos, #aliados, …) must clear the sticky header. */
:target,
main section[id] {
  scroll-margin-top: var(--sp-nav-height-mobile);
}
@media (min-width: 1024px) {
  :target,
  main section[id] { scroll-margin-top: var(--sp-nav-height); }
}
/* Landing target for the hero scroll cue — bumped a touch past the nav so
   the section heading sits clear of the header. */
#proyectos { scroll-margin-top: 6rem; }
body {
  font-family: var(--font-body);
  font-size: var(--size-15);
  color: var(--color-text);
  background: var(--color-sand);
  line-height: 1.5;
}
/* Sticky footer — scoped to the contact page only. Applying body { display:
   flex } globally was breaking Splide's width calculation inside the home
   Aliados/Equipo/Testimonios carousels, so the pattern is opt-in per page.
   Contact has no carousels and short content, so it benefits cleanly. */
body[data-page="contact"] {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
body[data-page="contact"] > main { flex: 1 0 auto; }
/* Kill pure-black leaks from UA defaults and third-party widgets. */
input, textarea, select, button { color: inherit; font: inherit; }
img, svg { max-width: 100%; display: block; }
a { color: var(--color-deep); }

/* Nav ---------------------------------------------------------------------- */
/* Fixed so it floats over the hero. Monochromatic-alpha treatment: a single
   hue (--color-deep) at two densities, both translucent + blurred so the
   page beneath shimmers through. Initial: navy at 55% — a navy haze over
   the dark hero overlay, carrying the white wordmark + sand controls.
   Scrolled (past 70% of hero, or immediate on no-hero pages): navy at 15%
   — a faint cool tint over the sand body, frosted-glass tile that the color
   logo + deep navy controls sit on. The diffused low-opacity shadow lifts
   the scrolled state; a quiet hairline holds the rim on browsers that skip
   backdrop-filter. Color/blur transition together on `md`; the shadow
   settles in slightly faster on `sm` so the lift feels like a consequence
   of the surface change, not a parallel animation. */
.sp-nav {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 100;
  background: color-mix(in srgb, var(--color-deep) 55%, transparent);
  backdrop-filter: blur(14px) saturate(1.15);
  -webkit-backdrop-filter: blur(14px) saturate(1.15);
  border-bottom: 1px solid transparent;
  height: var(--sp-nav-height-mobile);
  transition: background-color var(--motion-duration-md) var(--motion-ease-standard),
              border-color var(--motion-duration-md) var(--motion-ease-standard),
              backdrop-filter var(--motion-duration-md) var(--motion-ease-standard),
              -webkit-backdrop-filter var(--motion-duration-md) var(--motion-ease-standard),
              box-shadow var(--motion-duration-sm) var(--motion-ease-standard);
}
.sp-nav.is-scrolled {
  background: color-mix(in srgb, var(--color-deep) 15%, transparent);
  /* Amber rim — brand fingerprint at the moment the surface resolves. Echoes
     the warmest of the three logomark bars (navy/forest/amber) and restores
     a hint of warmth to the otherwise cool nav. 40% is the threshold where
     the eye registers warmth without registering the line as a UI element. */
  border-bottom-color: color-mix(in srgb, var(--color-amber) 40%, transparent);
  box-shadow: 0 8px 28px rgba(26, 58, 82, 0.07);
}
.sp-nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--spacing-md);
  max-width: var(--sp-content-max);
  margin: 0 auto;
  padding: 0 var(--sp-nav-gutter);
  height: 100%;
}
@media (min-width: 1024px) {
  .sp-nav { height: var(--sp-nav-height); }
}
/* Pages without a hero need top padding so their first section isn't hidden
   beneath the fixed nav. The nav stays in its initial (translucent navy)
   state on these pages — only the home hero scroll flips it (see nav.js). */
body[data-page="contact"] main,
body[data-page="404"] main,
body[data-page="projects"] main {
  padding-top: var(--sp-nav-height-mobile);
}
@media (min-width: 1024px) {
  body[data-page="contact"] main,
  body[data-page="404"] main,
  body[data-page="projects"] main { padding-top: var(--sp-nav-height); }
}
.sp-nav__logo {
  display: inline-flex;
  align-items: center;
  color: var(--color-sand);
  text-decoration: none;
}
.sp-nav__logo-img {
  height: var(--logo-height-nav-mobile, 2.10rem);
  width: auto;
  display: block;
}
@media (min-width: 1024px) {
  .sp-nav__logo-img { height: var(--logo-height-nav, 5.0rem); }
}
/* Brand mark variants. Initial nav surface is dark (--color-deep) — the
   white wordmark (--light variant) sits on it. On `.is-scrolled` the surface
   flips to sand and the color logo (--dark, designed for dark text on light
   bg) takes over. */
.sp-nav__logo-img--dark { display: none; }
.sp-nav.is-scrolled .sp-nav__logo-img--light { display: none; }
.sp-nav.is-scrolled .sp-nav__logo-img--dark  { display: block; }
.sp-nav__logo-text {
  font-family: var(--font-display);
  font-size: 1.5rem;
}
.sp-nav__drawer {
  position: fixed;
  top: 0;
  right: 0;
  width: 80%;
  max-width: 20rem;
  height: 100vh;
  background: var(--color-primary);
  padding: var(--spacing-xl) var(--spacing-lg);
  transform: translateX(100%);
  transition: transform var(--motion-duration-md) var(--motion-ease-decelerate);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-lg);
  box-shadow: var(--shadow-lg);
  z-index: 101;
}
body[data-nav-open] .sp-nav__drawer { transform: translateX(0); }

/* Scrim — covers the page behind the drawer. Click closes (handled in
   nav.js). Pointer-events disabled until open so the scrim doesn't block
   clicks on the page. */
.sp-nav__scrim {
  position: fixed;
  inset: 0;
  background: rgba(20, 20, 19, 0.48);
  opacity: 0;
  pointer-events: none;
  z-index: 100;
  transition: opacity var(--motion-duration-md) var(--motion-ease-decelerate);
}
body[data-nav-open] .sp-nav__scrim {
  opacity: 1;
  pointer-events: auto;
}
@media (min-width: 1024px) {
  /* Desktop layout has the drawer inline; scrim should never appear. */
  .sp-nav__scrim { display: none; }
}
.sp-nav__links {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: var(--spacing-md);
}
.sp-nav__links a {
  text-decoration: none;
  color: var(--color-sand);
  font-size: 1rem;
  font-weight: var(--weight-medium);
}
.sp-nav__links a:hover { opacity: 0.8; }

/* Nav CTA — fixed 2.75rem baseline to align with links + lang toggle. */
.sp-nav__cta.sp-button {
  height: 2.75rem;
  padding: 0.75rem 1.75rem;
  font-size: 1rem;
  font-weight: var(--weight-medium);
}

@media (min-width: 1024px) {
  .sp-nav__hamburger { display: none; }
  .sp-nav__drawer {
    position: static;
    width: auto;
    max-width: none;
    height: auto;
    transform: none;
    background: transparent;
    padding: 0;
    flex-direction: row;
    align-items: center;
    box-shadow: none;
  }
  .sp-nav__links {
    flex-direction: row;
    gap: var(--spacing-lg);
  }
}

/* Hero --------------------------------------------------------------------- */
/* Every --sp-hero-* custom property consumed below is set (or left unset) by
   the inline <style> block in templates/_partials/head.html, driven by
   config/site.json -> hero.*. Fallbacks here preserve the default look when a
   key is null. Vertical rhythm inside the stack is driven by per-element
   margins (8px scale), NOT a flex gap. */
.sp-hero {
  position: relative;
  /* Nav is fixed-floating, so the hero owns the full viewport (no nav-height
     subtraction). 100vh fallback first for older browsers; 100dvh excludes
     collapsible mobile UI so the hero doesn't jump when the URL bar hides. */
  min-height: var(--sp-hero-min-height, 100vh);
  min-height: var(--sp-hero-min-height, 100dvh);
  color: var(--color-sand);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-hero-padding,
    4rem
    calc(var(--sp-page-gutter) + env(safe-area-inset-right))
    3rem
    calc(var(--sp-page-gutter) + env(safe-area-inset-left))
  );
  background-size: cover;
  background-position: center;
  isolation: isolate;
}
/* Tonal scrim: darker at top where the eyebrow/H1 sit, lifts readability. */
.sp-hero::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  background: linear-gradient(
    180deg,
    var(--sp-hero-overlay-top, rgba(26, 58, 82, 0.45)),
    var(--sp-hero-overlay-bottom, rgba(26, 58, 82, 0.35))
  );
  pointer-events: none;
}
.sp-hero--solid {
  background-color: var(--sp-hero-bg-color, var(--color-hero, var(--color-deep)));
}
.sp-hero--solid::before { display: none; }
.sp-hero__inner {
  max-width: 70rem;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-hero-gap, 0);
  text-align: center;
  position: relative;
}

.sp-hero__eyebrow {
  font-family: var(--font-body);
  font-size: clamp(0.9375rem, 3vw, 1.375rem);
  font-weight: var(--weight-medium);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-amber);
  opacity: 0.9;
  margin: 0 0 1rem;
  display: inline-block;
  cursor: default;
  transition: letter-spacing var(--motion-duration-md) var(--motion-ease-standard),
              opacity var(--motion-duration-xs) var(--motion-ease-standard),
              transform var(--motion-duration-md) var(--motion-ease-standard);
}
.sp-hero__eyebrow:hover {
  letter-spacing: 0.18em;
  opacity: 1;
  transform: translateY(-1px);
}
@media (prefers-reduced-motion: reduce) {
  .sp-hero__eyebrow,
  .sp-hero__eyebrow:hover { transition: none; transform: none; }
}
.sp-hero__headline {
  font-family: var(--sp-hero-headline-font-family, var(--font-display));
  font-size: var(--sp-hero-headline-size, clamp(2.25rem, 11vw, 3.625rem));
  font-weight: var(--sp-hero-headline-weight, 600);
  line-height: var(--sp-hero-headline-line-height, 1.12);
  letter-spacing: -0.015em;
  color: var(--sp-hero-headline-color, var(--color-sand));
  max-width: 60.75rem;
  margin: 0 1 1rem;
}
.sp-hero__subline {
  font-family: var(--sp-hero-subline-font-family, var(--font-body));
  font-size: var(--sp-hero-subline-size, clamp(1.125rem, 3.6vw, 1.85rem));
  line-height: 1.5;
  font-weight: var(--weight-regular);
  color: var(--sp-hero-subline-color, var(--color-sand));
  opacity: var(--sp-hero-subline-opacity, 0.88);
  max-width: var(--sp-hero-subline-max-width, 60rem);
  margin: 0 auto 3rem;
}

.sp-hero__metrics {
  list-style: none;
  padding: 0;
  margin: 0 0 2.5rem;
  width: 100%;
  max-width: 45rem;
  display: flex;
  flex-direction: row;
  gap: 1.5rem;
  justify-content: center;
  align-items: center;
}

.sp-hero__cta-cluster {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  width: 100%;
  max-width: 22.5rem;
  align-items: stretch;
  justify-content: center;
}
.sp-hero__cta {
  align-self: stretch;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  height: 3.375rem;
  font-size: var(--sp-hero-cta-size, 1rem);
  font-weight: 600;
  padding: var(--sp-hero-cta-padding, 1rem 1.5rem);
  border-radius: var(--sp-hero-cta-radius, var(--radius-button));
}
.sp-hero__cta-arrow {
  font-size: 1.5rem;
  line-height: 1;
  display: inline-block;
}
@media (min-width: 640px) {
  .sp-hero__cta-cluster {
    flex-direction: row;
    gap: 1rem;
    max-width: none;
    width: auto;
    align-items: center;
  }
  .sp-hero__cta {
    align-self: auto;
    min-width: 16.25rem;
    padding: var(--sp-hero-cta-padding, 1rem 2rem);
  }
}

@media (min-width: 768px) {
  .sp-hero {
    padding: var(--sp-hero-padding,
      5rem
      calc(var(--sp-page-gutter) + env(safe-area-inset-right))
      5rem
      calc(var(--sp-page-gutter) + env(safe-area-inset-left))
    );
  }
  .sp-hero__headline {
    font-size: var(--sp-hero-headline-size, clamp(3.5rem, 7vw, 5.5rem));
    line-height: var(--sp-hero-headline-line-height, 1.04);
    letter-spacing: -0.02em;
  }
  .sp-hero__metrics { gap: 3rem; }
}

/* Extra-narrow phones (iPhone SE 1st gen, Galaxy Fold outer display, etc.) */
@media (max-width: 360px) {
  .sp-hero {
    padding-left: calc(1rem + env(safe-area-inset-left));
    padding-right: calc(1rem + env(safe-area-inset-right));
  }
  .sp-hero__metrics { gap: 0.75rem; }
}

/* Short landscape phones: let the hero collapse to content height. */
@media (max-height: 560px) and (orientation: landscape) {
  .sp-hero {
    min-height: 0;
    padding-top: 2rem;
    padding-bottom: 2rem;
  }
  .sp-hero__subline { margin-bottom: 1.25rem; }
  .sp-hero__metrics { margin-bottom: 1.25rem; }
}

/* Sections ----------------------------------------------------------------- */
.sp-section {
  padding: var(--spacing-section) var(--sp-page-gutter);
  max-width: var(--sp-content-max);
  margin: 0 auto;
}
/* Sand band — when Equipo is rendered (white) right before Aliados, this
   stays transparent so the body sand shows through, preserving the
   white→sand→deep-footer rhythm. When Equipo is hidden (Nosotros's
   sand-ending gradient lands directly on Aliados), the .sp-aliados--white
   modifier flips this to white so two sand bands don't sit back-to-back.
   Contacto on its own page uses the standard .sp-section envelope. */
#aliados {
  max-width: none;
  padding-left: var(--sp-page-gutter);
  padding-right: var(--sp-page-gutter);
  background: transparent;
}
#aliados.sp-aliados--white {
  background: var(--color-white);
}
/* White bands — Servicios and Equipo break the sand with a full-bleed
   white wrapper. Equipo sits between the sand-ending Nosotros gradient
   and the sand Aliados; giving it white preserves the white/sand
   alternation. Inner content centers via .sp-section-servicios__grid /
   .sp-section__header (capped at --spacing-container-max). */
#servicios,
#equipo {
  background: var(--color-white);
  max-width: none;
  padding-left: var(--sp-page-gutter);
  padding-right: var(--sp-page-gutter);
}
/* Nosotros — long section holding four subsections. Full-bleed with a soft
   vertical gradient (sand → near-white core → sand) so the block reads as
   one unit while its mid stretch gets visual lift. The outer stops match
   body sand exactly, so the section edges remain hard against the white
   Servicios band above and the white Aliados band below. */
#nosotros {
  background: linear-gradient(
    180deg,
    var(--color-sand) 0%,
    var(--color-sand) 8%,
    #fbf8f2 45%,
    #fbf8f2 55%,
    var(--color-sand) 92%,
    var(--color-sand) 100%
  );
  max-width: none;
  padding-left: var(--sp-page-gutter);
  padding-right: var(--sp-page-gutter);
}
/* Nosotros content wrappers center within the 1200px envelope. The
   .sp-about-pillars rule in components.css carries max-width + margin:auto
   for the grid itself; the section header needs help here too. Left-aligned
   text inside; the wrapper itself is centered by margin:auto. */
.sp-section-nosotros > .sp-section__header {
  max-width: var(--sp-content-max);
  margin-left: auto;
  margin-right: auto;
}
/* Section-header blurb sits left-aligned (matches the rest of the page).
   Override any center-inheritance from parent flex/grid. */
.sp-section-nosotros > .sp-section__header,
.sp-section-equipo > .sp-section__header { text-align: left; }
/* Tighter vertical rhythm on the homepage — 4rem top/bottom on these
   sections yields ~8rem inter-section gap, matching the Hero→Proyectos
   cadence. */
#aliados,
#servicios,
#nosotros,
#equipo {
  padding-top: 4rem;
  padding-bottom: 4rem;
}
/* Contact page is a single-section page; preserve its roomier block. */
#contacto {
  padding-top: 6rem;
  padding-bottom: 6rem;
}
@media (max-width: 767px) {
  #contacto {
    padding-top: 4rem;
    padding-bottom: 4rem;
  }
}
/* Full-bleed sections (aliados, servicios) need the outer band to stretch
   edge-to-edge but still align their inner content with the rest of the
   page. We achieve that via max-width:none + an inner wrapper (grid or
   section__header scoped below). */
.sp-section__header { margin-bottom: 2.5rem; }
/* Section title typography mirrors #proyectos (reference): responsive clamp
   that maxes at 3.5rem, semibold, tight leading. Hardcoded (not
   token-derived) to match the Proyectos rule one-for-one. */
.sp-section__header h1,
.sp-section__header h2 {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 4vw, 3.5rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--color-deep);
  margin: 0 0 var(--spacing-sm);
}
@media (max-width: 767px) {
  .sp-section__header h1,
  .sp-section__header h2 { font-size: clamp(2rem, 7vw, 2.5rem); }
}
/* Amber brand spark under section titles — matches Proyectos bar (3px × 3rem,
   0.75rem offset), not the thinner token default. */
.sp-section__header h1::after,
.sp-section__header h2::after {
  content: "";
  display: block;
  width: 3rem;
  height: 3px;
  background: var(--color-amber);
  border-radius: var(--radius-full);
  margin-top: 0.75rem;
}

/* Full-bleed section headers — align titles with nav logo */
.sp-aliados > .sp-section__header,
.sp-section-servicios > .sp-section__header,
.sp-section-equipo > .sp-section__header,
.sp-section-equipo > .sp-team-carousel {
  max-width: var(--sp-content-max);
  margin-left: auto;
  margin-right: auto;
}

/* Servicios ---------------------------------------------------------------- */
/* Background + full-bleed are owned by the #servicios ID rule above so we can
   alternate sand/white at the section level. The class here keeps only the
   grid envelope. */
.sp-section-servicios {
  max-width: none;
  padding-left: var(--sp-page-gutter);
  padding-right: var(--sp-page-gutter);
}
.sp-section-servicios__grid {
  max-width: var(--sp-content-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--spacing-lg);
}
@media (min-width: 768px) {
  .sp-section-servicios__grid { grid-template-columns: repeat(3, 1fr); }
}

/* Portfolio ---------------------------------------------------------------- */
/* All rules below are scoped to #proyectos so the refactor doesn't bleed into
   other sections or the card internals emitted by susplify-projects. */
.sp-portfolio-item { list-style: none; }

/* Each fragment carries `<div data-lang-fragment="es|en">`; show only the
   active language. `<html lang>` is set by lang.js so the toggle is instant
   and JS-free. The selector is universal — covers portfolio cards, modal
   slots, the per-project page hero, the related-projects list, breadcrumb,
   grid pills, and any future fragment that adopts the same attribute. */
html[lang="es"] [data-lang-fragment="en"],
html[lang="en"] [data-lang-fragment="es"] {
  display: none;
}

#proyectos {
  --sp-portfolio-max: var(--sp-content-max);
  max-width: none;
  padding-top: 6rem;
  padding-bottom: 6rem;
  padding-left: var(--sp-page-gutter);
  padding-right: var(--sp-page-gutter);
}
@media (max-width: 767px) {
  #proyectos { padding-top: 4rem; padding-bottom: 4rem; }
}

#proyectos .sp-portfolio-head {
  max-width: var(--sp-portfolio-max);
  margin: 0 auto 2.5rem;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 1.5rem;
  align-items: stretch;
}
@media (min-width: 1024px) {
  #proyectos .sp-portfolio-head {
    flex-direction: row;
    justify-content: space-between;
    align-items: flex-end;
    gap: 2rem;
  }
}
#proyectos .sp-portfolio-head__titles { flex: 1 1 auto; min-width: 0; }
#proyectos .sp-portfolio-head__titles h2 {
  font-family: var(--font-display);
  font-size: clamp(2.5rem, 4vw, 3.5rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--color-deep);
  margin: 0;
}
@media (max-width: 767px) {
  #proyectos .sp-portfolio-head__titles h2 { font-size: clamp(2rem, 7vw, 2.5rem); }
}
#proyectos .sp-portfolio-head__titles h2::after {
  content: "";
  display: block;
  width: 3rem;
  height: 3px;
  background: var(--color-amber);
  border-radius: var(--radius-full);
  margin-top: 0.75rem;
}

/* Filter tabs — scoped overrides of the shared .sp-tag look. */
#proyectos .sp-portfolio-filters {
  display: flex;
  flex-wrap: nowrap;
  gap: 0.75rem;
  margin: 0;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 0.25rem;
}
#proyectos .sp-portfolio-filters::-webkit-scrollbar { display: none; }
@media (min-width: 1024px) {
  #proyectos .sp-portfolio-filters {
    overflow: visible;
    flex-wrap: wrap;
    justify-content: flex-end;
    padding-bottom: 0;
  }
}
#proyectos .sp-portfolio-filters .sp-tag {
  height: 2.5rem;
  min-height: 2.5rem;
  padding: 0.625rem 1.125rem;
  border: 1px solid var(--color-border);
  background: transparent;
  color: var(--color-text);
  font-size: 0.875rem;
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
  white-space: nowrap;
  transition: background-color var(--motion-duration-xs) var(--motion-ease-standard),
              color var(--motion-duration-xs) var(--motion-ease-standard),
              border-color var(--motion-duration-xs) var(--motion-ease-standard);
}
#proyectos .sp-portfolio-filters .sp-tag:hover { background: var(--alpha-deep-04); }
#proyectos .sp-portfolio-filters .sp-tag.is-active {
  background: var(--color-amber);
  color: var(--color-deep);
  border-color: var(--color-amber);
}
#proyectos .sp-portfolio-filters .sp-tag:focus-visible {
  outline: 2px solid var(--color-amber);
  outline-offset: 3px;
}

/* Grid container — paginated grid that replaces the previous Splide carousel.
   Columns are driven by a CSS variable so a single rule covers the three
   breakpoints; data-cols-* attributes on #sp-portfolio-grid carry the values
   coming from site.portfolio.grid (used by JS, not CSS). The visible page is
   selected by toggling [hidden] on each <li> from JS — no transform tricks,
   so a11y tools see only the active subset. */
#proyectos .sp-portfolio-grid-board {
  max-width: var(--sp-portfolio-max);
  margin: 0 auto;
  position: relative;
}
#proyectos .sp-portfolio-grid-board__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: grid;
  gap: var(--spacing-lg);
  grid-template-columns: repeat(var(--portfolio-cols, 4), minmax(0, 1fr));
  align-items: stretch;
}
@media (max-width: 1023px) {
  #proyectos .sp-portfolio-grid-board__list { --portfolio-cols: 2; }
}
@media (max-width: 639px) {
  #proyectos .sp-portfolio-grid-board__list { --portfolio-cols: 1; }
}
#proyectos .sp-portfolio-item[hidden] { display: none !important; }

/* Project full-page layout ------------------------------------------------ */
/* Top padding lives on .sp-project-hero so the dark hero background extends
   from the very top of the viewport (behind the translucent fixed nav) with
   no sand gap between nav and hero. */
.sp-project-page {
  max-width: var(--sp-content-max);
  margin: 0 auto;
  padding: 0 0 0;
}
@media (max-width: 767px) {
  .sp-project-page { padding-bottom: 3rem; }
}
.sp-project-page__back {
  display: inline-block;
  margin-top: var(--spacing-xl);
  font-family: var(--font-body);
  font-size: var(--size-14);
  font-weight: var(--weight-medium);
  color: var(--color-deep);
  text-decoration: none;
  letter-spacing: 0.02em;
}
.sp-project-page__back:hover { color: var(--color-amber); }

/* Breadcrumb — Inicio › Proyectos › <current>. Lives inside .sp-project-hero
   so it overlays the dark hero gradient instead of sitting on the sand
   backdrop. Absolute-positioned beneath the fixed nav; readable against the
   hero overlay via on-dark colors. */
.sp-project-breadcrumb {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.375rem;
  font-family: var(--font-body);
  font-size: var(--size-13);
  letter-spacing: 0.02em;
}
.sp-project-breadcrumb__sep { opacity: 0.5; }
.sp-project-hero .sp-project-breadcrumb {
  position: absolute;
  top: calc(var(--sp-nav-height-mobile) + var(--sp-3));
  left: var(--sp-page-gutter);
  right: var(--sp-page-gutter);
  margin: 0;
  z-index: 2;
  color: var(--fg-on-dark-muted);
}
.sp-project-hero .sp-project-breadcrumb a {
  color: var(--fg-on-dark-muted);
  text-decoration: none;
}
.sp-project-hero .sp-project-breadcrumb a:hover { color: var(--color-amber); }
.sp-project-hero .sp-project-breadcrumb__current {
  color: var(--color-sand);
  font-weight: var(--weight-medium);
}
@media (min-width: 1024px) {
  .sp-project-hero .sp-project-breadcrumb {
    top: calc(var(--sp-nav-height) + var(--sp-3));
  }
}

.sp-project-page__hero { margin-bottom: var(--spacing-xl); }
.sp-project-page__hero-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-sm);
  margin-bottom: var(--spacing-md);
}
/* Year + status pill — small, sand-on-deep so they read as metadata, not as
   primary content. Status pill carries a small dot whose color is keyed off
   the grid_type modifier so on-grid / off-grid / hybrid feel distinct. */
.sp-project-badge {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  height: 1.75rem;
  padding: 0 0.75rem;
  border-radius: var(--radius-full, 999px);
  font-family: var(--font-body);
  font-size: var(--size-13);
  font-weight: var(--weight-medium);
  letter-spacing: 0.04em;
}
.sp-project-badge--year {
  background: var(--color-deep);
  color: var(--color-sand);
}
.sp-project-badge--status {
  background: var(--alpha-deep-08, rgba(26,58,82,0.08));
  color: var(--color-deep);
  border: 1px solid var(--alpha-deep-16, rgba(26,58,82,0.16));
}
.sp-project-badge__dot {
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--color-text-muted);
}
.sp-project-badge--on-grid  .sp-project-badge__dot { background: #2ec27e; }
.sp-project-badge--off-grid .sp-project-badge__dot { background: var(--color-amber); }
.sp-project-badge--hybrid   .sp-project-badge__dot { background: var(--color-forest); }

.sp-project-page__eyebrow {
  font-family: var(--font-body);
  font-size: var(--size-13);
  font-weight: var(--weight-medium);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--color-amber);
  margin: 0 0 var(--spacing-xs);
}
.sp-project-page__hero h1 {
  font-family: var(--font-display);
  font-size: clamp(2.25rem, 5vw, 3.5rem);
  font-weight: 600;
  line-height: 1.1;
  color: var(--color-deep);
  margin: 0 0 var(--spacing-xs);
}
.sp-project-page__location {
  font-family: var(--font-body);
  font-size: var(--size-16);
  color: var(--color-text-muted);
  margin: 0;
}

/* Metrics strip — 4 tiles, equal width. Wraps to 2-up on tablet, stacks on
   mobile. "—" fallback keeps the row's shape stable when a metric is
   missing in the payload. */
.sp-project-metrics {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--spacing-md);
  margin-bottom: var(--spacing-xl);
}
@media (max-width: 1023px) {
  .sp-project-metrics { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 479px) {
  .sp-project-metrics { grid-template-columns: 1fr; }
}
.sp-project-metric {
  display: flex;
  flex-direction: column;
  gap: var(--spacing-xs);
  padding: var(--spacing-md) var(--spacing-lg);
  background: var(--color-background);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
}
.sp-project-metric__value {
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3vw, 2.25rem);
  font-weight: 600;
  line-height: 1;
  color: var(--color-deep);
}
.sp-project-metric__label {
  font-family: var(--font-body);
  font-size: var(--size-13);
  font-weight: var(--weight-medium);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-text-muted);
}

.sp-project-page__detail {
  margin-bottom: var(--spacing-xl);
}

/* Chart section — sits in rhythm with the other detail sections: same
   page gutter on the sides, same vertical breathing room. The canvas
   wrap below caps the height so the chart doesn't dominate tall viewports. */
.sp-project-chart {
  padding: var(--sp-10) var(--sp-page-gutter);
}
.sp-project-chart h2 {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 600;
  color: var(--color-deep);
  margin: 0 0 var(--spacing-md);
}
.sp-project-chart__canvas-wrap {
  position: relative;
  width: 100%;
  height: clamp(16rem, 38vw, 24rem);
}

/* Gallery — responsive grid of project images. */
.sp-project-gallery {
  margin-bottom: var(--spacing-xl);
}
.sp-project-gallery h2 {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 600;
  color: var(--color-deep);
  margin: 0 0 var(--spacing-md);
}
.sp-project-gallery__list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(15rem, 1fr));
  gap: var(--spacing-sm);
}
.sp-project-gallery__item {
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--color-sand);
  aspect-ratio: 4 / 3;
}
.sp-project-gallery__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.sp-project-page__related {
  padding: var(--sp-10) var(--sp-page-gutter);
}
.sp-project-page__related h2 {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2rem);
  font-weight: 600;
  color: var(--color-deep);
  margin: 0 0 var(--spacing-md);
}
.sp-project-page__related-list {
  list-style: none;
  margin: 0;
  padding: 0 0 var(--spacing-xs) 0;
  display: flex;
  gap: var(--spacing-md);
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
}
.sp-project-page__related-item {
  flex: 0 0 clamp(15rem, 28vw, 20rem);
  scroll-snap-align: start;
}
/* Related cards: the library's <a class="sp-card"> is the click surface.
   Focus ring lives in the same scoped rule under .sp-portfolio-item .sp-card
   in components.css; nothing extra needed here. */

/* Aliados ------------------------------------------------------------------ */
/* Background + full-bleed are owned by the #aliados ID rule above. */
.sp-aliados {
  max-width: none;
  padding-left: var(--sp-page-gutter);
  padding-right: var(--sp-page-gutter);
}
.sp-aliados__group {
  max-width: var(--sp-content-max);
  margin: 0 auto var(--spacing-xl);
}
.sp-aliados__group h3 {
  font-family: var(--font-body);
  font-size: var(--size-13);
  font-weight: var(--weight-medium);
  color: var(--color-text-secondary);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  margin: 0 0 var(--spacing-md);
}
.sp-aliados__empty {
  color: var(--color-text-muted);
  font-family: var(--font-body);
}

/* CTA strip ---------------------------------------------------------------- */
/* Closing CTA band sitting between Aliados and the deep footer. Background is
   a 50/50 mix of brand forest and brand deep — a dark teal (~#2a5256) that
   bridges the green and navy ends of the palette, so the page steps cleanly
   from sand → mix → deep into the footer. Derived via color-mix so any
   upstream change to forest or deep keeps this in sync. */
.sp-cta-strip {
  background: color-mix(in srgb, var(--color-forest) 50%, var(--color-deep) 50%);
  color: var(--color-sand);
  padding: 5rem var(--sp-page-gutter);
  text-align: center;
}
.sp-cta-strip__inner {
  max-width: 48rem;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--spacing-md);
}
.sp-cta-strip__heading {
  font-family: var(--font-display);
  font-size: clamp(2rem, 4vw, 3rem);
  font-weight: 600;
  line-height: 1.15;
  margin: 0;
  color: var(--color-sand);
}
.sp-cta-strip__sub {
  font-family: var(--font-body);
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  line-height: 1.5;
  margin: 0;
  opacity: 0.9;
  max-width: 38rem;
}
.sp-cta-strip__cta {
  margin-top: var(--spacing-sm);
  height: 3rem;
  padding: 0.875rem 1.75rem;
  font-size: 1rem;
}
.sp-cta-strip__cta-arrow {
  font-size: 1rem;
  line-height: 1;
  display: inline-block;
}
@media (max-width: 767px) {
  .sp-cta-strip { padding-top: 4rem; padding-bottom: 4rem; }
}

/* Nosotros / team ---------------------------------------------------------- */
.sp-section-nosotros__blurb {
  font-family: var(--font-body);
  font-size: var(--size-16);
  color: var(--color-text);
  max-width: 45rem;
}
/* Contact ------------------------------------------------------------------ */
.sp-contact__segments {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-sm);
  margin-bottom: var(--spacing-lg);
}
.sp-contact__fallback {
  margin-top: var(--spacing-lg);
  font-family: var(--font-body);
  color: var(--color-text-muted);
}

/* 404 ---------------------------------------------------------------------- */
.sp-404 {
  min-height: 60vh;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
}
.sp-404__inner h1 {
  font-family: var(--font-display);
  font-size: var(--size-80);
  font-weight: var(--weight-regular);
  color: var(--color-deep);
  margin: 0;
}
.sp-404__actions {
  display: flex;
  gap: var(--spacing-md);
  justify-content: center;
  margin-top: var(--spacing-lg);
  flex-wrap: wrap;
}

/* Footer ------------------------------------------------------------------- */
.sp-footer {
  background: var(--color-deep);
  color: var(--color-sand);
  padding: var(--spacing-xl) var(--sp-page-gutter) var(--spacing-md);
}
.sp-footer a { color: var(--color-sand); }
.sp-footer__inner {
  max-width: var(--sp-content-max);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--spacing-lg);
}
.sp-footer__brand {
  width: fit-content;
  height: fit-content;
}
.sp-footer__wordmark {
  font-family: var(--font-display);
  font-size: 1.5rem;
}
.sp-footer__wordmark-img {
  height: 3.875rem;
  width: auto;
  display: block;
}
.sp-footer__motto {
  margin: var(--spacing-xs) 0 0;
  opacity: 0.8;
}
.sp-footer__links,
.sp-footer__social {
  display: flex;
  flex-wrap: wrap;
  gap: var(--spacing-md);
  padding: 0;
  margin: 0;
  list-style: none;
}
/* Footer nav + social stay on one line each — never wrap. */
.sp-footer__links {
  flex-wrap: nowrap;
  align-items: center;
  white-space: nowrap;
}
.sp-footer__social {
  flex-wrap: nowrap;
  gap: var(--spacing-sm);
  align-items: center;
}
.sp-footer__links a,
.sp-footer__social a { text-decoration: none; }
.sp-footer__contact {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--spacing-sm);
}
.sp-footer__copy {
  max-width: var(--sp-content-max);
  margin: var(--spacing-lg) auto 0;
  padding-top: var(--spacing-md);
  border-top: 1px solid rgba(245, 239, 230, 0.15);
  opacity: 0.8;
}
@media (min-width: 1024px) {
  .sp-footer__inner {
    /* Brand shrinks to its wordmark image; nav gets the flex slack so the row
       balances; contact + social size to content. Both nav (5 links) and
       social (4 icons) stay on a single line. */
    grid-template-columns: auto 1fr auto auto;
    align-items: center;
  }
}

/* ========================================================================== */
/* Project detail — page-level layout                                         */
/* Migrated from the susplify-projects library. The hero and bottom CTA strip */
/* keep the project namespace (.sp-project-hero / .sp-project-cta-strip) so   */
/* they don't collide with the home #hero (.sp-hero) and home #cta-strip      */
/* (.sp-cta-strip) styles already defined above.                              */
/* ========================================================================== */
.sp-project-hero {
  position: relative;
  overflow: hidden;
  min-height: var(--layout-detail-hero-min-h);
  background: var(--color-deep);
  color: var(--fg-on-dark);
  /* Top padding absorbs the fixed nav height so the hero starts at the very
     top of the viewport (its background extends behind the translucent nav)
     while text content stays clear of it. */
  padding: calc(var(--sp-nav-height-mobile) + var(--sp-10)) var(--sp-page-gutter) var(--sp-10);
  display: flex;
  align-items: flex-end;
}
@media (min-width: 1024px) {
  .sp-project-hero {
    padding-top: calc(var(--sp-nav-height) + var(--sp-10));
  }
}
.sp-project-hero__bg {
  position: absolute; inset: 0;
  background-size: cover;
  background-position: center;
  filter: saturate(1.05) contrast(1.02);
}
.sp-project-hero__overlay {
  position: absolute; inset: 0;
  background: linear-gradient(
    180deg,
    transparent 0%,
    var(--alpha-deep-50) 50%,
    var(--alpha-deep-75) 100%
  );
}
.sp-project-hero__inner {
  position: relative;
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.sp-project-hero__title {
  font-family: var(--font-body);
  font-size: var(--t-display-size);
  font-weight: var(--t-display-weight);
  line-height: var(--t-display-lh);
  letter-spacing: var(--t-display-track);
  color: var(--color-sand);
  margin: 0;
  max-width: 22ch;
}
.sp-project-hero__subline {
  font-size: var(--t-body-lg-size);
  font-weight: var(--t-body-lg-weight);
  color: var(--fg-on-dark-muted);
  margin: 0;
}
.sp-project-hero__facts {
  display: flex; flex-wrap: wrap; gap: var(--sp-3);
  margin-top: var(--sp-3);
}

/* Detail sections — full-bleed like home page sections, inset only by the
   page gutter so they align edge-to-edge with the rest of the site. */
.sp-metrics-strip,
.sp-story,
.sp-ficha,
.sp-galeria {
  padding: var(--sp-10) var(--sp-page-gutter);
}
/* Hairline separators between adjacent sections. */
.sp-metrics-strip + .sp-story,
.sp-story + .sp-ficha,
.sp-ficha + .sp-galeria,
.sp-galeria + .sp-project-cta-strip,
.sp-ficha + .sp-project-cta-strip,
.sp-metrics-strip + .sp-ficha {
  background-image: linear-gradient(
    to right,
    transparent 0%,
    var(--alpha-deep-16) 12%,
    var(--alpha-deep-16) 88%,
    transparent 100%
  );
  background-size: 100% var(--size-1);
  background-repeat: no-repeat;
  background-position: top center;
}

/* Partner card — sand-toned card with logo + optional name + optional link. */
.sp-partner { display: flex; flex-direction: column; gap: var(--sp-4); }
.sp-partner__card {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  padding: var(--sp-6) var(--sp-5);
  background: var(--alpha-sand-32, var(--color-sand));
  border: var(--size-1) solid var(--alpha-deep-16);
  border-radius: var(--radius-md, 12px);
  min-height: 140px;
}
.sp-partner__link {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-3);
  text-decoration: none;
  color: inherit;
  width: 100%;
}
.sp-partner__link:hover .sp-partner__name { color: var(--color-amber); }
.sp-partner__logo {
  display: block;
  max-height: 96px;
  max-width: 100%;
  width: auto;
  object-fit: contain;
}
.sp-partner__name {
  font-family: var(--font-body);
  font-size: var(--size-14);
  font-weight: var(--weight-medium);
  color: var(--color-deep);
  letter-spacing: 0.02em;
  text-align: center;
  transition: color 160ms ease;
}
/* Name-only partner — when payload provides partner.name without a logo,
   keep the same .sp-partner__card shell but render the name as the focal
   element so the card has visual mass comparable to the logo case. */
.sp-partner__name--lg {
  font-size: var(--t-h3-size);
  font-weight: var(--t-h3-weight);
  line-height: var(--t-h3-lh);
  letter-spacing: var(--t-h3-track);
  color: var(--color-deep);
  text-align: center;
}
.sp-partner__link--name-only {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 96px;
}
.sp-partner__link--name-only:hover .sp-partner__name--lg { color: var(--color-amber); }
@media (max-width: 680px) {
  .sp-partner__card { min-height: 120px; padding: var(--sp-5) var(--sp-4); }
  .sp-partner__logo { max-height: 72px; }
  .sp-partner__link--name-only { min-height: 72px; }
}

/* Multi-partner: inline list of names under the same "En alianza con" label
   when payload supplies partners[]. No logos — just text, dot-separated. */
.sp-partner--list .sp-partner__list {
  list-style: none;
  margin: 0;
  padding: var(--sp-6) var(--sp-5);
  background: var(--alpha-sand-32, var(--color-sand));
  border: var(--size-1) solid var(--alpha-deep-16);
  border-radius: var(--radius-md, 12px);
  min-height: 140px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2) var(--sp-3);
  font-family: var(--font-body);
  font-size: var(--size-14);
  font-weight: var(--weight-medium);
  color: var(--color-deep);
  letter-spacing: 0.02em;
  text-align: center;
}
.sp-partner__list-item { display: inline-flex; align-items: center; gap: var(--sp-3); }
.sp-partner__list-item + .sp-partner__list-item::before {
  content: "·";
  color: var(--alpha-deep-48, var(--color-text-muted));
  margin-right: var(--sp-1);
}
.sp-partner__list-item a {
  color: inherit;
  text-decoration: none;
  transition: color 160ms ease;
}
.sp-partner__list-item a:hover { color: var(--color-amber); }
@media (max-width: 680px) {
  .sp-partner--list .sp-partner__list { min-height: 120px; padding: var(--sp-5) var(--sp-4); }
}

/* Merged metrics strip — up to 5 tiles in a single row: capacity, kWh/year,
   Cobertura (spans 2 cols when present), CO2, Payback. data-count is the
   visible-tile count (1-5); data-coverage="1" widens the grid by one extra
   column so Cobertura's span-2 rule fits without forcing a wrap. When the
   row has only 1-2 tiles, coverage falls back to its natural single column. */
.sp-metrics-grid {
  display: grid;
  column-gap: var(--sp-8);
  row-gap: var(--sp-6);
  align-items: start;
}
.sp-metrics-grid[data-count="5"][data-coverage="1"] { grid-template-columns: repeat(6, minmax(0, 1fr)); }
.sp-metrics-grid[data-count="4"][data-coverage="1"] { grid-template-columns: repeat(5, minmax(0, 1fr)); }
.sp-metrics-grid[data-count="4"][data-coverage="0"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.sp-metrics-grid[data-count="3"][data-coverage="1"] { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.sp-metrics-grid[data-count="3"][data-coverage="0"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.sp-metrics-grid[data-count="2"][data-coverage="1"] { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.sp-metrics-grid[data-count="2"][data-coverage="0"] { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.sp-metrics-grid[data-count="1"]                    { grid-template-columns: 1fr; }
.sp-metrics-grid .sp-metric-lg--coverage             { grid-column: span 2; }
.sp-metrics-grid[data-count="1"] .sp-metric-lg--coverage { grid-column: auto; }

.sp-story__h {
  font-family: var(--font-body);
  font-size: var(--t-h2-size);
  font-weight: var(--t-h2-weight);
  line-height: var(--t-h2-lh);
  letter-spacing: var(--t-h2-track);
  color: var(--fg-strong);
  margin: 0 0 var(--sp-4);
  max-width: 22ch;
}
.sp-story__lede {
  font-size: var(--t-body-lg-size);
  line-height: var(--t-body-lg-lh);
  color: var(--fg-muted);
  margin: 0 0 var(--sp-6);
  max-width: 60ch;
}
.sp-story__flow {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-6);
}

.sp-ficha__h {
  font-family: var(--font-body);
  font-size: var(--t-h2-size);
  font-weight: var(--t-h2-weight);
  line-height: var(--t-h2-lh);
  letter-spacing: var(--t-h2-track);
  color: var(--fg-strong);
  margin: 0 0 var(--sp-6);
}
.sp-specs { margin: 0; padding: 0; display: grid; grid-template-columns: 1fr 1fr; column-gap: var(--sp-6); }

.sp-galeria__h {
  font-family: var(--font-body);
  font-size: var(--t-h2-size);
  font-weight: var(--t-h2-weight);
  line-height: var(--t-h2-lh);
  letter-spacing: var(--t-h2-track);
  color: var(--fg-strong);
  margin: 0 0 var(--sp-6);
}
.sp-gallery-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--sp-4);
}

.sp-project-cta-strip {
  background: var(--surface-cta);
  color: var(--fg-on-dark);
  padding: var(--sp-10) var(--sp-page-gutter);
}
.sp-project-cta-strip__inner {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--sp-6);
  flex-wrap: wrap;
}
.sp-project-cta-strip .sp-section-label { color: var(--fg-on-dark-muted); }
.sp-project-cta__copy { display: flex; flex-direction: column; gap: 0; }
.sp-project-cta__title {
  font-family: var(--font-body);
  font-size: var(--t-h1-size);
  font-weight: var(--t-h1-weight);
  line-height: var(--t-h1-lh);
  letter-spacing: var(--t-h1-track);
  color: var(--color-sand);
  max-width: 20ch;
  margin: 0;
}
.sp-project-cta__btn {
  font: var(--t-body-weight) var(--t-body-size)/1.2 var(--font-body);
  letter-spacing: 0.02em;
  color: var(--color-deep);
  background: var(--color-sand);
  padding: var(--size-14) var(--size-28);
  border-radius: var(--radius-sharp);
  text-decoration: none;
  transition: background-color var(--dur-fast) var(--ease-out);
}
.sp-project-cta__btn::after {
  content: "\2192";
  display: inline-block;
  margin-left: var(--sp-2);
  transition: transform var(--dur-fast) var(--ease-out);
}
.sp-project-cta__btn:hover { background: var(--color-amber); }
.sp-project-cta__btn:hover::after { transform: translateX(3px); }
.sp-project-cta__btn:focus-visible {
  outline: var(--size-2) solid var(--color-amber);
  outline-offset: var(--size-3);
}

@media (max-width: 960px) {
  .sp-story__flow { grid-template-columns: 1fr; }
  .sp-specs { grid-template-columns: 1fr; }
  .sp-gallery-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 680px) {
  .sp-card__content { padding: var(--sp-4); }
  /* Keep the nav-aware top padding on mobile so the breadcrumb has room and
     the hero background still flushes against the nav. */
  .sp-project-hero {
    padding: calc(var(--sp-nav-height-mobile) + var(--sp-8)) var(--sp-5) var(--sp-8);
    min-height: 0;
  }
  .sp-project-hero__title { font-size: var(--size-36); line-height: 1.1; }
  .sp-metrics-strip,
  .sp-story,
  .sp-ficha,
  .sp-galeria,
  .sp-project-cta-strip { padding: var(--sp-8) var(--sp-5); }
  .sp-metrics-grid { grid-template-columns: repeat(2, 1fr) !important; }
  .sp-metrics-grid[data-count="1"] { grid-template-columns: 1fr !important; }
  .sp-metrics-grid .sp-metric-lg {
    background-image: linear-gradient(
      to bottom,
      transparent 0%,
      var(--alpha-deep-16) 18%,
      var(--alpha-deep-16) 82%,
      transparent 100%
    );
    background-size: var(--size-1) 100%;
    background-repeat: no-repeat;
    background-position: left center;
    padding-left: var(--sp-5);
  }
  .sp-metrics-grid .sp-metric-lg:nth-child(2n+1) { background-image: none; padding-left: 0; }
  .sp-project-cta-strip__inner { flex-direction: column; align-items: stretch; }
  .sp-project-cta__btn { align-self: flex-start; }
  .sp-gallery-grid { grid-template-columns: 1fr; }
  .sp-gallery-cell.is-feat { grid-column: span 1; }
}
@media (max-width: 420px) {
  .sp-card__metrics[style] { grid-template-columns: repeat(2, minmax(0,1fr)) !important; }
  .sp-card__metrics[style] .sp-metric {
    background-image: linear-gradient(
      to bottom,
      transparent 0%,
      var(--alpha-deep-16) 18%,
      var(--alpha-deep-16) 82%,
      transparent 100%
    );
    background-size: var(--size-1) 100%;
    background-repeat: no-repeat;
    background-position: left center;
    padding-left: var(--sp-4);
  }
  .sp-card__metrics[style] .sp-metric:nth-child(2n+1) {
    background-image: none;
    padding-left: 0;
  }
  .sp-card__title { font-size: var(--size-28); line-height: 1.15; }
  .sp-card__summary { -webkit-line-clamp: 3; }
}

/* ========================================================================== */
/* All-projects page (/proyectos/) — wider grid, dedicated header.            */
/* `body[data-page="projects"] main` already pads for the fixed nav (see top  */
/* of this file). Add a small extra breathing room above the back link so it  */
/* clears the translucent nav band.                                           */
/* ========================================================================== */
.sp-projects-page { padding-top: 2rem; }
.sp-projects-page__header {
  max-width: var(--sp-content-max);
  margin: 0 auto var(--spacing-xl);
  padding: 0 var(--sp-page-gutter);
  display: flex;
  flex-direction: column;
  gap: var(--spacing-sm);
}
/* Catalogue: clear separation between filters and the grid below. The
   #proyectos .sp-portfolio-filters rule above (specificity 1,1,0) zeroes
   margin, so we chain id + class on the same element to win (1,2,0). */
#proyectos.sp-projects-page .sp-portfolio-filters { margin-bottom: 3rem; }
@media (min-width: 1024px) {
  #proyectos.sp-projects-page .sp-portfolio-filters { margin-bottom: 5rem; }
}
.sp-projects-page__back {
  display: inline-block;
  width: fit-content;
  font-family: var(--font-body);
  font-size: var(--size-14);
  font-weight: var(--weight-medium);
  color: var(--color-deep);
  text-decoration: none;
  letter-spacing: 0.02em;
  margin-bottom: var(--spacing-sm);
}
.sp-projects-page__back:hover { color: var(--color-amber); }
.sp-projects-page__title {
  font-family: var(--font-display);
  font-size: clamp(2rem, 5vw, 3.5rem);
  color: var(--color-deep);
  margin: 0;
  line-height: 1.05;
}
.sp-projects-page__lede {
  font-family: var(--font-body);
  font-size: var(--size-18);
  color: var(--color-text-muted);
  max-width: 60ch;
  margin: 0;
}

/* Wide variant of the portfolio grid: 4 cols on desktop. The base rule at
   line ~784 already defaults --portfolio-cols to 4; we lock it explicitly so
   future home-grid tweaks don't accidentally shrink the catalogue. */
.sp-portfolio-grid-board--wide { padding: 0 var(--sp-page-gutter); }
.sp-portfolio-grid-board--wide .sp-portfolio-grid-board__list {
  --portfolio-cols: 4;
}
@media (max-width: 1023px) {
  .sp-portfolio-grid-board--wide .sp-portfolio-grid-board__list { --portfolio-cols: 2; }
}
@media (max-width: 639px) {
  .sp-portfolio-grid-board--wide .sp-portfolio-grid-board__list { --portfolio-cols: 1; }
}

/* CTA below home pagination — "Ver más proyectos". */
.sp-portfolio-cta-row {
  display: flex;
  justify-content: center;
  margin-top: var(--spacing-lg);
}

/* ========================================================================== */
/* Contact page — two-column grid (form card + side panel).                   */
/* ========================================================================== */
.sp-contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  gap: var(--spacing-xl);
  align-items: start;
  margin-top: var(--spacing-lg);
}
@media (max-width: 1023px) {
  .sp-contact-grid {
    grid-template-columns: 1fr;
    gap: var(--spacing-lg);
  }
  /* Mobile: the side panel sets expectations before the form. */
  .sp-contact-side { order: -1; }
}

/* Short-laptop desktop viewports — e.g., 1930x1200 @ 125% zoom (~1544x960),
   or a 13"-14" 1366x768 laptop. Width is still desktop, but vertical room is
   reduced. Trim chrome sized for >=1080px-tall screens so the hero, nav, and
   section paddings stay balanced. Width gate keeps mobile/tablet rules
   untouched; height gate (<=880) skips standard 1080/1200/1440 desktops. */
@media (min-width: 1024px) and (max-height: 880px) {
  /* Redefine the var (not just .sp-nav height) so scroll-margin-top on anchors
     and the project breadcrumb top offsets stay in sync. */
  :root { --sp-nav-height: 6rem; }
  .sp-nav__logo-img { height: 4rem; }

  .sp-hero {
    padding-top: 3rem;
    padding-bottom: 3rem;
  }

  #proyectos { padding-top: 4rem; padding-bottom: 4rem; }
  #servicios,
  #nosotros,
  #equipo,
  #aliados {
    padding-top: 3rem;
    padding-bottom: 3rem;
  }
  .sp-cta-strip { padding-top: 3.5rem; padding-bottom: 3.5rem; }
}
