/* ==========================================================================
   Early access — the pre-launch capture component.

   One component, four placements (hero, under the live demo, the closing CTA
   panel, the footer). It replaces the two forms this site used to carry, both
   of which reported success without storing anything: the footer's leftover
   Webflow form, which still pointed at the template's original Webflow
   project, and the "Notify me" form in webapp/Commingsoonpage.html, whose
   submit handler only hid itself and revealed a tick.

   Everything here is deliberately built from the brand layer already defined
   in style.css (--looxx-black / --silk / --stone / --mist / --taupe, Playfair
   for display, Inter for UI, the 999px pill). Nothing new is invented: the
   chips are the same pill as .lx-btn at a smaller size, so the questions read
   as the buttons they sit under rather than as a form widget bolted on.

   Loaded AFTER style.css so these rules win without needing !important or
   selector-weight games against a 7,000-line stylesheet.
   ========================================================================== */

.lx-ea {
  --ea-ink: var(--looxx-black);
  --ea-soft: var(--stone);
  --ea-line: var(--mist);
  --ea-field: #fff;
  --ea-accent: #8f5f37;
  --ea-danger: #9b2f38;

  width: 100%;
  max-width: 30rem;
  text-align: left;
}

/* The closing CTA sits on the clay gradient panel; the same component, with
   its own token values rather than a second set of selectors. */
.lx-ea--dark {
  --ea-ink: var(--silk);
  --ea-soft: #e6dbd0c4;
  --ea-line: #f3e9df3d;
  --ea-field: #ffffff14;
  --ea-accent: #f0cba6;
  --ea-danger: #ffb9b0;
}

.lx-ea--center { margin-inline: auto; }
.lx-ea--center .lx-ea__panel { align-items: center; text-align: center; }

/* --- The hero placement --------------------------------------------------
   No card around it: the rail lifts off the paper on its own, which is one
   less edge than wrapping a bordered field inside a bordered box. Only the
   hero is elevated — the closing panel already sits on the clay gradient, and
   the footer field is meant to stay quiet.

   The shadow is warm rather than neutral grey; a grey drop shadow on a cream
   ground reads as dirt. Two layers: a tight one to seat the edge, a wide soft
   one for the lift. */
.lx-ea--hero {
  max-width: 34rem;
}

.lx-ea--hero .lx-ea__rail {
  border-color: #1717140f;
  box-shadow:
    0 1px 2px #2b241f0d,
    0 14px 30px -14px #2b241f26;
}

.lx-ea--hero .lx-ea__rail:focus-within {
  box-shadow:
    0 0 0 3px color-mix(in srgb, var(--ea-ink) 10%, transparent),
    0 14px 30px -14px #2b241f26;
}

@media screen and (max-width: 520px) {
  /* .hero-cta carries no side padding of its own — the two buttons that used
     to live here inset themselves with width: min(20rem, 78vw), so nothing
     ever needed it. A full-width rail does. The gutter goes on the container
     rather than each child, so the lede above is held off the screen edge by
     the same rule. */
  .hero-cta {
    padding-inline: 18px;
  }
}

/* --- Panels --------------------------------------------------------------
   All four states ship in the markup and are toggled with [hidden], never
   rebuilt in JS. That is what lets the existing data-i18n pass in js/site.js
   translate every state on load, including the ones nobody has reached yet —
   a panel built at submit time would come back in English on a Dutch page. */

.lx-ea__panel {
  display: flex;
  flex-direction: column;
  gap: .75rem;
  margin: 0;
}

.lx-ea__panel[hidden] { display: none; }

.lx-ea__label {
  font-family: Inter, sans-serif;
  font-size: .8125rem;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--ea-soft);
}

/* --- The rail: field + submit as one pill -------------------------------- */

.lx-ea__rail {
  display: flex;
  align-items: center;
  gap: .5rem;
  width: 100%;
  padding: .3rem .3rem .3rem 1.1rem;
  background: var(--ea-field);
  border: 1px solid var(--ea-line);
  border-radius: 999px;
  transition: border-color .2s ease, box-shadow .2s ease;
}

.lx-ea__rail:focus-within {
  border-color: var(--ea-ink);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--ea-ink) 12%, transparent);
}

.lx-ea.is-invalid .lx-ea__rail { border-color: var(--ea-danger); }

.lx-ea__input {
  flex: 1 1 auto;
  min-width: 0;
  height: 44px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--ea-ink);
  font-family: Inter, sans-serif;
  /* 16px exactly: anything smaller makes iOS Safari zoom the page on focus. */
  font-size: 1rem;
  line-height: 1.2;
}

.lx-ea__input::placeholder { color: var(--ea-soft); opacity: 1; }
.lx-ea__input:focus { outline: none; }
.lx-ea__input:-webkit-autofill { -webkit-text-fill-color: var(--ea-ink); transition: background-color 9999s; }

/* The envelope leads the field, where it marks what the field takes. It is
   decorative — the input is named by its own visually-hidden label — so it
   stays out of the accessibility tree and never carries meaning alone. */
.lx-ea__mail {
  flex: 0 0 auto;
  width: 20px;
  height: 20px;
  margin-right: .6rem;
  color: var(--ea-soft);
  opacity: .8;
  pointer-events: none;
}

.lx-ea__go {
  flex: 0 0 auto;
  min-height: 44px;
  padding: .7rem 1.35rem;
  font-size: .875rem;
  white-space: nowrap;
  gap: .5rem;
}

.lx-ea__go-arrow {
  width: 17px;
  height: 17px;
  flex: 0 0 auto;
  transition: transform .22s cubic-bezier(.2, .7, .3, 1);
}

.lx-ea__go:hover .lx-ea__go-arrow { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .lx-ea__go-arrow { transition: none; }
  .lx-ea__go:hover .lx-ea__go-arrow { transform: none; }
}

/* On the clay panel the site's default pill (near-black on brown) reads as the
   quieter of the two options, which inverts the hierarchy exactly where the
   primary action lives. Both treatments flip for the dark placement: solid
   becomes silk, and the ghost takes a light border instead of the near-black
   one it inherits, which is all but invisible against this ground. */
.lx-ea--dark .lx-btn {
  background: var(--silk);
  color: #2b241f;
  border-color: var(--silk);
}

.lx-ea--dark .lx-btn:hover { background: #fff; border-color: #fff; }

.lx-ea--dark .lx-btn--ghost {
  background: transparent;
  color: var(--silk);
  border-color: #f3e9df5c;
}

.lx-ea--dark .lx-btn--ghost:hover {
  background: #f3e9df14;
  border-color: #f3e9df8f;
  color: var(--silk);
}

.lx-ea--dark .lx-ea__back { color: #e6dbd0c4; }
.lx-ea--dark .lx-ea__back:hover { color: var(--silk); }

/* The closing panel has room the hero does not, and the note is the last thing
   read before the phone below it — so it gets air on both sides and a looser
   line rather than sitting tight under the field. */
.lx-ea--dark .lx-ea__note {
  margin-block: .55rem .35rem;
  max-width: 31rem;
  line-height: 1.8;
}

.lx-ea--dark .lx-btn:focus-visible,
.lx-ea--dark .lx-ea__back:focus-visible {
  outline: 2px solid var(--silk);
  outline-offset: 3px;
}

.lx-ea__go[aria-busy="true"] { opacity: .72; cursor: progress; }

/* Used to stack into a tall rounded rectangle here (field on its own row,
   a full-width button below it) - correct in isolation, but next to the
   rest of the page it read as a generic sign-up widget dropped onto an
   editorial layout: a blocky card where everything around it is a slim
   line, a rule, a pill button, a serif headline. The wide rail - one
   slender pill holding icon, field and submit together - is the actual
   design; this kept the field but threw that away the moment the screen
   narrowed. Shrinking the submit button to an icon-only circle matching
   the rail's own height, with its text label clipped rather than removed
   (see [data-ea-submit-label] below), lets the whole thing stay one line
   down to a 320px phone, so the "field + submit as one pill" idea above
   holds at every width instead of only above 520px. */

@media screen and (max-width: 520px) {
  .lx-ea__rail {
    padding: .3rem .3rem .3rem 1rem;
  }

  .lx-ea__input {
    height: 40px;
  }

  /* Square, not the wide rail's pill-with-label: at this width the label
     and the field were fighting for the same ~300px, and the label always
     lost first (four-word copy wrapping inside a pill reads as broken, not
     compact). The arrow alone says "submit" next to a field with nothing
     else it could mean, the way a search box's magnifying glass does. */
  .lx-ea__go {
    width: 40px;
    height: 40px;
    min-height: 40px;
    padding: 0;
    flex: 0 0 auto;
  }

  /* Not display:none - that would drop the button's accessible name along
     with the pixels. Clipped to 1px instead, the same technique .lx-sr-only
     uses in style.css (duplicated rather than referenced: this file ships
     standalone, see the header comment), so a screen reader still announces
     "Get early access" even though nothing here is drawn. */
  [data-ea-submit-label] {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    white-space: nowrap;
    clip-path: inset(50%);
  }
}

/* --- Supporting text ----------------------------------------------------- */

.lx-ea__note {
  margin: 0;
  font-family: Inter, sans-serif;
  font-size: .8125rem;
  line-height: 1.55;
  color: var(--ea-soft);
}

.lx-ea__err {
  margin: 0;
  display: flex;
  align-items: flex-start;
  gap: .4rem;
  font-family: Inter, sans-serif;
  font-size: .8125rem;
  line-height: 1.5;
  /* Never colour alone: the message keeps its own icon so the failure reads
     without relying on the red. */
  color: var(--ea-danger);
}

.lx-ea__err[hidden] { display: none; }

.lx-ea__err::before {
  content: "";
  flex: 0 0 auto;
  width: 15px;
  height: 15px;
  margin-top: .13rem;
  background: currentColor;
  -webkit-mask: var(--ea-warn-icon) center / contain no-repeat;
  mask: var(--ea-warn-icon) center / contain no-repeat;
}

.lx-ea {
  --ea-warn-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.5v5.5'/%3E%3Cpath d='M12 16.4v.1'/%3E%3C/svg%3E");
}

/* --- Reassurance row -----------------------------------------------------
   Three answers to the three things someone weighs in the second before they
   type an address: is it worth it, what will it cost me, who else is doing
   this. Hero only, and inside the idle panel, so it leaves with the form.

   The lilac picks up the wordmark rather than the clay used elsewhere on the
   page — clay badges here would read as a fourth feature row, where the point
   is that this is a quiet aside to the field above it. Kept to the badges, so
   the accent never touches type that has to stay legible. */
.lx-ea__trust {
  --trust-badge: #ebe5f8;
  --trust-badge-ink: #2c2344;

  list-style: none;
  /* Sits close under the note it reinforces — the two are one reassurance
     block, not two stacked ones. */
  margin: .8rem 0 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  width: 100%;
}

.lx-ea__trust-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .1rem;
  padding-inline: .75rem;
  text-align: center;
}

/* Hairline rules between the three, not around them — the row is one object
   divided, not three cards in a line. */
.lx-ea__trust-item + .lx-ea__trust-item {
  border-left: 1px solid var(--ea-line);
}

.lx-ea__trust-badge {
  display: grid;
  place-items: center;
  width: 38px;
  height: 38px;
  margin-bottom: .55rem;
  border-radius: 50%;
  background: var(--trust-badge);
  color: var(--trust-badge-ink);
}

.lx-ea__trust-badge svg { width: 19px; height: 19px; }

.lx-ea__trust-lead {
  font-family: Inter, sans-serif;
  font-size: .875rem;
  font-weight: 600;
  line-height: 1.35;
  color: var(--ea-ink);
  text-wrap: balance;
}

.lx-ea__trust-sub {
  font-family: Inter, sans-serif;
  font-size: .875rem;
  font-weight: 400;
  line-height: 1.35;
  color: var(--ea-soft);
  text-wrap: balance;
}

@media screen and (max-width: 520px) {
  /* Every row of the hero block competes for the same scarce height on a
     phone: the block runs ~370px against a hero stage that hands over to the
     brand marquee shortly after it, and it was overrunning the marquee's
     kicker by ~28px on 320-375px screens. The spacing tightens here, and the
     marquee's own top buffer takes the rest — see style.css. */
  .lx-ea__panel { gap: .45rem; }
  .lx-ea__trust { margin-top: .4rem; }
  .lx-ea__trust-item { padding-inline: .4rem; }
  .lx-ea__trust-badge { width: 31px; height: 31px; margin-bottom: .35rem; }
  .lx-ea__trust-badge svg { width: 16px; height: 16px; }
  .lx-ea__trust-lead,
  .lx-ea__trust-sub { font-size: .8125rem; }
}

@media screen and (max-width: 479px) {
  .hero-cta { gap: .9rem; }
}

/* Honeypot. Off-screen rather than display:none — a bot reading the computed
   style skips hidden fields, and this one exists precisely to be filled in. */
.lx-ea__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --- The card: every step after the email field -------------------------
   The three mid-flow panels (the beta ask, the three questions, the
   confirmation) leave the component's own layout entirely and present as one
   card over the page. The hero placement sits inside a 100vh scroll-pinned
   stage (see .hero-heading-wrapper in style.css): content that grows there
   has no page to push taller, so it either overflowed the pinned viewport or
   was cut off by the section after it. An overlay sidesteps that instead of
   fighting the pin, and it fits on any viewport, at any scroll position, on
   either placement.

   THE CARD IS SET LIKE STATIONERY, NOT LIKE A DIALOG. A letterhead line, a
   stitched rule under it, then a Playfair headline and left-aligned content —
   the register of a note from an atelier rather than a system prompt, which
   is the right voice for asking someone to help build the thing. The stitch
   is the one flourish and it earns its place: it is a garment seam on a
   fashion product, it appears nowhere else on the site, and it costs one
   background-image on a heading that was already there.

   Left-aligned on purpose. Centred, the three chip rows (3, 4 and 2 answers)
   set to different ragged centres and read as an accident; ranged left they
   read as a form someone laid out.

   early-access.js moves these panels to be direct children of <body> on init
   (see the comment there), so nothing here can lean on a .lx-ea--center or
   .lx-ea--dark ancestor for centring, theming, or the masked icons — all of
   it is asserted directly on .lx-ea__panel--modal and .lx-ea__modal-card. */
.lx-ea__panel--modal {
  position: fixed;
  inset: 0;
  z-index: 300;
  align-items: center;
  justify-content: center;
  padding: clamp(1rem, 4vw, 2rem);
  /* Warm, not neutral: a grey scrim over this page's cream and clay reads as
     dirt on the glass. #1c1612 is the clay panel's own shadow tone. */
  background: #1c1612a3;
  -webkit-backdrop-filter: blur(6px) saturate(.92);
  backdrop-filter: blur(6px) saturate(.92);
}

.lx-ea__panel--modal[hidden] { display: none; }

/* Programmatic focus lands on this wrapper (see early-access.js's show()) so
   a screen reader announces the card; it is not itself an interactive
   element, so it takes no visible ring of its own. */
.lx-ea__panel--modal:focus { outline: none; }

.lx-ea__modal-card {
  --ea-ink: var(--looxx-black);
  --ea-soft: var(--stone);
  --ea-line: var(--mist);
  --ea-field: #faf8f5;
  --ea-accent: #8f5f37;
  --ea-danger: #9b2f38;
  /* Restated here, not inherited: .lx-ea is no longer an ancestor, and a
     masked pseudo-element whose mask resolves to nothing paints as a solid
     block of its own background colour — which is what the tick beside
     "You're in." had become. */
  --ea-warn-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='12' cy='12' r='9'/%3E%3Cpath d='M12 7.5v5.5'/%3E%3Cpath d='M12 16.4v.1'/%3E%3C/svg%3E");

  width: 100%;
  max-width: 30rem;
  max-height: min(86vh, 45rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  display: flex;
  flex-direction: column;
  /* Spacing is set per element below rather than by one flex gap: an
     editorial rhythm needs a different interval after the headline than
     between two question groups. */
  gap: 0;
  padding: clamp(1.5rem, 1rem + 2.4vw, 2.375rem);
  text-align: left;
  background: #fff;
  border-radius: 18px;
  box-shadow:
    0 2px 6px -2px #2b241f29,
    0 24px 48px -20px #2b241f5c,
    0 64px 80px -64px #2b241f8c;
}

/* --- Letterhead ---------------------------------------------------------- */

.lx-ea__eyebrow {
  display: flex;
  align-items: center;
  gap: .5rem;
  margin: 0 0 1.4rem;
  padding-bottom: .95rem;
  font-family: Inter, sans-serif;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .2em;
  text-transform: uppercase;
  color: var(--ea-soft);
  /* The stitch. A dashed border renders dashes too short to read as
     stitching, so the rule is drawn as a gradient with a 6px stitch and a
     5px gap, which at this scale reads as thread. */
  background-image: repeating-linear-gradient(to right, var(--taupe) 0 6px, transparent 6px 11px);
  background-size: 100% 1px;
  background-repeat: no-repeat;
  background-position: left bottom;
}

.lx-ea__eyebrow::before {
  content: "";
  flex: 0 0 auto;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ea-accent);
}

/* --- Card type ----------------------------------------------------------
   The headline is the one piece of Playfair in the card and it is set at
   display size, tight, so the card has a clear first voice before the Inter
   body starts talking. */

.lx-ea__modal-card .lx-ea__confirm {
  display: block;
  margin: 0 0 .85rem;
  font-size: clamp(1.75rem, 1.3rem + 1.9vw, 2.125rem);
  line-height: 1.04;
  letter-spacing: -.018em;
  color: var(--ea-ink);
}

/* The tick that used to lead the headline is gone. "You're in." is already
   unambiguous, and a mark beside it only competed with the letterhead dot
   two lines above for the same job. */
.lx-ea__modal-card .lx-ea__confirm::before { content: none; }

.lx-ea__modal-card .lx-ea__ask,
.lx-ea__modal-card .lx-ea__done-body {
  margin: 0;
  /* ~46 characters a line at this size — short enough to read in one pass,
     which is all this copy gets before someone decides. */
  max-width: 34ch;
  font-size: .9375rem;
  line-height: 1.72;
  color: var(--ea-soft);
  text-wrap: pretty;
}

.lx-ea__modal-card .lx-ea__ask strong,
.lx-ea__modal-card .lx-ea__done-body strong {
  color: var(--ea-ink);
  font-weight: 600;
}

/* --- Card controls -------------------------------------------------------
   The dark placement's button treatments are for the clay panel behind them
   and are wrong on a white card, so the light set is reasserted here. The
   pair stays a real pair: both full size, both plainly worded, weighted only
   by fill — someone nudged into testing is someone who never opens the
   build. */

.lx-ea__modal-card .lx-ea__choices,
.lx-ea__modal-card .lx-ea__actions {
  gap: .55rem .6rem;
  margin-top: 1.75rem;
}

.lx-ea__modal-card .lx-btn {
  min-height: 46px;
  padding: .8rem 1.45rem;
  font-size: .9rem;
  background: var(--looxx-black);
  color: var(--silk);
  border-color: var(--looxx-black);
}

.lx-ea__modal-card .lx-btn:hover { background: #2c2c2c; border-color: #2c2c2c; }

.lx-ea__modal-card .lx-btn--ghost {
  background: #0000;
  color: #3f3a35;
  border-color: var(--ea-line);
  font-weight: 500;
}

.lx-ea__modal-card .lx-btn--ghost:hover {
  background: #17171708;
  border-color: var(--taupe);
  color: var(--looxx-black);
}

.lx-ea__modal-card .lx-ea__back { color: var(--ea-soft); }
.lx-ea__modal-card .lx-ea__back:hover { color: var(--ea-ink); }

.lx-ea__modal-card .lx-btn:focus-visible,
.lx-ea__modal-card .lx-ea__back:focus-visible,
.lx-ea__modal-card .lx-ea__chip input:focus-visible + span {
  outline: 2px solid var(--looxx-black);
  outline-offset: 3px;
}

/* --- Card questions ------------------------------------------------------ */

.lx-ea__modal-card .lx-ea__q { gap: .6rem; }
.lx-ea__modal-card .lx-ea__q:first-of-type { margin-top: 1.8rem; }
.lx-ea__modal-card .lx-ea__q + .lx-ea__q { margin-top: 1.5rem; }

.lx-ea__modal-card .lx-ea__q legend {
  font-size: .875rem;
  line-height: 1.45;
  color: var(--ea-ink);
}

/* Silk rather than white: a white chip on a white card is a label with a
   stray outline, where a filled one reads as something to press. */
.lx-ea__modal-card .lx-ea__chip span {
  min-height: 42px;
  padding: .5rem 1rem;
  background: var(--ea-field);
  border-color: #e7e1da;
  font-size: .875rem;
}

.lx-ea__modal-card .lx-ea__chip input:hover + span {
  background: #fff;
  border-color: var(--taupe);
}

.lx-ea__modal-card .lx-ea__chip input:checked + span {
  background: var(--ea-ink);
  border-color: var(--ea-ink);
  color: var(--silk);
}

.lx-ea__modal-card .lx-ea__aside {
  margin-top: .45rem;
  border-left-width: 2px;
  font-size: .8125rem;
}

.lx-ea__modal-card .lx-ea__err { margin-top: 1.1rem; }

/* A modal open on either placement stops the page scrolling behind it —
   see early-access.js's syncModalScrollLock(). */
body.lx-ea-modal-open { overflow: hidden; }

/* --- Rung two: the beta ask ---------------------------------------------- */

.lx-ea__confirm {
  display: flex;
  align-items: baseline;
  gap: .5rem;
  margin: 0;
  font-family: "Playfair Display", Georgia, serif;
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--ea-ink);
}

.lx-ea__confirm::before {
  content: "";
  flex: 0 0 auto;
  width: 17px;
  height: 17px;
  align-self: center;
  background: var(--ea-accent);
  -webkit-mask: var(--ea-tick-icon) center / contain no-repeat;
  mask: var(--ea-tick-icon) center / contain no-repeat;
}

.lx-ea {
  --ea-tick-icon: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m4 12.5 5.5 5.5L20 6'/%3E%3C/svg%3E");
}

.lx-ea__ask {
  margin: 0;
  font-family: Inter, sans-serif;
  font-size: .9375rem;
  line-height: 1.65;
  color: var(--ea-soft);
}

.lx-ea__ask strong { color: var(--ea-ink); font-weight: 600; }

/* The two answers sit on one row with the doodle pointing at the left one.
   Equal visual weight would be dishonest in the other direction — a beta
   tester who was nudged into it is a beta tester who never opens the build —
   so the decline is a real, full-size, clearly-labelled choice, and only the
   arrow says which one we hope for. */
.lx-ea__choices {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
}

.lx-ea__choices .lx-btn { min-height: 44px; }

/* --- Rung two: the three questions --------------------------------------- */

.lx-ea__q {
  display: flex;
  flex-direction: column;
  gap: .55rem;
  margin: 0;
  padding: 0;
  border: 0;
}

.lx-ea__q + .lx-ea__q { margin-top: 1.35rem; }

.lx-ea__q legend {
  padding: 0;
  font-family: Inter, sans-serif;
  font-size: .9375rem;
  font-weight: 600;
  line-height: 1.5;
  color: var(--ea-ink);
}

.lx-ea__chips {
  display: flex;
  flex-wrap: wrap;
  gap: .45rem;
}

/* The radio itself stays in the accessibility tree and keeps arrow-key
   behaviour; only its painted box is replaced by the chip. */
.lx-ea__chip { position: relative; }

.lx-ea__chip input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.lx-ea__chip span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: .5rem 1.05rem;
  border: 1px solid var(--ea-line);
  border-radius: 999px;
  background: var(--ea-field);
  font-family: Inter, sans-serif;
  font-size: .875rem;
  font-weight: 500;
  color: var(--ea-ink);
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}

.lx-ea__chip input:hover + span { border-color: var(--ea-ink); }

.lx-ea__chip input:checked + span {
  background: var(--ea-ink);
  border-color: var(--ea-ink);
  color: var(--silk);
}

.lx-ea--dark .lx-ea__chip input:checked + span { color: #2b241f; }

.lx-ea__chip input:focus-visible + span {
  outline: 2px solid var(--ea-ink);
  outline-offset: 2px;
}

/* Shown only when the answer to the device question is Android — TestFlight
   is iOS-only, and saying so at the moment it becomes relevant is better
   than discovering it in the invitation email that never arrives. */
.lx-ea__aside {
  display: flex;
  gap: .45rem;
  margin: .3rem 0 0;
  padding: .7rem .85rem;
  border-left: 2px solid var(--ea-accent);
  background: color-mix(in srgb, var(--ea-accent) 9%, transparent);
  font-family: Inter, sans-serif;
  font-size: .8125rem;
  line-height: 1.55;
  color: var(--ea-soft);
  /* Prose against a left-hand rule reads left-aligned even inside the centred
     placements — centring it leaves the rule marking nothing. */
  text-align: left;
}

.lx-ea__aside[hidden] { display: none; }

.lx-ea__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .6rem;
  margin-top: 1.6rem;
}

.lx-ea__back {
  padding: .5rem .25rem;
  min-height: 44px;
  border: 0;
  background: none;
  font-family: Inter, sans-serif;
  font-size: .875rem;
  color: var(--ea-soft);
  text-decoration: underline;
  text-underline-offset: 3px;
  cursor: pointer;
}

.lx-ea__back:hover { color: var(--ea-ink); }

/* --- Done ---------------------------------------------------------------- */

.lx-ea__done-body {
  margin: 0;
  font-family: Inter, sans-serif;
  font-size: .9375rem;
  line-height: 1.7;
  color: var(--ea-soft);
}

.lx-ea__done-body strong { color: var(--ea-ink); font-weight: 600; }

/* --- Motion -------------------------------------------------------------- */

.lx-ea__panel:not([hidden]).is-entering {
  animation: lx-ea-in .42s cubic-bezier(.16, .84, .44, 1) both;
}

@keyframes lx-ea-in {
  from { opacity: 0; transform: translate3d(0, 10px, 0); }
  to   { opacity: 1; transform: none; }
}

/* The card and the glass behind it are two different arrivals: the scrim
   simply fades, while the card rises and settles. Moving them as one object
   is what makes an overlay feel like a screenshot sliding in rather than
   something opening. Declared after the rule above so the tie on specificity
   falls this way. */
.lx-ea__panel--modal:not([hidden]).is-entering {
  animation: lx-ea-scrim-in .26s ease both;
}

.lx-ea__panel--modal:not([hidden]).is-entering .lx-ea__modal-card {
  animation: lx-ea-card-in .46s cubic-bezier(.16, .84, .44, 1) both;
}

@keyframes lx-ea-scrim-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

@keyframes lx-ea-card-in {
  from { opacity: 0; transform: translate3d(0, 16px, 0) scale(.985); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  .lx-ea__panel:not([hidden]).is-entering,
  .lx-ea__panel--modal:not([hidden]).is-entering,
  .lx-ea__panel--modal:not([hidden]).is-entering .lx-ea__modal-card { animation: none; }
  .lx-ea__rail, .lx-ea__chip span { transition: none; }
}

/* ==========================================================================
   Placement adjustments
   ========================================================================== */

/* --- Hero ---------------------------------------------------------------- */

/* The hero used to carry two buttons and both store badges. It now carries
   one ask. The demo is still one tap away as a text link under the field, and
   the badges moved to the closing panel where "coming to the App Store" can
   be stated honestly instead of implied by an unlinked logo above the fold. */
.hero-cta .lx-ea { margin-top: -.25rem; }

.hero-cta__secondary {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: baseline;
  gap: .35rem;
  margin: 0;
  font-family: Inter, sans-serif;
  font-size: .875rem;
  color: var(--stone);
}

.hero-cta__secondary a {
  display: inline-flex;
  align-items: center;
  gap: .25rem;
  color: var(--looxx-black);
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: #17171740;
}

.hero-cta__secondary a:hover { text-decoration-color: currentColor; }

.hero-cta__secondary a:focus-visible {
  outline: 2px solid var(--looxx-black);
  outline-offset: 3px;
  border-radius: 3px;
}

/* Marks the demo as somewhere you go, against the card above it, which is
   something you fill in. The arrow is not underlined with the words. */
.hero-cta__jump {
  width: 13px;
  height: 13px;
  flex: 0 0 auto;
  color: var(--stone);
}

/* Only one of the two labels is ever shown — see the comment in index.html. */
.hero-cta__demo-solo { display: none; }

/* ==========================================================================
   Signed up, card closed
   The field has done its job and is gone. What is left has to stand on its
   own: a line confirming the thing that just happened, and the demo — which
   was a footnote under the form and is now the only thing to do here, so it
   stops being a text link and becomes the button the hero no longer has.
   ========================================================================== */

[data-ea-host].is-ea-complete .lx-ea { display: none; }

.lx-ea-done-note {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  margin: 0;
  font-family: Inter, sans-serif;
  font-size: .875rem;
  font-weight: 500;
  color: var(--stone);
}

.lx-ea-done-note[hidden] { display: none; }
.lx-ea-done-note:focus { outline: none; }

.lx-ea-done-note__tick {
  width: 15px;
  height: 15px;
  flex: 0 0 auto;
  color: #8f5f37;
}

/* On the clay panel the same line has to carry its own contrast. */
.lx-ea-done-note--dark { color: #e6dbd0; }
.lx-ea-done-note--dark .lx-ea-done-note__tick { color: #f0cba6; }

/* .hero-cta already puts 1.75rem between its children; this is the extra
   step down from the confirmation to the action under it. */
[data-ea-host].is-ea-complete .hero-cta__secondary {
  margin-top: .4rem;
}

/* "Leave your email and you're in the first group through the door" is an
   instruction for a field that is no longer on the page. The title and the
   confirmation line under it say everything still true. */
[data-ea-host].is-ea-complete .white-paragraph { display: none; }

/* "Or try the demo first" only parses while it trails the field. Alone, the
   conjunction has nothing to join and the lowercase label is not a button. */
[data-ea-host].is-ea-complete .hero-cta__or,
[data-ea-host].is-ea-complete .hero-cta__demo-inline { display: none; }

[data-ea-host].is-ea-complete .hero-cta__demo-solo { display: inline; }

[data-ea-host].is-ea-complete .hero-cta__secondary a {
  gap: .5rem;
  min-height: 46px;
  padding: .8rem 1.6rem;
  border: 1px solid var(--looxx-black);
  border-radius: 999px;
  background: var(--looxx-black);
  color: var(--silk);
  font-size: .9rem;
  text-decoration: none;
  transition: transform .25s ease, background-color .25s ease;
}

[data-ea-host].is-ea-complete .hero-cta__secondary a:hover {
  background: #2c2c2c;
  transform: translateY(-1px);
}

[data-ea-host].is-ea-complete .hero-cta__jump { color: currentColor; }

/* --- Beta invitation under the live demo --------------------------------- */

/* Placed here because this is the one point on the page where the visitor has
   just used the product rather than read about it — the only honest moment to
   ask someone to help build it. */
.lx-beta-invite {
  max-width: 46rem;
  margin: 0 auto;
  padding: 2.75rem 0 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.1rem;
  text-align: center;
}

.lx-beta-invite__kicker {
  font-family: Inter, sans-serif;
  font-size: .75rem;
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--stone);
  margin: 0;
}

.lx-beta-invite__title {
  margin: 0;
  font-family: "Playfair Display", Georgia, serif;
  font-size: clamp(1.75rem, 4vw, 2.5rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -.01em;
  color: var(--looxx-black);
  text-wrap: balance;
}

.lx-beta-invite__title em { font-style: italic; color: #8f5f37; }

.lx-beta-invite__body {
  margin: 0;
  max-width: 34rem;
  font-family: Inter, sans-serif;
  font-size: 1rem;
  font-weight: 300;
  line-height: 1.7;
  color: var(--stone);
  text-wrap: pretty;
}

/* --- Closing CTA panel --------------------------------------------------- */

.cta-content .lx-ea { margin-top: 1.75rem; }

/* --- Store badges (footer) -----------------------------------------------
   The official Apple / Google artwork, at full strength. An earlier pass had
   these at 62% opacity, which made them read as disabled download buttons
   rather than as a statement about what is coming — the "Coming soon" caption
   above carries that meaning instead, so the marks can sit at full contrast
   and simply look like themselves.

   No hover or focus state: they are not links yet, and nothing should suggest
   a tap that goes nowhere. */
.lx-platforms {
  margin-top: 1.6rem;
}

.lx-platforms__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  margin-top: .65rem;
}

/* 38px puts each badge at ~128px wide. Two of those plus the gap need ~264px,
   so in the 216px footer column the row wraps and they stack; on mobile, where
   the column runs full width, they stay side by side. The width/height
   attributes in the markup reserve the space so neither reflows on load. */
.lx-platforms__badges img {
  display: block;
  height: 38px;
  width: auto;
}
