/* ═══════════════════════════════════════════════════════════════════════
   Xanzo AI — conventional agency landing, Axion-shaped.

   v2. The split-stage build with the fixed centre rail is kept in
   lab/v1-split-stage/ and is not loaded by anything.

   Dark is the chosen and only theme. The light variant that was built for
   the comparison is kept whole in lab/v2-dual-theme.{css,html} and is not
   loaded by anything: a half-maintained second theme is a code path nobody
   verifies, and an unverified code path is worse than no code path.

   One accent, cyan, the cool end of the Xanzo gradient. The magenta-to-cyan
   gradient itself stays confined to the mark and to the hero field; it is
   never a background wash and never text.
   ═══════════════════════════════════════════════════════════════════════ */

:root {
  --sc-font-display: "Archivo", "Geist", system-ui, sans-serif;
  --sc-font-text:    "Geist", system-ui, sans-serif;
  --sc-font-mono:    "Geist Mono", ui-monospace, "SF Mono", monospace;

  --xz-mag:  #de02fb;
  --xz-vio:  #7a0fe8;
  --xz-cya:  #01d2fd;

  --xz-maxw: 1440px;
  --xz-pad:  clamp(1.25rem, 4vw, 3rem);
  --xz-nav-h: 4.25rem;
  /* Radius scale. Was seven ad-hoc values (4/6/8/12/18/20/999) with an
     18-vs-20 pair that was a pure accident. */
  --xz-r-xs: 6px;   /* chips, the focus ring */
  --xz-r-sm: 10px;  /* inputs, the hero badge, the card art band */
  --xz-r:    18px;  /* cards, panels, the form, the sheet */

  /* Type, small end. Was fourteen values inside a 2.2px window: .66 .7 .72
     .74 .78 .8 .82 .84 .85 .86 .87 .88 .92 .95rem. None of those were
     distinguishable and none of them were steps. */
  --xz-t-xs: .72rem;  /* mono micro-labels */
  --xz-t-sm: .84rem;  /* controls, nav, captions */
  --xz-t-md: .94rem;  /* body inside cards, panels and inputs */

  /* The two grounds are declared as channels, not hex, because every seam
     fades one of them to zero alpha. rgb(x / 0) off the same triple cannot
     drift away from the opaque value the way a second literal would. */
  --sc-ground-a-ch: 8 9 12;    /* deep:   hero field, el metodo, contacto */
  --sc-ground-b-ch: 16 19 24;  /* raised: que hacemos, footer */
  --sc-canvas:     rgb(var(--sc-ground-a-ch));
  --sc-surface:    rgb(var(--sc-ground-b-ch));
  --sc-raise:      #151920;
  --sc-ink:        #f2f4f7;
  --sc-ink-soft:   #98a0ad;
  --sc-accent:     #2fe4f2;
  --sc-accent-ink: #04141a;
  --xz-line:       rgba(255, 255, 255, 0.11);
  --xz-line-soft:  rgba(255, 255, 255, 0.07);
  --xz-nav-bg:     rgba(20, 24, 31, 0.72);
  /* Tinted to the canvas hue: a pure-black shadow on a coloured dark ground
     resolves to a 4-level difference and reads as dirt, not depth. */
  /* Two elevation steps. One 40px-blur token was doing both the ~36px hero
     badge and the ~460px form, which floats a chip a foot off the page. */
  --xz-shadow-sm:  0 1px 2px hsl(220 40% 2% / .45), 0 4px 10px -4px hsl(220 40% 2% / .5);
  --xz-shadow:     0 2px 6px hsl(220 40% 2% / .5), 0 16px 40px -12px hsl(220 40% 2% / .62);
  /* Derived, not a hand-copied literal: the card art is the largest accent
     surface on the page and must follow the token if the accent ever moves. */
  --xz-art:        color-mix(in oklab, var(--sc-accent) 50%, transparent);
  color-scheme: dark;
}

/* The nav is fixed. Without this, Shift+Tab to a control above the viewport
   scrolls its top edge to y=0, i.e. underneath the bar (WCAG 2.4.11), and
   every in-page anchor lands with its heading tucked behind the same bar. */
html { scroll-padding-top: calc(var(--xz-nav-h) + 1rem); }

* { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--sc-canvas);
  color: var(--sc-ink);
  font-family: var(--sc-font-text);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}

::selection { background: var(--sc-accent); color: var(--sc-accent-ink); }
:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 3px; border-radius: var(--xz-r-xs); }

.xz-wrap { max-width: var(--xz-maxw); margin-inline: auto; padding-inline: var(--xz-pad); }

.xz-skip {
  position: fixed; top: 10px; left: 10px; z-index: 300;
  transform: translateY(-200%);
  background: var(--sc-accent); color: var(--sc-accent-ink);
  padding: .55em 1em; border-radius: 999px; text-decoration: none;
  font-size: var(--xz-t-sm); font-weight: 500;
  transition: transform 160ms cubic-bezier(.23,1,.32,1);
}
.xz-skip:focus-visible { transform: translateY(0); }


/* ── Type ─────────────────────────────────────────────────────────────── */

.xz-h1 {
  margin: 0;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(2rem, 5.2vw, 4.2rem);
  line-height: 1.06; letter-spacing: -.032em;
  text-wrap: balance;
}
.xz-h2 {
  margin: 0;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.5rem, 3.4vw, 3rem);
  line-height: 1.1; letter-spacing: -.024em;
  text-wrap: balance;
}
.xz-lede { margin: 0; font-size: clamp(1rem, 0.94rem + 0.28vw, 1.125rem); line-height: 1.62; color: var(--sc-ink-soft); max-width: 52ch; text-wrap: pretty; }
.xz-note { margin: 0; font-size: var(--xz-t-sm); line-height: 1.55; color: var(--sc-ink-soft); max-width: 56ch; }
.xz-tag  { margin: 0; font-family: var(--sc-font-mono); font-size: var(--xz-t-xs); letter-spacing: .15em; text-transform: uppercase; color: var(--sc-ink-soft); }

/* Numbered badge + pill label, the Axion section-opener pattern. */
.xz-eyebrow { display: flex; align-items: center; gap: .7rem; margin: 0 0 1.4rem; }
/* Flex gap ADDS to this margin, so the same eyebrow/heading pair rendered at
   22px in two sections, 35px in a third and 45px in a fourth. Zero it wherever
   the parent already owns the spacing. */
.xz-close .xz-eyebrow { margin-bottom: 0; }
.xz-eyebrow i {
  display: grid; place-items: center; flex: none;
  width: 1.7rem; height: 1.7rem; border-radius: 999px;
  background: var(--sc-ink); color: var(--sc-canvas);
  font-style: normal; font-size: var(--xz-t-xs); font-weight: 600;
  font-family: var(--sc-font-text);
}
.xz-eyebrow span {
  border: 1px solid var(--xz-line); border-radius: 999px;
  padding: .3rem .85rem; font-size: var(--xz-t-sm); font-weight: 500;
}

.xz-br { display: none; }
@media (min-width: 780px) { .xz-br { display: block; } }


/* ── Buttons ──────────────────────────────────────────────────────────── */

.xz-btn {
  display: inline-flex; align-items: center; gap: .6rem;
  padding: .45rem .45rem .45rem 1.15rem;
  border: 1px solid transparent; border-radius: 999px;
  font-size: var(--xz-t-sm); font-weight: 500; line-height: 1;
  text-decoration: none; cursor: pointer; white-space: nowrap;
  transition: background 160ms cubic-bezier(.23,1,.32,1), transform 110ms cubic-bezier(.23,1,.32,1), border-color 160ms var(--sc-ease-out);
}
.xz-btn--lg { font-size: var(--xz-t-md); padding: .55rem .55rem .55rem 1.4rem; }
.xz-btn--wide { width: 100%; justify-content: space-between; }
.xz-btn--accent { background: var(--sc-accent); color: var(--sc-accent-ink); }
.xz-btn--dark   { background: var(--sc-ink);    color: var(--sc-canvas); }
/* A ghost carrying the arrow disc keeps the button padding, so the disc has
   room; only the fill goes. Used for the in-page jump, which is navigation and
   should not wear the conversion treatment. */
.xz-btn--ghost  { background: transparent; color: var(--sc-accent); border-color: color-mix(in oklab, var(--sc-accent) 55%, transparent); padding: .7rem 1.4rem; }
/* A ghost that carries the arrow disc goes back to button padding so the disc
   has room on the right. */
.xz-btn--ghost:has(.xz-btn__disc) { padding: .45rem .45rem .45rem 1.15rem; }
.xz-btn--ghost .xz-btn__disc { background: transparent; border: 1px solid color-mix(in oklab, var(--sc-accent) 45%, transparent); color: var(--sc-accent); }

.xz-btn__disc {
  display: grid; place-items: center; flex: none;
  width: 1.75rem; height: 1.75rem; border-radius: 999px;
  background: var(--sc-canvas); color: var(--sc-ink);
  transition: transform 260ms cubic-bezier(.23,1,.32,1);
}
.xz-btn--dark .xz-btn__disc { background: var(--sc-canvas); color: var(--sc-ink); }
.xz-btn--accent .xz-btn__disc { background: var(--sc-accent-ink); color: var(--sc-accent); }
.xz-btn--lg .xz-btn__disc { width: 2rem; height: 2rem; }

/* Text roll: the label is duplicated and the stack slides one line up. */
.xz-roll { display: block; overflow: hidden; height: 1em; }
.xz-roll > span { display: block; height: 1em; transition: transform 240ms var(--sc-ease-out); }

@media (hover: hover) and (pointer: fine) {
  .xz-btn:hover .xz-roll > span:first-child { transform: translateY(-100%); }
  .xz-btn:hover .xz-btn__disc { transform: translate(2px, -2px) rotate(45deg); }
  .xz-btn--accent:hover { filter: brightness(1.08); }
  .xz-btn--dark:hover   { filter: brightness(1.25); }
  .xz-btn--ghost:hover  { background: color-mix(in oklab, var(--sc-accent) 12%, transparent); }
}
.xz-btn:active { transform: translateY(1px); }


/* ── Nav ──────────────────────────────────────────────────────────────── */

.xz-nav { position: fixed; inset: 0 0 auto; z-index: 100; padding: .6rem var(--xz-pad); }
.xz-nav__bar {
  /* Its own cap. At the page max-width the bar stretched to 1342px with ~470px
     of dead air in the middle and a 27px effective corner: not a pill any more,
     just a very wide rounded rectangle, and it is the first object on the page. */
  max-width: min(var(--xz-maxw), 1100px); margin-inline: auto;
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
  padding: 5px 5px 5px 1rem;
  background: var(--xz-nav-bg);
  -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px);
  border: 1px solid var(--xz-line-soft);
  border-radius: 999px;
  box-shadow: var(--xz-shadow-sm), var(--sc-edge);
}
.xz-nav__left  { display: flex; align-items: center; gap: 1.6rem; min-width: 0; }
.xz-nav__right { display: none; align-items: center; gap: 1rem; }

.xz-lockup { display: inline-flex; align-items: center; gap: .5rem; text-decoration: none; color: inherit; }
.xz-lockup img { width: 1.7rem; height: auto; display: block; }
.xz-lockup span { font-family: var(--sc-font-display); font-weight: 600; font-size: 1rem; letter-spacing: -.02em; }
.xz-lockup b { font-weight: 600; color: var(--sc-accent); }  /* spacing comes from a real &nbsp; in the markup, not a margin */

.xz-nav__links { display: none; gap: 1.5rem; }
.xz-nav__links a { color: inherit; text-decoration: none; font-size: var(--xz-t-sm); transition: color 180ms var(--sc-ease-out); }
@media (hover: hover) and (pointer: fine) { .xz-nav__links a:hover { color: var(--sc-accent); } }

.xz-burger {
  display: inline-flex; align-items: center; gap: .45rem;
  background: var(--sc-ink); color: var(--sc-canvas);
  border: 0; border-radius: 999px; padding: .6rem 1rem;
  font: 500 .82rem/1 var(--sc-font-text); cursor: pointer;
}
.xz-burger--close { background: transparent; color: var(--sc-ink); border: 1px solid var(--xz-line); }

@media (min-width: 900px) {
  .xz-nav__links, .xz-nav__right { display: flex; }
  /* Scoped to the nav. ".xz-burger" is worn by two controls: the nav "Menú"
     button AND the sheet own "Cerrar" button. Unscoped, this hid the close
     button too, so a sheet opened below 900px and then widened past it had no
     visible way out. */
  .xz-nav__bar .xz-burger { display: none; }
}


/* ── Mobile sheet ─────────────────────────────────────────────────────── */

.xz-sheet { position: fixed; inset: 0; z-index: 200; }
.xz-sheet__scrim { position: absolute; inset: 0; background: rgba(0,0,0,.6); opacity: 0; transition: opacity 260ms var(--sc-ease-out); }
.xz-sheet__panel {
  position: absolute; inset: auto .6rem .6rem;
  background: var(--sc-surface); color: var(--sc-ink);
  border: 1px solid var(--xz-line); border-radius: var(--xz-r);
  padding: 1.1rem;
  transform: translateY(110%);
  transition: transform 460ms cubic-bezier(.32,.72,0,1);
  box-shadow: var(--xz-shadow), var(--sc-edge);  /* edge light: a 1px top highlight sells a raised surface better than blur */
}
.xz-sheet[data-xz-open] .xz-sheet__scrim { opacity: 1; }
.xz-sheet[data-xz-open] .xz-sheet__panel { transform: translateY(0); }
.xz-sheet__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: .8rem; }
.xz-sheet__links { display: grid; gap: .1rem; margin-bottom: 1rem; }
.xz-sheet__links a {
  color: inherit; text-decoration: none;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: 1.75rem; letter-spacing: -.02em;
  padding: .35rem 0; border-bottom: 1px solid var(--xz-line-soft);
}


/* ── Hero ─────────────────────────────────────────────────────────────── */

.xz-hero {
  position: relative;
  min-height: 100svh;
  display: flex; flex-direction: column; justify-content: flex-end;
  overflow: hidden;
  isolation: isolate;
}
.xz-hero__bg { position: absolute; inset: 0; width: 100%; height: 100%; z-index: -2; display: block; }
/* Fallback ground: if WebGL is unavailable the canvas paints nothing, so the
   hero must still be a designed surface rather than a flat rectangle. */
.xz-hero::before {
  content: ""; position: absolute; inset: 0; z-index: -3;
  background:
    radial-gradient(58% 48% at 18% 22%, color-mix(in oklab, var(--xz-vio) 26%, transparent), transparent 70%),
    radial-gradient(52% 46% at 82% 30%, color-mix(in oklab, var(--xz-cya) 24%, transparent), transparent 68%),
    radial-gradient(70% 60% at 50% 96%, color-mix(in oklab, var(--xz-mag) 12%, transparent), transparent 72%),
    var(--sc-canvas);
}
/* Density only where the copy sits, never a full-frame overlay. */
.xz-hero__veil {
  position: absolute; inset: 0; z-index: -1; pointer-events: none;
  background: linear-gradient(to top,
    rgb(var(--sc-ground-b-ch))       0%,
    rgb(var(--sc-ground-b-ch) / .90) 11%,
    rgb(var(--sc-ground-b-ch) / .60) 28%,
    rgb(var(--sc-ground-b-ch) / 0)   60%);
}
.xz-hero__inner {
  width: 100%; max-width: var(--xz-maxw); margin-inline: auto;
  padding: 0 var(--xz-pad) clamp(3rem, 7vh, 5rem);
}
.xz-hero__label { margin-bottom: clamp(1rem, 2.4vh, 1.75rem); }
.xz-hero__cta { display: flex; flex-wrap: wrap; align-items: center; gap: 1rem; margin-top: clamp(1.75rem, 4vh, 3rem); }

/* ── Sections ─────────────────────────────────────────────────────────── */

.xz-sec { padding-block: clamp(4.5rem, 10vw, 9rem); }
.xz-sec--a { background: var(--sc-surface); }
.xz-sec--b { background: var(--sc-canvas); }
.xz-sec--d { background: var(--sc-canvas); }
/* --c was the third ground of the five-section page and matched nothing in
   the markup any more, so it is gone rather than kept "in case". --b also
   carried padding-block: 0, left over from when it held the pinned demo
   stage; with an ordinary section in there its heading sat flush on the
   boundary with nothing above it. */


/* ── Seams ────────────────────────────────────────────────
   The grounds alternate, so every change of section landed as a hard
   horizontal line straight across the page. A section that sits on a
   different ground than whatever is above it now STARTS on that previous
   ground and dissolves it over a band, so scrolling reads as one surface
   changing rather than as two rectangles butted together.

   The band is a pseudo-element, not a gradient on the section's own
   background, because that background has to stay a flat colour: the
   contrast checks resolve text against the nearest painted ancestor, and a
   gradient there would make that answer depend on the y position.

   isolation + z-index: -1 puts the band above the section's own background
   and below every child, so no content rule is needed to stay clear of it.
   ───────────────────────────────────────────────────────── */

.xz-sec--b, .xz-foot { position: relative; isolation: isolate; }
.xz-sec--b::before, .xz-foot::before {
  content: ""; position: absolute; inset-inline: 0; top: 0; z-index: -1;
  height: clamp(5rem, 15vh, 11rem);
  pointer-events: none;
}
/* Que hacemos (raised) into el metodo (deep). */
.xz-sec--b::before {
  background: linear-gradient(to bottom,
    rgb(var(--sc-ground-b-ch)) 0%, rgb(var(--sc-ground-b-ch) / 0) 100%);
}
/* Contacto (deep) into the footer (raised). */
.xz-foot::before {
  background: linear-gradient(to bottom,
    rgb(var(--sc-ground-a-ch)) 0%, rgb(var(--sc-ground-a-ch) / 0) 100%);
}

.xz-que { display: grid; gap: clamp(2rem, 5vw, 4rem); margin-top: clamp(2.5rem, 6vw, 5rem); }
@media (min-width: 940px) { .xz-que { grid-template-columns: minmax(0, .92fr) minmax(0, 1.08fr); align-items: start; } }
.xz-que__copy { display: flex; flex-direction: column; align-items: flex-start; gap: 1.6rem; }

.xz-pillars { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.xz-pillars li { padding: 1.25rem 0; border-top: 1px solid var(--xz-line); }
.xz-pillars li:last-child { border-bottom: 1px solid var(--xz-line); }
.xz-pillars h3 { margin: 0 0 .35rem; font-family: var(--sc-font-display); font-weight: 500; font-size: clamp(1.12rem, 1.5vw, 1.35rem); line-height: 1.2; letter-spacing: -.015em; }
.xz-pillars p { margin: 0; font-size: var(--xz-t-md); color: var(--sc-ink-soft); max-width: 46ch; }


/* ── The method: numbered steps ───────────────────────────────────────
   Replaces the side-by-side demo. Each step is a number, a claim and the
   concrete things that come out of it, so the section reads as a process
   rather than as three more cards. ─────────────────────────────────────── */

.xz-sec__lede { margin-top: 1.1rem; }

.xz-steps-list {
  list-style: none; margin: clamp(2.5rem, 6vw, 4.5rem) 0 0; padding: 0;
  display: grid; gap: 0;
}
.xz-step {
  display: grid; gap: .6rem 1.6rem;
  padding: clamp(1.75rem, 3.5vw, 2.75rem) 0;
  border-top: 1px solid var(--xz-line);
}
.xz-step:last-child { border-bottom: 1px solid var(--xz-line); }

/* The numeral is the section's spine: one column of 01/02/03 running down the
   left edge, not a badge stuck on a card. */
.xz-step__n { margin: 0; }
.xz-step__n span {
  display: inline-grid; place-items: center;
  width: 2.6rem; height: 2.6rem; border-radius: 999px;
  border: 1px solid color-mix(in oklab, var(--sc-accent) 38%, transparent);
  color: var(--sc-accent);
  font-family: var(--sc-font-mono); font-size: var(--xz-t-sm); letter-spacing: .06em;
}
.xz-step__body { min-width: 0; }
.xz-step__body h3 {
  margin: 0 0 .5rem;
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.3rem, 2.2vw, 1.9rem); line-height: 1.14; letter-spacing: -.02em;
}
.xz-step__body > p {
  margin: 0 0 1.1rem;
  font-size: var(--xz-t-md); line-height: 1.65; color: var(--sc-ink-soft);
  max-width: 62ch;
}
.xz-step__body ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .5rem; }
.xz-step__body ul li {
  position: relative; padding-left: 1.4rem;
  font-size: var(--xz-t-sm); line-height: 1.5; color: var(--sc-ink-soft);
  max-width: 60ch;
}
/* A rule, not a bullet glyph: the page has no other bulleted list and a disc
   would be the only one of its kind. */
.xz-step__body ul li::before {
  content: ""; position: absolute; left: 0; top: .62em;
  width: .75rem; height: 1px; background: var(--sc-accent);
}

@media (min-width: 760px) {
  .xz-step { grid-template-columns: 2.6rem minmax(0, 1fr); }
}


/* ── Close ────────────────────────────────────────────────────────────── */

/* Two columns: the argument on the left, the form on the right. One column
   below 960px, where a side-by-side would squeeze both. */
.xz-close { display: grid; gap: clamp(2.5rem, 5vw, 4rem); align-items: start; }
@media (min-width: 960px) {
  .xz-close { grid-template-columns: minmax(0, 1fr) minmax(0, .92fr); }
}
.xz-close__copy { display: flex; flex-direction: column; align-items: flex-start; }
.xz-close__h { max-width: 24ch; }
.xz-close__lede { margin: 1.25rem 0 2rem; }


/* ── The form ─────────────────────────────────────────────────────────
   Hand-written rather than a third-party embed. An embedded form lives in
   an iframe, which means its contrast, its focus ring and its error
   handling are someone else's and cannot be measured from here: the
   regression suite cannot see inside one, and this build's whole method is
   measuring what it ships.
   ─────────────────────────────────────────────────────────────────────── */

.xz-form {
  display: grid; grid-template-columns: 1fr 1fr; gap: .9rem 1.1rem;
  background: var(--sc-surface);
  border: 1px solid var(--xz-line); border-radius: var(--xz-r);
  padding: clamp(1.25rem, 2.5vw, 2rem);
  box-shadow: var(--xz-shadow), var(--sc-edge);
}
.xz-form__title { grid-column: 1 / -1; margin: 0; font-size: 1rem; font-weight: 500; color: var(--sc-ink); }
.xz-field { margin: 0; display: grid; gap: .3rem; }
.xz-field--wide { grid-column: 1 / -1; }
.xz-field label { font-size: var(--xz-t-sm); color: var(--sc-ink-soft); }
/* Marking the one optional field beats starring the three required ones:
   no asterisk key to explain, and nothing carried by colour alone. */
.xz-field__opt { color: var(--sc-ink-soft); opacity: .8; }
.xz-field input, .xz-field textarea {
  font: 400 var(--xz-t-md)/1.5 var(--sc-font-text); color: var(--sc-ink);
  background: var(--sc-canvas);
  /* A control boundary is a UI component, not a decorative hairline, so
     WCAG 1.4.11 wants 3:1. --xz-line composites to 1.28:1 over this fill.
     0.34 alpha lands at 3.02:1. */
  border: 1px solid rgba(255, 255, 255, 0.34); border-radius: var(--xz-r-sm);
  padding: .6em .75em; width: 100%;
  caret-color: var(--sc-accent);
  transition: border-color 160ms var(--sc-ease-out);
}
.xz-field textarea { resize: vertical; min-height: 5.5em; }
@media (hover: hover) and (pointer: fine) {
  .xz-field input:hover, .xz-field textarea:hover { border-color: color-mix(in oklab, var(--sc-ink) 28%, transparent); }
}
.xz-field input:focus-visible, .xz-field textarea:focus-visible { border-color: var(--sc-accent); }
/* The invalid state is a border colour AND a message, never colour alone
   (WCAG 1.4.1). */
.xz-field input[aria-invalid="true"], .xz-field textarea[aria-invalid="true"] { border-color: #ff9a8b; }
.xz-field__err:empty { display: none; }
.xz-field__err { font-size: var(--xz-t-sm); line-height: 1.4; color: #ff9a8b; }

.xz-form__send { margin-top: .2rem; }
.xz-form__send .xz-btn { width: 100%; justify-content: center; }
.xz-form__status { grid-column: 1 / -1; margin: 0; font-size: var(--xz-t-sm); line-height: 1.55; color: var(--sc-accent); }
.xz-form__status:empty { display: none; }
.xz-form__status[data-xz-err] { color: #ff9a8b; }
.xz-form__status a { color: inherit; }

/* Visually hidden, still in the accessibility tree where it is wanted. */
.xz-sr {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%); overflow: hidden; white-space: nowrap;
}
/* The honeypot control keeps its own layout width inside that 1px box, which
   the clip hides but which still measures 227px. Pinning it here keeps the
   invariant on the element itself rather than on its parent's clip. */
.xz-sr input { width: 1px; height: 1px; min-height: 0; padding: 0; border: 0; }


/* ── Footer ───────────────────────────────────────────────────────────
   Columns, not a single strip. It was ~91px of three dim links on the same
   ground as the section above it, so the page had no closing beat at all. ── */

.xz-foot {
  background: var(--sc-surface);
  /* No top rule. It was the only hard line left once the grounds started
     dissolving into each other, and the columns plus the base rule already
     say "footer" without one. The top padding is opened up so the seam has
     somewhere to land before the first column heading. */
  padding-block: clamp(4rem, 8vw, 6.5rem) 0;
}
.xz-foot__grid { display: grid; gap: 2.5rem 2rem; }
@media (min-width: 720px) {
  .xz-foot__grid { grid-template-columns: minmax(0, 1.6fr) repeat(3, minmax(0, 1fr)); gap: 2rem; }
}
.xz-foot__brand { display: flex; flex-direction: column; align-items: flex-start; gap: .9rem; }
.xz-foot__brand p { margin: 0; font-size: var(--xz-t-sm); line-height: 1.6; color: var(--sc-ink-soft); max-width: 34ch; }

.xz-foot__col h2 {
  margin: 0 0 .9rem;
  font-family: var(--sc-font-mono); font-size: var(--xz-t-xs); font-weight: 500;
  letter-spacing: .15em; text-transform: uppercase; color: var(--sc-ink-soft);
}
.xz-foot__col ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .55rem; }
.xz-foot__col a {
  color: var(--sc-ink); text-decoration: none;
  font-size: var(--xz-t-sm); text-underline-offset: 3px;
}
@media (hover: hover) and (pointer: fine) {
  .xz-foot__col a:hover { color: var(--sc-accent); text-decoration: underline; }
}
/* A link whose URL does not exist yet should not look like one that does. */
.xz-foot__col a[aria-disabled="true"] { color: var(--sc-ink-soft); cursor: default; }
.xz-foot__col ul:not(.xz-social) a[aria-disabled="true"]::after { content: " · pendiente"; font-size: .85em; opacity: .7; }

.xz-foot__base {
  margin-top: clamp(2rem, 4vw, 3rem);
  padding-block: 1.25rem;
  border-top: 1px solid var(--xz-line-soft);
}
.xz-foot__base p { margin: 0; font-size: var(--xz-t-sm); color: var(--sc-ink-soft); }

/* ── Social marks ─────────────────────────────────────────────────────
   The three brand glyphs, solid, in a row. They are the one place on the
   page that is not drawn in the site's own 1.6px stroke language, and that
   is deliberate: a logo redrawn as an outline stops being the logo.
   ─────────────────────────────────────────────────────────────────────── */

/* Scoped through .xz-foot__col on purpose: the column rule above is
   `.xz-foot__col ul { display: grid }`, which outranks a bare .xz-social and
   silently stacked the three marks in a vertical line. */
.xz-foot__col ul.xz-social {
  list-style: none; margin: 1.35rem 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: .5rem;
}
.xz-social a {
  display: inline-grid; place-items: center;
  /* 40px. WCAG 2.5.8 asks 24; an icon-only control in a footer is exactly
     where an undersized target hurts, so it gets the comfortable size. */
  width: 2.5rem; height: 2.5rem;
  border: 1px solid var(--xz-line); border-radius: 999px;
  color: var(--sc-ink-soft);
  transition: color 160ms var(--sc-ease-out), border-color 160ms var(--sc-ease-out),
              background 160ms var(--sc-ease-out);
}
.xz-social a:hover { text-decoration: none; }
@media (hover: hover) and (pointer: fine) {
  .xz-social a:not([aria-disabled="true"]):hover {
    color: var(--sc-accent);
    border-color: color-mix(in oklab, var(--sc-accent) 55%, transparent);
    background: color-mix(in oklab, var(--sc-accent) 10%, transparent);
  }
}
/* A network with no URL yet must not look like one that works. */
.xz-social a[aria-disabled="true"] { opacity: .4; cursor: default; }
.xz-social svg { display: block; }


/* ── Legal documents ──────────────────────────────────────────────────
   privacidad.html and terminos.html. A document, not a landing page: one
   column, generous measure, no scroll devices, no engine. They borrow the
   tokens and nothing else. This lived inline in privacidad.html until the
   second page appeared and would have copied every line of it.
   ─────────────────────────────────────────────────────────────────────── */

.xz-legal {
  max-width: 46rem; margin-inline: auto;
  padding: calc(var(--xz-nav-h) + 3rem) var(--xz-pad) 5rem;
}
.xz-legal h1 {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.9rem, 4vw, 2.8rem); line-height: 1.1; letter-spacing: -.028em;
  margin: 0 0 .6rem;
}
.xz-legal h2 {
  font-family: var(--sc-font-display); font-weight: 500;
  font-size: clamp(1.1rem, 1.8vw, 1.35rem); line-height: 1.2; letter-spacing: -.015em;
  margin: 2.6rem 0 .7rem;
}
.xz-legal p, .xz-legal li { font-size: var(--xz-t-md); line-height: 1.68; color: var(--sc-ink-soft); }
.xz-legal p { margin: 0 0 1rem; }
.xz-legal ul { margin: 0 0 1rem; padding-left: 1.1rem; }
.xz-legal li { margin-bottom: .45rem; }
.xz-legal a { color: var(--sc-accent); text-underline-offset: 3px; }
.xz-legal strong { color: var(--sc-ink); font-weight: 500; }
.xz-legal__date {
  font-family: var(--sc-font-mono); font-size: var(--xz-t-xs);
  letter-spacing: .12em; text-transform: uppercase; color: var(--sc-ink-soft);
  margin-bottom: 2.5rem;
}
/* Anything only the business can supply is marked, so it is obvious in the
   rendered page and cannot be shipped by accident. */
.xz-todo { color: var(--sc-accent); border-bottom: 1px dashed currentColor; font-style: normal; }

.xz-legal__nav {
  display: flex; flex-wrap: wrap; gap: .75rem 1.75rem;
  margin-top: 3rem; padding-top: 1.5rem;
  border-top: 1px solid var(--xz-line-soft);
}
.xz-legal__nav a {
  display: inline-flex; align-items: center; gap: .5rem;
  font-size: var(--xz-t-sm); color: var(--sc-accent); text-decoration: none;
}
.xz-legal__nav a:hover { text-decoration: underline; text-underline-offset: 3px; }


/* The engine ships [data-sc-in] { opacity: 0 } unconditionally and only ever
   removes it from JavaScript, so a blocked or broken scrollcraft.js left the
   three pillars and all three method steps as blank space under two orphan
   headings. The watchdog inline in <head> sets .sc-rescue when the engine
   never announced itself, and this un-hides everything it was holding.
   The engine's own files are not touched. */
.sc-rescue [data-sc-in],
.sc-rescue [data-sc-stagger] > * { opacity: 1 !important; transform: none !important; }


/* Entrance reveals are the engine's: it already ships the opacity/rise pair
   for [data-sc-in] and the stagger for [data-sc-stagger] > *, including the
   reduced-motion floor. Restating them here only fights it. */

@media (prefers-reduced-motion: reduce) {
  .xz-btn, .xz-btn__disc, .xz-roll > span, .xz-skip, .xz-social a,
  .xz-field input, .xz-field textarea { transition: none; }
  .xz-sheet__panel { transition: none; }
}
