/* ============================================================
   SENSUM CONSTRUCCIONES — design tokens pulled from the live
   site's stylesheet (main.css / style.css) so colors match 1:1.
   ============================================================ */
:root{
  /* Brand colors sampled directly from the Sensum logo artwork:
     a red -> orange -> amber gradient mark on near-black neutrals. */
  --ink:         #1c1c1c;
  --ink-soft:    #2a2a2a;
  --charcoal:    #222222;
  --charcoal-2:  #3a3a3a;
  --charcoal-3:  #333333;
  --footer-black:#090909;
  --brand-red:      #f0351f;
  --brand-orange:   #f6740a;
  --brand-amber:    #ffaa0b;
  --brand-orange-rgb: 246,116,10;
  --brand-gradient: linear-gradient(135deg, var(--brand-red) 0%, var(--brand-orange) 55%, var(--brand-amber) 100%);
  --gray-text:   #555555;
  --gray-text-2: #373737;
  --gray-mid:    #888888;
  --border:      #dfe3e4;
  --border-2:    #cccccc;
  --bg-light:    #f5f5f5;
  --bg-lighter:  #fefefe;
  --white:       #ffffff;

  --font-head: "Oswald", "Helvetica Neue", Arial, sans-serif;
  --font-body: "Roboto", system-ui, -apple-system, "Segoe UI", Arial, sans-serif;

  --container: 1180px;
  --radius: 10px;
  --shadow-sm: 0 4px 16px rgba(20,20,20,0.08);
  --shadow-md: 0 12px 32px rgba(20,20,20,0.14);
  --shadow-gold: 0 10px 26px rgba(var(--brand-orange-rgb),0.35);

  --ease-out: cubic-bezier(.16,1,.3,1);
  --ease-spring: cubic-bezier(.22,1.12,.36,1);
  /* Critically-damped-style deceleration — reaches the target smoothly with
     no overshoot. Reserved for transitions triggered by a single discrete
     action (a click/tap/key press) rather than a live, continuously-tracked
     drag — per this project's Apple Design motion notes, bounce is earned
     by momentum carried over from an actual gesture, not added by default. */
  --ease-fluid: cubic-bezier(.32,.72,0,1);
  /* A smooth, symmetric ease-in-out — gently accelerates, glides, then
     settles — with no overshoot. Used specifically for the project-modal
     carousel's slide transition, where the content change itself needs
     to read as a visible, liquid glide rather than a quick snap (unlike
     --ease-fluid above, which is for fast, discrete micro-interactions:
     a hover, a press, an icon morph). */
  --ease-glide: cubic-bezier(.65,0,.35,1);
  --dur-fast: 150ms;
  --dur: 300ms;
  --dur-slow: 550ms;
  /* Slide-to-slide step duration for the project-modal carousel. Long
     enough that the glide between slides is clearly visible/felt, short
     enough that stepping through several slides in a row doesn't drag. */
  --dur-slide: 520ms;

  color-scheme: light;
}

*,*::before,*::after{ box-sizing: border-box; }
html{
  scroll-behavior: smooth;
  scroll-padding-top: 92px;
  /* Reserve the vertical-scrollbar's width at all times (instead of only
     when a scrollbar is actually showing). Without this, toggling
     `.no-scroll` below (used by the mobile nav drawer and the project
     modal) removes the scrollbar and the page's content area suddenly
     gets wider by the scrollbar's width, forcing a full-page layout
     recalculation at the exact moment the modal/drawer starts to open —
     which painted as a brief white flash/flicker. Reserving the gutter
     up front means opening/closing never changes the content width, so
     there is nothing to reflow and nothing to flicker. */
  scrollbar-gutter: stable;
}
body{
  margin:0;
  font-family: var(--font-body);
  color: var(--gray-text);
  background: var(--white);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}
img{ max-width:100%; display:block; }
a{ color: inherit; text-decoration:none; }
ul{ list-style:none; margin:0; padding:0; }
button{ font-family: inherit; cursor:pointer; }
h1,h2,h3,h4,h5,h6{
  font-family: var(--font-head);
  color: var(--charcoal);
  margin: 0 0 .5em;
  font-weight: 600;
  line-height: 1.15;
}
p{ margin: 0 0 1em; }
.container{
  width: min(92%, var(--container));
  margin-inline: auto;
}
::selection{ background: var(--brand-orange); color:#fff; }

/* Focus visibility — accessibility, never remove outlines silently */
a:focus-visible, button:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible, summary:focus-visible{
  outline: 3px solid var(--brand-orange);
  outline-offset: 2px;
  border-radius: 4px;
}

.skip-link{
  position:absolute; left:1rem; top:-60px;
  background: var(--ink); color:#fff; padding:.75rem 1.25rem;
  border-radius: 6px; z-index: 2000; transition: top var(--dur) var(--ease-out);
  font-weight:600;
}
.skip-link:focus{ top: 1rem; }

/* Visually hidden but still available to assistive tech — used for
   "(opens in a new tab)" context on external links, and reusable
   anywhere text needs to exist for screen readers only. */
.visually-hidden{
  position:absolute !important; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0,0,0,0); white-space:nowrap; border:0;
}

/* ---------- Buttons ---------- */
.btn{
  display:inline-flex; align-items:center; justify-content:center; gap:.5em;
  font: 700 14px/1 var(--font-body);
  letter-spacing:.03em;
  text-transform: uppercase;
  padding: 1.05em 1.9em;
  border-radius: 3px;
  border: 0;
  transition: transform var(--dur-fast) var(--ease-out), box-shadow var(--dur) var(--ease-out), background var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}
.btn:active{ transform: scale(.96); transition-duration: 90ms; }
.btn-gold{ background: var(--brand-gradient); color: var(--ink); box-shadow: var(--shadow-gold); }
.btn-gold:hover{ background: var(--charcoal); color:#fff; box-shadow: var(--shadow-md); }
.btn-outline{ background: transparent; color:#fff; border:2px solid rgba(255,255,255,.75); }
.btn-outline:hover{ background:#fff; color: var(--ink); }
.btn-dark{ background: var(--charcoal); color:#fff; }
.btn-dark:hover{ background: var(--brand-orange); color: var(--charcoal); }

/* ---------- Section titles ---------- */
.eyebrow{
  display:inline-block; font: 700 12px/1 var(--font-body); letter-spacing:.18em;
  text-transform: uppercase; color: var(--brand-amber); background: rgba(var(--brand-orange-rgb),.12);
  padding:.55em 1em; border-radius: 999px; margin-bottom: 1.1em;
}
.section-title{
  font-size: clamp(1.9rem, 3.6vw, 2.7rem);
  text-transform: uppercase;
  letter-spacing: -0.01em;
  position: relative;
  padding-bottom: .55em;
}
.section-title::after{
  content:""; position:absolute; left:0; bottom:0; height:4px; width:64px; background: var(--brand-gradient);
  border-radius: 2px;
}
.section-head{ max-width: 640px; margin-bottom: 3rem; }
.section-head.center{ margin-inline:auto; text-align:center; }
.section-head.center .section-title::after{ left:50%; transform:translateX(-50%); }
.section-head p{ color: var(--gray-text); font-size: 1.02rem; }
.section-pad{ padding: 6.5rem 0; }

/* ============================================================
   HEADER
   ============================================================ */
.site-header{
  position: fixed; inset: 0 0 auto 0; z-index: 1000;
  padding: 20px 0;
  transition: padding var(--dur) var(--ease-out), background var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out), backdrop-filter var(--dur) var(--ease-out);
  background: transparent;
}
.site-header.is-scrolled{
  padding: 10px 0;
  background: rgba(255,255,255,.78);
  backdrop-filter: blur(18px) saturate(180%);
  -webkit-backdrop-filter: blur(18px) saturate(180%);
  box-shadow: 0 1px 0 rgba(20,20,20,.06), 0 12px 30px rgba(20,20,20,.08);
}
/* While the mobile drawer (.mobile-nav, z-index 1100) is open, lift the
   whole header above it — found via testing: #menuToggle lives inside
   .site-header, which has its own stacking context at z-index 1000, so
   giving the button alone a higher z-index could never lift it above a
   1100 sibling; only raising the context-establishing ancestor does.
   This keeps the toggle visible/usable as the morphed "X" close control
   on top of the open drawer, instead of being covered by it. */
.site-header.nav-above-drawer{ z-index: 1150; }
.header-inner{
  width: min(94%, 1320px); margin-inline:auto;
  display:flex; align-items:center; gap: 2rem;
}
.brand{ display:flex; align-items:center; gap:.65rem; margin-right:auto; }
.brand-mark{
  width: 44px; height:44px; flex: none; display:block; object-fit: contain;
  filter: drop-shadow(0 4px 10px rgba(var(--brand-orange-rgb),.35));
}
.brand-text{ display:flex; flex-direction:column; line-height:1.05; }
.brand-text b, .brand-text .brand-name{
  font: 700 19px/1 var(--font-head); letter-spacing:.03em; color: var(--ink);
  text-transform: uppercase;
}
.site-header:not(.is-scrolled) .brand-text .brand-name{ color:#fff; }
.brand-text small{
  font: 500 10px/1 var(--font-body); letter-spacing:.22em; color: var(--brand-amber);
  text-transform: uppercase; margin-top:4px;
}
.nav-desktop ul{ display:flex; gap: 2.1rem; }
.nav-desktop a{
  font: 600 13px/1 var(--font-body); letter-spacing:.05em; text-transform:uppercase;
  color:#fff; position:relative; padding: .4rem 0;
  transition: color var(--dur) var(--ease-out);
}
.site-header.is-scrolled .nav-desktop a{ color: var(--charcoal); }
.nav-desktop a::after{
  content:""; position:absolute; left:0; right:100%; bottom:-2px; height:2px; background: var(--brand-orange);
  transition: right var(--dur) var(--ease-fluid);
}
.nav-desktop a:hover::after, .nav-desktop a:focus-visible::after, .nav-desktop a.active::after{ right:0; }
.header-cta{ flex:none; }
.lang-toggle{
  flex:none; height:38px; padding:0 .85rem; border-radius:999px;
  border:1.5px solid rgba(255,255,255,.35); background: rgba(255,255,255,.08); color:#fff;
  font:700 12px/1 var(--font-body); letter-spacing:.06em; cursor:pointer;
  transition: background var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.site-header.is-scrolled .lang-toggle{ border-color: rgba(20,20,20,.25); color: var(--charcoal); background: rgba(20,20,20,.04); }
.lang-toggle:hover, .lang-toggle:focus-visible{ background: var(--brand-orange); border-color: var(--brand-orange); color:#fff; }
.lang-toggle:active{ transform: scale(.92); transition-duration: 90ms; }
.menu-toggle{
  display:none; flex:none; width:44px; height:44px; border-radius:8px; border:0;
  background: rgba(255,255,255,.14); position:relative;
  transition: transform var(--dur-fast) var(--ease-out), background var(--dur) var(--ease-out);
}
.site-header.is-scrolled .menu-toggle{ background: rgba(20,20,20,.06); }
.menu-toggle:active{ transform: scale(.92); transition-duration: 90ms; }
.menu-toggle span{
  position:absolute; left:11px; right:11px; height:2px; background:#fff; border-radius:2px;
  transition: transform var(--dur) var(--ease-fluid), opacity var(--dur-fast) linear, background var(--dur) var(--ease-out);
}
.site-header.is-scrolled .menu-toggle span{ background: var(--ink); }
.menu-toggle span:nth-child(1){ top:14px; }
.menu-toggle span:nth-child(2){ top:21px; }
.menu-toggle span:nth-child(3){ top:28px; }
.menu-toggle[aria-expanded="true"] span:nth-child(1){ transform: translateY(7px) rotate(45deg); }
.menu-toggle[aria-expanded="true"] span:nth-child(2){ opacity:0; }
.menu-toggle[aria-expanded="true"] span:nth-child(3){ transform: translateY(-7px) rotate(-45deg); }

/* Mobile nav — enters/exits from the right, matching the trigger side (spatial consistency) */
.mobile-nav-scrim{
  position:fixed; inset:0; background: rgba(10,10,10,.55); z-index: 1090;
  opacity:0; pointer-events:none; transition: opacity var(--dur) var(--ease-out);
}
.mobile-nav-scrim.is-open{ opacity:1; pointer-events:auto; }
.mobile-nav{
  position:fixed; top:0; right:0; bottom:0; width:min(86%, 360px); z-index: 1100;
  background: var(--ink); color:#fff; padding: 6.5rem 2rem 2rem;
  transform: translateX(100%);
  transition: transform var(--dur-slow) var(--ease-spring);
  display:flex; flex-direction:column;
  box-shadow: -18px 0 40px rgba(0,0,0,.25);
}
.mobile-nav.is-open{ transform: translateX(0); }
.mobile-nav ul{ display:flex; flex-direction:column; gap:.3rem; }
.mobile-nav a{
  display:block; padding: .95rem .25rem; font: 600 16px/1 var(--font-head);
  letter-spacing:.03em; text-transform:uppercase; border-bottom:1px solid rgba(255,255,255,.08);
  color:#fff;
}
.mobile-nav a:hover, .mobile-nav a:focus-visible{ color: var(--brand-orange); }
.mobile-nav .btn{ margin-top: 1.6rem; }
.mobile-nav-social{ margin-top:auto; display:flex; gap:.7rem; padding-top:2rem; }
.mobile-nav-social a{
  width:38px; height:38px; border:2px solid rgba(255,255,255,.25); border-radius:50%;
  display:flex; align-items:center; justify-content:center;
  transition: background var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.mobile-nav-social a:hover{ background: var(--brand-orange); border-color: var(--brand-orange); color: var(--ink); }
.mobile-nav-social a:active{ transform: scale(.9); transition-duration: 90ms; }
.mobile-nav-social svg{ width:16px; height:16px; fill:currentColor; }

@media (max-width: 900px){
  .nav-desktop, .header-cta{ display:none; }
  .menu-toggle{ display:block; }
}

/* Small phones (iPhone SE/mini-width devices down to 320px). Found via a
   responsiveness audit: .header-inner's 2rem gap plus the brand's full
   "Sensum Construcciones" wordmark don't fit next to the language toggle
   and the hamburger button in the ~300px of header width left on a 320px
   screen — the menu button was being pushed off the right edge of the
   viewport entirely. Tightening the gap and the two toggle buttons' own
   padding (never their tap-target size, which stays at the 44px already
   used site-wide) closes that gap without touching the brand mark itself. */
@media (max-width: 400px){
  .header-inner{ gap:.5rem; }
  .lang-toggle{ padding:0 .6rem; }
  .brand-text small{ letter-spacing:.14em; }
}

/* ============================================================
   HERO
   ============================================================ */
.hero{
  position:relative; overflow:hidden; isolation:isolate;
  min-height: 100svh; display:flex; align-items:center;
  background: radial-gradient(120% 90% at 82% 12%, var(--ink-soft) 0%, var(--ink) 46%, #141414 100%);
  padding-top: 120px; padding-bottom:80px;
  color:#fff;
}
.hero-grid{
  position:absolute; inset:0; z-index:0; opacity:.14;
  background-image:
    linear-gradient(rgba(255,255,255,.6) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.6) 1px, transparent 1px);
  background-size: 46px 46px;
  animation: gridDrift 40s linear infinite;
}
@keyframes gridDrift{ from{ background-position: 0 0; } to{ background-position: 460px 460px; } }
.hero-glow{
  position:absolute; z-index:0; border-radius:50%; filter: blur(60px);
  background: radial-gradient(circle, rgba(var(--brand-orange-rgb),.55), transparent 70%);
  width: 640px; height:640px; right:-160px; top:-160px; opacity:.55;
  animation: floaty 16s ease-in-out infinite;
}
.hero-glow.two{
  background: radial-gradient(circle, rgba(255,255,255,.18), transparent 70%);
  width:420px; height:420px; left:-120px; bottom:-140px; right:auto; top:auto; animation-duration: 22s; animation-delay: -6s;
}
@keyframes floaty{ 0%,100%{ transform: translate(0,0); } 50%{ transform: translate(-24px, 26px); } }
.hero-inner{ position:relative; z-index:1; display:grid; grid-template-columns: 1.15fr .85fr; gap: 3rem; align-items:center; }
.hero-copy .eyebrow{ background: rgba(var(--brand-orange-rgb),.16); color: var(--brand-amber); }
.hero-copy h1{
  color:#fff; font-size: clamp(2.4rem, 5.6vw, 4.1rem); letter-spacing: -0.02em; line-height:1.04;
  text-transform: uppercase; margin-bottom:.5em;
}
.hero-copy h1 em{ font-style:normal; color: var(--brand-orange); }
.hero-copy p{ color: rgba(255,255,255,.78); font-size: 1.12rem; max-width: 540px; }
.hero-actions{ display:flex; flex-wrap:wrap; gap:1rem; margin-top: 1.6rem; }
.hero-badges{ display:flex; gap:1.6rem; flex-wrap:wrap; margin-top: 3rem; }
.hero-badge{ display:flex; align-items:center; gap:.7rem; color: rgba(255,255,255,.85); font-size:.85rem; }
.hero-badge svg{ width:22px; height:22px; flex:none; color: var(--brand-orange); }

/* Hero panel — floating "material" panel. Shows the four working
   principles from the hero copy (planning / precision / clear
   communication / technical support) rather than unverified numeric
   stats — see CONTENT-APPROVAL.md for why the old stat counters were
   removed. */
.hero-panel{
  position:relative; background: rgba(255,255,255,.06);
  border: 1px solid rgba(255,255,255,.14);
  backdrop-filter: blur(16px);
  border-radius: 18px; padding: 2rem;
  display:grid; grid-template-columns: 1fr 1fr; gap: 1.6rem;
}
.hero-pillar{ text-align:left; }
.hero-pillar svg{
  width:28px; height:28px; color: var(--brand-orange); margin-bottom:.7rem;
}
.hero-pillar .label{ font: 600 .95rem/1.25 var(--font-head); letter-spacing:.01em; text-transform:uppercase; color:#fff; }

@media (max-width: 980px){
  .hero-inner{ grid-template-columns: 1fr; }
  .hero-panel{ grid-template-columns: repeat(4,1fr); }
}
@media (max-width: 620px){
  .hero-panel{ grid-template-columns: repeat(2,1fr); }
  /* Found via a responsiveness audit: on common phone sizes (iPhone
     12/13/14 at 390x844, iPhone 11/XR at 414x896, and others) the
     heading wraps to enough lines that the hero's last row — the
     "Comunicación clara / Supervisión técnica / Presupuestos
     detallados" badges — landed right behind the fixed WhatsApp
     button, hiding part of a badge's text behind it. The hero's
     content here is taller than the viewport (min-height:100svh is a
     floor, not a cap), so there's no centering slack to redistribute —
     the only way to pull the badges clear is to trim the space above
     them. Tightening the top padding and the badges' own top margin
     does that without touching their spacing from each other. */
  .hero{ padding-top: 96px; }
  .hero-badges{ margin-top: 1.75rem; }
}

/* ============================================================
   REVEAL ON SCROLL (respects prefers-reduced-motion)
   ============================================================ */
.reveal{
  opacity:0; transform: translateY(28px);
  transition: opacity var(--dur-slow) var(--ease-out), transform var(--dur-slow) var(--ease-out);
}
.reveal.in-view{ opacity:1; transform: translateY(0); }
.reveal-group > *{ transition-delay: calc(var(--i, 0) * 80ms); }
/* Stagger-index utility classes — set the --i custom property from a
   stylesheet rule instead of an inline style="--i:N" attribute, so the
   site's CSP can stay free of style-src 'unsafe-inline'. */
.i0{ --i:0; } .i1{ --i:1; } .i2{ --i:2; } .i3{ --i:3; } .i4{ --i:4; } .i5{ --i:5; }

@media (prefers-reduced-motion: reduce){
  html{ scroll-behavior:auto; }
  .reveal{ transform:none; transition: opacity 220ms ease; }
  .hero-grid, .hero-glow{ animation:none; }
  *{ animation-duration: 0.001ms !important; animation-iteration-count:1 !important; transition-duration: 120ms !important; }
}

/* ============================================================
   WHY US / DIFFERENTIATORS (used in About)
   ============================================================ */
.about{ background: var(--bg-lighter); }
.about-grid{ display:grid; grid-template-columns: .95fr 1.05fr; gap: 4rem; align-items:start; }
.about-art{
  position:relative; border-radius: 18px; overflow:hidden; min-height: 420px;
  background:
    linear-gradient(160deg, var(--ink) 0%, var(--charcoal-2) 100%);
  display:flex; align-items:flex-end; padding: 2.2rem;
}
.about-art::before{
  content:""; position:absolute; inset:0;
  background-image: linear-gradient(rgba(255,255,255,.08) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.08) 1px, transparent 1px);
  background-size: 34px 34px; opacity:.6;
}
.about-art .blueprint-icon{ position:relative; width:120px; height:120px; color: var(--brand-orange); opacity:.9; }
.about-art-caption{ position:relative; color:#fff; }
.about-art-caption p{ color: rgba(255,255,255,.85); margin:0; max-width:280px; font: 600 1.05rem/1.4 var(--font-head); text-transform:none; letter-spacing:0; }
/* Optional About photo, published from the Content Manager. These rules
   only apply once a photo exists (.about-art.has-photo); without one the
   blueprint illustration above is unchanged. The box keeps its approved
   size and the photo is cropped to fill it, with the same dark bottom
   gradient the project cards use so the caption stays legible. */
.about-art .about-photo{ position:absolute; inset:0; width:100%; height:100%; object-fit:cover; display:block; }
.about-art.has-photo::before{ display:none; }
.about-art.has-photo::after{ content:""; position:absolute; inset:0; background: linear-gradient(0deg, rgba(10,10,10,.85) 0%, rgba(10,10,10,.1) 55%); }
.about-art.has-photo .about-art-caption{ z-index:1; }

.mission-vision{ display:grid; gap:1.4rem; margin: 2rem 0 2.4rem; }
.mv-card{
  background: var(--white); border:1px solid var(--border); border-radius: var(--radius);
  padding: 1.5rem 1.7rem; transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out);
}
.mv-card:hover{ transform: translateY(-4px); box-shadow: var(--shadow-sm); border-color: rgba(var(--brand-orange-rgb),.5); }
.mv-card h3{ font-size:1.05rem; display:flex; align-items:center; gap:.6rem; }
.mv-card h3 svg{ width:20px; height:20px; color: var(--brand-amber); flex:none; }
.mv-card p{ margin:.6rem 0 0; font-size:.95rem; }

@media (max-width: 900px){
  .about-grid{ grid-template-columns:1fr; }
}

/* ============================================================
   SERVICES
   ============================================================ */
.services{ background: var(--bg-light); }
.services-grid{ display:grid; grid-template-columns: repeat(3, 1fr); gap: 1.6rem; }
.service-card{
  background: var(--white); border-radius: var(--radius); padding: 2.1rem 1.8rem;
  position:relative; overflow:hidden; border:1px solid var(--border);
  transition: transform var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.service-card:hover{ transform: translateY(-8px); box-shadow: var(--shadow-md); }
.service-card::before{
  content:""; position:absolute; left:0; top:0; height:4px; width:100%;
  background: var(--brand-gradient);
  transform: scaleX(0); transform-origin: 0 50%;
  transition: transform var(--dur) var(--ease-fluid);
}
.service-card:hover::before{ transform: scaleX(1); }
.service-card .icon{
  width:58px; height:58px; border-radius:14px; background: rgba(20,20,20,.06);
  display:flex; align-items:center; justify-content:center; margin-bottom:1.3rem;
  transition: background var(--dur) var(--ease-out), transform var(--dur) var(--ease-fluid);
}
.service-card:hover .icon{ background: rgba(var(--brand-orange-rgb),.14); transform: translateY(-3px); }
.service-card .icon svg{ width:28px; height:28px; color: var(--ink); transition: color var(--dur) var(--ease-out); }
.service-card:hover .icon svg{ color: var(--brand-orange); }
.service-card h3{ font-size:1.15rem; text-transform:uppercase; margin-bottom:.6rem; }
.service-card p{ font-size:.94rem; margin-bottom:1.1rem; }
.service-card .learn{
  font: 700 12px/1 var(--font-body); letter-spacing:.05em; text-transform:uppercase;
  color: var(--ink); display:inline-flex; align-items:center; gap:.4rem;
}
.service-card .learn svg{ width:14px; height:14px; transition: transform var(--dur) var(--ease-fluid); }
.service-card:hover .learn svg{ transform: translateX(5px); }

@media (max-width: 980px){ .services-grid{ grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px){ .services-grid{ grid-template-columns: 1fr; } }

/* ============================================================
   PROCESS STRIP
   ============================================================ */
.process{ background: var(--white); }
.process-list{ display:grid; grid-template-columns: repeat(4,1fr); gap: 1.6rem; counter-reset: step; }
.process-item{ position:relative; padding-top: 2.6rem; }
.process-item::before{
  counter-increment: step; content: counter(step, decimal-leading-zero);
  font: 700 1.1rem/1 var(--font-head); color: var(--brand-orange); position:absolute; top:0; left:0;
  border-bottom: 3px solid var(--brand-orange); padding-bottom:.6rem;
}
.process-item h3{ font-size:1rem; text-transform:uppercase; margin-bottom:.4rem; }
.process-item p{ font-size:.9rem; margin:0; }
@media (max-width: 900px){ .process-list{ grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px){ .process-list{ grid-template-columns: 1fr; } }

/* ============================================================
   PROJECTS
   ============================================================ */
.projects{ background: var(--bg-light); }
.project-grid{ display:grid; grid-template-columns: repeat(3,1fr); gap: 1.6rem; }
.project-card{
  position:relative; border-radius: var(--radius); overflow:hidden; aspect-ratio: 4/3;
  color:#fff; display:flex; flex-direction:column; justify-content:flex-end; padding: 1.6rem;
  isolation:isolate; cursor:pointer;
}
.project-card::before{
  content:""; position:absolute; inset:0; z-index:-2;
  background: linear-gradient(150deg, var(--pc-a, #262626), var(--pc-b, #333333));
  transition: transform var(--dur-slow) var(--ease-out);
}
/* Per-card gradient-pair utility classes (replaces inline
   style="--pc-a:...; --pc-b:..." so the CSP can stay free of
   style-src 'unsafe-inline'). */
.pc-0{ --pc-a:#262626; --pc-b:#333333; }
.pc-1{ --pc-a:#333333; --pc-b:#1c1c1c; }
.pc-2{ --pc-a:#1c1c1c; --pc-b:#262626; }
.pc-3{ --pc-a:#333333; --pc-b:#262626; }
.pc-4{ --pc-a:#262626; --pc-b:#1c1c1c; }
.pc-5{ --pc-a:#1c1c1c; --pc-b:#333333; }
.project-card::after{
  content:""; position:absolute; inset:0; z-index:-1;
  background: linear-gradient(0deg, rgba(10,10,10,.9) 0%, rgba(10,10,10,.15) 60%);
}
.project-card:hover::before{ transform: scale(1.08); }
.project-card .tag{
  align-self:flex-start; font:700 10px/1 var(--font-body); letter-spacing:.08em; text-transform:uppercase;
  background: var(--brand-orange); color: var(--charcoal); padding:.45em .8em; border-radius:999px; margin-bottom:.8rem;
}
.project-card h3{ color:#fff; font-size:1.2rem; margin-bottom:.2rem; text-transform:uppercase; }
.project-card p{ color: rgba(255,255,255,.75); font-size:.86rem; margin:0; }
.project-card .illus{
  position:absolute; inset:0; z-index:-1; display:flex; align-items:center; justify-content:center;
  padding: 1.4rem 1.4rem 4.6rem; pointer-events:none; opacity:.6;
  transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur-slow) var(--ease-out);
}
.project-card .illus svg{ width:100%; height:100%; max-width:132px; max-height:132px; color: var(--brand-amber); overflow:visible; }
.project-card:hover .illus{ transform: scale(1.06); opacity:.8; }
@media (max-width: 620px){ .project-card .illus{ padding-bottom: 4rem; } .project-card .illus svg{ max-width:104px; max-height:104px; } }
/* Real project-card photo, swapped in for .illus once a real photo
   exists for that project (see the "case-study-card" comment above
   each card in index.html). Same position/stacking as .illus — fills
   the card behind the ::after dark gradient that keeps the title and
   tag legible — but at full opacity, since a real photo doesn't need
   the muted icon treatment. object-fit:cover crops any photo to the
   card's own box cleanly, so submitted photos don't need to be
   pre-cropped to an exact ratio. */
.project-card .case-photo{
  position:absolute; inset:0; z-index:-1; width:100%; height:100%; object-fit:cover; display:block;
  transition: transform var(--dur-slow) var(--ease-out);
}
.project-card:hover .case-photo{ transform: scale(1.06); }

@media (max-width: 980px){ .project-grid{ grid-template-columns: 1fr 1fr; } }
@media (max-width: 620px){ .project-grid{ grid-template-columns: 1fr; } }

.projects-cta{ text-align:center; margin-top: 3rem; }

/* ============================================================
   CTA BANNER
   ============================================================ */
.cta-banner{
  background: var(--brand-gradient);
  text-align:center;
}
.cta-banner h2{ font-size: clamp(1.8rem,4vw,2.6rem); text-transform:uppercase; color: var(--charcoal); }
.cta-banner p{ color: rgba(34,34,34,.75); max-width: 560px; margin-inline:auto; font-size:1.05rem; }
.cta-banner .btn-dark{ margin-top:.6rem; }

/* ============================================================
   CONTACT
   ============================================================ */
.contact{ background: var(--white); }
.contact-grid{ display:grid; grid-template-columns: 1fr 1.1fr; gap: 3.5rem; }
.contact-info h2{ font-size:1.5rem; text-transform:uppercase; }
.contact-list{ margin-top:1.6rem; display:grid; gap:1.1rem; }
/* min-width:0 lets this flex row actually shrink below its text's
   natural size — flex items default to min-width:auto, which (found via
   a responsiveness audit) was letting the unbroken email address below
   force the row, the list, and the whole contact section wider than a
   320px screen, pushing the entire page into horizontal overflow. */
.contact-list li{ display:flex; gap:1rem; align-items:flex-start; min-width:0; }
.contact-list .icn{
  width:44px; height:44px; border-radius:10px; background: var(--bg-light); flex:none;
  display:flex; align-items:center; justify-content:center;
}
.contact-list .icn svg{ width:20px; height:20px; color: var(--brand-amber); }
/* overflow-wrap lets a long unbroken token (the email address has no
   spaces to break on) wrap onto a second line on narrow screens instead
   of forcing the row wider than the viewport. min-width:0 is needed in
   addition to the min-width:0 on the <li> above: this span is itself a
   flex child of the <li> and defaults to min-width:auto same as any
   other flex item, which was still blocking the wrap above without it. */
.contact-list a, .contact-list span{ font-size:.95rem; color: var(--gray-text); overflow-wrap: break-word; min-width:0; }
.contact-list strong{ display:block; color: var(--charcoal); font-size:.82rem; text-transform:uppercase; letter-spacing:.04em; margin-bottom:.15rem; }
.contact-map{ margin-top: 2.2rem; border-radius: var(--radius); overflow:hidden; border:1px solid var(--border); aspect-ratio: 16/10; }
.contact-map iframe{ width:100%; height:100%; border:0; }
/* Static locator card — used as a dependency-free stand-in for a live map
   embed (third-party map iframes can be blocked by a host's CSP/sandbox).
   Links straight out to Google Maps, so it always "works" everywhere. */
.map-card{
  position:relative; width:100%; height:100%; overflow:hidden; isolation:isolate;
  display:flex; flex-direction:column; align-items:center; justify-content:center;
  text-align:center; gap:.9rem; padding:2rem;
  background: linear-gradient(160deg, var(--ink) 0%, #0f0f0f 100%);
  color:#fff;
}
.map-card .hero-grid{ opacity:.16; }
.map-card .pin{
  position:relative; width:60px; height:60px; border-radius:50% 50% 50% 0;
  background: var(--brand-gradient); transform: rotate(-45deg);
  display:flex; align-items:center; justify-content:center;
  box-shadow: 0 10px 26px rgba(var(--brand-orange-rgb),.4);
}
.map-card .pin svg{ width:22px; height:22px; transform: rotate(45deg); color:#fff; }
.map-card .pin::after{
  content:""; position:absolute; top:50%; left:50%; width:110px; height:110px; border-radius:50%;
  border:1px solid rgba(var(--brand-orange-rgb),.35); transform: translate(-50%,-50%) rotate(45deg);
}
.map-card h3{ color:#fff; font-size:1.05rem; text-transform:uppercase; margin:0; }
.map-card p{ color: rgba(255,255,255,.68); font-size:.88rem; max-width:320px; margin:0; }
.map-card .btn{ margin-top:.3rem; }

.contact-form{ background: var(--bg-light); border-radius: 14px; padding: 2.2rem; }
.contact-form .form-title{ font-size:1.3rem; text-transform:uppercase; }
.btn-block{ width:100%; }
.form-row{ display:grid; grid-template-columns: 1fr 1fr; gap: 1rem; }
.field{ margin-bottom: 1rem; }
.field label{ display:block; font-size:.78rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color: var(--charcoal); margin-bottom:.4rem; }
.field input, .field select, .field textarea{
  width:100%; border:1px solid var(--border); border-radius:8px; padding:.85em 1em;
  font: 400 14px/1.4 var(--font-body); color: var(--charcoal); background:#fff;
  transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.field textarea{ resize:vertical; min-height:110px; }
.field input:focus, .field select:focus, .field textarea:focus{
  border-color: var(--brand-orange); box-shadow: 0 0 0 4px rgba(var(--brand-orange-rgb),.18); outline:none;
}
/* Error indication never relies on color alone: an icon + text message
   appears next to the field, the field also gets a visibly thicker/darker
   border, and aria-invalid + aria-describedby (set in assets/main.js)
   connect the two for assistive tech. */
.field small.err{ display:none; align-items:flex-start; gap:.35rem; color:#b3261e; font-size:.78rem; margin-top:.35rem; line-height:1.35; }
.field.invalid input, .field.invalid select, .field.invalid textarea{ border-color:#b3261e; border-width:2px; }
.field.invalid small.err{ display:flex; }
.err-icon{ width:15px; height:15px; flex:none; margin-top:1px; color:#b3261e; }
/* Questions added in the Content Manager (Sitio web → Formulario de contacto):
   "(opcional)", help text, and choices (one or several). */
.field .field-opt{ font-weight:400; text-transform:none; letter-spacing:0; color: var(--gray-text); }
.field .field-help{ display:block; margin:-.15rem 0 .45rem; font-size:.78rem; line-height:1.4; color: var(--gray-text); }
.field .field-help:empty{ margin:0; }
.field fieldset{ border:0; margin:0; padding:0; min-width:0; }
.field legend{ display:block; padding:0; font-size:.78rem; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color: var(--charcoal); margin-bottom:.4rem; }
.choices{ display:grid; gap:.5rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr)); }
.field label.choice{ display:flex; align-items:center; gap:.6rem; min-height:46px; margin:0; padding:.6rem .9rem; border:1px solid var(--border); border-radius:8px; background:#fff; font:400 14px/1.35 var(--font-body); text-transform:none; letter-spacing:0; color: var(--charcoal); cursor:pointer; transition: border-color var(--dur) var(--ease-out), background-color var(--dur) var(--ease-out); }
.field .choice input{ width:18px; height:18px; margin:0; padding:0; flex:none; accent-color: var(--brand-orange); }
.field .choice:has(input:checked){ border-color: var(--brand-orange); background:#fff7f0; }
.field .choice:has(input:focus-visible){ outline:3px solid rgba(var(--brand-orange-rgb),.45); outline-offset:2px; }
.field.invalid .choice{ border-color:#b3261e; }
/* honeypot — hidden from humans, visible to naive bots */
.hp-field{ position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden; }
.form-note{ font-size:.8rem; color: var(--gray-mid); margin-top:.9rem; }
.form-note a{ color: var(--gray-text-2); text-decoration:underline; }
.form-fallback{ font-size:.85rem; color: var(--gray-text); margin-top:.6rem; }
.form-fallback a{ color: var(--brand-orange); font-weight:600; }
/* Captcha note (anti-spam check runs in the background — assets/main.js) */
.form-captcha{ display:flex; align-items:center; gap:.4rem; font-size:.8rem; color: var(--gray-mid); margin-top:.7rem; }
.form-captcha-icon{ width:14px; height:14px; flex:none; }
.form-captcha[data-state="ok"]{ color:#1e7e34; }
.form-captcha[data-state="error"]{ color:#b3261e; }
.form-turnstile:not(:empty){ margin:.2rem 0 .9rem; }
.form-status{ margin-top:1rem; font-size:.9rem; font-weight:600; display:none; }
.form-status.show{ display:block; }
.form-status.ok{ color:#1e7e34; }
.form-status.error{ color:#b3261e; }
.form-summary{
  background:#fdecea; border:1px solid #b3261e; color:#7a1c15; border-radius:8px;
  padding:.85rem 1rem; margin-bottom:1.1rem; font-size:.88rem; font-weight:600;
}
.form-summary[hidden]{ display:none; }

@media (max-width: 980px){ .contact-grid{ grid-template-columns:1fr; } }
@media (max-width: 560px){ .form-row{ grid-template-columns:1fr; } }
/* Side by side, the two questions share rows (label · help · field · error) so the boxes line up. */
@media (min-width: 561px){
  .form-row{ grid-template-rows:repeat(4, auto); row-gap:0; }
  .form-row > .field{ display:grid; grid-row:span 4; grid-template-rows:subgrid; align-content:start; }
}

/* ============================================================
   FAQ — native <details>/<summary>: keyboard- and screen-reader-
   accessible with zero JavaScript, and still fully usable if
   scripts fail to load.
   ============================================================ */
.faq{ background: var(--bg-light); }
.faq-list{ max-width: 780px; margin-inline:auto; display:grid; gap:.9rem; }
.faq-item{
  background: var(--white); border:1px solid var(--border); border-radius: var(--radius);
  padding: .3rem 1.5rem; transition: border-color var(--dur) var(--ease-out), box-shadow var(--dur) var(--ease-out);
}
.faq-item[open]{ border-color: rgba(var(--brand-orange-rgb),.5); box-shadow: var(--shadow-sm); }
.faq-item summary{
  list-style:none; cursor:pointer; padding: 1.15rem 2rem 1.15rem 0; position:relative;
  font: 600 1rem/1.4 var(--font-head); color: var(--charcoal); text-transform:uppercase; letter-spacing:.01em;
}
.faq-item summary::-webkit-details-marker{ display:none; }
.faq-item summary::after{
  content:""; position:absolute; right:.1rem; top:50%; width:12px; height:12px;
  border-right:2px solid var(--brand-orange); border-bottom:2px solid var(--brand-orange);
  transform: translateY(-65%) rotate(45deg); transition: transform var(--dur) var(--ease-out);
}
.faq-item[open] summary::after{ transform: translateY(-35%) rotate(-135deg); }
.faq-item p{ margin: 0 0 1.3rem; font-size:.94rem; color: var(--gray-text); max-width: 66ch; }
@media (prefers-reduced-motion: reduce){
  .faq-item summary::after{ transition:none; }
}

/* ============================================================
   FOOTER
   ============================================================ */
.site-footer{
  background: linear-gradient(180deg, var(--ink) 0%, #121212 100%);
  color: rgba(255,255,255,.8); position:relative;
}
.footer-grid{
  /* minmax(0, 1fr) — not bare 1fr — so a track can shrink below its
     content's min-content width (e.g. the long email address in the
     Contacto column) instead of stealing space from the other columns. */
  display:grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2.6rem;
  padding: 5rem 0 3rem;
}
.footer-brand{ display:flex; align-items:center; gap:.65rem; margin-bottom:1.2rem; }
.footer-brand .brand-name{ color:#fff; }
.footer-about p{ font-size:.92rem; color: rgba(255,255,255,.65); }
.footer-social{ margin-top:1.2rem; }
.footer-social a{
  display:inline-flex; align-items:center; gap:.55rem; padding:.6em 1.15em .6em .8em;
  border:2px solid var(--brand-orange); border-radius:999px; position:relative; overflow:hidden; z-index:1;
  color:#fff; font:700 .78rem/1 var(--font-body); letter-spacing:.04em; text-transform:uppercase;
  transition: color var(--dur) var(--ease-out), transform var(--dur) var(--ease-out);
}
.footer-social a::after{
  content:""; position:absolute; inset:0; background: var(--brand-orange); z-index:-1;
  transform: scaleX(0); transform-origin:0 50%; transition: transform var(--dur) var(--ease-out);
}
.footer-social a:hover::after{ transform: scaleX(1); }
.footer-social a:hover{ color: var(--ink); transform: translateY(-2px); }
.footer-social svg{ width:18px; height:18px; fill:currentColor; flex:none; }
.footer h4{ color:#fff; font-size:.95rem; text-transform:uppercase; letter-spacing:.04em; margin-bottom:1.3rem; }
.footer-links li{ margin-bottom:.75rem; }
.footer-links a{ font-size:.9rem; color: rgba(255,255,255,.68); display:flex; align-items:center; gap:.5rem; transition: color var(--dur) var(--ease-out), gap var(--dur) var(--ease-out); }
.footer-links a svg{ width:12px; height:12px; color: var(--brand-orange); flex:none; }
.footer-links a:hover{ color: var(--brand-orange); gap:.75rem; }
.footer-contact li{ display:flex; gap:.6rem; margin-bottom:.9rem; font-size:.88rem; min-width:0; }
.footer-contact svg{ width:16px; height:16px; color: var(--brand-orange); flex:none; margin-top:.15rem; }
.footer-contact a{ color: rgba(255,255,255,.75); overflow-wrap: anywhere; }
.footer-contact a:hover{ color: var(--brand-orange); }
.footer-bottom{
  border-top: 1px solid rgba(255,255,255,.08); padding: 1.6rem 0; text-align:center;
  background: var(--footer-black);
}
.footer-bottom p{ margin:0; font-size:.82rem; color: rgba(255,255,255,.55); }
.footer-bottom a{ color: var(--brand-orange); font-weight:700; }

@media (max-width: 980px){ .footer-grid{ grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px){ .footer-grid{ grid-template-columns: 1fr; } }

/* ============================================================
   BACK TO TOP
   ============================================================ */
.back-to-top{
  position:fixed; right:1.4rem; bottom:1.4rem; z-index: 900;
  width:48px; height:48px; border-radius:50%; background: var(--ink); color:#fff; border:0;
  display:flex; align-items:center; justify-content:center; box-shadow: var(--shadow-md);
  opacity:0; transform: translateY(12px) scale(.9); pointer-events:none;
  transition: opacity var(--dur) var(--ease-out), transform var(--dur) var(--ease-fluid), background var(--dur) var(--ease-out);
}
.back-to-top.show{ opacity:1; transform: translateY(0) scale(1); pointer-events:auto; }
.back-to-top:hover{ background: var(--brand-orange); color: var(--charcoal); }
.back-to-top:active{ transform: translateY(0) scale(.9); transition-duration: 90ms; }
.back-to-top svg{ width:20px; height:20px; }

/* ============================================================
   WHATSAPP FLOATING BUTTON
   ============================================================ */
.whatsapp-fab{
  position:fixed; left:1.4rem; bottom:1.4rem; z-index: 900;
  width:56px; height:56px; border-radius:50%; background:#25D366; color:#fff;
  display:flex; align-items:center; justify-content:center; box-shadow: 0 10px 26px rgba(37,211,102,.45);
  transition: transform var(--dur) var(--ease-fluid), box-shadow var(--dur) var(--ease-out);
}
.whatsapp-fab:hover, .whatsapp-fab:focus-visible{ transform: translateY(-3px) scale(1.05); box-shadow: 0 14px 32px rgba(37,211,102,.55); }
.whatsapp-fab:active{ transform: translateY(-3px) scale(.98); transition-duration: 90ms; }
.whatsapp-fab svg{ width:28px; height:28px; }
.whatsapp-fab::before{
  content:""; position:absolute; inset:0; border-radius:50%; background:#25D366;
  animation: wa-pulse 2.4s ease-out infinite; z-index:-1;
}
@keyframes wa-pulse{
  0%{ transform:scale(1); opacity:.55; }
  100%{ transform:scale(1.7); opacity:0; }
}
@media (max-width: 560px){
  .whatsapp-fab{ width:50px; height:50px; left:1rem; bottom:1rem; }
  .whatsapp-fab svg{ width:25px; height:25px; }
  .back-to-top{ right:1rem; bottom:1rem; }
  /* Keep the fixed WhatsApp/back-to-top buttons from covering the
     copyright line on narrow screens, where it wraps to two lines. */
  .footer-bottom{ padding-bottom: 4.5rem; }
  /* Same fix, applied to the hero badges. Trimming the space above them
     (see the .hero/.hero-badges rule in the 620px breakpoint) shrinks
     how often they land behind the fixed WhatsApp button, but can't
     guarantee it — the badges can wrap onto 2–3 lines, taller than the
     button itself, so no amount of vertical shifting clears every
     combination of viewport height and heading line-wrap. Reserving
     the button's own footprint (its 50px width + 1rem offset, plus a
     little breathing room) as left padding on the badges row instead
     removes the horizontal overlap outright, which is reliable
     regardless of how tall the row ends up being. */
  .hero-badges{ padding-left: 74px; }
}

/* Reduced transparency: make translucent chrome solid */
@media (prefers-reduced-transparency: reduce){
  .site-header.is-scrolled{ background: #fff; backdrop-filter:none; }
  .hero-panel{ background: rgba(20,20,20,.85); backdrop-filter:none; }
}
@media (prefers-contrast: more){
  .btn-gold{ outline: 2px solid var(--charcoal); }
  .service-card, .mv-card{ border-width:2px; border-color: var(--charcoal); }
}

/* No-JS contact form fallback response page (assets/contact-handler.php) */
.contact-fallback-page{ max-width:32rem; text-align:center; padding-top:6rem; }

/* ============================================================
   SECONDARY PAGES (privacy-notice.html, and reusable elsewhere) —
   a simple in-flow header instead of the homepage's fixed/floating
   one, plus a dark-outline button variant for use on a light header.
   ============================================================ */
.static-page-header{ position:static; padding:1.4rem 0; }
.static-page-header .btn{ margin-left:auto; }
.btn-outline-dark{ border-color: var(--charcoal); color: var(--charcoal); }
.btn-outline-dark:hover{ background: var(--charcoal); color:#fff; }

/* ============================================================
   LEGAL PAGES (privacy-notice.html)
   ============================================================ */
.legal-page{ padding-top: 8rem; }
.legal-page .container{ max-width: 820px; }
.legal-page .section-title{ margin-bottom: 1.4rem; }
.legal-page h2{ font-size:1.15rem; text-transform:uppercase; margin-top:2.2rem; }
.legal-page p{ font-size:.98rem; }
.legal-page a{ color: var(--brand-orange); font-weight:600; }
.legal-placeholder{
  background:#fff7e8; border:1px solid rgba(var(--brand-orange-rgb),.4); border-radius:8px;
  padding:.9rem 1.1rem; font-size:.9rem; color: var(--gray-text-2);
}
.legal-updated{ margin-top:2.4rem; padding-top:1.4rem; border-top:1px solid var(--border); font-size:.88rem; color: var(--gray-text); }
.legal-page h3{ font-size:1rem; margin:1.4rem 0 .5rem; }
.legal-page ul{ list-style:disc; margin:.4rem 0 1rem; padding-left:1.25rem; }
.legal-page li::marker{ color: var(--brand-orange); }
.legal-page li{ font-size:.98rem; line-height:1.65; margin:.4rem 0; }
.legal-page .legal-lead{ font-size:1.05rem; }
.legal-summary{ margin:1.6rem 0 .6rem; padding:1.1rem 1.3rem; border-radius:12px; background:#fff7f0; border:1px solid rgba(var(--brand-orange-rgb),.28); }
.legal-summary h2{ margin-top:0; font-size:1rem; }
.legal-summary ul{ margin-bottom:0; }


/* ============================================================
   PROJECT DETAIL MODAL — opened from a "Tipos de proyectos" card.
   Mirrors the mobile nav's scrim/transform/is-open pattern. The
   slideshow is a 3-position carousel driven purely by class toggles
   (.is-active/.is-prev/.is-next) — never inline styles — so it stays
   compatible with this site's CSP (style-src has no unsafe-inline).
   ============================================================ */
.project-card-btn{
  align-self:flex-start; margin-top:.9rem; font:700 .76rem/1 var(--font-body); letter-spacing:.04em;
  text-transform:uppercase; color:#fff; background:transparent; border:1.5px solid rgba(255,255,255,.55);
  border-radius:999px; padding:.5em 1.1em; cursor:pointer; position:relative; z-index:1;
  transition: background var(--dur) var(--ease-out), border-color var(--dur) var(--ease-out), color var(--dur) var(--ease-out);
}
.project-card-btn:hover, .project-card-btn:focus-visible{
  background: var(--brand-orange); border-color: var(--brand-orange); color: var(--charcoal);
}

.project-modal-scrim{
  position:fixed; inset:0; background: rgba(10,10,10,.65); z-index: 1200;
  opacity:0; pointer-events:none; transition: opacity var(--dur) var(--ease-out);
}
.project-modal-scrim.is-open{ opacity:1; pointer-events:auto; }

.project-modal{
  position:fixed; inset:0; z-index: 1210; display:flex; align-items:center; justify-content:center;
  padding: 1.4rem; opacity:0; pointer-events:none; transition: opacity var(--dur) var(--ease-out);
}
/* The wrapper itself stays pointer-events:none even while open — only the
   panel (below) re-enables pointer events. This lets a click in the empty
   gutter around the panel fall through to .project-modal-scrim underneath,
   so backdrop-click-to-close actually reaches the scrim's click handler
   instead of being swallowed by this full-viewport flex wrapper. */
.project-modal.is-open{ opacity:1; }

.project-modal-panel{
  position:relative; background: var(--white); border-radius: calc(var(--radius) + 4px); overflow:hidden;
  width:min(640px, 100%); max-height: 92vh; display:flex; flex-direction:column;
  box-shadow: 0 24px 64px rgba(0,0,0,.35);
  transform: scale(.96) translateY(8px);
  /* --ease-glide, not --ease-spring: the spring's overshoot (briefly past
     100% scale, then settling back) combined with the aspect-ratio
     slideshow box resizing along with the panel read as a flicker on
     open rather than a lively bounce. A smaller scale delta (.96 vs the
     previous .92) plus a clean, no-overshoot glide opens just as
     noticeably but settles in one direction only. */
  transition: transform var(--dur-slow) var(--ease-glide);
  pointer-events:auto;
}
.project-modal.is-open .project-modal-panel{ transform: scale(1) translateY(0); }

.project-modal-close{
  position:absolute; top:.8rem; right:.8rem; z-index:3;
  width:40px; height:40px; border-radius:50%; border:0; background: rgba(10,10,10,.55); color:#fff;
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  transition: background var(--dur) var(--ease-out), transform var(--dur) var(--ease-fluid);
}
.project-modal-close:hover, .project-modal-close:focus-visible{ background: var(--brand-orange); color: var(--charcoal); transform: scale(1.08); }
.project-modal-close:active{ transform: scale(.96); transition-duration: 90ms; }
.project-modal-close svg{ width:18px; height:18px; }

.project-modal-slideshow{ position:relative; aspect-ratio: 4/3; overflow:hidden; touch-action: pan-y; background: var(--ink); }
.project-modal-slides{ position:relative; width:100%; height:100%; }
.project-modal-slide{
  position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
  gap:.9rem; color:#fff; text-align:center;
  background: linear-gradient(150deg, var(--pc-a, #262626), var(--pc-b, #333333));
  opacity:0; transform: translateX(10%);
  /* Slide stepping is a discrete action (button/dot/key/swipe-release),
     never a live drag the user is tracking frame-by-frame, so there is
     no earned momentum to carry into an overshoot/spring. --ease-glide
     is a slower, symmetric ease-in-out — it visibly accelerates, glides,
     and settles — so the motion is felt rather than just registered as
     a flicker. A full ±100% slide (an earlier attempt) is still avoided:
     travelling the slideshow's entire width reads as mechanical no
     matter how it's eased, so this keeps a short ~10% drift-and-fade.
     No scale() here (an earlier attempt added one for a bit of
     "settle"): shrinking an inset:0 slide opens a thin gap around its
     edges for the duration of the transition, and while the slide is
     also semi-transparent mid-fade, that gap let the panel's white
     background show through as a flickering edge. A pure translate+fade
     never shrinks the slide, so no gap ever opens. */
  transition: opacity var(--dur-slide) var(--ease-glide), transform var(--dur-slide) var(--ease-glide);
  pointer-events:none;
  will-change: transform, opacity;
}
.project-modal-slide.is-prev{ opacity:0; transform: translateX(-10%); }
.project-modal-slide.is-next{ opacity:0; transform: translateX(10%); }
.project-modal-slide.is-active{ opacity:1; transform: translateX(0); pointer-events:auto; }
.project-modal-slide-art{ width:25%; max-width:92px; color: var(--brand-amber); opacity:.9; }
.project-modal-slide-art svg{ width:100%; height:100%; overflow:visible; }
.project-modal-slide-caption{ font:700 .8rem/1 var(--font-body); letter-spacing:.08em; text-transform:uppercase; color: rgba(255,255,255,.85); }
/* A real-photo slide (see the data-images swap in main.js's
   buildSlides()) replaces the icon+caption placeholder with a single
   <img>, so it drops the flex centering/gap/padding meant for those —
   the photo fills the whole slide instead. object-fit:cover crops to
   fill the slideshow's 4:3 box cleanly regardless of the photo's own
   aspect ratio, exactly like .case-photo does for the project cards'
   own thumbnails (see the project-grid comment near the top of
   index.html). */
.project-modal-slide.has-photo{ display:block; gap:0; }
/* object-fit:cover crops to fill the slideshow's 4:3 box cleanly no
   matter what aspect ratio the source photo happens to be, so photos
   of mixed shapes/sizes still line up consistently from slide to
   slide instead of leaving letterboxed gaps. */
.project-modal-slide.has-photo img{ width:100%; height:100%; object-fit:cover; display:block; }

.project-modal-nav{
  position:absolute; top:50%; transform: translateY(-50%); z-index:2;
  width:38px; height:38px; border-radius:50%; border:0; background: rgba(10,10,10,.5); color:#fff;
  display:flex; align-items:center; justify-content:center; cursor:pointer;
  transition: background var(--dur) var(--ease-out), transform var(--dur) var(--ease-fluid);
}
.project-modal-nav:hover, .project-modal-nav:focus-visible{ background: var(--brand-orange); color: var(--charcoal); transform: translateY(-50%) scale(1.08); }
.project-modal-nav:active{ transform: translateY(-50%) scale(.94); transition-duration: 90ms; }
.project-modal-nav.prev{ left:.7rem; }
.project-modal-nav.next{ right:.7rem; }
.project-modal-nav svg{ width:16px; height:16px; }

.project-modal-dots{
  position:absolute; left:0; right:0; bottom:.8rem; z-index:2;
  display:flex; justify-content:center; gap:.45rem;
}
.project-modal-dots button{
  width:8px; height:8px; border-radius:50%; border:0; padding:0; background: rgba(255,255,255,.45); cursor:pointer;
  transition: background var(--dur) var(--ease-out), transform var(--dur) var(--ease-fluid);
}
.project-modal-dots button.is-active{ background: var(--brand-orange); transform: scale(1.3); }
.project-modal-dots button:focus-visible{ outline:2px solid var(--brand-orange); outline-offset:2px; }

.project-modal-body{ padding: 1.4rem 1.6rem 1.6rem; overflow-y:auto; }
.project-modal-body .tag{
  display:inline-block; font:700 10px/1 var(--font-body); letter-spacing:.08em; text-transform:uppercase;
  background: var(--brand-orange); color: var(--charcoal); padding:.45em .8em; border-radius:999px; margin-bottom:.7rem;
}
.project-modal-body h3{ font-size:1.25rem; margin-bottom:.4rem; text-transform:uppercase; color: var(--ink); }
.project-modal-body p{ color: var(--gray-text); font-size:.94rem; margin:0 0 .6rem; }
.project-modal-note{ font-size:.8rem; font-style:italic; color: var(--gray-mid); margin:0; }
/* Toggled by main.js once a project has real data-images photos — the
   "reference images, real photos coming soon" note stops applying. */
.project-modal-note.is-hidden{ display:none; }

/* Page-scroll lock while the modal (or the mobile nav) is open —
   a class toggle rather than a direct .style.overflow assignment, so
   it stays within the CSP's style-src (no unsafe-inline). */
html.no-scroll, html.no-scroll body{ overflow:hidden; }

@media (max-width: 560px){
  .project-modal{ padding:0; align-items:flex-end; }
  .project-modal-panel{
    width:100%; max-height:92vh; border-radius: calc(var(--radius) + 4px) calc(var(--radius) + 4px) 0 0;
    transform: translateY(100%);
  }
  .project-modal.is-open .project-modal-panel{ transform: translateY(0); }
}

@media (prefers-reduced-motion: reduce){
  .project-modal-panel{ transform:none; }
  .project-modal-slide{ transform:none; transition: opacity 150ms ease; }
  .project-modal-close, .project-modal-nav, .project-modal-dots button{ transition:none; }
}

/* ============================================================
   404 PAGE
   ============================================================ */
.error-page{
  min-height: 100svh; display:flex; align-items:center; color:#fff;
  background: radial-gradient(120% 90% at 82% 12%, var(--ink-soft) 0%, var(--ink) 46%, #141414 100%);
  padding: 8rem 0 4rem;
}
.error-page .container{ max-width: 620px; text-align:center; }
.error-page .error-code{
  font: 700 clamp(4rem,14vw,7rem)/1 var(--font-head); color: var(--brand-orange);
  letter-spacing:-0.02em; margin-bottom:.2rem;
}
.error-page h1{ color:#fff; font-size: clamp(1.4rem,3vw,1.9rem); text-transform:uppercase; }
.error-page p{ color: rgba(255,255,255,.78); font-size:1.02rem; }
.error-page .error-actions{ display:flex; flex-wrap:wrap; gap:1rem; justify-content:center; margin: 1.6rem 0 2.4rem; }
.error-page .error-fallback{ font-size:.92rem; color: rgba(255,255,255,.65); }
.error-page .error-fallback a{ color: var(--brand-orange); font-weight:600; }
.error-page .brand-mark{ margin-inline:auto; margin-bottom:1.6rem; }

/* Print */
@media print{
  .site-header, .mobile-nav, .mobile-nav-scrim, .back-to-top, .whatsapp-fab, .cta-banner, video{ display:none !important; }
}
