/* ============================================================
   Hablemos Finanzen - the stylesheet.
   Palette hex values are fixed by the brand strategy.
   Contrast pairings are VERIFIED - run tools/contrast.py before changing any value.
   ============================================================ */

:root {
  /* Palette - exact values from the brand strategy, do not invent variants */
  --dark-red: #800400;  /* authority ground. carries cream/white text (9.84/10.85) */
  --red:      #d42f2e;  /* CTA only. carries WHITE only (4.95). cream FAILS (4.49) */
  --orange:   #ff914d;  /* warmth. carries INK only (5.91). white FAILS (2.23) */
  --yellow:   #fbbf46;  /* the goal. carries INK only (7.95). white FAILS (1.66) */
  --cream:    #f6f4ea;  /* default page ground. carries ink (11.97) */
  --ink:      #303030;  /* all body text */
  /* Type scale */
  --step--1: clamp(0.89rem, 0.85rem + 0.2vw, 1rem);
  --step-0:  clamp(1rem, 0.95rem + 0.25vw, 1.125rem);   /* body, >=16px always */
  --step-1:  clamp(1.33rem, 1.2rem + 0.6vw, 1.6rem);
  --step-2:  clamp(1.78rem, 1.5rem + 1.4vw, 2.6rem);
  --step-3:  clamp(2.37rem, 1.8rem + 2.8vw, 4.2rem);
  --step-4:  clamp(3.16rem, 2rem + 5.5vw, 7rem);        /* display + oversized figures */
  /* Vidaloka display floor - never below 28px (hairline Didone strokes break up smaller).
     Ceiling stays below --step-2 so anything using it reads as subordinate to a page h1/h2.
     Shared by .article h2 and .legal h2 - do not give either of them their own
     sub-28px clamp again, that defect has already been reintroduced once. */
  --step-1-display: clamp(1.75rem, 1.5rem + 0.8vw, 2.1rem);

  /* Spacing - 8px rhythm */
  --s1: 0.5rem; --s2: 1rem; --s3: 1.5rem; --s4: 2rem;
  --s5: 3rem;   --s6: 4rem; --s7: 6rem;   --s8: 8rem;

  --measure: 68ch;       /* desktop line length 60-75 */
  /* The gutter grows past 76rem viewport width so content never exceeds 68rem (1088px)
     and sits centered - without it every band starts at a 4rem gutter and the right
     half of a laptop screen is dead space. Colour grounds still bleed full-width
     because the cap lives in the padding, not in a wrapper.
     --gutter-min is the ungrown gutter: use it inside already-centered max-width
     boxes (.article, .legal), where the grown gutter would eat the text measure. */
  --gutter-min: clamp(1.25rem, 5vw, 4rem);
  --gutter: max(var(--gutter-min), calc((100vw - 68rem) / 2));
}

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

/* The nav scrolls to sections on this same page, so every landing point has to clear the
   sticky header. scroll-padding on the scroll container does it for every anchor at once -
   one line instead of a scroll-margin on each target. The value is the header's real height
   (var(--s3) padding x2 + the 3.25rem logo) plus a little air. Smooth scrolling is turned
   off again by the prefers-reduced-motion block below. */
html { scroll-padding-top: 7rem; scroll-behavior: smooth; }
@media (max-width: 860px) { html { scroll-padding-top: 5.5rem; } }

body {
  margin: 0;
  background: var(--cream);
  color: var(--ink);
  font-family: "Lato", system-ui, sans-serif;
  font-size: var(--step-0);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-family: "Vidaloka", Georgia, serif;  /* display ONLY - never below 28px */
  font-weight: 400;
  line-height: 1.05;
  letter-spacing: -0.01em;
}
h1 { font-size: var(--step-3); }
h2 { font-size: var(--step-2); }
/* --step-1-display, not --step-1: same 28px Vidaloka floor as .article h2 (see :root). */
h3 { font-size: var(--step-1-display); }

/* Anton: eyebrows, labels, oversized figures. NEVER paragraphs. */
.eyebrow {
  font-family: "Anton", Impact, sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  font-size: var(--step--1);
}
.figure {
  font-family: "Anton", Impact, sans-serif;
  font-size: var(--step-4);
  line-height: 0.85;
  font-feature-settings: "tnum";  /* tabular figures - no shift */
}

/* German financial terms in Spanish copy stay wrapped in <span class="de" lang="de">
   so screen readers switch pronunciation - but they render as plain text. German nouns
   are already capitalized, and the strategy reserves Anton for the logo, titles and
   figures. (An earlier Anton-uppercase + gold-underline inline treatment was not in the
   brand strategy and read as highlighter noise - removed on user call, 2026-07-15.) */

/* The surfaces nobody draws. Selection, the caret and the scrollbar ship with browser
   defaults that belong to no design system - a stock blue highlight is the loudest tell
   that a page was assembled rather than built. Yellow carries ink at 7.95, and because a
   selection paints its own ground it reads the same on cream, dark red and black. */
::selection { background: var(--yellow); color: var(--ink); }
/* Standard property only. The -webkit-scrollbar pseudo-elements would need a second, much
   longer implementation of the same two colours. */
html { scrollbar-color: rgba(48,48,48,0.4) transparent; }
.lead input, .lead textarea { caret-color: var(--red); }

/* Focus: visible, always. Never remove. */
:focus-visible { outline: 3px solid var(--red); outline-offset: 3px; }
/* --red measures 2.19 against --dark-red, under the 3.0 non-text floor - so on every dark
   band the ring was effectively invisible, including the header nav, which is the most-used
   keyboard path on the site. The stylesheet already records that same 2.19 for the button's
   border and solves it with cream; the ring never got the same treatment. Yellow clears both
   dark ground (6.53 on dark red) and stays off cream, where it is 1.51. */
.on-dark :focus-visible { outline-color: var(--yellow); }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* Self-hosted. NEVER load these from Google's CDN - see LG Muenchen I (2022). */
@font-face {
  font-family: "Vidaloka"; src: url("../fonts/vidaloka-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Anton"; src: url("../fonts/anton-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Lato"; src: url("../fonts/lato-400.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
}
@font-face {
  font-family: "Lato"; src: url("../fonts/lato-700.woff2") format("woff2");
  font-weight: 700; font-style: normal; font-display: swap;
}

/* ---------- shell ---------- */
.skip {
  position: absolute; left: -9999px;
  background: var(--ink); color: var(--cream); padding: var(--s2);
}
.skip:focus { left: var(--s2); top: var(--s2); z-index: 100; }

.on-dark { background: var(--dark-red); color: var(--cream); }

/* Sticky ("barra fija" - client, 2026-08-27). One page now, so the nav is the only way
   back out of a section; it has to stay reachable. sticky still establishes the containing
   block the mobile dropdown needs, so `relative` was not lost, it was upgraded. */
.site-header {
  position: sticky; top: 0; z-index: 30;
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s3) var(--gutter);
}
/* touch target floor (44px) on the hit area only - the logo itself stays 3.25rem/52px */
.site-header .brand {
  margin-right: auto;
  display: inline-flex; align-items: center; min-height: 44px;
}
/* logo.svg ships cropped to the wordmark (LOGO_VIEWBOX in tools/build-assets.py), so this
   height IS the wordmark height - not a box with invisible padding around it. The dark-red
   ground it keeps blends into the header. Box lands ~130x52. */
.site-header img { height: 3.25rem; width: auto; }
.site-header nav { display: flex; gap: var(--s3); }
.site-header a {
  color: var(--cream); text-decoration: none;
  display: inline-flex; align-items: center; min-height: 44px;   /* touch target floor */
}
.site-header a:hover { text-decoration: underline; text-underline-offset: 0.3em; }
.nav-toggle {
  display: none; min-height: 44px; min-width: 44px;   /* touch target floor */
  background: none; border: 1px solid var(--cream); color: var(--cream);
  font-family: "Anton", sans-serif; text-transform: uppercase; cursor: pointer;
}

/* ---------- hero: the frame runs full-bleed, the type sits on it ----------
   Two numbers drive this whole block, and both are read off the photograph rather
   than guessed: Natalia's outline starts at 31% of the frame's width, her face at
   37%. The frame is scaled to the hero's width, so those land at 31vw and 37vw at
   every viewport - which is why the caps below are derived from vw. Swapping the
   photograph invalidates them; re-measure before you do. */
.hero {
  position: relative; isolation: isolate; overflow: hidden;
  min-height: min(86vh, 820px);
  display: grid; align-items: end;
  /* --gutter-min, not --gutter: the grown gutter centres the reading bands at 68rem,
     which on a wide screen pushes this copy ~400px inward - straight into her. A
     full-bleed hero has no reason to obey it, so the type hangs at the viewport edge. */
  padding: var(--s6) var(--gutter) var(--s5) var(--gutter-min);
}
.hero__img {
  position: absolute; inset: 0;
  width: 100%; height: 100%; object-fit: cover; object-position: center 46%;
  /* No negative z-index: .on-dark's ground would paint over it. Instead .hero
     isolates, and paint order (image, scrim, then positioned text) does the work -
     which also leaves the dark-red ground as the fallback until the frame loads. */
}
/* Legibility scrim: dark-red, heaviest at the left where the type sits. Deliberately
   light - it only has to carry cream over a blurred tree, and a heavier one washed
   the frame out to a red haze, which is what made the old hero look cheap. */
.hero__scrim {
  position: absolute; inset: 0;
  background:
    linear-gradient(90deg, rgba(64,3,0,0.78) 0%, rgba(64,3,0,0.42) 26%, rgba(64,3,0,0) 52%),
    linear-gradient(0deg,  rgba(64,3,0,0.55) 0%, rgba(64,3,0,0.14) 38%, rgba(64,3,0,0) 60%);
}
.hero-text { position: relative; }        /* positioned, so it paints over the scrim */
.hero .eyebrow { color: var(--yellow); }
/* The headline is set as three written lines, so each has to fit as written. Measured
   as rendered, the longest ("no se improvisa.") is 6.85em - hence the 7em cap, in em
   so it tracks the headline rather than the body text. The hero also takes a steeper
   scale than --step-3: same 4.2rem ceiling, smaller start, because below ~1500px the
   site scale cannot fit 6.85em in the strip of frame left beside her. */
.hero h1 {
  font-size: clamp(2.37rem, 0.4rem + 3.5vw, 4.2rem);
  max-width: 7em; margin: var(--s2) 0 var(--s3);
}
.lede { font-size: var(--step-1); max-width: 40ch; }
/* The lede is the one block long enough to reach her face, so it is capped against
   that 37vw line and not by measure alone. */
.hero .lede {
  max-width: min(40ch, calc(37vw - 1.5rem - var(--gutter-min)));
  margin: 0 0 var(--s4);
}
/* The hero h1 carries the slogan; its closing verb takes the yellow "goal" accent.
   Yellow-on-cream measures 1.51:1, so it is scoped to .on-dark (the dark-red hero) only. */
.on-dark h1 .goal,
.on-dark h2 .goal { color: var(--yellow); }

/* CTA: red ground carries WHITE only. Cream fails at 4.49.
   .wa is the WhatsApp button; .cta is the same object pointing somewhere on this page.
   Two names because the destination differs, one treatment because the job is identical. */
.wa, .cta {
  display: inline-block; background: var(--red); color: #fff;
  font-family: "Anton", sans-serif; text-transform: uppercase;
  letter-spacing: 0.04em; text-decoration: none;
  padding: var(--s2) var(--s4); min-height: 44px;
  border: 2px solid transparent;
  transition: transform 180ms ease-out, background-color 180ms ease-out;
}
.wa:hover, .cta:hover { transform: translateY(-2px); background: #b82725; }
.wa:active, .cta:active { transform: translateY(0); }
/* On the dark-red ground the button's own edge measures 2.19:1 against it (non-text
   contrast needs 3.0) - the transparent border above was an unused hook for exactly this.
   Cream border on dark-red: 9.84:1. */
.on-dark .wa, .on-dark .cta { border-color: var(--cream); }

/* Below 1100px the strip of frame beside her is too narrow to hold the headline at any
   readable size, so the hero stops overlaying and stacks: the photo becomes a band and
   the type takes .on-dark's ground underneath it. The breakpoint is where the geometry
   runs out, which is why it is not the site's usual 860. */
@media (max-width: 1100px) {
  .hero { min-height: 0; padding: 46svh var(--gutter) var(--s5); }
  .hero__img { height: 46svh; bottom: auto; object-position: center 44%; }
  .hero__scrim { display: none; }
  /* The type no longer sits on the frame, so there is no face to stop short of. The
     37vw cap has to go with it - left on, it collapses the lede to ~100px on a phone. */
  .hero .lede { max-width: 40ch; }
}

@media (max-width: 860px) {
  .nav-toggle { display: block; }
  .site-header nav { display: none; }
  .site-header nav:not([hidden]) {
    display: flex; flex-direction: column;
    /* anchored to .site-header (position: relative above), not a hardcoded offset - the
       header's real height changes with its padding/logo/button, a fixed rem value would drift */
    position: absolute; top: 100%; left: 0; right: 0;
    background: var(--dark-red); padding: var(--s3) var(--gutter);
    /* Same rule as the footer's top border: the dropdown ground matches the hero
       ground, so without an edge it reads as links floating over the headline. */
    border-bottom: 1px solid rgba(246,244,234,0.2);
    z-index: 10;
  }
}

/* ---------- bands ---------- */
.band { padding: var(--s7) var(--gutter); }
.band > h2 { max-width: 20ch; margin: var(--s2) 0 var(--s4); }
.band .note { max-width: var(--measure); font-size: var(--step-1); }
.band .wa, .band .cta { margin-top: var(--s2); }

/* Oversized figures. Every one needs a .source next to it - no invented numbers. */
.figure-row {
  display: grid; gap: var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
  margin: var(--s5) 0;
}
.figure-row > div { border-top: 3px solid var(--red); padding-top: var(--s2); }
.figure-row .figure { color: var(--red); margin: 0 0 var(--s2); }
.figure-row p { max-width: 30ch; }
.source { font-size: var(--step--1); opacity: 0.7; margin-top: var(--s1); }
/* Same small-print link treatment as .reviews-score: the default blue is not in the palette. */
.source a { color: inherit; text-decoration-color: var(--orange); text-underline-offset: 0.2em; }

/* Process: numbered ONLY because these steps are a real sequence. */
/* padding: 0 como .articles y .qualifiers - sin el, el <ol> conserva sus 40px de sangria
   por defecto y la lista queda descuadrada respecto al h2 y al .note de su banda.
   Se notaba poco mientras no habia filetes; con los de .proceso salta a la vista. */
.process { counter-reset: step; display: grid; gap: var(--s4);
  margin-top: var(--s5); padding: 0; }
.process > li { counter-increment: step; list-style: none; display: grid;
  grid-template-columns: auto 1fr; gap: var(--s3); align-items: start; }
.process > li::before {
  content: counter(step, decimal-leading-zero);
  font-family: "Anton", sans-serif; font-size: var(--step-2);
  color: var(--yellow); line-height: 1;
}
.process p { margin: 0; max-width: var(--measure); }

/* #proceso - "Tu plan individual". Iba sobre --black; la clienta lo rechazo (2026-08-30)
   porque no combinaba con el resto del sitio, y era cierto: --black era un color inventado
   para este unico bloque. Ahora la banda es hueso y quien marca el modulo es la tipografia.
   Las cifras suben a --step-3 y se pintan en rojo - el idiom del "48 %". --red sobre hueso
   mide 4.49, solo apto para texto grande: --step-3 pisa 37.9px, muy por encima del limite,
   igual que lo esta .figure-row .figure.
   Comparte fondo con #servicios pero no se pega a el: entre los dos hay una fila de dos
   fotos que ya rompe la mancha, y de paso desaparece el roce rojo-negro-rojo con
   #para-quien que quedaba anotado en /variantes.
   Los filetes son los de .articles (1px tinta al 15 %), NO los 3px amarillos de
   .qualifiers: #para-quien viene justo despues y los dos bloques no pueden leerse igual -
   alli son cuatro condiciones en paralelo, aqui cuatro pasos en secuencia. */
.proceso .process { gap: 0; border-top: 1px solid rgba(48,48,48,0.15); }
.proceso .process > li {
  padding: var(--s3) 0; border-bottom: 1px solid rgba(48,48,48,0.15);
}
/* Ancho fijo, no `auto`: cada <li> es su propia rejilla, asi que con `auto` la columna la
   fija el ancho de SU cifra - y en Anton "01" es mas estrecho que "04", con lo que el texto
   arrancaba en una x distinta en cada paso. 1.1em sobre el propio tamano de la cifra cubre
   el avance de dos digitos (~0.96em) y escala con el clamp. */
.proceso .process > li::before {
  font-size: var(--step-3); color: var(--red); width: 1.1em;
}
/* A --step-3 la cifra se lleva ~65px de la columna izquierda: en un movil de 320px al
   texto le quedan 27ch, por debajo de lo legible. Debajo de 560px la cifra pasa a ser un
   rotulo sobre el paso, no una columna al lado. */
@media (max-width: 560px) {
  .proceso .process > li { grid-template-columns: 1fr; gap: var(--s1); }
}

/* Editorial article list - rules and type, no icon boxes. */
.articles {
  list-style: none; margin: var(--s5) 0 0; padding: 0;
  border-top: 1px solid rgba(48,48,48,0.15);
}
.articles li { border-bottom: 1px solid rgba(48,48,48,0.15); }
.articles a {
  display: block; padding: var(--s3) 0; text-decoration: none; color: inherit;
  min-height: 44px;
}
.articles .title {
  display: block; font-weight: 700; font-size: var(--step-1);
  max-width: 40ch; margin-bottom: var(--s1);
}
.articles .dek { display: block; font-size: var(--step--1); opacity: 0.7; max-width: 40ch; }
.more {
  display: inline-flex; align-items: center; min-height: 44px;   /* touch target floor */
  margin-top: var(--s4); color: var(--ink); font-weight: 700;
  text-decoration-color: var(--orange); text-underline-offset: 0.25em;
}

/* ---------- servicios: six areas as cards, each opening its .area block as a popup ----------
   Boxed, unlike the rest of the site - the client's own material presents these six as tiles.
   Kept to type and a rule: cream ground, ink border, no shadow, no icons. */
.services {
  list-style: none; padding: 0; margin: var(--s5) 0 0;
  display: grid; gap: var(--s3);
  /* 18rem lands on 3 columns at the 68rem measure (4 would need <16rem tracks), so the six
     cards read as the client's 3x2 slide, then 2 and 1 as the viewport narrows. */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 18rem), 1fr));
}
.service-card {
  position: relative; display: flex; flex-direction: column; gap: var(--s2);
  height: 100%; padding: var(--s3) var(--s3) var(--s5);
  align-items: center; text-align: center;
  border: 2px solid var(--ink); color: inherit; text-decoration: none;
  transition: background 0.2s ease-out;
}
/* currentColor by default; .services overrides it with the client's orange/red further
   down. Orange measures 2.02 on cream - decorative only, which is exactly what these are. */
.card-icon { width: 2.25rem; height: 2.25rem; flex: none; align-self: center; }
/* Anton, not Vidaloka: a card title lands under the 28px Vidaloka floor (see :root). */
.service-card .title {
  font-family: "Anton", Impact, sans-serif; text-transform: uppercase;
  letter-spacing: 0.04em; font-size: var(--step-1); line-height: 1.1;
}
.service-card .dek { font-size: var(--step--1); }
/* --step--1 lands at 14.4px on a phone. That is fine for a label and under the floor for
   three lines of body copy, which is what this is once the cards are one per row. */
@media (max-width: 560px) { .service-card .dek { font-size: var(--step-0); } }
/* "There is more behind this" affordance. Decorative, so a pseudo-element - never announced. */
.service-card::after {
  content: "+"; position: absolute; right: var(--s3); bottom: var(--s2);
  font-family: "Anton", Impact, sans-serif; font-size: var(--step-1);
  color: inherit; opacity: 0.55; line-height: 1;
}
/* An 8% wash of --dark-red over cream, replacing the ink invert the clients turned down
   (2026-08-27: "no les gusta el fondo oscuro"). The card stays light and the gesture is
   unchanged - only the value. Ink text on the washed ground measures 10.28, AAA. Alpha
   over cream rather than a new hex, the same technique as the hairlines. Elegida entre
   seis maquetas; las otras cinco vivian en /hover-models/, que se borro con la decision. */
.service-card:hover, .service-card:focus-visible { background: rgba(128, 4, 0, 0.08); }
@media (prefers-reduced-motion: reduce) { .service-card { transition: none; } }

/* Popup. Padding lives on .area so a click on the dialog element itself is unambiguously
   a backdrop click (see modal.js). */
.area-dialog {
  padding: 0; border: 2px solid var(--ink); background: var(--cream); color: var(--ink);
  width: min(38rem, calc(100vw - 2 * var(--s3)));
  max-width: none; max-height: min(84vh, 44rem);
}
.area-dialog[open] { display: flex; flex-direction: column; }
.area-dialog::backdrop { background: rgba(64, 3, 0, 0.72); }
.area-dialog .area { overflow-y: auto; padding: 0 var(--s4) var(--s4); }
.area-dialog h3 { margin: 0 0 var(--s3); }
.area-close {
  align-self: flex-end; flex: none; min-width: 44px; min-height: 44px;
  background: none; border: 0; color: var(--ink); cursor: pointer;
  font-size: var(--step-1); line-height: 1;
}
.area-close:hover { color: var(--red); }
/* Without JS the dialogs never exist and these are ordinary sections below the cards. */
.area { margin-top: var(--s5); }
.area h3 { margin: 0 0 var(--s2); }
.area p { margin: 0 0 var(--s3); max-width: var(--measure); }
.area p:last-child { margin-bottom: 0; }
/* showModal() makes the page inert, not unscrollable. */
.dialog-open { overflow: hidden; }
@media (max-width: 560px) {
  .area-dialog { width: calc(100vw - var(--s2)); max-height: 90vh; }
  .area-dialog .area { padding: 0 var(--s3) var(--s3); }
}

/* Qualifiers: the four conditions of "Este servicio es exclusivo para ti si:".
   A grid, not a list. They are not a sequence (no order to carry) and not an index of
   links, which is what the hairline .articles idiom they used to borrow announces - they
   are four conditions that hold at the same time, and a grid says "in parallel" where a
   stack says "one after another". Two columns at the measure, one on a phone.
   The rule above each is the same device as the "48 %" figures - which the client pointed
   at and called "este estilo". Note that #riesgo is hidden right now, so on the rendered
   page that precedent is carried only by .manifesto .claim; it comes back when the figures
   do. Yellow, because these sit on the dark red ground where --red measures 2.19.
   Two explicit columns, not auto-fit. Four items want 2x2; auto-fit gave three columns at
   1440 (a ragged 3+1) and, at a 26rem floor, dropped to one column for everything between
   700 and 940 - where a 34ch cap then held the text at ~490px and stranded up to 403px of
   empty red beside it, worse than the stack this replaced. A stated breakpoint says what
   the layout actually is and cannot surprise at either end. Below it, one column, and the
   track sets the measure so there is no cap left to strand anything. */
.qualifiers {
  list-style: none; margin: var(--s5) 0 0; padding: 0;
  display: grid; gap: var(--s5) var(--s4);
  grid-template-columns: 1fr;
}
@media (min-width: 44rem) { .qualifiers { grid-template-columns: 1fr 1fr; } }
.qualifiers > li {
  border-top: 3px solid var(--yellow); padding-top: var(--s2);
  /* body leading (1.6) at --step-1 is 41px, which exaggerates the height difference between
     a two-line and a four-line condition. The site steps type up but never steps leading
     down; at this size it should. balance evens the last lines - `pretty` is scoped to
     p/.lede/.note and never reached these. */
  font-size: var(--step-1); line-height: 1.35; text-wrap: balance;
}
/* The opening clause of each condition, so the eye has somewhere to land. These are the
   client's own words - the mark is typographic, nothing is reworded. */
.qualifiers strong { font-weight: 700; }
/* Without this the closing line sits a paragraph gap under the last condition and
   reads as part of it - most visible on a phone, where the grid is one column. */
.qualifiers + .note { margin-top: var(--s5); }

/* ---------- article ---------- */
.article { max-width: var(--measure); margin: 0 auto; padding: var(--s6) var(--gutter-min); }
.article h1 { margin-bottom: var(--s3); }
.article p { margin: 0 0 var(--s3); }
/* --step-1-display, not --step-1: --step-1's ceiling is 1.6rem = 25.6px, below Vidaloka's
   28px floor (see :root). */
.article h2 { font-size: var(--step-1-display); margin: var(--s5) 0 var(--s2); }
.article .lede { font-size: var(--step-1); }
.article-cta { margin-top: var(--s6); padding-top: var(--s4); border-top: 2px solid var(--ink); }

/* ---------- contenido: editorial index, rules and type only ---------- */
.article-index {
  list-style: none; margin: var(--s5) 0 0; padding: 0;
  border-top: 1px solid rgba(48,48,48,0.15);
}
.article-index li { border-bottom: 1px solid rgba(48,48,48,0.15); }
.article-index a { display: block; padding: var(--s5) 0; text-decoration: none; color: inherit; }
.article-index h2 { margin: var(--s1) 0 var(--s2); }
.article-index p { max-width: var(--measure); margin: 0; }

/* Internal review notes are NEVER visible page text (they look real and would ship) -
   they live in HTML comments carrying a [PLACEHOLDER] gate that check-site.py enforces.
   The old .notice callout existed only for such notes and was removed with them. */

/* ---------- contacto: the lead form, posting to Web3Forms (see index.html) ---------- */
/* Two-column form: short fields pair up, full-width ones and the button span both. */
.lead { margin: 0; display: grid; grid-template-columns: 1fr 1fr; gap: var(--s3); }
.lead .field { display: grid; gap: var(--s1); }
.lead .field--full { grid-column: 1 / -1; }
.lead label { font-weight: 700; }
.lead input, .lead textarea {
  min-height: 44px; padding: var(--s1) var(--s2); border: 2px solid var(--ink);
  background: var(--cream); color: var(--ink); font: inherit; width: 100%;
}
.lead textarea { min-height: 8rem; resize: vertical; }
.lead button {
  grid-column: 1 / -1; justify-self: start; min-height: 44px; padding: var(--s2) var(--s4);
  background: none; border: 2px solid var(--ink); color: var(--ink);
  font-family: "Anton", sans-serif; text-transform: uppercase; letter-spacing: 0.04em;
  cursor: pointer;
}
@media (max-width: 560px) { .lead { grid-template-columns: 1fr; } }
.lead button:hover { background: var(--ink); color: var(--cream); }
/* Consent gate. The label is the whole row so the text is part of the hit target, and the
   box has to opt out of the 44px/full-width sizing every other .lead input gets. Normal
   weight: .lead label is bold because it titles a field, and this one is a sentence. */
.lead .consent label { display: flex; gap: var(--s1); align-items: flex-start; font-weight: 400; }
.lead .consent input { width: auto; min-height: 0; margin-top: 0.25em; flex: none; }
/* Same link idiom as .legal and .more - the browser default blue is not in the palette. */
.lead .consent a { color: inherit; text-decoration-color: var(--orange); text-underline-offset: 0.25em; }
/* What form.js writes into after a submit. Spans both columns like .field--full; hidden
   until there is something to say. --dark-red on cream measures 9.84 (AAA) - --red would
   be 4.49, large-text-only, and this is body size. */
.form-status { grid-column: 1 / -1; margin: 0; font-weight: 700; }
.form-status.is-error { color: var(--dark-red); }

/* ---------- contact segment (home #contacto): walking photo + WhatsApp + form ---------- */
/* Photo fills the left column full-height (cover), WhatsApp + form fill the right - both
   sides stay full so a tall form never leaves dead cream beside a short photo. */
.contact-split {
  display: grid; grid-template-columns: 42fr 58fr; gap: var(--s5);
  align-items: stretch; margin-top: var(--s4);
}
/* absolute-fill so the photo always spans the stretched column height (a percentage-height
   chain silently fails when the ancestor height is grid-derived rather than declared). */
.contact-photo { position: relative; overflow: hidden; min-height: 22rem; }
/* .contact-split prefix raises specificity over the generic `.photo-frame img { height:auto }`
   defined later in the file, which otherwise wins the tie and collapses the fill. */
.contact-split .contact-photo img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.contact-body .wa { margin-top: var(--s2); }
.contact-form h3 { margin: 0 0 var(--s3); }
/* The form leads; WhatsApp is the alternative below it, separated by the same rule idiom
   as .article-cta. */
.contact-wa { margin-top: var(--s5); padding-top: var(--s4); border-top: 2px solid var(--ink); }
@media (max-width: 860px) {
  .contact-split { grid-template-columns: 1fr; gap: var(--s4); align-items: start; }
  /* stacked: portrait back in normal flow with a sane fixed ratio, not stretched */
  .contact-photo { min-height: 0; }
  .contact-split .contact-photo img { position: static; height: auto; aspect-ratio: 4 / 5; }
}

/* ---------- impressum / datenschutz: dense legal prose, same measure as .article ---------- */
.legal { max-width: var(--measure); margin: 0 auto; padding: var(--s6) var(--gutter-min); }
.legal h1 { margin-bottom: var(--s3); }
/* --step-1-display, not --step-1: same 28px Vidaloka floor as .article h2 (see :root). */
.legal h2 { font-size: var(--step-1-display); margin: var(--s5) 0 var(--s2); }
.legal p { margin: 0 0 var(--s3); }
/* Same link idiom as .more: ink text, orange underline - the default browser blue
   is the only unstyled colour that can appear on these pages. */
.legal a { color: inherit; text-decoration-color: var(--orange); text-underline-offset: 0.25em; }

/* ---------- motion: subtle, opt-out-safe ---------- */
/* Scroll-reveal. reveal.js adds .reveal-ready to <html> (only when JS runs AND motion is
   allowed), then toggles .is-visible per element via IntersectionObserver. Without JS, or
   under reduced motion, .reveal-ready is never set so the hidden state never applies and
   content is always shown. IntersectionObserver is chosen over CSS animation-timeline because
   the latter isn't supported in Firefox yet - this must work in every browser. */
@media (prefers-reduced-motion: no-preference) {
  /* 0.55s over 1rem on an exponential ease-out, not 0.8s over 2rem on ease-out. The long
     slow rise from far below is the stock scroll entrance; at this distance and curve the
     movement settles almost as the eye arrives and reads as the page catching up with the
     reader rather than as an effect being played at her. */
  .reveal-ready .reveal {
    opacity: 0; transform: translateY(1rem);
    transition: opacity 0.55s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.55s cubic-bezier(0.16, 1, 0.3, 1);
  }
  .reveal-ready .reveal.is-visible { opacity: 1; transform: none; }
}

/* Shared image-hover zoom: the frame clips, the image scales a touch. Only when motion is
   welcome. Used by the on-location photos. */
.photo-frame { overflow: hidden; margin: 0; }
.photo-frame img { display: block; width: 100%; height: auto; }
@media (prefers-reduced-motion: no-preference) {
  .photo-frame img { transition: transform 0.6s ease; }
  .photo-frame:hover img { transform: scale(1.04); }
}

/* ---------- brand band: full-bleed on-location photo, one line over it ---------- */
.brand-band {
  position: relative; overflow: hidden;
  min-height: min(78vh, 660px);
  display: grid; align-items: end;
  padding: var(--s7) var(--gutter);
}
.brand-band__img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
  /* bias low: the two of you stand in the lower half, so a top-weighted crop cut you off
     at the waist. 62% keeps faces + upper bodies framed and the cut below the hip. */
  object-position: center 62%;
}
/* Legibility scrim: dark-red, heavier on the left where the text sits (cream on the darkest
   stop clears AA). Uses the palette's authority colour, not a neutral black. */
.brand-band__scrim {
  position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(90deg,
    rgba(64,3,0,0.85) 0%, rgba(64,3,0,0.62) 40%, rgba(64,3,0,0.12) 100%);
}
.brand-band__text { color: var(--cream); max-width: 30ch; }
.brand-band__text .eyebrow { color: var(--yellow); }
.brand-band__text h2 { margin: var(--s2) 0 0; }
.brand-band__text p { margin: var(--s2) 0 0; font-size: var(--step-1); }
/* On a phone the frame crops to portrait, which pulls both of them into the text column -
   the 90deg left-weighted scrim above is built for a landscape crop and leaves the type on
   a white jacket and sunlit paving. Measured worst case behind the headline at 390px was
   1.25:1 against yellow and 1.88:1 against cream, both far under the 3.0 large-text floor.
   Below 860 the gradient turns bottom-up and heavier, which is where the type sits. Desktop
   is untouched: there the same measurement is 3.56 and 5.37, and the ranged-left treatment
   is the one the client asked to keep. */
@media (max-width: 860px) {
  .brand-band__scrim {
    background: linear-gradient(0deg,
      rgba(64,3,0,0.94) 0%, rgba(64,3,0,0.82) 42%, rgba(64,3,0,0.34) 100%);
  }
}

/* Slow Ken Burns, motion-gated. Scales within overflow:hidden so no layout shift. */
@media (prefers-reduced-motion: no-preference) {
  .brand-band__img { animation: kenburns 26s ease-in-out infinite alternate; }
}
@keyframes kenburns { from { transform: scale(1); } to { transform: scale(1.08); } }

/* ---------- band-split: photo beside a heading (asesoras intro) ---------- */
.band-split {
  display: grid; grid-template-columns: 38fr 62fr; gap: var(--s5);
  align-items: center; margin-bottom: var(--s6);
}
/* The bottom margin exists to separate the split from what follows inside the same band.
   When nothing follows, it is just a hole. */
.band-split:last-child { margin-bottom: 0; }
@media (max-width: 860px) {
  .band-split { grid-template-columns: 1fr; gap: var(--s3); }
}

/* "Online o en persona" is a part of the services module now, not a section of its own
   (client, 2026-08-27: dropping its eyebrow "kinda merges all as a Services module"). The
   child combinator keeps this off the six .area h3s nested deeper in the same section. The
   top margin does the work the band padding used to do when they were two sections. */
#servicios > h3 { margin: var(--s7) 0 var(--s2); text-wrap: balance; }

/* ---------- mode-photos: two on-location shots side by side (online / in person) ---------- */
/* A sangre (full-bleed): margin negativo del gutter para tocar los dos bordes de la
   pantalla, como .brand-band y el hero. Es lo que convierte estas dos fotos en una franja
   que corta la pagina, en vez de dos imagenes posadas sobre el hueso.
   Sin esto, #servicios (1711px) y #proceso (931px) suman 2642px de hueso seguidos - el
   doble que cualquier otro tramo de un mismo fondo en la pagina - y #proceso se lee como
   una tercera parte de #servicios en vez de como un bloque propio.
   gap: 0 a proposito: las dos fotos se tocan y leen como UNA franja. Con separacion
   vuelven a leerse como dos imagenes, que es justo lo que hay que evitar aqui. */
.mode-photos {
  display: grid; grid-template-columns: 1fr 1fr; gap: 0;
  margin-top: var(--s5); margin-inline: calc(var(--gutter) * -1);
}
/* the two sources differ slightly in ratio (16:9 online vs 3:2 office); a shared aspect-ratio
   box + object-fit cover keeps the pair the same height. 21:9 en vez de 3:2: a sangre, cada
   foto es el doble de ancha, y a 3:2 la franja se comia ~700px de alto. */
.mode-photos .photo-frame img { aspect-ratio: 21 / 9; object-fit: cover; }
/* Apiladas, cada foto ocupa el ancho entero, asi que 21:9 recortaria las caras. 16:9 las
   deja respirar y las dos juntas siguen cabiendo en una pantalla de movil. */
@media (max-width: 860px) {
  .mode-photos { grid-template-columns: 1fr; }
  .mode-photos .photo-frame img { aspect-ratio: 16 / 9; }
}

/* ---------- reviews: real ProvenExpert quotes, editorial not carded ---------- */
.reviews-score { font-size: var(--step--1); opacity: 0.85; margin: 0 0 var(--s4); max-width: var(--measure); }
.reviews-score a { color: inherit; text-decoration-color: var(--orange); text-underline-offset: 0.2em; }

/* Marquee: two identical tracks sit side by side in a flex row; both translate -100% of
   their own width in sync, so when track 1 scrolls off the left, track 2 is exactly where
   it started - a seamless loop with no seam arithmetic. Spacing lives on .review's right
   margin (not a flex gap) so the wrap-around gap matches the inter-item gap. */
.marquee {
  display: flex; overflow: hidden;
  /* full-bleed: cancel the band's side padding so quotes scroll edge to edge */
  margin: 0 calc(-1 * var(--gutter));
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
          mask-image: linear-gradient(90deg, transparent, #000 6%, #000 94%, transparent);
}
.marquee-track {
  display: flex; flex: 0 0 auto; margin: 0; padding: 0; list-style: none;
  animation: marquee-scroll 70s linear infinite;
}
.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track { animation-play-state: paused; }
@keyframes marquee-scroll { to { transform: translateX(-100%); } }

.review {
  flex: 0 0 auto; width: 32ch; margin-right: var(--s5);
  border-top: 3px solid var(--orange); padding-top: var(--s2);
}
.review:first-child { margin-left: var(--gutter); }  /* first quote clears the mask edge */
.review blockquote { margin: 0 0 var(--s2); font-size: var(--step-0); }
.review cite { font-style: normal; font-size: var(--step--1); opacity: 0.7; }
.review cite b {
  font-family: "Anton", Impact, sans-serif; font-weight: 400;
  text-transform: uppercase; letter-spacing: 0.04em; opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  /* no motion: one track only, swipe/scroll horizontally instead. !important beats the
     global reduced-motion animation-duration override, which would otherwise snap the
     track to its -100% end state and hide it. */
  .marquee { overflow-x: auto; margin: 0 calc(-1 * var(--gutter)); -webkit-mask-image: none; mask-image: none; }
  .marquee-track { animation: none !important; transform: none !important; }
  .marquee-track[aria-hidden="true"] { display: none; }
  .review:first-child { margin-left: var(--gutter); }
}

/* ---------- footer: slim - brand left, one row of links right ---------- */
.site-footer {
  display: flex; justify-content: space-between; align-items: center;
  flex-wrap: wrap; gap: var(--s1) var(--s4);
  padding: var(--s4) var(--gutter);
  border-top: 1px solid rgba(246,244,234,0.2);
  font-size: var(--step--1);
}
.site-footer .footer-brand { font-weight: 700; font-size: var(--step-0); margin: 0; }
.footer-nav { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s1) var(--s4); }
.footer-nav a, .footer-copy {
  color: var(--cream);
  display: inline-flex; align-items: center; min-height: 44px;   /* touch target floor */
}
.footer-copy { opacity: 0.7; }
.footer-ig { min-width: 44px; justify-content: center; }
.footer-ig svg { width: 20px; height: 20px; }

/* ============================================================
   Polish pass (2026-07-30): typography, view transitions,
   hyphenation, drawn underline. No JS, no third-party.
   ============================================================ */

/* Balance headlines (no orphan words); let paragraphs avoid runt last lines.
   Unsupported browsers fall back to normal wrapping. */
h1, h2 { text-wrap: balance; }
p, .lede, .note { text-wrap: pretty; }

/* Hyphenate the narrow-measure columns so long Spanish/German words don't rag.
   lang is set on <html lang="es"> and on .de spans, so dictionaries resolve.
   :not(.eyebrow) porque la linea de creditos de cada asesora tambien es un <p> dentro de
   .team, y ahi partia "SENIOR CONSUL-TANT". Un cargo no se parte: es un nombre, no prosa.
   Sin guion la linea rompe por el espacio y sigue cayendo en dos lineas igual. */
.figure-row p, .review blockquote, .team p:not(.eyebrow) { hyphens: auto; }

/* Cross-document view transitions: content crossfades on navigation; the header
   and footer are named so they persist (do not fade) across the transition.
   Chrome/Safari honor this; Firefox ignores it and navigates normally. */
@view-transition { navigation: auto; }

/* Motion opt-out: disable the crossfade under reduced-motion (web.dev pattern). */
@media (prefers-reduced-motion: reduce) {
  @view-transition { navigation: none; }
}

.site-header { view-transition-name: site-header; }
.site-footer { view-transition-name: site-footer; }

/* Drawn underline: a gradient "rule" under editorial link titles that grows
   left-to-right on hover/focus, instead of snapping on. Orange, 2px. */
.articles .title, .article-index a h2 {
  background-image: linear-gradient(var(--orange), var(--orange));
  background-repeat: no-repeat;
  background-position: 0 100%;
  background-size: 0% 2px;
  transition: background-size 220ms ease;
}
.articles a:hover .title, .articles a:focus-visible .title,
.article-index a:hover h2, .article-index a:focus-visible h2 {
  background-size: 100% 2px;
}
@media (prefers-reduced-motion: reduce) {
  .articles .title, .article-index a h2 { transition: none; }
}

/* Staggered reveal: for these containers, the container itself does not fade;
   its direct children rise in sequence. Cancels the generic container hide from
   the ".reveal-ready .reveal" rule above for exactly these selectors. Motion-gated. */
@media (prefers-reduced-motion: no-preference) {
  .reveal-ready .figure-row.reveal,
  .reveal-ready .process.reveal,
  .reveal-ready .articles.reveal { opacity: 1; transform: none; }

  .reveal-ready .figure-row.reveal > *,
  .reveal-ready .process.reveal > li,
  .reveal-ready .articles.reveal > li {
    opacity: 0; transform: translateY(0.75rem);
    transition: opacity 0.5s cubic-bezier(0.16, 1, 0.3, 1),
                transform 0.5s cubic-bezier(0.16, 1, 0.3, 1);
  }
  .reveal-ready .figure-row.reveal.is-visible > *,
  .reveal-ready .process.reveal.is-visible > li,
  .reveal-ready .articles.reveal.is-visible > li { opacity: 1; transform: none; }

  /* Per-position delay. Containers here hold 2-5 children; cap at 320ms. */
  .reveal-ready .reveal.is-visible > *:nth-child(2) { transition-delay: 80ms; }
  .reveal-ready .reveal.is-visible > *:nth-child(3) { transition-delay: 160ms; }
  .reveal-ready .reveal.is-visible > *:nth-child(4) { transition-delay: 240ms; }
  .reveal-ready .reveal.is-visible > *:nth-child(5) { transition-delay: 320ms; }
}

/* ============================================================
   Landing page (2026-08-27): the site collapsed from five pages into one, so the
   grounds now have to do the work the page boundaries used to do. Cream is the
   reading ground and --dark-red marks the moments that carry weight (film, riesgo,
   para-quien, resenas). No two reading bands of the same ground ever touch - the photo
   bands break the runs, and #servicios -> #proceso, the one place two cream bands meet,
   is cut by the full-bleed two-photo stripe that closes #servicios (see .mode-photos).
   Hubo un tercer fondo, --black, para #proceso; la clienta lo rechazo (no combinaba) y se
   retiro con /beta y /variantes. La paleta de fondos es hueso, --dark-red y foto.
   ============================================================ */

/* Grounds swapped under blocks that were built for cream. Each of these is a colour
   swap only - no geometry changes, so the block reads identically on either ground. */
/* Oversized figures: --red is the accent on cream (4.49, large-text) but only 2.19 on
   dark red. Yellow measures 6.53 there, so the ground swap takes the accent with it. */
.on-dark .figure-row > div { border-top-color: var(--yellow); }
.on-dark .figure-row .figure { color: var(--yellow); }
/* Hairline rules are ink-tinted by default and vanish on a dark ground. */
.on-dark .articles,
.on-dark .articles li { border-color: rgba(246,244,234,0.25); }

/* ---------- manifiesto: the opening block, centred, no photo ----------
   The client pointed at the "48 %" card and wrote "este estilo!" - that card is a red
   rule over the type and nothing else. Here the rule sits over the closing claim, which
   is the line she wants set "tipo titulo, un poco mas grande" than an .eyebrow. */
.manifesto { text-align: center; }
.manifesto > .eyebrow { margin: 0 auto var(--s3); }
.manifesto > h2 { max-width: 24ch; margin: 0 auto var(--s4); }
.manifesto > p { max-width: 62ch; margin-inline: auto; }
/* Wider than the generic .lede's 40ch: centred, a 40ch column in the middle of a full
   band is what made this block read as empty. */
.manifesto > .lede { max-width: 56ch; }
/* This is the "mismo estilo que el 48%" the client asked for, transplanted from a number
   onto a sentence: red hairline, oversized Anton, red fill, short measure. --red on cream
   is 4.49 - AA for large text only, which is why it is only ever used at display size,
   exactly as .figure-row .figure already uses it. --step-2 floors at 28.5px; a 68-character
   sentence cannot take .figure's --step-4 without becoming a tower - and 34ch is the measure
   that lands it on four lines instead of six. */
/* On the red ground the whole 48% idiom has to change hand: --red measures 2.19 on
   --dark-red, so both the rule and the fill go yellow (6.53, AA). Scoped to .on-dark so
   the cream version keeps the red the client actually pointed at. */
.manifesto.on-dark .claim { color: var(--yellow); border-top-color: var(--yellow); }
.manifesto.on-dark .eyebrow { color: var(--yellow); }

/* line-height 1.15, not the 1.05 the headings use: this line is set in Anton and forced
   to uppercase, and Anton's accented capitals are drawn far above its cap height - the
   tilde of N-tilde reaches 1.07em over the baseline and the acute of I/U/A 1.10em, while a
   flat cap stops at 0.86em. At 1.05 the accent therefore lands INSIDE the line above: on a
   phone the sentence wraps to three lines and the tilde of ACOMPANARTE touched the letters
   of ESTAMOS (reported 2026-09-02). 1.15 is the tightest value that clears every accented
   capital in the face, and it is still far tighter than the 1.6 body default. Do not lower
   it back to match the headings - Vidaloka's accents only reach 0.90em, so 1.05 is safe
   there and is not safe here. */
.manifesto .claim {
  font-family: "Anton", Impact, sans-serif;
  text-transform: uppercase; letter-spacing: 0.01em;
  font-size: var(--step-2); line-height: 1.15; color: var(--red);
  max-width: 34ch; margin: var(--s6) auto var(--s5);
  border-top: 3px solid var(--red); padding-top: var(--s3);
}

/* The client's docx asked for this block's type centred; centred on this frame it lands on
   the two of them, so it moved above their heads. Reverted on 2026-08-27 to the ranged-left
   treatment main still carries - "as it was" - which is the base .brand-band, so the whole
   --center modifier goes rather than being overridden. What does NOT revert: the eyebrow
   stays deleted and the body line stays rewritten, both explicit client edits nobody asked
   to undo. The yellow headline is the third of those edits, so it needs its own rule now
   that it is no longer riding on the modifier. Yellow on the scrim's darkest stop clears AA
   (6.53 against --dark-red, and every stop here is darker). Never on cream: 1.51. */
.brand-band__text h2 { color: var(--yellow); }

/* ---------- service card icons: the client's "naranja y rojo" ----------
   .card-icon is normally currentColor. These six are aria-hidden and every card repeats
   its label as text, so the mark is pure decoration - which is exactly the case WCAG
   1.4.11 exempts from the 3:1 non-text floor (orange measures 2.02 on cream). Alternating
   the two gives the grid the two-colour rhythm she asked for without adding a third idea. */
.services .card-icon { color: var(--orange); }
.services > li:nth-child(2n) .card-icon { color: var(--red); }

/* ---------- team: the two asesoras, as type ----------
   Same rule-over-type idiom as .bio, which is what nosotras.html used - but no portrait.
   The studio cut-outs carry their own white ground and show their box on cream, which is
   why they left the home page in the first place; folding that page in is no reason to
   bring them back. h3, not h2: these sit under the section's own h2, and --step-1-display
   keeps them above Vidaloka's 28px floor. */
.team {
  list-style: none; margin: var(--s6) 0 0; padding: 0;
  display: grid; gap: var(--s5);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr));
}
.team > li { border-top: 3px solid var(--orange); padding-top: var(--s2); }
.team h3 { margin: 0 0 var(--s1); }
.team .eyebrow { margin: 0 0 var(--s3); }
/* El tope va en TODOS los parrafos, no solo en el ultimo. Con una sola frase por asesora
   daba igual - era el ultimo y el unico. Con las biografias completas, dejarlo solo en el
   ultimo daba dos parrafos a lo ancho de la columna (~64ch) y el tercero a 40ch, con el
   borde derecho saltando. */
.team p:not(.eyebrow) { max-width: 40ch; }
.team p:last-child { margin-bottom: 0; }
/* La credencial, siempre en su propio renglon y en las dos. Dejandolo al ancho no casan:
   "Co-Fundadora" es tres caracteres mas larga que "Fundadora", asi que la linea de Luciana
   rompia una palabra antes que la de Natalia. Aqui el salto es del marcado, no del ancho,
   y las dos leen igual: cargo arriba, certificacion debajo. */
.team .eyebrow .cert { display: block; }

/* ---------- sticky header on small screens ----------
   A 6.25rem bar pinned to the top of a phone eats a tenth of the viewport for the whole
   scroll. Below 860 the logo and the padding both come down, to ~4.4rem. */
@media (max-width: 860px) {
  .site-header { padding: var(--s2) var(--gutter); }
  .site-header img { height: 2.5rem; }
}
