/* ---------------------------------------------------------------------------
 * What Alex draws, rather than Webflow.
 *
 * Loaded after alexlegal.webflow.css, so it wins where the two meet — which is
 * only the header, whose `.head` keeps Webflow's sticky and its blur and gets
 * everything else from here.
 *
 * It lives under /alex and not /site because `npm run site:import` empties
 * /site on every Webflow re-export, and this is not Webflow's.
 *
 * Every measurement below was read off the Sketch frames rather than guessed:
 * the 1200px column, the 33px buttons at 8px radius, #685bff on a button and
 * #171719 behind the announcement, the 1px #00000012 and 0 14px 48px #00000015
 * on the card, and the dashed purple outline on "Importer une société".
 * ------------------------------------------------------------------------- */

:root {
  --alex-ink: #2b2c30;
  --alex-ink-2: #5a5b60;
  --alex-purple: #685bff;
  --alex-green: #71f481;
  --alex-dark: #171719;
  /* Pennylane's own, sampled out of the logo rather than guessed: the wordmark
     is #006767 and the mark carries #00fd79. */
  --alex-penny: #006767;
  --alex-penny-bright: #00fd79;
  --alex-hairline: #2b2c3014;
  --alex-hairline-2: #00000012;
  --alex-width: 1200px;
  --alex-gutter: 24px;
  --alex-radius: 8px;
}

/* --- The column everything sits in ---------------------------------------- */

.alex-wrap {
  width: 100%;
  max-width: calc(var(--alex-width) + var(--alex-gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--alex-gutter);
}

/* --- Buttons --------------------------------------------------------------- */

.alex-btn {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 33px;
  padding: 8px 18px;
  border: 1px solid #0000000f;
  border-radius: var(--alex-radius);
  font-size: 14px;
  font-weight: 400;
  line-height: 17px;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease, background-color 0.12s ease;
}

.alex-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 12px #00000014;
}

.alex-btn:active {
  transform: none;
  box-shadow: none;
}

.alex-btn--dark {
  background-color: var(--alex-ink);
  color: #fff;
}

.alex-btn--primary {
  background-color: var(--alex-purple);
  color: #fff;
}

.alex-btn--green {
  background-color: var(--alex-green);
  color: #0d2c13;
}

/* The import action is drawn as an outline, and the outline is dashed — it is
   the one control on the page that adopts something rather than creating it. */
.alex-btn--ghost {
  background-color: #fff;
  border: 1px dashed var(--alex-purple);
  color: var(--alex-purple);
}

.alex-link-arrow {
  color: var(--alex-purple);
  font-size: 14px;
  font-weight: 400;
  line-height: 17px;
  text-decoration: none;
}

.alex-link-arrow:hover {
  text-decoration: underline;
}

/* --- The header ------------------------------------------------------------ */

.alex-nav.head {
  height: auto;
  padding-inline: 0;
  background-color: #fafafacc;
}

.alex-nav__inner {
  display: flex;
  align-items: center;
  gap: 34px;
  width: 100%;
  max-width: calc(var(--alex-width) + var(--alex-gutter) * 2);
  height: 64px;
  margin-inline: auto;
  padding-inline: var(--alex-gutter);
  border-bottom: 1px solid #00000010;
}

.alex-nav__brand {
  display: flex;
  align-items: center;
  flex: none;
  width: 48px;
  color: var(--alex-ink);
}

.alex-nav__brand svg {
  display: block;
  width: 48px;
  height: 18px;
}

.alex-nav__links,
.alex-nav__actions {
  display: flex;
  align-items: center;
  /* Narrower than the 34px it reads as: each link now carries 10px of its own
     on either side, and the two together make the gap that was there before. */
  gap: 14px;
}

/* The padding is the link's, not the row's, so the row is pulled back by it —
   "Guides" sits where it always did against the logo. */
.alex-nav__links {
  margin-inline: -10px;
}

/* The header's own margins do the spacing; this pushes the actions right. */
.alex-nav__actions {
  margin-left: auto;
}

/*
 * A link is a target, and a target has edges.
 *
 * It used to turn purple under the cursor, which is a colour this site spends
 * on actions — a button, a link into a flow. A header link is navigation, so
 * it lights up the way a menu item does instead: the ink stays put and a soft
 * grey panel appears behind it, at the same radius and the same padding as the
 * items in the logo menu and the guides dropdown.
 */
.alex-nav__link {
  padding: 7px 10px;
  border-radius: 7px;
  color: var(--alex-ink);
  font-size: 14px;
  font-weight: 400;
  line-height: 17px;
  text-decoration: none;
  white-space: nowrap;
  transition: background-color 0.12s ease;
}

.alex-nav__link:hover {
  background-color: #2b2c300f;
  color: var(--alex-ink);
}

.alex-nav__demo {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}

.alex-nav__icon {
  flex: none;
}

/* Webflow's dropdown, restyled. The toggle is Webflow's element, so the label
   inside it is what gets the type — the wrapper is positioning only. */
.alex-nav__menu .w-dropdown,
.alex-nav__menu .dropdown-none {
  margin: 0;
}

/* "Guides" is a Webflow toggle rather than one of our links, so it is given
   the same padding, radius and panel by hand. */
.alex-nav__menu .header-link.w-dropdown-toggle {
  padding: 7px 10px;
  border-radius: 7px;
  color: var(--alex-ink);
  font-size: 14px;
  font-weight: 400;
  line-height: 17px;
  transition: background-color 0.12s ease;
}

.alex-nav__menu .header-link.w-dropdown-toggle:hover,
.alex-nav__menu .header-link.w-dropdown-toggle.w--open {
  background-color: #2b2c300f;
  color: var(--alex-ink);
}

.alex-nav__burger {
  display: none;
  align-items: center;
  justify-content: center;
  width: 36px;
  height: 36px;
  margin-left: auto;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--alex-radius);
  color: var(--alex-ink);
  cursor: pointer;
}

/* --- The hero -------------------------------------------------------------- */

/*
 * One block of markup, two arrangements.
 *
 * The four children are the announcement, the headline, the pitch (paragraph
 * and buttons) and the social proof. Variant A puts the announcement across
 * the top as a dark band and sets the headline against the pitch; variant B
 * makes it a card down the right and stacks everything else on the left.
 * Nothing is added or removed between them, which is what lets one set of
 * strings serve both — see lib/ab.ts.
 *
 * The outer columns are the gutters, so the announcement can run edge to edge
 * in variant A by taking all four.
 */
/*
 * The colour behind it.
 *
 * `isolation` is what makes the z-index below mean "behind the hero's content"
 * rather than "behind the page": without it the aurora would sit under the
 * document background and never be seen.
 */
.alex-hero {
  position: relative;
  isolation: isolate;
  display: grid;
  /* The gap between the two content columns is a column of its own rather
     than `column-gap`, which would also push the gutters apart and leave the
     content narrower than the 1200 it is drawn at. */
  grid-template-columns:
    minmax(var(--alex-gutter), 1fr)
    minmax(0, 564px)
    72px
    minmax(0, 564px)
    minmax(var(--alex-gutter), 1fr);
  align-items: start;
  /*
   * The hero owns the first screen.
   *
   * Tall enough that the row of tabs below it is just showing — an invitation
   * to scroll rather than a second thing competing for the first look. 64px is
   * the header, 104px is what the tab row needs to peek, and 96px is this
   * block's own padding — all three come off, or the padding pushes the tabs
   * back under the fold. `svh` and not `vh` because on a phone `vh` is the
   * viewport with the browser chrome hidden, which it is not on first load.
   */
  min-height: calc(100svh - 64px - 104px - 96px);
  padding-bottom: 96px;
}

.alex-hero__title {
  max-width: 430px;
  margin: 0;
  color: #000;
  font-size: 44px;
  font-weight: 600;
  line-height: 50px;
  letter-spacing: -0.02em;
}

.alex-hero__lede {
  max-width: 405px;
  margin: 0;
  /* Centred in variant B, ranged left in A — `auto` on both sides only bites
     when there is room to spare, which is exactly when B wants it. */
  margin-inline: var(--alex-lede-margin, 0);
  color: var(--alex-ink-2);
  font-size: 16px;
  line-height: 24px;
}

.alex-hero__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 26px;
}

/*
 * Variant A is the default, and not just for tidiness: with JavaScript off
 * nothing sets `data-ab-hero` at all, and a grid whose areas were only ever
 * defined under an attribute selector would drop its four children wherever
 * auto-placement felt like. A is what a browser with no script gets, and it is
 * a complete hero.
 */
.alex-hero,
[data-ab-hero="a"] .alex-hero {
  grid-template-areas:
    "promo promo promo promo promo"
    ".     title .     pitch ."
    ".     proof proof proof .";
  /*
   * Rows as tall as their contents, and the slack at the foot.
   *
   * Left to itself `align-content` is stretch, and the height the hero is asked
   * to fill gets handed out between the rows — which is where the canyon
   * between the headline and the paragraph came from. `start` puts all of it
   * below the last row instead, where it reads as the hero having room rather
   * than as the copy having come apart.
   */
  grid-template-rows: auto auto auto;
  align-content: start;
  row-gap: 0;
}

[data-ab-hero="b"] .alex-hero {
  grid-template-areas:
    ". .     . promo ."
    ". title . promo ."
    ". pitch . promo ."
    ". .     . promo ."
    ". proof . promo .";
  /*
   * The headline and its paragraph centred, the logo box at the foot.
   *
   * This used to be `space-between`, which shared the spare height out as
   * equal gaps — on a tall screen, hundreds of pixels between the headline
   * and its own paragraph. The two now stay together, and two empty rows of
   * equal height either side of them put the pair in the middle of the space
   * above the logo box, which stays level with the foot of the card.
   */
  grid-template-rows: 1fr auto auto 1fr auto;
  align-content: stretch;
  row-gap: 0;
  padding-top: 88px;
}

/* The gap between headline and paragraph, now that the rows have none. */
[data-ab-hero="b"] .alex-hero__title {
  margin-bottom: 26px;
}

/*
 * The card fills its column, and the proof box lines up with the foot of it.
 *
 * Two blocks of unequal content either side of a hero look like a mistake
 * unless they agree at top and bottom; these now do.
 */
[data-ab-hero="b"] .alex-promo {
  align-self: stretch;
}

[data-ab-hero="b"] .alex-proof {
  align-self: end;
}

/*
 * The card's own contents: the offer as one block, the button at the foot.
 *
 * `space-between` used to share the card's height out between its four
 * blocks, which left the logo lockup floating far above the headline it
 * introduces, and the headline far above its points. Those three are one
 * statement and now sit as one; the height left over goes above the button.
 */
[data-ab-hero="b"] .alex-promo__inner {
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 18px;
  /* The 1200px column and its gutters belong to the band, not to a card that
     already has forty pixels of padding of its own. */
  max-width: none;
  height: 100%;
  padding-inline: 0;
}

[data-ab-hero="b"] .alex-promo__title,
[data-ab-hero="b"] .alex-promo__points {
  margin-top: 0;
}

[data-ab-hero="b"] .alex-promo__actions {
  margin-top: auto;
}

.alex-promo { grid-area: promo; }
.alex-hero__title { grid-area: title; }
.alex-hero__pitch { grid-area: pitch; }
.alex-proof { grid-area: proof; }

.alex-hero__title,
.alex-hero__pitch,
[data-ab-hero="a"] .alex-hero__title,
[data-ab-hero="a"] .alex-hero__pitch {
  padding-top: 86px;
}

.alex-proof,
[data-ab-hero="a"] .alex-proof {
  margin-top: 22px;
  align-self: end;
  padding-bottom: 8px;
}

[data-ab-hero="b"] .alex-hero__title,
[data-ab-hero="b"] .alex-hero__pitch,
[data-ab-hero="b"] .alex-proof {
  padding-top: 0;
  margin-top: 0;
}

/* --- One hero, while the announcement is off ------------------------------- */

/*
 * `data-promo="off"` is set on <html> by the server (PROMO_LIVE in lib/ab.ts)
 * together with `data-ab-hero="b"`, so everything above that dresses variant B
 * — the centred headline, the customers in their box — applies as it stands.
 * What is left to say here is only what the card's absence changes: the card
 * is hidden, and the column it shared the hero with is the hero's one column.
 *
 * `html[...]` rather than `[...]` for the extra weight: these have to beat the
 * B rules of the same shape wherever they fall in this file.
 */
html[data-promo="off"] .alex-promo {
  display: none;
}

html[data-promo="off"] .alex-hero {
  grid-template-columns:
    minmax(var(--alex-gutter), 1fr)
    minmax(0, 720px)
    minmax(var(--alex-gutter), 1fr);
  grid-template-areas:
    ". title ."
    ". pitch ."
    ". proof .";
  /* Headline, paragraph and customers as one composition, in the middle of
     the first screen. With no card to line the box up with, a box left at the
     foot of a tall screen is a box on its own. */
  grid-template-rows: auto auto auto;
  align-content: center;
}

/* The headline had 430px because it shared the row with a card. Alone, it
   can run to the width the new sentence needs to break in two even lines. */
html[data-promo="off"] .alex-hero__title {
  max-width: 560px;
}

html[data-promo="off"] .alex-proof {
  align-self: start;
  justify-self: center;
  width: 100%;
  /* Four 112px slots and their gaps, plus the box's own padding. */
  max-width: 620px;
  margin-top: 44px;
}

/* On a narrow screen the card used to be the first thing under the header, and
   the headline took its top space from it. With the card gone the headline
   sat flush against the header's rule — so the hero brings its own. */
@media (max-width: 991px) {
  html[data-promo="off"] .alex-hero {
    align-content: start;
    padding-top: 48px;
  }

  html[data-promo="off"] .alex-proof {
    margin-top: 12px;
  }
}

/* --- The colour behind the hero -------------------------------------------- */

/*
 * Gone. The four coloured washes that rose from the bottom of the hero are
 * switched off here rather than deleted from the markup: the markup is written
 * into every stored page by `npm run site:design`, and taking it out is a
 * database write across all of them for four empty, aria-hidden spans that
 * this one rule already makes invisible.
 */
.alex-aurora {
  display: none;
}

/* --- The announcement ------------------------------------------------------ */

.alex-promo__inner {
  width: 100%;
  max-width: calc(var(--alex-width) + var(--alex-gutter) * 2);
  margin-inline: auto;
  padding-inline: var(--alex-gutter);
}

.alex-promo__lockup {
  display: flex;
  align-items: center;
  gap: 14px;
}

.alex-promo__lockup svg {
  display: block;
  height: 17px;
  width: auto;
}

.alex-promo__plus {
  color: currentColor;
  font-size: 18px;
  line-height: 1;
}

.alex-promo__pennylane {
  display: block;
  height: 21px;
  width: auto;
}

.alex-promo__title {
  margin: 0;
  font-weight: 600;
  letter-spacing: -0.01em;
}

/* The arrow is the bullet, drawn rather than typed — a "→" inside the string
   would be a character every translator has to carry through by hand. */
.alex-promo__points li::before {
  content: "→";
  margin-right: 8px;
}

.alex-promo__points {
  display: flex;
  flex-direction: column;
  gap: 0;
  margin: 22px 0 0;
  padding: 0;
  list-style: none;
  color: #5a5b61;
  font-size: 15px;
  line-height: 22px;
}

.alex-promo__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 24px;
}

/* The "learn more" link must not be squeezed into a column of single words
   beside the button, which is what a flex item is happy to do. */
.alex-promo__actions .alex-link-arrow {
  flex: none;
}

/* The footnote sits with the offer it qualifies, not at the foot of the page:
   the conditions on a "frais offerts" have to be readable next to the claim. */
.alex-promo__note {
  margin: 14px 0 0;
  max-width: 62ch;
  font-size: 12px;
  line-height: 18px;
}

/* Variant A — a dark band across the page, centred. */
.alex-promo,
[data-ab-hero="a"] .alex-promo {
  background-color: var(--alex-dark);
  padding-block: 40px 44px;
  color: #fff;
  text-align: center;
}

.alex-promo__lockup,
[data-ab-hero="a"] .alex-promo__lockup {
  justify-content: center;
  color: #fff;
}

.alex-promo__title,
[data-ab-hero="a"] .alex-promo__title {
  margin-top: 22px;
  font-size: 22px;
  line-height: 28px;
}

.alex-promo__actions,
[data-ab-hero="a"] .alex-promo__actions {
  justify-content: center;
  margin-top: 26px;
}

.alex-promo__note,
[data-ab-hero="a"] .alex-promo__note {
  margin-inline: auto;
  color: #ffffff8a;
}

/* Variant B's extra detail. It stays in the markup in A and is not shown, so
   both arrangements hold the same strings in the same order. */
.alex-promo__points,
[data-ab-hero="a"] .alex-promo__points {
  display: none;
}

/* The band is dark, so the two marks in the lockup are drawn white on it.
   Alex's is an inline SVG and follows `currentColor`; Pennylane's is a file,
   and this is cheaper and truer than keeping a second copy of it. */
[data-ab-hero="a"] .alex-promo__pennylane {
  filter: brightness(0) invert(1);
}

/*
 * The halftone behind the announcement card.
 *
 * Two grids on the same 12px pitch. The first is always there and almost not
 * there — a texture you notice only once you look for it. The second has the
 * same dots at nearly twice the radius and is masked to a single soft blob
 * that drifts corner to corner over thirty-eight seconds; where it passes, the
 * dots appear to swell. That is the halftone, done with opacity rather than by
 * drawing four hundred circles at four hundred different sizes.
 *
 * Both are in Pennylane's own colours, sampled out of the logo — #006767 for
 * the field, and the bright #00fd79 only inside the moving blob, where there
 * is enough of it to read as a colour rather than as noise.
 *
 * `overflow: hidden` on the card is what clips the grids to its 16px corners.
 */
[data-ab-hero="b"] .alex-promo {
  position: relative;
  overflow: hidden;
  /* Both grids fade along the same diagonal. */
  --alex-halftone-fade: radial-gradient(
    135% 135% at 100% 0%,
    #000 0%,
    #0000009e 40%,
    transparent 82%
  );
}

[data-ab-hero="b"] .alex-promo::before,
[data-ab-hero="b"] .alex-promo::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
}

/*
 * The field: constant, and graded away from the copy.
 *
 * Strongest at the top-right corner and gone by the bottom-left, so the
 * headline and the three lines under it sit on clean white. An even field
 * across the whole card is legible too, but the grid starts to read as a
 * texture applied *to* the text rather than behind it.
 */
[data-ab-hero="b"] .alex-promo::before {
  background-image: radial-gradient(
    circle,
    color-mix(in srgb, var(--alex-penny) 24%, transparent) 0.8px,
    transparent 1.25px
  );
  background-size: 12px 12px;
  -webkit-mask-image: var(--alex-halftone-fade);
  mask-image: var(--alex-halftone-fade);
}

/* The swell: the same grid, bigger dots, shown only through a drifting blob. */
[data-ab-hero="b"] .alex-promo::after {
  background-image: radial-gradient(
    circle,
    color-mix(in srgb, var(--alex-penny-bright) 45%, var(--alex-penny)) 1.45px,
    transparent 1.95px
  );
  background-size: 12px 12px;
  opacity: 0.32;
  /* The drifting blob, and the same diagonal fade, multiplied together: the
     swell only shows where the field does. */
  -webkit-mask-image: radial-gradient(
      ellipse 50% 58% at 50% 50%,
      #000 0%,
      #0000006b 38%,
      transparent 78%
    ),
    var(--alex-halftone-fade);
  mask-image: radial-gradient(
      ellipse 50% 58% at 50% 50%,
      #000 0%,
      #0000006b 38%,
      transparent 78%
    ),
    var(--alex-halftone-fade);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  -webkit-mask-size: 200% 200%, 100% 100%;
  mask-size: 200% 200%, 100% 100%;
  -webkit-mask-repeat: no-repeat, no-repeat;
  mask-repeat: no-repeat, no-repeat;
  animation: alex-halftone 38s ease-in-out infinite alternate;
}

@keyframes alex-halftone {
  from {
    -webkit-mask-position: -25% 115%, 0 0;
    mask-position: -25% 115%, 0 0;
  }
  to {
    -webkit-mask-position: 115% -25%, 0 0;
    mask-position: 115% -25%, 0 0;
  }
}

/* Still textured, just not moving. */
@media (prefers-reduced-motion: reduce) {
  [data-ab-hero="b"] .alex-promo::after {
    animation: none;
    -webkit-mask-position: 78% 18%, 0 0;
    mask-position: 78% 18%, 0 0;
  }
}

/* The card's contents sit over the pattern, not under it. */
.alex-promo__inner {
  position: relative;
  z-index: 1;
}

/* Variant B — a card down the right, left-aligned. */
[data-ab-hero="b"] .alex-promo {
  box-sizing: border-box;
  padding: 40px;
  background-color: #fff;
  border: 1px solid var(--alex-hairline-2);
  border-radius: 16px;
  box-shadow: 0 14px 48px #00000015;
  color: var(--alex-ink);
}

/*
 * Variant B centres the column of copy and left-aligns the card beside it —
 * the opposite of the band, which centres its own contents and leaves the copy
 * ranged left. Both are in the frames; neither is a default.
 */
[data-ab-hero="b"] .alex-hero__title,
[data-ab-hero="b"] .alex-hero__pitch {
  --alex-lede-margin: auto;
  margin-inline: auto;
  text-align: center;
}

[data-ab-hero="b"] .alex-hero__actions {
  justify-content: center;
}

[data-ab-hero="b"] .alex-promo {
  text-align: left;
}

/* The offer's details, which only the card has room for. */
[data-ab-hero="b"] /* The arrow is the bullet, drawn rather than typed — a "→" inside the string
   would be a character every translator has to carry through by hand. */
.alex-promo__points li::before {
  content: "→";
  margin-right: 8px;
}

.alex-promo__points {
  display: flex;
}

[data-ab-hero="b"] .alex-promo__lockup {
  justify-content: flex-start;
  color: var(--alex-ink);
}

[data-ab-hero="b"] .alex-promo__actions {
  justify-content: flex-start;
}

/* On the card the offer's own button is the green one. */
[data-ab-hero="b"] .alex-promo__cta {
  background-color: var(--alex-green);
  color: #0d2c13;
}

[data-ab-hero="b"] .alex-promo__title {
  margin-top: 30px;
  font-size: 28px;
  line-height: 37px;
}

[data-ab-hero="b"] .alex-promo__note {
  color: var(--alex-ink-2);
}

/* --- Social proof ---------------------------------------------------------- */

.alex-proof__link {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  color: var(--alex-ink-2);
  font-size: 16px;
  line-height: 24px;
  text-decoration: none;
}

.alex-proof__link:hover {
  color: var(--alex-ink);
}

.alex-proof__heart {
  flex: none;
  color: var(--alex-purple);
}

.alex-proof__logos {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 52px;
  margin: 26px 0 0;
  padding: 0;
  list-style: none;
}

/*
 * Four places, three customers taking turns in each.
 *
 * A slot is a fixed box and every logo in it is fitted to that box, which is
 * what stops the row shuffling sideways each time one changes. They are stacked
 * in a grid cell and faded between — never swapped by a script, because
 * swapping `src` means swapping `alt`, and alt text is translated.
 */
/*
 * One box, whatever shape the logo is.
 *
 * These files range from a 423x66 wordmark to a 148x126 near-square mark. A
 * wall that respects each one's pixels has the wide ones shouting and the tall
 * ones reduced to a speck, so every slot is the same box and every logo is
 * fitted inside it — the rule that makes a logo wall look deliberate.
 *
 * The box is wider than tall because most of these are wordmarks; a square
 * mark uses the height and leaves the sides empty, which is the right way
 * round.
 */
.alex-proof__slot {
  display: grid;
  place-items: center start;
  width: 116px;
  height: 30px;
}

/*
 * Fitted to the slot rather than drawn at its own size.
 *
 * These twelve files range from a 423x66 wordmark to a near-square mark, and a
 * wall that respects each one's pixels has some logos shouting and some barely
 * there. Every one is fitted to the same box instead, which is what a logo wall
 * is for — and `object-position` keeps them on the row's left edge as they
 * change, rather than growing out from the middle.
 */
.alex-proof__logo {
  grid-area: 1 / 1;
  /* The height comes from the markup — `logoHeight` in lib/site/hero.ts gives
     each logo the same inked area — and the width follows from it. The slot
     only caps the width, for the one wordmark long enough to need it. */
  width: auto;
  max-width: 100%;
  height: var(--h, 19px);
  object-fit: contain;
  object-position: left center;
  animation: alex-logo 15s infinite;
  /* Each logo waits its turn, and each slot starts a beat after the one before
     it — four logos changing in unison reads as a page reloading. */
  animation-delay: calc(var(--n, 0) * -5s + var(--slot, 0) * -0.7s);
}

.alex-proof__slot:nth-child(1) { --slot: 0; }
.alex-proof__slot:nth-child(2) { --slot: 1; }
.alex-proof__slot:nth-child(3) { --slot: 2; }
.alex-proof__slot:nth-child(4) { --slot: 3; }

.alex-proof__logo:nth-child(1) { --n: 0; }
.alex-proof__logo:nth-child(2) { --n: 1; }
.alex-proof__logo:nth-child(3) { --n: 2; }

@keyframes alex-logo {
  0%, 28% {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
  33% {
    opacity: 0;
    transform: translateY(-7px);
    filter: blur(3px);
  }
  /* Out through the top, in from below. The jump happens at zero opacity. */
  33.01%, 95% {
    opacity: 0;
    transform: translateY(7px);
    filter: blur(3px);
  }
  100% {
    opacity: 1;
    transform: translateY(0);
    filter: blur(0);
  }
}

@media (prefers-reduced-motion: reduce) {
  .alex-proof__logo {
    animation: none;
  }

  .alex-proof__logo:not(:first-child) {
    opacity: 0;
  }
}

[data-ab-hero="b"] .alex-proof {
  box-sizing: border-box;
  padding: 26px 40px 30px;
  border: 1px solid var(--alex-hairline);
  border-radius: 12px;
  text-align: center;
}

/* The card is narrower than the band's full width, so the wall tightens up
   rather than wrapping onto a second row. */
[data-ab-hero="b"] .alex-proof__logos {
  justify-content: center;
  gap: 20px;
}

/* 112px: the longest wordmark at its proportional height needs 113, and a slot
   narrower than its logo shrinks it — which is the one thing proportional
   sizing is there to stop. */
[data-ab-hero="b"] .alex-proof__slot {
  width: 112px;
  place-items: center;
}

[data-ab-hero="b"] .alex-proof__logo {
  object-position: center;
}

/* --- The choice dialog ----------------------------------------------------- */

.alex-modal[hidden] {
  display: none;
}

.alex-modal {
  position: fixed;
  inset: 0;
  z-index: 200;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--alex-gutter);
}

.alex-modal__scrim {
  position: absolute;
  inset: 0;
  background-color: #14141766;
  -webkit-backdrop-filter: blur(2px);
  backdrop-filter: blur(2px);
}

.alex-modal__panel {
  position: relative;
  box-sizing: border-box;
  width: 100%;
  max-width: 858px;
  padding: 56px 40px 64px;
  background-color: #fff;
  border-radius: 16px;
  box-shadow: 0 24px 64px #00000026;
}

.alex-modal__title {
  margin: 0 0 48px;
  color: #000;
  font-size: 26px;
  font-weight: 600;
  line-height: 34px;
  text-align: center;
}

.alex-modal__close {
  position: absolute;
  top: 20px;
  right: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  background: none;
  border: 0;
  border-radius: var(--alex-radius);
  color: var(--alex-ink-2);
  cursor: pointer;
}

.alex-modal__close:hover {
  background-color: #00000008;
  color: var(--alex-ink);
}

.alex-modal__choices {
  display: grid;
  grid-template-columns: 1fr 1px 1fr;
  gap: 40px;
}

.alex-modal__rule {
  background-color: #00000019;
}

.alex-modal__choice {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.alex-modal__icon {
  color: var(--alex-purple);
}

.alex-modal__heading {
  margin: 34px 0 0;
  color: #000;
  font-size: 17px;
  font-weight: 600;
  line-height: 21px;
}

.alex-modal__blurb {
  margin: 14px 0 0;
  max-width: 252px;
  color: #5a5b61;
  font-size: 14px;
  line-height: 22px;
}

.alex-modal__choice .alex-btn {
  width: 100%;
  max-width: 244px;
  min-height: 44px;
  margin-top: 34px;
}

.alex-modal__time {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin: 16px 0 0;
  color: var(--alex-ink-2);
  font-size: 13px;
  line-height: 16px;
}

/* --- A change-log entry ---------------------------------------------------- */

.alex-post {
  padding: 56px 0 120px;
}

.alex-post__date {
  margin: 0;
  color: var(--alex-ink-2);
  font-size: 14px;
  line-height: 20px;
  text-align: center;
}

.alex-post__title {
  max-width: 660px;
  margin: 24px auto 0;
  color: var(--alex-ink);
  font-size: 36px;
  font-weight: 600;
  line-height: 45px;
  letter-spacing: -0.02em;
  text-align: center;
}

.alex-post__figure {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 32px;
  max-width: 650px;
  height: 255px;
  margin: 64px auto 0;
  background-color: #fff;
  border-radius: 12px;
}

.alex-post__figure svg {
  display: block;
  height: 34px;
  width: auto;
  color: var(--alex-ink);
}

.alex-post__figure img {
  display: block;
  height: 38px;
  width: auto;
}

.alex-post__plus {
  color: #000;
  font-size: 26px;
  line-height: 1;
}

.alex-post__body {
  max-width: 520px;
  margin: 52px auto 0;
  color: var(--alex-ink-2);
  font-size: 16px;
  line-height: 27px;
}

.alex-post__body p {
  margin: 0 0 27px;
}

.alex-post__body h2 {
  margin: 48px 0 0;
  color: var(--alex-ink);
  font-size: 16px;
  font-weight: 600;
  line-height: 27px;
}

.alex-post__body h2 + p {
  margin-top: 0;
}

.alex-post__body a {
  color: var(--alex-purple);
}

/* A quotation is set apart by its colour and a rule, not by italics: the
   quote on the Pennylane announcement runs eight lines, and eight lines of
   italic French is a paragraph nobody finishes. */
.alex-post__body blockquote {
  margin: 0 0 20px;
  padding: 0 0 0 20px;
  background-image: none;
  background-color: transparent;
  border: 0;
  border-left: 2px solid var(--alex-purple);
  border-radius: 0;
  color: var(--alex-ink);
  font-size: 16px;
  line-height: 27px;
}

.alex-post__body ul {
  margin: 0 0 27px;
  padding-left: 20px;
}

.alex-post__note {
  font-size: 13px;
  line-height: 22px;
}

.alex-post__back {
  display: inline-block;
  margin-top: 16px;
}

/* --- The change-log index -------------------------------------------------- */

.alex-log {
  padding: 56px 0 120px;
}

.alex-log__title {
  margin: 0;
  color: var(--alex-ink);
  font-size: 36px;
  font-weight: 600;
  line-height: 45px;
  letter-spacing: -0.02em;
  text-align: center;
}

.alex-log__lede {
  max-width: 520px;
  margin: 16px auto 0;
  color: var(--alex-ink-2);
  font-size: 16px;
  line-height: 27px;
  text-align: center;
}

.alex-log__list {
  max-width: 720px;
  margin: 64px auto 0;
  padding: 0;
  list-style: none;
}

.alex-log__item {
  padding: 28px 0;
  border-top: 1px solid var(--alex-hairline);
}

.alex-log__date {
  margin: 0;
  color: var(--alex-ink-2);
  font-size: 13px;
  line-height: 20px;
}

.alex-log__link {
  display: inline-block;
  margin-top: 6px;
  color: var(--alex-ink);
  font-size: 20px;
  font-weight: 600;
  line-height: 28px;
  text-decoration: none;
}

.alex-log__link:hover {
  color: var(--alex-purple);
}

.alex-log__summary {
  margin: 8px 0 0;
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 24px;
}

/* --- An article, opened over the page -------------------------------------- */

/*
 * The announcement opens here rather than on its own page.
 *
 * A card laid over where you were, not a place you navigated to: the page
 * stays behind it, greyed and out of focus, and the article sits on a white
 * 900px card in front. It scrolls the way a page does and closes back to
 * exactly where you were — including on the browser's own Back button, which
 * is what people reach for.
 *
 * The card is two elements and not one. The close button and the article are
 * siblings in the header's markup, and this is a stylesheet, not a rewrite of
 * a stored row — so they are given the same width and the matching halves of
 * one radius, and what you see is a single card with its button in the corner.
 */
.alex-reader[hidden] {
  display: none;
}

.alex-reader {
  position: fixed;
  inset: 0;
  z-index: 300;
  overflow-y: auto;
  overscroll-behavior: contain;
  background-color: #2b2c3061;
  -webkit-backdrop-filter: blur(16px) saturate(115%);
  backdrop-filter: blur(16px) saturate(115%);
  animation: alex-reader-in 0.28s cubic-bezier(0.2, 0.7, 0.3, 1);
}

@keyframes alex-reader-in {
  from {
    opacity: 0;
    transform: translateY(18px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .alex-reader {
    animation: none;
  }
}

/* The top of the card. Sticky, so the way out stays in the corner however far
   down the article you have read. */
.alex-reader__bar {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  justify-content: flex-end;
  width: calc(100% - var(--alex-gutter) * 2);
  max-width: 900px;
  margin: 40px auto 0;
  padding: 14px 14px 0;
  border-radius: 16px 16px 0 0;
  background-color: #fff;
  /* Everything here but the button is card, and card does not take clicks. */
  pointer-events: none;
}

.alex-reader__close {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  background-color: #2b2c300f;
  border: 0;
  border-radius: 999px;
  color: var(--alex-ink-2);
  cursor: pointer;
  pointer-events: auto;
  transition: background-color 0.12s ease, color 0.12s ease;
}

.alex-reader__close:hover {
  background-color: #2b2c301c;
  color: var(--alex-ink);
}

/* The rest of the card. Same width, the other half of the radius. */
.alex-reader__body {
  width: calc(100% - var(--alex-gutter) * 2);
  max-width: 900px;
  margin: 0 auto 40px;
  border-radius: 0 0 16px 16px;
  background-color: #fff;
  outline: none;
}

/* The article arrives with its own padding; it does not need the sheet's too. */
.alex-reader .alex-post {
  padding: 16px 0 72px;
}

/* On the page the figure is a white panel on a grey ground. On the card the
   ground is white, so the two swap. */
.alex-reader .alex-post__figure {
  background-color: #fafafa;
}

/*
 * On a phone the card takes the screen.
 *
 * Its margins and the article's own gutters were being paid twice, which left
 * the text 48px narrower inside the card than the same article is on its own
 * page. The card's margin shrinks and the gutter inside it with it, so a line
 * is the length it is everywhere else.
 */
@media screen and (max-width: 767px) {
  .alex-reader__bar,
  .alex-reader__body {
    width: calc(100% - 24px);
  }

  .alex-reader__bar {
    margin-top: 20px;
  }

  .alex-reader__body {
    margin-bottom: 20px;
  }

  .alex-reader .alex-wrap {
    padding-inline: 16px;
  }
}

/* --- What customers say ----------------------------------------------------- */

.alex-quotes {
  padding: 96px 0 104px;
  text-align: center;
}

.alex-quotes__mark {
  display: flex;
  justify-content: center;
  color: var(--alex-purple);
}

/*
 * A list first, a slider second.
 *
 * Without the script the three quotes are simply stacked and the controls are
 * not drawn — `data-alex-quotes` is set by the script, and everything that
 * makes this a carousel hangs off it. Three quotes down the page is a lesser
 * design than three in a carousel; it is not a broken one, which a carousel
 * with a dead button would be.
 */
.alex-quotes__track {
  display: flex;
  flex-direction: column;
  gap: 72px;
  margin: 32px 0 0;
  padding: 0;
  list-style: none;
}

/* Every blockquote on this site is a tinted purple card — see alexlegal.webflow
   .css. A pull quote set at 34px is not a card, so all of it comes off. */
.alex-quotes__quote {
  max-width: 900px;
  margin: 0 auto;
  padding: 0;
  background-image: none;
  background-color: transparent;
  border: 0;
  border-radius: 0;
  color: var(--alex-ink);
  /* A customer's words, set in the serif the site already carries — it is what
     marks them as somebody speaking rather than as one more line of interface.
     PT Serif runs wider than the sans at the same size, hence the step down and
     the letter-spacing let go. */
  font-family: "PT Serif", Georgia, serif;
  font-size: 32px;
  font-weight: 400;
  line-height: 46px;
  letter-spacing: -0.01em;
}

.alex-quotes__who {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  margin-top: 36px;
}

.alex-quotes__photo {
  flex: none;
  width: 56px;
  height: 56px;
  border-radius: 999px;
  object-fit: cover;
}

.alex-quotes__name {
  text-align: left;
}

.alex-quotes__person {
  margin: 0;
  color: var(--alex-ink);
  font-size: 15px;
  line-height: 22px;
}

.alex-quotes__role {
  margin: 0;
  color: var(--alex-ink-2);
  font-size: 14px;
  line-height: 20px;
}

.alex-quotes__logo {
  height: auto;
  max-height: 28px;
  width: auto;
  margin-left: 12px;
  padding-left: 24px;
  border-left: 1px solid var(--alex-hairline);
}

.alex-quotes__story {
  display: inline-block;
  margin-top: 22px;
}

.alex-quotes__controls {
  display: none;
  align-items: center;
  justify-content: center;
  gap: 24px;
  margin-top: 48px;
}

.alex-quotes__arrow {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  padding: 0;
  background-color: #fff;
  border: 1px solid var(--alex-hairline);
  border-radius: 999px;
  color: var(--alex-ink-2);
  cursor: pointer;
  transition: color 0.12s ease, border-color 0.12s ease;
}

.alex-quotes__arrow:hover {
  border-color: var(--alex-purple);
  color: var(--alex-purple);
}

.alex-quotes__dots {
  display: flex;
  gap: 8px;
}

.alex-quotes__dot {
  width: 7px;
  height: 7px;
  padding: 0;
  background-color: #2b2c3029;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.18s ease, transform 0.18s ease;
}

.alex-quotes__dot[aria-current="true"] {
  background-color: var(--alex-purple);
  transform: scale(1.35);
}

/* Once the script is running it is a carousel: one slide at a time, the rest
   stacked behind it so the section keeps the height of the tallest. */
[data-alex-quotes] .alex-quotes__track {
  display: grid;
  gap: 0;
}

[data-alex-quotes] .alex-quotes__slide {
  grid-area: 1 / 1;
  opacity: 0;
  visibility: hidden;
  transform: translateY(10px);
  transition: opacity 0.4s ease, transform 0.4s ease, visibility 0.4s;
}

[data-alex-quotes] .alex-quotes__slide[data-current] {
  opacity: 1;
  visibility: visible;
  transform: none;
}

[data-alex-quotes] .alex-quotes__controls {
  display: flex;
}

@media (prefers-reduced-motion: reduce) {
  [data-alex-quotes] .alex-quotes__slide {
    transition: opacity 0.2s ease, visibility 0.2s;
    transform: none;
  }
}

/* --- One column width for the whole site ----------------------------------- */

/*
 * Webflow's pages were laid out on a 980px column and the new design is 1200.
 * Rather than edit sixteen rules in a 130KB stylesheet that a re-export would
 * overwrite, every container that was capped at 980 is widened here. The list
 * is exhaustive — it was read off `max-width: 980px` in
 * alexlegal.webflow.css — so a page that still looks narrow has a container
 * this does not name yet.
 *
 * The footer's legal bar is deliberately in the list: it sits under the footer
 * container and would otherwise be 220px narrower than the thing above it.
 */
.header-wrapper,
.tab-block,
.customer-wrapper,
.footer-container,
.footer-legal,
.before-after-container,
.white-block.cta,
.guide-header-wrapper,
.guide-wrapper,
.landing-wrapper-guides,
.formality-animation-wrapper,
.formal-container,
.stories-list,
.testimonials,
.white-block-after.cta,
.none.cta {
  max-width: var(--alex-width);
}

/*
 * The feature tabs, squared up.
 *
 * Webflow laid this card out on a 980px column: the text column carried its
 * own 60px inset on the left, the illustration sat flush against the right
 * edge, and widening the card to 1200 above dropped all 220px of the
 * difference into the middle — a hole between the two halves, and two
 * different margins at the two ends.
 *
 * The inset belongs to the row rather than to the column inside it, so it is
 * set once here on both sides and taken off the column. `min-height` gives the
 * card the room the illustration never asked for and the text was short of,
 * and because every pane is the same height, switching tabs does not resize
 * the card under the cursor.
 *
 * Only on the wide layout. Below 992px Webflow re-proportions both columns and
 * below 768px it stacks them, and neither wants a 56px gutter or a floor.
 */
@media screen and (min-width: 992px) {
  .tab-content {
    min-height: 428px;
    padding-inline: 56px;
  }

  .tab-left {
    padding: 48px 0;
  }
}

/* The resting state of a collapsing group's chevron: pointing down, at what it
   would open. The embedded script settles on the same value — see
   `uprightChevrons` in site/templates.ts — so nothing flips on first paint. */
.nav-guide-collapsing > .guide-nav-item .guide-nav-icon {
  transform: rotate(180deg);
  transition: transform 0.3s ease;
}

/* The guide's two columns were proportioned for 980; at 1200 the reading
   column should take the extra room, not the nav beside it. */
.guide-nav {
  flex: none;
}

.guide-article,
.guide-content {
  min-width: 0;
}

/* --- The guides ------------------------------------------------------------- */

/*
 * The wordmark beside "Guides", once you have left the top of the page.
 *
 * The guide header is sticky, so on a long article it is the only thing on
 * screen that says which site you are on — the real header has scrolled away.
 * It is not there at the top, where the real one is still visible and two
 * wordmarks in a column would be one too many.
 *
 * `data-alex-scrolled` is set on <html> by public/alex/alex.js. The width and
 * opacity are animated rather than `display`, so it grows in from nothing
 * instead of appearing.
 */
/* The title is a block in Webflow's stylesheet, so the mark would sit above
   the word rather than beside it. */
.guide-link-title {
  display: inline-flex;
  align-items: center;
}

.alex-guides-mark {
  display: inline-flex;
  align-items: center;
  overflow: hidden;
  width: 0;
  margin-right: 0;
  opacity: 0;
  color: var(--alex-ink);
  transition: width 0.28s cubic-bezier(0.2, 0.7, 0.3, 1),
    margin-right 0.28s cubic-bezier(0.2, 0.7, 0.3, 1), opacity 0.2s ease;
}

.alex-guides-mark svg {
  display: block;
  width: 42px;
  height: 16px;
  flex: none;
}

[data-alex-scrolled] .alex-guides-mark {
  width: 42px;
  margin-right: 14px;
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .alex-guides-mark {
    transition: none;
  }
}

/* --- Search ----------------------------------------------------------------- */

.alex-search {
  padding: 72px 0 120px;
}

.alex-search__title {
  margin: 0;
  color: var(--alex-ink);
  font-size: 36px;
  font-weight: 600;
  line-height: 45px;
  letter-spacing: -0.02em;
}

.alex-search__form {
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: 680px;
  margin: 28px 0 0;
  padding: 6px 6px 6px 16px;
  background-color: #fff;
  border: 1px solid var(--alex-hairline-2);
  border-radius: 12px;
  box-shadow: 0 1px 2px #00000008;
  transition: border-color 0.14s ease, box-shadow 0.14s ease;
}

.alex-search__form:focus-within {
  border-color: #685bff5c;
  box-shadow: 0 0 0 4px #685bff1a;
}

.alex-search__icon {
  flex: none;
  color: var(--alex-ink-2);
}

.alex-search__input {
  flex: 1;
  min-width: 0;
  height: 38px;
  padding: 0;
  background: none;
  border: 0;
  color: var(--alex-ink);
  font-family: inherit;
  font-size: 16px;
  outline: none;
}

.alex-search__input::placeholder {
  color: #8b8c93;
}

.alex-search__form .alex-btn {
  min-height: 38px;
}

.alex-search__note,
.alex-search__count {
  margin: 28px 0 0;
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 24px;
}

.alex-search__count {
  margin-top: 40px;
}

.alex-search__list {
  display: flex;
  flex-direction: column;
  gap: 0;
  max-width: 760px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}

.alex-search__hit {
  padding: 24px 0;
  border-bottom: 1px solid var(--alex-hairline);
}

.alex-search__kind {
  margin: 0;
  color: var(--alex-ink-2);
  font-size: 13px;
  line-height: 20px;
}

.alex-search__link {
  display: inline-block;
  margin-top: 4px;
  color: var(--alex-ink);
  font-size: 18px;
  font-weight: 600;
  line-height: 26px;
  text-decoration: none;
}

.alex-search__link:hover {
  color: var(--alex-purple);
}

.alex-search__excerpt {
  margin: 6px 0 0;
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 24px;
}

/*
 * The short answer.
 *
 * Marked as an answer rather than dressed up as one: a tinted panel with the
 * guides it came from printed underneath, so it reads as a summary of what is
 * below and not as a voice of its own. When the guides do not cover the
 * question the panel is not drawn at all.
 */
.alex-answer {
  max-width: 760px;
  margin: 36px 0 0;
  padding: 22px 24px;
  background-image: linear-gradient(120deg, #685bff0f, #6ef8bf12);
  border: 1px solid #685bff26;
  border-radius: 14px;
}

.alex-answer__text {
  margin: 0;
  color: var(--alex-ink);
  font-size: 16px;
  line-height: 27px;
}

.alex-answer__sources {
  margin: 14px 0 0;
  color: var(--alex-ink-2);
  font-size: 13px;
  line-height: 22px;
}

.alex-answer__sources a {
  color: var(--alex-purple);
}

.alex-answer__thinking {
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 0;
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 24px;
}

.alex-answer__pulse {
  width: 8px;
  height: 8px;
  background-color: var(--alex-purple);
  border-radius: 999px;
  animation: alex-pulse 1.1s ease-in-out infinite;
}

@keyframes alex-pulse {
  0%, 100% { opacity: 0.25; transform: scale(0.8); }
  50% { opacity: 1; transform: scale(1); }
}

@media (prefers-reduced-motion: reduce) {
  .alex-answer__pulse { animation: none; opacity: 0.6; }
}

/* The guides' own search box, which posts to the same page. */
.guide-search {
  border-radius: 10px;
  transition: border-color 0.14s ease, box-shadow 0.14s ease;
}

.guide-search:focus-within {
  border-color: #685bff5c;
  box-shadow: 0 0 0 4px #685bff1a;
}

/* --- Narrow ---------------------------------------------------------------- */

@media (max-width: 991px) {
  .alex-nav__burger {
    display: inline-flex;
  }

  .alex-nav__links,
  .alex-nav__actions {
    display: none;
  }

  /* With JavaScript off there is no button to press, so the links are simply
     laid out instead of hidden behind one. `w-mod-js` is Webflow's own flag
     and it is already set before first paint. */
  html:not(.w-mod-js) .alex-nav__links,
  html:not(.w-mod-js) .alex-nav__actions {
    display: flex;
  }

  html:not(.w-mod-js) .alex-nav__burger {
    display: none;
  }

  .alex-nav__inner {
    flex-wrap: wrap;
    height: auto;
    padding-block: 12px;
  }

  /* The button comes after the links in the markup — where a screen reader
     wants it, right before what it controls — so `order` is what keeps it
     beside the logo once the links wrap onto their own lines below. */
  .alex-nav__burger {
    order: 1;
  }

  .alex-nav__links {
    order: 2;
  }

  .alex-nav__actions {
    order: 3;
  }

  .alex-nav__inner[data-open="true"] .alex-nav__links,
  .alex-nav__inner[data-open="true"] .alex-nav__actions {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 18px;
    width: 100%;
    margin: 0;
    padding-top: 18px;
  }

  .alex-nav__inner[data-open="true"] .alex-nav__actions {
    padding-bottom: 8px;
    border-top: 1px solid var(--alex-hairline);
    margin-top: 18px;
  }

  .alex-hero,
  [data-ab-hero="a"] .alex-hero,
  [data-ab-hero="b"] .alex-hero {
    grid-template-areas:
      "promo promo promo promo promo"
      ".     title title title ."
      ".     pitch pitch pitch ."
      ".     proof proof proof .";
    /* One column, four rows, stacked. None of the desktop distribution applies:
       there is no second column to line up with, and a hero asked to fill a
       phone screen would space four blocks halfway down it. */
    grid-template-rows: none;
    align-content: start;
    min-height: 0;
    row-gap: 28px;
    padding-top: 0;
    padding-bottom: 64px;
  }

  [data-ab-hero="b"] .alex-promo__inner {
    gap: 22px;
  }

  .alex-hero__title,
  .alex-hero__pitch,
  [data-ab-hero="a"] .alex-hero__title,
  [data-ab-hero="a"] .alex-hero__pitch {
    padding-top: 0;
  }

  .alex-hero__title,
  [data-ab-hero="a"] .alex-hero__title {
    padding-top: 56px;
  }

  .alex-proof,
  [data-ab-hero="a"] .alex-proof {
    margin-top: 0;
  }

  /* On a narrow screen both variants read as the band: a card floated beside
     nothing is just a card with a margin. */
  [data-ab-hero="b"] .alex-promo {
    margin-bottom: 8px;
  }

  .alex-hero__title {
    max-width: none;
    font-size: 36px;
    line-height: 42px;
  }

  .alex-hero__lede {
    max-width: none;
  }

  .alex-modal__choices {
    grid-template-columns: 1fr;
    gap: 32px;
  }

  .alex-modal__rule {
    height: 1px;
  }

  .alex-modal__panel {
    padding: 48px 24px 40px;
  }

  .alex-post__title,
  .alex-log__title,
  .alex-search__title {
    font-size: 28px;
    line-height: 36px;
  }

  .alex-search__form {
    flex-wrap: wrap;
  }

  .alex-search__form .alex-btn {
    width: 100%;
  }

  .alex-post__figure {
    height: 180px;
  }

  .alex-quotes {
    padding: 64px 0 72px;
  }

  .alex-quotes__quote {
    font-size: 24px;
    line-height: 34px;
  }

  .alex-quotes__who {
    flex-wrap: wrap;
    gap: 12px;
  }

  .alex-quotes__logo {
    margin-left: 0;
    padding-left: 0;
    border-left: 0;
  }

  /* The announcement's headline steps down with everything else; left at 28px
     it out-shouts the page's own h1. */
  .alex-promo__title,
  [data-ab-hero="a"] .alex-promo__title,
  [data-ab-hero="b"] .alex-promo__title {
    font-size: 21px;
    line-height: 28px;
  }

  [data-ab-hero="b"] .alex-promo {
    padding: 28px 24px 32px;
  }

  [data-ab-hero="b"] .alex-proof {
    padding: 22px 20px 26px;
  }

  .alex-proof__logos {
    gap: 24px;
  }
}

/* --- The brand page -------------------------------------------------------- */

/*
 * Quiet on purpose. The page is about a logo, so everything around it is a
 * hairline and a label — anything with a colour of its own would be competing
 * with the thing on display.
 */
.alex-brand {
  padding: 56px 0 120px;
}

.alex-brand__title {
  margin: 0;
  color: var(--alex-ink);
  font-size: 36px;
  font-weight: 600;
  line-height: 45px;
  letter-spacing: -0.02em;
}

.alex-brand__lede {
  max-width: 560px;
  margin: 16px 0 0;
  color: var(--alex-ink-2);
  font-size: 16px;
  line-height: 27px;
}

.alex-brand__section {
  margin-top: 72px;
  padding-top: 40px;
  border-top: 1px solid var(--alex-hairline);
}

.alex-brand__heading {
  margin: 0;
  color: var(--alex-ink);
  font-size: 22px;
  font-weight: 600;
  line-height: 30px;
}

.alex-brand__subheading {
  margin: 48px 0 0;
  color: var(--alex-ink);
  font-size: 15px;
  font-weight: 600;
  line-height: 24px;
}

.alex-brand__note {
  max-width: 560px;
  margin: 10px 0 0;
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 25px;
}

/* --- The logo tiles -------------------------------------------------------- */

.alex-brand__tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 20px;
  margin-top: 32px;
}

.alex-brand__tile-wrap {
  margin: 0;
}

/* The tile is the surface, not a button: right-clicking it is the whole
   interaction, so it takes no pointer and no left-click of its own. */
.alex-brand__tile {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 180px;
  border: 1px solid var(--alex-hairline-2);
  border-radius: var(--alex-radius);
  /* A long press is the right button on a touch screen, and it opens the same
     menu — so the system's own callout has to stay out of its way. */
  -webkit-touch-callout: none;
  user-select: none;
}

.alex-brand__tile--light {
  background-color: #fff;
  color: var(--alex-ink);
}

.alex-brand__tile--dark {
  background-color: var(--alex-dark);
  color: #fff;
}

.alex-brand__logo {
  display: block;
}

.alex-brand__logo--logotype {
  width: 132px;
  height: auto;
}

.alex-brand__logo--mark {
  width: 44px;
  height: auto;
}

.alex-brand__caption {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 10px;
  margin-top: 12px;
}

.alex-brand__caption-label {
  color: var(--alex-ink);
  font-size: 13px;
  font-weight: 500;
  line-height: 20px;
}

.alex-brand__caption-hint {
  color: var(--alex-ink-2);
  font-size: 13px;
  line-height: 20px;
}

/* --- The menu a right-click opens ------------------------------------------ */

/*
 * Drawn on the page and not by the browser, so it can offer the file rather
 * than "Save image as…" on a piece of inline SVG — which saves nothing.
 * Positioned where the cursor was, and kept inside the window by the component.
 */
.alex-brand__menu,
.alex-logo-menu {
  position: fixed;
  z-index: 400;
  min-width: 182px;
  padding: 5px;
  border: 1px solid var(--alex-hairline-2);
  border-radius: 10px;
  background-color: #fff;
  box-shadow: 0 14px 48px #00000015;
  animation: alex-menu-in 0.1s ease-out;
}

@keyframes alex-menu-in {
  from {
    opacity: 0;
    transform: translateY(-3px);
  }
}

@media (prefers-reduced-motion: reduce) {
  .alex-brand__menu,
  .alex-logo-menu {
    animation: none;
  }
}

.alex-brand__menu button,
.alex-logo-menu button,
.alex-logo-menu a {
  display: block;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 6px;
  background: none;
  color: var(--alex-ink);
  font-family: inherit;
  font-size: 13px;
  line-height: 20px;
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.alex-brand__menu button:hover,
.alex-logo-menu button:hover,
.alex-logo-menu a:hover {
  background-color: #2b2c300a;
}

.alex-logo-menu hr {
  margin: 5px 6px;
  border: 0;
  border-top: 1px solid var(--alex-hairline);
}

/* --- What not to do -------------------------------------------------------- */

.alex-brand__dont {
  max-width: 560px;
  margin: 12px 0 0;
  padding-left: 18px;
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 27px;
}

/* --- Colours --------------------------------------------------------------- */

.alex-brand__swatches {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 20px;
  margin: 32px 0 0;
  padding: 0;
  list-style: none;
}

.alex-brand__swatch {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.alex-brand__chip {
  height: 88px;
  margin-bottom: 10px;
  border: 1px solid var(--alex-hairline-2);
  border-radius: var(--alex-radius);
}

.alex-brand__swatch-name {
  color: var(--alex-ink);
  font-size: 13px;
  font-weight: 500;
  line-height: 20px;
}

.alex-brand__swatch-hex {
  color: var(--alex-ink-2);
  font-size: 13px;
  line-height: 20px;
}

.alex-brand__swatch-token {
  color: #8b8c93;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 12px;
  line-height: 20px;
}

/* --- Type ------------------------------------------------------------------ */

.alex-brand__faces {
  margin: 32px 0 0;
  padding: 0;
  list-style: none;
}

.alex-brand__face {
  padding: 24px 0;
  border-top: 1px solid var(--alex-hairline);
}

.alex-brand__face-sample {
  margin: 0;
  color: var(--alex-ink);
  font-size: 30px;
  line-height: 42px;
}

.alex-brand__face--inter {
  font-family: "Inter Variable", sans-serif;
  font-weight: 500;
  letter-spacing: -0.02em;
}

.alex-brand__face--kalam {
  font-family: Kalam, sans-serif;
}

.alex-brand__face--serif {
  font-family: "PT Serif", serif;
}

.alex-brand__face-name {
  display: flex;
  gap: 10px;
  margin: 10px 0 0;
  color: var(--alex-ink-2);
  font-size: 13px;
  line-height: 20px;
}

.alex-brand__face-use {
  color: #8b8c93;
}

.alex-brand__contact {
  margin: 56px 0 0;
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 25px;
}

@media screen and (max-width: 767px) {
  .alex-brand__title {
    font-size: 28px;
    line-height: 36px;
  }

  .alex-brand__section {
    margin-top: 48px;
  }
}

/* The label above each pair of formats in the header's logo menu. */
.alex-logo-menu[hidden] {
  display: none;
}

.alex-logo-menu__label {
  margin: 6px 10px 2px;
  color: #8b8c93;
  font-size: 11px;
  font-weight: 500;
  line-height: 16px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* --- The analytics line under the footer ------------------------------------
 *
 * The footer's own colours — #1e1f24 behind it, #ffffff80 on the text, the
 * 1px #ffffff12 rule it separates its legal bar with — and the same 980px
 * column, so it reads as one more line of the footer rather than a thing
 * bolted under it.
 *
 * It is hidden by an attribute and not by a class the script adds later: the
 * snippet in lib/site/consent.ts puts `data-consent` on <html> in the head,
 * before the first paint, so a visitor who answered last month never sees this
 * flash up and disappear. `display: none` and not `hidden` because the buttons
 * inside it must not be reachable by Tab once the question is settled.
 */
.alex-consent {
  background-color: #1e1f24;
  border-top: 1px solid #ffffff12;
  padding: 14px 24px;
}

[data-consent] .alex-consent {
  display: none;
}

.alex-consent__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px 28px;
  max-width: 980px;
  margin-inline: auto;
}

.alex-consent__text {
  margin: 0;
  color: #ffffff80;
  font-size: 13px;
  line-height: 20px;
}

.alex-consent__more {
  color: #ffffff80;
  text-decoration: underline;
  text-underline-offset: 2px;
  transition: color 0.2s;
}

.alex-consent__more:hover {
  color: #fff;
}

.alex-consent__actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.alex-consent__btn {
  box-sizing: border-box;
  min-height: 28px;
  padding: 5px 14px;
  border: 1px solid #ffffff24;
  border-radius: var(--alex-radius);
  background: none;
  color: #ffffffcc;
  font-family: inherit;
  font-size: 13px;
  line-height: 18px;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.12s ease, color 0.12s ease, border-color 0.12s ease;
}

.alex-consent__btn:hover {
  border-color: #ffffff40;
  color: #fff;
}

.alex-consent__btn--yes {
  border-color: transparent;
  background-color: var(--alex-purple);
  color: #fff;
}

.alex-consent__btn--yes:hover {
  background-color: #5849f5;
  color: #fff;
}

@media screen and (max-width: 767px) {
  .alex-consent__inner {
    align-items: flex-start;
    flex-direction: column;
  }
}

/* A page that is one embed — the demo calendar — still needs to say what it
   is, to a reader arriving cold as much as to a crawler. */
.alex-page-title {
  max-width: 980px;
  margin: 0 auto 28px;
  color: #000;
  font-size: 32px;
  font-weight: 600;
  line-height: 40px;
  letter-spacing: -0.02em;
  text-align: center;
}

@media screen and (max-width: 767px) {
  .alex-page-title {
    font-size: 26px;
    line-height: 32px;
  }
}

/* --- The product tabs: there when the page is ------------------------------
 *
 * Webflow hid this section at `opacity: 0` in its markup and had an
 * interaction fade it in on scroll. It is the first thing under the hero, so
 * on most screens it was half on the page and half invisible until a scroll
 * event woke it up — and with JavaScript slow or off it never appeared at all.
 * `!important` because the zero is an inline style, and the interaction keeps
 * rewriting it; nothing short of that wins.
 */
.tab-section {
  opacity: 1 !important;
  transform: none !important;
}

/* --- Integrations -----------------------------------------------------------
 *
 * Alex on the left, wired to whichever partner is chosen; the partners in a
 * rail; what the chosen one does on the right. lib/site/integrations.ts writes
 * the markup and explains why it is markup.
 *
 * One number drives all of it: `data-active` on the section, which alex.js
 * sets and nothing else. The rules just below turn it into `--i`, the index,
 * and into `--on` on the tab and the panel at that position — and everything
 * that moves or lights up reads those two. Five partners, five rules: adding a
 * sixth means adding a sixth, which is a fair price for no script touching a
 * style.
 */
.alex-int[data-active="0"] .alex-int__tab:nth-child(1),
.alex-int[data-active="0"] .alex-int__panel:nth-child(1) { --on: 1; }
.alex-int[data-active="0"] { --i: 0; }
.alex-int[data-active="1"] .alex-int__tab:nth-child(2),
.alex-int[data-active="1"] .alex-int__panel:nth-child(2) { --on: 1; }
.alex-int[data-active="1"] { --i: 1; }
.alex-int[data-active="2"] .alex-int__tab:nth-child(3),
.alex-int[data-active="2"] .alex-int__panel:nth-child(3) { --on: 1; }
.alex-int[data-active="2"] { --i: 2; }
.alex-int[data-active="3"] .alex-int__tab:nth-child(4),
.alex-int[data-active="3"] .alex-int__panel:nth-child(4) { --on: 1; }
.alex-int[data-active="3"] { --i: 3; }
.alex-int[data-active="4"] .alex-int__tab:nth-child(5),
.alex-int[data-active="4"] .alex-int__panel:nth-child(5) { --on: 1; }
.alex-int[data-active="4"] { --i: 4; }

.alex-int {
  --row: 60px;
  --rows: 5;
  padding-block: 40px 96px;
}

.alex-int .home-h2 {
  margin-bottom: 56px;
  text-align: center;
}

.alex-int__stage {
  display: grid;
  width: 100%;
  grid-template-columns: auto 72px 220px 40px minmax(0, 420px);
  justify-content: center;
  align-items: center;
  max-width: 980px;
  margin-inline: auto;
}

/* Alex, at the size of the logos it is wired to — a wordmark among wordmarks
   rather than a headline beside a list. */
.alex-int__hub {
  display: grid;
  place-items: center;
  width: 112px;
  height: 64px;
  border: 1px solid var(--alex-hairline);
  border-radius: 14px;
  background: #fff;
  box-shadow: 0 1px 2px #0000000a, 0 8px 24px #0000000d;
}

.alex-int__hub img {
  display: block;
  width: auto;
  height: 22px;
}

/*
 * The wire from Alex to the chosen partner.
 *
 * An elbow: out from Alex, along, and into the rail at the height of the
 * active row. It is one box whose top or bottom edge is the far end, so it
 * stretches from the middle row — where Alex sits — to wherever `--i` says,
 * and folds flat when that *is* the middle row.
 */
.alex-int__wire {
  position: relative;
  align-self: stretch;
  --mid: calc((var(--rows) - 1) / 2);
  --offset: calc((var(--i, 0) - var(--mid)) * var(--row));
}

.alex-int__wire span {
  position: absolute;
  left: 8px;
  right: 8px;
  top: 50%;
  height: max(calc(var(--offset)), calc(var(--offset) * -1), 1px);
  border: 0 solid #c9cad3;
  border-left-width: 0;
  transition: height 0.32s cubic-bezier(0.3, 0.7, 0.2, 1), transform 0.32s cubic-bezier(0.3, 0.7, 0.2, 1);
}

/* Below the middle: the box hangs down, and its left and bottom edges draw. */
.alex-int__wire span {
  border-bottom-width: 1.5px;
  border-left-width: 1.5px;
  border-bottom-left-radius: 12px;
}

/* Above the middle: the same box flipped over the midline. */
.alex-int[data-active="0"] .alex-int__wire span,
.alex-int[data-active="1"] .alex-int__wire span {
  transform: translateY(-100%) scaleY(-1);
}

/* On the middle row there is no elbow to turn: just the line. */
.alex-int[data-active="2"] .alex-int__wire span {
  border-left-width: 0;
  border-radius: 0;
}

/* The stub from Alex to the elbow, and the dot where the wire lands. */
.alex-int__wire::before {
  content: "";
  position: absolute;
  left: 0;
  top: 50%;
  width: 8px;
  border-top: 1.5px solid #c9cad3;
}

.alex-int__wire::after {
  content: "";
  position: absolute;
  right: 3px;
  top: calc(50% + var(--offset) - 3px);
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--alex-purple);
  box-shadow: 0 0 0 3px #685bff26;
  transition: top 0.32s cubic-bezier(0.3, 0.7, 0.2, 1);
}

.alex-int__rail {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 10px;
}

.alex-int__tabs {
  display: flex;
  flex-direction: column;
}

.alex-int__tab {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  height: var(--row);
  padding: 0 18px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: none;
  cursor: pointer;
  /* Quiet until chosen: grey, and most of the way to the background. */
  filter: grayscale(calc(1 - var(--on, 0)));
  opacity: calc(0.42 + var(--on, 0) * 0.58);
  transition: opacity 0.2s ease, filter 0.2s ease, background-color 0.2s ease, border-color 0.2s ease;
}

.alex-int__tab:hover {
  opacity: calc(0.75 + var(--on, 0) * 0.25);
}

.alex-int__tab:focus-visible {
  outline: 2px solid var(--alex-purple);
  outline-offset: 2px;
}

.alex-int[data-active="0"] .alex-int__tab:nth-child(1),
.alex-int[data-active="1"] .alex-int__tab:nth-child(2),
.alex-int[data-active="2"] .alex-int__tab:nth-child(3),
.alex-int[data-active="3"] .alex-int__tab:nth-child(4),
.alex-int[data-active="4"] .alex-int__tab:nth-child(5) {
  border-color: var(--alex-hairline);
  background: #fff;
  box-shadow: 0 1px 2px #0000000a, 0 6px 18px #0000000a;
}

/* Every logo at the height its own file needs to look the same size as the
   rest — see `height` in lib/site/integrations.ts. */
.alex-int__tab img {
  display: block;
  width: auto;
  max-width: 150px;
  height: var(--h, 22px);
  object-fit: contain;
  pointer-events: none;
}

.alex-int__arrow {
  display: grid;
  place-items: center;
  align-self: flex-start;
  width: 32px;
  height: 32px;
  margin-left: 14px;
  padding: 0;
  border: 1px solid var(--alex-hairline);
  border-radius: 50%;
  background: #fff;
  color: var(--alex-ink-2);
  cursor: pointer;
  transition: color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}

.alex-int__arrow:hover {
  border-color: #685bff66;
  color: var(--alex-purple);
}

.alex-int__arrow:active {
  transform: scale(0.94);
}

.alex-int__arrow:focus-visible {
  outline: 2px solid var(--alex-purple);
  outline-offset: 2px;
}

/* The panels share one cell, so the card is as tall as the longest of them
   and does not jump as the partner changes. */
.alex-int__panels {
  grid-column: 5;
  display: grid;
}

.alex-int__panel {
  grid-area: 1 / 1;
  box-sizing: border-box;
  padding: 28px 32px 30px;
  border: 1px solid var(--alex-hairline);
  border-radius: 16px;
  background: #fff;
  box-shadow: 0 1px 2px #0000000a, 0 14px 40px #0000000f;
  opacity: var(--on, 0);
  visibility: hidden;
  transform: translateY(calc((1 - var(--on, 0)) * 6px));
  transition: opacity 0.24s ease, transform 0.24s ease, visibility 0s linear 0.24s;
}

.alex-int[data-active="0"] .alex-int__panel:nth-child(1),
.alex-int[data-active="1"] .alex-int__panel:nth-child(2),
.alex-int[data-active="2"] .alex-int__panel:nth-child(3),
.alex-int[data-active="3"] .alex-int__panel:nth-child(4),
.alex-int[data-active="4"] .alex-int__panel:nth-child(5) {
  visibility: visible;
  transition-delay: 0s;
}

.alex-int__kind {
  margin: 0 0 6px;
  color: var(--alex-purple);
  font-size: 12px;
  font-weight: 600;
  line-height: 16px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.alex-int__name {
  margin: 0;
  color: #000;
  font-size: 22px;
  font-weight: 600;
  line-height: 28px;
  letter-spacing: -0.01em;
}

.alex-int__pitch {
  margin: 8px 0 0;
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 23px;
}

.alex-int__points {
  display: grid;
  gap: 10px;
  margin: 20px 0 0;
  padding: 18px 0 0;
  border-top: 1px solid var(--alex-hairline);
  list-style: none;
}

.alex-int__points li {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  color: var(--alex-ink);
  font-size: 14.5px;
  line-height: 21px;
}

.alex-int__check {
  flex: none;
  margin-top: 2.5px;
  color: var(--alex-purple);
}

/*
 * Narrow: the rail lies down.
 *
 * Alex and the wire go — there is no room to draw a connection and nothing
 * lost by not drawing it — the logos become a row of chips that scrolls
 * sideways, and the arrows sit at either end of it pointing the way it moves.
 */
@media (max-width: 991px) {
  .alex-int {
    padding-block: 24px 64px;
  }

  .alex-int .home-h2 {
    margin-bottom: 32px;
  }

  /* `width` because Webflow's `.section` centres its children as flex items,
     and a flex item that is not told otherwise is as wide as its content —
     here, the whole row of logos, well past the edge of a phone. */
  .alex-int__stage {
    display: block;
    box-sizing: border-box;
    width: 100%;
    max-width: 560px;
    /* The section already pads the sides; a gutter of its own would double it. */
    padding-inline: 0;
  }

  .alex-int__hub,
  .alex-int__wire {
    display: none;
  }

  .alex-int__rail {
    flex-direction: row;
    align-items: center;
    gap: 8px;
    margin-bottom: 18px;
  }

  .alex-int__tabs {
    flex: 1;
    flex-direction: row;
    gap: 8px;
    min-width: 0;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    scrollbar-width: none;
    padding-block: 4px;
  }

  .alex-int__tabs::-webkit-scrollbar {
    display: none;
  }

  .alex-int__tab {
    flex: none;
    height: 52px;
    padding: 0 16px;
    scroll-snap-align: center;
  }

  .alex-int__tab img {
    max-width: 120px;
    height: calc(var(--h, 22px) * 0.9);
  }

  .alex-int__arrow {
    flex: none;
    align-self: center;
    margin: 0;
  }

  /* Up and down become back and forward. */
  .alex-int__arrow svg {
    transform: rotate(-90deg);
  }

  .alex-int__panel {
    padding: 24px 22px 26px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .alex-int__wire span,
  .alex-int__wire::after,
  .alex-int__tab,
  .alex-int__panel {
    transition: none;
  }
}

/* --- The header's frosted glass, on a phone too ------------------------------
 *
 * Webflow's stylesheet switches the blur off under 991px and makes the header
 * opaque instead. Ours made it translucent again and never put the blur back,
 * so on a phone the page scrolled underneath it in sharp focus — tabs and
 * headings legible through the logo. Both halves, restored together.
 */
@media screen and (max-width: 991px) {
  .head.alex-nav {
    background-color: #fafafacc;
    -webkit-backdrop-filter: blur(16px) saturate(140%);
    backdrop-filter: blur(16px) saturate(140%);
  }
}

/* --- The Registres tab, on a phone -----------------------------------------
 *
 * Its illustration — the list of minutes, each with a date and a check — is
 * positioned absolutely, which works on a desktop because the box it sits in
 * is given 364px. Under 991px Webflow lets that box size itself instead, and
 * an absolutely positioned child gives it nothing to size from: it collapsed
 * to its own padding, and the list spilled up over the bullet points and was
 * cut off by the tab card's edge. Every other tab keeps its picture in the
 * flow; this one now does too.
 */
@media screen and (max-width: 991px) {
  .tab-illustration-wrapper .for-regsiter {
    position: relative;
    inset: auto;
    box-sizing: border-box;
    width: 100%;
    max-width: 420px;
    margin: 0 auto;
  }

  /* Each row is drawn 320px wide, which on a phone is wider than the card
     holding it; they overhung its right edge. */
  .tab-illustration-wrapper .for-regsiter-copy {
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
  }
}

/* --- The welcome dialog, on a phone -----------------------------------------
 *
 * It was 793px of dialog on an 812px screen, centred, with no maximum height
 * and nothing to scroll — so on an iPhone, where Safari's own bars take a
 * hundred and more of those pixels, the title went under the status bar and
 * the second choice under the toolbar, with no way to reach either.
 *
 * Two things, then. It never grows past the part of the screen that is
 * actually visible — `dvh` is that part, and moves with the toolbars — and
 * scrolls inside itself if it has to. And it is drawn tighter, so that on any
 * phone of the last few years it does not have to: the same two choices, the
 * same words, a third less air between them.
 */
@media screen and (max-width: 767px) {
  .alex-modal {
    padding: 12px;
  }

  .alex-modal__panel {
    max-height: calc(100vh - 24px);
    max-height: calc(100dvh - 24px);
    overflow-y: auto;
    overscroll-behavior: contain;
    -webkit-overflow-scrolling: touch;
    padding: 36px 20px 26px;
    border-radius: 14px;
  }

  .alex-modal__close {
    top: 10px;
    right: 10px;
  }

  .alex-modal__title {
    margin-bottom: 24px;
    font-size: 22px;
    line-height: 28px;
  }

  .alex-modal__choices {
    gap: 22px;
  }

  .alex-modal__icon svg {
    width: 30px;
    height: 30px;
  }

  .alex-modal__heading {
    margin-top: 14px;
    font-size: 16px;
  }

  .alex-modal__blurb {
    margin-top: 6px;
    max-width: 300px;
    font-size: 13.5px;
    line-height: 20px;
  }

  .alex-modal__choice .alex-btn {
    max-width: 300px;
    margin-top: 16px;
  }

  .alex-modal__time {
    margin-top: 10px;
  }
}
