/* ============================================================
   Nexum Padel (built under the earlier working name
   "Premium Padel Academy"; renamed 2026-08-03)
   Editable Recreation of 97jnvjsg4j.wixsite.com/riki-coach,
   plus the client's requested fixes.

   Type and colour are measured from the source's computed styles
   (see reports/discovery-report.md). Desktop reproduces the source.
   Mobile is where the client's fixes live:

     - nothing below 15px (source itself sits at 16px on mobile;
       the earlier build had dropped to 12.2px)
     - no overlapping images
     - menu opens centred, not off to one side
   ============================================================ */

:root {
  --ink:        #172338;   /* headings, dark bands — Nexum navy (was #2F3E3A) */
  --muted:      #6F7F78;   /* body copy */
  --gold:       #C2A46A;   /* eyebrow / accent */
  --soft:       #FAF9F6;   /* warm section band */
  --soft-2:     #F5F5F2;   /* grey section band */
  --white:      #FFFFFF;
  --line:       #E6E4DD;

  --serif: "Instrument Serif", Georgia, "Times New Roman", serif;
  --sans:  "Instrument Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Helvetica, Arial, sans-serif;

  --maxw: 1200px;
  --pad:  clamp(20px, 5vw, 60px);
  --radius: 18px;

  /* Fluid type. Every ramp bottoms out at a size that is still readable on a
     390px phone — that is the "letras muy pequeñas" fix, expressed once. */
  --t-h1:      clamp(2.5rem,  1.30rem + 6.00vw, 6.47rem);
  --t-h2:      clamp(2.0rem,  1.30rem + 3.50vw, 5.06rem);
  --t-h3:      clamp(1.625rem, 1.20rem + 2.10vw, 4.08rem);
  --t-card:    clamp(1.375rem, 1.15rem + 1.10vw, 1.97rem);
  --t-lead:    clamp(1.125rem, 1.05rem + 0.35vw, 1.41rem);
  --t-body:    clamp(1rem,     0.97rem + 0.15vw, 1.125rem);
  --t-meta:    clamp(0.9375rem, 0.93rem + 0.05vw, 0.99rem);
  /* Uppercase + letterspaced reads smaller than its nominal size, so this floor
     sits at 15px too rather than dipping into the range the client flagged. */
  --t-eyebrow: clamp(0.9375rem, 0.91rem + 0.12vw, 1.0625rem);
}

*, *::before, *::after { box-sizing: border-box; }

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

body {
  margin: 0;
  font-family: var(--sans);
  font-size: var(--t-body);
  line-height: 1.6;
  color: var(--muted);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
}

/* height:auto is load-bearing — every img carries width/height attributes to
   reserve layout space, and without this they render at that literal height. */
img { max-width: 100%; height: auto; display: block; }
ul  { margin: 0; padding: 0; list-style: none; }
a   { color: inherit; text-decoration: none; }

h1, h2, h3 {
  font-family: var(--serif);
  font-weight: 400;
  color: var(--ink);
  margin: 0;
  line-height: 1.04;
  letter-spacing: -0.01em;
}

h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }

p { margin: 0 0 1.15em; }
p:last-child { margin-bottom: 0; }

.container { width: 100%; max-width: var(--maxw); margin-inline: auto; padding-inline: var(--pad); }

.eyebrow {
  font-family: var(--sans);
  font-size: var(--t-eyebrow);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold);
  margin: 0 0 0.85em;
}

.lead { font-size: var(--t-lead); line-height: 1.5; color: var(--ink); }

.rule { display: block; width: 64px; height: 1px; background: var(--gold); margin: 1.5rem 0; }

/* ---------- skip link ----------
   Clipped rather than pushed to -9999px, so it never counts as horizontal
   overflow in a layout audit. */
.skip {
  position: absolute;
  width: 1px; height: 1px; overflow: hidden;
  clip-path: inset(50%); white-space: nowrap;
  background: var(--ink); color: #fff; padding: 12px 18px; z-index: 200;
}
.skip:focus {
  width: auto; height: auto; clip-path: none;
  left: 12px; top: 12px;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-block;
  font-family: var(--sans);
  font-size: var(--t-body);
  font-weight: 500;
  color: #fff;
  background: var(--ink);
  border: 1px solid var(--ink);
  border-radius: 999px;
  padding: 0.75em 1.7em;
  cursor: pointer;
  transition: background .18s ease, color .18s ease, transform .18s ease;
}
.btn:hover  { background: #121B2C; transform: translateY(-1px); }
.btn:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.btn-light  { background: #fff; color: var(--ink); border-color: #fff; }
.btn-light:hover { background: var(--soft-2); }
.btn-ghost  { background: transparent; color: #fff; border-color: rgba(255,255,255,.65); }
.btn-ghost:hover { background: rgba(255,255,255,.14); }

/* ============================================================
   Header + navigation
   ============================================================ */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255,255,255,.94);
  backdrop-filter: saturate(150%) blur(8px);
  border-bottom: 1px solid var(--line);
}
/* The brand mark is the client's stacked lockup: ball over NEXUM / PADEL, with
   "INTERNATIONAL PADEL SERVICES" on a curved baseline (supplied 2026-08-05,
   replacing the earlier "MARBELLA - SPAIN" version).

   An earlier build dropped the curved strapline because at 58px it rendered
   around 5px tall and read as a smudge. The client has now asked for the full
   lockup, so it stays — and the header grew instead. At 72px the wordmark is
   legible and the strapline reads as fine detail rather than broken text, which
   is how a strapline is meant to behave at small sizes. Height is what governs
   this, not width: the lockup is square, so a wider header buys nothing. */
.header-inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; min-height: 88px;
}
.brand { display: inline-flex; align-items: center; gap: 10px; flex: 0 0 auto; }
/* The lockup already contains the wordmark, so no type sits beside it — that
   would print the name twice. */
.brand img { height: 72px; width: auto; }   /* stacked lockup: height drives
     legibility of the wordmark, not width. 58px left it unreadable. */

.main-nav { display: flex; align-items: center; gap: clamp(20px, 3vw, 46px); }
.nav-link {
  font-size: var(--t-body);
  color: var(--ink);
  padding: 6px 0;
  border-bottom: 1px solid transparent;
  transition: border-color .18s ease;
}
.nav-link:hover { border-color: var(--gold); }
.nav-link[aria-current="page"] { border-color: var(--ink); }

/* Language switch. Boxed rather than underlined so it reads as a control that
   leaves the current language, not as a fifth section of the site. */
.nav-lang {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
  padding: 5px 11px; border: 1px solid var(--line); border-radius: 999px;
  transition: color .18s ease, border-color .18s ease, background .18s ease;
}
/* Flags are inline SVG, never emoji: emoji flags are absent on Windows and
   unstylable everywhere. Sized in px rather than em so they stay crisp
   rectangles, with an inset ring so a white-edged flag (Union Jack, Ireland)
   doesn't bleed into a light background. */
.flag {
  width: 19px; height: 13px; flex: 0 0 auto;
  border-radius: 2px;
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .12);
}
.review-where .flag { width: 17px; height: 11.5px; }
.nav-lang:hover, .nav-lang:focus-visible {
  color: var(--white); background: var(--ink); border-color: var(--ink);
}

/* Burger — hidden on desktop, revealed with the mobile panel below. */
.nav-toggle {
  display: none;
  width: 46px; height: 46px;
  align-items: center; justify-content: center;
  background: none; border: 1px solid var(--line); border-radius: 12px;
  cursor: pointer; color: var(--ink);
}
.nav-toggle:focus-visible { outline: 3px solid var(--gold); outline-offset: 2px; }
.nav-toggle span {
  position: relative; display: block; width: 20px; height: 1.5px;
  background: currentColor; transition: background .18s ease;
}
.nav-toggle span::before,
.nav-toggle span::after {
  content: ""; position: absolute; left: 0; width: 20px; height: 1.5px;
  background: currentColor; transition: transform .22s ease, top .22s ease;
}
.nav-toggle span::before { top: -6px; }
.nav-toggle span::after  { top: 6px; }

/* ============================================================
   Hero — photo behind, copy on an inset card (source layout)
   ============================================================ */
.hero { position: relative; background: var(--ink); overflow: hidden; }
.hero-media { position: absolute; inset: 0; overflow: hidden; }
.hero-media img { width: 100%; height: 100%; object-fit: cover; }
.hero-inner {
  position: relative;
  display: flex; align-items: center;
  min-height: clamp(520px, 62vw, 760px);
  padding-block: clamp(40px, 6vw, 72px);
}
.hero-card {
  background: #fff;
  border-radius: 28px;
  padding: clamp(28px, 4vw, 56px);
  max-width: 560px;
  box-shadow: 0 30px 70px rgba(20,30,26,.18);
}
.hero-card h1 { margin-bottom: .5rem; }
.hero-card .lead { color: var(--muted); font-size: var(--t-body); }

/* Strapline under the wordmark: "Your international Padel Partner". English on
   a Spanish page on purpose — it is the brand line, not body copy — so it is
   marked lang="en" for screen readers and translators. Set in the sans at a
   weight the serif h1 above it does not compete with. */
.hero-tagline {
  font-family: var(--sans);
  font-size: clamp(1.0625rem, .99rem + .42vw, 1.35rem);
  font-weight: 500;
  line-height: 1.25;
  color: var(--ink);
  margin: 0 0 .55rem;
}
.hero-on-image .hero-tagline { color: #fff; }

/* Hero variant with the copy directly on the image (Clubs) */
.hero-on-image { color: #fff; }
.hero-on-image::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(24,32,28,.30), rgba(24,32,28,.68));
}
.hero-on-image .hero-inner { z-index: 1; }
.hero-on-image h1 { color: #fff; }
.hero-on-image .lead { color: rgba(255,255,255,.92); }
.hero-copy { max-width: 720px; }

/* ============================================================
   Generic section rhythm
   ============================================================ */
.section        { padding-block: clamp(56px, 7vw, 104px); }
.section-soft   { background: var(--soft); }
.section-soft2  { background: var(--soft-2); }
.section-tight  { padding-block: clamp(40px, 5vw, 72px); }
.section-head   { max-width: 780px; margin-bottom: clamp(32px, 4vw, 56px); }
.section-head p { color: var(--muted); }

/* ---------- coaches ---------- */
/* Shared credentials, above the pair — deliberately not attached to either
   coach, so the section reads as one academy rather than a lead and a second. */
.coach-creds {
  display: grid; grid-template-columns: repeat(2, 1fr);
  gap: clamp(18px, 3vw, 40px);
  max-width: 980px; margin: 0 0 clamp(36px, 4vw, 56px);
}
.coach-creds li { position: relative; padding-left: 1.2em; color: var(--muted); }
.coach-creds li::before { content: "—"; position: absolute; left: 0; color: var(--gold); }

/* Both columns are structurally identical: same photo ratio, same role label,
   same name treatment. Nothing distinguishes one as senior. */
.coach-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(24px, 4vw, 56px); }
.coach { display: flex; flex-direction: column; }
.coach-photo { border-radius: var(--radius); overflow: hidden; background: var(--soft-2); }
.coach-photo img { width: 100%; aspect-ratio: 3/4; object-fit: cover; }
.coach .eyebrow { margin: 1.25rem 0 .3rem; }
/* Instagram link on a coach card. min-height 44px for the touch target, as with
   the footer social link. */
.coach-ig {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; margin-top: .35rem;
  font-size: var(--t-meta); color: var(--muted);
  transition: color .2s ease;
}
.coach-ig svg {
  width: 17px; height: 17px; flex: 0 0 auto;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
.coach-ig:hover, .coach-ig:focus-visible { color: var(--ink); }
.coach-ig:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; border-radius: 6px; }
.coach-name {
  display: flex; align-items: center; gap: .55em; flex-wrap: wrap;
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.6rem, 1.15rem + 1.9vw, 2.7rem);
  line-height: 1.1; color: var(--ink); margin: 0;
}
.coach-flag {
  flex: 0 0 auto; width: 1.15em; height: auto; border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(20,30,26,.10);
}

/* ---------- split: copy + stacked photos ---------- */
.split { display: grid; grid-template-columns: 1.05fr .95fr; gap: clamp(32px, 5vw, 72px); align-items: center; }
.split-media { position: relative; }
/* object-position biased above centre: these slots have a fixed aspect-ratio, so
   a photo that is not the same shape gets cropped, and a centred crop takes the
   difference off the top — which is where the faces are. Supplied photos have
   ranged from 3:4 to square, so the slot cannot assume a shape. */
.split-media img {
  width: 100%; border-radius: var(--radius);
  object-fit: cover; object-position: 50% 32%;
}
.split-media .img-main  { aspect-ratio: 4/5; }

/* The source overlaps a small inset photo over the main one. Kept on desktop,
   unstacked below — the overlap was landing on top of the subject on a phone. */
.split-media .img-inset {
  position: absolute; right: -6%; bottom: -8%;
  width: 46%; aspect-ratio: 3/4;
  border: 8px solid #fff; border-radius: var(--radius);
  box-shadow: 0 18px 40px rgba(20,30,26,.20);
}

/* ---------- checklist ---------- */
.checklist li {
  position: relative; padding-left: 1.9em; margin-bottom: 1rem;
  font-size: var(--t-body);
}
.checklist li::before {
  content: ""; position: absolute; left: 0; top: .55em;
  width: 10px; height: 10px; border-radius: 50%;
  border: 2px solid var(--gold);
}

/* ---------- service cards ---------- */
.cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 2.5vw, 30px); align-items: stretch; }
.card {
  display: flex; flex-direction: column; height: 100%;
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 22px;
  padding: clamp(26px, 3vw, 38px);
}
.card-soft { background: var(--soft); }
/* Title + button only, no description/list: centred as one compact unit in
   the full-height card (now matching its fuller siblings via align-items:
   stretch above) instead of pinning the title to the top with a large blank
   gap before the auto-margin button at the bottom. */
.card-compact { justify-content: center; align-items: center; text-align: center; gap: 1.5rem; }
.card-compact .card-title { margin: 0; }
.card-compact .btn { margin-top: 0; }

/* ---------- Home editorial additions (Fase 3) ---------- */

/* Coaching personal: reuses .split (same pattern as "20+ años" and Clubs'
   "Nuestra filosofía de coaching") with the elite-958 photo as the large
   left-hand image — no inset here, just the one protagonist shot. The
   heading stays "Coaching personal" for correct document structure, but is
   styled as a small label (.eyebrow); the lead line is the large serif
   piece that carries the column. */
.coaching-lead {
  font-family: var(--serif); font-weight: 400; color: var(--ink);
  font-size: clamp(2rem, 1.5rem + 2.2vw, 3.6rem);
  line-height: 1.1; margin: 0 0 clamp(20px, 2.5vw, 32px);
}

/* Services: same three offers, presented as an editorial index (numbered,
   divided by hairlines) instead of a row of boxed cards. Reuses .cards/.card
   for layout and typography — only the box chrome is removed. */
/* Natural height, not stretched to match the tallest column — Local Service
   has more to say than the other two, and that's fine; forcing equal height
   is what was pinning their buttons artificially far from the title. */
.cards-editorial { counter-reset: services; align-items: start; }
.cards-editorial .card {
  counter-increment: services;
  background: none; border: none; border-radius: 0;
  padding: 0 clamp(22px, 2.5vw, 34px);
  height: auto; justify-content: flex-start;
}
.cards-editorial .card:first-child { padding-left: 0; }
.cards-editorial .card:last-child { padding-right: 0; }
.cards-editorial .card:not(:first-child) { border-left: 1px solid var(--line); }
.cards-editorial .card::before {
  content: counter(services, decimal-leading-zero);
  display: block;
  font-family: var(--sans); font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .12em; color: var(--gold); margin-bottom: .6rem;
}
/* Button sits right after whatever content the service actually has,
   instead of being pinned to the bottom of an artificially tall column. */
.cards-editorial .card .btn { align-self: flex-start; margin-top: 1.4rem; }
/* .card-compact centred title+button for the old equal-height treatment;
   in the natural-height editorial list that reads as a mismatch against
   Local Service's left-aligned flow, so the two short entries now follow
   the same left-aligned, number → title → button rhythm as the third. */
.cards-editorial .card-compact { justify-content: flex-start; align-items: flex-start; text-align: left; gap: 0; }
.cards-editorial .card-compact .card-title { margin: 0 0 1rem; }
.cards-editorial .card-compact .btn { margin-top: 1.4rem; }
.card-title {
  font-family: var(--sans);
  font-size: var(--t-card);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: .01em;
  line-height: 1.15;
  color: var(--ink);
  margin: 0 0 .9rem;
}
.card-desc { color: var(--muted); margin-bottom: 1.4rem; }
.card-list { margin-bottom: 1.6rem; }
.card-list li { position: relative; padding-left: 1.2em; margin-bottom: .65rem; }
.card-list li::before { content: "•"; position: absolute; left: .1em; color: var(--gold); }
.card .btn { align-self: center; margin-top: auto; }

/* ---------- media cards (Clubs programme grid) ----------
   Fase 3: de-carded. No border/background/radius — the photo bleeds and the
   caption reads as an editorial index entry, not a SaaS feature card. Numbers
   are a CSS counter (not markup) so the count can change without touching HTML. */
.media-cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(28px, 3vw, 44px); align-items: start; counter-reset: media-card; }
.media-card { counter-increment: media-card; background: none; border: none; border-radius: 0; overflow: visible; display: flex; flex-direction: column; }
/* Alternating stagger on the 2nd/4th (or, in the 2-col tablet layout, the
   right column) — enough to break the perfect grid without hurting scanability. */
.media-card:nth-child(2n) { margin-top: clamp(24px, 3vw, 40px); }
.media-card img { width: 100%; aspect-ratio: 4/5; object-fit: cover; }
.media-card-body { padding: 0; margin-top: 1.1rem; }
.media-card-body::before {
  content: counter(media-card, decimal-leading-zero);
  display: block;
  font-family: var(--sans); font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .12em; color: var(--gold); margin-bottom: .5rem;
}
.media-card h3 { font-family: var(--sans); font-size: var(--t-card); font-weight: 600; margin-bottom: .5rem; line-height: 1.2; }
.media-card p  { color: var(--muted); }

/* ---------- numbered steps ---------- */
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(28px, 3.5vw, 52px); }
.step-num {
  font-family: var(--sans);
  font-size: clamp(1.05rem, .95rem + .45vw, 1.35rem);
  font-weight: 600; color: var(--gold);
  width: 2.6em; height: 2.6em; border-radius: 50%;
  border: 1px solid var(--gold);
  display: inline-flex; align-items: center; justify-content: center;
  margin-bottom: 1rem;
}
.step h3 { font-family: var(--sans); font-size: var(--t-card); font-weight: 600; margin-bottom: .55rem; }
.step p  { color: var(--muted); }

/* ---------- numbered index list (Fase 3 — Clubs "En qué trabajamos") ----------
   Same .step-num circle as above, laid out as rows with a hairline rule
   instead of a grid — reads as a coaching-programme index rather than a
   repeat of the checklist bullets used elsewhere. Works at any item count
   without a grid remainder, so it needs no separate mobile layout. */
.index-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.index-item {
  display: flex; align-items: flex-start; gap: clamp(20px, 2.5vw, 32px);
  padding-block: clamp(18px, 2.2vw, 26px);
  border-bottom: 1px solid var(--line);
}
.index-item:first-child { border-top: 1px solid var(--line); }
.index-item .step-num { flex: 0 0 auto; margin-bottom: 0; }
.index-item h3 { font-family: var(--sans); font-size: var(--t-card); font-weight: 600; margin-bottom: .35rem; }
.index-item p { color: var(--muted); margin-bottom: 0; }
/* Extra breathing room before the closing item — spacing only, same
   typography as every other row in the list (client correction). */
.index-item-feature { padding-block: clamp(28px, 3.5vw, 40px); }

/* ---------- statement blocks ---------- */
.statements {
  display: grid; grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 2.5vw, 30px);
}
.statement {
  background: var(--white); border: 1px solid var(--line); border-radius: 22px;
  padding: clamp(26px, 3vw, 38px);
  display: flex; flex-direction: column; gap: .8rem;
}
.statement .eyebrow { margin: 0; order: -1; }
.statement h3 {
  font-family: var(--sans);
  font-size: var(--t-card); font-weight: 600; line-height: 1.25;
  margin: 0;
}

/* ---------- statement list (Fase 3 — Clubs "Qué puedes esperar") ----------
   Same eyebrow+heading pairing as .statement above, but stacked as one
   column with no card chrome and alternating alignment — a typographic
   "manifesto" reading rather than a 3-up card grid. Deliberately the third
   different shape on this page (photo / numbered index / typography), so
   it doesn't read as a variation of the two sections above it. */
.statement-list { display: flex; flex-direction: column; gap: clamp(28px, 4vw, 48px); max-width: 900px; margin-top: clamp(32px, 4vw, 56px); }
.statement-block { max-width: 640px; }
.statement-block:nth-child(even) { align-self: flex-end; text-align: right; }
.statement-block .eyebrow { margin-bottom: .5rem; }
.statement-block h3 {
  font-family: var(--serif); font-weight: 400; color: var(--ink);
  font-size: clamp(1.5rem, 1.15rem + 1.6vw, 2.6rem);
  line-height: 1.15; margin: 0;
}

/* ---------- feature icons (Camps) ---------- */
.features { display: grid; grid-template-columns: repeat(4, 1fr); gap: clamp(24px, 3vw, 40px); text-align: center; }
.feature { display: flex; flex-direction: column; align-items: center; }
.feature p { max-width: 30ch; margin-inline: auto; }
.feature-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 54px; height: 54px; border-radius: 50%;
  background: var(--soft); border: 1px solid var(--line);
  color: var(--gold); margin-bottom: 1rem;
}
.feature-icon svg { width: 24px; height: 24px; fill: none; stroke: currentColor; stroke-width: 1.6; }
.feature h3 { font-family: var(--sans); font-size: var(--t-card); font-weight: 600; margin-bottom: .5rem; }
.feature p  { color: var(--muted); }

/* ---------- FAQ ---------- */
.faq { max-width: 820px; margin-inline: auto; }
.faq-item { border-bottom: 1px solid var(--line); padding: clamp(20px, 2.4vw, 30px) 0; }
.faq-item h3 { font-size: var(--t-card); font-family: var(--sans); font-weight: 600; margin-bottom: .6rem; }
.faq-item p  { color: var(--muted); }

/* ---------- band with image + floating card (Camps) ---------- */
.band { position: relative; background: var(--soft); }
.band-media img { width: 100%; height: clamp(320px, 44vw, 560px); object-fit: cover; }
.band-card {
  background: #fff; border: 1px solid var(--line); border-radius: 24px;
  padding: clamp(28px, 3.5vw, 48px);
  box-shadow: 0 26px 56px rgba(20,30,26,.14);
}

/* ============================================================
   Contact — a real block, not an empty placeholder
   ============================================================ */
.contact { background: var(--ink); color: #fff; }
.contact h2 { color: #fff; }
.contact-grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 72px); align-items: center; }
.contact-copy p { color: rgba(255,255,255,.82); }
.contact-detail { margin-top: 1.8rem; }
.contact-label {
  display: block;
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--gold); margin-bottom: .4rem;
}
.contact-email {
  font-family: var(--serif);
  font-size: clamp(1.35rem, 1.05rem + 1.3vw, 2.1rem);
  color: #fff; line-height: 1.2;
  border-bottom: 1px solid rgba(255,255,255,.35);
  padding-bottom: 2px;
  overflow-wrap: anywhere;
}
.contact-email:hover { border-color: var(--gold); color: var(--gold); }

.contact-panel { background: #fff; border-radius: 24px; padding: clamp(28px, 3.5vw, 44px); color: var(--muted); }
.contact-panel h3 { font-family: var(--sans); font-size: var(--t-card); font-weight: 600; margin-bottom: .8rem; }

/* ---------- form ---------- */
.field { display: block; margin-bottom: 1.3rem; }
.field > span {
  display: block;
  font-size: var(--t-meta); font-weight: 600; color: var(--ink);
  margin-bottom: .45rem;
}
.field input, .field textarea {
  width: 100%;
  font-family: var(--sans);
  font-size: var(--t-body);
  color: var(--ink);
  background: var(--soft);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: .8em .9em;
}
.field input:focus, .field textarea:focus { outline: none; border-color: var(--gold); background: #fff; }
.field textarea { resize: vertical; min-height: 120px; }
.form-note { font-size: var(--t-meta); margin-top: 1rem; }

/* ============================================================
   Colaboradores — logo band

   Sits as the last section of <main>, directly above the footer.
   Generated from assets/partners.json by tools/partner_logos.py, so
   all four pages carry the identical band.

   Empty slots are the point: they reserve space for logos the client
   has not supplied yet, and are visibly marked rather than blank.
   ============================================================ */
.partners {
  padding-block: clamp(40px, 5vw, 72px);
  background: var(--soft-2);
  border-top: 1px solid var(--line);
}
.partners-head { text-align: center; margin-bottom: clamp(24px, 3vw, 40px); }
.partners-head .eyebrow { margin-bottom: 0; }
.partners-head .rule { margin: 1rem auto 0; }

/* Flex rather than grid: the band has to look deliberate at any count, and
   auto-fit columns stretch a single logo across the full width. Centred wrap
   keeps one logo, four, or six all reading as an intentional row. */
.partners-grid {
  list-style: none; margin: 0; padding: 0;
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: clamp(14px, 1.8vw, 26px);
}
.partner {
  flex: 1 1 150px; max-width: 220px;
  display: flex; align-items: center; justify-content: center;
  min-height: 78px; padding: 16px 18px;
}
.partner a { display: flex; align-items: center; justify-content: center; }

/* Fixed height + width:auto, matching .footer-logo img. Logos arrive at wildly
   different intrinsic sizes, so height is what makes a row of them read evenly. */
.partner img {
  height: 26px; width: auto; max-width: 100%;
  opacity: .8;
  transition: opacity .6s var(--ease-out-soft), transform .6s var(--ease-out-soft);
}
.partner a:hover img,
.partner a:focus-visible img { opacity: 1; transform: translateY(-3px); }

.partner.is-empty {
  border: 1px dashed var(--line);
  border-radius: calc(var(--radius) / 2);
  background: var(--white);
}
.partner.is-empty span {
  font-size: var(--t-meta);        /* 15px floor — the client's "letras pequeñas" fix */
  color: var(--muted);
  text-align: center;
  opacity: .75;
}

@media (max-width: 560px) {
  /* Two per row rather than one: a single 150px logo on a 390px screen leaves the
     band looking like a stack of empty cards. */
  .partner {
    flex: 0 0 calc(50% - clamp(14px, 1.8vw, 26px) / 2);
    max-width: none; min-height: 68px; padding: 12px;
  }
}

/* ============================================================
   Footer
   ============================================================ */
.site-footer { background: var(--white); border-top: 1px solid var(--line); }
.footer-grid {
  display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: clamp(28px, 4vw, 56px);
  padding-block: clamp(44px, 5vw, 72px);
}
.footer-logo img { height: 78px; width: auto; margin-bottom: 1rem; }
.footer-col h2 {
  font-family: var(--sans);
  font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .14em; text-transform: uppercase;
  color: var(--ink); margin-bottom: .9rem;
}
.footer-col p, .footer-col a { font-size: var(--t-meta); color: var(--muted); }
.footer-col a:hover { color: var(--ink); }
/* li carries the size too: the location is plain text, not a link, and would
   otherwise sit a size larger than the address above it. */
.footer-col li { margin-bottom: .5rem; font-size: var(--t-meta); color: var(--muted); }
.footer-col li:last-child { margin-bottom: 0; }
/* The brand column is the widest; its blurb shouldn't run the full width. */
.footer-logo p { max-width: 26ch; }
.footer-legal-link { font-size: var(--t-meta); color: var(--muted); }
.footer-legal-link:hover { color: var(--ink); text-decoration: underline; }

/* ---------- legal / prose pages ----------
   Narrow measure and a plain vertical rhythm: these pages are read, not
   scanned, so they drop the marketing layout entirely. */
.legal-inner { max-width: 760px; }
.legal-title { font-size: var(--t-h2); margin-bottom: .4rem; }
.legal-updated { font-size: var(--t-meta); color: var(--muted); margin-bottom: 2rem; }
.legal h2 {
  font-family: var(--sans);
  font-size: clamp(1.06rem, 1rem + .3vw, 1.24rem);
  font-weight: 600; color: var(--ink);
  margin: 2.4rem 0 .7rem;
}
.legal p { color: var(--muted); }
.legal-list { margin: 0 0 1.15em; padding-left: 1.1em; list-style: disc; }
.legal-list li { margin-bottom: .5rem; color: var(--muted); }
.legal-list strong { color: var(--ink); font-weight: 600; }
.legal a { color: var(--ink); text-decoration: underline; text-underline-offset: 3px; }
.legal a:hover { color: var(--gold); }
/* Unfilled legal identifiers must be impossible to mistake for real ones —
   same rule the build applies to placeholder reviews and partner slots. */
.legal-pending {
  display: inline-block;
  font-family: var(--sans); font-size: var(--t-meta); font-weight: 600;
  color: #A8762B; background: #FBF0DC;
  border: 1px dashed #D9B46A; border-radius: 4px;
  padding: 1px 7px;
}

/* Social links. Generated by tools/social_links.py; the chip is an outlined
   circle that fills with the brand ink on hover, so the icon reads at the same
   weight as the footer text around it rather than as a coloured logo drop-in. */
.socials { margin-top: 1.1rem; }
.socials li { margin-bottom: .25rem; }
/* min-height 44px, not the 38px chip: the chip alone left a 34px tap target,
   under the 44px touch minimum. The link box carries the extra height so the
   target grows without inflating the mark itself. */
.social {
  display: inline-flex; align-items: center; gap: 11px;
  min-height: 44px; border-radius: 999px;
}
.social-chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; flex: 0 0 auto;
  border: 1px solid var(--line); border-radius: 50%;
  color: var(--ink); background: var(--white);
  transition: background .25s ease, color .25s ease,
              border-color .25s ease, transform .25s ease;
}
.social-chip svg {
  width: 18px; height: 18px;
  fill: none; stroke: currentColor; stroke-width: 1.6;
  stroke-linecap: round; stroke-linejoin: round;
}
.social-handle { font-size: var(--t-meta); color: var(--muted); }
.social:hover .social-chip,
.social:focus-visible .social-chip {
  background: var(--ink); border-color: var(--ink);
  color: var(--white); transform: translateY(-2px);
}
.social:hover .social-handle,
.social:focus-visible .social-handle { color: var(--ink); }
/* Keyboard focus needs its own signal — the chip fill above is identical to
   hover. Matches the gold ring used on .btn and .nav-toggle. */
.social:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.nav-lang:focus-visible { outline: 3px solid var(--gold); outline-offset: 3px; }
.partner a:focus-visible { outline: 3px solid var(--gold); outline-offset: 4px; }
.footer-bottom {
  border-top: 1px solid var(--line);
  padding-block: 24px;
  font-size: var(--t-meta);
  color: var(--muted);
  display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap;
}


/* ============================================================
   Scroll motion

   Client: "anade mas movimiento, las partes no tienen que moverse
   todas a la misma velocidad o direccion... que sea muy suave."

   So: several entrance variants that differ in direction, distance
   and duration, plus multi-speed parallax. Long durations and a
   gentle ease keep it calm rather than busy.

   Every variant is gated behind .js — without scripts nothing hides —
   and all of it is switched off under prefers-reduced-motion.
   ============================================================ */
:root {
  --ease-out-soft: cubic-bezier(.16, .84, .34, 1);
}

.js [data-anim] {
  opacity: 0;
  transition-property: opacity, transform, filter;
  transition-timing-function: var(--ease-out-soft);
  transition-duration: 1.15s;
  will-change: opacity, transform;
}
.js [data-anim].is-in { opacity: 1; transform: none; filter: none; }

/* --- direction + character variants --- */
.js [data-anim="up"]      { transform: translate3d(0, 46px, 0); }
.js [data-anim="up-far"]  { transform: translate3d(0, 82px, 0); transition-duration: 1.45s; }
.js [data-anim="left"]    { transform: translate3d(-56px, 14px, 0); transition-duration: 1.3s; }
.js [data-anim="right"]   { transform: translate3d(56px, 14px, 0);  transition-duration: 1.3s; }
.js [data-anim="scale"]   { transform: scale(.93) translate3d(0, 26px, 0); transition-duration: 1.35s; }
.js [data-anim="rise"]    { transform: translate3d(0, 30px, 0); transition-duration: .95s; }
.js [data-anim="blur"]    { transform: translate3d(0, 24px, 0); filter: blur(7px); transition-duration: 1.3s; }
.js [data-anim="fade"]    { transform: none; transition-duration: 1.5s; }

/* --- staggered children: alternate direction so a row assembles, not slides --- */
.js .stagger > * {
  opacity: 0;
  transition: opacity 1.05s var(--ease-out-soft), transform 1.05s var(--ease-out-soft);
}
.js .stagger > *:nth-child(odd)  { transform: translate3d(0, 44px, 0); }
.js .stagger > *:nth-child(even) { transform: translate3d(0, 68px, 0); }
.js .stagger.is-in > * { opacity: 1; transform: none; }
.js .stagger.is-in > *:nth-child(1) { transition-delay: 0s; }
.js .stagger.is-in > *:nth-child(2) { transition-delay: .13s; }
.js .stagger.is-in > *:nth-child(3) { transition-delay: .26s; }
.js .stagger.is-in > *:nth-child(4) { transition-delay: .39s; }
.js .stagger.is-in > *:nth-child(5) { transition-delay: .52s; }
.js .stagger.is-in > *:nth-child(6) { transition-delay: .65s; }

/* --- parallax: each element carries its own rate, set per element in JS --- */
[data-parallax] { transform: translate3d(0, var(--py, 0px), 0); will-change: transform; }
.hero-media img { transform: translate3d(0, var(--drift, 0px), 0) scale(1.08); }


/* ============================================================
   Reviews — large section, star ratings
   ============================================================ */
.reviews-section { padding-block: clamp(64px, 7vw, 104px); background: var(--soft); }

.reviews-head { text-align: center; max-width: 760px; margin: 0 auto clamp(40px, 5vw, 68px); }
.reviews-head h2 { margin-bottom: .6rem; }
.reviews-head p  { color: var(--muted); }

/* aggregate score block */
.rating-summary {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: center;
  gap: clamp(16px, 3vw, 40px);
  margin-top: clamp(24px, 3vw, 36px);
  padding: clamp(20px, 2.5vw, 30px) clamp(24px, 3vw, 40px);
  background: var(--white); border: 1px solid var(--line); border-radius: 22px;
}
.rating-score {
  font-family: var(--serif);
  font-size: clamp(2.6rem, 2rem + 2.4vw, 4rem);
  line-height: 1; color: var(--ink);
}
.rating-meta { text-align: left; }
.rating-meta p { margin: .35rem 0 0; font-size: var(--t-meta); color: var(--muted); }

/* stars */
/* Rounded-tip star (path lives in tools/reviews.py). Round joins stop the five
   points reading as clip-art at 19px, and the empty state is the same outline
   rather than a different shape, so a 4/5 row still scans as one set. */
.stars { display: inline-flex; gap: 3px; }
.stars svg {
  width: 19px; height: 19px;
  fill: var(--gold); stroke: var(--gold);
  stroke-width: .6; stroke-linejoin: round;
}
.stars svg.is-empty { fill: none; stroke-width: 1.5; opacity: .38; }
.stars-lg svg { width: 27px; height: 27px; }

/* ---------- marquee ----------
   Three rows drifting in alternating directions. Each track holds its cards
   twice and travels exactly -50%, so the second copy arrives where the first
   started and the loop has no visible seam.

   Full-bleed: the rows break out of .container so cards run off both edges
   rather than stopping at the text column. overflow:hidden on the row is what
   keeps that off the document's scroll width — without it audit3.py would
   (correctly) fail the page for horizontal scroll. */
.reviews-marquee {
  display: flex; flex-direction: column;
  gap: clamp(14px, 1.6vw, 22px);
  margin-top: clamp(34px, 4vw, 56px);
  /* Cards fade out at both edges instead of being chopped by a hard border. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
          mask-image: linear-gradient(to right, transparent, #000 7%, #000 93%, transparent);
}
.marquee-row { overflow: hidden; }
.marquee-track {
  display: flex; align-items: flex-start;
  gap: clamp(14px, 1.6vw, 22px);
  width: max-content;
  animation: marquee-left var(--dur, 80s) linear infinite;
}
.marquee-row[data-dir="right"] .marquee-track { animation-name: marquee-right; }

/* Rows start at different offsets so the columns never line up into a grid —
   the misalignment is the point. */
.marquee-row:nth-child(2) .marquee-track { margin-left: -7%; }
.marquee-row:nth-child(3) .marquee-track { margin-left: -3%; }

@keyframes marquee-left  { from { transform: translate3d(0,0,0); }
                           to   { transform: translate3d(-50%,0,0); } }
@keyframes marquee-right { from { transform: translate3d(-50%,0,0); }
                           to   { transform: translate3d(0,0,0); } }

/* Hovering anywhere in the band holds every row, so a quote can be read
   without chasing it across the screen. */
.reviews-marquee:hover .marquee-track,
.reviews-marquee:focus-within .marquee-track { animation-play-state: paused; }

/* cards — rectangular and flatter than the old grid tiles, with smaller type */
.review {
  flex: 0 0 auto;
  width: clamp(268px, 25vw, 340px);
  background: var(--white);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: clamp(18px, 1.7vw, 24px);
  display: flex; flex-direction: column; gap: .75rem;
  transition: border-color .35s var(--ease-out-soft), box-shadow .35s var(--ease-out-soft);
}
.review:hover { border-color: #D9D5C9; box-shadow: 0 14px 34px rgba(20,30,26,.09); }
.review blockquote {
  margin: 0; flex: 1;
  /* 15px floor: the client's original complaint was tiny text on mobile, and
     audit3.py fails anything under 15px. This is as small as it may go. */
  font-size: var(--t-meta);
  line-height: 1.55; color: var(--ink);
}
.review-author { display: flex; align-items: center; gap: 10px; margin-top: auto; padding-top: .35rem; }
.review-avatar {
  flex: 0 0 auto; width: 34px; height: 34px; border-radius: 50%;
  background: var(--ink); color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  /* 15px, not 14: the "nothing under 15px" floor is a client fix, and audit3.py
     enforces it on every text node — an avatar initial is no exception. */
  font-family: var(--sans); font-weight: 600; font-size: .9375rem;
}
.review-author > span:last-child { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.review-who   { display: block; font-weight: 600; color: var(--ink); font-size: var(--t-meta); line-height: 1.3; }
.review-where {
  display: flex; align-items: center; gap: 7px;
  font-size: var(--t-meta); color: var(--muted); line-height: 1.3;
}

/* ---------- reviews strip (Fase 3) ----------
   Replaces the auto-scrolling marquee with a calm, manually-scrolled row —
   the same idea the marquee's own reduced-motion fallback already used, now
   the default rather than an accessibility exception. All 20 reviews stay,
   just without the ticker, the card borders or the colour-circle avatars;
   the quote itself (set in serif) is what's meant to hold attention now. */
.reviews-strip { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: thin; margin-top: clamp(34px, 4vw, 56px); }
.reviews-strip-track { display: flex; gap: clamp(24px, 2.5vw, 40px); width: max-content; padding: 4px 4px 12px; }
.reviews-strip .review {
  width: clamp(260px, 23vw, 320px);
  background: none; border: none; border-radius: 0; padding: 0;
  transition: none;
}
.reviews-strip .review:hover { border-color: transparent; box-shadow: none; }
.reviews-strip .review blockquote {
  font-family: var(--serif); font-weight: 400;
  font-size: clamp(1.15rem, 1.02rem + .5vw, 1.45rem);
  line-height: 1.4; color: var(--ink);
}
/* The avatar initial was the most "generic UI" element on the page — the
   name and quote already identify who's speaking. */
.reviews-strip .review-avatar { display: none; }
.reviews-strip .review-author { margin-top: .9rem; padding-top: 0; }
/* Stars stay, muted and small — a quiet confirmation, not a second headline. */
.reviews-strip .stars { opacity: .55; margin-bottom: .3rem; }
.reviews-strip .stars svg { width: 13px; height: 13px; }

/* Reduced motion: no drifting. The band becomes a normal horizontally
   scrollable row so every review is still reachable — stopping the animation
   without this would strand most of them off-screen with no way to get there.
   The duplicate half is hidden so nothing reads twice. */
@media (prefers-reduced-motion: reduce) {
  .marquee-row { overflow-x: auto; scrollbar-width: thin; }
  .marquee-track { animation: none; margin-left: 0 !important; }
  .marquee-track .review[aria-hidden="true"] { display: none; }
  .reviews-marquee { -webkit-mask-image: none; mask-image: none; }
}

/* No scripting is fine — the marquee is pure CSS and needs no JS at all. */

/* Unfilled state. Deliberately unmistakable: a real review must never be
   confused with a slot waiting for one. */
.review.is-placeholder { border-style: dashed; background: transparent; }
.review.is-placeholder blockquote { color: var(--muted); }
.review.is-placeholder .review-avatar { background: var(--line); color: var(--muted); }
.review.is-placeholder .stars svg { fill: none; stroke: var(--gold); stroke-width: 1.4; opacity: .5; }
.review-pending {
  align-self: flex-start;
  font-size: var(--t-eyebrow); font-weight: 600; letter-spacing: .12em;
  text-transform: uppercase; color: var(--gold);
  border: 1px dashed var(--gold); border-radius: 999px; padding: .25em .8em;
}
.reviews-note {
  margin-top: clamp(28px, 3vw, 40px); text-align: center;
  font-size: var(--t-meta); color: var(--muted);
}

/* ============================================================
   Testimonials
   ============================================================ */
.testimonials { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(20px, 2.5vw, 30px); }
.testimonial {
  background: var(--white); border: 1px solid var(--line); border-radius: 22px;
  padding: clamp(26px, 3vw, 38px);
  display: flex; flex-direction: column; gap: 1rem;
}
.testimonial blockquote {
  margin: 0; font-family: var(--serif);
  font-size: clamp(1.1rem, 1rem + .5vw, 1.45rem);
  line-height: 1.35; color: var(--ink);
}
.testimonial figcaption { font-size: var(--t-meta); color: var(--muted); }
.testimonial cite { font-style: normal; font-weight: 600; color: var(--ink); display: block; }

/* Placeholder styling — deliberately obvious, so an unfilled quote can never be
   mistaken for a real one if this ships before the client supplies them. */
.testimonial.is-placeholder { border-style: dashed; background: var(--soft); }
.testimonial.is-placeholder blockquote { color: var(--muted); }
.placeholder-tag {
  align-self: flex-start;
  font-family: var(--sans); font-size: var(--t-eyebrow); font-weight: 600;
  letter-spacing: .12em; text-transform: uppercase; color: var(--gold);
  border: 1px dashed var(--gold); border-radius: 999px; padding: .25em .8em;
}

/* ============================================================
   Responsive
   ============================================================ */
@media (max-width: 1024px) {
  .cards        { grid-template-columns: 1fr; max-width: 620px; }
  .media-cards  { grid-template-columns: repeat(2, 1fr); }
  .steps        { grid-template-columns: repeat(2, 1fr); }
  .statements   { grid-template-columns: repeat(2, 1fr); }
  .testimonials { grid-template-columns: repeat(2, 1fr); }
  .features     { grid-template-columns: repeat(2, 1fr); }
  .footer-grid  { grid-template-columns: 1fr 1fr; }
  /* Single column now, so the vertical divider has nothing to sit between —
     a horizontal rule between stacked items reads the same way. Same
     specificity as the desktop rule (both :not(:first-child)), so this
     actually wins instead of losing silently to source order. */
  .cards-editorial .card { padding-inline: 0; }
  .cards-editorial .card:not(:first-child) { border-left: none; border-top: 1px solid var(--line); padding-top: clamp(24px, 3vw, 34px); }
}

@media (max-width: 860px) {
  /* A 56px horizontal slide is most of a phone's width — it reads as breakage
     and pushes content past the viewport edge before it settles. Below this
     breakpoint every entrance is vertical. */
  .js [data-anim="left"],
  .js [data-anim="right"] { transform: translate3d(0, 44px, 0); }

  /* --- Mobile menu: burger opens a CENTRED panel (client request:
         "me sale a la derecha, quiero que me salga en el medio") --- */
  .nav-toggle { display: inline-flex; }

  /* backdrop-filter would make the header the containing block for the
     position:fixed panel below, so the overlay would size itself to the
     header instead of the viewport. The header is near-opaque regardless. */
  .site-header { backdrop-filter: none; background: rgba(255,255,255,.98); }

  .main-nav {
    position: fixed; inset: 0;
    display: flex; flex-direction: column;
    align-items: center;          /* centred horizontally */
    justify-content: center;      /* centred vertically   */
    gap: clamp(18px, 4vh, 32px);
    background: rgba(255,255,255,.985);
    backdrop-filter: blur(10px);
    opacity: 0; visibility: hidden;
    transition: opacity .22s ease, visibility .22s ease;
    z-index: 90;
  }
  .main-nav .nav-link {
    font-family: var(--serif);
    font-size: clamp(1.75rem, 1.2rem + 3vw, 2.5rem);
    text-align: center;
    border-bottom: none;
  }
  .main-nav .nav-link[aria-current="page"] { color: var(--gold); }

  /* .main-nav .nav-link above (two classes) otherwise outranks the plain
     .nav-lang rule and inflates the EN chip to the same giant size as the
     other links, breaking its pill shape. Restore its compact chip size and
     guarantee a 44px tap target, matching .social/.coach-ig elsewhere. */
  .main-nav .nav-lang { font-size: var(--t-eyebrow); min-height: 44px; }

  /* Two buttons in one <p> rely on a text-node space for their gap on one
     line; once they wrap to separate lines on a narrow phone that space
     collapses and they end up touching. */
  .hero .btn { margin: 0 10px 12px 0; }

  body.nav-open .main-nav { opacity: 1; visibility: visible; }
  body.nav-open { overflow: hidden; }
  body.nav-open .nav-toggle span { background: transparent; }
  body.nav-open .nav-toggle span::before { top: 0; transform: rotate(45deg); }
  body.nav-open .nav-toggle span::after  { top: 0; transform: rotate(-45deg); }

  /* Both stay above the panel so the logo and the close control remain usable. */
  .nav-toggle { position: relative; z-index: 95; }
  .brand      { position: relative; z-index: 95; }

  .coach-grid   { grid-template-columns: 1fr; gap: 44px; }
  .coach-creds  { grid-template-columns: 1fr; gap: 14px; }
  .split        { grid-template-columns: 1fr; gap: 36px; }
  /* Sections alternate on desktop, so every other one puts .split-media first in
     the DOM to sit on the left. Stacked, that order puts a section's photos above
     its own heading — and two such sections back to back ran four images together
     with nothing between them, which is what the client flagged
     ("salen 4 imágenes seguidas, deberían ser máx 2"). Forcing the media after
     the copy gives text, 2 photos, text, 2 photos. */
  .split-media  { order: 2; }
  /* This section is the exception: client asked specifically for the big
     photo first and the copy underneath here, not the site-wide text-then-
     photo stacking order used elsewhere. Higher specificity than the rule
     above, so it wins without touching any other .split section. */
  .coaching-split .split-media { order: -1; }
  .contact-grid { grid-template-columns: 1fr; }
  .media-cards  { grid-template-columns: 1fr; max-width: 520px; }
  /* Single column, so the alternating stagger has nothing to alternate
     against — a leftover offset here just reads as a random gap. */
  .media-card:nth-child(2n) { margin-top: 0; }
  /* The alternating indent only works with room to spare either side;
     collapse to plain left alignment rather than cramping it. */
  .statement-block, .statement-block:nth-child(even) { align-self: flex-start; text-align: left; max-width: none; }
  .steps        { grid-template-columns: 1fr; gap: 30px; }
  .features     { grid-template-columns: 1fr; gap: 30px; }
  .statements   { grid-template-columns: 1fr; }
  .testimonials { grid-template-columns: 1fr; }
  .rating-summary { flex-direction: column; text-align: center; }
  .rating-meta { text-align: center; }

  /* --- No overlapping photographs on a phone.
         The inset comes out of absolute flow and sits beside the main image. --- */
  .split-media { display: grid; grid-template-columns: 1.5fr 1fr; gap: 12px; align-items: end; }
  .split-media .img-main { aspect-ratio: 3/4; }
  .split-media .img-inset {
    position: static;
    width: 100%; border-width: 0;
    box-shadow: none;
    aspect-ratio: 3/4;
  }

  .hero-card { max-width: none; }
  .band-card { margin-top: 24px; }
}

@media (max-width: 560px) {
  /* Sized for the stacked lockup, not the old monogram it replaced. */
  .header-inner { min-height: 78px; }
  .brand img    { height: 58px; }
  .cards, .media-cards { max-width: none; }
  .footer-grid  { grid-template-columns: 1fr; gap: 30px; }
  .footer-bottom { flex-direction: column; gap: 8px; }
  /* Both images stay on phones, stacked. They used to collapse to one here
     ("one strong image beats two cramped ones"), but that made the page show
     different photographs on desktop and mobile — which Riki spotted on
     2026-08-03. Consistency across devices matters more than the tighter crop:
     stacked full-width they are not cramped anyway. */
  .split-media  { grid-template-columns: 1fr; gap: 14px; }
  /* Stacked full-width, so there is no neighbour to line up with and no reason
     to force a shape. Letting the photo keep its own ratio means zero cropping —
     a fixed 4/3 here took 25% off a square photo's height, which is exactly
     where faces are. */
  .split-media .img-inset {
    aspect-ratio: auto;
    /* Safety floor only: with no aspect-ratio, a lazy-loaded image has zero
       intrinsic height until it decodes, so the box can collapse to 0px and
       punch a gap in the layout while it loads. min-height prevents that;
       once the real photo loads, its own (taller, uncropped) ratio still wins. */
    min-height: 58vw;
  }

  /* Slightly tighter vertical rhythm on small phones — the same clamp floors
     used from 768px up read as oversized white space on a 375–430px screen. */
  .section         { padding-block: clamp(40px, 11vw, 56px); }
  .section-tight   { padding-block: clamp(28px, 8vw, 40px); }
  .reviews-section { padding-block: clamp(48px, 12vw, 72px); }
  .partners        { padding-block: clamp(28px, 7vw, 40px); }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: .01ms !important; animation-duration: .01ms !important; }
  /* Never leave revealed content stuck at opacity 0 for these users. */
  [data-anim], .stagger > * { opacity: 1 !important; transform: none !important; filter: none !important; }
  [data-parallax] { transform: none !important; }
  .hero-media img { transform: none !important; }
  .float { animation: none !important; }
}
