/* ==========================================================================
   Catalystica — base layer (sistema)
   Tokens, the two type voices and the readable no-JS layout for every section.
   Enhanced, section-specific rules live in fx/<id>.css and are gated by
   html.fx-<id> / html.has-<id>, so a failed or reduced feature always falls
   back to what is written here.
   ========================================================================== */

@font-face {
  font-family: "Geist";
  /* Self-hosted, like every script: the site loads nothing from third-party origins. */
  src: url("/fonts/Geist-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

/* Weight is energy: 100 latent, 900 reacted. No-JS and reduced motion stay at 900. */
@property --w {
  syntax: "<number>";
  inherits: true;
  initial-value: 900;
}

:root {
  /* Palette: three colours and their alphas, nothing else. */
  --blue: #5472FB;
  --ink: #0C1821;
  --white: #FFFFFF;
  --fg2-ink: rgba(255, 255, 255, 0.64);   /* secondary text on ink, ~7.7:1 */
  --fg2-white: rgba(12, 24, 33, 0.72);    /* secondary text on white, ~7.3:1 */
  --rule-ink: rgba(255, 255, 255, 0.18);
  --band-fg: rgba(255, 255, 255, 0.72);

  /* Motion law: react / settle / leave on a 0.15s pulse. */
  --ease-react: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-settle: cubic-bezier(0.65, 0, 0.35, 1);
  --ease-leave: cubic-bezier(0.7, 0, 0.84, 0);
  --t-micro: 0.3s;
  --t-short: 0.6s;
  --t-base: 0.9s;
  --t-long: 1.2s;

  /* Z-index map. Sections are stacking contexts; hero and closing are not. */
  --z-ignite: 1;
  --z-flood-hero: 15;
  --z-reaction: 20;
  --z-words: 30;
  --z-ecuador: 32;
  --z-flood-words: 35;            /* the Ecuador coda's flood into the silence */
  --z-silent: 40;
  --z-flood-silent: 45;
  --z-ribbon: 50;
  --z-catalyst: 70;
  --z-text: 75;
  --z-cursor: 95;

  /* Layout */
  --gutter: clamp(20px, 4.5vw, 64px);
  --dock-col: minmax(56px, 8vw);
  --s-1: 8px;
  --s-2: 16px;
  --s-3: 24px;
  --s-4: 40px;
  --s-5: 64px;
  --s-6: 104px;
  --s-7: 168px;

  /* Text voice */
  --text-size: clamp(17px, 1.35vw, 19px);
  --latent: 100;

  /* Catalyst bookend box (hero .mark-wrap, closing .closing-mark). Sized by width,
     capped by height so the mark never runs into the ink band on short screens. */
  --vh-s: 100vh;
  --band-h: 58px;                                  /* .closing-bar: 20 + 15px*1.2 + 20 */
  --mark-top: clamp(72px, 8.5vw, 120px);
  --mark-w0: clamp(200px, 32vw, 460px);            /* width-only size */
  --mark-w: min(var(--mark-w0), calc(var(--vh-s) - var(--mark-top) - var(--band-h) - env(safe-area-inset-bottom, 0px) - 24px));
}

@supports (height: 100svh) { :root { --vh-s: 100svh; } }

@media (max-width: 719px) {
  /* The band wraps to two rows here. */
  :root { --latent: 200; --band-h: 86px; --mark-top: 76px; --mark-w0: 56vw; }
}

* { box-sizing: border-box; margin: 0; padding: 0; }

/* A stable gutter: ignition and Lenis's stopped state hide the scrollbar, and its
   return must not shift the hero and the catalyst sideways mid-glide. The gutter is
   ink with a white-alpha thumb, so classic (Windows) scrollbars stay in the palette and
   the bled hero / closing mark meets an ink edge, never a light grey track. */
html {
  -webkit-text-size-adjust: 100%;
  scrollbar-gutter: stable;
  color-scheme: dark;
  scrollbar-color: rgba(255, 255, 255, 0.28) var(--ink);
}

body {
  font-family: "Geist", system-ui, -apple-system, sans-serif;
  font-synthesis: none;
  font-weight: 500;
  background: var(--blue);
  color: var(--ink);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}

a { color: inherit; }

:where(a, button):focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 4px;
  border-radius: 2px;
}

/* Surfaces. Every surface element carries data-surface. */
[data-surface="blue"] { background: var(--blue); color: var(--ink); }
[data-surface="ink"] { background: var(--ink); color: var(--white); }
[data-surface="white"] { background: var(--white); color: var(--ink); }

[data-surface="blue"] ::selection,
[data-surface="white"] ::selection { background: var(--ink); color: var(--white); }
[data-surface="ink"] ::selection { background: var(--white); color: var(--ink); }

/* Enhancement-only layers never show without their feature. */
.cursor,
.catalyst,
.flood,
.ignite { display: none; }

/* ---------- Two voices ---------- */
/* DISPLAY: Geist on the weight axis, tight tracking, stems on the gutter. */
.hero h1,
.reaction .state,
.row-word,
.ecuador-hoy h2,
.eh-num,
.silent h2,
.closing h2 {
  font-weight: var(--w, 900);
  line-height: 0.94;
  letter-spacing: -0.045em;
  margin-inline-start: -0.045em;
}

/* Geist failed to load (html.no-geist, set by main.js): the system fallback is wider
   and taller, so the tracking and leading tuned for Geist are relaxed. */
.no-geist :is(.hero h1, .reaction .state, .row-word, .ecuador-hoy h2, .eh-num, .silent h2, .closing h2) {
  letter-spacing: -0.02em;
  line-height: 1.04;
  margin-inline-start: -0.02em;
}

/* Its glyphs are also wider: the hero steps down a size and gets a wider measure so
   the definition keeps its four lines inside the first screen, and the closing line
   breaks in balanced pairs instead of stranding 'mejor'. */
.no-geist .hero h1 {
  font-size: clamp(48px, min(7.8vw, 11vh), 112px);
  font-size: clamp(48px, min(7.8vw, 11svh), 112px);
  max-width: 13ch;
}
.no-geist .closing h2 {
  max-width: 14ch;
  text-wrap: balance;
}

/* TEXT: Geist 500, one size, one measure. */
.row-note,
.words-coda,
.eh-intro,
.eh-label,
.eh-more,
.ecuador-coda,
.silent-note,
.r-status {
  font-weight: 500;
  font-size: var(--text-size);
  line-height: 1.45;
  letter-spacing: -0.01em;
  max-width: 34ch;
  text-wrap: pretty;
}

/* ---------- 01 Hero ---------- */
.hero {
  position: relative;
  z-index: auto;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: clamp(24px, 3vw, 40px) var(--gutter) clamp(40px, 5vw, 72px);
  overflow: hidden;
}

@supports (min-height: 100svh) {
  .hero { min-height: 100svh; }
}

.nav {
  position: relative;
  z-index: var(--z-text);
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  font-weight: 700;
  font-size: 19px;
  letter-spacing: -0.02em;
  text-decoration: none;
}

.brand svg { width: 24px; height: 24px; fill: none; stroke: var(--ink); stroke-width: 8; }

.nav-meta { font-weight: 700; font-size: 19px; letter-spacing: -0.01em; }

/* The nav link to /ecuador: one underline geometry on every page (colour follows the surface). */
a.nav-meta { text-decoration-thickness: 2px; text-underline-offset: 6px; }

/* Static fallback and pose anchor for the catalyst. */
.mark-wrap {
  position: absolute;
  z-index: 0;
  top: var(--mark-top);
  /* Uncapped this is clamp(-120px, -8vw, -40px); a cap keeps ~75% of the mark on screen. */
  right: calc(clamp(-120px, -8vw, -40px) + (var(--mark-w0) - var(--mark-w)) / 4);
  width: var(--mark-w);
  pointer-events: none;
}

.mark { display: block; width: 100%; height: auto; fill: var(--white); overflow: visible; }

.mark-rest {
  transform-box: view-box;
  transform-origin: 50% 50%;
  transform: rotate(-10deg);
}

.definition {
  position: relative;
  z-index: var(--z-text);
  display: flex;
  flex-direction: column;
  gap: clamp(16px, 2vw, 28px);
  /* Sized by width, capped by height: on short laptops and phones the whole
     definition (and its mark-shaped full stop) stays in the first screen. */
  padding-top: min(clamp(120px, 18vw, 200px), max(64px, 16vh));
  padding-top: min(clamp(120px, 18vw, 200px), max(64px, 16svh));
}

.phonetic {
  font-weight: 700;
  font-size: clamp(19px, 1.6vw, 22px);
  letter-spacing: -0.01em;
}

.hero h1 {
  font-size: clamp(52px, min(9.2vw, 13.5vh), 132px);
  font-size: clamp(52px, min(9.2vw, 13.5svh), 132px);
  max-width: 12.5ch;
  text-wrap: balance;
}

/* Desktop and tablet: the four lines are locked in the markup. Balance alone is not
   enough once the words are split into inline-blocks (Firefox then wraps greedily and
   moves 'antes,' under the ignition point). Phones keep the inline flow. */
@media (min-width: 720px) { .hero h1 .ln { display: block; } }

@media (max-width: 608px) { .hero h1 { letter-spacing: -0.03em; } }

/* Narrow phones (<= 360px wide): the 52px floor wraps to 8 lines, cuts the last one on
   short screens and starts the definition above the ignition point (mid-viewport) on
   taller ones. A 40-52px floor keeps it to ~5 lines that start below the centre. */
@media (max-width: 360px) {
  .hero h1 {
    font-size: clamp(40px, min(12.5vw, 7.6vh), 52px);
    font-size: clamp(40px, min(12.5vw, 7.6svh), 52px);
  }
}
@media (min-width: 1304px) { .hero h1 { letter-spacing: -0.055em; } }

/* ---------- 02 Reaction (no-JS: three lines stacked on ink) ---------- */
.reaction {
  position: relative;
  z-index: var(--z-reaction);
  background: var(--ink);
  color: var(--white);
}

.reaction-pin {
  position: relative;
  padding: clamp(96px, 12vw, 160px) var(--gutter);
}

.reaction-canvas { display: none; }

.reaction-copy {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

.reaction .state {
  font-size: clamp(34px, 5.4vw, 80px);
  line-height: 0.96;
  letter-spacing: -0.03em;
  max-width: 16ch;
  text-wrap: balance;
}

@media (min-width: 1037px) { .reaction .state { letter-spacing: -0.045em; } }

.reaction .is-accent { color: var(--blue); }

/* ---------- 03 Words ---------- */
.words {
  position: relative;
  z-index: var(--z-words);
  background: var(--ink);
  color: var(--white);
  padding: clamp(40px, 6vw, 80px) var(--gutter) clamp(96px, 11vw, 160px);
  overflow-x: clip;
}

.row {
  position: relative;
  display: grid;
  grid-template-columns: var(--dock-col) 1fr;
  align-items: baseline;
  column-gap: var(--s-3);
  row-gap: var(--s-1);
  padding: clamp(12px, 1.5vw, 20px) 0;
}

.row::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 1px;
  background: var(--rule-ink);
  transform-origin: left;
  transform: scaleX(var(--line, 1));
}

.row-word,
.row-note { grid-column: 2; }

.row-word {
  display: block;
  font-size: clamp(56px, 9vw, 140px);
  line-height: 1;
  padding-bottom: 0.06em;
}

@media (min-width: 1334px) { .row-word { letter-spacing: -0.055em; } }

.row-word > span { display: inline-block; }

.row-word.is-accent { color: var(--blue); }

.row-note { color: var(--fg2-ink); }

.words-coda {
  margin-top: clamp(56px, 6vw, 96px);
  margin-left: 0;
  color: var(--fg2-ink);
}

/* Without the crossing (no JS, CDN down) there is no axis to settle on: the coda keeps
   the rows' left edge (dock column + gap) instead of a second, unexplained one. */
@media (min-width: 720px) {
  .words:not(.is-aligned) .words-coda { margin-left: calc(max(56px, 8vw) + var(--s-3)); }
}

@media (min-width: 1600px) {
  .row { grid-template-columns: var(--dock-col) 1fr minmax(240px, 300px); }
  .row-note { grid-column: 3; }
}

@media (max-width: 719px) {
  .row { grid-template-columns: 1fr; }
  .row-word,
  .row-note { grid-column: 1; }
  .row-word { font-size: clamp(40px, 13vw, 56px); letter-spacing: -0.03em; }
}


/* ---------- 03b Ecuador, hoy (El día dura lo mismo.) ----------
   Six questions a founder asks, each answered by a public figure: a ledger in the crossing's
   grammar (hairline rows, figures in the display voice at a fixed 900, no weight reactions
   here), then one line to the sources on /ecuador, today's line in Quito and the coda.
   A row reads question → figure → note (its period) → tag. From 1000px the question
   has a column of its own and the row sits on its foot; below, the question sits over the
   row's rule, so a measured share is never separated from its figure.
   The official figures, the typical daylight span (--sr / --ss) and the range of sunrises
   are what no-JS readers get; .is-live (fx/ecuador-hoy.js, every JS path) shows the live
   variants and the 'now' marks. */
.ecuador-hoy {
  --eh-pe: var(--gutter);                    /* inline-end padding; the mobile dock widens it */
  --eh-cat-r: clamp(20px, 2vw, 28px);        /* the catalyst's radius on the day line */
  --eh-in: 0px;                              /* where rules start (the dock column stays clear) */
  --eh-fig: clamp(36px, min(7vw, calc(0.11 * var(--vh-s))), 112px);   /* the figures */
  position: relative;
  z-index: var(--z-ecuador);
  background: var(--ink);
  color: var(--white);
  padding: clamp(64px, 8vw, 128px) var(--eh-pe) clamp(96px, 11vw, 160px) var(--gutter);
  overflow-x: clip;
}

.eh-head,
.eh-row,
.eh-src {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: var(--s-3);
}

.eh-eyebrow {
  font-weight: 700;
  font-size: clamp(19px, 1.6vw, 22px);
  letter-spacing: -0.01em;
}

.ecuador-hoy h2 {
  margin-top: var(--s-2);
  font-weight: 900;
  font-size: clamp(44px, 7vw, 112px);
  color: var(--blue);
  max-width: 9ch;
  text-wrap: balance;
}

.eh-intro {
  margin-top: var(--s-3);
  color: var(--fg2-ink);
}

.eh-rows {
  list-style: none;
  margin-top: clamp(48px, 6vw, 96px);
}

/* Stacked (phones; tablets in the content column): question, 10px, the rule with the
   measured share, 8px, figure, 10px, note and its tag. */
.eh-row {
  position: relative;
  align-items: start;
  padding: 8px 0 clamp(28px, 4vw, 36px);
}

/* Placed, never auto-placed: the rule and the bar share one cell. */
.eh-row > *,
.eh-src > * { grid-column: 1; }
.eh-row > .eh-q { grid-row: 1; margin-bottom: 10px; }
.eh-row > .eh-rule,
.eh-row > .eh-bar { grid-row: 2; }
.eh-row > .eh-num { grid-row: 3; margin-top: 8px; }
.eh-row > .eh-note { grid-row: 4; margin-top: 10px; }

/* The hairline (1px, structure) and, on percentage rows, the measured share in 2px white:
   the full rule is 100 %. Both are drawn in full here; fx/ecuador-hoy.css draws them with
   scroll. Explicit elements, so the rule is never a pseudo-element of a cell that moves. */
.eh-rule,
.eh-bar {
  display: block;
  align-self: center;
  height: 1px;
  background: var(--rule-ink);
  transform-origin: left;
}

.eh-bar {
  justify-self: start;
  width: calc(var(--pct, 0) * 100%);
  height: 2px;
  background: var(--white);
}

/* The question: the text voice's heading, white, balanced, never wider than 18ch. */
.eh-q {
  font-weight: 700;
  font-size: clamp(19px, 1.6vw, 22px);
  line-height: 1.2;
  letter-spacing: -0.01em;
  color: var(--white);
  max-width: 18ch;
  text-wrap: balance;
}

.eh-num {
  font-weight: 900;
  font-size: var(--eh-fig);
  line-height: 0.9;
  letter-spacing: -0.035em;
  margin-inline-start: -0.035em;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  padding-top: 0.06em;
}

/* Units inside a duration ('h', 'min') speak in the text voice, with their own room on
   both sides (the inner spaces alone shrink to a few px at .3em). */
.eh-u {
  font-size: 0.3em;
  font-weight: 500;
  letter-spacing: 0;
  margin-inline: 0.2em 0.35em;
}

.eh-label { color: var(--white); }

/* The status of a figure (spec §1: no period) and a calculation's formula, on one line
   under the note. */
.eh-s {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
  margin-top: 6px;
}

.eh-tag {
  font-weight: 600;
  font-size: 13px;
  line-height: 1.4;
  letter-spacing: 0.01em;
  color: var(--fg2-ink);
}

.eh-f {
  font-weight: 500;
  font-size: 15px;
  line-height: 1.4;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  color: var(--fg2-ink);
}

/* Official and live variants share one cell: the swap never reflows. */
.eh-swap { display: grid; }
.eh-swap > * { grid-area: 1 / 1; align-self: start; }
.eh-swap > .l-1 { visibility: hidden; }
.is-now .eh-swap > .l-0 { visibility: hidden; }
.is-now .eh-swap > .l-1 { visibility: visible; }

/* ---------- The way to the sources (owner, 2026-10-04) ----------
   The home shows no notes and no list: each figure keeps its period, and one line under the
   rows leads to «Fuentes y criterios» on /ecuador, the one place with the numbered list and
   the links. Its hairline closes the last row (drawn with scroll, as a row's); from 1000px the
   line sits in the figure column, below it on the full width of the content column. */
.eh-src {
  position: relative;
  align-items: start;
  padding-top: 8px;
}

.eh-src > .eh-rule { grid-row: 1; }
.eh-src > .eh-more { grid-row: 2; margin-top: 14px; }

.eh-more { max-width: none; }

.eh-more a {
  color: var(--white);
  text-decoration: underline;
  text-decoration-color: var(--blue);
  text-decoration-thickness: 2px;
  text-underline-offset: 6px;
}

.eh-more a:hover { text-decoration-color: var(--white); }

.eh-day { margin-top: clamp(56px, 7vw, 112px); }

/* The day line: one 24 h scale, full bleed, its hairline the night and its 2px white
   the daylight. Labels sit under their positions. */
.eh-day-line {
  position: relative;
  height: 112px;
  margin-inline: calc(-1 * var(--gutter)) calc(-1 * var(--eh-pe));
  margin-top: var(--s-2);
}

.eh-day-line::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 56px;
  height: 1px;
  background: var(--rule-ink);
  transform-origin: calc(var(--gutter) + var(--now, 0.5) * (100% - 2 * var(--gutter))) 50%;
}

.eh-day-scale {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  top: 56px;
  height: 1px;
}

.eh-light {
  position: absolute;
  top: -0.5px;
  height: 2px;
  left: calc(var(--sr, 0.2569) * 100%);
  width: calc((var(--ss, 0.7618) - var(--sr, 0.2569)) * 100%);
  background: var(--white);
  transform-origin: left;
}

.eh-tick {
  position: absolute;
  top: 0;
  left: calc(var(--at) * 100%);
  width: 1px;
  height: 6px;
  margin-left: -0.5px;
  background: var(--fg2-ink);
}

.eh-end,
.eh-sr,
.eh-ss,
.eh-now {
  position: absolute;
  top: 14px;
  font-size: 13px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  color: var(--fg2-ink);
}

.eh-end-0 { left: 0; }
.eh-end-24 { right: 0; }
.eh-sr { left: calc(var(--sr, 0.2569) * 100%); transform: translateX(-50%); }
.eh-ss { left: calc(var(--ss, 0.7618) * 100%); transform: translateX(-50%); }

/* 'Now' in Quito: a white tick on the line (the catalyst sets down on it) and the time
   above. Only once the live values run: without JS there is no 'now' to show. */
.eh-now,
.eh-now-tick { display: none; }

.is-live .eh-now-tick {
  display: block;
  position: absolute;
  top: -12px;
  left: calc(var(--now, 0.5) * 100%);
  width: 1px;
  height: 25px;
  margin-left: -0.5px;
  background: var(--white);
}

.is-live .eh-now {
  display: block;
  top: auto;
  bottom: calc(var(--eh-cat-r) + 10px);
  left: calc(var(--now, 0.5) * 100%);
  transform: translateX(-50%);
  font-size: 15px;
  font-weight: 600;
  color: var(--white);
}

/* Forced colors (Windows High Contrast): the section's drawn structure is backgrounds of empty
   elements, which the system would paint as Canvas. The measured spans (bars, daylight, ticks, now)
   take CanvasText and the rules GrayText, as on /ecuador; the scroll-drawn transforms still apply. */
@media (forced-colors: active) {
  .ecuador-hoy :is(.eh-bar, .eh-light, .eh-tick, .eh-now-tick) {
    forced-color-adjust: none;
    background: CanvasText;
  }
  .ecuador-hoy .eh-rule,
  .ecuador-hoy .eh-day-line::before {
    forced-color-adjust: none;
    background: GrayText;
  }
}

/* No catalyst on the line (reduced motion, no GSAP): the time sits right over its tick. */
html:not(.has-catalyst) .is-live .eh-now { bottom: 22px; }

/* A label the catalyst sits on steps aside (fx/ecuador-hoy.js). */
.eh-day-scale .is-near { opacity: 0; }

.ecuador-coda {
  margin-top: clamp(56px, 6vw, 96px);
  color: var(--fg2-ink);
}

/* Tablets: the crossing's dock column on the left (the catalyst rests in it while the rows
   pass: no rule runs under it), the stacked rows in the content column. */
@media (min-width: 720px) {
  .ecuador-hoy { --eh-in: calc(max(56px, 8vw) + var(--s-3)); }
  .eh-head,
  .eh-row,
  .eh-src { grid-template-columns: var(--dock-col) minmax(0, 1fr); }
  .eh-head > *,
  .eh-row > *,
  .eh-src > * { grid-column: 2; }
  .ecuador-coda { margin-left: calc(max(56px, 8vw) + var(--s-3)); }
}

/* Desktops: dock | question | figure | note, all on the row's foot, sharing the last
   baseline. The rule runs on the row's top; a measured share lies on the row's closing
   rule (the next row's hairline), under its own figure, never under the figure above. */
@media (min-width: 1000px) {
  .ecuador-hoy { --eh-fig: clamp(36px, min(6vw, calc(0.11 * var(--vh-s))), 104px); }
  .eh-row,
  .eh-src {
    grid-template-columns: var(--dock-col) clamp(180px, 15vw, 216px) minmax(0, 1fr) minmax(280px, 30ch);
  }
  .eh-row {
    align-items: end;
    align-items: last baseline;
    padding: clamp(24px, 2.4vw, 36px) 0 clamp(8px, 0.8vw, 12px);
  }
  .eh-row > :is(.eh-q, .eh-num, .eh-note) { grid-row: 1; margin: 0; }
  .eh-row > .eh-q { grid-column: 2; }
  .eh-row > .eh-num { grid-column: 3; }
  .eh-row > .eh-note { grid-column: 4; }
  .eh-row > :is(.eh-rule, .eh-bar),
  .eh-src > .eh-rule {
    position: absolute;
    grid-area: auto;
    left: var(--eh-in);
  }
  .eh-row > .eh-rule,
  .eh-src > .eh-rule { top: 0; right: 0; }
  .eh-row > .eh-bar {
    bottom: -1.5px;
    width: calc(var(--pct, 0) * (100% - var(--eh-in)));
  }
  /* The note sits on the row's foot: a shorter live variant hugs the figure's baseline. */
  .eh-swap > * { align-self: end; }
  .eh-head > * { grid-column: 2 / -1; }
  .ecuador-hoy h2 { max-width: none; }

  /* The way to the sources: under the last row's closing rule, in the figure column. */
  .eh-src { padding-top: clamp(20px, 2vw, 28px); }
  .eh-src > .eh-more { grid-column: 3 / -1; grid-row: 1; margin: 0; }
}

/* From 1200px the figure column has room for the full figure scale. Below, the widest
   figure («USD 616») still fits between question and note. */
@media (min-width: 1200px) {
  .ecuador-hoy { --eh-fig: clamp(36px, min(6.6vw, calc(0.11 * var(--vh-s))), 104px); }
}

/* Around 1024px the note column gives up a little to the figure. */
@media (min-width: 1000px) and (max-width: 1099px) {
  .eh-row,
  .eh-src {
    grid-template-columns: var(--dock-col) clamp(180px, 15vw, 216px) minmax(0, 1fr) minmax(240px, 26ch);
  }
}

/* Phones: one column; the figure scale steps down, the line is a little shorter. */
@media (max-width: 719px) {
  .ecuador-hoy {
    --eh-cat-r: 5.5vw;
    --eh-fig: clamp(36px, 11.5vw, 56px);
  }
  .ecuador-hoy h2 { font-size: 44px; letter-spacing: -0.03em; }
  .eh-day-line { height: 96px; }
  .eh-day-line::before,
  .eh-day-scale { top: 48px; }
  .eh-end,
  .eh-sr,
  .eh-ss { font-size: 12px; }
}

/* Motion: the coda's full stop floods into the white section. A quarter screen above it
   keeps the swell clear of the day line; half a screen of ink below lets the flood start
   (mark at 55% of the viewport) before any white edge shows. No JS and reduced motion
   have no flood, so they keep the plain spacing. */
@media (prefers-reduced-motion: no-preference) {
  html.js .ecuador-hoy {
    padding-bottom: max(clamp(96px, 11vw, 160px), 45vh);
    padding-bottom: max(clamp(96px, 11vw, 160px), 45svh);
  }
  html.js .ecuador-coda {
    margin-top: max(clamp(56px, 6vw, 96px), 26vh);
    margin-top: max(clamp(56px, 6vw, 96px), 26svh);
  }
}

/* Short desktop screens: figures and rows tighten so a few rows share each frame. */
@media (min-width: 720px) and (max-width: 999px) and (max-height: 820px) {
  .eh-row {
    padding-block: 6px clamp(20px, 3vh, 28px);
    padding-block: 6px clamp(20px, 3svh, 28px);
  }
}

@media (min-width: 1000px) and (max-height: 820px) {
  .eh-row {
    padding-block: clamp(16px, 2.4vh, 28px) clamp(6px, 0.8vh, 10px);
    padding-block: clamp(16px, 2.4svh, 28px) clamp(6px, 0.8svh, 10px);
  }
}

/* Short landscape (phones on their side): smaller figures, a compact line. */
@media (max-height: 520px) and (orientation: landscape) {
  .ecuador-hoy { --eh-fig: min(clamp(36px, 7vw, 112px), calc(0.13 * var(--vh-s))); }
  .ecuador-hoy h2 {
    font-size: min(clamp(44px, 7vw, 112px), 15vh);
    font-size: min(clamp(44px, 7vw, 112px), 15svh);
  }
  .eh-row {
    padding-block: 1vh 4vh;
    padding-block: 1svh 4svh;
  }
  .eh-day-line { height: 96px; }
  .eh-day-line::before,
  .eh-day-scale { top: 48px; }
}

/* ---------- 04 Silent ---------- */
.silent {
  position: relative;
  z-index: var(--z-silent);
  background: var(--white);
  color: var(--ink);
  padding: clamp(96px, 12vw, 180px) var(--gutter);
}

.silent h2 {
  font-size: clamp(44px, 7vw, 104px);
  line-height: 0.96;
  letter-spacing: -0.03em;
  max-width: 13ch;
}

@media (min-width: 800px) { .silent h2 { letter-spacing: -0.045em; } }

.redacted {
  list-style: none;
  margin-top: clamp(56px, 7vw, 104px);
}

.redacted li {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: center;
  gap: var(--s-3);
  padding: clamp(20px, 2.4vw, 32px) 0;
  border-top: 1px solid var(--ink);
}

.redacted li:last-child { border-bottom: 1px solid var(--ink); }

.r-status {
  display: flex;
  align-items: center;
  gap: 10px;
}

.r-status i {
  flex: none;
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: var(--blue);
}

/* The contact answer stays hidden unless fx/capsulas-selladas.css stacks it. */
.r-s2 { display: none; }

.silent-note {
  margin-top: 32px;
  color: var(--fg2-white);
}

@media (max-width: 719px) {
  .redacted li { grid-template-columns: 1fr; gap: var(--s-1); }
}

/* Phones: the same flood runway tablets get below (the note's mark floods the lens). */
@media (max-width: 719px) and (prefers-reduced-motion: no-preference) {
  html.js .silent {
    padding-bottom: max(96px, 45vh);
    padding-bottom: max(96px, 45svh);
  }
}

/* Phones without the enhanced silence (reduced motion, no JS, failed init): the quiet
   section still gets a screen of its own instead of a short white band squeezed between
   an ink and a blue stripe. The enhanced runway padding is left untouched. */
@media (max-width: 719px) {
  html:not(.fx-capsulas) .silent {
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

/* Tall portrait tablets: the crossing gets a screen of its own (rows centred on the
   mid-viewport dock, so the catalyst holds it and no white shows yet), and the note's
   full stop sits far enough above the lens section that its flood is already swelling
   when that section's edge comes into view. */
@media (orientation: portrait) and (min-width: 720px) {
  .words {
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
  .silent {
    padding-bottom: max(clamp(96px, 12vw, 180px), 45vh);
    padding-bottom: max(clamp(96px, 12vw, 180px), 45svh);
  }
}

/* Tablets and desktops (landscape too): the crossing is at least one screen tall, so
   the white section never shows as a hard band under the three aligned rows. */
@media (min-width: 720px) and (min-height: 600px) {
  .words {
    min-height: 100vh;
    min-height: 100svh;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

/* Short desktop screens (laptops at 650-820px): the aligned rows, their notes and the
   coda fit in ~85% of the screen instead of being cropped at the aligned moment. */
@media (min-width: 720px) and (max-height: 820px) {
  .row-word {
    font-size: clamp(56px, min(9vw, 13vh), 140px);
    font-size: clamp(56px, min(9vw, 13svh), 140px);
  }
  .row {
    padding-block: clamp(8px, 1.2vh, 20px);
    padding-block: clamp(8px, 1.2svh, 20px);
  }
  .words-coda {
    margin-top: clamp(32px, 6vh, 96px);
    margin-top: clamp(32px, 6svh, 96px);
  }
}

/* Dock clearance: the catalyst's mobile dock is a whole 11vw mark, 1.2vw in from the
   right edge (fx/el-catalizador.js); rules and copy stop a few px short of it. */
@media (max-width: 719px) {
  html.has-catalyst .words,
  html.has-catalyst .silent { padding-inline-end: max(var(--gutter), calc(11vw + 12px)); }
  /* The day line stays full bleed: it reads --eh-pe to undo the wider padding. */
  html.has-catalyst .ecuador-hoy { --eh-pe: max(var(--gutter), calc(11vw + 12px)); }
}

/* ---------- 05 Ribbon (the lens base lives in fx/lente-de-peso.css) ---------- */
.ribbon {
  position: relative;
  z-index: var(--z-ribbon);
  background: var(--blue);
  color: var(--ink);
}

/* ---------- 06 Closing ---------- */
.closing {
  position: relative;
  z-index: auto;
  background: var(--blue);
  color: var(--ink);
  padding: clamp(96px, 12vw, 180px) var(--gutter) clamp(24px, 2.5vw, 36px);
  display: flex;
  flex-direction: column;
  gap: clamp(40px, 5vw, 64px);
  overflow-x: clip;
  /* The last frame is the closing alone: on tall screens the lens line no longer
     peeks in above it, and the ink band always sits on the viewport's bottom edge. */
  min-height: 100vh;
}

@supports (min-height: 100svh) {
  .closing { min-height: 100svh; }
}

/* Spare height is shared above the line and below the pill: the closing sits
   centred between its padding and the band instead of hugging the top. */
.closing h2 { margin-top: auto; }
.closing .magnetic { margin-bottom: auto; }

.closing h2,
.magnetic,
.closing-bar {
  position: relative;
  z-index: var(--z-text);
}

.closing h2 {
  /* Same scale as the hero h1 so the closing mirrors the first frame and clears the catalyst. */
  /* The floor drops below 52px only under ~361px, where "conversarlo." would overflow. */
  font-size: clamp(min(52px, 14.4vw), min(9.2vw, 13.5vh), 132px);
  font-size: clamp(min(52px, 14.4vw), min(9.2vw, 13.5svh), 132px);
  line-height: 0.92;
  max-width: 11ch;
}

@media screen and (max-width: 459px) and (max-height: 640px) and (prefers-reduced-motion: no-preference),
       screen and (min-width: 420px) and (max-width: 459px) and (max-height: 700px) and (prefers-reduced-motion: no-preference) {
  /* At max scroll the live catalyst covers x >= 58vw down to 76px + 56vw. On SE-class
     phones (568-640px tall) the closing is taller than the viewport, so its padding
     reservation scrolls away and 'Lo demás,' would run into the mark's left lobe: one
     word per line keeps the headline left of the mark, as the hero's short lines do.
     From ~641px (Safari's iPhone 12-15 frame with toolbars, 393x659) the bottom-anchored
     line already starts below the lobe and wraps naturally ('Lo demás, / mejor /
     conversarlo.'), without orphaning 'Lo'. From ~432px wide 'Lo demás, mejor' fits on
     one line and reaches the lobe up to ~690px tall, so 420-459px keeps the 700px cut. */
  html.has-catalyst .closing h2 { word-spacing: 100vw; }
}

/* 720-1100px: at the hero's 9.2vw, 'mejor' ran into the catalyst's left lobe on the
   closing line. One step down keeps the line clear of the mark. */
@media (min-width: 720px) and (max-width: 1100px) {
  .closing h2 {
    font-size: clamp(52px, min(8vw, 13.5vh), 132px);
    font-size: clamp(52px, min(8vw, 13.5svh), 132px);
  }
}

/* Portrait tablets: the last frame mirrors the first. The line and pill rest on the band
   the way the hero's definition rests on the bottom edge, the spare height opens under
   the catalyst, and the line keeps the hero's 9.2vw (the mark sits far above it here). */
@media (orientation: portrait) and (min-width: 720px) {
  .closing .magnetic { margin-bottom: 0; }
  .closing h2 {
    font-size: clamp(52px, min(9.2vw, 13.5vh), 132px);
    font-size: clamp(52px, min(9.2vw, 13.5svh), 132px);
  }
}

@media (max-height: 520px) and (orientation: landscape) {
  /* Short landscape: the closing frame (line, pill, band) fits one viewport. */
  html .closing { padding-top: 16svh; gap: 6svh; }
  html .closing h2 { font-size: min(clamp(min(52px, 14.4vw), 9.2vw, 132px), 17svh); }
  html .closing-bar { margin-top: 6svh; }

  /* The hero: nav, phonetic and all four lines with the full stop in one screen. */
  .hero { padding-bottom: 6vh; padding-bottom: 6svh; }
  .definition { padding-top: 0; gap: 2vh; gap: 2svh; }
  .hero h1 {
    font-size: min(clamp(52px, 9.2vw, 132px), 15vh);
    font-size: min(clamp(52px, 9.2vw, 132px), 15svh);
  }

  /* The crossing: three rows and the shared 'd' axis in one frame. */
  .row { padding-block: 1.5vh; padding-block: 1.5svh; row-gap: 0; }
  .words { padding-bottom: 8vh; padding-bottom: 8svh; }
  .words-coda { margin-top: 4vh; margin-top: 4svh; }
  .row-word {
    font-size: min(clamp(56px, 9vw, 140px), 14vh);
    font-size: min(clamp(56px, 9vw, 140px), 14svh);
  }

  /* Silence: heading, both capsules and the note (whose mark floods the lens) in one frame.
     The heading keeps its 13ch measure (three short lines), clear of the catalyst's pose. */
  .silent { padding-block: 10vh; padding-block: 10svh; }
  .silent h2 {
    font-size: min(clamp(44px, 7vw, 104px), 13vh);
    font-size: min(clamp(44px, 7vw, 104px), 13svh);
  }
  .redacted { margin-top: 5vh; margin-top: 5svh; }
  .redacted li { padding-block: 2.2vh; padding-block: 2.2svh; }
  .silent-note { margin-top: 3vh; margin-top: 3svh; }
}

@media (min-width: 1091px) { .closing h2 { letter-spacing: -0.055em; } }

.magnetic {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: clamp(16px, 1.6vw, 22px) clamp(22px, 2.2vw, 32px);
  background: var(--ink);
  color: var(--white);
  border-radius: 999px;
  text-decoration: none;
  font-weight: 600;
  font-size: clamp(17px, 1.6vw, 22px);
  letter-spacing: -0.01em;
  transition: background var(--t-micro) var(--ease-react), color var(--t-micro) var(--ease-react);
}

.magnetic svg {
  flex: none;
  width: 20px;
  height: 20px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: transform var(--t-short) var(--ease-react);
}

@media (hover: hover) {
  .magnetic:hover { background: var(--white); color: var(--ink); }
  .magnetic:hover svg { transform: rotate(45deg); }
}

.magnetic:focus-visible { background: var(--white); color: var(--ink); }
.magnetic:focus-visible svg { transform: rotate(45deg); }

.closing-bar {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: center;
  gap: 12px 24px;
  margin-top: clamp(48px, 7vw, 120px);
}

.sign { font-weight: 700; letter-spacing: -0.02em; }

.clock { font-weight: 500; font-variant-numeric: tabular-nums; }

.links { display: flex; gap: 24px; }

.links a { text-decoration: none; font-weight: 500; }
.links a:hover { text-decoration: underline; text-underline-offset: 5px; }

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