/* triboo.site. Phone first: the phone layout is the base and the desktop one
   starts at 761px wide when the screen is wider than 4:5, the same query as
   the 3D (src/main.js, src/bracelet.js). "story" on <html> means the light
   bracelet is coming: panels leave room for it (on the phone the copy of each
   beat holds in the lower part of the screen, under the light), and the hero
   is only the band at first, its copy comes in as the page starts to move.
   Without it (no JavaScript, reduced motion, no WebGL) the page is compact
   and complete at rest: the static posters of the bracelet and of the card,
   and the hero copy. "js" (assets/gate.js) shows the interactive parts;
   "intro-play" runs the opening of the logo. */

@font-face {
  font-family: "MuseoModerno";
  src: url("../fonts/museomoderno-latin-var.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("../fonts/poppins-latin-400.woff2") format("woff2");
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Poppins";
  src: url("../fonts/poppins-latin-600.woff2") format("woff2");
  font-weight: 600;
  font-style: normal;
  font-display: swap;
}
/* Local fallbacks sized like the real fonts (measured against Arial), so the
   swap does not move text. */
@font-face {
  font-family: "Poppins fallback";
  src: local("Arial"), local("ArialMT");
  font-weight: 400;
  size-adjust: 111.8%;
  ascent-override: 93.9%;
  descent-override: 31.3%;
  line-gap-override: 8.9%;
}
@font-face {
  font-family: "Poppins fallback";
  src: local("Arial Bold"), local("Arial-BoldMT");
  font-weight: 600;
  size-adjust: 106.4%;
  ascent-override: 98.7%;
  descent-override: 32.9%;
  line-gap-override: 9.4%;
}
@font-face {
  font-family: "MuseoModerno fallback";
  src: local("Arial"), local("ArialMT");
  size-adjust: 108.6%;
  ascent-override: 105.9%;
  descent-override: 41.5%;
  line-gap-override: 0%;
}

:root {
  --midnight: #000624;
  --violet: #8170ff;
  --violet-hover: #9587ff;
  --lilac: #b5aaff;
  --ice: #f7f7fa;
  --text-2: rgba(247, 247, 250, 0.78);
  --text-3: rgba(247, 247, 250, 0.6);
  --line: rgba(247, 247, 250, 0.13);
  --surface: #0b103c;
  --o1: #8780f4;
  --o2: #8a72f3;
  --o3: #9f65eb;
  --danger: #ffb4c0;
  --gutter: clamp(22px, 6vw, 112px);
  --bar-h: 64px;
  --radius: 28px;
  /* room kept free at the bottom of the screen for the floating button */
  --fab-room: calc(env(safe-area-inset-bottom, 0px) + 84px);
  --ease: cubic-bezier(0.22, 0.8, 0.24, 1);
  --head: "MuseoModerno", "MuseoModerno fallback", ui-rounded, system-ui, sans-serif;
  --text: "Poppins", "Poppins fallback", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  color-scheme: dark;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}
html {
  background: var(--midnight);
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  scroll-padding-top: calc(var(--bar-h) + 12px);
}
@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}
body {
  margin: 0;
  min-height: 100vh;
  background: var(--midnight);
  color: var(--ice);
  font-family: var(--text);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overflow-x: hidden;
  overflow-x: clip;
}
img {
  display: block;
  max-width: 100%;
  height: auto;
}
h1,
h2,
h3 {
  margin: 0;
  font-family: var(--head);
  font-weight: 500;
  letter-spacing: -0.015em;
  text-wrap: balance;
}
p {
  margin: 0;
  text-wrap: pretty;
}
ul,
ol {
  margin: 0;
  padding: 0;
  list-style: none;
}
a {
  color: inherit;
  text-underline-offset: 0.22em;
  text-decoration-thickness: 1px;
}
button {
  font: inherit;
  color: inherit;
}
:focus-visible {
  outline: 2px solid var(--ice);
  outline-offset: 3px;
  border-radius: 6px;
}
::selection {
  background: var(--violet);
  color: var(--midnight);
}
.js .nojs-only,
html:not(.js) .js-only {
  display: none !important;
}

.skip {
  position: fixed;
  left: 12px;
  top: 12px;
  z-index: 30;
  padding: 12px 20px;
  border-radius: 999px;
  background: var(--ice);
  color: var(--midnight);
  font-weight: 600;
  text-decoration: none;
  transform: translateY(-180%);
  transition: transform 0.25s var(--ease);
}
.skip:focus {
  transform: none;
}

/* ---------- the light: live canvas and static poster ---------- */
.stage {
  position: fixed;
  left: 0;
  top: 0;
  z-index: 0;
  display: block;
  width: 100%;
  height: 100vh;
  height: 100lvh;
  pointer-events: none;
  opacity: 0;
}
.stage-live .stage {
  opacity: 1;
}
/* The posters are frames of the 3D, rendered once. The live light reads the
   box of the hero band (and of the contact band on the phone) and fills it,
   so it takes over in place. The glow behind is the scene's glow, as a
   gradient. */
.light {
  position: relative;
  aspect-ratio: 1;
}
.light::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: radial-gradient(
    closest-side,
    rgba(122, 50, 255, 0.315) 0%,
    rgba(120, 48, 255, 0.298) 13.3%,
    rgba(115, 42, 255, 0.248) 26.6%,
    rgba(108, 34, 255, 0.194) 37.2%,
    rgba(96, 25, 255, 0.136) 47.8%,
    rgba(76, 16, 255, 0.083) 58.5%,
    rgba(60, 1, 255, 0.036) 69.1%,
    rgba(60, 1, 255, 0) 80%
  );
}
.light img {
  position: relative;
  width: 100%;
  height: 100%;
}

/* ---------- header ---------- */
.bar {
  position: fixed;
  z-index: 20;
  left: 0;
  right: 0;
  top: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  height: calc(var(--bar-h) + env(safe-area-inset-top, 0px));
  padding: env(safe-area-inset-top, 0px) var(--gutter) 0;
  background: var(--midnight);
  transition: opacity 0.3s var(--ease);
}
.bar::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  height: 24px;
  background: linear-gradient(var(--midnight), rgba(0, 6, 36, 0));
  pointer-events: none;
}
.bar__logo {
  display: block;
  margin-right: auto;
  padding: 12px 0;
}
.bar__logo img {
  width: 124px;
}
.bar__nav {
  display: none;
}

/* ---------- buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 52px;
  padding: 0 24px;
  border: 1px solid transparent;
  border-radius: 999px;
  background: none;
  font-family: var(--text);
  font-weight: 600;
  font-size: 1rem;
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  transition:
    background-color 0.25s var(--ease),
    border-color 0.25s var(--ease),
    opacity 0.25s var(--ease),
    transform 0.2s var(--ease);
}
.btn:active {
  transform: scale(0.98);
}
.btn:focus-visible {
  border-radius: 999px;
  outline-offset: 4px;
}
.btn--primary {
  background: var(--violet);
  color: var(--midnight);
}
.btn--primary:hover {
  background: var(--violet-hover);
}
.btn--ghost {
  border-color: rgba(247, 247, 250, 0.36);
  color: var(--ice);
}
.btn--ghost:hover {
  border-color: var(--ice);
  background: rgba(247, 247, 250, 0.06);
}
/* the hero's way down: on the phone a quiet text link with an arrow, so the
   floating button stays the one action on screen; a ghost pill on desktop */
.btn__arrow {
  flex: none;
  margin-left: 8px;
}
.btn--down {
  min-height: 44px;
  padding: 0;
  border-color: transparent;
  color: var(--text-2);
  text-decoration: underline;
  text-decoration-color: rgba(247, 247, 250, 0.32);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.3em;
}
.btn--down:hover {
  border-color: transparent;
  background: none;
  color: var(--ice);
  text-decoration-color: currentColor;
}
.btn--down:focus-visible {
  border-radius: 6px;
  outline-offset: 2px;
}

/* ---------- the floating button: clear glass, always at hand ----------
   Web approximation of Apple's glass material: almost no fill, so the page
   and the light show through, blurred and saturated (backdrop-filter); a
   hairline rim, brighter at the top (::before), a soft inner glow and shadow.
   The backdrop is also a little darker under the glass, so the white label
   reads on the midnight page and on the violet light; over light content
   (the event photos: data-bright, src/main.js) the glass
   turns darker ("fab-dense"), and stays so without JavaScript. Opaque where
   the browser cannot blur, or when transparency is turned down. */
.fab {
  position: fixed;
  z-index: 15;
  left: 50%;
  bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 52px;
  padding: 0 22px 0 16px;
  border: 0;
  border-radius: 999px;
  background:
    radial-gradient(140% 100% at 50% 0%, rgba(255, 255, 255, 0.12), rgba(255, 255, 255, 0) 62%),
    rgba(214, 208, 255, 0.04);
  -webkit-backdrop-filter: blur(14px) saturate(170%) brightness(0.84);
  backdrop-filter: blur(14px) saturate(170%) brightness(0.84);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.3),
    inset 0 -1px 1px rgba(255, 255, 255, 0.05),
    inset 0 0 16px rgba(214, 208, 255, 0.08),
    0 10px 30px rgba(0, 3, 20, 0.36),
    0 1px 3px rgba(0, 3, 20, 0.24);
  color: #fff;
  font-weight: 600;
  font-size: 0.9875rem;
  line-height: 1.2;
  white-space: nowrap;
  text-decoration: none;
  text-shadow:
    0 1px 2px rgba(0, 3, 20, 0.5),
    0 0 14px rgba(0, 3, 20, 0.3);
  transform: translateX(-50%);
  transition:
    opacity 0.35s var(--ease),
    transform 0.35s var(--ease),
    background-color 0.3s var(--ease),
    box-shadow 0.3s var(--ease),
    -webkit-backdrop-filter 0.3s var(--ease),
    backdrop-filter 0.3s var(--ease);
}
/* the rim: a hairline of light, bright at the top, faint on the sides */
.fab::before {
  content: "";
  position: absolute;
  inset: 0;
  padding: 1px;
  border-radius: inherit;
  background: linear-gradient(
    180deg,
    rgba(255, 255, 255, 0.58),
    rgba(255, 255, 255, 0.14) 40%,
    rgba(255, 255, 255, 0.07) 60%,
    rgba(255, 255, 255, 0.24)
  );
  -webkit-mask:
    linear-gradient(#000 0 0) content-box,
    linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask:
    linear-gradient(#000 0 0) content-box exclude,
    linear-gradient(#000 0 0);
  pointer-events: none;
}
/* hover and press: a little more light in the glass */
.fab:hover {
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.36),
    inset 0 -1px 1px rgba(255, 255, 255, 0.06),
    inset 0 0 16px rgba(214, 208, 255, 0.1),
    inset 0 0 0 99px rgba(255, 255, 255, 0.06),
    0 12px 34px rgba(0, 3, 20, 0.4),
    0 1px 3px rgba(0, 3, 20, 0.24);
}
.fab:active {
  transform: translateX(-50%) scale(0.97);
  box-shadow:
    inset 0 1px 1px rgba(255, 255, 255, 0.36),
    inset 0 -1px 1px rgba(255, 255, 255, 0.06),
    inset 0 0 16px rgba(214, 208, 255, 0.1),
    inset 0 0 0 99px rgba(255, 255, 255, 0.1),
    0 8px 24px rgba(0, 3, 20, 0.36),
    0 1px 3px rgba(0, 3, 20, 0.24);
}
.fab:focus-visible {
  border-radius: 999px;
  outline-offset: 4px;
}
/* over light content: the same glass, darker */
.fab-dense .fab,
html:not(.js) .fab {
  background:
    radial-gradient(140% 100% at 50% 0%, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0) 62%),
    rgba(0, 6, 36, 0.24);
  -webkit-backdrop-filter: blur(16px) saturate(160%) brightness(0.56);
  backdrop-filter: blur(16px) saturate(160%) brightness(0.56);
}
/* the circle of the sign, in the gradient of the logo, lit a little so it
   reads on the glass */
.fab__o {
  flex: none;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: linear-gradient(180deg, #a9a3ff, var(--o2) 50%, var(--o3));
  -webkit-mask: radial-gradient(circle, transparent 5.4px, #000 6px);
  mask: radial-gradient(circle, transparent 5.4px, #000 6px);
}
.form-open .fab,
.intro-play .fab {
  opacity: 0;
  pointer-events: none;
  transform: translate(-50%, 18px);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .fab,
  .fab-dense .fab,
  html:not(.js) .fab {
    background:
      linear-gradient(180deg, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0.02)),
      rgba(22, 20, 78, 0.94);
  }
}
@media (prefers-reduced-transparency: reduce) {
  .fab,
  .fab-dense .fab,
  html:not(.js) .fab {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: #1c1960;
  }
}

/* ---------- type ---------- */
.eyebrow {
  display: block;
  margin-bottom: 10px;
  font-family: var(--text);
  font-weight: 600;
  font-size: 0.9375rem;
  line-height: 1.6;
  letter-spacing: 0.01em;
  color: var(--text-2);
}
h1 {
  font-size: clamp(2.6rem, 11.6vw, 3.6rem);
  line-height: 1;
  letter-spacing: -0.02em;
}
h2 {
  font-size: clamp(2rem, 8.4vw, 2.6rem);
  line-height: 1.06;
}
h3 {
  font-size: 1.375rem;
  line-height: 1.2;
}
.lead {
  margin-top: 16px;
  max-width: 30rem;
  font-size: 1.0625rem;
  color: var(--text-2);
}

/* ---------- panels: one message each ---------- */
main {
  position: relative;
  z-index: 1;
  display: block;
}
.panel {
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 88px var(--gutter) 40px;
}
.copy {
  position: relative;
  isolation: isolate;
  width: 100%;
  max-width: 34rem;
}
.copy h2 + p {
  margin-top: 16px;
}
.copy p {
  color: var(--text-2);
}
.copy p + p {
  margin-top: 12px;
}

/* ---------- hero ---------- */
/* phone: the band fills the space above the copy, whatever the height of the
   screen; desktop: beside it */
.hero {
  display: grid;
  grid-template-rows: minmax(9rem, 1fr) auto;
  grid-template-columns: minmax(0, 1fr);
  justify-content: stretch;
  min-height: 100vh;
  min-height: 100svh;
  padding-top: calc(var(--bar-h) + env(safe-area-inset-top, 0px) + 8px);
  padding-bottom: calc(var(--fab-room) + 16px);
  isolation: isolate;
}
.hero__light {
  position: relative;
  z-index: -1;
  min-height: 0;
  pointer-events: none;
  transition: opacity 0.9s ease;
}
.stage-live .hero__light {
  opacity: 0;
}
/* The band's body is the middle half of the poster (dust above and below),
   so the box is larger than its row and its body sits in the middle of it. */
.hero__light .light {
  position: absolute;
  left: 50%;
  top: 50%;
  height: min(160%, 86vw);
  transform: translate(-50%, -54%);
}
.hero__copy {
  align-self: end;
}
.hero__copy h1 {
  max-width: 9.5em;
}
.actions {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 24px;
}
.actions .btn {
  flex: 0 0 auto;
}
@media (prefers-reduced-motion: no-preference) {
  .hero__copy > * {
    animation: rise 0.45s var(--ease) both;
  }
  .hero__copy > :nth-child(2) {
    animation-delay: 0.08s;
  }
  .hero__copy > :nth-child(3) {
    animation-delay: 0.16s;
  }
  /* With the opening, the copy waits for it: src/intro.js makes it rise
     once the logo has left it (with the story it stays for the scroll); if
     the opening never starts, it rises when the curtain fades ("intro-late",
     assets/gate.js). */
  .intro-play .hero__copy > * {
    animation-play-state: paused;
  }
  .intro-run .hero__copy > *,
  .intro-done .hero__copy > * {
    animation: none;
  }
  .intro-run:not(.intro-open) .hero__copy > * {
    opacity: 0;
  }
}
@keyframes rise {
  from {
    opacity: 0;
    transform: translateY(14px);
  }
}
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

/* Copy that can pass over the light sits on a soft midnight scrim. */
.hero__copy::before,
.story .panel > .copy::before,
.story .solutions__head .copy::before,
.story .along__head .copy::before {
  content: "";
  position: absolute;
  z-index: -1;
  /* from the left edge of the screen, across all of it */
  left: calc(-1 * var(--gutter));
  width: 100vw;
  top: -12svh;
  bottom: -8svh;
  background: linear-gradient(
    to bottom,
    rgba(0, 6, 36, 0) 0%,
    rgba(0, 6, 36, 0.78) 30%,
    rgba(0, 6, 36, 0.9) 70%,
    rgba(0, 6, 36, 0) 100%
  );
  pointer-events: none;
}

/* ---------- the hero in the story: the band alone, then the copy ----------
   At rest only the band, large in the middle of the screen (its poster here,
   then the live light in its place). The copy holds at --hero-hold (set by
   src/main.js: low on the phone, in the middle on desktop) from the start,
   hidden, and comes in as the page starts to move while the band makes room
   (scrubbed by src/main.js; "hero-free": shown at once, if the page moved
   before the script was ready). The empty block after it is the length of
   that moment. */
.story .hero.panel {
  display: block;
  min-height: 0;
  padding-top: var(--hero-hold, 44svh);
  padding-bottom: 0;
}
.story .hero.panel::after {
  content: "";
  display: block;
  height: 82vh;
  height: 82svh;
}
.story .hero__light {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.story .hero__light .light {
  left: 50%;
  top: 50%;
  width: min(112vw, 64svh);
  height: auto;
  transform: translate(-50%, -50%);
}
.story .hero__copy {
  position: sticky;
  top: var(--hero-hold, 44svh);
}
.story .hero__copy > * {
  opacity: 0;
  animation: none;
}
.story .hero__copy::before {
  opacity: var(--scrim, 0);
}
.story.hero-free .hero__copy {
  --scrim: 1;
}
.story.hero-free .hero__copy > * {
  opacity: 1;
  transition: opacity 0.45s var(--ease);
}
/* the way down: a thin line under the band with a light running down it,
   above the floating button; it goes as soon as the page moves */
.hero__cue {
  display: none;
}
.story .hero__cue {
  position: absolute;
  left: 50%;
  top: calc(100vh - var(--fab-room) - 62px);
  top: calc(100svh - var(--fab-room) - 62px);
  display: block;
  width: 2px;
  height: 40px;
  overflow: hidden;
  border-radius: 2px;
  background: rgba(247, 247, 250, 0.14);
  transform: translateX(-50%);
  transition: opacity 0.6s var(--ease) 0.9s;
  pointer-events: none;
}
.story .hero__cue::after {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  width: 2px;
  height: 18px;
  border-radius: 2px;
  background: linear-gradient(rgba(247, 247, 250, 0), rgba(247, 247, 250, 0.85));
  animation: cue 2.4s cubic-bezier(0.45, 0, 0.25, 1) infinite;
}
@keyframes cue {
  0% {
    transform: translateY(-18px);
  }
  70%,
  100% {
    transform: translateY(40px);
  }
}
.intro-play .hero__cue,
.hero-moved .hero__cue {
  opacity: 0;
  transition-delay: 0s;
  transition-duration: 0.3s;
}

/* ---------- the opening, which is also the preloader ----------
   Shown only with "intro-play" (assets/gate.js); src/intro.js plays it while
   the page loads (src/preload.js). At the first paint the circle of the sign
   (triboo-simbolo.webp) stands in the middle of the curtain, with the white
   one (triboo-o-bianca.webp) hidden behind it: the same size, in the same
   place. Then the white circle slides out to the right, both land on the
   "oo" of the wordmark, "trib" comes out of the first one (a window on the
   logo) and the logo itself (triboo-logo-grande.webp, the class
   "opening--whole") takes the place of the three parts: the same pixels,
   so nothing moves. The mark is the wordmark master, 2000x643 (gradient o
   x 1104-1529, white o x 1541-1966, y 193-616). The two circles are cut
   from their 2000x2000 masters on the centre of the ring (the white one
   sits 9 px lower in its file), 1720 px square, made 512 px; in the
   wordmark the ring is 0.2608 of its master, so each image is 22.4298% of
   the mark wide and sits by the centre of its ring (65.849% / 87.670% of
   the width, 62.953% of the height). The browser draws an image on whole
   pixels, each on its own: so the mark sits on whole pixels (where round()
   is known) and the circles start at its corner and get to their place
   with a transform (--o-x, --o-y), which is not rounded; there they meet
   the "oo" of the logo to the pixel. At the start both are --o-k times
   larger, their centre on the centre of the mark (the middle of the
   screen). "intro-still" (reduced motion): only the logo, still, while the
   page loads. */
.opening {
  --mark-w: min(80vw, 400px);
  --o-k: 1.6;
  display: none;
}
.intro-play .opening,
.intro-late .opening {
  position: fixed;
  z-index: 60;
  inset: 0;
  display: block;
  overflow: hidden;
  /* the page under the curtain waits: a tap or a swipe here moves nothing
     (src/intro.js hurries or ends the opening instead) */
  touch-action: none;
}
/* the last resort: if nothing ends the opening, the curtain goes by itself
   (src/intro.js always ends it sooner) */
.intro-play .opening {
  animation: opening-failsafe 0.5s ease 15s forwards;
}
.intro-open .opening,
.intro-late .opening {
  pointer-events: none;
}
.opening__bg {
  position: absolute;
  inset: 0;
  background: var(--midnight);
}
/* a faint violet breath behind the sign */
.opening__glow {
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(120vw, 900px);
  aspect-ratio: 1;
  border-radius: 50%;
  background: radial-gradient(closest-side, rgba(122, 50, 255, 0.2), rgba(96, 25, 255, 0.07) 55%, rgba(60, 1, 255, 0));
  opacity: 0;
  transform: translate(-50%, -50%);
}
.intro-play .opening__glow {
  animation: opening-glow 1.8s ease-out 0.2s both;
}
@keyframes opening-glow {
  to {
    opacity: 0.6;
  }
}
.opening__mark {
  position: absolute;
  left: calc(50% - var(--mark-w) / 2);
  top: calc(50% - var(--mark-w) * 0.16075);
  width: var(--mark-w);
  height: calc(var(--mark-w) * 0.3215);
  transform-origin: 0 0;
}
@supports (width: round(1.5px, 1px)) {
  .opening__mark {
    left: round(calc(50% - var(--mark-w) / 2), 1px);
    top: round(calc(50% - var(--mark-w) * 0.16075), 1px);
    width: round(var(--mark-w), 1px);
    height: round(calc(var(--mark-w) * 0.3215), 1px);
  }
}
.opening__mark img {
  position: absolute;
  display: block;
  max-width: none;
}
/* "trib": x 0-1098 of the master, between the b and the first circle */
.opening__trib {
  position: absolute;
  left: 0;
  top: 0;
  width: 54.9%;
  height: 100%;
  overflow: hidden;
}
.opening__trib img {
  left: 0;
  top: 0;
  width: 182.1494%;
  height: 100%;
  opacity: 0;
}
.opening__o {
  left: 0;
  top: 0;
  width: 22.4298%;
  height: 69.766%;
  transform: translate(var(--o-x), var(--o-y)) translate(var(--o-dx), var(--o-dy)) scale(var(--o-k));
}
/* in the wordmark: 54.6377% / 28.0516% of the mark; at the start its ring
   is on the centre of the mark */
.opening__o--grad {
  --o-x: 243.5942%;
  --o-y: 40.2081%;
  --o-dx: -70.6596%;
  --o-dy: -18.5666%;
  transform-origin: 49.9831% 50.0266%;
}
/* in the wordmark: 76.4594% / 28.0736% of the mark; at the start behind
   the other one, until it slides out */
.opening__o--white {
  --o-x: 340.8831%;
  --o-y: 40.2397%;
  --o-dx: -167.9482%;
  --o-dy: -18.5688%;
  transform-origin: 49.9828% 49.9973%;
  opacity: 0;
}
.opening__logo {
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  visibility: hidden;
}
.opening--whole .opening__logo,
.intro-still .opening__logo {
  visibility: visible;
}
.opening--whole .opening__trib,
.opening--whole .opening__o,
.intro-still .opening__trib,
.intro-still .opening__o {
  visibility: hidden;
}
/* a long load: a thin line under the sign fills with the page (never a
   number) */
.opening__line {
  position: absolute;
  left: calc(50% - var(--mark-w) * 0.1061);
  top: calc(50% + var(--mark-w) * 0.1062 * var(--o-k) + 36px);
  width: calc(var(--mark-w) * 0.2123);
  height: 2px;
  overflow: hidden;
  border-radius: 1px;
  background: rgba(247, 247, 250, 0.1);
  opacity: 0;
  transition: opacity 0.6s ease;
}
.opening__line > span {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--o1), var(--o3));
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform 0.5s var(--ease);
}
.opening--wait .opening__line {
  opacity: 1;
}
/* the opening never started (assets/gate.js gave up): the curtain fades */
.intro-late .opening {
  animation: opening-failsafe 0.5s ease forwards;
}
@keyframes opening-failsafe {
  to {
    opacity: 0;
    visibility: hidden;
  }
}
/* the header logo waits for the one of the opening (it is there at once
   under the still one, which only fades) */
.intro-play:not(.intro-still) .bar__logo img {
  opacity: 0;
}
/* the hero light waits until the logo has landed in the header */
.intro-play:not(.intro-land) .hero__light,
.intro-gather .hero__light {
  opacity: 0;
  transition: none;
}

/* ---------- badges and lists ---------- */
.badge,
.events__note {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  font-weight: 600;
  font-size: 0.875rem;
  line-height: 1.3;
}
.badge {
  margin-bottom: 14px;
  padding: 7px 14px 7px 10px;
  border: 1px solid rgba(181, 170, 255, 0.34);
  border-radius: 999px;
  background: rgba(129, 112, 255, 0.1);
}
.copy .badge {
  color: var(--ice);
}
.badge__o {
  flex: none;
  width: 12px;
  height: 12px;
  border: 2.5px solid var(--o2);
  border-radius: 50%;
}
.ticks li {
  position: relative;
  padding-left: 26px;
}
.ticks li::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0.5em;
  width: 11px;
  height: 11px;
  border: 2px solid var(--violet);
  border-radius: 50%;
}

/* ---------- the two solutions ---------- */
.solutions__head {
  padding: 88px var(--gutter) 8px;
}
.solutions__head p {
  max-width: 32rem;
}
.sol .copy h3 {
  font-size: clamp(2rem, 8.4vw, 2.6rem);
  line-height: 1.06;
}
.sol__lead {
  margin-top: 10px;
  font-size: 1.0625rem;
  line-height: 1.5;
}
.sol .ticks {
  display: grid;
  gap: 6px;
  margin-top: 14px;
  font-size: 0.9375rem;
  line-height: 1.5;
  color: var(--text-2);
}
/* the official Apple Wallet and Google Wallet badges, unchanged: the same
   height, at least the 48px Google asks for, with more than the clear space
   Apple (a tenth of the height) and Google (8px) want around them */
.wallets {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-top: 16px;
}
.wallets img {
  display: block;
  width: auto;
  height: 48px;
}
/* static posters when the light is not coming */
.sol__poster {
  position: relative;
  align-self: center;
  width: min(78vw, 340px);
  aspect-ratio: 1;
  margin-bottom: 8px;
}
.sol__poster--card {
  width: min(60vw, 260px);
  aspect-ratio: 4 / 5;
  margin-bottom: 24px;
}
.sol__poster::before {
  content: "";
  position: absolute;
  inset: -6% -14%;
  border-radius: 50%;
  background: radial-gradient(
    closest-side,
    rgba(122, 50, 255, 0.3) 0%,
    rgba(108, 34, 255, 0.18) 40%,
    rgba(76, 16, 255, 0.07) 65%,
    rgba(60, 1, 255, 0) 85%
  );
}
.sol__poster img {
  position: relative;
  width: 100%;
  height: 100%;
}
.story .sol__poster {
  display: none;
}
.sol + .sol {
  padding-top: 56px;
}

/* ---------- how we work ---------- */
.how {
  position: relative;
  padding: 88px var(--gutter) 24px;
}
.how__head p {
  max-width: 32rem;
  margin-top: 16px;
  color: var(--text-2);
}
/* a sequence: rings on a line */
.steps {
  position: relative;
  display: grid;
  gap: 28px;
  margin-top: 36px;
}
.step {
  position: relative;
  display: grid;
  grid-template-columns: 48px minmax(0, 1fr);
  column-gap: 18px;
}
.step::before {
  content: "";
  position: absolute;
  left: 23.5px;
  top: 52px;
  bottom: -26px;
  width: 1px;
  background: linear-gradient(rgba(129, 112, 255, 0.5), rgba(129, 112, 255, 0.12));
}
.step:last-child::before {
  content: none;
}
/* The ring: dark grey, then the violet of the brand with a light glint,
   turning slowly (an overlay on the grey border, cut to a ring by a mask). src/steps.js marks
   the list "live" and lights each ring (is-lit) as the page brings it up,
   and the rings only turn while the list is near the screen (is-near);
   without it every ring is lit. Still with reduced motion. */
.step__n {
  position: relative;
  grid-row: span 2;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border: 2px solid rgba(247, 247, 250, 0.16);
  border-radius: 50%;
  font-family: var(--head);
  font-weight: 500;
  font-size: 1.375rem;
  line-height: 1;
  color: var(--ice);
  transition: color 0.6s ease;
}
.step__n::before {
  content: "";
  position: absolute;
  inset: -2px;
  border-radius: 50%;
  background: conic-gradient(
    var(--ice),
    var(--lilac) 15%,
    var(--violet) 40%,
    var(--o3) 65%,
    var(--violet) 85%,
    var(--ice)
  );
  -webkit-mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2px));
  mask: radial-gradient(farthest-side, transparent calc(100% - 2.5px), #000 calc(100% - 2px));
  transition: opacity 0.6s ease;
  animation: ring-turn 4s linear infinite;
}
[data-live]:not(.is-near) .step__n::before {
  animation-play-state: paused;
}
[data-live] .step:not(.is-lit) .step__n {
  color: var(--text-3);
}
[data-live] .step:not(.is-lit) .step__n::before {
  opacity: 0;
  animation-play-state: paused;
}
@keyframes ring-turn {
  to {
    transform: rotate(1turn);
  }
}
@media (prefers-reduced-motion: reduce) {
  .step__n::before {
    animation: none;
  }
}
.step h3 {
  padding-top: 10px;
  font-size: 1.375rem;
}
.step p {
  margin-top: 8px;
  color: var(--text-2);
}

/* ---------- with you from the first entry: the phone's screens, the team ----------
   The same beats as the solutions (.sol): the light (or, without it, the
   poster) beside a short line. */
.along {
  position: relative;
  padding-bottom: 40px;
}
.along__head {
  padding: 72px var(--gutter) 0;
}
.sol.feat .copy h3 {
  font-size: clamp(1.5rem, 5.6vw, 2.125rem);
  line-height: 1.18;
}
.feat .badge {
  margin-top: 18px;
  margin-bottom: 0;
}
/* the first words of each line: white, then, once the line has come to
   where it holds (src/keys.js: is-lit), the violet of the brand flowing
   through them; still with reduced motion, white without the script */
.feat__key {
  background: linear-gradient(90deg, var(--lilac), var(--violet), var(--o3), var(--violet), var(--lilac)) 0 0 / 300% 100%;
  -webkit-background-clip: text;
  background-clip: text;
  color: var(--ice);
  transition: color 0.9s ease;
}
.feat.is-lit .feat__key {
  color: transparent;
  animation: key-flow 5s linear infinite;
}
@keyframes key-flow {
  to {
    background-position: 300% 0;
  }
}
@media (prefers-reduced-motion: reduce) {
  .feat.is-lit .feat__key {
    animation: none;
  }
}
.sol__poster--team {
  width: min(76vw, 400px);
  aspect-ratio: 5 / 4;
}

/* ---------- events: two rows of photos drifting ----------
   src/reel.js splits the list in two rows and adds hidden copies so each
   row loops without a seam. Without it (no JavaScript, reduced motion) the
   photos are a strip that scrolls sideways. */
.events {
  position: relative;
  padding: 88px 0 48px;
}
.events__head {
  padding: 0 var(--gutter);
}
.events__head > p:not(.events__note) {
  max-width: 32rem;
  margin-top: 16px;
  color: var(--text-2);
}
.events__note {
  margin-top: 16px;
  padding: 7px 14px 7px 10px;
  border: 1px solid rgba(247, 247, 250, 0.2);
  border-radius: 18px;
  color: var(--text-2);
}
/* "Parlaci del tuo evento" in the note opens the form, like the floating button */
.events__note a {
  color: var(--ice);
  text-decoration: underline;
  text-decoration-color: var(--violet);
  text-underline-offset: 3px;
}
.events__note a:hover {
  text-decoration-color: currentColor;
}
.reel {
  --shot-w: clamp(172px, 46vw, 300px);
  --shot-gap: 14px;
  display: flex;
  flex-direction: column;
  margin-top: 32px;
}
.reel__list,
.reel__track {
  display: flex;
}
.reel__list {
  gap: var(--shot-gap);
  padding: 4px var(--gutter) 18px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scroll-padding-inline: var(--gutter);
  scrollbar-width: thin;
  scrollbar-color: rgba(247, 247, 250, 0.3) transparent;
}
.reel__list > li {
  flex: none;
  scroll-snap-align: start;
}
/* the strip is reachable from the keyboard (arrow keys scroll it); the
   drifting rows too, which stand still while they have the focus */
.reel__list:focus-visible,
.reel:focus-visible {
  outline: 2px solid var(--lilac);
  outline-offset: -2px;
  border-radius: 18px;
}
.reel__row {
  overflow: hidden;
  -webkit-mask: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
  mask: linear-gradient(90deg, transparent, #000 5%, #000 95%, transparent);
}
.reel__row + .reel__row {
  margin-top: var(--shot-gap);
}
.reel__track {
  width: max-content;
  will-change: transform;
}
.reel__track > li {
  flex: none;
  padding-right: var(--shot-gap);
}
.shot {
  position: relative;
  width: var(--shot-w);
  margin: 0;
  overflow: hidden;
  border-radius: 24px;
  background: var(--surface);
  isolation: isolate;
}
.shot img {
  width: 100%;
  aspect-ratio: 4 / 5;
  object-fit: cover;
}
/* the photos are not for taking: nothing to select or drag, no menu to save
   them on a long press (src/reel.js also blocks the right-click menu); a
   right click lands on the card, not on the image. A screenshot still can. */
.reel {
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
}
.reel img {
  pointer-events: none;
  -webkit-user-drag: none;
}
.shot::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 1px rgba(247, 247, 250, 0.1);
  pointer-events: none;
}
.shot figcaption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  display: grid;
  gap: 2px;
  padding: 48px 16px 15px;
  background: linear-gradient(rgba(0, 6, 36, 0), rgba(0, 6, 36, 0.82) 60%);
}
.shot strong {
  font-family: var(--head);
  font-weight: 500;
  font-size: 1.0625rem;
  line-height: 1.2;
  text-wrap: balance;
}
.shot figcaption span {
  font-size: 0.8125rem;
  line-height: 1.35;
  color: var(--text-2);
}
/* the date of the event, on the photo */
.shot__date {
  position: absolute;
  z-index: 1;
  left: 12px;
  top: 12px;
  padding: 3px 10px;
  border-radius: 999px;
  background: rgba(0, 6, 36, 0.62);
  font-weight: 600;
  font-size: 0.75rem;
  line-height: 1.5;
  color: var(--ice);
}

/* ---------- contact ---------- */
.contact.panel {
  padding-top: 88px;
  padding-bottom: 56px;
}
.contact .actions {
  margin-top: 26px;
}
/* The band of the contact: the static poster, or on the phone the box the
   live light comes back to. */
.contact__light {
  order: -1;
  align-self: center;
  width: min(64vw, 280px, 36svh);
  margin-bottom: 16px;
}
.stage-live .contact__light {
  visibility: hidden;
}

/* ---------- footer ---------- */
.foot {
  position: relative;
  z-index: 1;
  display: grid;
  gap: 18px;
  padding: 40px var(--gutter) calc(var(--fab-room) + 20px);
  border-top: 1px solid var(--line);
  font-size: 0.875rem;
  color: var(--text-2);
}
.foot__brand img {
  width: 136px;
}
.foot__brand p {
  margin-top: 10px;
}
/* who makes TRIBOO: one quiet line under the brand */
.foot__brand .foot__by {
  max-width: 34rem;
  margin-top: 6px;
  font-size: 0.8125rem;
  line-height: 1.5;
  color: var(--text-3);
}
.foot__end {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 22px;
}
.foot a {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}
.foot a[aria-current] {
  color: var(--ice);
}
/* "Scrivici su WhatsApp": a chip with the WhatsApp sign, in its green */
.foot .wa {
  gap: 10px;
  margin-top: 16px;
  padding: 0 18px 0 14px;
  border: 1px solid rgba(247, 247, 250, 0.22);
  border-radius: 999px;
  font-weight: 600;
  color: var(--ice);
  text-decoration: none;
  transition: border-color 0.2s var(--ease);
}
.foot .wa:hover {
  border-color: rgba(247, 247, 250, 0.5);
}
.wa__icon {
  flex: none;
  color: #25d366;
}

/* ---------- the request form: a frosted sheet ----------
   Web approximation of a glass material: backdrop-filter over a
   semi-transparent midnight tint, a hairline light edge, a soft top
   highlight. Opaque where the browser cannot blur. On the phone a sheet from
   the bottom, almost full height, that scrolls; on desktop a panel in the
   middle whose height follows its step. Two steps, with their buttons kept
   at the bottom of the sheet. With the light ("form-light", see below) the
   light of the page comes behind the glass (src/main.js). src/form.js opens
   and closes it. */
.form-open,
.form-open body {
  overflow: hidden;
}
/* One scale for the whole form: a control (field, choice, button) is
   --f-ctl high with radius --f-r, a card (suggestion, recap, messages) has
   radius --f-card; type steps: --f-small for labels and notes, --f-body for
   choices and messages; inputs keep 16 px (smaller ones make iPhones zoom). */
.sheet {
  --f-ctl: 46px;
  --f-r: 12px;
  --f-card: 16px;
  --f-small: 0.8125rem;
  --f-body: 0.9375rem;
  position: fixed;
  inset: 0;
  width: 100%;
  max-width: none;
  height: 100%;
  max-height: none;
  margin: 0;
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--ice);
  overflow: hidden;
}
.sheet:not([open]) {
  display: none;
}
.sheet::backdrop {
  background: rgba(0, 3, 22, 0.52);
  -webkit-backdrop-filter: blur(6px) saturate(120%);
  backdrop-filter: blur(6px) saturate(120%);
  opacity: 0;
  transition: opacity 0.38s var(--ease);
}
.sheet.is-open::backdrop {
  opacity: 1;
}
/* With the light behind the form (src/main.js; "form-light" on <html> only
   for a sheet opened while the light is on, src/form.js) the page around it
   is dimmed less, and the glass is clearer where the light stands. */
.stage-live.form-light .sheet::backdrop {
  background: rgba(0, 3, 22, 0.34);
}
/* Phone: in the first step the sheet stops lower and the light stands on its
   top edge, sharp: the page around steps back ("form-veil", while the sheet
   is open), so nothing but the light is above the sheet. In the second step
   and for the thanks the sheet rises to the whole height (the keyboard needs
   the room) and the light moves behind its top. The glass is clearer in its
   upper part (the tint stays put while the form scrolls). */
@media (max-width: 760px), (max-aspect-ratio: 4/5) {
  .stage-live.form-light .sheet::backdrop {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
  }
  main,
  .foot {
    transition: opacity 0.3s var(--ease);
  }
  .stage-live.form-veil main,
  .stage-live.form-veil .foot,
  .stage-live.form-veil .bar {
    opacity: 0;
  }
  .stage-live.form-light .sheet__panel {
    background:
      linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0) 180px),
      linear-gradient(180deg, rgba(8, 12, 50, 0.46), rgba(8, 12, 50, 0.74) 320px);
    -webkit-backdrop-filter: blur(22px) saturate(170%);
    backdrop-filter: blur(22px) saturate(170%);
    transition-property: transform, top;
  }
  .stage-live.form-light .sheet[data-place="1"] .sheet__panel {
    top: max(env(safe-area-inset-top, 0px), clamp(14px, 30svh - 80px, 200px));
  }
}
/* short phones: the whole height for the form, the light behind its top */
@media (max-width: 760px) and (max-height: 620px), (max-aspect-ratio: 4/5) and (max-height: 620px) {
  .stage-live.form-light .sheet[data-place="1"] .sheet__panel {
    top: max(env(safe-area-inset-top, 0px), 14px);
  }
}
.sheet__panel {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  top: max(env(safe-area-inset-top, 0px), 14px);
  display: flex;
  flex-direction: column;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  border: 1px solid rgba(214, 208, 255, 0.2);
  border-bottom: 0;
  border-radius: 28px 28px 0 0;
  background:
    linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0) 180px),
    rgba(8, 12, 50, 0.72);
  -webkit-backdrop-filter: blur(28px) saturate(170%);
  backdrop-filter: blur(28px) saturate(170%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.16),
    0 -20px 60px rgba(0, 3, 20, 0.45);
  /* a field brought into view stays clear of the head and of the buttons */
  scroll-padding: 150px 0 100px;
  transform: translateY(104%);
  transition: transform 0.42s cubic-bezier(0.32, 0.72, 0, 1);
}
.sheet.is-open .sheet__panel {
  transform: none;
}
.sheet.is-closing .sheet__panel {
  transition-duration: 0.3s;
  transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
}
.sheet.is-closing::backdrop {
  transition-duration: 0.3s;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .sheet__panel {
    background: #0b103c;
  }
  .sheet::backdrop {
    background: rgba(0, 3, 22, 0.78);
  }
}
@media (prefers-reduced-transparency: reduce) {
  .sheet__panel {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: #0b103c;
  }
}
/* the grabber of a sheet: the head can be dragged down to close it
   (src/form.js) */
.sheet__panel::before {
  content: "";
  position: absolute;
  z-index: 3;
  left: 50%;
  top: 7px;
  width: 38px;
  height: 5px;
  border-radius: 999px;
  background: rgba(247, 247, 250, 0.28);
  transform: translateX(-50%);
}
/* Phone: one row, the steps and ✕ (the title is read out, not shown: the
   button that opens the sheet says it), so the first step has the room. */
.sheet__head {
  position: sticky;
  z-index: 3;
  top: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 16px;
  padding: 20px 12px 10px 22px;
  border-bottom: 1px solid transparent;
  border-radius: 28px 28px 0 0;
  touch-action: none;
  transition:
    border-color 0.2s ease,
    background-color 0.2s ease;
}
/* once the form scrolls under it, the header turns to solid midnight, so
   nothing reads through it */
.sheet__panel.is-scrolled .sheet__head {
  border-bottom-color: rgba(247, 247, 250, 0.1);
  background: rgb(13, 17, 60);
}
.sheet__head h2 {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  font-size: 1.375rem;
  line-height: 1.15;
}
.sheet__head h2:focus {
  outline: none;
}
.sheet__close {
  flex: none;
  /* at the right end, also when the steps are gone (the thanks) */
  margin-left: auto;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  padding: 0;
  border: 1px solid rgba(247, 247, 250, 0.16);
  border-radius: 50%;
  background: rgba(247, 247, 250, 0.08);
  cursor: pointer;
  transition: background-color 0.2s var(--ease);
}
.sheet__close:hover {
  background: rgba(247, 247, 250, 0.16);
}
.sheet__close:focus-visible {
  border-radius: 50%;
}

/* the two steps: a bar for each, lit in the gradient of the logo up to the
   step on screen */
.stepper {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
  flex: 1 1 0;
  order: -1;
  min-width: 0;
}
.stepper__item {
  display: grid;
  gap: 8px;
  min-width: 0;
}
.stepper__bar {
  position: relative;
  height: 3px;
  border-radius: 3px;
  background: rgba(247, 247, 250, 0.14);
  overflow: hidden;
}
.stepper__bar::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: linear-gradient(90deg, var(--o1), var(--o2) 55%, var(--o3));
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 0.5s var(--ease);
}
.stepper__item[aria-current] .stepper__bar::after,
.stepper__item.is-done .stepper__bar::after {
  transform: none;
}
.stepper__label {
  font-weight: 600;
  font-size: 0.75rem;
  line-height: 1.3;
  color: var(--text-3);
  transition: color 0.3s var(--ease);
}
.stepper__item[aria-current] .stepper__label {
  color: var(--ice);
}
.stepper__item.is-done .stepper__label {
  color: var(--text-2);
}
.sheet.is-done .stepper {
  display: none;
}

.form {
  display: flex;
  flex-direction: column;
  flex: 1 0 auto;
  padding: 6px 22px 0;
}
.form[hidden] {
  display: none;
}
.form__step {
  display: flex;
  flex-direction: column;
  flex: 1 0 auto;
  gap: 22px;
}
.form__step[hidden] {
  display: none;
}
/* the question that opens each step (the focus lands on it) */
.form__q {
  font-size: 1.25rem;
  line-height: 1.2;
}
.form__q:focus {
  outline: none;
}
.form__intro {
  margin-top: -14px;
  font-size: var(--f-small);
  line-height: 1.5;
  color: var(--text-2);
}
.req {
  color: var(--lilac);
  font-weight: 600;
}
.form__grid {
  display: grid;
  gap: 16px;
  min-width: 0;
}
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* ---------- how many people: the slider of the first step ---------- */
.people {
  --thumb: 22px;
  /* where the slider is (src/people.js) and the 5.000 stop: 49 of 79 */
  --p: 0.2405;
  --mark: 0.62025;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-areas: "q" "value" "track" "scale" "err" "unsure";
}
.people .form__q {
  grid-area: q;
}
.people__value {
  grid-area: value;
  display: flex;
  align-items: baseline;
  /* the height of the number, also while it reads «Sposta il cursore» or
     «Da definire insieme» */
  min-height: 2.25rem;
  margin-top: 10px;
  font-family: var(--head);
  font-weight: 500;
  font-size: var(--f-body);
  line-height: 1;
  color: var(--text-2);
}
.people__value output {
  margin-right: 6px;
  font-size: 2rem;
  line-height: 1;
  letter-spacing: -0.02em;
  color: var(--ice);
  font-variant-numeric: tabular-nums;
  transition: color 0.25s var(--ease);
}
.people.is-unknown .people__value output {
  color: var(--text-3);
}
/* not moved yet: an invitation, not a number (nothing is sent until then) */
.people.is-idle .people__value output {
  color: var(--text-2);
}
.people.is-unknown .people__value,
.people.is-idle .people__value {
  align-items: center;
}
.people.is-unknown .people__value output,
.people.is-idle .people__value output {
  font-size: 1.125rem;
  letter-spacing: 0;
}
.people.is-unknown .people__value span,
.people.is-idle .people__value span {
  display: none;
}
.people__track {
  grid-area: track;
  position: relative;
  margin-top: 4px;
  transition: opacity 0.25s var(--ease);
}
.people.is-unknown .people__track,
.people.is-unknown .people__scale {
  opacity: 0.42;
}
/* the 5.000 threshold on the track */
.people__track::before {
  content: "";
  position: absolute;
  z-index: 1;
  left: calc(var(--thumb) / 2 + var(--mark) * (100% - var(--thumb)) - 1px);
  top: calc(50% - 7px);
  width: 2px;
  height: 14px;
  border-radius: 2px;
  background: rgba(247, 247, 250, 0.6);
  pointer-events: none;
}
.people__range {
  position: relative;
  z-index: 2;
  display: block;
  width: 100%;
  height: 40px;
  margin: 0;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  touch-action: pan-y;
}
.people__range:focus-visible {
  outline: none;
}
.people__range::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 999px;
  background:
    linear-gradient(90deg, var(--o1), var(--o2) 60%, var(--o3)) 0 0 / calc(var(--thumb) / 2 + var(--p) * (100% - var(--thumb))) 100% no-repeat,
    rgba(247, 247, 250, 0.14);
}
.people__range::-moz-range-track {
  height: 4px;
  border-radius: 999px;
  background: rgba(247, 247, 250, 0.14);
}
.people__range::-moz-range-progress {
  height: 4px;
  border-radius: 999px;
  background: linear-gradient(90deg, var(--o1), var(--o2) 60%, var(--o3));
}
/* not moved yet: the track is not filled */
.people.is-idle .people__range::-webkit-slider-runnable-track {
  background-size: 0 100%;
}
.people.is-idle .people__range::-moz-range-progress {
  background: transparent;
}
.people__range::-webkit-slider-thumb {
  width: var(--thumb);
  height: var(--thumb);
  margin-top: calc(2px - var(--thumb) / 2);
  border: 0;
  border-radius: 50%;
  background: var(--ice);
  box-shadow:
    0 0 0 4px rgba(129, 112, 255, 0.32),
    0 3px 10px rgba(0, 3, 20, 0.5);
  -webkit-appearance: none;
  appearance: none;
  transition: box-shadow 0.2s var(--ease);
}
.people__range::-moz-range-thumb {
  width: var(--thumb);
  height: var(--thumb);
  border: 0;
  border-radius: 50%;
  background: var(--ice);
  box-shadow:
    0 0 0 4px rgba(129, 112, 255, 0.32),
    0 3px 10px rgba(0, 3, 20, 0.5);
}
.people__range:active::-webkit-slider-thumb {
  box-shadow:
    0 0 0 7px rgba(129, 112, 255, 0.34),
    0 3px 10px rgba(0, 3, 20, 0.5);
}
.people__range:focus-visible::-webkit-slider-thumb {
  box-shadow:
    0 0 0 3px var(--midnight),
    0 0 0 5px var(--ice);
}
.people__range:focus-visible::-moz-range-thumb {
  box-shadow:
    0 0 0 3px var(--midnight),
    0 0 0 5px var(--ice);
}
.people__scale {
  grid-area: scale;
  position: relative;
  display: flex;
  justify-content: space-between;
  height: 1.4em;
  font-size: 0.75rem;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
  transition: opacity 0.25s var(--ease);
}
.people__mark {
  position: absolute;
  left: calc(var(--thumb) / 2 + var(--mark) * (100% - var(--thumb)));
  transform: translateX(-50%);
  color: var(--text-2);
  font-weight: 600;
}
.people .field__error {
  grid-area: err;
  margin-top: 6px;
}

/* «Non lo so ancora»: a switch (the native checkbox, invisible, over it) */
.toggle {
  grid-area: unsure;
  position: relative;
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  margin-top: 2px;
  font-size: var(--f-small);
  line-height: 1.3;
  color: var(--text-2);
  cursor: pointer;
}
.toggle input {
  position: absolute;
  z-index: 1;
  left: 0;
  top: 50%;
  width: 36px;
  height: 22px;
  margin: 0;
  opacity: 0;
  cursor: pointer;
  transform: translateY(-50%);
}
.toggle__track {
  position: relative;
  flex: none;
  width: 36px;
  height: 22px;
  border: 1px solid rgba(247, 247, 250, 0.26);
  border-radius: 999px;
  background: rgba(247, 247, 250, 0.1);
  transition:
    background-color 0.25s var(--ease),
    border-color 0.25s var(--ease);
}
.toggle__track::after {
  content: "";
  position: absolute;
  left: 2px;
  top: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--ice);
  box-shadow: 0 2px 6px rgba(0, 3, 20, 0.4);
  transition: transform 0.25s var(--ease);
}
.toggle:hover .toggle__track {
  border-color: rgba(247, 247, 250, 0.42);
}
.toggle input:checked + .toggle__track {
  border-color: var(--violet);
  background: var(--violet);
}
.toggle input:checked + .toggle__track::after {
  transform: translateX(14px);
}
.toggle input:checked ~ span:last-child {
  color: var(--ice);
}
.toggle input:focus-visible + .toggle__track {
  outline: 2px solid var(--ice);
  outline-offset: 3px;
}

/* the suggestion: the drawing that turns from the wristband into the QR,
   the name and one reason. Its three texts (QR code, wristband, «Non lo sai
   ancora?») sit on top of each other and cross-fade, so the card never
   changes height and nothing under it moves (src/people.js). */
.advice {
  position: relative;
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: -6px;
  padding: 12px 16px 12px 12px;
  border: 1px solid rgba(214, 208, 255, 0.2);
  border-radius: var(--f-card);
  background:
    radial-gradient(120% 140% at 0% 0%, rgba(135, 128, 244, 0.22), rgba(135, 128, 244, 0) 60%),
    rgba(247, 247, 250, 0.05);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.08);
}
.advice__art {
  flex: none;
  width: 48px;
  height: 48px;
  overflow: visible;
  filter: drop-shadow(0 0 10px rgba(129, 112, 255, 0.55));
  transition: opacity 0.3s var(--ease);
}
/* «Non lo so ancora»: a question mark of light in place of the drawing,
   with its depth behind it, sparks running along it and a slow float */
.advice__shape,
.advice__ask {
  transform-box: fill-box;
  transform-origin: center;
  transition:
    opacity 0.35s var(--ease),
    transform 0.35s var(--ease);
}
.advice__ask {
  opacity: 0;
  transform: scale(0.7);
}
.advice.is-unsure .advice__shape {
  opacity: 0;
  transform: scale(0.85);
}
.advice.is-unsure .advice__ask {
  opacity: 1;
  transform: none;
}
.advice.is-unsure .advice__ask-body {
  transform-box: fill-box;
  transform-origin: center;
  animation: ask-float 3.2s ease-in-out infinite;
}
.advice.is-unsure .advice__ask-spark {
  animation: ask-spark 1.6s linear infinite;
}
@keyframes ask-float {
  50% {
    transform: translateY(-2px) rotate(-4deg);
  }
}
@keyframes ask-spark {
  to {
    stroke-dashoffset: -6.42;
  }
}
@media (prefers-reduced-motion: reduce) {
  .advice.is-unsure .advice__ask-body,
  .advice.is-unsure .advice__ask-spark {
    animation: none;
  }
}
.advice__texts {
  display: grid;
  flex: 1 1 auto;
  min-width: 0;
}
.advice__text {
  grid-area: 1 / 1;
  min-width: 0;
  opacity: 0;
  visibility: hidden;
  transform: translateY(5px);
  transition:
    opacity 0.2s var(--ease),
    transform 0.2s var(--ease),
    visibility 0s linear 0.2s;
}
.advice__text.is-on {
  opacity: 1;
  visibility: visible;
  transform: none;
  transition:
    opacity 0.3s var(--ease) 0.1s,
    transform 0.3s var(--ease) 0.1s,
    visibility 0s;
}
.advice.is-still .advice__text {
  transition: none;
}
.advice__label {
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--text-3);
}
.advice__name {
  margin-top: 1px;
  font-family: var(--head);
  font-weight: 500;
  font-size: 1.0625rem;
  line-height: 1.2;
  color: var(--ice);
}
.advice__why {
  margin-top: 3px;
  font-size: var(--f-small);
  line-height: 1.45;
  color: var(--text-2);
}
/* narrow phones: «il QR code» fits one line, like «il bracciale NFC» */
@media (max-width: 520px) {
  .advice__more {
    display: none;
  }
}

/* the line that sums up the first step, at the top of the second */
.recap {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 14px;
  padding: 4px 6px 4px 14px;
  border: 1px solid rgba(247, 247, 250, 0.12);
  border-radius: var(--f-card);
  background: rgba(247, 247, 250, 0.05);
  font-size: var(--f-small);
  line-height: 1.45;
  color: var(--text-2);
}
.recap__text {
  flex: 1 1 14rem;
  min-width: 0;
  padding: 6px 0;
}
.recap__edit {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 0 10px;
  border: 0;
  border-radius: 10px;
  background: none;
  color: var(--lilac);
  font-weight: 600;
  font-size: var(--f-small);
  text-decoration: underline;
  text-decoration-color: rgba(181, 170, 255, 0.45);
  text-underline-offset: 0.25em;
  cursor: pointer;
}
.recap__edit:hover {
  text-decoration-color: currentColor;
}

.field {
  display: grid;
  /* an error under the field beside this one does not stretch this one */
  align-content: start;
  gap: 6px;
  min-width: 0;
}
.field > label,
.choice > legend {
  font-weight: 600;
  font-size: var(--f-small);
  line-height: 1.4;
}
.field input:not([type="radio"]):not([type="checkbox"]),
.field select,
.field textarea {
  width: 100%;
  min-height: var(--f-ctl);
  margin: 0;
  padding: 10px 14px;
  border: 1px solid rgba(247, 247, 250, 0.18);
  border-radius: var(--f-r);
  background: rgba(247, 247, 250, 0.07);
  color: var(--ice);
  font: inherit;
  font-size: 1rem;
  line-height: 1.5;
  transition:
    border-color 0.2s var(--ease),
    background-color 0.2s var(--ease),
    box-shadow 0.2s var(--ease);
  -webkit-appearance: none;
  appearance: none;
}
.field textarea {
  min-height: 104px;
  resize: vertical;
}
.field input::placeholder,
.field textarea::placeholder {
  color: rgba(247, 247, 250, 0.42);
}
.field input:not([type="radio"]):not([type="checkbox"]):hover,
.field select:hover,
.field textarea:hover {
  border-color: rgba(247, 247, 250, 0.32);
}
.field input:not([type="radio"]):not([type="checkbox"]):focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  border-color: var(--lilac);
  background: rgba(247, 247, 250, 0.1);
  box-shadow: 0 0 0 3px rgba(129, 112, 255, 0.35);
}
.field [aria-invalid="true"] {
  border-color: var(--danger) !important;
}
.select {
  position: relative;
}
.select::after {
  content: "";
  position: absolute;
  right: 16px;
  top: 50%;
  width: 7px;
  height: 7px;
  border-right: 1.5px solid var(--text-2);
  border-bottom: 1.5px solid var(--text-2);
  transform: translateY(-70%) rotate(45deg);
  pointer-events: none;
}
.field select {
  padding-right: 40px;
  cursor: pointer;
}
.field select option {
  background: #0b103c;
  color: var(--ice);
}
/* the date: the calendar of the device, in the dark; the field is as tall
   as the others also while empty (iPhone) and its text starts on the left */
.field input[type="date"] {
  color-scheme: dark;
  cursor: pointer;
}
.field input[type="date"]::-webkit-date-and-time-value {
  min-height: 1.5em;
  text-align: left;
}
.field input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: 0.7;
  cursor: pointer;
}
/* «Altro»: the box to write which type, under the list */
.field__more {
  display: grid;
  gap: 6px;
  margin-top: 4px;
}
.field__more[hidden] {
  display: none;
}
.field__error {
  font-size: var(--f-small);
  line-height: 1.4;
  color: var(--danger);
}
.field__error:empty {
  display: none;
}
/* «Forse intendevi …?» under the email: a word, never a block; the address
   is a button that fixes it with one tap (src/form.js). Kept in the
   accessibility tree when empty, so the suggestion is read out when it
   comes, but out of the layout. */
.field__hint {
  font-size: var(--f-small);
  line-height: 1.45;
  color: var(--lilac);
  overflow-wrap: anywhere;
}
.field__hint:empty {
  position: absolute;
}
.field__fix {
  display: inline;
  margin: -10px -3px;
  padding: 10px 3px;
  border: 0;
  border-radius: 8px;
  background: none;
  color: var(--ice);
  font-size: inherit;
  line-height: inherit;
  text-align: left;
  text-decoration: underline;
  text-decoration-color: rgba(181, 170, 255, 0.6);
  text-underline-offset: 0.22em;
  overflow-wrap: anywhere;
  cursor: pointer;
}
.field__fix:hover {
  text-decoration-color: currentColor;
}
.field__fix strong {
  font-weight: 600;
}
/* how many characters the message has, near its limit */
.field__count {
  justify-self: end;
  font-size: 0.75rem;
  line-height: 1.4;
  color: var(--text-3);
  font-variant-numeric: tabular-nums;
}
.field__count:empty {
  display: none;
}
.field__count.is-full {
  color: var(--danger);
}
/* what to fix, at the top of a step after «Avanti» or «Invia»: each line
   takes to its field */
.form__summary:empty {
  display: none;
}
.form__summary {
  padding: 12px 16px 4px;
  border: 1px solid rgba(255, 180, 192, 0.4);
  border-radius: var(--f-card);
  background: rgba(255, 120, 150, 0.1);
  font-size: var(--f-small);
  line-height: 1.45;
}
.form__summary-title {
  font-weight: 600;
}
.form__summary ul {
  margin-top: 2px;
}
.form__summary a {
  position: relative;
  display: flex;
  align-items: center;
  min-height: 32px;
  padding: 5px 0 5px 18px;
  color: var(--ice);
  text-decoration: underline;
  text-decoration-color: rgba(255, 180, 192, 0.55);
}
.form__summary a:hover {
  text-decoration-color: currentColor;
}
.form__summary a::before {
  content: "";
  position: absolute;
  left: 2px;
  top: calc(5px + 0.725em - 3px);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--danger);
}
.choice {
  margin: 0;
  padding: 0;
  border: 0;
}
.choice > legend {
  margin-bottom: 8px;
  padding: 0;
}
.choice__options {
  display: grid;
  gap: 8px;
}
/* the solution picked is not the one we suggest: a word, never a block */
.choice__note {
  margin-top: 8px;
  font-size: var(--f-small);
  line-height: 1.45;
  color: var(--lilac);
}
.choice__note:empty {
  display: none;
}
.choice__item,
.consent__item {
  position: relative;
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: var(--f-ctl);
  padding: 9px 14px;
  border: 1px solid rgba(247, 247, 250, 0.16);
  border-radius: var(--f-r);
  background: rgba(247, 247, 250, 0.05);
  font-size: var(--f-body);
  line-height: 1.3;
  cursor: pointer;
  transition:
    border-color 0.2s var(--ease),
    background-color 0.2s var(--ease);
}
.choice__item:hover,
.consent__item:hover {
  border-color: rgba(247, 247, 250, 0.3);
}
.choice__item:has(input:checked) {
  border-color: rgba(181, 170, 255, 0.6);
  background: rgba(129, 112, 255, 0.16);
}
.choice__item input {
  flex: none;
  width: 18px;
  height: 18px;
  margin: 0;
  border: 1.5px solid rgba(247, 247, 250, 0.5);
  border-radius: 50%;
  background: transparent;
  -webkit-appearance: none;
  appearance: none;
  cursor: pointer;
  transition:
    border-color 0.2s var(--ease),
    background-color 0.2s var(--ease),
    box-shadow 0.2s var(--ease);
}
.choice__item input:checked {
  border-color: var(--lilac);
  box-shadow: inset 0 0 0 3.5px #1c1858;
  background: var(--lilac);
}
.choice__item input:focus-visible {
  outline: 2px solid var(--ice);
  outline-offset: 3px;
}
/* the checkbox: the native one, invisible, over a drawn box */
.consent__item input {
  position: absolute;
  z-index: 1;
  left: 14px;
  top: 12px;
  width: 18px;
  height: 18px;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.consent__box {
  position: relative;
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 1px;
  border: 1.5px solid rgba(247, 247, 250, 0.5);
  border-radius: 5px;
  transition:
    border-color 0.2s var(--ease),
    background-color 0.2s var(--ease);
}
.consent__box::after {
  content: "";
  position: absolute;
  left: 4.5px;
  top: 1px;
  width: 5px;
  height: 9px;
  border: solid var(--midnight);
  border-width: 0 2px 2px 0;
  opacity: 0;
  transform: rotate(45deg) scale(0.6);
  transition:
    opacity 0.15s var(--ease),
    transform 0.2s var(--ease);
}
.consent__item input:checked + .consent__box {
  border-color: var(--violet);
  background: var(--violet);
}
.consent__item input:checked + .consent__box::after {
  opacity: 1;
  transform: rotate(45deg);
}
.consent__item input:focus-visible + .consent__box {
  outline: 2px solid var(--ice);
  outline-offset: 3px;
}
.consent__item input[aria-invalid="true"] + .consent__box {
  border-color: var(--danger);
}
.consent {
  margin-top: -6px;
}
.consent__item {
  align-items: flex-start;
  padding-top: 11px;
  padding-bottom: 11px;
  font-size: var(--f-small);
  line-height: 1.5;
}
.consent__item a {
  color: var(--lilac);
  text-decoration: underline;
}
.consent__item:has([aria-invalid="true"]) {
  border-color: var(--danger);
}
/* the trap for bots: out of sight, out of the tab order */
.hp {
  position: absolute;
  left: -10000px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}
/* The anti-robot check (Cloudflare Turnstile, src/turnstile.js), right above
   the buttons. The place of its widget (65 px high; 150 × 140 when compact,
   below 300 px of width, as src/turnstile.js decides: FLEXIBLE_MIN) is kept
   from the moment the form opens, so nothing moves when it comes. The box
   is a size container for that: its width is the widget's. The widget draws
   itself in an iframe of Cloudflare (dark theme); its message goes under it,
   kept in the accessibility tree when empty (read out when it comes). */
.robot[hidden] {
  display: none;
}
.robot {
  display: grid;
  gap: 10px;
  margin-top: -6px;
  border-radius: 12px;
  container-type: inline-size;
}
.robot:focus {
  outline: none;
}
.robot:focus-visible {
  outline: 2px solid var(--ice);
  outline-offset: 4px;
}
.robot__widget {
  min-width: 0;
  min-height: 65px;
}
.robot__widget[data-size="compact"] {
  min-height: 140px;
}
.robot__widget iframe {
  display: block;
}
/* the script did not arrive: only the message, no empty place */
.robot[data-state="failed"] .robot__widget {
  display: none;
}
.robot__wait,
.robot__mock {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 65px;
  padding: 10px 14px;
  border: 1px solid rgba(247, 247, 250, 0.14);
  border-radius: var(--f-r);
  background: rgba(247, 247, 250, 0.04);
  font-size: var(--f-small);
  line-height: 1.4;
  color: var(--text-3);
}
/* the preview: where the check goes, clearly not the real one */
.robot__mock {
  border-style: dashed;
  border-color: rgba(247, 247, 250, 0.3);
  color: var(--text-2);
}
.robot__mock::before {
  content: "";
  flex: none;
  width: 18px;
  height: 18px;
  border: 1.5px solid rgba(247, 247, 250, 0.5);
  border-radius: 5px;
}
/* the compact widget's place, already while the script is on its way */
@container (width < 299.5px) {
  .robot__wait {
    min-height: 140px;
  }
}
.robot__msg {
  font-size: var(--f-small);
  line-height: 1.45;
  color: var(--text-2);
}
.robot__msg:empty {
  position: absolute;
}
.robot[aria-invalid="true"] .robot__msg {
  color: var(--danger);
}
.robot__msg a {
  color: var(--ice);
  font-weight: 600;
}
.form__status:empty {
  display: none;
}
.form__status {
  margin-top: -6px;
  padding: 12px 16px;
  border: 1px solid rgba(255, 180, 192, 0.4);
  border-radius: var(--f-card);
  background: rgba(255, 120, 150, 0.1);
  font-size: var(--f-small);
  line-height: 1.5;
}
.form__status a {
  color: var(--ice);
  font-weight: 600;
}
/* the buttons of a step stay at the bottom of the sheet while it scrolls */
.form__nav {
  position: sticky;
  z-index: 2;
  bottom: 0;
  display: flex;
  gap: 10px;
  margin: auto -22px 0;
  padding: 12px 22px calc(env(safe-area-inset-bottom, 0px) + 12px);
  border-top: 1px solid rgba(247, 247, 250, 0.1);
  background: rgba(11, 15, 54, 0.96);
  -webkit-backdrop-filter: blur(20px) saturate(160%);
  backdrop-filter: blur(20px) saturate(160%);
}
.form__nav .btn {
  flex: 1 1 auto;
  min-height: var(--f-ctl);
  font-size: var(--f-body);
}
.form__nav .form__back {
  flex: 0 0 auto;
  padding: 0 20px;
}
/* while sending the button stays focusable (aria-disabled, src/form.js) */
.form__nav .btn[aria-disabled="true"] {
  opacity: 0.7;
  cursor: progress;
}
.sheet__done {
  display: grid;
  justify-items: start;
  gap: 12px;
  padding: 24px 22px calc(env(safe-area-inset-bottom, 0px) + 32px);
}
.sheet__done[hidden] {
  display: none;
}
.sheet__done-o {
  width: 48px;
  height: 48px;
  margin-bottom: 4px;
  border-radius: 50%;
  background: linear-gradient(180deg, var(--o1), var(--o2) 50%, var(--o3));
  -webkit-mask: radial-gradient(circle, transparent 15.5px, #000 16.1px);
  mask: radial-gradient(circle, transparent 15.5px, #000 16.1px);
}
.sheet__done h3 {
  font-size: 1.625rem;
  line-height: 1.1;
}
.sheet__done h3:focus {
  outline: none;
}
.sheet__done p {
  max-width: 30rem;
  color: var(--text-2);
}
.sheet__done .sheet__preview {
  padding: 8px 14px;
  border: 1px dashed rgba(247, 247, 250, 0.3);
  border-radius: var(--f-r);
  font-size: var(--f-small);
}
.sheet__done .btn {
  min-height: var(--f-ctl);
  font-size: var(--f-body);
}
.sheet__done .btn {
  margin-top: 12px;
}

/* ---------- phone, story: the light above, the copy of each beat below ----------
   Each beat rises, holds at --hold-top (set by src/main.js, about the middle
   of the screen) while the light shows it, then fades as it leaves. The
   empty block after the copy is the length of the hold. */
.story .sol.panel {
  justify-content: flex-start;
  padding-top: 10vh;
  padding-top: 10svh;
  padding-bottom: 0;
}
.story .sol.panel:first-of-type {
  padding-top: 34vh;
  padding-top: 34svh;
}
.story .sol > .copy {
  position: sticky;
  top: var(--hold, var(--hold-top, 54svh));
}
.story .sol.panel::after {
  content: "";
  flex: none;
  height: 28vh;
  height: 28svh;
}
.story .solutions__head {
  padding-top: 24px;
}
/* the heading comes alone (the light is out: pose "standby"); the phone of
   light forms after it, above the first beat */
.story .along__head {
  padding-top: 24vh;
  padding-top: 24svh;
}
/* "Scopri le soluzioni" from the hero lands with its heading on the hold line */
.story #soluzioni {
  scroll-margin-top: calc(var(--hold-top, 54svh) - var(--bar-h) - 36px);
}
.story .how {
  padding-top: 112px;
}
.story .contact.panel {
  padding-top: 72px;
}

/* ---------- short phones: a little less type, so the light keeps its room ---------- */
@media (max-width: 760px) and (max-height: 760px) {
  .story .sol__lead {
    display: none;
  }
  .sol .copy h3 {
    font-size: 1.875rem;
  }
  .sol.feat .copy h3 {
    font-size: 1.3125rem;
  }
  .sol .ticks {
    font-size: 0.875rem;
    gap: 4px;
  }
  .badge {
    margin-bottom: 10px;
  }
}
@media (max-width: 760px) and (max-height: 700px) {
  h1 {
    font-size: clamp(2.25rem, 10.2vw, 2.9rem);
  }
  .lead {
    margin-top: 12px;
    font-size: 1rem;
  }
  .actions {
    gap: 10px;
    margin-top: 20px;
  }
  .actions .btn {
    min-height: 48px;
  }
}

/* ---------- desktop ---------- */
@media (min-width: 761px) and (min-aspect-ratio: 4001/5000) {
  :root {
    --bar-h: 76px;
    --fab-room: 104px;
  }
  body {
    font-size: 1.0625rem;
  }
  .bar {
    gap: 20px;
  }
  .bar__logo img {
    width: 136px;
  }
  .bar__nav {
    display: block;
  }
  .bar__nav ul {
    display: flex;
    gap: 2px;
  }
  .bar__nav a {
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 14px;
    border-radius: 999px;
    color: var(--text-2);
    font-size: 0.9375rem;
    text-decoration: none;
    transition: color 0.2s var(--ease);
  }
  .bar__nav a:hover {
    color: var(--ice);
  }

  .fab {
    left: auto;
    right: 28px;
    bottom: 28px;
    min-height: 56px;
    padding: 0 26px 0 18px;
    font-size: 1rem;
    transform: none;
  }
  .fab:active {
    transform: scale(0.97);
  }
  .form-open .fab,
  .intro-play .fab {
    transform: translateY(18px);
  }

  h1 {
    font-size: clamp(3.4rem, 6vw, 6.4rem);
    line-height: 0.98;
  }
  h2,
  .sol .copy h3 {
    font-size: clamp(2.4rem, 3.5vw, 3.6rem);
  }
  h3 {
    font-size: clamp(1.375rem, 1.6vw, 1.6rem);
  }
  .lead {
    margin-top: 22px;
    font-size: clamp(1.125rem, 1.3vw, 1.3rem);
  }
  .actions {
    margin-top: 34px;
  }
  .btn--down {
    min-height: 52px;
    padding: 0 24px;
    border-color: rgba(247, 247, 250, 0.36);
    color: var(--ice);
    text-decoration: none;
  }
  .btn--down:hover {
    border-color: var(--ice);
    background: rgba(247, 247, 250, 0.06);
  }
  .btn--down:focus-visible {
    border-radius: 999px;
    outline-offset: 4px;
  }

  .panel {
    justify-content: center;
    padding: calc(var(--bar-h) + 56px) var(--gutter) 88px;
  }
  .copy {
    max-width: min(40vw, 34rem);
  }

  .opening {
    --mark-w: min(42vw, 600px);
  }

  /* desktop: the band right of centre (pose "band", layout d) */
  .hero {
    display: flex;
    padding-bottom: 72px;
  }
  .hero__light {
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    height: 100vh;
    height: 100lvh;
  }
  .hero__light .light {
    left: 65%;
    top: 50%;
    width: min(72.91vh, 52.5vw);
    width: min(72.91lvh, 52.5vw);
    height: auto;
    transform: translate(-50%, -50%);
  }
  .hero__copy {
    align-self: auto;
    max-width: min(42vw, 36rem);
  }
  .hero__copy::before,
  .story .panel > .copy::before,
  .story .solutions__head .copy::before,
  .story .along__head .copy::before {
    left: -12%;
    right: -12%;
    width: auto;
    top: -18%;
    bottom: -18%;
    background: radial-gradient(closest-side, rgba(0, 6, 36, 0.72), rgba(0, 6, 36, 0));
  }

  .solutions__head {
    padding-top: 120px;
  }
  /* without the light: the poster beside the copy */
  html:not(.story) .sol.panel {
    flex-direction: row;
    align-items: center;
    justify-content: flex-start;
    gap: 6vw;
  }
  .sol__poster {
    flex: none;
    width: min(36vw, 460px);
    margin: 0;
  }
  .sol__poster--card {
    width: min(30vw, 380px);
  }
  .sol + .sol {
    padding-top: calc(var(--bar-h) + 56px);
  }

  .how {
    padding-top: 140px;
  }
  .steps {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 32px;
    margin-top: 48px;
  }
  .step {
    display: block;
  }
  .step::before {
    left: 60px;
    right: -26px;
    top: 26px;
    bottom: auto;
    width: auto;
    height: 1px;
    background: linear-gradient(90deg, rgba(129, 112, 255, 0.5), rgba(129, 112, 255, 0.1));
  }
  .step__n {
    width: 52px;
    height: 52px;
    font-size: 1.5rem;
  }
  .step h3 {
    padding-top: 24px;
    font-size: clamp(1.375rem, 1.7vw, 1.75rem);
  }
  .step p {
    margin-top: 10px;
  }

  .along {
    padding-bottom: 72px;
  }
  .along__head {
    padding-top: 120px;
  }

  .events {
    padding-top: 140px;
    padding-bottom: 72px;
  }
  .events__head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: 16px 48px;
  }
  .events__head h2,
  .events__head > p:not(.events__note) {
    grid-column: 1;
  }
  .events__note {
    grid-column: 2;
    grid-row: 1 / span 2;
    align-self: end;
  }
  .reel {
    --shot-w: clamp(220px, 19vw, 300px);
    --shot-gap: 18px;
    margin-top: 44px;
  }
  .shot {
    border-radius: 28px;
  }
  .shot figcaption {
    padding: 56px 20px 18px;
  }
  .shot strong {
    font-size: 1.1875rem;
  }

  .contact.panel {
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    gap: 6vw;
    padding-bottom: 96px;
  }
  .contact__light {
    order: 0;
    width: min(40vw, 520px);
    margin: 0;
  }
  .story .contact__light {
    display: none;
  }

  .foot {
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: end;
    gap: 24px 56px;
    padding-top: 40px;
  }
  .foot__end {
    grid-column: 1 / -1;
    padding-right: 300px;
  }

  /* the form: a panel in the middle of the screen */
  .sheet__panel {
    left: 50%;
    right: auto;
    top: 50%;
    bottom: auto;
    width: min(720px, calc(100vw - 48px));
    max-height: calc(100vh - 32px);
    max-height: calc(100dvh - 32px);
    border-bottom: 1px solid rgba(214, 208, 255, 0.2);
    border-radius: 28px;
    box-shadow:
      inset 0 1px 0 rgba(255, 255, 255, 0.16),
      0 40px 120px rgba(0, 3, 20, 0.6);
    opacity: 0;
    transform: translate(-50%, calc(-50% + 18px)) scale(0.97);
    transition:
      transform 0.4s var(--ease),
      opacity 0.3s var(--ease);
  }
  .sheet.is-open .sheet__panel {
    opacity: 1;
    transform: translate(-50%, -50%);
  }
  .sheet.is-closing .sheet__panel {
    transition-duration: 0.25s;
  }
  .sheet__panel::before {
    content: none;
  }
  /* with the light, the form steps a little to the left and the light
     stands to its right, half behind the glass */
  .stage-live.form-light .sheet__panel {
    /* never closer than 24px to the left edge */
    left: max(calc(50% - min(9vw, 130px)), calc(24px + min(360px, 50vw - 24px)));
    background:
      linear-gradient(180deg, rgba(255, 255, 255, 0.07), rgba(255, 255, 255, 0) 180px),
      linear-gradient(90deg, rgba(8, 12, 50, 0.74) 45%, rgba(8, 12, 50, 0.5));
    -webkit-backdrop-filter: blur(22px) saturate(170%);
    backdrop-filter: blur(22px) saturate(170%);
  }
  /* between the steps the height follows the content (src/form.js) */
  .sheet__panel.is-resizing {
    overflow: hidden;
    transition:
      transform 0.4s var(--ease),
      opacity 0.3s var(--ease),
      height 0.4s var(--ease);
  }
  .sheet {
    --f-ctl: 44px;
  }
  .sheet__head {
    padding: 22px 22px 12px 32px;
    touch-action: auto;
  }
  .sheet__head h2 {
    position: static;
    flex: 1 1 0;
    min-width: 0;
    width: auto;
    height: auto;
    margin: 0;
    overflow: visible;
    clip: auto;
    white-space: normal;
    font-size: 1.5rem;
  }
  .stepper {
    flex: 1 0 100%;
    order: 0;
    gap: 12px;
    margin-top: 12px;
  }
  .form {
    padding: 8px 32px 0;
  }
  .form__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 16px;
  }
  .field--wide {
    grid-column: 1 / -1;
  }
  /* the switch beside the question, the number under it */
  .people {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "q unsure" "value value" "track track" "scale scale" "err err";
    align-items: center;
  }
  .toggle {
    justify-self: end;
    margin-top: 0;
  }
  .form__step {
    gap: 20px;
  }
  .people__value {
    margin-top: 8px;
  }
  .people__value output {
    font-size: 2.25rem;
  }
  .advice {
    gap: 16px;
    margin-top: -4px;
    padding: 12px 20px 12px 14px;
  }
  .advice__art {
    width: 52px;
    height: 52px;
  }
  .advice__name {
    font-size: 1.125rem;
  }
  .choice__options {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .form__nav {
    justify-content: flex-end;
    margin: auto -32px 0;
    padding: 14px 32px 20px;
  }
  .form__nav .btn {
    flex: 0 0 auto;
    min-width: 140px;
  }
  .form__nav .form__send {
    min-width: 188px;
  }
  .form__nav .form__back {
    min-width: 0;
    margin-right: auto;
  }
  .sheet__done {
    padding: 28px 32px 40px;
  }

  /* story: copy beside the light, which moves between the sides */
  .story .panel {
    min-height: 100vh;
    padding-bottom: 88px;
  }
  /* the hero: the band alone in the middle, then the copy on the left while
     the band moves to the right */
  .story .hero.panel {
    padding: var(--hero-hold, 30vh) var(--gutter) 0;
  }
  .story .hero.panel::after {
    height: 76vh;
  }
  .story .hero__light {
    height: 100vh;
    height: 100lvh;
  }
  .story .hero__light .light {
    left: 50%;
    width: min(92vh, 62vw);
    width: min(92lvh, 62vw);
  }
  .story .hero__cue {
    top: calc(100vh - 92px);
  }
  .story .panel--right {
    align-items: flex-end;
  }
  /* the band stays on the right while the heading passes on the left */
  .story .solutions__head {
    padding-top: 22vh;
    padding-bottom: 14vh;
  }
  /* «Con te dal primo ingresso»: the heading on the right, where the copy
     of its beats comes; the phone of light appears on the left after it */
  .story .along__head {
    display: flex;
    justify-content: flex-end;
    padding: 30vh var(--gutter) 6vh;
  }
  .story .sol.panel {
    justify-content: center;
    padding: calc(var(--bar-h) + 56px) var(--gutter) 88px;
  }
  .story .sol > .copy {
    position: relative;
    top: auto;
  }
  .story .sol.panel::after {
    content: none;
  }
  .story .how {
    padding-top: 160px;
  }
  .story .contact.panel {
    padding-top: calc(var(--bar-h) + 104px);
  }
  .story #soluzioni {
    scroll-margin-top: 0;
  }
}

/* narrow desktop: the heading of the solutions stays clear of the band */
@media (min-width: 761px) and (max-width: 1179px) and (min-aspect-ratio: 4001/5000) {
  .story .solutions__head .copy {
    max-width: 36vw;
  }
}

/* wide desktop with the light: dense blocks leave the right side to the light */
@media (min-width: 1180px) and (min-aspect-ratio: 4001/5000) {
  .story .how {
    width: 74vw;
    padding-right: 0;
  }
  .story .steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 64px;
    row-gap: 48px;
  }
  .story .step:nth-child(2n)::before {
    content: none;
  }
}

/* ---------- short wide screens (a phone held sideways) ----------
   The desktop layout, smaller: a lower header and floating button, smaller
   type and less padding, so each block reads whole between them. */
@media (min-width: 761px) and (min-aspect-ratio: 4001/5000) and (max-height: 500px) {
  :root {
    --bar-h: 52px;
    --fab-room: 64px;
  }
  body {
    font-size: 0.9375rem;
  }
  .bar__logo img {
    width: 104px;
  }
  .bar__nav a {
    min-height: 40px;
    padding: 0 10px;
    font-size: 0.875rem;
  }
  .fab {
    right: calc(env(safe-area-inset-right, 0px) + 16px);
    bottom: calc(env(safe-area-inset-bottom, 0px) + 10px);
    gap: 8px;
    min-height: 44px;
    padding: 0 18px 0 12px;
    font-size: 0.875rem;
  }
  h1 {
    font-size: clamp(2.2rem, 4.6vw, 3rem);
  }
  h2,
  .sol .copy h3 {
    font-size: clamp(1.625rem, 3.2vw, 2.1rem);
  }
  h3 {
    font-size: 1.25rem;
  }
  .lead {
    margin-top: 12px;
    font-size: 1rem;
  }
  .actions {
    margin-top: 16px;
  }
  .btn--down {
    min-height: 44px;
  }
  .panel,
  .story .panel,
  .story .sol.panel {
    padding: calc(var(--bar-h) + 16px) var(--gutter) var(--fab-room);
  }
  .copy {
    max-width: min(50vw, 34rem);
  }
  .hero__copy {
    max-width: min(48vw, 34rem);
  }
  .story .sol__lead {
    display: none;
  }
  .badge {
    margin-bottom: 8px;
  }
  .sol .ticks {
    gap: 2px;
    margin-top: 10px;
    font-size: 0.875rem;
  }
  .story .how {
    padding-top: 88px;
  }
  /* no room for the cue under the band */
  .story .hero__cue {
    display: none;
  }
}

/* ---------- text pages: privacy ---------- */
.doc {
  position: relative;
  z-index: 1;
  padding: calc(var(--bar-h) + env(safe-area-inset-top, 0px) + 28px) var(--gutter) 64px;
}
.doc__inner {
  max-width: 46rem;
}
.doc h1 {
  font-size: clamp(2.4rem, 9vw, 3.6rem);
}
.doc__updated {
  margin-top: 14px;
  color: var(--text-2);
  font-size: 0.9375rem;
}
.doc h2 {
  margin-top: 48px;
  font-size: clamp(1.5rem, 5.6vw, 2rem);
  line-height: 1.15;
}
.doc p,
.doc li {
  color: var(--text-2);
}
.doc p {
  margin-top: 14px;
}
.doc strong {
  color: var(--ice);
  font-weight: 600;
}
.doc ul.ticks {
  display: grid;
  gap: 8px;
  margin-top: 14px;
}
.doc a {
  color: var(--lilac);
}
.doc table {
  width: 100%;
  margin-top: 18px;
  border-collapse: collapse;
  font-size: 0.9375rem;
  line-height: 1.5;
}
.doc th,
.doc td {
  padding: 12px 14px;
  border-top: 1px solid var(--line);
  text-align: left;
  vertical-align: top;
}
.doc thead th {
  border-top: 0;
  color: var(--ice);
  font-weight: 600;
  font-size: 0.875rem;
}
.doc td {
  color: var(--text-2);
}
.doc td:first-child {
  color: var(--ice);
}
/* phone: each row of a table is a small card */
@media (max-width: 760px) {
  .doc table,
  .doc tbody,
  .doc tr,
  .doc td {
    display: block;
  }
  .doc thead {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
  }
  .doc tr {
    margin-top: 12px;
    padding: 6px 16px;
    border: 1px solid var(--line);
    border-radius: 18px;
    background: var(--surface);
  }
  .doc td {
    padding: 10px 0;
    border-top: 0;
  }
  .doc td + td {
    border-top: 1px solid var(--line);
  }
  .doc td::before {
    content: attr(data-label);
    display: block;
    margin-bottom: 2px;
    color: var(--text-3);
    font-weight: 600;
    font-size: 0.8125rem;
  }
}
.doc + .foot {
  padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 28px);
}
.doc + .foot .foot__end {
  padding-right: 0;
}

/* ---------- 404 ---------- */
.lost {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  min-height: 100vh;
  min-height: 100svh;
  padding: calc(var(--bar-h) + 48px) var(--gutter) 12vh;
  overflow: hidden;
}
/* the circle of the sign, above the copy on the phone, beside it on desktop */
.lost::before {
  content: "";
  position: absolute;
  z-index: -1;
  right: -34vw;
  top: calc(var(--bar-h) + 5vh);
  width: 76vw;
  aspect-ratio: 1;
  border: 1.5px solid rgba(129, 112, 255, 0.4);
  border-radius: 50%;
  pointer-events: none;
}
.lost .copy p {
  margin-top: 16px;
}
.lost .actions {
  margin-top: 30px;
}
.lost + .foot {
  padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 28px);
}
.lost + .foot .foot__end {
  padding-right: 0;
}
@media (min-width: 761px) and (min-aspect-ratio: 4001/5000) {
  .lost {
    justify-content: center;
    padding-bottom: 64px;
  }
  .lost::before {
    right: -12vw;
    top: 50%;
    width: min(62vw, 78vh);
    transform: translateY(-50%);
  }
}

/* ---------- the form with the light: where glass cannot be clear ----------
   The rules of the light behind the form (above) are more specific than the
   fallbacks of the sheet, so they are repeated here: no blur → a solid
   panel and a darker page around it (on the phone the page is hidden while
   the form is open, so the light above the sheet stays bright); less
   transparency asked → a solid panel. */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
  .stage-live.form-light .sheet__panel {
    background: #0b103c;
  }
  .stage-live.form-light .sheet::backdrop {
    background: rgba(0, 3, 22, 0.78);
  }
  @media (max-width: 760px), (max-aspect-ratio: 4/5) {
    .stage-live.form-light .sheet::backdrop {
      background: rgba(0, 3, 22, 0.34);
    }
  }
}
@media (prefers-reduced-transparency: reduce) {
  .stage-live.form-light .sheet__panel {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: #0b103c;
  }
}
