/* ============================================================
   AJM Comunicaciones S.A.S — Landing Page

   Colour pipeline: the three brand anchors stay as exact hex from the
   brand manual (fidelity is not negotiable). Every derived tone is
   mixed from them in oklab, so tints stay perceptually even instead of
   muddying the way sRGB mixing does.

   Light only, on purpose: the use scene is a phone in daylight, in the
   field, in rural Santander and Boyacá.
   ============================================================ */

@view-transition { navigation: auto; }

@property --sweep {
  syntax: "<angle>";
  initial-value: 0deg;
  inherits: false;
}

:root {
  color-scheme: light;

  /* --- Brand anchors: exact, never mixed away --- */
  --blue: #0066cc;
  --green: #009933;
  --navy: #0b1a33;

  /* --- Derived in oklab from the anchors --- */
  --blue-deep: color-mix(in oklab, var(--blue) 84%, var(--navy));
  --green-deep: color-mix(in oklab, var(--green) 78%, var(--navy));
  --navy-lift: color-mix(in oklab, var(--navy) 88%, var(--blue));

  --ink: color-mix(in oklab, var(--navy) 92%, white);
  --ink-soft: color-mix(in oklab, var(--navy) 68%, white); /* 4.5:1 on white */
  --ink-faint: color-mix(in oklab, var(--navy) 55%, white); /* large text only */

  --paper: #ffffff;
  --paper-sunken: color-mix(in oklab, white 92%, var(--blue));
  --rule: color-mix(in oklab, var(--navy) 8%, #e9edf4);
  --rule-strong: color-mix(in oklab, var(--navy) 14%, #d9e0ea);

  /* On navy, secondary text is tinted from the surface, never gray */
  --on-navy: color-mix(in oklab, white 96%, var(--blue));
  --on-navy-soft: color-mix(in oklab, white 74%, var(--navy));
  --on-navy-faint: color-mix(in oklab, white 63%, var(--navy));
  --rule-navy: color-mix(in oklab, white 18%, transparent);

  /* --- Type --- */
  --font-display: "Fraunces", "Georgia", serif;
  --font-body: "Manrope", "Segoe UI", system-ui, sans-serif;

  /* --- Layout --- */
  --container: 1240px;
  --gutter: 20px;

  --r-xs: 6px;
  --r-sm: 10px;
  --r-md: 14px;
  --r-lg: 22px;
  --r-pill: 999px;

  /* --- Depth: offset and blur, tinted with the navy --- */
  --shadow-sm: 0 1px 2px color-mix(in oklab, var(--navy) 7%, transparent),
    0 10px 24px -18px color-mix(in oklab, var(--navy) 10%, transparent);
  --shadow-md: 0 10px 22px -18px color-mix(in oklab, var(--navy) 14%, transparent),
    0 24px 48px -32px color-mix(in oklab, var(--navy) 18%, transparent);
  --shadow-lg: 0 16px 32px -22px color-mix(in oklab, var(--navy) 18%, transparent),
    0 34px 72px -42px color-mix(in oklab, var(--navy) 24%, transparent);
  --shadow-accent: 0 10px 24px -20px color-mix(in oklab, var(--green-deep) 30%, transparent),
    0 18px 42px -28px color-mix(in oklab, var(--blue) 18%, transparent);

  --z-header: 30;
  --z-float: 40;
  --z-grain: 50;

  /* Exponential ease-out, from an already-visible default. Nothing
     overshoots: real objects decelerate, they do not bounce back. */
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-quick: cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- Reset ---------- */
*,
*::before,
*::after { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
  -webkit-text-size-adjust: 100%;
  interpolate-size: allow-keywords;
}

body {
  margin: 0;
  font-family: var(--font-body);
  font-size: 0.96875rem;
  line-height: 1.56;
  color: var(--ink);
  background:
    radial-gradient(circle at 18% 10%, color-mix(in oklab, var(--blue) 7%, transparent), transparent 22%),
    radial-gradient(circle at 82% 18%, color-mix(in oklab, var(--green) 8%, transparent), transparent 24%),
    var(--paper);
  -webkit-font-smoothing: antialiased;
}

body::before {
  content: "";
  position: fixed;
  inset: -8% -10% auto auto;
  width: 34vw;
  height: 34vw;
  min-width: 300px;
  min-height: 300px;
  background:
    radial-gradient(circle at 35% 35%, color-mix(in oklab, var(--green) 10%, transparent), transparent 62%),
    radial-gradient(circle at 70% 30%, color-mix(in oklab, var(--blue) 9%, transparent), transparent 58%);
  filter: blur(56px);
  opacity: 0.26;
  pointer-events: none;
}

/* Grain: a material, not decoration — it keeps the flat navy from
   banding across the large gradient fields. */
body::after {
  content: "";
  position: fixed;
  inset: 0;
  z-index: var(--z-grain);
  pointer-events: none;
  opacity: 0.08;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.85' numOctaves='3'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23n)' opacity='0.11'/%3E%3C/svg%3E");
}

img { max-width: 100%; display: block; }
a { color: inherit; text-decoration: none; }
ul, ol { margin: 0; padding: 0; list-style: none; }
p { margin: 0; max-width: 68ch; text-wrap: pretty; }

h1, h2, h3 {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 600;
  line-height: 1.04;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

:focus-visible {
  outline: 2px solid var(--green);
  outline-offset: 3px;
  border-radius: var(--r-xs);
}

/* ---------- Skip link ---------- */
.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 100;
  padding: 12px 20px;
  background: var(--green);
  color: white;
  font-weight: 600;
  border-radius: var(--r-sm);
  transition: top 0.25s var(--ease);
}
.skip-link:focus { top: 16px; }

/* ---------- Layout ---------- */
.container {
  width: 100%;
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: var(--gutter);
}

.section { padding: 88px 0 100px; }
.section--sunken { background: var(--paper-sunken); }

/* More space above a heading than below it. The measure belongs to the
   heading, not to the block: the lead needs its own, wider one. */
.section-head { margin-bottom: 42px; }
.section-head .section-title { max-width: 20ch; }
.section-title { font-size: clamp(1.85rem, 4vw, 3rem); font-variation-settings: "opsz" 32; }
.section-lead { margin-top: 18px; max-width: 46ch; font-size: 1rem; color: var(--ink-soft); }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  padding: 12px 22px;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  font-family: var(--font-body);
  font-size: 0.875rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 0.3s var(--ease-quick), background-color 0.25s var(--ease),
    border-color 0.25s var(--ease), color 0.25s var(--ease), box-shadow 0.3s var(--ease);
}

.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(1px) scale(0.985); }
.btn[disabled] { opacity: 0.45; pointer-events: none; }

.btn--accent { background: var(--green); color: white; box-shadow: var(--shadow-accent); }
.btn--accent:hover { background: var(--green-deep); }

.btn--solid { background: var(--navy); color: white; box-shadow: var(--shadow-md); }
.btn--solid:hover { background: var(--navy-lift); }

.btn--line { background: transparent; color: var(--ink); border-color: var(--rule-strong); }
.btn--line:hover { border-color: var(--ink); background: var(--paper-sunken); }

.btn--line-invert { background: transparent; color: white; border-color: var(--rule-navy); }
.btn--line-invert:hover {
  background: color-mix(in oklab, white 10%, transparent);
  border-color: color-mix(in oklab, white 34%, transparent);
}

.btn--block { width: 100%; }

.link-arrow {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding-bottom: 3px;
  font-size: 0.9375rem;
  font-weight: 600;
  color: var(--blue);
  border-bottom: 1px solid transparent;
  transition: border-color 0.25s var(--ease), color 0.25s var(--ease);
}
.link-arrow:hover { border-bottom-color: currentColor; }
.link-arrow svg { width: 15px; height: 15px; transition: transform 0.3s var(--ease); }
.link-arrow:hover svg { transform: translateX(5px); }

/* ---------- Header ----------

   One bar, not three islands. Every group used to carry its own plate,
   which left four elements at four heights on four different baselines,
   and the phone number with no plate at all — illegible the moment page
   content scrolled under it. A single surface makes the alignment
   structural instead of something to keep re-tuning by hand.
   ------------------------------------------------------------------ */
.header {
  position: fixed;
  inset: 18px 0 auto 0;
  z-index: var(--z-header);
  background: transparent;
}

/* Real glass, which means the fill has to stay thin enough to see
   through. A backdrop-filter over an opaque surface is wasted work:
   the blur only reads because the hero photograph sits behind it.
   The inset highlight is the light catching the top edge. */
.header__inner {
  position: relative;
  display: grid;
  /* The bar hugs its content instead of stretching the full container.
     A 1050px slab holding four short links reads as empty, and glass
     needs curvature and edge to look like glass at all. */
  grid-template-columns: auto auto auto;
  width: max-content;
  max-width: 100%;
  margin-inline: auto;
  align-items: center;
  gap: 34px;
  min-height: 64px;
  padding: 7px 8px 7px 22px;
  border: 1px solid rgba(255, 255, 255, 0.55);
  border-radius: var(--r-pill);
  /* Glass is not a flat white fill. Three things sell it: a gradient that
     is brighter at the top than the bottom (refraction), a fill thin
     enough for the blur to matter, and a specular arc on the top edge.
     The inset shadows follow the pill's curve, so the highlight bends
     with it the way light on a real edge does. */
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.68) 0%,
    rgba(255, 255, 255, 0.42) 55%,
    rgba(255, 255, 255, 0.52) 100%);
  backdrop-filter: blur(22px) saturate(190%) brightness(1.06);
  -webkit-backdrop-filter: blur(22px) saturate(190%) brightness(1.06);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -1px 0 rgba(255, 255, 255, 0.3),
    0 1px 2px color-mix(in oklab, var(--navy) 10%, transparent),
    0 4px 10px -4px color-mix(in oklab, var(--navy) 14%, transparent),
    0 18px 44px -20px color-mix(in oklab, var(--navy) 42%, transparent);
  transition: background 0.35s var(--ease), border-color 0.35s var(--ease),
    box-shadow 0.35s var(--ease);
}

/* Past the hero the bar travels over plain copy, where a thin fill would
   cost legibility and buy nothing: there is no photograph left to refract. */
.header.is-scrolled .header__inner {
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.92) 0%,
    rgba(255, 255, 255, 0.8) 55%,
    rgba(255, 255, 255, 0.86) 100%);
  border-color: rgba(255, 255, 255, 0.8);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    inset 0 -1px 0 rgba(255, 255, 255, 0.4),
    0 1px 2px color-mix(in oklab, var(--navy) 8%, transparent),
    0 4px 10px -4px color-mix(in oklab, var(--navy) 12%, transparent),
    0 20px 46px -22px color-mix(in oklab, var(--navy) 34%, transparent);
}

.header__brand { display: inline-flex; align-items: center; }

/* One transparent asset for every surface: white on dark, full colour
   once the header turns light. No second file, no colour seam. */
/* A UI lockup, not the print logo: its transparent margin is trimmed and
   the "COMUNICACIONES S.A.S" line — five pixels tall at this size, and
   pure mush — is gone. Same artwork, a third larger on screen. */
.header__logo {
  height: 45px;
  width: auto;
  filter: none;
}

.header__nav {
  display: flex;
  align-items: center;
  gap: 26px;
}

.header__link {
  position: relative;
  padding: 4px 0;
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink-soft);
  transition: color 0.25s var(--ease);
}

.header__link::before {
  content: "";
  position: absolute;
  left: 50%;
  bottom: -2px;
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--green);
  transform: translate(-50%, 4px) scale(0);
  transition: transform 0.4s var(--ease-quick);
}

.header__link:hover { color: var(--ink); }
.header__link.is-active { color: var(--ink); font-weight: 700; }
.header__link.is-active::before { transform: translate(-50%, 0) scale(1); }

.header__nav-cta { display: none; }

.header__actions { display: flex; align-items: center; gap: 14px; }
.header__actions .btn { padding: 11px 20px; }
.header__actions .btn--accent {
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.3),
    0 1px 2px color-mix(in oklab, var(--navy) 12%, transparent),
    0 8px 20px -8px color-mix(in oklab, var(--green-deep) 55%, transparent);
}

/* A pill, like the button beside it. Loose text with a hairline rule read
   as a leftover; two pills read as two ways to reach the same company.
   nowrap is not cosmetic: without it the number breaks across three lines
   the moment the bar gets tight. */
.header__phone {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
  font-size: 0.8125rem;
  font-weight: 600;
  color: var(--ink);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.header__phone svg { width: 14px; height: 14px; flex: none; color: var(--green); }
.header__phone:hover {
  background: rgba(255, 255, 255, 0.72);
  border-color: rgba(255, 255, 255, 0.95);
}

.nav-toggle {
  display: none;
  width: 46px;
  height: 46px;
  padding: 0;
  border: 1px solid rgba(255, 255, 255, 0.7);
  border-radius: var(--r-pill);
  background: rgba(255, 255, 255, 0.42);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.8);
  cursor: pointer;
  place-items: center;
  transition: background-color 0.25s var(--ease), border-color 0.25s var(--ease);
}
.nav-toggle:hover,
.nav-toggle[aria-expanded="true"] {
  background: rgba(255, 255, 255, 0.75);
  border-color: rgba(255, 255, 255, 0.95);
}
.nav-toggle__bars { display: grid; gap: 4px; }
.nav-toggle__bar {
  width: 18px;
  height: 2px;
  background: var(--ink);
  transition: background-color 0.25s var(--ease), transform 0.4s var(--ease),
    opacity 0.25s var(--ease);
}
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bar:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- Hero ---------- */
/* The landscape the company actually sells into. The scrim is thin at the
   very top so the glass bar has something real to refract, then thickens
   fast to carry the dark headline, and is pure paper by the plan rail. */
.hero {
  position: relative;
  padding: 132px 0 68px;
  color: var(--ink);
  overflow: clip;
  --hero-photo: url("../img/fondo1-1200.webp");
  background:
    linear-gradient(180deg,
      rgba(255, 255, 255, 0.12) 0%,
      rgba(255, 255, 255, 0.44) 18%,
      rgba(255, 255, 255, 0.80) 40%,
      rgba(255, 255, 255, 0.96) 62%,
      #ffffff 78%),
    var(--hero-photo) center top / cover no-repeat,
    linear-gradient(180deg, #ffffff 0%, color-mix(in oklab, white 96%, var(--blue)) 100%);
}

@media (min-width: 900px) { .hero { --hero-photo: url("../img/fondo1-1800.webp"); } }
@media (min-width: 1600px) { .hero { --hero-photo: url("../img/fondo1-2600.webp"); } }

/* The decorative tiles are gone: they were standing in for an image the
   site did not have. With the photograph in place they are just noise. */

/* The swoosh from the mark, opened out into signal rings */
.hero__arcs {
  position: absolute;
  top: 8%;
  right: -10%;
  width: 760px;
  height: 760px;
  opacity: 0.05;
  pointer-events: none;
}
.hero__arcs circle { fill: none; stroke: color-mix(in oklab, var(--blue) 20%, transparent); stroke-width: 1; }

.hero__inner { position: relative; z-index: 1; }

.hero__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 34px;
  align-items: center;
}

.hero__grid > div:first-child {
  max-width: 940px;
  margin-inline: auto;
  text-align: center;
}

.hero__grid > div:last-child {
  max-width: 1060px;
  margin-inline: auto;
  width: 100%;
}

.hero__place {
  display: inline-flex;
  align-items: center;
  gap: 11px;
  font-size: 0.6875rem;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ink-soft);
}

.hero__pulse { position: relative; width: 7px; height: 7px; border-radius: 50%; background: var(--green); }
.hero__pulse::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
  border: 1px solid var(--green);
  opacity: 0;
  animation: pulse 2.8s var(--ease) infinite;
}

@keyframes pulse {
  0% { opacity: 0.7; transform: scale(0.6); }
  70%, 100% { opacity: 0; transform: scale(1.6); }
}

.hero__title {
  margin: 16px 0 0;
  max-width: 26ch;
  font-size: clamp(2.4rem, 5.4vw, 4.6rem);
  font-weight: 600;
  line-height: 0.9;
  letter-spacing: -0.055em;
  font-variation-settings: "opsz" 84;
}
.hero__title em { font-style: normal; color: var(--green); }

/* Below the narrow breakpoint the first line only just fits, and the
   balancer keeps choosing "Conectando nuestra / gente," — leaving one
   orphan word. A break that exists only there settles it deterministically
   instead of depending on font metrics holding still. */
.hero__title-break { display: none; }

.hero__text { margin: 20px auto 0; max-width: 42ch; font-size: 0.9375rem; color: var(--ink-soft); }

.hero__actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 14px; margin-top: 28px; }
.hero__actions .link-arrow { color: var(--blue); }
.hero__actions .link-arrow:hover { color: var(--ink); }

/* Plan rail. The blur is doing a job: the cards sit over the gradient
   field and the signal rings, and have to stay legible without a fill
   that would cut the rings in half. */
.rail {
  display: flex;
  gap: 14px;
  overflow-x: auto;
  padding: 8px 4px 18px;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  /* "safe" is the whole point: plain centring on a scroll container puts
     the first card out of reach once the row overflows, because there is
     no way to scroll past the start edge. safe centres while it fits and
     falls back to flex-start the moment it does not. */
  justify-content: safe center;
}
.rail::-webkit-scrollbar { display: none; }

.rail-card {
  position: relative;
  flex: 0 0 196px;
  min-height: 236px;
  padding: 18px 20px 20px;
  scroll-snap-align: start;
  display: flex;
  flex-direction: column;
  border-radius: 28px;
  /* Same lit-surface language as the header bar: a fill that is brighter
     at the top than the bottom, and a specular line on the top edge. */
  background: linear-gradient(180deg,
    rgba(255, 255, 255, 0.94) 0%,
    rgba(255, 255, 255, 0.7) 100%);
  border: 1px solid rgba(255, 255, 255, 0.9);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 1px 2px color-mix(in oklab, var(--navy) 7%, transparent),
    0 12px 30px -16px color-mix(in oklab, var(--navy) 32%, transparent);
  transition: transform 0.5s var(--ease-quick), box-shadow 0.4s var(--ease);
}

.rail-card:hover {
  transform: translateY(-4px);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.95),
    0 2px 4px color-mix(in oklab, var(--navy) 8%, transparent),
    0 20px 42px -18px color-mix(in oklab, var(--navy) 40%, transparent);
}

.rail-card--pick {
  background: linear-gradient(180deg,
    color-mix(in oklab, var(--green) 16%, white) 0%,
    rgba(255, 255, 255, 0.82) 78%);
  border-color: color-mix(in oklab, var(--green) 26%, rgba(255, 255, 255, 0.9));
}

.rail-card__tag {
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.rail-card--pick .rail-card__tag { color: var(--green-deep); }

.rail-card__speed {
  /* Holds the figure, name and price against the bottom edge while the
     tag stays at the top — without a wrapper element to do it. */
  margin-top: auto;
  font-family: var(--font-display);
  font-size: 2.95rem;
  font-weight: 600;
  line-height: 0.88;
  font-variant-numeric: tabular-nums;
  font-variation-settings: "opsz" 40;
}
.rail-card__speed small {
  margin-left: 5px;
  font-family: var(--font-body);
  font-size: 0.8125rem;
  font-weight: 500;
  color: var(--ink-soft);
}

.rail-card__name { margin-top: 8px; font-size: 0.75rem; font-weight: 700; color: var(--ink); }
.rail-card__price { margin-top: 2px; font-size: 0.6875rem; font-variant-numeric: tabular-nums; color: var(--ink-soft); }

/* Shown only once JS confirms the row really does overflow: on a wide
   screen all four cards fit and the instruction is simply false. */
.rail-hint {
  display: none;
  align-items: center;
  gap: 10px;
  font-size: 0.625rem;
  color: var(--ink-soft);
}
.rail-hint.is-needed { display: flex; }
html:not(.js) .rail-hint { display: flex; }
.rail-hint::before { content: ""; width: 28px; height: 1px; background: var(--rule-strong); }

/* ---------- Ticker ---------- */
.ticker { background: var(--paper); border-block: 1px solid #eff2f7; padding: 15px 0; overflow: hidden; }

.ticker__track {
  display: flex;
  width: max-content;
  white-space: nowrap;
  animation: ticker 66s linear infinite;
  font-size: 0.75rem;
  font-weight: 500;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.ticker__item { display: inline-flex; align-items: center; }
.ticker__item::after { content: ""; width: 20px; height: 1px; margin: 0 26px; background: var(--rule-strong); }

@keyframes ticker {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(-50%, 0, 0); }
}

/* ---------- Services: editorial rows ---------- */
.editorial {
  display: grid;
  grid-template-columns: minmax(0, 0.7fr) minmax(0, 1.3fr);
  gap: 48px;
  align-items: start;
}
.editorial__aside { position: sticky; top: 132px; }

.editorial__aside .section-title { max-width: 12ch; }
.editorial__aside .section-lead { max-width: 34ch; }

.entry {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 26px;
  align-items: center;
  padding: 24px 0;
  border-top: 1px solid #eef1f6;
}
.entry:last-child { border-bottom: 1px solid #eef1f6; }

.entry__title { font-size: 1.25rem; font-variation-settings: "opsz" 22; }
.entry__text { margin-top: 10px; max-width: 54ch; font-size: 0.875rem; color: var(--ink-soft); }

.entry__mark {
  width: 38px;
  height: 38px;
  color: var(--rule-strong);
  transition: color 0.4s var(--ease), transform 0.6s var(--ease-quick);
}
.entry:hover .entry__mark { color: var(--green); transform: translateX(5px); }

/* ---------- Plans ---------- */
.plans-shell { container: plans / inline-size; }

.plans {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-rows: auto auto auto auto 1fr auto;
  column-gap: 16px;
  row-gap: 0;
}

.plan {
  grid-row: 1 / -1;
  display: grid;
  grid-template-rows: subgrid;
  padding: 26px 20px 20px;
  border: 1px solid #eef1f6;
  border-radius: 28px;
  background: white;
  box-shadow: none;
  overflow: hidden;
  transition: border-color 0.4s var(--ease), box-shadow 0.4s var(--ease), transform 0.4s var(--ease);
}

@supports not (grid-template-rows: subgrid) {
  .plan { grid-template-rows: auto auto auto auto 1fr auto; }
}

.plan:hover { transform: translateY(-4px); box-shadow: none; border-color: color-mix(in oklab, var(--blue) 14%, #e4eaf1); }

.plan--pick {
  position: relative;
  background: linear-gradient(180deg, color-mix(in oklab, var(--green) 10%, white), white 66%);
  border-color: color-mix(in oklab, var(--green) 16%, #dde7df);
}

/* Colour band. It is a grid item on the button's own row, not an
   absolutely positioned block: that way it can never grow into the
   feature list above it, whatever the copy length or the font. The
   negative margins bleed it out to the card's padding edges, and the
   card's overflow clip gives it the bottom corners for free. */
.plan::after {
  content: "";
  grid-row: 6;
  grid-column: 1;
  margin: -14px -20px -20px;
  background: linear-gradient(180deg, var(--blue), var(--blue-deep));
  pointer-events: none;
}

.plan:nth-child(2)::after { background: linear-gradient(180deg, var(--blue-deep), var(--navy-lift)); }
.plan:nth-child(3)::after { background: linear-gradient(180deg, var(--green), var(--green-deep)); }
.plan:nth-child(4)::after { background: linear-gradient(180deg, var(--navy-lift), var(--navy)); }

.plan > * { position: relative; z-index: 1; }

/* On a saturated band the outline and accent variants both lose their
   contrast, so inside a plan the call to action is always the white pill. */
.plan .btn {
  background: white;
  color: var(--ink);
  border-color: transparent;
  box-shadow: var(--shadow-sm);
}
.plan .btn:hover { background: color-mix(in oklab, white 93%, var(--blue)); }

.plan__flag {
  justify-self: start;
  padding: 4px 8px;
  background: color-mix(in oklab, var(--green) 14%, white);
  color: var(--green-deep);
  font-size: 0.6875rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border-radius: var(--r-xs);
}

.plan__name {
  align-self: end;
  font-family: var(--font-body);
  font-size: 0.75rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--ink-soft);
}
.plan--pick .plan__name { color: var(--green-deep); }

.plan__speed {
  margin-top: 10px;
  font-family: var(--font-display);
  font-size: 3rem;
  font-weight: 600;
  line-height: 0.92;
  letter-spacing: -0.035em;
  font-variant-numeric: tabular-nums;
  font-variation-settings: "opsz" 52;
}
.plan__speed small {
  display: block;
  margin-top: 5px;
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.plan--pick .plan__speed small { color: var(--green-deep); }

.plan__price {
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid #e5ebf2;
  font-family: var(--font-display);
  font-size: 1.25rem;
  font-weight: 700;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}
.plan--pick .plan__price { border-top-color: var(--rule-strong); }
.plan__period { font-family: var(--font-body); font-size: 0.6875rem; font-weight: 400; color: var(--ink-soft); }
.plan--pick .plan__period { color: var(--green-deep); }

.plan__features { margin: 18px 0 26px; display: grid; gap: 9px; align-content: start; font-size: 0.75rem; }
.plan__features li {
  display: grid;
  grid-template-columns: 13px 1fr;
  gap: 9px;
  align-items: start;
  color: var(--ink-soft);
}
.plan--pick .plan__features li { color: var(--ink-soft); }
.plan__features svg { width: 12px; height: 12px; margin-top: 4px; color: var(--green); }

.plans-note { margin-top: 24px; max-width: 78ch; font-size: 0.6875rem; color: var(--ink-soft); }

@container plans (max-width: 940px) {
  .plans { grid-template-columns: repeat(2, minmax(0, 1fr)); grid-template-rows: none; row-gap: 20px; }
  .plan { grid-row: auto; grid-template-rows: auto auto auto auto 1fr auto; }
}

@container plans (max-width: 520px) {
  .plans { grid-template-columns: 1fr; }
}

/* ---------- Coverage ---------- */
.coverage {
  display: grid;
  grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr);
  gap: 56px;
  align-items: start;
}
.coverage__aside { position: sticky; top: 132px; }
.coverage__actions { margin-top: 28px; }

.places { border-top: 1px solid #eef1f6; }

.place {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 20px;
  align-items: center;
  padding: 16px 8px 16px 0;
  border-bottom: 1px solid #eef1f6;
  transition: transform 0.4s var(--ease), background-color 0.4s var(--ease);
}
.place:hover {
  transform: translateX(12px);
  background: color-mix(in oklab, var(--green) 3%, transparent);
}

.place__name { font-family: var(--font-display); font-size: 1.05rem; font-weight: 600; letter-spacing: -0.02em; }
.place__region { margin-top: 2px; font-size: 0.6875rem; color: var(--ink-soft); }

.place__status {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 0.625rem;
  font-weight: 500;
  color: var(--green-deep);
  white-space: nowrap;
}
.place__status::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: var(--green); }

/* ---------- Contact ---------- */
.contact { display: grid; grid-template-columns: minmax(0, 0.82fr) minmax(0, 1.18fr); gap: 56px; align-items: start; }

.contact .section-title { max-width: 12ch; }

.facts { margin-top: 30px; border-top: 1px solid #eef1f6; }
.fact {
  display: grid;
  grid-template-columns: 122px minmax(0, 1fr);
  gap: 20px;
  align-items: start;
  padding: 14px 0;
  border-bottom: 1px solid #eef1f6;
}
.fact__key {
  padding-top: 2px;
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-soft);
}
.fact__value { margin: 0; font-size: 0.8125rem; font-weight: 500; }
.fact__value a { border-bottom: 1px solid var(--rule-strong); transition: border-color 0.25s var(--ease); }
.fact__value a:hover { border-bottom-color: var(--ink); }
.fact__value span { display: block; font-weight: 400; font-size: 0.75rem; color: var(--ink-soft); }

.form { display: grid; gap: 16px; }
.form__row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
.field { display: grid; gap: 8px; }

.label { font-size: 0.6875rem; font-weight: 500; color: var(--ink-soft); }

.input,
.select,
.textarea {
  width: 100%;
  padding: 12px 18px;
  font: inherit;
  font-size: 0.8125rem;
  color: var(--ink);
  background: white;
  border: 1px solid #e7edf5;
  border-radius: 18px;
  transition: border-color 0.3s var(--ease);
}

.input::placeholder,
.textarea::placeholder { color: var(--ink-soft); }

.input:focus,
.select:focus,
.textarea:focus { outline: none; border-color: var(--green); box-shadow: 0 0 0 4px color-mix(in oklab, var(--green) 8%, transparent); }

.select {
  appearance: none;
  padding-right: 40px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5l5-5' fill='none' stroke='%234c5a71' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 2px center;
  background-size: 12px;
}

/* Grows with what the visitor types instead of forcing a scrollbar */
.textarea { resize: none; min-height: 40px; field-sizing: content; }
@supports not (field-sizing: content) {
  .textarea { resize: vertical; min-height: 76px; }
}

.field:has(.input[aria-invalid="true"]) .input,
.field:has(.select[aria-invalid="true"]) .select,
.field:has(input[aria-invalid="true"]) .checkbox { border-color: var(--danger, #b3271b); }

.field.has-error .input,
.field.has-error .select,
.field.has-error .textarea { border-color: #b3271b; }

.field__error { font-size: 0.6875rem; color: #b3271b; }

.checkbox {
  display: grid;
  grid-template-columns: 16px 1fr;
  gap: 12px;
  align-items: start;
  font-size: 0.6875rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.checkbox input { margin-top: 3px; width: 16px; height: 16px; accent-color: var(--green); }
.checkbox a { border-bottom: 1px solid var(--rule-strong); }
.checkbox a:hover { border-bottom-color: var(--ink); }

.form__status { min-height: 21px; font-size: 0.75rem; font-weight: 500; color: var(--green-deep); }
.form__status.is-error { color: #b3271b; }

/* ---------- Closing block ---------- */
.closing {
  position: relative;
  color: var(--ink-soft);
  overflow: clip;
  background:
    radial-gradient(860px 520px at 88% 0%, color-mix(in oklab, var(--green) 7%, transparent), transparent 66%),
    radial-gradient(700px 520px at 8% 100%, color-mix(in oklab, var(--blue) 8%, transparent), transparent 64%),
    linear-gradient(180deg, white 0%, color-mix(in oklab, white 98%, var(--blue)) 100%);
}

/* The one dark surface on the site, and the only place it belongs: the
   last thing the visitor sees before deciding. The scrim is heavy on the
   left, where the words are, and thins out to the right so the sun
   survives — and it is mixed from the brand navy, never flat black. */
.closing__cta {
  position: relative;
  overflow: hidden;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 32px;
  align-items: end;
  margin: 62px 0 50px;
  padding: 64px 48px 52px;
  border-radius: 28px;
  color: var(--on-navy-soft);
  --closing-photo: url("../img/fondo2-1200.webp");
  background:
    linear-gradient(100deg,
      color-mix(in oklab, var(--navy) 90%, transparent) 0%,
      color-mix(in oklab, var(--navy) 72%, transparent) 42%,
      color-mix(in oklab, var(--navy) 20%, transparent) 100%),
    var(--closing-photo) center 46% / cover no-repeat,
    var(--navy);
}

@media (min-width: 900px) { .closing__cta { --closing-photo: url("../img/fondo2-1800.webp"); } }
@media (min-width: 1600px) { .closing__cta { --closing-photo: url("../img/fondo2-2600.webp"); } }

.closing__title { font-size: clamp(1.75rem, 4vw, 3rem); color: white; max-width: 16ch; font-variation-settings: "opsz" 34; }
.closing__text { margin-top: 14px; max-width: 42ch; color: var(--on-navy-soft); }
.closing__actions { display: flex; flex-wrap: wrap; gap: 14px; }

.footer { padding: 44px 0 28px; }
.footer__grid { display: grid; grid-template-columns: minmax(0, 1.6fr) minmax(0, 1fr) minmax(0, 1fr); gap: 36px; }

.footer__logo { height: 46px; width: auto; margin-bottom: 16px; }
.footer__about { font-size: 0.8125rem; max-width: 34ch; }

.footer__title {
  margin-bottom: 14px;
  font-family: var(--font-body);
  font-size: 0.625rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.footer__links { display: grid; gap: 8px; font-size: 0.8125rem; }
.footer__links a { width: fit-content; transition: color 0.25s var(--ease); }
.footer__links a:hover { color: var(--green); }

.footer__legal-line {
  margin-top: 36px;
  padding-top: 18px;
  border-top: 1px solid #eef1f6;
  display: flex;
  flex-wrap: wrap;
  gap: 8px 28px;
  justify-content: space-between;
  font-size: 0.625rem;
  color: var(--ink-soft);
}
.footer__legal-line strong { color: var(--ink); font-weight: 600; }

/* ---------- Floating WhatsApp ---------- */
.wa-float {
  position: fixed;
  right: 20px;
  bottom: 20px;
  z-index: var(--z-float);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 44px;
  padding: 0 16px 0 14px;
  border-radius: var(--r-pill);
  background: var(--green);
  color: white;
  font-size: 0.75rem;
  font-weight: 600;
  box-shadow: none;
  transition: transform 0.3s var(--ease), background-color 0.3s var(--ease),
    opacity 0.3s var(--ease), visibility 0.3s var(--ease);
}
.wa-float:hover { background: var(--green-deep); transform: translateY(-3px); }
.wa-float.is-tucked { opacity: 0; visibility: hidden; transform: translateY(14px); pointer-events: none; }
.wa-float:active { transform: translateY(0); }
.wa-float svg { width: 22px; height: 22px; flex: none; }

/* ============================================================
   Motion

   One authored moment: the display face itself. The hero headline
   is set at wdth 76 and opens toward its natural width as the page
   scrolls away, so the brand's own type does the work. Everything
   else enters quietly and differently by section, so no two blocks
   share the same entrance.
   ============================================================ */

.js .reveal { opacity: 0; transform: translate3d(0, 14px, 0); transition: opacity 0.8s var(--ease), transform 0.8s var(--ease); transition-delay: var(--delay, 0ms); }
.js .reveal.is-visible { opacity: 1; transform: none; }

@supports (animation-timeline: view()) {
  /* Native scroll-driven timelines: the JS observer stands down. */
  .js .reveal { opacity: 1; transform: none; transition: none; }

  .entry {
    animation: entry-in linear both;
    animation-timeline: view();
    animation-range: entry 6% cover 26%;
  }

  .place {
    animation: place-in linear both;
    animation-timeline: view();
    animation-range: entry 2% cover 22%;
  }

  .plan {
    animation: plan-in linear both;
    animation-timeline: view();
    animation-range: entry 8% cover 34%;
  }

  .hero__title {
    animation: headline-open linear both;
    animation-timeline: scroll(root);
    animation-range: 0 72vh;
  }

  .hero__arcs {
    animation: arcs-drift linear both;
    animation-timeline: scroll(root);
    animation-range: 0 100vh;
  }
}

@keyframes headline-open {
  to {
    font-variation-settings: "opsz" 96;
    letter-spacing: -0.04em;
    opacity: 0.28;
  }
}

@keyframes arcs-drift {
  to { transform: translateY(-50%) scale(1.35) rotate(12deg); opacity: 0.1; }
}

/* Rows wipe in from their own rule line */
@keyframes entry-in {
  from { opacity: 0; clip-path: inset(0 34% 0 0); }
  to { opacity: 1; clip-path: inset(0 0 0 0); }
}

@keyframes place-in {
  from { opacity: 0; transform: translate3d(-14px, 0, 0); }
  to { opacity: 1; transform: none; }
}

/* Cards settle out of a shallow blur rather than sliding */
@keyframes plan-in {
  from { opacity: 0; filter: blur(6px); transform: scale(0.985); }
  to { opacity: 1; filter: blur(0); transform: none; }
}

/* ---------- Legal and 404 pages ---------- */
.page-hero {
  padding: 156px 0 72px;
  color: white;
  background:
    radial-gradient(800px 500px at 10% 0%, color-mix(in oklab, var(--blue) 44%, transparent), transparent 60%),
    var(--navy);
}
.page-hero__title { font-size: clamp(2rem, 5vw, 3.2rem); font-variation-settings: "opsz" 40; }
.page-hero__meta { margin-top: 22px; font-size: 0.875rem; color: var(--on-navy-soft); }

.prose { max-width: 68ch; }
.prose h2 {
  margin: 54px 0 16px;
  padding-top: 28px;
  border-top: 1px solid var(--rule);
  font-size: 1.25rem;
  font-variation-settings: "opsz" 22;
}
.prose h2:first-of-type { border-top: 0; padding-top: 0; margin-top: 0; }
.prose p { margin-bottom: 15px; font-size: 0.9375rem; color: var(--ink-soft); }
.prose ul { margin: 0 0 18px; padding-left: 20px; list-style: disc; font-size: 0.9375rem; color: var(--ink-soft); }
.prose li { margin-bottom: 9px; }
.prose li::marker { color: var(--green); }
.prose a { color: var(--blue); border-bottom: 1px solid color-mix(in oklab, var(--blue) 34%, transparent); }
.prose a:hover { border-bottom-color: currentColor; }
.prose strong { color: var(--ink); font-weight: 600; }

.back-link {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 44px;
  font-size: 0.875rem;
  font-weight: 500;
  color: var(--ink-soft);
  transition: color 0.25s var(--ease);
}
.back-link:hover { color: var(--ink); }
.back-link svg { width: 15px; height: 15px; transition: transform 0.3s var(--ease); }
.back-link:hover svg { transform: translateX(-5px); }

.notfound { display: grid; place-items: center; text-align: center; padding: 154px 0 122px; }
.notfound__code {
  font-family: var(--font-display);
  font-size: clamp(5rem, 17vw, 6rem);
  font-weight: 800;
  line-height: 0.85;
  letter-spacing: -0.05em;
  font-variation-settings: "opsz" 64;
  color: var(--rule-strong);
}
.notfound__title { margin-top: 20px; font-size: clamp(1.35rem, 3vw, 2rem); }
.notfound__text { margin: 16px auto 30px; color: var(--ink-soft); }
.notfound__actions { display: flex; flex-wrap: wrap; gap: 14px; justify-content: center; }

/* ---------- Responsive ---------- */
/* Wide screens. The measure and the type cap were set so a 25-character
   line fits at 1200px; past that the hero keeps shrinking away from the
   viewport instead of growing with it. Both open up together — the cap
   alone would just force the line to wrap. */
@media (min-width: 1400px) {
  .hero__grid > div:first-child { max-width: 1080px; }
  .hero__title { font-size: clamp(2.4rem, 5vw, 5.6rem); }
  .hero__text { max-width: 48ch; font-size: 1rem; }
}

@media (max-width: 1080px) {
  /* minmax(0, …) and not 1fr: a bare 1fr keeps an automatic min-content
     minimum, and the plan rail's four fixed-width cards would blow the
     track out to 834px instead of scrolling inside it. */
  .hero__grid { grid-template-columns: minmax(0, 1fr); gap: 34px; }
  /* Bleeding past the right gutter tells the reader there is more to
     scroll. It only earns that on screens where the row overflows. */
  .rail { margin-right: calc(var(--gutter) * -1); }
  .hero__arcs { opacity: 0.14; right: -40%; }
  .editorial, .coverage, .contact { grid-template-columns: 1fr; gap: 34px; }
  .editorial__aside, .coverage__aside { position: static; }
  .section-head { max-width: 26ch; }
  .footer__grid { grid-template-columns: 1fr 1fr; gap: 30px; }
}

@media (max-width: 860px) {
  .nav-toggle { display: grid; }

  .header__nav {
    /* An absolutely positioned child of a grid container resolves its
       offsets against its grid area, not the padding box. Without the
       full-row span the panel would inherit the narrow middle column. */
    grid-column: 1 / -1;
    justify-self: stretch;
    position: absolute;
    top: calc(100% + 10px);
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 2px;
    padding: 10px;
    background: rgba(255, 255, 255, 0.97);
    border: 1px solid #eef1f6;
    border-radius: var(--r-md);
    box-shadow: none;
  }
  .header__nav.is-open { display: flex; }
  .header__nav .header__link { color: var(--ink); padding: 11px 12px; font-size: 0.9375rem; }

  /* Three objects in a 335px bar left the button crushed to 122px and the
     whole group shunted left. The bar now carries only the mark and the
     control; the actions move into the panel, where they get full width
     and the phone number comes back — on a phone, of all places. */
  .header__actions .btn { display: none; }

  .header__nav-cta {
    display: grid;
    gap: 8px;
    margin-top: 10px;
    padding-top: 12px;
    border-top: 1px solid var(--rule);
  }
  .header__nav-cta .btn { font-size: 0.8125rem; }
  .header__nav .header__link::before { left: 0; bottom: 50%; transform: translateY(50%) scale(0); }
  .header__nav .header__link.is-active::before { transform: translateY(50%) scale(1); }
  .header__phone { display: none; }
  /* auto 1fr auto, never auto 0 auto: without a flexible track the spare
     width piles up after the last column instead of between them. */
  .header__inner { width: 100%; grid-template-columns: auto 1fr auto; }
  /* The panel is absolutely positioned, so it leaves the grid flow and
     occupies no track. That leaves two items for three columns, and
     auto-placement drops the control into the middle one. Pin it. */
  .header__actions { grid-column: 3; justify-self: end; }
}

@media (max-width: 560px) {
  .header__inner {
    gap: 12px;
    grid-template-columns: auto minmax(0, 1fr) auto;
  }
  .header__inner { padding: 8px 14px; gap: 12px; }
  .header__logo { height: 36px; }
}

@media (max-width: 720px) {
  .section { padding: 60px 0 72px; }
  .hero { padding: 126px 0 56px; }
  .hero__title { font-size: clamp(2.25rem, 10.5vw, 3.4rem); max-width: 16ch; }
  .hero__title-break { display: inline; }
  .entry { grid-template-columns: minmax(0, 1fr); gap: 16px; padding: 20px 0; }
  .entry__mark { display: none; }
  .place__status { display: none; }
  .form__row { grid-template-columns: 1fr; }
  .fact { grid-template-columns: 1fr; gap: 6px; }
  .closing__cta { grid-template-columns: 1fr; align-items: start; padding: 40px 26px 36px; margin: 44px 0 40px; }
  .footer__grid { grid-template-columns: 1fr; gap: 28px; }
  .wa-float { padding: 0; width: 44px; justify-content: center; }
  .wa-float__text { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .ticker__track,
  .hero__pulse::after { animation: none; }
  .js .reveal { opacity: 1; transform: none; transition: none; }
  .btn, .plan, .rail-card, .place, .entry, .wa-float { transition: none; }
  .btn:hover, .btn:active, .plan:hover, .rail-card:hover { transform: none; }

  @supports (animation-timeline: view()) {
    .entry, .place, .plan, .hero__title, .hero__arcs { animation: none; }
  }

  ::view-transition-group(*),
  ::view-transition-old(*),
  ::view-transition-new(*) { animation: none !important; }
}
