/* =============================================================================
   Iluena — the product's own site (apex domain).
   Loaded ONLY by templates/site/, on top of app.css + cinematic.css, so it can
   be read as one piece and never affects the owner tool or a booking page.

   Four short tabs, one real page each: the pitch, the working day, the
   customers, and whether it fits your trade — plus the sign-up. Same identity
   as the product — warm paper, jewel teal, serif voice — pushed to commercial
   scale, and every claim illustrated by the screen it actually produces.
   ============================================================================= */

/* ------------------------------------------------------------------ header -- */
.lp-top {
  --top-pad: clamp(1rem, 5vw, 3rem);
  position: sticky;
  top: 0;
  z-index: 50;
  display: flex;
  align-items: center;
  gap: 0.9rem;
  padding: 0.8rem var(--top-pad);
  /* A touch more opaque than the app's own bar: this header spends its first
     screen sitting on the teal hero, and at the shared 82% the secondary ink in
     it lands at 4.49:1 — just under AA. At 92% it clears with room. */
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  -webkit-backdrop-filter: var(--header-blur);
  backdrop-filter: var(--header-blur);
  border-bottom: 1px solid var(--border);
  transition: border-color 0.3s var(--ease), box-shadow 0.3s var(--ease);
}

/* A separator is only needed once there is something to separate from. While
   the page is at the top the bar floats on the hero with no line at all; the
   edge arrives with the first bit of scroll, and leaves when you come back.
   Gated on JS being present, so without it the line is simply always there. */
.has-motion .lp-top {
  border-bottom-color: transparent;
}

.has-motion .lp-top.is-scrolled {
  border-bottom-color: var(--border);
  box-shadow: 0 10px 24px -26px rgba(6, 26, 24, 0.9);
}

/* -------------------------------------------------------------------- tabs -- */
/* The site is four short pages, so the bar switches pages rather than jumping
   down one long one. The current tab is marked server-side, which means it is
   right with JavaScript off. On a phone the tabs take a row of their own and
   scroll sideways instead of shrinking to unreadable. */
.lp-tabs {
  display: flex;
  align-items: center;
  gap: 0.1rem;
  min-width: 0;
  margin-left: auto;
}

.lp-tab {
  position: relative;
  padding: 0.4rem 0.7rem;
  border-radius: 999px;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-secondary);
  white-space: nowrap;
  transition: color 0.18s var(--ease), background-color 0.18s var(--ease);
}

/* An underline that grows from the middle: on hover it appears, and on the
   page you are already on it is simply there. */
.lp-tab::after {
  content: "";
  position: absolute;
  left: 0.7rem;
  right: 0.7rem;
  bottom: 0.12rem;
  height: 2px;
  border-radius: 2px;
  background: var(--accent);
  transform: scaleX(0);
  transition: transform 0.26s var(--ease-out);
}

.lp-tab:hover {
  color: var(--accent-strong);
}

.lp-tab:hover::after { transform: scaleX(1); }

.lp-tab[aria-current="page"] {
  color: var(--accent-strong);
  font-weight: 600;
}

.lp-tab[aria-current="page"]::after { transform: scaleX(1); }

/* The one action the site has. Filled, so it never reads as one more tab. */
.lp-top__go {
  margin-left: 0.5rem;
  padding: 0.42rem 0.95rem;
  border-radius: 999px;
  background: var(--accent);
  /* Not #fff: in dark the accent is a bright teal and white on it is 2.6:1.
     --accent-contrast is the ink that theme picked for its own accent. */
  color: var(--accent-contrast);
  font-size: 0.9rem;
  font-weight: 600;
  white-space: nowrap;
  transition: background-color 0.2s var(--ease), transform 0.2s var(--ease-out);
}

.lp-top__go:hover {
  background: var(--accent-strong);
  transform: translateY(-1px);
}

.lp-top__link {
  margin-left: 0.35rem;
  padding: 0.4rem 0.9rem;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  font-size: 0.92rem;
  font-weight: 600;
  color: var(--text-secondary);
  white-space: nowrap;
  transition: border-color 0.2s var(--ease), color 0.2s var(--ease),
    background-color 0.2s var(--ease);
}

.lp-top__link:hover {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-strong);
}

/* How far down this page you are: a hairline across the bottom of the bar,
   set by motion.js. Zero-width — and therefore invisible — without JS. */
.lp-top__progress {
  position: absolute;
  left: 0;
  bottom: -1px;
  height: 2px;
  width: var(--progress, 0%);
  background: linear-gradient(90deg, var(--accent), var(--hero-mint, var(--accent)));
  transition: width 0.1s linear;
}

/* Said once, in the chrome, so no section has to wear it as a label. */
.lp-status {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  margin: 0;
  padding: 0.28rem 0.7rem 0.28rem 0.6rem;
  border: 1px solid color-mix(in srgb, var(--warn) 42%, transparent);
  border-radius: 999px;
  background: color-mix(in srgb, var(--warn) 12%, var(--surface));
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: color-mix(in srgb, var(--warn) 62%, var(--text));
  white-space: nowrap;
}

.lp-status__dot {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--warn);
  animation: lpPulse 2.6s var(--ease) infinite;
}

@keyframes lpPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.35; }
}

/* -------------------------------------------------------------- page shell -- */
.lp {
  --lp-max: 1280px;
  --lp-pad: clamp(1.15rem, 5vw, 3rem);
  /* Height the sticky header takes, so a jump never lands under it. Two rows
     on a phone (92px), one from the laptop up (63px). Measured, not guessed. */
  --top-h: 5.75rem;
  display: block;
  max-width: none;
  margin: 0;
  padding: 0;
}

/* Anchor targets clear the sticky header instead of hiding behind it. */
.lp > [id] { scroll-margin-top: calc(var(--top-h) + 0.75rem); }

@media (prefers-reduced-motion: no-preference) {
  html { scroll-behavior: smooth; }
}

.lp-h2 {
  max-width: 30ch;
  margin: 0 0 clamp(1.6rem, 3vw, 2.6rem);
  font-family: var(--font-display);
  font-size: clamp(1.75rem, 3.1vw, 2.7rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

/* --------------------------------------------------------------------- hero -- */
.lp-hero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(3rem, 7vw, 6rem) var(--lp-pad) clamp(3.5rem, 8vw, 6.5rem);
  background: var(--hero-bg);
  color: var(--hero-ink);
}

/* Two soft lights inside the teal so the surface has depth instead of being a
   flat fill. Purely decorative, hidden from assistive tech, cheap to paint. */
.lp-hero__glow {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.lp-hero__orb {
  position: absolute;
  border-radius: 50%;
  filter: blur(70px);
  opacity: 0.55;
}

.lp-hero__orb--a {
  top: -18%;
  right: -8%;
  width: 46vw;
  height: 46vw;
  max-width: 620px;
  max-height: 620px;
  background: radial-gradient(circle, var(--hero-mint), transparent 68%);
  animation: lpDriftA 26s var(--ease) infinite alternate;
}

.lp-hero__orb--b {
  bottom: -30%;
  left: -12%;
  width: 40vw;
  height: 40vw;
  max-width: 520px;
  max-height: 520px;
  background: radial-gradient(circle, color-mix(in srgb, var(--accent) 70%, #ffffff), transparent 70%);
  opacity: 0.35;
  animation: lpDriftB 32s var(--ease) infinite alternate;
}

@keyframes lpDriftA { to { transform: translate3d(-5%, 6%, 0) scale(1.08); } }
@keyframes lpDriftB { to { transform: translate3d(7%, -5%, 0) scale(1.12); } }

.lp-hero__inner {
  display: grid;
  gap: clamp(2.5rem, 5vw, 4rem);
  max-width: var(--lp-max);
  margin: 0 auto;
  align-items: center;
}

/* Grid items default to min-width:auto, so a wide mock would push the whole
   column past the viewport and the hero's overflow:hidden would quietly clip
   the headline. Let the columns shrink instead. */
.lp-hero__inner > *,
.lp-mo > * {
  min-width: 0;
}

.lp-hero__title {
  margin: 0 0 1.1rem;
  font-family: var(--font-display);
  /* Two lines, and they have to stay two: the cap is what the narrower of the
     hero's two columns can hold without "demás." falling to a third line. */
  font-size: clamp(2.05rem, 4.35vw, 3.9rem);
  font-weight: 600;
  line-height: 1.03;
  letter-spacing: -0.028em;
  text-wrap: balance;
}

/* Each sentence gets a box to rise out of. `clip` rather than `hidden` so the
   line never becomes a scroll container, and the padding/margin pair gives
   descenders somewhere to live inside the clip. */
.lp-hero__line {
  display: block;
  overflow: hidden;
  overflow: clip;
  padding-bottom: 0.08em;
  margin-bottom: -0.08em;
}

.lp-hero__line > span { display: block; }

.lp-hero__lede {
  max-width: 46ch;
  margin: 0 0 1.6rem;
  font-size: clamp(1.02rem, 1.25vw, 1.2rem);
  line-height: 1.55;
  color: var(--hero-dim-strong);
  text-wrap: pretty;
}

/* -------------------------------------------------------------- botones -- */
.lp-cta__row {
  display: flex;
  flex-wrap: wrap;
  gap: 0.6rem 0.7rem;
  margin: 0 0 1.9rem;
}

.lp-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.72rem 1.35rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.005em;
  transition: background-color 0.2s var(--ease), transform 0.2s var(--ease-out),
    box-shadow 0.24s var(--ease-out), border-color 0.2s var(--ease);
}

.lp-btn:hover {
  background: var(--accent-strong);
  transform: translateY(-2px);
  box-shadow: 0 10px 24px -12px rgba(0, 0, 0, 0.5);
}

.lp-btn .ico { transition: transform 0.24s var(--ease-out); }
.lp-btn:hover .ico { transform: translateX(3px); }

/* On the teal: an outline in the hero's own ink, not a white box. */
.lp-btn--ghost {
  background: transparent;
  border-color: var(--hero-line);
  color: var(--hero-ink);
}

.lp-btn--ghost:hover {
  background: var(--hero-chip);
  border-color: var(--hero-ink);
  color: var(--hero-ink);
}

/* The reverse: paper on the teal, for the closing bands. The ink is
   --hero-b, the darker of the surface's two stops — NOT --hero-bg, which is a
   gradient and therefore not a colour at all: as a `color` it is dropped and
   the label inherits the near-white ink onto its own near-white fill. */
.lp-btn--light {
  background: var(--hero-ink);
  color: var(--hero-b);
}

.lp-btn--light:hover {
  background: #fff;
  color: var(--hero-b);
}

/* ------------------------------------------------------- pulsar y pasar -- */
/* Feedback belongs to the press, not to the release: everything clickable
   gives way under the finger, fast, and comes back. 110ms, because below that
   it is not seen and above it the control feels slow. */
.lp-btn:active,
.lp-top__go:active,
.lp-top__link:active,
.lp-tab:active,
.lp-onward__list a:active {
  transform: scale(0.975);
  transition-duration: 0.11s;
}

/* A touch screen fires a hover on tap and then keeps it, so the lift would
   stick to whatever was last tapped. It is for a real pointer only. */
@media (hover: none), (pointer: coarse) {
  .lp-btn:hover,
  .lp-top__go:hover,
  .lp-onward__list a:hover { transform: none; }

  .lp-btn:hover .ico,
  .lp-onward__list a:hover .lp-onward__ico { transform: none; }

  .lp-tab:hover::after { transform: scaleX(0); }
  .lp-tab[aria-current="page"]:hover::after { transform: scaleX(1); }
}

@media (prefers-reduced-motion: reduce) {
  .lp-btn:active,
  .lp-top__go:active,
  .lp-top__link:active,
  .lp-tab:active,
  .lp-onward__list a:active { transform: none; }
}

/* ------------------------------------------------------------- el desfile -- */
/* The trades this serves. There are more of them than fit on a line, so the
   line moves; motion.js clones the list once so the loop has no seam. Stops
   on hover, and stands still under prefers-reduced-motion. */
.lp-marquee {
  position: relative;
  overflow: hidden;
  /* Fades at both ends so the words enter and leave instead of being sliced.
     The left fade is short: at rest the first chip is barely touched, and
     once the loop is running there is always a chip crossing that edge. */
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 4%, #000 82%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 4%, #000 82%, transparent);
}

.lp-marquee__track {
  display: flex;
  gap: 0.45rem;
  width: max-content;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-marquee__track li {
  padding: 0.26rem 0.7rem;
  border: 1px solid var(--hero-line);
  border-radius: 999px;
  background: var(--hero-chip);
  font-size: 0.82rem;
  white-space: nowrap;
  color: var(--hero-dim-strong);
}

/* Only once the track has been doubled does moving it make sense. */
.lp-marquee.is-looping .lp-marquee__track {
  animation: lpMarquee 34s linear infinite;
}

.lp-marquee:hover .lp-marquee__track { animation-play-state: paused; }

@keyframes lpMarquee {
  to { transform: translateX(-50%); }
}

.lp-hero__show {
  position: relative;
  display: flex;
  justify-content: center;
  padding-bottom: 2rem;
}

/* ------------------------------------------------------------------- mocks -- */
/* Real product screens with real content, drawn in markup so they stay sharp,
   theme with the page and cost no image bytes. */
.mock {
  --mock-ink: var(--text);
  border-radius: var(--radius-lg);
  background: var(--surface);
  color: var(--mock-ink);
  box-shadow: 0 32px 70px -30px rgba(6, 26, 24, 0.75);
  overflow: hidden;
}

.mock--panel {
  width: min(100%, 430px);
  border: 1px solid rgba(255, 255, 255, 0.14);
}

.mock__band {
  padding: 0.85rem 1rem 0.95rem;
  background: linear-gradient(150deg, #12645a, #0a3f39);
  color: var(--hero-ink);
}

.mock__biz {
  margin: 0;
  color: var(--hero-ink);
  font-family: var(--font-display);
  font-size: 1.15rem;
  letter-spacing: -0.015em;
}

.mock__day {
  margin: 0.1rem 0 0.7rem;
  font-size: 0.78rem;
  color: var(--hero-dim-strong);
}

.mock__figs {
  display: flex;
  gap: 1.2rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mock__figs li {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
}

.mock__figs b {
  font-size: 1.15rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.mock__figs span {
  font-size: 0.7rem;
  color: var(--hero-dim-strong);
}

.mock__agenda {
  margin: 0;
  padding: 0.4rem 0.35rem 0.6rem;
  list-style: none;
}

.mock__agenda li {
  display: flex;
  align-items: center;
  gap: 0.55rem;
  padding: 0.5rem 0.65rem;
  border-radius: var(--radius-sm);
  font-size: 0.85rem;
  color: var(--text-secondary);
}

.mock__agenda li + li { margin-top: 0.15rem; }

.mock__agenda span {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
}

.mock__agenda em {
  margin-left: auto;
  font-style: normal;
  font-size: 0.72rem;
  font-weight: 600;
  padding: 0.1rem 0.5rem;
  border-radius: 999px;
}

.mock__agenda .is-ok em {
  background: var(--accent-soft);
  color: var(--accent-strong);
}

.mock__agenda .is-done em {
  background: color-mix(in srgb, var(--success) 14%, var(--surface));
  color: color-mix(in srgb, var(--success) 75%, var(--text));
}

.mock__agenda .is-wait em {
  background: var(--surface-2);
  color: var(--text-tertiary);
}

/* A free slot is an opportunity, so it is drawn as one: dashed, not muted. */
.mock__agenda .is-free {
  border: 1px dashed color-mix(in srgb, var(--accent) 45%, var(--border));
  background: color-mix(in srgb, var(--accent) 5%, transparent);
  color: var(--accent-strong);
}

.mock__agenda .is-free span { color: var(--accent-strong); }

.mock__agenda .is-free em {
  background: var(--accent);
  color: var(--accent-contrast);
}

.mock--phone {
  width: 232px;
  padding: 9px;
  border-radius: 34px;
  background: linear-gradient(160deg, #2a2b30, #131417);
  box-shadow: 0 34px 60px -26px rgba(6, 26, 24, 0.8),
    inset 0 0 0 1px rgba(255, 255, 255, 0.08);
}

.mock__notch {
  width: 78px;
  height: 5px;
  margin: 2px auto 7px;
  border-radius: 999px;
  background: rgba(255, 255, 255, 0.22);
}

.mock__screen {
  padding: 0.9rem 0.85rem 1rem;
  border-radius: 26px;
  background: var(--bg);
}

.mock__biz--sm {
  font-size: 0.95rem;
  color: var(--text);
}

.mock__lede {
  margin: 0.15rem 0 0.7rem;
  font-size: 0.75rem;
  color: var(--text-tertiary);
}

.mock__slots {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.35rem;
  margin: 0 0 0.8rem;
  padding: 0;
  list-style: none;
}

.mock__slots li {
  padding: 0.42rem 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.78rem;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--text-secondary);
}

.mock__slots .is-sel,
.mock__picks .is-sel {
  border-color: var(--accent);
  background: var(--accent-soft);
  color: var(--accent-strong);
  font-weight: 600;
}

.mock__picks {
  margin: 0 0 0.8rem;
  padding: 0;
  list-style: none;
}

.mock__picks li {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.55rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--surface);
  font-size: 0.78rem;
  color: var(--text-secondary);
}

.mock__picks li + li { margin-top: 0.3rem; }
.mock__picks b { font-weight: 600; color: var(--text); }

.mock__cta {
  margin: 0;
  padding: 0.55rem;
  border-radius: var(--radius-sm);
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
}

/* ------------------------------------------------- cabecera de las pestañas -- */
/* Every tab but the front page opens with this: the same teal surface as the
   hero, compressed to a band, so you always know which tab you are on and the
   identity does not stop at the door. */
.lp-phero {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(2.4rem, 5.5vw, 4.2rem) var(--lp-pad) clamp(2.6rem, 6vw, 4.4rem);
  background: var(--hero-bg);
  color: var(--hero-ink);
}

.lp-phero__glow {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.lp-phero__inner {
  max-width: var(--lp-max);
  margin: 0 auto;
}

.lp-phero__kicker {
  margin: 0 0 0.7rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--hero-dim-strong);
}

.lp-phero__title {
  max-width: 20ch;
  margin: 0 0 0.9rem;
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 4.4vw, 3.4rem);
  font-weight: 600;
  line-height: 1.05;
  letter-spacing: -0.026em;
  text-wrap: balance;
}

.lp-phero__lede {
  max-width: 52ch;
  margin: 0;
  font-size: clamp(1rem, 1.2vw, 1.14rem);
  line-height: 1.55;
  color: var(--hero-dim-strong);
}

/* ---------------------------------------------------------------- escenas -- */
/* The front page's core. Not six cards you have to click: four flows that play
   themselves as you reach them, each one a client who comes in, who does not
   get lost, or who comes back. The words are the caption — the picture is what
   explains the product. */
.lp-scenes {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(3rem, 6.5vw, 4.75rem) var(--lp-pad) clamp(1rem, 2vw, 1.5rem);
}

/* The section's own heading, centred: it introduces four things, so it does
   not belong on either side. */
.lp-head.lp-head--center {
  display: block;
  max-width: 44rem;
  margin-inline: auto;
  text-align: center;
}

.lp-head.lp-head--center .lp-h2 {
  max-width: none;
  margin-bottom: 0.85rem;
}

.lp-head.lp-head--center .lp-head__lede {
  max-width: 40ch;
  margin-inline: auto;
}

.lp-scene__list {
  display: grid;
  gap: clamp(2rem, 4vw, 3rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-scene {
  display: grid;
  gap: clamp(1.4rem, 3vw, 2.4rem);
  align-items: center;
  padding-top: clamp(1.6rem, 3vw, 2.6rem);
}

/* The shared reveal blurs what it brings in, which is right for a paragraph
   and wrong for a block this size: a scene is most of the viewport, and
   blurring it is a full-surface rasterisation on every single reveal. It
   rises and fades like everything else, just without the blur. */
.has-motion .lp-scene[data-reveal] {
  filter: none;
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
  will-change: auto;
}

/* The rule between scenes fades out at both ends instead of running wall to
   wall: it separates without drawing a box around anything. */
.lp-scene + .lp-scene {
  background-image: linear-gradient(
    90deg,
    transparent,
    var(--border) 14%,
    var(--border) 86%,
    transparent
  );
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: top left;
}

/* Grid items default to min-width:auto; without this a wide flow card would
   push the column past the viewport. */
.lp-scene > * { min-width: 0; }

.lp-scene__kicker {
  margin: 0 0 0.6rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--accent-strong);
}

.lp-scene__title {
  margin: 0 0 0.75rem;
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.4vw, 2rem);
  font-weight: 600;
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.lp-scene__say p {
  max-width: 46ch;
  margin: 0 0 0.9rem;
  font-size: clamp(0.97rem, 1.1vw, 1.05rem);
  line-height: 1.55;
  color: var(--text-secondary);
  text-wrap: pretty;
}

.lp-scene__say .lp-scene__note {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  font-weight: 500;
  color: var(--text);
}

/* ------------------------------------------------------------ los flujos -- */
/* A flow is a numbered strip of cards. Each card is one beat of the story, and
   the whole strip deals itself out once, in order, when you arrive. */
.lp-fl {
  --fl-gap: 0.65rem;
  display: grid;
  gap: var(--fl-gap);
}

.lp-fl__card {
  position: relative;
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr);
  column-gap: 0.75rem;
  align-content: start;
  padding: 0.9rem 1rem 0.95rem;
  border: 1px solid var(--border);
  border-radius: var(--radius, 14px);
  background: var(--surface);
  box-shadow: 0 16px 34px -30px rgba(6, 26, 24, 0.8);
}

.lp-fl__card > * { grid-column: 2; }

/* The step number, in its own gutter so nothing has to flow around it. */
.lp-fl__n {
  grid-column: 1;
  grid-row: 1 / -1;
  display: grid;
  place-items: center;
  width: 1.5rem;
  height: 1.5rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.72rem;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

/* The thread between one beat and the next, drawn from the step number of the
   card above down into this one. It is what turns four cards into a sequence,
   and it draws itself as the flow plays. Only where the flow is a single file:
   in the 2×2 the cards are not each other's neighbours (see the media query). */
.lp-fl__card + .lp-fl__card::before {
  content: "";
  position: absolute;
  left: calc(1rem + 0.75rem - 1px);
  top: calc(var(--fl-gap) * -1);
  width: 2px;
  height: var(--fl-gap);
  border-radius: 2px;
  background: color-mix(in srgb, var(--accent) 42%, transparent);
  transform-origin: top;
  transition: transform 0.4s var(--ease-out) calc(var(--d, 0) * 0.11s);
}

/* The card that closes a flow: the outcome, so it carries the accent. */
.lp-fl__card--end {
  border-color: color-mix(in srgb, var(--accent) 38%, transparent);
  background: var(--accent-soft);
}

.lp-fl__cap {
  display: flex;
  align-items: center;
  gap: 0.4rem;
  margin: 0.1rem 0 0.65rem;
  font-size: 0.85rem;
  font-weight: 600;
  line-height: 1.3;
  color: var(--text);
}

.lp-fl__note {
  margin: 0.6rem 0 0;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--text-tertiary);
}

.lp-fl__wa { flex: none; color: #25d366; }

/* -- where the link lives -- */
.lp-fl__srcs {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-fl__srcs li {
  padding: 0.24rem 0.6rem;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 999px;
  background: var(--accent-soft);
  font-size: 0.78rem;
  color: var(--text);
}

.lp-fl__url {
  margin: 0.6rem 0 0;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--accent-strong);
  overflow-wrap: anywhere;
}

/* -- the hours the client sees, and the one they take -- */
.lp-fl__slots {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-fl__slots li {
  padding: 0.3rem 0.65rem;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  background: var(--surface);
  font-size: 0.82rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-secondary);
}

.lp-fl__slots .is-sel {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-contrast);
  font-weight: 600;
}

.lp-fl__btn {
  margin: 0.7rem 0 0;
  padding: 0.45rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.82rem;
  font-weight: 600;
  text-align: center;
}

/* -- one line of an agenda, in its three possible states -- */
.lp-fl__row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.4rem;
  margin: 0;
  padding: 0.5rem 0.65rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 10px);
  font-size: 0.85rem;
  color: var(--text);
}

.lp-fl__row + .lp-fl__row { margin-top: 0.4rem; }

.lp-fl__row > span:first-child {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.lp-fl__row em {
  display: inline-flex;
  align-items: center;
  gap: 0.2rem;
  margin-left: auto;
  font-size: 0.76rem;
  font-style: normal;
  font-weight: 600;
  white-space: nowrap;
}

.lp-fl__row--ok {
  border-color: color-mix(in srgb, var(--accent) 40%, transparent);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
}

.lp-fl__row--ok em { color: var(--accent-strong); }

/* The cancelled line: struck through, and stepping aside. */
.lp-fl__row--gone {
  color: var(--text-tertiary);
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
  text-decoration-color: color-mix(in srgb, var(--danger) 70%, transparent);
}

/* The hour nobody has yet: an outline, not a filled row. */
.lp-fl__row--free {
  border-style: dashed;
  border-color: var(--border-strong);
  color: var(--text-secondary);
}

/* -- a WhatsApp message and its two answers -- */
.lp-fl__bub {
  position: relative;
  margin: 0;
  padding: 0.55rem 0.75rem;
  border-radius: 12px 12px 12px 4px;
  background: var(--surface-2);
  font-size: 0.84rem;
  line-height: 1.4;
  color: var(--text);
}

.lp-fl__btns {
  display: flex;
  flex-wrap: wrap;
  gap: 0.4rem;
  margin: 0.45rem 0 0;
}

.lp-fl__btns span {
  flex: 1 1 auto;
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border-strong);
  border-radius: 8px;
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
  color: var(--text-secondary);
}

/* The one the client actually presses. */
.lp-fl__btns .is-tap {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-contrast);
}

/* -- who is waiting for an hour like that one -- */
.lp-fl__queue {
  display: grid;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-fl__queue li {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  padding: 0.42rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 10px);
  font-size: 0.84rem;
}

.lp-fl__queue span {
  margin-left: auto;
  font-size: 0.74rem;
  color: var(--text-tertiary);
}

.lp-fl__queue .is-turn {
  border-color: color-mix(in srgb, var(--accent) 45%, transparent);
  background: var(--accent-soft);
}

.lp-fl__queue .is-turn span {
  font-weight: 600;
  color: var(--accent-strong);
}

/* -- stars, and the pile of reviews they add up to -- */
.lp-fl__stars {
  margin: 0.5rem 0 0;
  font-size: 1rem;
  letter-spacing: 0.1em;
  color: var(--warn);
}

.lp-fl__stars--few { color: var(--text-tertiary); }

.lp-fl__big {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0;
}

.lp-fl__big b {
  font-family: var(--font-display);
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  font-weight: 600;
  letter-spacing: -0.02em;
  color: var(--accent-strong);
  font-variant-numeric: tabular-nums;
}

.lp-fl__big span {
  font-size: 0.82rem;
  color: var(--text-secondary);
}

/* -- two businesses side by side, and the one that gets picked -- */
.lp-fl__results {
  display: grid;
  gap: 0.45rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-fl__results li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.1rem 0.6rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 10px);
}

.lp-fl__results b {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  font-size: 0.86rem;
  font-weight: 600;
}

.lp-fl__results .lp-fl__stars {
  grid-row: 1 / span 2;
  grid-column: 2;
  margin: 0;
  font-size: 0.8rem;
}

.lp-fl__results em {
  font-size: 0.75rem;
  font-style: normal;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}

/* The one the client chooses: lifted off the list, ringed in the accent. */
.lp-fl__results .is-pick {
  border-color: var(--accent);
  background: color-mix(in srgb, var(--accent) 10%, var(--surface));
  box-shadow: 0 0 0 3px var(--accent-soft);
}

.lp-fl__results .is-pick em { color: var(--text-secondary); }

/* -- who is drifting away, with the state they fell into on their own -- */
.lp-fl__who {
  display: grid;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-fl__who li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "who seg" "meta seg";
  align-items: center;
  gap: 0.05rem 0.6rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 10px);
}

.lp-fl__who b {
  grid-area: who;
  font-size: 0.85rem;
  font-weight: 600;
}

.lp-fl__who > li > span {
  grid-area: meta;
  font-size: 0.74rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}

/* -- the switch that is the owner's, and what it would hand out -- */
.lp-fl__sw {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin: 0 0 0.55rem;
  padding: 0.45rem 0.6rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm, 10px);
  font-size: 0.85rem;
  font-weight: 600;
}

.lp-fl__sw i {
  position: relative;
  flex: none;
  margin-left: auto;
  width: 2.1rem;
  height: 1.15rem;
  border-radius: 999px;
  background: var(--accent);
}

.lp-fl__sw i::after {
  content: "";
  position: absolute;
  top: 0.15rem;
  left: 0.15rem;
  width: 0.85rem;
  height: 0.85rem;
  border-radius: 50%;
  background: #fff;
  transform: translateX(0.95rem);
}

.lp-fl__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-fl__chips li {
  padding: 0.24rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  font-size: 0.78rem;
  color: var(--text-secondary);
}

.lp-fl__chips .is-sel {
  border-color: var(--accent);
  background: var(--accent-soft);
  font-weight: 600;
  color: var(--text);
}
/* -------------------------------------------------------- hoy / con Iluena -- */
/* The four leaks and their four answers, side by side. The left column crosses
   itself out and the right column ticks itself off, once, on arrival. */
.lp-swap {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--lp-pad) clamp(2rem, 4vw, 3rem);
}

.lp-swap__h { max-width: 22ch; }

.lp-swap__pair {
  display: grid;
  gap: clamp(1rem, 2.5vw, 1.6rem);
}

.lp-swap__side {
  padding: clamp(1.3rem, 2.4vw, 1.8rem);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 18px);
}

.lp-swap__side--after {
  border-color: color-mix(in srgb, var(--accent) 38%, transparent);
  background: var(--accent-soft);
}

.lp-swap__label {
  margin: 0 0 1rem;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--text-secondary);
}

.lp-swap__side--after .lp-swap__label { color: var(--accent-strong); }

.lp-swap__list {
  display: grid;
  gap: 0.75rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-swap__list li {
  display: flex;
  align-items: flex-start;
  gap: 0.5rem;
  font-size: 0.98rem;
  line-height: 1.45;
  color: var(--text-secondary);
}

.lp-swap__side--before li {
  /* Drawn by the animation; the line is what says "this stops happening". */
  text-decoration: line-through;
  text-decoration-thickness: 1.5px;
  text-decoration-color: color-mix(in srgb, var(--danger, #b3261e) 65%, transparent);
}

.lp-swap__side--after li {
  color: var(--text);
  font-weight: 500;
}

.lp-swap__side--after .ico {
  flex: none;
  margin-top: 0.18rem;
  color: var(--accent-strong);
}

/* ----------------------------------------------------------------- adelante -- */
.lp-onward {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4rem) var(--lp-pad) clamp(2.5rem, 6vw, 4rem);
}

.lp-onward--single { padding-bottom: clamp(1.5rem, 3vw, 2.5rem); }

.lp-onward__h {
  margin: 0 0 1.5rem;
  font-family: var(--font-display);
  font-size: clamp(1.4rem, 2.2vw, 1.9rem);
  font-weight: 600;
  letter-spacing: -0.02em;
}

.lp-onward__list {
  display: grid;
  gap: clamp(0.7rem, 1.5vw, 1rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-onward__list a {
  position: relative;
  display: grid;
  grid-template-columns: auto 1fr auto;
  grid-template-areas: "n b i" "n s i";
  align-items: center;
  column-gap: 1rem;
  padding: 1.1rem 1.3rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg, 18px);
  background: var(--surface);
  color: inherit;
  transition: border-color 0.24s var(--ease), transform 0.24s var(--ease-out),
    background-color 0.24s var(--ease);
}

.lp-onward__list a:hover {
  transform: translateX(4px);
  border-color: var(--accent);
  background: var(--accent-soft);
}

.lp-onward__n {
  grid-area: n;
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}

.lp-onward__list b {
  grid-area: b;
  font-size: 1.05rem;
  font-weight: 600;
  letter-spacing: -0.012em;
}

.lp-onward__list a > span:not(.lp-onward__n) {
  grid-area: s;
  font-size: 0.92rem;
  line-height: 1.45;
  color: var(--text-secondary);
}

.lp-onward__ico {
  grid-area: i;
  color: var(--accent);
  transition: transform 0.24s var(--ease-out);
}

.lp-onward__list a:hover .lp-onward__ico { transform: translateX(4px); }

/* ------------------------------------------------------------- cierre -- */
.lp-cta {
  padding: clamp(3rem, 7vw, 5rem) var(--lp-pad);
  background: var(--hero-bg);
  color: var(--hero-ink);
  text-align: center;
}

.lp-cta__inner {
  max-width: 48ch;
  margin: 0 auto;
}

.lp-cta__kicker {
  margin: 0 0 0.7rem;
  font-size: 0.76rem;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--hero-dim-strong);
}

.lp-cta__title {
  margin: 0 0 0.8rem;
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 3.4vw, 2.7rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.022em;
}

.lp-cta__text {
  margin: 0 0 1.8rem;
  font-size: 1.04rem;
  line-height: 1.6;
  color: var(--hero-dim-strong);
}

.lp-cta .lp-cta__row {
  justify-content: center;
  margin-bottom: 0;
}

/* ----------------------------------------------- qué te da estar en la lista -- */
.lp-first {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4rem) var(--lp-pad);
}

.lp-first__list {
  display: grid;
  gap: clamp(1.1rem, 2.4vw, 1.8rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-first__list li {
  display: grid;
  gap: 0.3rem;
  padding-top: 1.1rem;
  border-top: 2px solid var(--accent-soft);
}

.lp-first__ico { color: var(--accent); }

.lp-first__list b {
  font-size: 1.02rem;
  font-weight: 600;
  letter-spacing: -0.012em;
}

.lp-first__list span {
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--text-secondary);
}

/* ------------------------------------------------------------------ la jornada -- */
.lp-day {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--lp-pad) clamp(3rem, 7vw, 5rem);
}

.lp-day__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-mo {
  --mo-pad: clamp(1.8rem, 4vw, 3rem);
  position: relative;
  display: grid;
  gap: 0.6rem clamp(1.5rem, 3vw, 3rem);
  padding: var(--mo-pad) 0;
}

.lp-mo + .lp-mo { border-top: 1px solid var(--border); }

/* The hour is the spine of the page, so it is set in the display face at a size
   that reads as a heading, not as a caption. */
.lp-mo__hour {
  position: relative;
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.2vw, 1.9rem);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--accent-strong);
}

/* A day is one line, so the hours are strung on one. Each block owns the
   segment that runs from its own hour down to the next, and draws it as you
   reach it, which is what turns five blocks into a morning. Desktop only:
   below that the hour sits above the words and there is no rail to hang it
   on. The line is decoration and lives on a pseudo-element, so nothing about
   it reaches a screen reader. */
@media (min-width: 900px) {
  .lp-mo__hour::after {
    content: "";
    position: absolute;
    left: calc(0.5em - 1px);
    top: 2em;
    /* Down to where the next hour starts: this row plus the air between. */
    height: calc(100% - 2em + var(--mo-pad) * 2);
    width: 2px;
    border-radius: 2px;
    background: linear-gradient(
      var(--accent),
      color-mix(in srgb, var(--accent) 22%, transparent)
    );
    transform: scaleY(0);
    transform-origin: top;
    transition: transform 0.9s var(--ease-out) 0.1s;
  }

  .lp-mo.is-in .lp-mo__hour::after { transform: scaleY(1); }

  /* The last hour closes the day; a line running off the end of it points at
     nothing. */
  .lp-mo:last-child .lp-mo__hour::after { content: none; }
}

.lp-mo__title {
  margin: 0 0 0.7rem;
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 2.3vw, 2rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.lp-mo__say p {
  max-width: 60ch;
  margin: 0 0 0.8rem;
  font-size: clamp(1rem, 1.1vw, 1.08rem);
  line-height: 1.6;
  color: var(--text-secondary);
}

/* A run of prose, not a row: flex here would turn every <b> and the text around
   it into its own column. The leading glyph, when there is one, is inline. */
.lp-mo__note {
  display: block;
  padding-top: 0.7rem;
  border-top: 1px solid var(--border);
  font-size: 0.92rem !important;
  color: var(--text-tertiary) !important;
}

.lp-mo__note b { color: var(--text-secondary); font-weight: 600; }

.lp-mo__art {
  display: flex;
  justify-content: center;
  align-items: center;
  min-width: 0;
}

/* WhatsApp's own glyph, in its own green, only ever to say "this goes out on
   WhatsApp". Never restyled. */
.lp-wa__glyph {
  color: #25d366;
  flex: none;
  margin-right: 0.35rem;
  vertical-align: -0.28em;
}

/* -------------------------------------------------------- el hilo de WhatsApp -- */
.lp-wa {
  width: min(100%, 400px);
}

.lp-wa__thread {
  padding: 1rem 0.9rem 1.1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface-2);
}

.lp-wa__msg {
  position: relative;
  max-width: 86%;
  margin: 0;
  padding: 0.6rem 0.75rem 1.35rem;
  border-radius: 16px;
  font-size: 0.92rem;
  line-height: 1.45;
  box-shadow: var(--shadow-sm);
}

.lp-wa__msg--in {
  border-bottom-left-radius: 5px;
  background: var(--surface);
  color: var(--text);
}

.lp-wa__msg--out {
  margin-left: auto;
  border-bottom-right-radius: 5px;
  background: var(--accent-soft);
  color: var(--text);
  font-weight: 600;
}

.lp-wa__time {
  position: absolute;
  right: 0.7rem;
  bottom: 0.45rem;
  font-size: 0.68rem;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}

.lp-wa__ticks { color: var(--accent-strong); }

/* The two template buttons WhatsApp draws under a message. */
.lp-wa__btns {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 2px;
  max-width: 86%;
  margin: 2px 0 0.6rem;
  padding: 0;
}

.lp-wa__btns span {
  padding: 0.5rem 0.4rem;
  background: var(--surface);
  font-size: 0.85rem;
  font-weight: 600;
  text-align: center;
  color: var(--accent-strong);
  box-shadow: var(--shadow-sm);
}

.lp-wa__btns span:first-child { border-radius: 0 0 0 12px; }
.lp-wa__btns span:last-child { border-radius: 0 0 12px 0; }

.lp-wa__result {
  margin-top: 0.9rem;
  padding: 0.85rem 0.95rem 0.95rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: var(--surface);
}

.lp-wa__resultlabel {
  margin: 0 0 0.5rem;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-tertiary);
}

.lp-wa__row {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
  font-size: 0.9rem;
  color: var(--text-secondary);
}

.lp-wa__row span {
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.lp-wa__row em {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-left: auto;
  padding: 0.15rem 0.55rem;
  border-radius: 999px;
  background: var(--accent-soft);
  font-style: normal;
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--accent-strong);
}

/* ----------------------------------------------------------------- la reseña -- */
.lp-rev {
  width: min(100%, 380px);
  padding: 1.15rem 1.25rem 1.25rem;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--surface);
  box-shadow: var(--shadow);
}

.lp-rev__place {
  display: flex;
  color: var(--text);
  align-items: center;
  gap: 0.45rem;
  margin: 0 0 0.35rem;
  font-weight: 600;
}

.lp-rev__pin { color: var(--accent); }

.lp-rev__stars {
  margin: 0 0 0.6rem;
  font-size: 1.05rem;
  letter-spacing: 0.12em;
  color: var(--warn);
}

.lp-rev__text {
  margin: 0 0 0.6rem;
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--text-secondary);
}

.lp-rev__who {
  margin: 0 0 0.9rem;
  font-size: 0.82rem;
  color: var(--text-tertiary);
}

.lp-rev__count {
  display: flex;
  align-items: baseline;
  gap: 0.5rem;
  margin: 0;
  padding-top: 0.75rem;
  border-top: 1px solid var(--border);
}

.lp-rev__count b {
  font-size: 1.05rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.lp-rev__count span {
  font-size: 0.85rem;
  color: var(--text-tertiary);
}

/* ----------------------------------------------------------- tarjeta de sellos -- */
.lp-loy {
  width: min(100%, 340px);
  padding: 1.2rem 1.25rem 1.3rem;
  border-radius: var(--radius-lg);
  background: linear-gradient(150deg, #12645a, #0a3f39);
  color: var(--hero-ink);
  box-shadow: var(--shadow-lg);
}

.lp-loy__title {
  margin: 0 0 1rem;
  color: var(--hero-ink);
  font-family: var(--font-display);
  font-size: 1.1rem;
  letter-spacing: -0.015em;
}

.lp-loy__stamps {
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 0.45rem;
  margin: 0 0 0.9rem;
  padding: 0;
  list-style: none;
}

.lp-loy__stamps li {
  display: grid;
  place-items: center;
  aspect-ratio: 1;
  border: 1px dashed var(--hero-line);
  border-radius: 50%;
  font-size: 0.8rem;
  color: var(--hero-dim-strong);
}

.lp-loy__stamps .is-on {
  border-style: solid;
  border-color: transparent;
  background: var(--hero-mint);
  color: #0a3f39;
}

.lp-loy__stamps .is-next {
  border-style: solid;
  border-color: var(--hero-mint);
  color: var(--hero-ink);
  font-weight: 600;
}

.lp-loy__note {
  margin: 0;
  font-size: 0.85rem;
  color: var(--hero-dim-strong);
}

/* ------------------------------------------------------------------ por qué -- */
/* ----------------------------------------------------------------- el motor -- */
/* The CRM half. Every block is the same three beats — the owner's own words,
   what Iluena does, the screen it produces — so the section reads as a machine
   rather than a feature list. */
.lp-eng {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--lp-pad) clamp(1.5rem, 3vw, 2.5rem);
}

.lp-eng__list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-eng__mo {
  display: grid;
  gap: 1.1rem clamp(1.5rem, 3vw, 3rem);
  padding: clamp(1.8rem, 4vw, 3rem) 0;
}

.lp-eng__mo + .lp-eng__mo { border-top: 1px solid var(--border); }

.lp-eng__title {
  margin: 0 0 0.7rem;
  font-family: var(--font-display);
  font-size: clamp(1.3rem, 2.2vw, 1.85rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.lp-eng__say p {
  max-width: 58ch;
  margin: 0 0 0.8rem;
  font-size: clamp(1rem, 1.1vw, 1.06rem);
  line-height: 1.6;
  color: var(--text-secondary);
}

.lp-eng__say p:last-child { margin-bottom: 0; }
.lp-eng__say b { font-weight: 600; color: var(--text); }
.lp-eng__say i { font-style: italic; color: var(--text); }

/* The situation, in the owner's own voice. Set in the display face and hung off
   a hairline so it reads as something overheard, not as a pull quote. */
.lp-eng__say .lp-eng__case {
  margin: 0 0 1.1rem;
  padding-left: 0.95rem;
  border-left: 1px solid var(--accent);
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 1.5vw, 1.22rem);
  line-height: 1.4;
  color: var(--text);
}

.lp-eng__say .lp-eng__note {
  margin-bottom: 0;
  padding-top: 0.8rem;
  border-top: 1px solid var(--border);
  font-size: 0.93rem;
  color: var(--text-tertiary);
}

.lp-eng__note b { color: var(--text-secondary); }

.lp-eng__art {
  display: flex;
  justify-content: center;
  align-items: center;
  min-width: 0;
}

.lp-eng__art .mock {
  width: min(100%, 420px);
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

/* -- the customer list, with the state each person fell into on their own -- */
.mock__rows {
  margin: 0;
  padding: 0.35rem 0.5rem 0.55rem;
  list-style: none;
}

.mock__rows li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "who seg" "meta seg";
  align-items: center;
  gap: 0.1rem 0.7rem;
  padding: 0.6rem;
}

.mock__rows li + li { border-top: 1px solid var(--border); }

.mock__who {
  grid-area: who;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
}

.mock__meta {
  grid-area: meta;
  font-size: 0.75rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}

/* Four states, four hues, and the label always in full-contrast ink. */
.seg {
  grid-area: seg;
  align-self: center;
  padding: 0.16rem 0.55rem;
  border-radius: 999px;
  font-size: 0.7rem;
  font-style: normal;
  font-weight: 600;
  white-space: nowrap;
  color: var(--text);
}

.seg--vip { background: color-mix(in srgb, var(--accent) 22%, var(--surface)); }
.seg--habitual { background: color-mix(in srgb, var(--success) 20%, var(--surface)); }
.seg--riesgo { background: color-mix(in srgb, var(--warn) 26%, var(--surface)); }
.seg--dormido { background: color-mix(in srgb, var(--danger) 18%, var(--surface)); }

/* -- the suggestion that opens a campaign already filled in -- */
.mock__sug {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  margin: 0.75rem;
  padding: 0.75rem 0.85rem;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--accent) 11%, var(--surface));
}

.mock__sugtext {
  margin: 0;
  font-size: 0.85rem;
  line-height: 1.4;
  color: var(--text);
}

.mock__sugtext b { font-weight: 600; }

.mock__sugcta {
  flex: none;
  margin: 0 0 0 auto;
  padding: 0.32rem 0.7rem;
  border-radius: 999px;
  background: var(--accent);
  color: var(--accent-contrast);
  font-size: 0.76rem;
  font-weight: 600;
  white-space: nowrap;
}

.mock__offer { padding: 0 0.9rem 0.95rem; }

.mock__label {
  margin: 0.7rem 0 0.4rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.05em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.mock__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.35rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.mock__chips li {
  padding: 0.26rem 0.6rem;
  border: 1px solid var(--border-strong);
  border-radius: 999px;
  font-size: 0.76rem;
  color: var(--text-secondary);
}

.mock__chips .is-sel {
  border-color: var(--accent);
  background: var(--accent);
  color: var(--accent-contrast);
  font-weight: 600;
}

.mock__val {
  margin: 0;
  font-size: 0.82rem;
  color: var(--text);
}

/* -- the appointment that was born out of an offer -- */
.mock__appt { padding: 0.85rem 0.9rem 1rem; }

.mock__apptwho {
  margin: 0 0 0.65rem;
  font-size: 0.9rem;
  font-weight: 600;
  color: var(--text);
}

.mock__tag {
  margin: 0 0 0.75rem;
  padding: 0.6rem 0.7rem;
  border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--warn) 18%, var(--surface));
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--text);
}

.mock__tag .ico {
  margin-right: 0.35rem;
  vertical-align: -0.22em;
  color: color-mix(in srgb, var(--warn) 55%, var(--text));
}

.mock__tag span {
  display: block;
  margin-top: 0.2rem;
  font-size: 0.74rem;
  font-weight: 500;
  color: var(--text-secondary);
}

.mock__price {
  margin: 0;
  font-size: 0.9rem;
  color: var(--text-tertiary);
}

.mock__price s { margin-right: 0.45rem; }

.mock__price b {
  font-size: 1.1rem;
  font-weight: 600;
  color: var(--text);
}

/* -- the recipes, all off until the owner says otherwise -- */
.mock__sw {
  margin: 0;
  padding: 0.35rem 0.55rem 0.6rem;
  list-style: none;
}

.mock__sw li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  grid-template-areas: "name sw" "cfg sw";
  align-items: center;
  gap: 0.1rem 0.7rem;
  padding: 0.65rem 0.6rem;
}

.mock__sw li + li { border-top: 1px solid var(--border); }

.mock__sw span {
  grid-area: name;
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--text);
}

.mock__sw b {
  grid-area: cfg;
  font-size: 0.74rem;
  font-weight: 500;
  color: var(--text-tertiary);
}

.mock__sw i {
  position: relative;
  grid-area: sw;
  align-self: center;
  width: 34px;
  height: 20px;
  border-radius: 999px;
  background: var(--border-strong);
}

.mock__sw i::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--shadow-sm);
}

.mock__sw .is-on i { background: var(--accent); }
/* Moved with a transform, not with `left`, so the knob never touches layout. */
.mock__sw .is-on i::after { transform: translateX(14px); }

/* -- what each campaign actually brought back -- */
.mock__res {
  margin: 0;
  padding: 0.35rem 0.5rem 0.15rem;
  list-style: none;
}

.mock__res li {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 3.1rem 4rem 3.4rem;
  align-items: center;
  gap: 0.35rem;
  padding: 0.55rem;
  font-size: 0.82rem;
}

.mock__res li + li { border-top: 1px solid var(--border); }

.mock__res span {
  font-weight: 600;
  color: var(--text);
}

.mock__res b,
.mock__res em {
  font-style: normal;
  font-weight: 500;
  font-variant-numeric: tabular-nums;
  text-align: right;
  color: var(--text-secondary);
}

.mock__res em {
  font-weight: 600;
  color: var(--accent-strong);
}

/* Plain case here: the column labels are too close together to survive the
   extra width that uppercase and tracking add. */
.mock__res .is-head { font-size: 0.72rem; }

.mock__res .is-head span,
.mock__res .is-head b,
.mock__res .is-head em {
  font-weight: 600;
  color: var(--text-tertiary);
}

.mock__resfoot {
  margin: 0;
  padding: 0.75rem 1.05rem 0.85rem;
  border-top: 1px solid var(--border);
  font-size: 0.76rem;
  line-height: 1.45;
  color: var(--text-tertiary);
}

.mock__resfoot b { font-weight: 600; color: var(--text-secondary); }

/* ---------------------------------------------------------------- el encaje -- */
/* The two agenda models, each drawn as the screen it actually produces: a
   column agenda where the customer picks a person, a capacity rail where only
   the seat counts. No box around either case — the mock is the only surface, so
   the pair reads as two pictures rather than two cards. */
.lp-fit {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4.5rem) var(--lp-pad) clamp(1.5rem, 3vw, 2.5rem);
}

/* Section masthead: on a wide screen the heading and its lede share the line
   instead of leaving half the page empty next to a two-word title. */
.lp-head {
  display: grid;
  margin-bottom: clamp(2rem, 4vw, 3rem);
}

.lp-head .lp-h2 { margin-bottom: 0.85rem; }

.lp-head__lede {
  max-width: 54ch;
  margin: 0;
  font-size: clamp(1rem, 1.1vw, 1.08rem);
  line-height: 1.6;
  color: var(--text-secondary);
}

.lp-fit__pair {
  display: grid;
  gap: clamp(2.4rem, 5vw, 3.5rem);
}

.lp-fit__case {
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.lp-fit__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.25rem, 2vw, 1.6rem);
  font-weight: 600;
  line-height: 1.15;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.lp-fit__text {
  margin: 0;
  max-width: 48ch;
  font-size: 0.98rem;
  line-height: 1.6;
  color: var(--text-secondary);
}

/* These mocks sit on paper, not on the teal hero, so they wear the paper
   shadow and a hairline instead of the hero's deep drop. */
.lp-fit__case .mock {
  width: 100%;
  margin-top: 0.3rem;
  border: 1px solid var(--border);
  box-shadow: var(--shadow);
}

/* Pushed to the bottom so both cases end on the same line whatever the copy. */
.lp-fit__who {
  margin: auto 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
  line-height: 1.5;
  color: var(--text-tertiary);
}

.mock__head {
  margin: 0;
  padding: 0.7rem 0.9rem;
  border-bottom: 1px solid var(--border);
  background: color-mix(in srgb, var(--accent) 7%, var(--surface));
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text-secondary);
}

/* Column agenda: one column per professional, exactly like the real one. Only
   the tint changes per person; every label keeps the full-contrast ink. */
.mock__grid {
  display: grid;
  grid-template-columns: auto repeat(3, minmax(0, 1fr));
  gap: 0.25rem;
  padding: 0.7rem 0.75rem 0.85rem;
}

.mock__gh {
  padding: 0 0.15rem 0.35rem;
  border-bottom: 1px solid var(--border);
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--text-secondary);
}

.mock__gt {
  align-self: center;
  padding-right: 0.5rem;
  font-size: 0.72rem;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}

.mock__gb {
  display: flex;
  align-items: center;
  min-height: 2.1rem;
  padding: 0 0.5rem;
  border-radius: 8px;
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text);
  background: color-mix(in srgb, var(--accent) 14%, var(--surface));
}

.mock__gb--a { background: color-mix(in srgb, var(--accent) 16%, var(--surface)); }
.mock__gb--b { background: color-mix(in srgb, var(--success) 16%, var(--surface)); }
.mock__gb--c { background: color-mix(in srgb, var(--warn) 20%, var(--surface)); }

/* A booking that runs into the next row is drawn as one block: the row gap is
   cancelled and the two halves lose the radius where they meet. */
.mock__gb.is-start {
  border-end-start-radius: 0;
  border-end-end-radius: 0;
}

.mock__gb.is-cont {
  min-height: 1.85rem;
  margin-top: -0.25rem;
  border-start-start-radius: 0;
  border-start-end-radius: 0;
}

.mock__gb.is-free {
  background: transparent;
  border: 1px dashed var(--border-strong);
  font-weight: 500;
  color: var(--text-tertiary);
}

/* Capacity rail: seats, not names. The filled row goes grey because it has
   stopped being offered. */
.mock__pool {
  margin: 0;
  padding: 0.55rem 0.6rem 0.75rem;
  list-style: none;
}

.mock__pool li {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  padding: 0.6rem 0.55rem;
  border-radius: var(--radius-sm);
  font-size: 0.82rem;
}

.mock__pool li + li { margin-top: 0.2rem; }

.mock__pt {
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text);
}

.mock__dots {
  display: flex;
  gap: 0.3rem;
  margin-right: auto;
}

.mock__dots i {
  width: 9px;
  height: 9px;
  border: 1px solid var(--border-strong);
  border-radius: 50%;
}

.mock__dots i.is-on {
  background: var(--accent);
  border-color: var(--accent);
}

.mock__pool em {
  font-style: normal;
  font-size: 0.74rem;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--text-tertiary);
}

.mock__pool .is-full {
  background: color-mix(in srgb, var(--border) 55%, var(--surface));
}

.mock__pool .is-full em { color: var(--text-secondary); }

.mock__pool .is-full .mock__dots i {
  background: var(--text-tertiary);
  border-color: var(--text-tertiary);
}

/* ----------------------------------------------------------------- las pegas -- */
/* The owner's own objection in the display face, the answer underneath. Ruled
   list, no boxes: the quotes are the structure. */
.lp-cases {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4rem) var(--lp-pad) clamp(2rem, 4vw, 3rem);
}

.lp-cases__list {
  display: grid;
  gap: 0;
  margin: 0;
  border-top: 1px solid var(--border);
}

.lp-case {
  padding: 1.3rem 0;
  border-bottom: 1px solid var(--border);
}

.lp-case dt {
  max-width: 32ch;
  margin: 0 0 0.5rem;
  font-family: var(--font-display);
  font-size: clamp(1.08rem, 1.5vw, 1.22rem);
  font-weight: 600;
  line-height: 1.25;
  letter-spacing: -0.015em;
  color: var(--text);
  text-wrap: balance;
}

.lp-case dd {
  max-width: 44ch;
  margin: 0;
  font-size: 0.95rem;
  line-height: 1.55;
  color: var(--text-secondary);
}

/* -- the drawn answer under each objection ------------------------------- */
/* A page of nine paragraphs is a page nobody reads. Each pega gets the
   smallest picture that settles it: a bar as long as the service lasts, the
   fortnight that disappears from the calendar, the hour changing hands. Small
   and uniform on purpose, so nine of them read as one device and not as nine
   ornaments. */
.lp-ca {
  /* Held to the width of the answer above it: a picture running twice as wide
     as its own paragraph reads as a different section. */
  max-width: 30rem;
  margin-top: 0.9rem;
  padding: 0.75rem 0.85rem 0.8rem;
  border: 1px solid var(--border);
  border-radius: var(--radius, 14px);
  background: color-mix(in srgb, var(--surface) 70%, transparent);
}

.lp-ca__label {
  margin: 0 0 0.5rem;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.lp-ca__foot {
  margin: 0.55rem 0 0;
  font-size: 0.78rem;
  line-height: 1.4;
  color: var(--text-tertiary);
}

/* The week, with the day off struck out of it. */
.lp-ca__days {
  display: flex;
  gap: 0.3rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-ca__days li {
  display: grid;
  place-items: center;
  width: 1.75rem;
  height: 1.75rem;
  border: 1px solid color-mix(in srgb, var(--accent) 30%, transparent);
  border-radius: 8px;
  background: var(--accent-soft);
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--text);
  transition: background-color 0.3s var(--ease) 0.35s,
    border-color 0.3s var(--ease) 0.35s, color 0.3s var(--ease) 0.35s;
}

.lp-ca__days .is-off {
  border-color: var(--border);
  background: transparent;
  color: var(--text-tertiary);
  text-decoration: line-through;
}

/* Two services, two bars, and the difference is the point. */
.lp-ca__bar {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 0.15rem 0.6rem;
  margin: 0;
  font-size: 0.8rem;
  color: var(--text-secondary);
}

.lp-ca__bar + .lp-ca__bar { margin-top: 0.55rem; }

.lp-ca__bar b {
  grid-column: 2;
  grid-row: 1 / span 2;
  font-size: 0.8rem;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.lp-ca__bar i {
  display: block;
  grid-column: 1;
  height: 0.55rem;
  width: var(--w, 100%);
  border-radius: 999px;
  background: var(--accent);
  transform-origin: left;
  transition: transform 0.7s var(--ease-out) calc(var(--d, 0) * 0.11s + 0.15s);
}

/* A fortnight of August, gone. */
.lp-ca__cal {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 0.2rem;
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-ca__cal li {
  height: 0.8rem;
  border-radius: 3px;
  background: var(--accent);
  box-shadow: none;
  transition: background-color 0.35s var(--ease) calc(var(--n, 0) * 18ms),
    box-shadow 0.35s var(--ease) calc(var(--n, 0) * 18ms);
}

/* A closed day is hollow, not a different shade of full: at this size a tint
   against a tint is not a difference anyone sees. */
.lp-ca__cal .is-off {
  background: transparent;
  box-shadow: inset 0 0 0 1px var(--border-strong);
}


/* The switches that ship off, and stay off. Nothing here animates: that is
   exactly what the picture is saying. */
.lp-ca .lp-fl__sw {
  margin: 0 0 0.35rem;
  padding: 0.35rem 0.5rem;
  font-size: 0.78rem;
  font-weight: 500;
}

.lp-ca .lp-fl__sw:last-child { margin-bottom: 0; }

.lp-fl__sw--off i { background: var(--border-strong); }
.lp-fl__sw--off i::after { transform: none; }

/* The rows borrowed from the flows sit tighter in here. */
.lp-ca .lp-fl__row { font-size: 0.8rem; }
.lp-ca .lp-fl__row em { font-size: 0.72rem; }

/* ------------------------------------------------------------------ diferencia -- */
.lp-why {
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: clamp(2.5rem, 6vw, 4rem) var(--lp-pad) clamp(3rem, 7vw, 4.5rem);
}

.lp-why__list {
  display: grid;
  gap: 1.1rem clamp(1.5rem, 4vw, 3.5rem);
  margin: 0;
  padding: 0;
  list-style: none;
}

.lp-why__list li {
  display: flex;
  align-items: flex-start;
  gap: 0.7rem;
}

.lp-why__ico {
  flex: none;
  margin-top: 0.15rem;
  color: var(--accent);
}

.lp-why__list p {
  margin: 0;
  font-size: 0.98rem;
  line-height: 1.55;
  color: var(--text-secondary);
}

.lp-why__list b {
  display: block;
  font-weight: 600;
  color: var(--text);
}

/* ------------------------------------------------------------------- estado -- */
/* The sign-up is a tab of its own now, so it owns the first screen rather than
   closing someone else's. */
.lp-soon {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  padding: clamp(3.5rem, 8vw, 6rem) var(--lp-pad) clamp(3.5rem, 8vw, 5.5rem);
  background: var(--hero-bg);
  color: var(--hero-ink);
  text-align: center;
}

.lp-soon__glow {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
}

.lp-soon__inner {
  max-width: 46ch;
  margin: 0 auto;
}

.lp-soon__back { justify-content: center; margin: 1.8rem 0 0; }

.lp-soon__title {
  margin: 0 0 0.9rem;
  font-family: var(--font-display);
  font-size: clamp(1.8rem, 3.4vw, 2.7rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.022em;
}

.lp-soon__text {
  margin: 0 0 1.6rem;
  font-size: 1.05rem;
  line-height: 1.6;
  color: var(--hero-dim-strong);
}

/* A state, not a control: no pill, no border, nothing that invites a click on
   a page where there is nothing yet to click. */
.lp-soon__meta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.9rem;
  margin: 0;
  color: var(--hero-dim-strong);
  font-size: 0.8rem;
  font-weight: 600;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

/* ------------------------------------------------------- apuntarse a la lista -- */
/* Sits on the deep teal, so the fields are lit from the surface itself rather
   than dropped in as white boxes: a translucent fill, a hairline in the same
   ink as the text, and the button in that ink with the teal back on top. */
.lp-signup {
  max-width: 27rem;
  margin: 1.9rem auto 0;
  text-align: left;
}

/* Honeypot: out of sight, out of the tab order, out of the a11y tree. */
.lp-signup__pot {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.lp-signup__fields {
  display: grid;
  gap: 0.8rem;
}

.lp-signup__field { margin: 0; }

.lp-signup__label {
  display: block;
  margin-bottom: 0.32rem;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--hero-dim-strong);
}

.lp-signup__input {
  width: 100%;
  padding: 0.72rem 0.9rem;
  border: 1px solid var(--hero-line);
  border-radius: var(--radius-sm);
  background: rgba(255, 255, 255, 0.08);
  color: var(--hero-ink);
  font: inherit;
  font-size: 1rem;
  transition: border-color 0.18s var(--ease), background-color 0.18s var(--ease);
}

.lp-signup__input:hover { border-color: var(--hero-chip-line); }

.lp-signup__input:focus {
  outline: 2px solid var(--hero-mint);
  outline-offset: 2px;
  border-color: var(--hero-mint);
  background: rgba(255, 255, 255, 0.14);
}

.lp-signup__input.is-bad {
  border-color: color-mix(in srgb, var(--danger) 55%, #ffffff);
}

.lp-signup__err {
  display: block;
  margin-top: 0.34rem;
  font-size: 0.84rem;
  font-weight: 600;
  color: color-mix(in srgb, var(--danger) 42%, #ffffff);
}

.lp-signup__go {
  width: 100%;
  margin-top: 1.15rem;
  padding: 0.85rem 1.2rem;
  border: 0;
  border-radius: 999px;
  background: var(--hero-ink);
  color: var(--hero-b);
  font: inherit;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: -0.01em;
  cursor: pointer;
  transition: transform 0.18s var(--ease), box-shadow 0.18s var(--ease);
}

.lp-signup__go:hover {
  transform: translateY(-1px);
  box-shadow: 0 12px 26px -14px rgba(0, 0, 0, 0.75);
}

.lp-signup__go:active { transform: translateY(0); }

.lp-signup__small {
  margin: 0.9rem 0 0;
  font-size: 0.82rem;
  line-height: 1.5;
  text-align: center;
  color: var(--hero-dim);
}

/* The article 13 notice. Small and quiet — it is not a selling point — but on
   the page, in reading order, before the button is pressed and not behind a
   link. Left-aligned: it is four sentences, and centred prose of that length
   is read by nobody. */
.lp-signup__legal {
  margin: 0.9rem 0 0;
  padding-top: 0.9rem;
  border-top: 1px solid color-mix(in srgb, var(--hero-dim) 25%, transparent);
  font-size: 0.76rem;
  line-height: 1.6;
  text-align: left;
  color: var(--hero-dim);
}

.lp-signup__legal b { font-weight: 600; }

.lp-signup__legal a {
  color: inherit;
  text-decoration: underline;
  text-underline-offset: 0.15em;
}

.lp-soon__meta::before,
.lp-soon__meta::after {
  content: "";
  width: clamp(1.5rem, 6vw, 3.5rem);
  height: 1px;
  background: var(--hero-line);
}

/* -------------------------------------------------------------------- footer -- */
.lp-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0.6rem 1.5rem;
  max-width: var(--lp-max);
  margin: 0 auto;
  padding: 2rem var(--lp-pad) 2.5rem;
}

.lp-foot__brand {
  display: flex;
  color: var(--text);
  align-items: center;
  gap: 0.55rem;
  margin: 0;
  font-weight: 600;
}

/* The tabs again at the bottom, so nobody has to scroll back up to move on. */
.lp-foot__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 0.9rem;
  margin-right: auto;
}

.lp-foot__nav a {
  font-size: 0.88rem;
  color: var(--text-secondary);
  transition: color 0.18s var(--ease);
}

.lp-foot__nav a:hover { color: var(--accent-strong); }

.lp-foot__note {
  flex-basis: 100%;
  margin: 0;
  padding-top: 0.9rem;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
  color: var(--text-tertiary);
}

.lp-foot__note b { font-weight: 600; color: var(--text-secondary); }

.lp-foot__note a {
  margin-left: 0.5rem;
  font-weight: 600;
  color: var(--accent-strong);
}

/* The obligatory three. Quieter than the sections above them — nobody arrives
   wanting to read a legal notice — but never hidden, and on every page. */
.lp-foot__legal {
  display: flex;
  flex-wrap: wrap;
  gap: 0.2rem 1rem;
  flex-basis: 100%;
  padding-top: 0.5rem;
}

.lp-foot__legal a {
  font-size: 0.82rem;
  color: var(--text-tertiary);
  transition: color 0.18s var(--ease);
}

.lp-foot__legal a:hover { color: var(--accent-strong); }

/* /entrar has no footer of its own; there the row stands on its own. */
/* Fallbacks because this one lives outside `.lp`, where those two are set. */
.entrar-legal {
  justify-content: center;
  max-width: var(--lp-max, 1280px);
  margin: 1.5rem auto 3rem;
  padding: 0 var(--lp-pad, 1.15rem);
}

/* ------------------------------------------------- legal: the documents -- */
/* A reading column, not a landing page. One measure, generous leading, and
   headings that are found by scanning rather than by being loud. */
.legal {
  max-width: 46rem;
  margin: 0 auto;
  padding: clamp(2rem, 6vw, 4rem) var(--lp-pad) 1rem;
}

.legal__head { margin-bottom: 2.5rem; }

.legal__eyebrow {
  margin: 0 0 0.4rem;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-tertiary);
}

.legal__title {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(1.9rem, 5vw, 2.8rem);
  line-height: 1.1;
  letter-spacing: -0.02em;
}

.legal__meta {
  margin: 0.6rem 0 0;
  font-size: 0.88rem;
  color: var(--text-tertiary);
}

/* Shown only while a mandatory detail is unset. Loud on purpose: the page is
   not finished, and it should not be possible to forget that it is not. */
.legal__gap {
  margin: 0 0 2rem;
  padding: 0.9rem 1.1rem;
  border: 1px dashed color-mix(in srgb, var(--danger, #b4232a) 45%, var(--border));
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--danger, #b4232a) 6%, transparent);
  font-size: 0.92rem;
}

.legal__s { margin-bottom: 2.6rem; }

.legal__s h2 {
  margin: 0 0 0.9rem;
  font-family: var(--font-display);
  font-size: 1.3rem;
  letter-spacing: -0.01em;
}

.legal__s h3 {
  margin: 1.8rem 0 0.7rem;
  font-size: 1rem;
  font-weight: 650;
}

.legal__s p,
.legal__ul li,
.legal__tldr li {
  font-size: 0.98rem;
  line-height: 1.7;
  color: var(--text-secondary);
}

.legal__s p { margin: 0 0 1rem; }
.legal__s b { color: var(--text); font-weight: 600; }

.legal__ul,
.legal__tldr {
  margin: 0 0 1rem;
  padding-left: 1.1rem;
  display: grid;
  gap: 0.5rem;
}

.legal__tldr {
  list-style: none;
  padding: 1.1rem 1.3rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  background: color-mix(in srgb, var(--accent) 4%, transparent);
}

.legal__tldr li { position: relative; padding-left: 1rem; }

.legal__tldr li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.65em;
  width: 0.32rem;
  height: 0.32rem;
  border-radius: 50%;
  background: var(--accent-strong);
}

/* A paragraph that changes what the rest of the page means. */
.legal__nota {
  padding: 0.9rem 1.1rem;
  border-left: 3px solid var(--accent-strong);
  border-radius: 0 var(--radius) var(--radius) 0;
  background: color-mix(in srgb, var(--accent) 6%, transparent);
}

/* Identification block: label and value, side by side where there is room. */
.legal-id {
  margin: 0 0 1.2rem;
  display: grid;
  gap: 0.1rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 0.4rem 0.2rem;
}

.legal-id__row {
  display: grid;
  grid-template-columns: 12rem 1fr;
  gap: 0.2rem 1rem;
  padding: 0.55rem 1rem;
}

.legal-id__row + .legal-id__row { border-top: 1px solid var(--border); }

.legal-id dt {
  margin: 0;
  font-size: 0.85rem;
  color: var(--text-tertiary);
}

.legal-id dd {
  margin: 0;
  font-size: 0.95rem;
  color: var(--text);
}

.legal-id dd i { color: var(--text-tertiary); }

.legal__roles {
  margin: 0;
  display: grid;
  gap: 1rem;
}

.legal__roles dt {
  font-weight: 650;
  font-size: 0.95rem;
}

.legal__roles dd {
  margin: 0.25rem 0 0;
  font-size: 0.98rem;
  line-height: 1.7;
  color: var(--text-secondary);
}

/* Tables carry the four-column answers (finalidad / datos / base / plazo).
   They scroll inside their own box so the page never does. */
.legal__tw {
  overflow-x: auto;
  margin: 0 0 1.2rem;
  border: 1px solid var(--border);
  border-radius: var(--radius);
}

/* From the laptop up they step outside the reading column, centred on it.
   The prose stays at a measure you can read; the table stops scrolling
   sideways on a screen that had the room all along. */
@media (min-width: 64rem) {
  .legal__tw {
    width: min(68rem, calc(100vw - 4rem));
    margin-left: 50%;
    transform: translateX(-50%);
  }
}

.legal__t {
  width: 100%;
  min-width: 40rem;
  border-collapse: collapse;
  font-size: 0.88rem;
}

.legal__t th,
.legal__t td {
  padding: 0.7rem 0.9rem;
  text-align: left;
  vertical-align: top;
  line-height: 1.55;
  border-bottom: 1px solid var(--border);
}

.legal__t thead th {
  font-size: 0.78rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--text-tertiary);
  white-space: nowrap;
}

.legal__t tbody tr:last-child th,
.legal__t tbody tr:last-child td { border-bottom: 0; }

.legal__t td { color: var(--text-secondary); }
.legal__t td b { color: var(--text); font-weight: 600; }

.legal__foot {
  margin-top: 3rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--border);
  font-size: 0.88rem;
  color: var(--text-tertiary);
}

.legal__foot a { color: var(--accent-strong); font-weight: 600; }

@media (max-width: 34rem) {
  .legal-id__row { grid-template-columns: 1fr; }
}

/* --------------------------------------------------------------- /entrar -- */
.entrar-host {
  display: flex;
  align-items: center;
  gap: 0.5rem;
}

.entrar-host .input { flex: 1 1 auto; min-width: 0; }

.entrar-host__suffix {
  flex: none;
  font-size: 0.95rem;
  color: var(--text-tertiary);
}

.entrar-help { margin-top: 1rem; font-size: 0.88rem; }

/* ================================================================ responsive == */

/* Below the laptop the tabs get their own row and scroll sideways, so the
   labels stay legible instead of being squeezed. The brand, the sign-up button
   and "Acceder" stay together on the first row. */
@media (max-width: 1023px) {
  .lp-top {
    flex-wrap: wrap;
    row-gap: 0;
    padding-bottom: 0;
  }

  .lp-tabs {
    order: 3;
    width: 100%;
    margin: 0 calc(-1 * var(--top-pad));
    padding: 0.2rem var(--top-pad) 0.5rem;
    gap: 0.15rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }

  .lp-tabs::-webkit-scrollbar { display: none; }
  .lp-tab { font-size: 0.86rem; padding-inline: 0.55rem; }
  .lp-tab::after { left: 0.55rem; right: 0.55rem; }
}

/* On a narrow phone the header is brand + the one action; the status pill and
   "Acceder" would push the tabs off the row, and both are said again below. */
@media (max-width: 519px) {
  .lp-status,
  .lp-top__link { display: none; }
}

/* Phones keep one column; the hour becomes a lead-in rather than a column. */
@media (max-width: 719px) {
  .lp-mo__hour {
    display: inline-block;
    padding: 0.15rem 0.6rem;
    border-radius: 999px;
    background: var(--accent-soft);
    font-size: 1.05rem;
  }

  .lp-hero__show { padding-bottom: 0; }
  .mock--panel { width: 100%; }

  /* One screen at a time on a phone: the hero shows the owner's side, which is
     whose page this is. The customer's phone gets its own moment on "Cómo
     funciona", at 22:40. */
  .lp-hero__show .mock--phone { display: none; }

  /* The buttons go full width rather than wrapping into two ragged lines. */
  .lp-cta__row .lp-btn { flex: 1 1 100%; justify-content: center; }
}

/* Tablet portrait: the grids pair up, the day stays a single column. */
@media (min-width: 560px) {
  .lp-why__list { grid-template-columns: 1fr 1fr; }
  /* The four-beat flow pairs up: two beats over two. In two columns a card is
     no longer under the one before it, so the thread would lie: it goes. */
  .lp-fl--two { grid-template-columns: 1fr 1fr; }
  .lp-fl--two .lp-fl__card + .lp-fl__card::before { content: none; }
  .lp-swap__pair { grid-template-columns: 1fr 1fr; }
  .lp-first__list { grid-template-columns: repeat(3, 1fr); }
}

/* Laptop and up: the day becomes hour + words + screen, alternating side. */
@media (min-width: 900px) {
  .lp-mo {
    grid-template-columns: minmax(88px, auto) minmax(0, 1fr) minmax(0, 1.02fr);
    grid-template-areas: "hour say art";
    align-items: center;
    gap: clamp(1.5rem, 3vw, 3rem);
  }

  .lp-mo__hour { grid-area: hour; align-self: stretch; padding-top: 0.35rem; }
  .lp-mo__say { grid-area: say; }
  .lp-mo__art { grid-area: art; }

  /* Alternate which side the screen sits on so the page has a rhythm instead
     of a stack; the hour rail stays put, on the left, always. */
  .lp-mo--flip {
    grid-template-columns: minmax(88px, auto) minmax(0, 1.02fr) minmax(0, 1fr);
    grid-template-areas: "hour art say";
  }

  /* A scene becomes caption + picture, swapping sides so the four of them
     read as a rhythm instead of a stack. */
  .lp-scene {
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    grid-template-areas: "say art";
    gap: clamp(2rem, 4vw, 3.5rem);
  }

  .lp-scene__say { grid-area: say; }
  .lp-scene__art { grid-area: art; }

  .lp-scene--flip {
    grid-template-columns: minmax(0, 1.08fr) minmax(0, 0.92fr);
    grid-template-areas: "art say";
  }

  /* The waitlist is the scene that sells the thing, so it gets the full
     width: caption over the top, the four beats laid out underneath. */
  .lp-scene--wide {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "say" "art";
    justify-items: center;
    gap: clamp(1.6rem, 3vw, 2.4rem);
  }

  .lp-scene--wide .lp-scene__say {
    max-width: 52rem;
    text-align: center;
  }

  .lp-scene--wide .lp-scene__say p { max-width: 62ch; margin-inline: auto; }
  .lp-scene--wide .lp-scene__note { justify-content: center; }
  .lp-scene--wide .lp-scene__art { width: 100%; }

  /* An index, not three identical cards side by side. Full-width rows with a
     hairline between them: the numeral keeps its column, the arrow keeps
     its own, and nothing is boxed. Three equal cards in a row is the one
     layout every page like this reaches for, and it is worth not reaching. */
  .lp-onward__list { gap: 0; }
  .lp-onward__list li + li { border-top: 1px solid var(--border); }

  .lp-onward__list a {
    column-gap: clamp(1.5rem, 4vw, 3.5rem);
    padding: clamp(1.15rem, 2vw, 1.6rem) clamp(0.4rem, 1.2vw, 0.9rem);
    border: 0;
    border-radius: 0;
    background: none;
  }

  .lp-onward__list a:hover { background: none; }

  .lp-onward__n { font-size: 1.4rem; color: var(--text-tertiary); }
  .lp-onward__list a:hover .lp-onward__n { color: var(--accent); }

  .lp-onward__list b {
    font-family: var(--font-display);
    font-size: clamp(1.15rem, 1.6vw, 1.4rem);
    letter-spacing: -0.018em;
  }

  .lp-onward__list a:hover b { color: var(--accent-strong); }

  /* The tabs that end pointing at one single place keep their card: a lone
     borderless row with nothing above or below it reads as unfinished. */
  .lp-onward--single .lp-onward__list a {
    padding: 1.25rem 1.4rem;
    border: 1px solid var(--border);
    border-radius: var(--radius-lg, 18px);
    background: var(--surface);
  }

  .lp-onward--single .lp-onward__list a:hover {
    border-color: var(--accent);
    background: var(--accent-soft);
  }

  /* A section heading is one message. It used to be a big title on the left
     with a small paragraph floating in the top right, which is a shape every
     page of this kind wears and which belongs to none of them: the eye has to
     decide which half to read first. Title on top, line underneath. */
  .lp-head .lp-h2 { max-width: 24ch; }

  /* The engine's blocks: words on one side, the screen on the other, swapping
     sides so the section has a rhythm instead of a stack. */
  .lp-eng__mo {
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.95fr);
    grid-template-areas: "say art";
    align-items: center;
    gap: clamp(2rem, 4vw, 4rem);
  }

  .lp-eng__say { grid-area: say; }
  .lp-eng__art { grid-area: art; }

  .lp-eng__mo--flip {
    grid-template-columns: minmax(0, 0.95fr) minmax(0, 1fr);
    grid-template-areas: "art say";
  }

  /* The two ways of working stand side by side, so the difference is a glance
     and not a scroll. */
  .lp-fit__pair { grid-template-columns: 1fr 1fr; }

  .lp-cases__list {
    grid-template-columns: 1fr 1fr;
    column-gap: clamp(1.8rem, 4vw, 3.5rem);
  }

  /* Rows line up across the columns: both mocks start on the same line, and
     every answer starts on the same line as its neighbour's. */
  @supports (grid-template-rows: subgrid) {
    .lp-fit__pair { grid-template-rows: auto auto auto auto; }

    .lp-fit__case {
      display: grid;
      grid-row: span 4;
      grid-template-rows: subgrid;
    }

    .lp-case {
      display: grid;
      grid-row: span 3;
      grid-template-rows: subgrid;
      align-content: start;
    }
  }
}

@media (min-width: 1024px) {
  /* The tabs fit on the header's own line, so the header is one row again. */
  .lp { --top-h: 3.95rem; }

  /* The headline is two sentences on two lines and has to stay that way, so
     the words get the wider half of the hero and the screens the narrower. */
  .lp-hero__inner {
    grid-template-columns: minmax(0, 1.06fr) minmax(0, 1fr);
  }

  /* The freed hour, start to finish, in one line of four: it reads as a
     sequence rather than as a block of cards. */
  .lp-fl--two { grid-template-columns: repeat(4, 1fr); }

  /* Side by side again, so the thread comes back — now running left to right,
     from one step number to the next. */
  .lp-fl--two .lp-fl__card + .lp-fl__card::before {
    content: "";
    left: calc(var(--fl-gap) * -1);
    top: calc(0.9rem + 0.75rem - 1px);
    width: var(--fl-gap);
    height: 2px;
    transform-origin: left;
  }

  .has-motion .lp-fl--two[data-play]:not(.is-playing) .lp-fl__card + .lp-fl__card::before {
    transform: scaleX(0);
  }

  /* And because the story now travels sideways, so do the cards: each one
     arrives from the one before it instead of rising in place. */
  .has-motion .lp-fl--two[data-play]:not(.is-playing) > .lp-fl__card[data-d] {
    transform: translateX(-18px);
  }

  /* The two halves of the product side by side: the customer's phone and the
     owner's panel. They sit on different baselines so the pair reads as one
     composition, and they never overlap — an overlap would cover the panel's
     own hours, which is the part that has to be legible. */
  .lp-hero__show {
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    gap: clamp(0.75rem, 1.4vw, 1.5rem);
    padding-bottom: 0;
  }

  .lp-hero__show .mock--phone {
    flex: none;
    margin-bottom: -1.75rem;
  }

  .lp-hero__show .mock--panel {
    flex: 1 1 auto;
    width: auto;
    max-width: 460px;
  }
}

@media (min-width: 1280px) {
  .lp { --lp-max: 1320px; }
  .mock--phone-lg { width: 262px; }
  .mock--panel-lg { max-width: 480px; }

  /* Six objections read faster in three columns than in two long ones. */
  .lp-cases__list { grid-template-columns: repeat(3, 1fr); }
}

/* ================================================================== motion == */
/* One idea, four places: a mock that illustrates a *change* performs that
   change once, when you reach it. The finished state is what these rules
   describe by default; the "before" state only exists while JS is present and
   the block has not played yet, so a failed script or a reduced-motion setting
   simply shows the outcome.

   Nothing here animates a mock that merely shows a state — the customer list,
   the column agenda and the results table are stills, and stay stills. */

.lp-loy__stamps .is-on,
.mock__dots i,
.mock__pool li,
.mock__sw i,
.mock__tag,
.mock__price b {
  transition: opacity 0.34s var(--ease-out), transform 0.44s var(--ease-out),
    background-color 0.3s var(--ease), border-color 0.3s var(--ease);
}

.mock__sw i::after { transition: transform 0.34s var(--ease-out); }

/* The line through the old price is drawn at the moment the offer applies. */
.mock__price s {
  text-decoration-color: currentColor;
  transition: text-decoration-color 0.4s var(--ease) 0.35s;
}

.has-motion [data-play]:not(.is-playing) .mock__price s {
  text-decoration-color: transparent;
}

/* -- the card gets its stamps, one at a time -- */
.has-motion .lp-loy[data-play]:not(.is-playing) .lp-loy__stamps .is-on {
  opacity: 0;
  transform: scale(0.5) rotate(-14deg);
}

.lp-loy[data-play] .lp-loy__stamps .is-on:nth-child(1) { transition-delay: 0.08s; }
.lp-loy[data-play] .lp-loy__stamps .is-on:nth-child(2) { transition-delay: 0.21s; }
.lp-loy[data-play] .lp-loy__stamps .is-on:nth-child(3) { transition-delay: 0.34s; }
.lp-loy[data-play] .lp-loy__stamps .is-on:nth-child(4) { transition-delay: 0.47s; }

/* And then the next one asks for its turn, twice, and stops. */
.lp-loy[data-play].is-playing .lp-loy__stamps .is-next {
  animation: loyNext 1.5s var(--ease) 0.7s 2;
}

/* A ring that leaves the circle and fades: "this one is next". */
@keyframes loyNext {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--hero-mint) 55%, transparent); }
  70%, 100% { box-shadow: 0 0 0 7px transparent; }
}

/* -- the seats fill up, and the full row stops being offered -- */
.has-motion .mock--pool[data-play]:not(.is-playing) .mock__dots i.is-on {
  background: transparent;
  border-color: var(--border-strong);
}

.has-motion .mock--pool[data-play]:not(.is-playing) .is-full {
  background: transparent;
}

.mock--pool[data-play] .mock__dots i:nth-child(1) { transition-delay: 0.06s; }
.mock--pool[data-play] .mock__dots i:nth-child(2) { transition-delay: 0.14s; }
.mock--pool[data-play] .mock__dots i:nth-child(3) { transition-delay: 0.22s; }
.mock--pool[data-play] .mock__dots i:nth-child(4) { transition-delay: 0.3s; }
.mock--pool[data-play] .mock__dots i:nth-child(5) { transition-delay: 0.38s; }
.mock--pool[data-play] .mock__dots i:nth-child(6) { transition-delay: 0.46s; }
.mock--pool[data-play] .is-full { transition-delay: 0.5s; }

/* -- the one recipe that is on, turning on -- */
.has-motion .mock--switch[data-play]:not(.is-playing) .is-on i {
  background: var(--border-strong);
}

.has-motion .mock--switch[data-play]:not(.is-playing) .is-on i::after {
  transform: none;
}

.mock--switch[data-play] .is-on i,
.mock--switch[data-play] .is-on i::after { transition-delay: 0.35s; }

/* -- the offer landing on the appointment, then the price it leaves -- */
.has-motion .mock--tagged[data-play]:not(.is-playing) .mock__tag {
  opacity: 0;
  transform: translateY(-7px);
}

.has-motion .mock--tagged[data-play]:not(.is-playing) .mock__price b {
  opacity: 0;
  transform: translateY(5px);
}

.mock--tagged[data-play] .mock__tag { transition-delay: 0.1s; }
.mock--tagged[data-play] .mock__price b { transition-delay: 0.55s; }

/* -- anything that plays, deals itself out one beat at a time ----------- */
/* Every marked element carries its own turn in --d, so a screen plays in the
   order the story happens: the link, the hour, the booking. The finished
   state is the default, so without JS the whole thing is simply there.
   Written against [data-play] rather than against the flows, because the
   product screens on the other tabs tell sequences too. */
[data-play] [data-d] {
  transition: opacity 0.55s var(--ease-out), transform 0.55s var(--ease-out);
  transition-delay: calc(var(--d, 0) * 0.11s);
}

.has-motion [data-play]:not(.is-playing) [data-d] {
  opacity: 0;
  transform: translateY(12px);
}

/* -- the drawn answers under the objections ----------------------------- */
/* The bar grows to the length of the service, the fortnight goes out of the
   calendar day by day, and the week loses its Tuesday. */
.has-motion [data-play]:not(.is-playing) .lp-ca__bar i { transform: scaleX(0); }

.has-motion [data-play]:not(.is-playing) .lp-ca__cal .is-off {
  background: var(--accent);
  box-shadow: none;
}

.has-motion [data-play]:not(.is-playing) .lp-ca__days .is-off {
  border-color: color-mix(in srgb, var(--accent) 30%, transparent);
  background: var(--accent-soft);
  color: var(--text);
}

/* The thread between beats draws itself, top to bottom, as each card lands. */
.has-motion .lp-fl[data-play]:not(.is-playing) .lp-fl__card + .lp-fl__card::before {
  transform: scaleY(0);
}

/* The step number settles rather than appearing at full size. Never from
   scale(0) — nothing in the world arrives out of nothing. */
.lp-fl__n {
  transition: transform 0.5s var(--ease-out) calc(var(--d, 0) * 0.11s + 0.06s);
}

.has-motion .lp-fl[data-play]:not(.is-playing) .lp-fl__n {
  transform: scale(0.86);
}

/* The hour the client takes is not already taken when the card lands: it is a
   plain hour for a beat, and then it is theirs. That half second is the whole
   point of the scene. */
.lp-fl__slots .is-sel {
  transition:
    opacity 0.55s var(--ease-out) calc(var(--d, 0) * 0.11s),
    transform 0.55s var(--ease-out) calc(var(--d, 0) * 0.11s),
    background-color 0.3s var(--ease) calc(var(--d, 0) * 0.11s + 0.45s),
    border-color 0.3s var(--ease) calc(var(--d, 0) * 0.11s + 0.45s),
    color 0.3s var(--ease) calc(var(--d, 0) * 0.11s + 0.45s);
}

.has-motion [data-play]:not(.is-playing) .lp-fl__slots .is-sel {
  border-color: var(--border-strong);
  background: var(--surface);
  color: var(--text-secondary);
  font-weight: 400;
}

/* Same idea one screen over: the service list arrives plain and only then does
   one of them become the one they picked. */
.mock__picks .is-sel {
  transition:
    opacity 0.55s var(--ease-out) calc(var(--d, 0) * 0.11s),
    transform 0.55s var(--ease-out) calc(var(--d, 0) * 0.11s),
    background-color 0.3s var(--ease) calc(var(--d, 0) * 0.11s + 0.5s),
    border-color 0.3s var(--ease) calc(var(--d, 0) * 0.11s + 0.5s),
    color 0.3s var(--ease) calc(var(--d, 0) * 0.11s + 0.5s);
}

.has-motion [data-play]:not(.is-playing) .mock__picks .is-sel {
  border-color: var(--border);
  background: var(--surface);
  color: var(--text-secondary);
  font-weight: 400;
}

/* The five stars fill left to right, the way a rating is given. clip-path so
   nothing reflows; the text is already there underneath. */
.lp-rev__stars,
.lp-fl__card > .lp-fl__stars {
  clip-path: inset(0 0 0 0);
  transition:
    opacity 0.55s var(--ease-out) calc(var(--d, 0) * 0.11s),
    transform 0.55s var(--ease-out) calc(var(--d, 0) * 0.11s),
    clip-path 0.85s var(--ease-out) calc(var(--d, 0) * 0.11s + 0.3s);
}

.has-motion [data-play]:not(.is-playing) .lp-rev__stars,
.has-motion [data-play]:not(.is-playing) .lp-fl__card > .lp-fl__stars {
  clip-path: inset(0 100% 0 0);
}

/* The cancelled line is struck through at the moment it is cancelled. */
.lp-fl__row--gone {
  transition: text-decoration-color 0.4s var(--ease) 0.5s;
}

.has-motion .lp-fl[data-play]:not(.is-playing) .lp-fl__row--gone {
  text-decoration-color: transparent;
}

/* The reply the client actually presses, being pressed. */
.lp-fl[data-play].is-playing .lp-fl__btns .is-tap {
  animation: flTap 1.4s var(--ease) 0.45s 2;
}

@keyframes flTap {
  0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 45%, transparent); }
  70%, 100% { box-shadow: 0 0 0 8px transparent; }
}

/* The business with the reviews, being chosen. */
.lp-fl[data-play].is-playing .lp-fl__results .is-pick {
  animation: flPick 1.6s var(--ease) 0.8s 2;
}

@keyframes flPick {
  0% { box-shadow: 0 0 0 3px var(--accent-soft); }
  45% { box-shadow: 0 0 0 9px transparent; }
  100% { box-shadow: 0 0 0 3px var(--accent-soft); }
}

/* The automation is off until the owner turns it on — so that is what it
   does here too, rather than arriving already on. */
.lp-fl__sw i { transition: background-color 0.34s var(--ease) 0.75s; }
.lp-fl__sw i::after { transition: transform 0.34s var(--ease-out) 0.75s; }

.has-motion .lp-fl[data-play]:not(.is-playing) .lp-fl__sw i {
  background: var(--border-strong);
}

.has-motion .lp-fl[data-play]:not(.is-playing) .lp-fl__sw i::after {
  transform: none;
}

/* -- what arrives with the page ---------------------------------------- */
/* [data-reveal] waits until you scroll to it, which is wrong for the first
   screen: it is already in front of you. [data-rise] plays on load instead, so
   every tab opens with the same small movement rather than sitting there. */
.has-motion [data-rise] {
  opacity: 0;
  transform: translateY(20px);
}

/* The headline is the exception: it does not fade in as a block. Its two
   sentences rise out from behind their own line, one after the other, which is
   the one moment on the site that is allowed to be theatrical. */
.has-motion .lp-hero__title[data-rise] {
  opacity: 1;
  transform: none;
}

.has-motion .lp-hero__title[data-rise] .lp-hero__line > span {
  opacity: 0;
  transform: translateY(105%);
}

.has-motion .lp-hero__title[data-rise].is-in .lp-hero__line > span {
  opacity: 1;
  transform: none;
  transition:
    transform 0.8s var(--ease-out) calc(var(--i, 0) * 90ms),
    opacity 0.5s var(--ease) calc(var(--i, 0) * 90ms);
}

/* The two screens arrive as an object, not as a card: a touch of scale with
   the rise so they read as coming forward rather than sliding up. */
.has-motion .lp-hero__show[data-rise] {
  transform: translateY(26px) scale(0.985);
}

.has-motion [data-rise].is-in {
  opacity: 1;
  transform: none;
  transition: opacity 0.75s var(--ease-out), transform 0.75s var(--ease-out);
}

/* -- lists that arrive one item at a time ------------------------------- */
/* The index is set by motion.js, so the delay is the item's own and a grid of
   six cards lands as six cards instead of one block. */
.has-motion [data-stagger] > * {
  opacity: 0;
  transform: translateY(16px);
}

.has-motion [data-stagger].is-in > * {
  opacity: 1;
  transform: none;
  transition:
    opacity 0.6s var(--ease-out) calc(var(--i, 0) * 70ms),
    transform 0.6s var(--ease-out) calc(var(--i, 0) * 70ms);
}

/* -- depth while you scroll --------------------------------------------- */
/* `translate` rather than `transform`, so this never fights the reveal above,
   which owns transform. */
[data-parallax] { translate: 0 var(--py, 0px); }

/* -- today crosses itself out, and the answers tick themselves off ------- */
.lp-swap__side--before li { transition: text-decoration-color 0.45s var(--ease); }

.has-motion .lp-swap__pair[data-play]:not(.is-playing) .lp-swap__side--before li {
  text-decoration-color: transparent;
}

.lp-swap__side--before li:nth-child(1) { transition-delay: 0.1s; }
.lp-swap__side--before li:nth-child(2) { transition-delay: 0.25s; }
.lp-swap__side--before li:nth-child(3) { transition-delay: 0.4s; }
.lp-swap__side--before li:nth-child(4) { transition-delay: 0.55s; }

.lp-swap__side--after li {
  transition: opacity 0.45s var(--ease-out), transform 0.45s var(--ease-out);
}

.has-motion .lp-swap__pair[data-play]:not(.is-playing) .lp-swap__side--after li {
  opacity: 0;
  transform: translateX(-10px);
}

.lp-swap__side--after li:nth-child(1) { transition-delay: 0.45s; }
.lp-swap__side--after li:nth-child(2) { transition-delay: 0.6s; }
.lp-swap__side--after li:nth-child(3) { transition-delay: 0.75s; }
.lp-swap__side--after li:nth-child(4) { transition-delay: 0.9s; }

/* ------------------------------------------------------------------ motion -- */
@media (prefers-reduced-motion: reduce) {
  .lp-hero__orb,
  .lp-status__dot { animation: none; }

  /* The page still arrives; it just arrives without travelling. */
  .has-motion [data-rise],
  .has-motion [data-stagger] > * { opacity: 1; transform: none; }

  /* The headline is simply there, rather than climbing out of its line. */
  .has-motion .lp-hero__title[data-rise] .lp-hero__line > span,
  .has-motion .lp-hero__title[data-rise].is-in .lp-hero__line > span {
    opacity: 1;
    transform: none;
    transition: none;
  }

  .has-motion .lp-hero__show[data-rise] { transform: none; }

  .lp-marquee.is-looping .lp-marquee__track { animation: none; }
  [data-parallax] { translate: none; }

  .lp-swap__side--before li,
  .lp-swap__side--after li { transition-duration: 0.01ms; transition-delay: 0s; }

  /* The flows stop being flows: the whole story is simply on screen. */
  [data-play] [data-d],
  .lp-fl__row--gone,
  .lp-fl__n,
  .lp-fl__card + .lp-fl__card::before,
  .lp-fl__slots .is-sel,
  .mock__picks .is-sel,
  .lp-ca__bar i,
  .lp-ca__cal li,
  .lp-ca__days li,
  .lp-rev__stars,
  .lp-fl__card > .lp-fl__stars,
  .lp-fl__sw i,
  .lp-fl__sw i::after { transition-duration: 0.01ms; transition-delay: 0s; }

  .lp-fl[data-play].is-playing .lp-fl__btns .is-tap,
  .lp-fl[data-play].is-playing .lp-fl__results .is-pick { animation: none; }

  /* The outcome still arrives — it just arrives without travelling. motion.js
     marks these played immediately, so only the colour changes remain. */
  .lp-loy[data-play] .lp-loy__stamps .is-next { animation: none; }

  .lp-loy__stamps .is-on,
  .mock__dots i,
  .mock__pool li,
  .mock__sw i,
  .mock__sw i::after,
  .mock__tag,
  .mock__price b,
  .mock__price s { transition-duration: 0.01ms; transition-delay: 0s; }
}
