/* ---------------------------------------------------------------------------
 * 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 centred column: what is new, the headline, the pitch, and who uses it.
 *
 * It replaced the split test of 2026 — the announcement as a dark band (A) or
 * as a card down the right (B) — on 2026-11-01. The announcement is one of the
 * cards in the stack at the top now. See lib/site/hero.ts.
 *
 * `isolation` keeps the (switched-off) aurora's z-index meaning "behind the
 * hero" rather than "behind the page".
 */
.alex-hero {
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-sizing: border-box;
  width: 100%;
  /*
   * The hero owns the first screen: tall enough that the row of tabs below it
   * is just showing. 64px is the header and 104px what the tab row needs to
   * peek. `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);
  padding: 56px var(--alex-gutter) 96px;
  text-align: center;
}

.alex-hero__title {
  max-width: 640px;
  margin: 72px 0 0;
  color: #000;
  font-size: 56px;
  font-weight: 600;
  line-height: 62px;
  letter-spacing: -0.025em;
}

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

.alex-hero__lede {
  max-width: 500px;
  margin: 22px 0 0;
  color: var(--alex-ink-2);
  font-size: 16px;
  line-height: 24px;
}

.alex-hero__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-top: 28px;
}

/* --- 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;
}

/* --- What is new ----------------------------------------------------------- */

/*
 * A pill that says "Nouveau", with a dot per card, over a stack of cards.
 *
 * The card in front is a link; the next one peeks out from behind it, turned
 * a degree, so the stack reads as a stack before anything moves. The dot of
 * the card in front is drawn as a short bar that fills from the left while its
 * turn runs, and alex.js moves on when the fill ends — so the bar *is* the
 * timer, and pausing it (the cursor over the stack, a keyboard focus inside
 * it) pauses everything. With reduced motion there is no fill and no turn: the
 * first card stays, and the dots still switch.
 */
.alex-news {
  --alex-news-turn: 6s;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 14px;
  width: 100%;
  max-width: 488px;
}

.alex-news__bar {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  padding: 7px 10px 7px 14px;
  border-radius: 999px;
  background-color: #2b2c300d;
}

.alex-news__new {
  color: #2b2c3080;
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
  letter-spacing: 0.02em;
  text-transform: uppercase;
}

.alex-news__dots {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.alex-news__dot {
  position: relative;
  overflow: hidden;
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background-color: #fff;
  cursor: pointer;
  transition: width 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.alex-news__dot[aria-current="true"] {
  width: 26px;
}

.alex-news__dot::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 0;
  border-radius: inherit;
  background-color: var(--alex-dark);
}

.alex-news__dot[aria-current="true"]::after {
  animation: alex-news-fill var(--alex-news-turn) linear forwards;
}

.alex-news:hover .alex-news__dot::after,
.alex-news:focus-within .alex-news__dot::after {
  animation-play-state: paused;
}

@keyframes alex-news-fill {
  from { width: 8px; }
  to { width: 100%; }
}

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

.alex-news__stack {
  display: grid;
  width: 100%;
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Every card in the same cell, one on top of another. */
.alex-news__card {
  grid-area: 1 / 1;
  box-sizing: border-box;
  border: 1px solid #0000000f;
  border-radius: 20px;
  background-color: #fff;
  box-shadow: 0 1px 2px #0000000a, 0 12px 32px #0000000d;
  text-align: left;
  transform-origin: 50% 100%;
  transition:
    transform 0.6s cubic-bezier(0.2, 0.8, 0.2, 1),
    opacity 0.45s ease,
    box-shadow 0.3s ease;
}

.alex-news__card[data-state="front"] {
  z-index: 2;
}

/* Behind, a little lower and turned: its edge shows at the right and below. */
.alex-news__card[data-state="back"] {
  z-index: 1;
  transform: translate(8px, 5px) rotate(1.2deg);
}

/* The card whose turn is over lifts away, and then goes round the back. */
.alex-news__card[data-state="out"] {
  z-index: 3;
  opacity: 0;
  transform: translateY(-16px) scale(0.97);
}

.alex-news__card[data-state="hidden"] {
  z-index: 0;
  opacity: 0;
}

/* Only the card in front is read, clicked or tabbed to. */
.alex-news__card:not([data-state="front"]) {
  pointer-events: none;
}

.alex-news__card:not([data-state="front"]) .alex-news__link {
  visibility: hidden;
}

.alex-news__link {
  display: flex;
  align-items: center;
  gap: 22px;
  padding: 14px 24px 14px 16px;
  border-radius: inherit;
  color: inherit;
  text-decoration: none;
}

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

.alex-news__copy {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.alex-news__title {
  color: #000;
  font-size: 16px;
  font-weight: 600;
  line-height: 22px;
}

.alex-news__text {
  color: #2b2c3080;
  font-size: 15px;
  line-height: 21px;
}

/*
 * The whole card answers the pointer, not its title: it rises a little, the
 * marks fan out, and an arrow comes in from the right to say it goes
 * somewhere. Only the card in front can be pointed at (see above).
 */
.alex-news__card[data-state="front"]:hover {
  transform: translateY(-2px);
  box-shadow: 0 1px 2px #0000000a, 0 18px 40px #00000014;
}

.alex-news__copy {
  flex: 1;
}

.alex-news__go {
  display: grid;
  flex: none;
  place-items: center;
  width: 28px;
  height: 28px;
  margin-left: auto;
  border-radius: 999px;
  background-color: #2b2c300d;
  color: var(--alex-ink);
  opacity: 0;
  transform: translateX(-6px);
  transition: opacity 0.25s ease, transform 0.35s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.alex-news__link:hover .alex-news__go,
.alex-news__link:focus-visible .alex-news__go {
  opacity: 1;
  transform: none;
}

.alex-news__art {
  transition: transform 0.45s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.alex-news__link:hover .alex-news__art {
  transform: scale(1.06) rotate(-3deg);
}

/* --- A card's picture: marks on tiles, tumbled together -------------------- */

.alex-news__art {
  position: relative;
  flex: none;
  width: 76px;
  height: 76px;
}

.alex-news__tile {
  position: absolute;
  display: grid;
  place-items: center;
  box-sizing: border-box;
  width: 36px;
  height: 36px;
  border-radius: 11px;
  background-color: #fff;
  box-shadow: 0 0 0 1px #0000000d, 0 4px 10px #00000014;
  transition: transform 0.5s cubic-bezier(0.2, 0.8, 0.2, 1);
}

.alex-news__tile img {
  display: block;
  width: 20px;
  height: 20px;
}

.alex-news__tile svg {
  display: block;
  width: 26px;
  height: auto;
}

/* The three assistants in a triangle, MCP — what joins them — in the middle. */
.alex-news__art--mcp .alex-news__tile--claude { top: 0; left: 20px; transform: rotate(-6deg); }
.alex-news__art--mcp .alex-news__tile--chatgpt { bottom: 0; left: 0; transform: rotate(-8deg); }
.alex-news__art--mcp .alex-news__tile--grok { right: 0; bottom: 2px; transform: rotate(7deg); }

.alex-news__art--mcp .alex-news__tile--mcp {
  top: 54%;
  left: 50%;
  z-index: 1;
  width: 32px;
  height: 32px;
  border-radius: 10px;
  background-color: var(--alex-dark);
  transform: translate(-50%, -50%) rotate(-2deg);
}

/* The MCP mark is drawn grey; on the dark tile it is white. */
.alex-news__art--mcp .alex-news__tile--mcp img {
  filter: brightness(0) invert(1);
}

.alex-news__tile--claude { background-color: #faf9f5; }
/* Grok's mark is a whole app icon, so it fills its tile edge to edge. */
.alex-news__tile--grok { overflow: hidden; background-color: #000; }
.alex-news__tile--grok img { width: 100%; height: 100%; }
.alex-news__tile--mcp img { width: 24px; height: 24px; }

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

/* On the svg itself: the header's rules colour `.brand` ink. */
.alex-news__tile--alex svg {
  width: 20px;
  color: #fff;
}

/* Two tiles: Pennylane's mark, and Alex's leaning on it. */
.alex-news__art--pennylane .alex-news__tile {
  width: 46px;
  height: 46px;
  border-radius: 13px;
}

.alex-news__art--pennylane .alex-news__tile--pennylane { top: 2px; left: 0; transform: rotate(-7deg); }
.alex-news__art--pennylane .alex-news__tile--alex { right: 0; bottom: 2px; transform: rotate(6deg); }

.alex-news__art--pennylane .alex-news__tile--alex svg {
  width: 28px;
}

/*
 * Pennylane's mark, cut out of its wordmark: the file is a 120x22 picture of
 * the two together and the mark is its first 21 pixels.
 */
.alex-news__penny {
  width: 26px;
  height: 26px;
  background: url("/alex/pennylane.svg") no-repeat left center / auto 26px;
  clip-path: inset(0 0 0 0 round 4px);
}

/* The tiles settle as the card comes to the front. */
.alex-news__card:not([data-state="front"]) .alex-news__tile {
  transform: none;
}

.alex-news__card:not([data-state="front"]) .alex-news__art--mcp .alex-news__tile--mcp {
  transform: translate(-50%, -50%);
}

@media (prefers-reduced-motion: reduce) {
  .alex-news__card,
  .alex-news__tile,
  .alex-news__dot,
  .alex-news__art,
  .alex-news__go {
    transition: none;
  }

  .alex-news__dot[aria-current="true"]::after {
    animation: none;
    width: 100%;
  }
}

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

.alex-proof {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;
  max-width: calc(var(--alex-width) - 160px);
  margin-top: 88px;
}

.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);
}

/*
 * One row of logos, drawn twice end to end and slid left by its own width, on
 * a loop. Both copies move together, so when the first has gone by the second
 * is exactly where the first started, and the loop has no seam. The edges fade
 * so logos arrive and leave rather than being cut off.
 */
.alex-proof__marquee {
  display: flex;
  overflow: hidden;
  width: 100%;
  margin-top: 30px;
  -webkit-mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
  mask-image: linear-gradient(90deg, transparent, #000 12%, #000 88%, transparent);
}

.alex-proof__row {
  display: flex;
  flex: none;
  /* Webflow's stylesheet stands every `ul` on end. */
  flex-direction: row;
  align-items: center;
  gap: 72px;
  margin: 0;
  /* The gap between the last logo of one copy and the first of the next. */
  padding: 0 72px 0 0;
  list-style: none;
  animation: alex-marquee 48s linear infinite;
}

@keyframes alex-marquee {
  to { transform: translateX(-100%); }
}

.alex-proof__item {
  display: flex;
  flex: none;
  align-items: center;
  height: 32px;
}

/*
 * 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.
 */
.alex-proof__logo {
  display: block;
  width: auto;
  height: var(--h, 19px);
}

/* Without the slide, one row, wrapped and centred, and no copy. */
@media (prefers-reduced-motion: reduce) {
  .alex-proof__marquee {
    -webkit-mask-image: none;
    mask-image: none;
  }

  .alex-proof__row {
    flex: 1;
    flex-wrap: wrap;
    justify-content: center;
    row-gap: 24px;
    padding: 0;
    animation: none;
  }

  .alex-proof__row[aria-hidden="true"] {
    display: none;
  }
}

/* --- 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-x: hidden;
  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;
}

/* A customer story: its own page centres a 580px column in a padded section,
   and the sheet is that section now — a wide card with the column at the
   width it always has, and air either side of it. */
.alex-reader:has(.success-article) .alex-reader__bar,
.alex-reader:has(.success-article) .alex-reader__body {
  max-width: 980px;
}

/* Webflow gives the article `width: 100%`; with the padding added on top that
   is wider than the card, and on a phone the whole sheet slid sideways.
   `width: auto` fills what is left inside the padding, up to the 580px column
   it always has. */
.alex-reader .success-article {
  box-sizing: content-box;
  width: auto;
  margin: 0 auto;
  padding: 24px var(--alex-gutter) 88px;
}

/* 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) {
  /* Edge to edge on a phone: the card is the screen, less a strip at the top
     that shows it is laid over the page. */
  .alex-reader__bar,
  .alex-reader__body {
    width: 100%;
  }

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

  .alex-reader__body {
    min-height: calc(100svh - 12px - 48px);
    margin-bottom: 0;
    border-radius: 0;
  }

  .alex-reader .success-article {
    padding: 8px 16px 64px;
  }

  .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;
}

/* The quotation marks are drawn here, not typed into the sentence: the words
   stay exactly what was said, and the phrasebook's keys with them. */
.alex-quotes__quote {
  quotes: "“" "”";
}

.alex-quotes__quote::before {
  content: open-quote;
}

.alex-quotes__quote::after {
  content: close-quote;
}

.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 {
  display: block;
  height: auto;
  max-height: 32px;
  width: auto;
  margin: 0 auto 32px;
}

/* A customer whose logo we do not hold: the name, in the logo's place. */
.alex-quotes__company {
  margin: 0 auto 32px;
  color: var(--alex-ink);
  font-size: 18px;
  font-weight: 600;
  line-height: 32px;
  letter-spacing: -0.01em;
  text-align: center;
}

.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;
}

/*
 * The dots, and the one that is a bar.
 *
 * The current quote's dot stretches into a pill and fills from the left over
 * the four seconds the quote is on screen — how long is left, drawn rather
 * than guessed. The timer in alex.js runs for the same four seconds.
 */
.alex-quotes__dots {
  align-items: center;
}

.alex-quotes__dot {
  position: relative;
  overflow: hidden;
  width: 8px;
  height: 8px;
  padding: 0;
  background-color: #2b2c3033;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  transition: width 0.3s ease, background-color 0.18s ease;
}

.alex-quotes__dot:hover {
  background-color: #2b2c3059;
}

.alex-quotes__dot[aria-current="true"] {
  width: 36px;
}

.alex-quotes__dot[aria-current="true"]::after {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 100%;
  border-radius: inherit;
  background-color: var(--alex-ink);
  animation: alex-quote-fill 4s linear forwards;
}

[data-still] .alex-quotes__dot[aria-current="true"]::after {
  animation: none;
}

@keyframes alex-quote-fill {
  from { width: 8px; }
  to { width: 100%; }
}

/* 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;
  }
}

/* --- Tabs in a guide -------------------------------------------------------- */

/*
 * A section's sub-subheadings drawn as tabs (`tabbed` in lib/site/render.ts).
 * Until alex.js marks the block ready, the tab row is hidden and every panel
 * shows with its own heading — the page reads top to bottom without a script.
 * Ready, the row shows, one panel shows, and the headings the tabs repeat go.
 */
.alex-tabs {
  margin: 8px 0 24px;
}

.alex-tabs__list {
  display: none;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 20px;
  padding: 4px;
  border-radius: 12px;
  background-color: #2b2c300d;
}

.alex-tabs.is-ready .alex-tabs__list {
  display: flex;
}

.alex-tabs__tab {
  display: inline-flex;
  flex: 1 1 auto;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 36px;
  padding: 7px 14px;
  border: 0;
  border-radius: 9px;
  background: none;
  color: var(--alex-ink-2);
  font: inherit;
  font-size: 14px;
  line-height: 18px;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;
}

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

.alex-tabs__tab[aria-selected="true"] {
  background-color: #fff;
  color: #000;
  box-shadow: 0 1px 2px #0000000f, 0 2px 8px #0000000a;
}

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

.alex-tabs__tab img {
  flex: none;
  width: 18px;
  height: 18px;
  border-radius: 5px;
}

.alex-tabs.is-ready .alex-tabs__panel[hidden] {
  display: none;
}

.alex-tabs.is-ready .alex-tabs__panel > h3:first-child {
  display: none;
}

/* Inside a tab, a sub-heading opens a new part of the instructions: room above
   it, and close to what it introduces. */
/* Drawn like the section headings (16px, semibold, ink), a step smaller —
   Webflow's 18px grey h4 outranked the section it sits in. */
.w-richtext .alex-tabs__panel h4 {
  margin: 32px 0 10px;
  color: var(--alex-ink);
  font-size: 15px;
  font-weight: 600;
  line-height: 21px;
}

.w-richtext .alex-tabs__panel > h4:first-child,
.w-richtext .alex-tabs__panel > h3:first-child + h4,
.w-richtext .alex-tabs__panel > h3:first-child + p + h4 {
  margin-top: 16px;
}

/* Without the row, each panel is its own part of the section. */
.alex-tabs:not(.is-ready) .alex-tabs__panel + .alex-tabs__panel {
  margin-top: 28px;
}

/* --- Text to copy, in a guide --------------------------------------------------- */

/*
 * A prompt to give an assistant, or an address or command to paste
 * (`copyable` in lib/site/render.ts): a quiet grey block with its button on the
 * right, the same for both so a reader learns the shape once.
 */
.alex-copy {
  display: flex;
  align-items: flex-start;
  gap: 12px;
  margin: 10px 0;
  padding: 10px 10px 10px 14px;
  border: 1px solid #2b2c300f;
  border-radius: 10px;
  background-color: #2b2c300a;
}

.alex-copy + .alex-copy {
  margin-top: 8px;
}

/* Mono, so what is to be typed or pasted reads as such, set apart from the
   copy around it. */
.w-richtext .alex-copy__text,
.alex-copy__text,
.w-richtext .alex-copy pre,
.alex-copy pre {
  flex: 1;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  color: var(--alex-ink);
  font-family: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 13px;
  line-height: 21px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.alex-copy pre code {
  padding: 0;
  background: none;
  font: inherit;
}

/* Just the mark: no box, no label. The label is the aria-label. */
.alex-copy__button {
  display: grid;
  flex: none;
  place-items: center;
  width: 24px;
  height: 24px;
  margin: -2px -4px -2px 0;
  padding: 0;
  border: 0;
  border-radius: 6px;
  background: none;
  color: #2b2c3080;
  cursor: pointer;
  transition: color 0.12s ease, background-color 0.12s ease;
}

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

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

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

.alex-copy__button svg {
  grid-area: 1 / 1;
}

.alex-copy__done,
.alex-copy__button.is-copied .alex-copy__icon {
  visibility: hidden;
}

.alex-copy__button.is-copied .alex-copy__done {
  visibility: visible;
}

.alex-copy__button.is-copied {
  color: #1a7f37;
}

/* --- 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 {
    min-height: 0;
    padding-top: 32px;
    padding-bottom: 64px;
  }

  .alex-hero__title {
    margin-top: 48px;
    font-size: 36px;
    line-height: 42px;
  }

  .alex-news__link {
    gap: 16px;
    padding: 12px 16px 12px 12px;
  }

  .alex-news__title {
    font-size: 15px;
    line-height: 20px;
  }

  .alex-news__text {
    font-size: 14px;
    line-height: 19px;
  }

  .alex-proof {
    margin-top: 56px;
  }

  .alex-proof__row {
    gap: 48px;
    padding-right: 48px;
  }

  .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;
  }
}

/* --- 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));
}

/*
 * The wire, as two halves that meet in the middle: out of Alex, a rounded
 * turn down (or up), and a rounded turn into the dot. Each half is a box with
 * two of its borders drawn and the corner between them rounded; the halves
 * share the vertical stroke. Above the middle row the whole thing is flipped.
 */
.alex-int__wire span {
  --h: max(var(--offset), calc(var(--offset) * -1), 0px);
  position: absolute;
  inset: 0;
}

.alex-int__wire i {
  position: absolute;
  box-sizing: border-box;
  border: 0 solid #c9cad3;
  transition: height 0.32s cubic-bezier(0.3, 0.7, 0.2, 1), top 0.32s cubic-bezier(0.3, 0.7, 0.2, 1);
}

.alex-int__wire i:first-child {
  left: 0;
  width: calc(50% + 1.5px);
  top: calc(50% - 0.75px);
  height: calc(var(--h) / 2 + 1.5px);
  border-top-width: 1.5px;
  border-right-width: 1.5px;
  border-top-right-radius: 12px;
}

.alex-int__wire i:last-child {
  left: 50%;
  right: 8px;
  top: calc(50% + var(--h) / 2 - 0.75px);
  height: calc(var(--h) / 2 + 1.5px);
  border-left-width: 1.5px;
  border-bottom-width: 1.5px;
  border-bottom-left-radius: 12px;
}

.alex-int[data-active="0"] .alex-int__wire span,
.alex-int[data-active="1"] .alex-int__wire span {
  transform: scaleY(-1);
}

/* On the middle row there is no turn to make: one straight line. */
.alex-int[data-active="2"] .alex-int__wire i:first-child {
  width: calc(100% - 8px);
  border-right-width: 0;
  border-radius: 0;
}

.alex-int[data-active="2"] .alex-int__wire i:last-child {
  display: none;
}

.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;
}

/* The category as small grey capsules, one per kind. */
.alex-int__kind {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 0 0 12px;
}

.alex-int__kind span {
  padding: 3px 10px;
  border-radius: 999px;
  background: #2b2c300d;
  color: #6b6c73;
  font-size: 12px;
  font-weight: 500;
  line-height: 16px;
}

.alex-int__pitch strong {
  color: var(--alex-ink);
  font-weight: 600;
}

.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;
  }
}

/* --- A release that ends on an action -------------------------------------- */

/* Sticky to the foot of whatever is scrolling — the page, or the reading sheet
   when the homepage opens the article there. See RELEASE_CTA in Release.tsx. */
.alex-post__cta {
  position: sticky;
  bottom: 20px;
  z-index: 5;
  display: flex;
  justify-content: center;
  margin-top: 48px;
  pointer-events: none;
}

.alex-post__cta-btn {
  pointer-events: auto;
  padding: 14px 26px;
  font-size: 15px;
  font-weight: 600;
  background-color: var(--alex-ink);
  border-color: var(--alex-ink);
  color: #fff;
  box-shadow: 0 10px 30px rgba(20, 20, 40, 0.22);
}

.alex-post__cta-btn:hover {
  background-color: #000;
  color: #fff;
}

/* --- Never bold ------------------------------------------------------------ */

/* Semi-bold is the heaviest weight on the site. Webflow's stylesheets (and
   normalize's `bolder`) set these to 700; they are overridden here rather than
   edited, because `npm run site:import` rewrites /site. */
b,
strong,
h1,
h2,
h3,
h4,
h5,
h6,
label,
.text-span-3,
.cell.sign,
.error-title,
.story-number,
.div-block-21,
.title-conclustion,
.tite-man,
.story-kpi {
  font-weight: 600;
}

/* --- The customers wall ------------------------------------------------------ */

/*
 * lib/site/wall.ts writes one tile of cells — logos, stories, quotes, and the
 * headline across four of them — ruled off like a table; alex.js repeats it
 * in every direction and moves it under the pointer. Everything that makes it
 * a canvas hangs off `data-alex-wall`, which only the script sets: without it
 * the tile is a plain grid down the page.
 *
 * Each cell draws its own right and bottom rule and nothing else, so cells
 * side by side share one line, and so do two copies of the tile.
 */
/* The site's own grey ground, as on every other page. */
.alex-wall {
  --alex-wall-line: #e6e6e9;
  position: relative;
  background-color: #fafafa;
}

.alex-wall__tile {
  box-sizing: border-box;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  max-width: calc(var(--alex-width) + var(--alex-gutter) * 2);
  margin: 0 auto;
  padding: 0 var(--alex-gutter) 64px;
  list-style: none;
}

.alex-wall__item {
  box-sizing: border-box;
  display: flex;
  min-width: 0;
  min-height: 320px;
  border-right: 1px solid var(--alex-wall-line);
  border-bottom: 1px solid var(--alex-wall-line);
}

.alex-wall__item--intro {
  grid-column: 1 / -1;
  min-height: 0;
  border: 0;
}

.alex-wall__item--logo {
  align-items: center;
  justify-content: center;
  min-height: 160px;
}

/* A logo's window onto its own ink — see `mark` in lib/site/wall.ts. The
   file inside is larger than the window and shifted, so its margins fall
   outside and are clipped. */
.alex-wall__mark {
  display: block;
  flex: none;
  overflow: hidden;
  user-select: none;
}

.alex-wall__mark img {
  display: block;
  max-width: none;
}

/* The two files that are a white box round the mark: multiplied, the box
   goes. Only those — see `flat` in lib/site/wall.ts. */
.alex-wall__mark--flat img {
  mix-blend-mode: multiply;
}

/* --- The headline ------------------------------------------------------------ */

.alex-wall__intro {
  box-sizing: border-box;
  padding: 56px 0 32px;
}

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

.alex-wall__accent {
  color: var(--alex-purple);
  font-family: "PT Serif", Georgia, serif;
  font-style: italic;
  font-weight: 400;
}

/* --- The cells ---------------------------------------------------------------- */

.alex-wall__card {
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  width: 100%;
  padding: 28px;
  color: var(--alex-ink);
  text-decoration: none;
  user-select: none;
  -webkit-user-drag: none;
  transition: background-color 0.15s ease;
}

.alex-wall__card:hover {
  background-color: #f5f5f6;
}

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

/* A story is a card in its cell: white on the grey ground, the logo at the
   top and the figure and its line at the foot. The whole card is the link. */
.alex-wall__card--story {
  flex: 1;
  width: auto;
  margin: 12px;
  padding: 24px;
  gap: 20px;
  border: 1px solid var(--alex-hairline-2);
  border-radius: 16px;
  background-color: #fff;
  box-shadow: 0 1px 2px #0000000a;
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
}

.alex-wall__card--story:hover {
  background-color: #fff;
  border-color: #00000017;
  box-shadow: 0 1px 2px #0000000a, 0 10px 28px #0000000f;
}

.alex-wall__body {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: auto;
}

.alex-wall__figure {
  color: var(--alex-ink);
  font-size: 52px;
  font-weight: 600;
  line-height: 1;
  letter-spacing: -0.03em;
}

.alex-wall__line {
  color: var(--alex-ink-2);
  font-size: 15px;
  line-height: 22px;
}

/* "Lire l'histoire": a small plain button. The card is the link; this only
   says so. */
.alex-wall__read {
  align-self: flex-start;
  padding: 5px 11px;
  border: 1px solid #0000001a;
  border-radius: 7px;
  background-color: #fff;
  color: var(--alex-ink);
  font-size: 13px;
  font-weight: 500;
  line-height: 16px;
  transition: background-color 0.15s ease, border-color 0.15s ease;
}

.alex-wall__card--story:hover .alex-wall__read {
  border-color: #00000029;
  background-color: #f7f7f8;
}

/* A story with no figure says it in its line, a size up. */
.alex-wall__line:only-child {
  color: var(--alex-ink);
  font-size: 19px;
  line-height: 26px;
}

/* Every blockquote on this site is a tinted card in Webflow's stylesheet;
   this one is plain type, set in the serif. */
.alex-wall__quote {
  flex: 1;
  margin: 0;
  padding: 0;
  background: none;
  border: 0;
  border-radius: 0;
  color: inherit;
  font-family: "PT Serif", Georgia, serif;
  font-size: 19px;
  font-weight: 400;
  line-height: 27px;
  letter-spacing: -0.005em;
  quotes: "“" "”";
}

.alex-wall__card--short .alex-wall__quote {
  font-size: 25px;
  line-height: 34px;
  letter-spacing: -0.01em;
}

.alex-wall__quote::before {
  content: open-quote;
}

.alex-wall__quote::after {
  content: close-quote;
}

.alex-wall__who {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
}

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

.alex-wall__name {
  display: flex;
  flex-direction: column;
  min-width: 0;
}

.alex-wall__person {
  font-size: 14px;
  font-weight: 600;
  line-height: 18px;
}

.alex-wall__role {
  color: var(--alex-ink-2);
  font-size: 13px;
  line-height: 17px;
}

/* --- The canvas ------------------------------------------------------------ */

/* The wall fills the window and runs up under the header, whose own blur
   (Webflow's .head, sticky at z-index 100) is what frames it. */
.alex-wall[data-alex-wall] {
  height: 100svh;
  min-height: 480px;
  margin-top: calc(-1 * var(--alex-wall-top, 64px));
  overflow: hidden;
}

.alex-wall[data-alex-wall] .alex-wall__view {
  position: absolute;
  inset: 0;
  overflow: hidden;
  cursor: grab;
  touch-action: none;
  outline: none;
}

.alex-wall[data-alex-wall] .alex-wall__view:focus-visible {
  box-shadow: inset 0 0 0 2px var(--alex-purple);
}

.alex-wall[data-dragging] .alex-wall__view,
.alex-wall[data-dragging] .alex-wall__card {
  cursor: grabbing;
}

.alex-wall[data-dragging] .alex-wall__card:hover {
  background-color: transparent;
}

.alex-wall[data-alex-wall] .alex-wall__tile {
  transform-origin: 0 0;
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  width: var(--tile-w);
  height: var(--tile-h);
  max-width: none;
  margin: 0;
  padding: 0;
  will-change: transform;
}

.alex-wall[data-alex-wall] .alex-wall__item {
  position: absolute;
  top: var(--y);
  left: var(--x);
  width: var(--cell-w);
  height: var(--cell-h);
  min-height: 0;
}

/* A logo takes half a slot. */
.alex-wall[data-alex-wall] .alex-wall__item--logo {
  height: calc(var(--cell-h) / 2);
}

/* The headline's cell: a slot tall and two wide, ruled like the rest, its
   text in the middle. */
.alex-wall[data-alex-wall] .alex-wall__item--intro {
  align-items: center;
  justify-content: center;
  width: var(--w);
  height: var(--h);
  border-right: 1px solid var(--alex-wall-line);
  border-bottom: 1px solid var(--alex-wall-line);
  cursor: default;
}

.alex-wall[data-alex-wall] .alex-wall__intro {
  width: 600px;
  max-width: calc(100vw - 48px);
  padding: 0;
  text-align: center;
}

/* Medium rather than semi-bold: at this length the headline is a sentence to
   read, not a word to shout. The figure takes a line of its own above it. */
.alex-wall[data-alex-wall] .alex-wall__title {
  font-size: 32px;
  font-weight: 500;
  line-height: 1.2;
  text-wrap: balance;
}

.alex-wall__title .alex-wall__accent {
  display: block;
  margin-bottom: 4px;
  font-family: inherit;
  font-style: normal;
  font-weight: 600;
}

/* The counter: the real figure keeps its place (and its width) while the
   running digits are drawn over it, right-aligned so "sociétés" never moves. */
.alex-wall__count {
  position: relative;
  display: inline-block;
  font-variant-numeric: tabular-nums;
}

.alex-wall__count-now {
  position: absolute;
  inset: 0;
  display: flex;
  justify-content: flex-end;
  align-items: flex-start;
  white-space: nowrap;
}

/* The odometer (alex.js): a window one digit tall over a column of digits.
   The window reaches a little past the digit above and below and fades out
   there, so a turning digit rolls in and out of sight rather than being cut
   off at a hard edge; at rest the neighbours are too far off to show. */
.alex-odo {
  box-sizing: content-box;
  display: block;
  height: 1.2em;
  margin: -0.3em 0;
  padding: 0.3em 0;
  overflow: hidden;
  /* Clear for the outer tenth of an em, where a resting neighbour's edge
     would sit, then fading up to full over the next fifth. */
  -webkit-mask-image: linear-gradient(to bottom, transparent 0.1em, #000 0.3em, #000 calc(100% - 0.3em), transparent calc(100% - 0.1em));
  mask-image: linear-gradient(to bottom, transparent 0.1em, #000 0.3em, #000 calc(100% - 0.3em), transparent calc(100% - 0.1em));
  transition: opacity 0.4s ease;
}

.alex-odo[data-lead] {
  opacity: 0;
}

.alex-odo__strip {
  display: block;
  will-change: transform;
}

.alex-odo__strip > span {
  display: block;
  height: 1.2em;
  line-height: 1.2em;
  text-align: center;
}

.alex-odo__gap {
  display: block;
  width: 0.26em;
}

.alex-wall__count[data-counting] .alex-wall__count-to {
  visibility: hidden;
}

/* --- Opening --------------------------------------------------------------- */

/* The headline first, then the cells rippling out from it (--in, from
   lib/site/wall.ts), then the joystick. Only once the script has made the
   wall a canvas: without it there is nothing to wait for. */
@keyframes alex-wall-in {
  from {
    opacity: 0;
    transform: translateY(14px) scale(0.985);
  }
}

@keyframes alex-stick-in {
  from {
    opacity: 0;
    transform: translateX(-50%) translateY(16px) scale(0.6);
  }
}

/* `data-opening` is on for the first moments only, so a repeat of the tile
   made later, as the wall is dragged, is simply there. */
.alex-wall[data-opening] .alex-wall__item {
  animation: alex-wall-in 0.7s cubic-bezier(0.2, 0.7, 0.3, 1) both;
  animation-delay: var(--in, 0ms);
}

.alex-wall[data-alex-wall] .alex-stick {
  animation: alex-stick-in 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 0.9s both;
}

@media (prefers-reduced-motion: reduce) {
  .alex-wall[data-opening] .alex-wall__item,
  .alex-wall[data-alex-wall] .alex-stick {
    animation: none;
  }
}

/* No cookie line over the wall: its bottom edge is where the joystick is,
   and the page is one screen with nothing under it to scroll to. Nothing is
   lost by it — until someone answers, analytics runs in Consent Mode's denied
   default and writes no cookie (lib/site/consent.ts); the line still asks on
   every other page. */
body:has(.alex-wall) .alex-consent {
  display: none !important;
}

/* --- The joystick ------------------------------------------------------------ */

/*
 * A frosted puck with a purple knob. Push the knob and the wall moves that
 * way, faster the further it goes; let go and it springs home. The glow in
 * the base follows the knob (--sx, --sy, from -1 to 1, set by alex.js) and
 * the arrow on the side being pushed lights up. The arrows are buttons too:
 * one press, one cell.
 */
.alex-stick {
  display: none;
}

.alex-wall[data-alex-wall] .alex-stick {
  --sx: 0;
  --sy: 0;
  position: absolute;
  bottom: 28px;
  left: 50%;
  z-index: 5;
  display: block;
  transform: translateX(-50%);
}

.alex-stick__base {
  position: relative;
  width: 84px;
  height: 84px;
  border-radius: 999px;
  /* Smoked glass: dark enough to stand off a white table, clear enough to
     see the wall slide under it. */
  background: radial-gradient(circle at 50% 30%, #232427e6, #121214eb 72%);
  box-shadow:
    0 14px 32px #12121440,
    0 2px 6px #12121426,
    inset 0 1px 0 #ffffff12,
    inset 0 0 0 1px #ffffff0d,
    inset 0 -6px 14px #00000066;
  -webkit-backdrop-filter: blur(12px) saturate(140%);
  backdrop-filter: blur(12px) saturate(140%);
}

/* An invitation, until the first push: a ring breathing out from the base. */
.alex-stick__base::before {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  border: 1.5px solid #685bff80;
  pointer-events: none;
  animation: alex-stick-breathe 2.8s ease-out infinite;
}

.alex-stick[data-used] .alex-stick__base::before {
  animation: none;
  opacity: 0;
}

@keyframes alex-stick-breathe {
  0% {
    transform: scale(1);
    opacity: 0.9;
  }
  70%,
  100% {
    transform: scale(1.35);
    opacity: 0;
  }
}

.alex-stick__glow {
  position: absolute;
  inset: 4px;
  border-radius: inherit;
  background: radial-gradient(
    circle at calc(50% + var(--sx) * 34%) calc(50% + var(--sy) * 34%),
    #685bff8c,
    transparent 60%
  );
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.25s ease;
}

.alex-stick[data-held] .alex-stick__glow {
  opacity: 1;
}

/* The arrows: a small chevron at each point of the compass. */
.alex-stick__arrow {
  position: absolute;
  width: 22px;
  height: 22px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  color: #ffffff59;
  cursor: pointer;
  transition: color 0.15s ease, transform 0.2s cubic-bezier(0.34, 1.56, 0.64, 1);
}

.alex-stick__arrow::before {
  content: "";
  position: absolute;
  inset: 0;
  background-color: currentColor;
  -webkit-mask: 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.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 14l4-4 4 4'/%3E%3C/svg%3E") center / 14px no-repeat;
  mask: 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.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M8 14l4-4 4 4'/%3E%3C/svg%3E") center / 14px no-repeat;
}

.alex-stick__arrow--up {
  top: 1px;
  left: calc(50% - 11px);
}

.alex-stick__arrow--right {
  top: calc(50% - 11px);
  right: 1px;
  rotate: 90deg;
}

.alex-stick__arrow--down {
  bottom: 1px;
  left: calc(50% - 11px);
  rotate: 180deg;
}

.alex-stick__arrow--left {
  top: calc(50% - 11px);
  left: 1px;
  rotate: -90deg;
}

.alex-stick__arrow:hover,
.alex-stick__arrow:focus-visible,
.alex-stick[data-lean~="up"] .alex-stick__arrow--up,
.alex-stick[data-lean~="right"] .alex-stick__arrow--right,
.alex-stick[data-lean~="down"] .alex-stick__arrow--down,
.alex-stick[data-lean~="left"] .alex-stick__arrow--left {
  color: #fff;
  transform: translateY(-2px);
}

.alex-stick__arrow:focus-visible {
  outline: 2px solid #fff;
  outline-offset: -2px;
}

/* The knob: glossy, lit from above, and it leans the way it is pushed. */
.alex-stick__knob {
  position: absolute;
  top: calc(50% - 16px);
  left: calc(50% - 16px);
  width: 32px;
  height: 32px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background:
    radial-gradient(circle at 36% 30%, #ffffff47 0 10%, transparent 38%),
    radial-gradient(circle at 50% 60%, #7c70ff, #5a4bf0 70%, #4a3bd9);
  box-shadow:
    0 6px 14px #685bff73,
    0 2px 4px #00000066,
    inset 0 -3px 5px #2b1fa84d,
    inset 0 1px 1px #ffffff33;
  cursor: grab;
  touch-action: none;
  transform: translate(var(--kx, 0px), var(--ky, 0px));
  /* Home again with a little overshoot, like a stick on a spring. */
  transition: transform 0.5s cubic-bezier(0.34, 1.8, 0.64, 1), box-shadow 0.2s ease, scale 0.2s ease;
}

.alex-stick__knob:hover {
  scale: 1.06;
}

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

.alex-stick[data-held] .alex-stick__knob {
  cursor: grabbing;
  scale: 0.94;
  transition: box-shadow 0.2s ease, scale 0.2s ease;
  box-shadow:
    calc(var(--sx) * -5px) calc(8px + var(--sy) * -5px) 18px #685bffa6,
    0 2px 4px #00000066,
    inset 0 -3px 5px #2b1fa84d,
    inset 0 1px 1px #ffffff33;
}

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

  .alex-stick__knob {
    transition: none;
  }
}

/* A smaller window, a smaller table: at 1000px the full-size cells show
   three across and the headline's crowds the rest out. alex.js reads the
   scale to know how far a tile reaches. */
@media (max-width: 1100px) {
  .alex-wall {
    --alex-wall-scale: 0.8;
  }
}

@media (max-width: 767px) {
  /* The table at three quarters, so a phone shows more than the headline's
     cell. */
  .alex-wall {
    --alex-wall-scale: 0.75;
  }

  .alex-wall__title {
    font-size: 30px;
  }

  /* Sizes here are before the three-quarter scale: 38px is drawn at 28. */
  .alex-wall[data-alex-wall] .alex-wall__title {
    font-size: 38px;
  }

  .alex-wall[data-alex-wall] .alex-wall__intro {
    width: 420px;
    max-width: none;
  }

  .alex-wall[data-alex-wall] .alex-stick {
    bottom: 20px;
  }

  /* Quotes a size down on a phone; these are before the three-quarter
     scale, so 17px is drawn at about 13. */
  .alex-wall__quote {
    font-size: 17px;
    line-height: 25px;
  }

  .alex-wall__card--short .alex-wall__quote {
    font-size: 21px;
    line-height: 29px;
  }
}

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