/*
 * Plié — marketing site stylesheet.
 *
 * Consumes only the semantic `--color-*` / `--space-*` / `--radius-*` layer from
 * tokens.css, per DESIGN.md §8 ("never hard-code hex colors in UI").
 *
 * Sections, in order:
 *   1. Reset & base            6. App-component replicas (the phone mock)
 *   2. Layout primitives       7. Content blocks (steps, features, table, FAQ)
 *   3. Buttons & pills         8. Contact form
 *   4. Header & nav            9. Footer
 *   5. Heroes                 10. Motion & responsive
 */

/* ══ 1. Reset & base ═══════════════════════════════════════════════════════ */

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  /* Sticky header height + breathing room, so anchors don't land under the nav. */
  scroll-padding-top: 96px;
  -webkit-text-size-adjust: 100%;
}

body {
  margin: 0;
  background: var(--color-background-primary);
  color: var(--color-content-primary);
  font-family: var(--font-sans);
  font-size: var(--type-body-l);
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizelegibility;
}

img,
svg {
  display: block;
  max-width: 100%;
}

a {
  color: inherit;
  text-decoration: none;
}

button {
  font: inherit;
  color: inherit;
}

h1,
h2,
h3,
h4,
p,
figure,
ul,
ol {
  margin: 0;
}

ul,
ol {
  padding: 0;
  list-style: none;
}

:focus-visible {
  outline: 2px solid var(--color-interactive-focus-ring);
  outline-offset: 3px;
  border-radius: var(--radius-s);
}

/* ── Icons ────────────────────────────────────────────────────────────────
   Every glyph comes from the sprite injected at the top of <body>, generated
   from :core:design-system's ImageVectors (Phosphor regular + PlieIcons) by
   web/tools/build-icon-sprite.py. Colour is never set on the symbol — the
   sprite paths use `currentColor`, mirroring how Compose's `Icon` tints from
   the ambient content colour. */
.icon {
  display: inline-block;
  flex-shrink: 0;
  width: 1.5rem;
  height: 1.5rem;
  vertical-align: middle;
}

/* Phosphor's stroke scales with render size: the regular set draws ~1.5px at
   24px but only ~1px at 16px. Same trade-off as PhosphorBold in the app — here
   the sizes below stay at or above 20px wherever stroke weight matters. */
.icon--sm {
  width: 1rem;
  height: 1rem;
}

.icon--md {
  width: 1.25rem;
  height: 1.25rem;
}

.icon--lg {
  width: 1.75rem;
  height: 1.75rem;
}

/* Visible to assistive tech only — table captions, redundant labels. */
.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Skip link — first tab stop, hidden until focused. */
.skip-link {
  position: absolute;
  left: var(--space-l);
  top: var(--space-l);
  z-index: 100;
  padding: var(--space-m) var(--space-xl);
  background: var(--color-content-primary);
  color: var(--color-content-on-inverse);
  border-radius: var(--radius-pill);
  font-size: var(--type-label-l);
  font-weight: 500;
  transform: translateY(-200%);
  transition: transform var(--duration-fast) var(--ease-out);
}

.skip-link:focus-visible {
  transform: translateY(0);
}

/* ══ 2. Layout primitives ══════════════════════════════════════════════════ */

.wrap {
  width: 100%;
  max-width: var(--page-max);
  margin-inline: auto;
  padding-inline: var(--page-gutter);
}

.section {
  padding-block: var(--space-section);
}

.section--tight {
  padding-block: calc(var(--space-section) * 0.62);
}

.section--cream {
  background: var(--color-background-primary);
}

/* Warm off-white band, one notch away from the cream page — used to separate
   consecutive sections without introducing a new surface colour. */
.section--warm {
  background: var(--color-surface-warm);
}

.section--ink {
  background: var(--color-surface-ink);
  color: var(--color-on-ink-muted);
}

.section--ink .section-title,
.section--ink .stat__value {
  color: var(--color-content-on-inverse);
}

.section-head {
  max-width: 62ch;
  margin-bottom: var(--space-xxxxl);
}

.section-head--center {
  margin-inline: auto;
  text-align: center;
}

/* Standalone centered paragraph, e.g. the pricing footnote under a card grid. */
.section-note {
  max-width: 62ch;
  margin: var(--space-xxxl) auto 0;
  font-size: var(--type-body-l);
  line-height: 1.65;
  text-align: center;
  color: var(--color-content-secondary-warm);
  text-wrap: pretty;
}

.section-note a {
  color: var(--color-brand);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* SectionLabel — DESIGN.md §5: 11px Medium, uppercase, 0.08em tracking. */
/* Logo pleine taille en tête du hero : la seule occurrence du site où la
   baseline « On t'attendait » est assez grande pour se lire. Plafonné à 280 px
   et borné à 60 % de la colonne pour qu'il ne domine pas le titre. */
.hero__logo {
  display: block;
  width: min(280px, 60%);
  height: auto;
  margin-bottom: var(--space-xl);
}

.eyebrow {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  margin-bottom: var(--space-l);
  font-size: var(--type-label-s);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-content-tertiary);
}

.eyebrow::before {
  content: "";
  width: 18px;
  height: 2px;
  border-radius: var(--radius-pill);
  background: var(--color-brand);
}

.section--ink .eyebrow {
  color: var(--color-on-ink-subtle);
}

.section--ink .eyebrow::before {
  background: var(--color-tier-vip);
}

.section-title {
  font-size: var(--type-display-s);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.section-lead {
  margin-top: var(--space-l);
  font-size: var(--type-body-l);
  line-height: 1.65;
  color: var(--color-content-secondary-warm);
  text-wrap: pretty;
}

.section--ink .section-lead {
  color: var(--color-on-ink-muted);
}

.grid {
  display: grid;
  gap: var(--space-xxl);
}

.grid--2 {
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

.grid--3 {
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

.grid--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

/* ══ 3. Buttons & pills ════════════════════════════════════════════════════ */

/* PlieButton — pill CTA. Sizes map to PlieComponentSpec.Button heights. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-s);
  height: var(--btn-h-default);
  padding-inline: var(--space-xxl);
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  background: none;
  font-size: var(--type-label-l);
  font-weight: 500;
  line-height: 1;
  white-space: nowrap;
  cursor: pointer;
  transition:
    background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out),
    color var(--duration-fast) var(--ease-out),
    transform var(--duration-fast) var(--ease-out);
}

.btn:active {
  transform: translateY(1px);
}

.btn--lg {
  height: var(--btn-h-large);
  padding-inline: var(--space-xxxl);
  font-size: var(--type-title-m);
}

.btn--sm {
  height: var(--btn-h-small);
  padding-inline: var(--space-l);
  font-size: var(--type-label-m);
}

.btn--primary {
  background: var(--color-interactive-primary);
  color: var(--color-interactive-primary-content);
}

.btn--primary:hover {
  background: var(--color-interactive-primary-hover);
}

.btn--secondary {
  border-color: var(--color-interactive-secondary-border);
  color: var(--color-content-primary);
}

.btn--secondary:hover {
  background: var(--color-content-primary);
  color: var(--color-content-on-inverse);
}

/* On the wine hero band the black-bordered secondary disappears — invert it. */
.btn--on-ink {
  border-color: var(--color-on-ink-subtle);
  color: var(--color-content-on-inverse);
}

.btn--on-ink:hover {
  background: var(--color-content-on-inverse);
  color: var(--color-surface-ink);
}

.btn--gold {
  background: var(--color-tier-vip);
  color: var(--color-on-gold);
}

.btn--gold:hover {
  background: var(--color-interactive-gold-hover);
}

.btn--ghost {
  color: var(--color-content-secondary-warm);
}

.btn--ghost:hover {
  background: var(--color-background-tertiary);
  color: var(--color-content-primary);
}

.btn--block {
  width: 100%;
}

.btn-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
}

/* PliePill / Badge — compact label. */
.pill {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: var(--chip-h);
  padding: 3px var(--space-m);
  border-radius: var(--radius-pill);
  font-size: var(--type-label-m);
  font-weight: 500;
  line-height: 1.4;
}

.pill--brand {
  background: var(--color-brand-container);
  color: var(--color-on-brand-container);
}

.pill--discount {
  background: var(--color-discount);
  color: var(--color-on-discount);
}

.pill--offer {
  background: var(--color-offer-background);
  color: var(--color-on-offer);
}

.pill--tier-vip {
  background: var(--color-tier-vip);
  color: var(--color-on-gold);
}

.pill--glass {
  background: var(--color-surface-glass);
  color: var(--color-content-primary);
}

.pill--outline-ink {
  border: 1px solid var(--color-on-ink-subtle);
  color: var(--color-on-ink-muted);
}

/* ══ 4. Header & nav ═══════════════════════════════════════════════════════ */

.site-header {
  position: sticky;
  top: 0;
  z-index: 50;
  background: color-mix(in srgb, var(--color-background-primary) 82%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid transparent;
  transition:
    border-color var(--duration-base) var(--ease-out),
    background-color var(--duration-base) var(--ease-out);
}

.site-header.is-stuck {
  border-bottom-color: var(--color-border-subtle);
  background: color-mix(in srgb, var(--color-background-primary) 94%, transparent);
}

.site-header--pro {
  background: color-mix(in srgb, var(--color-surface-ink) 84%, transparent);
  color: var(--color-on-ink-muted);
}

.site-header--pro.is-stuck {
  background: color-mix(in srgb, var(--color-surface-ink) 97%, transparent);
  border-bottom-color: var(--color-ink-border);
}

.nav {
  display: flex;
  align-items: center;
  gap: var(--space-xxl);
  height: 72px;
}

.nav__logo {
  display: flex;
  align-items: center;
  flex-shrink: 0;
}

.nav__logo img {
  /* 40 plutôt que 34 : la barre porte la MARQUE SEULE (logo-plie-mark.svg,
     251 × 182), un bloc quasi carré et non un lockup horizontal — à 34 px elle
     ne pèse plus rien dans la barre. */
  height: 40px;
  width: auto;
}

.nav__links {
  display: flex;
  align-items: center;
  gap: var(--space-xl);
  margin-left: auto;
}

.nav__link {
  position: relative;
  padding-block: var(--space-s);
  font-size: var(--type-label-l);
  font-weight: 500;
  color: var(--color-content-secondary-warm);
  transition: color var(--duration-fast) var(--ease-out);
}

.site-header--pro .nav__link {
  color: var(--color-on-ink-muted);
}

/* Seule entrée de menu à porter une icône : c'est la seule qui mène à une
   offre payante. La couronne est dorée même quand le libellé est en retrait,
   de sorte que l'entrée se repère sans avoir à lire la barre. */
.nav__link--premium {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.nav__link--premium .icon {
  color: var(--color-interactive-gold);
}

.nav__link::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 2px;
  width: 100%;
  height: 1.5px;
  border-radius: var(--radius-pill);
  background: currentcolor;
  transform: scaleX(0);
  transform-origin: left;
  transition: transform var(--duration-base) var(--ease-out);
}

.nav__link:hover {
  color: var(--color-content-primary);
}

.site-header--pro .nav__link:hover {
  color: var(--color-content-on-inverse);
}

.nav__link:hover::after {
  transform: scaleX(1);
}

.nav__actions {
  display: flex;
  align-items: center;
  gap: var(--space-m);
}

.nav__toggle {
  display: none;
  align-items: center;
  justify-content: center;
  width: 42px;
  height: 42px;
  margin-left: auto;
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-pill);
  background: none;
  cursor: pointer;
}

.site-header--pro .nav__toggle {
  border-color: var(--color-on-ink-subtle);
}

.nav__toggle span {
  display: block;
  width: 16px;
  height: 1.5px;
  border-radius: var(--radius-pill);
  background: currentcolor;
  transition: transform var(--duration-base) var(--ease-out),
    opacity var(--duration-fast) var(--ease-out);
}

.nav__toggle span + span {
  margin-top: 4px;
}

.nav__toggle[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(5.5px) rotate(45deg);
}

.nav__toggle[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

.nav__toggle[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-5.5px) rotate(-45deg);
}

/* ══ 5. Heroes ═════════════════════════════════════════════════════════════ */

.hero {
  position: relative;
  overflow: hidden;
  padding-block: clamp(48px, 7vw, 88px) var(--space-section);
}

/* The "fold" motif: two soft washes meeting on a diagonal, echoing the logo. */
.hero::before,
.hero::after {
  content: "";
  position: absolute;
  z-index: 0;
  border-radius: 50%;
  filter: blur(90px);
  pointer-events: none;
}

.hero::before {
  top: -14%;
  right: -6%;
  width: 46vw;
  height: 46vw;
  max-width: 640px;
  max-height: 640px;
  background: var(--color-wash-rose);
}

.hero::after {
  bottom: -22%;
  left: -10%;
  width: 34vw;
  height: 34vw;
  max-width: 460px;
  max-height: 460px;
  background: var(--color-wash-gold);
}

.hero__inner {
  position: relative;
  z-index: 1;
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr);
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

.hero__title {
  font-size: var(--type-display-l);
  font-weight: 700;
  line-height: 1.06;
  letter-spacing: -0.03em;
  text-wrap: balance;
}

.hero__title em {
  font-style: normal;
  color: var(--color-brand);
}

/* For a headline carrying a full two-sentence message rather than a short
   punchline: a notch smaller, so it still dominates without pushing the CTA
   below the fold. */
.hero__title--long {
  font-size: clamp(32px, 4.4vw, 44px);
  line-height: 1.14;
  letter-spacing: -0.02em;
}

.hero__lead {
  max-width: 52ch;
  margin-top: var(--space-xxl);
  font-size: clamp(16px, 1.5vw, 19px);
  line-height: 1.62;
  color: var(--color-content-secondary-warm);
  text-wrap: pretty;
}

.hero__cta {
  margin-top: var(--space-xxxl);
}

.hero__note {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s) var(--space-l);
  margin-top: var(--space-xxl);
  font-size: var(--type-body-m);
  color: var(--color-content-tertiary);
}

.hero__note-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

/* B2B hero — deep wine band, so the merchant space reads as a distinct world. */
.hero--pro {
  background: var(--color-surface-ink);
  color: var(--color-on-ink-muted);
}

.hero--pro::before {
  background: var(--color-wash-wine);
}

.hero--pro::after {
  background: var(--color-wash-brick);
}

.hero--pro .hero__title {
  color: var(--color-content-on-inverse);
}

.hero--pro .hero__title em {
  color: var(--color-tier-vip);
}

.hero--pro .hero__lead {
  color: var(--color-on-ink-muted);
}

.hero--pro .hero__note {
  color: var(--color-on-ink-subtle);
}

/* ── Store badges (App Store / Google Play placeholders) ──────────────────── */

.store-badges {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
}

.store-badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-m);
  height: var(--btn-h-large);
  padding-inline: var(--space-xl);
  border-radius: var(--radius-xl);
  background: var(--color-content-primary);
  color: var(--color-content-on-inverse);
  transition: transform var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}

.store-badge:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-lifted);
}

.store-badge__text {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
}

.store-badge__top {
  font-size: 10px;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.72;
}

.store-badge__bottom {
  font-size: var(--type-title-m);
  font-weight: 600;
}

/* ── Store badges, "coming soon" state ────────────────────────────────────
   The apps aren't published yet, so these are rendered as <span>, not <a>:
   nothing to click, nothing that pretends to lead somewhere. Muted so they
   read as a promise rather than an action, and never compete with the beta
   form beside them. */
.store-badge--soon {
  background: transparent;
  border: 1px dashed var(--color-border-default);
  color: var(--color-content-tertiary);
  cursor: default;
}

.store-badge--soon:hover {
  transform: none;
  box-shadow: none;
}

.hero--pro .store-badge--soon {
  border-color: var(--color-ink-border);
  color: var(--color-on-ink-subtle);
}

/* ── Beta signup form ─────────────────────────────────────────────────────
   Single-field email capture. The row collapses to a stack below 560px so the
   input never shrinks under a comfortable tap target. */
.beta-form {
  max-width: 520px;
}

.beta-form__title {
  margin-bottom: var(--space-m);
  font-size: var(--type-title-m);
  font-weight: 600;
  line-height: 1.4;
  text-wrap: pretty;
}

.beta-form__row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-m);
}

.beta-form__row .field {
  flex: 1 1 auto;
  min-width: 0;
}

.beta-form__row .btn {
  flex-shrink: 0;
}

.beta-form__note {
  margin-top: var(--space-m);
  font-size: var(--type-body-s);
  line-height: 1.55;
  color: var(--color-content-tertiary);
}

.beta-form__note a {
  color: var(--color-brand);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* On the wine CTA band the neutral field disappears — lift it onto white and
   swap the accents that would otherwise vanish against the dark ground. */
.beta-form--on-ink {
  margin-inline: auto;
}

/* The band form carries three fields (e-mail, city, shop) where the hero form
   carries one: let them wrap onto a second line rather than squeezing every
   placeholder into an unreadable sliver. The hero row is left untouched. */
.beta-form--on-ink .beta-form__row {
  flex-wrap: wrap;
}

.beta-form--on-ink .beta-form__row .field {
  flex: 1 1 220px;
}

.beta-form--on-ink .field input {
  background: var(--color-surface-card);
  border-color: transparent;
}

.beta-form--on-ink .field input:focus {
  border-color: var(--color-interactive-gold);
}

.beta-form--on-ink .beta-form__note {
  color: var(--color-on-ink-muted);
}

.beta-form--on-ink .beta-form__note a {
  color: var(--color-interactive-gold);
}

.beta-form--on-ink .field__error {
  color: var(--color-tier-vip);
}

.beta-form--on-ink .field[data-invalid="true"] input {
  border-color: var(--color-tier-vip);
  background: var(--color-surface-card);
}

@media (max-width: 560px) {
  .beta-form__row {
    flex-direction: column;
    align-items: stretch;
  }

  .beta-form__row .btn {
    width: 100%;
  }
}

/* ══ 6. App-component replicas (the phone mock) ════════════════════════════ */
/* Faithful HTML/CSS restatements of :core:design-system composables, so the site
   shows the real product rather than a generic illustration. */

.phone {
  position: relative;
  width: min(320px, 100%);
  margin-inline: auto;
  padding: 12px;
  border-radius: 44px;
  background: var(--color-content-primary);
  box-shadow: var(--shadow-lifted);
}

.phone__screen {
  position: relative;
  overflow: hidden;
  padding: var(--space-xxl) var(--space-l) var(--space-xxxl);
  border-radius: 34px;
  background: var(--color-background-primary);
  /* Reset the inherited colour: on the wine hero the page text is rose-pale,
     which would wash out against the app's light screen. */
  color: var(--color-content-primary);
}

.phone__notch {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  width: 92px;
  height: 22px;
  border-radius: var(--radius-pill);
  background: var(--color-content-primary);
  z-index: 3;
}

.phone__stack {
  display: grid;
  gap: var(--space-l);
  margin-top: var(--space-xl);
}

/* SearchBar — pill field on a tinted surface. */
.app-search {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  height: 44px;
  padding-inline: var(--space-l);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-pill);
  background: var(--color-surface-card);
  font-size: var(--type-body-m);
  color: var(--color-content-tertiary);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* StoreItem — hero image, floating rating badge, name + meta line. */
.app-store-card {
  padding: var(--space-m);
  border-radius: var(--radius-xl);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-card);
}

.app-store-card__media {
  position: relative;
  aspect-ratio: 274 / 128;
  border-radius: var(--radius-l);
  background:
    radial-gradient(120% 90% at 20% 10%, var(--color-wash-gold), transparent 62%),
    radial-gradient(120% 90% at 85% 80%, var(--color-wash-rose), transparent 60%),
    var(--color-surface-footer);
}

.app-badge-rating {
  position: absolute;
  left: var(--space-s);
  bottom: var(--space-s);
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 3px var(--space-s);
  border-radius: var(--radius-pill);
  background: var(--color-surface-card);
  font-size: var(--type-label-m);
  font-weight: 600;
  box-shadow: var(--shadow-pill);
}

.app-badge-rating .icon {
  width: 12px;
  height: 12px;
  color: var(--color-tier-vip);
}

.app-badge-super {
  position: absolute;
  right: var(--space-s);
  top: var(--space-s);
  padding: 3px var(--space-s);
  border-radius: var(--radius-pill);
  background: var(--color-status-container-tertiary);
  color: var(--color-status-content-tertiary);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.app-store-card__name {
  margin-top: var(--space-m);
  font-size: var(--type-title-m);
  font-weight: 600;
}

.app-store-card__meta {
  margin-top: 2px;
  font-size: var(--type-body-s);
  color: var(--color-content-secondary-warm);
}

/* ProductCardItem — tile with DiscountTag overlay + QuantityStepper. */
.app-product-row {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-m);
}

.app-product {
  padding: var(--space-s);
  border-radius: var(--radius-l);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-card);
}

.app-product__media {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--radius-m);
  background: var(--color-image-background);
  border: 1px solid var(--color-border-subtle);
}

.app-product__glyph {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 40px;
  line-height: 1;
}

.app-tag-discount {
  position: absolute;
  left: 6px;
  top: 6px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--color-discount);
  color: var(--color-on-discount);
  font-size: 10px;
  font-weight: 700;
}

.app-tag-offer {
  position: absolute;
  left: 6px;
  top: 6px;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--color-offer-background);
  color: var(--color-on-offer);
  font-size: 10px;
  font-weight: 700;
}

.app-tag-bio {
  position: absolute;
  left: 6px;
  bottom: 6px;
  font-size: 10px;
  font-weight: 700;
  color: var(--color-bio-label);
}

.app-product__title {
  margin-top: var(--space-s);
  font-size: var(--type-body-m);
  font-weight: 500;
  line-height: 1.3;
}

/* The real tile keeps price and stepper on one line, but at mock width a
   strikethrough price + stepper overflows — stack them instead of wrapping
   mid-price. */
.app-product__price-row {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-s);
  margin-top: 6px;
}

.app-price {
  display: inline-flex;
  align-items: baseline;
  gap: 5px;
  font-size: var(--type-body-m);
  font-weight: 700;
  white-space: nowrap;
  color: var(--color-brand);
}

.app-price s {
  font-size: var(--type-label-s);
  font-weight: 400;
  white-space: nowrap;
  color: var(--color-content-tertiary);
}

/* QuantityStepper — resting state (32px circle) and expanded pill (40px). */
.app-stepper {
  display: inline-flex;
  align-items: center;
  gap: var(--space-s);
  height: 32px;
  padding: 3px;
  padding-left: var(--space-m);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-pill);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-pill);
  font-size: var(--type-body-m);
  font-weight: 500;
}

.app-stepper__plus {
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: 50%;
  background: var(--color-brand);
  color: var(--color-on-brand);
}

.app-stepper--rest {
  padding-left: 3px;
}

/* PlieStatusTicket — loyalty ticket with dashed divider and edge notches. */
.app-ticket {
  position: relative;
  padding: var(--space-l);
  border-radius: var(--radius-xl);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-card);
}

.app-ticket__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
}

.app-ticket__steps {
  display: flex;
  gap: 4px;
}

.app-ticket__steps i {
  display: block;
  width: 16px;
  height: 5px;
  border-radius: var(--radius-pill);
  background: var(--color-inactive-indicator);
}

.app-ticket__steps i.is-filled {
  background: var(--color-tier-vip);
}

.app-ticket__status {
  margin-top: var(--space-m);
  font-size: var(--type-body-m);
  font-weight: 600;
}

.app-ticket__divider {
  position: relative;
  margin-block: var(--space-m);
  border-top: 1.5px dashed var(--color-border-default);
}

/* Concave edge notches, faked by punching two discs in the surrounding surface
   colour. `--ticket-notch` lets a section that isn't on the cream page
   background (e.g. .section--warm) re-declare what "behind the card" means.
   Scoped to a direct child of .app-ticket: the dashed rule is reused elsewhere
   as a plain separator, where the notches would read as stray dots. */
.app-ticket > .app-ticket__divider::before,
.app-ticket > .app-ticket__divider::after {
  content: "";
  position: absolute;
  top: 50%;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--ticket-notch, var(--color-background-primary));
  transform: translateY(-50%);
}

.section--warm {
  --ticket-notch: var(--color-surface-warm);
}

.app-ticket > .app-ticket__divider::before {
  left: calc(var(--space-l) * -1 - 8px);
}

.app-ticket > .app-ticket__divider::after {
  right: calc(var(--space-l) * -1 - 8px);
}

.app-ticket__perk {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  font-size: var(--type-body-s);
  color: var(--color-content-secondary-warm);
}

.app-ticket__perk + .app-ticket__perk {
  margin-top: 6px;
}

/* PlieGlassNav — floating bottom bar. */
.app-glassnav {
  display: flex;
  align-items: center;
  justify-content: space-around;
  height: 56px;
  margin-top: var(--space-l);
  padding-inline: var(--space-m);
  border-radius: var(--radius-glass-nav);
  background: var(--color-surface-glass);
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
}

.app-glassnav span {
  width: 20px;
  height: 20px;
  border-radius: var(--radius-s);
  background: color-mix(in srgb, var(--color-content-primary) 24%, transparent);
}

.app-glassnav span.is-active {
  background: var(--color-brand);
}

/* Floating callouts pinned around the phone — annotate the mock. */
.phone-wrap {
  position: relative;
}

.phone-callout {
  position: absolute;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: var(--space-s) var(--space-m);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-pill);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-lifted);
  font-size: var(--type-label-m);
  font-weight: 500;
  white-space: nowrap;
  /* Same reason as .phone__screen — the callout is a white pill, so it must not
     inherit the hero's light-on-dark text colour. */
  color: var(--color-content-primary);
}

.phone-callout--tl {
  top: 12%;
  left: -6%;
}

.phone-callout--br {
  bottom: 16%;
  right: -6%;
}

.phone-callout__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--color-feedback-positive);
}

/* ══ 7. Content blocks ═════════════════════════════════════════════════════ */

/* ── Card (shared shell) ──────────────────────────────────────────────────── */

.card {
  display: flex;
  flex-direction: column;
  padding: var(--space-xxl);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xl);
  background: var(--color-surface-card);
  transition: transform var(--duration-base) var(--ease-out),
    box-shadow var(--duration-base) var(--ease-out);
}

.card--hover:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-lifted);
}

.section--ink .card {
  border-color: var(--color-ink-border);
  background: var(--color-ink-surface);
  color: var(--color-on-ink-muted);
}

.card__icon {
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  margin-bottom: var(--space-l);
  border-radius: var(--radius-l);
  background: var(--color-brand-container);
  color: var(--color-content-primary);
}

.card__icon--sage {
  background: var(--color-discount);
}

.card__icon--gold {
  background: var(--color-icon-tile-gold);
}

.card__icon--lilac {
  background: var(--color-icon-tile-lilac);
}

.card__icon--blue {
  background: var(--color-icon-tile-blue);
}

.card__icon--rose {
  background: var(--color-icon-tile-rose);
}

/* Sized to stay readable in a 4-up grid, where titleLarge (22px) reads chunky. */
.card__title {
  font-size: 19px;
  font-weight: 600;
  line-height: 1.3;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

/* ── Highlighted pricing card ─────────────────────────────────────────────
   One card in the pricing grid carries the rate. It takes the brand ground so
   the number is the first thing read in the section — everything around it
   stays quiet. */
.card--feature {
  background: var(--color-surface-ink);
  border-color: transparent;
  color: var(--color-on-ink-muted);
}

.card--feature .card__title {
  color: var(--color-on-ink);
}

.card--feature .card__text {
  color: var(--color-on-ink-muted);
}

.card--feature .card__icon {
  background: var(--color-ink-surface);
  color: var(--color-interactive-gold);
}

.price-figure {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  margin-bottom: var(--space-s);
  color: var(--color-interactive-gold);
}

.price-figure__value {
  font-size: clamp(44px, 5vw, 56px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  font-variant-numeric: tabular-nums;
}

.price-figure__unit {
  font-size: var(--type-title-m);
  font-weight: 500;
  color: var(--color-on-ink-muted);
}

.card__text {
  margin-top: var(--space-m);
  font-size: var(--type-body-m);
  line-height: 1.65;
  color: var(--color-content-secondary-warm);
}

.section--ink .card__title {
  color: var(--color-content-on-inverse);
}

.section--ink .card__text {
  color: var(--color-on-ink-muted);
}

/* ── Steps ────────────────────────────────────────────────────────────────── */

.steps {
  display: grid;
  gap: var(--space-xxl);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  counter-reset: step;
}

.steps--4 {
  grid-template-columns: repeat(4, minmax(0, 1fr));
}

.step {
  position: relative;
  counter-increment: step;
}

.step__num {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-bottom: var(--space-l);
  border-radius: 50%;
  background: var(--color-brand);
  color: var(--color-on-brand);
  font-size: var(--type-title-m);
  font-weight: 700;
}

.step__num::before {
  content: counter(step);
}

.section--ink .step__num {
  background: var(--color-tier-vip);
  color: var(--color-on-gold);
}

/* Connector line between steps — hidden on the last one and on narrow screens. */
.step:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 22px;
  left: 56px;
  right: calc(var(--space-xxl) * -1 + 8px);
  height: 1.5px;
  border-top: 1.5px dashed var(--color-border-default);
}

.section--ink .step:not(:last-child)::after {
  border-color: var(--color-ink-border-strong);
}

.step__title {
  font-size: var(--type-title-m);
  font-weight: 600;
}

.step__text {
  margin-top: var(--space-s);
  font-size: var(--type-body-m);
  line-height: 1.6;
  color: var(--color-content-secondary-warm);
}

.section--ink .step__text {
  color: var(--color-on-ink-muted);
}

/* ── Split (media + copy) ─────────────────────────────────────────────────── */

.split {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

.split--reverse .split__media {
  order: 2;
}

/* Top-aligned variant — for pairs of very unequal height (copy vs. a tall form),
   where vertical centring leaves the short column floating mid-section. */
.split--top {
  align-items: start;
}

.checklist {
  display: grid;
  gap: var(--space-l);
  margin-top: var(--space-xxl);
}

.checklist li {
  display: flex;
  gap: var(--space-m);
  font-size: var(--type-body-l);
  line-height: 1.55;
  color: var(--color-content-secondary-warm);
}

.checklist .icon {
  margin-top: 1px;
  color: var(--color-brand);
}

.section--ink .checklist li {
  color: var(--color-on-ink-muted);
}

.section--ink .checklist .icon {
  color: var(--color-tier-vip);
}

/* Deficit variant — the "what click & collect doesn't give you today" column.
   Muted and struck-through-feeling, so the affirmative column next to it wins
   the eye without needing a louder colour. */
.checklist--lacking li {
  color: var(--color-content-tertiary);
}

.checklist--lacking .icon {
  color: var(--color-inactive-indicator);
}

.section--ink .checklist--lacking li {
  color: var(--color-on-ink-faded);
}

.section--ink .checklist--lacking .icon {
  color: var(--color-on-ink-faint);
}

/* Column heading inside a contrast pair. */
.contrast-label {
  margin-bottom: var(--space-l);
  font-size: var(--type-label-s);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-content-tertiary);
}

.section--ink .contrast-label {
  color: var(--color-on-ink-subtle);
}

.contrast-label--accent {
  color: var(--color-brand);
}

.section--ink .contrast-label--accent {
  color: var(--color-tier-vip);
}

/* ── Stats strip ──────────────────────────────────────────────────────────── */

.stats {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-xxl);
}

.stat {
  padding-left: var(--space-l);
  border-left: 2px solid var(--color-brand);
}

.section--ink .stat {
  border-left-color: var(--color-tier-vip);
}

.stat__value {
  font-size: var(--type-headline-m);
  font-weight: 700;
  letter-spacing: -0.02em;
  line-height: 1.15;
}

.stat__label {
  margin-top: 6px;
  font-size: var(--type-body-m);
  color: var(--color-content-secondary-warm);
}

.section--ink .stat__label {
  color: var(--color-on-ink-muted);
}

/* ── Comparison table ─────────────────────────────────────────────────────── */

.compare {
  overflow-x: auto;
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xl);
  background: var(--color-surface-card);
}

.compare table {
  width: 100%;
  min-width: 620px;
  border-collapse: collapse;
}

.compare th,
.compare td {
  padding: var(--space-l) var(--space-xl);
  text-align: left;
  font-size: var(--type-body-m);
  vertical-align: top;
}

.compare thead th {
  font-size: var(--type-label-s);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-content-tertiary);
  border-bottom: 1px solid var(--color-border-subtle);
}

.compare tbody tr + tr {
  border-top: 1px solid var(--color-border-subtle);
}

.compare tbody th {
  font-weight: 600;
  color: var(--color-content-primary);
}

.compare td {
  color: var(--color-content-secondary-warm);
}

.compare .is-plie {
  background: color-mix(in srgb, var(--color-brand-container) 46%, transparent);
  color: var(--color-content-primary);
  font-weight: 500;
}

/* Cellule dont le sens est porté par une icône seule. Le libellé
   `visually-hidden` qui l'accompagne n'est pas optionnel : sans lui, la
   cellule est vide pour un lecteur d'écran et la ligne devient illisible. */
.compare__mark {
  display: inline-flex;
  align-items: center;
  color: var(--color-content-primary);
}

.compare__mark--yes {
  color: var(--color-feedback-positive);
}

/* ── FAQ accordion ────────────────────────────────────────────────────────── */

.faq {
  max-width: 820px;
  margin-inline: auto;
}

.faq__item {
  border-bottom: 1px solid var(--color-border-subtle);
}

.faq__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-l);
  width: 100%;
  padding: var(--space-xl) 0;
  border: 0;
  background: none;
  text-align: left;
  font-size: var(--type-title-m);
  font-weight: 600;
  cursor: pointer;
}

.faq__q .icon {
  color: var(--color-brand);
  transition: transform var(--duration-base) var(--ease-out);
}

.faq__q[aria-expanded="true"] .icon {
  transform: rotate(45deg);
}

.faq__a {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--duration-base) var(--ease-out);
}

.faq__a[data-open="true"] {
  grid-template-rows: 1fr;
}

.faq__a > div {
  overflow: hidden;
}

.faq__a p {
  padding-bottom: var(--space-xl);
  font-size: var(--type-body-m);
  line-height: 1.7;
  color: var(--color-content-secondary-warm);
  max-width: 68ch;
}

/* ── Final CTA band ───────────────────────────────────────────────────────── */

.cta-band {
  position: relative;
  overflow: hidden;
  padding: clamp(40px, 6vw, 72px);
  border-radius: var(--radius-modal);
  background:
    radial-gradient(90% 140% at 12% 0%, var(--color-wash-wine) 0%, transparent 58%),
    var(--color-surface-ink);
  color: var(--color-content-on-inverse);
  text-align: center;
}

.cta-band__title {
  font-size: var(--type-display-s);
  font-weight: 700;
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-wrap: balance;
}

.cta-band__text {
  max-width: 56ch;
  margin: var(--space-l) auto 0;
  color: var(--color-on-ink-muted);
  text-wrap: pretty;
}

.cta-band__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-m);
  margin-top: var(--space-xxxl);
}

/* ══ 8. Contact form ═══════════════════════════════════════════════════════ */

.lead-form {
  padding: clamp(24px, 3.5vw, 40px);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-modal);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-card);
}

.field-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-l);
}

.field {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.field--full {
  grid-column: 1 / -1;
}

.field label {
  font-size: var(--type-label-l);
  font-weight: 500;
}

.field__hint {
  font-size: var(--type-body-s);
  color: var(--color-content-tertiary);
}

/* FluidTextField — swaps background between rest and focus. */
.field input,
.field select,
.field textarea {
  width: 100%;
  min-height: var(--field-h);
  padding: var(--space-m) var(--space-l);
  border: 1px solid var(--color-border-default);
  border-radius: var(--field-radius);
  background: var(--color-background-secondary);
  font: inherit;
  font-size: var(--type-body-m);
  color: var(--color-content-primary);
  transition: background-color var(--duration-fast) var(--ease-out),
    border-color var(--duration-fast) var(--ease-out);
}

.field textarea {
  min-height: 116px;
  resize: vertical;
}

.field select {
  appearance: none;
  /* Phosphor.CaretDown — une propriété CSS ne pouvant pas viser un
     <symbol>, le glyphe est inliné ici en data URI. Régénéré par
     web/tools/build-icon-sprite.py si le sprite change. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 256 256' fill='%23535353'%3E%3Cpath d='M213.66,101.66l-80,80a8,8,0,0,1-11.32,0l-80-80A8,8,0,0,1,53.66,90.34L128,164.69l74.34-74.35a8,8,0,0,1,11.32,11.32Z'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--space-l) center;
  background-size: 18px;
  padding-right: 44px;
}

.field input:focus,
.field select:focus,
.field textarea:focus {
  outline: none;
  background: var(--color-surface-card);
  border-color: var(--color-interactive-focus-ring);
  border-width: 2px;
  padding: calc(var(--space-m) - 1px) calc(var(--space-l) - 1px);
}

.field select:focus {
  padding-right: 43px;
}

.field[data-invalid="true"] input,
.field[data-invalid="true"] select,
.field[data-invalid="true"] textarea {
  border-color: var(--color-feedback-negative);
  background: var(--color-feedback-negative-surface);
}

.field__error {
  display: none;
  font-size: var(--type-body-s);
  color: var(--color-feedback-negative);
}

.field[data-invalid="true"] .field__error {
  display: block;
}

.form-consent {
  display: flex;
  gap: var(--space-m);
  margin-top: var(--space-xl);
  font-size: var(--type-body-s);
  line-height: 1.55;
  color: var(--color-content-secondary-warm);
}

.form-consent input {
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  margin-top: 2px;
  accent-color: var(--color-brand);
}

/* The consent box carries no .field wrapper, so it needs its own invalid state —
   otherwise an unchecked box blocks submission with no visible reason. */
.form-consent[data-invalid="true"] {
  color: var(--color-feedback-negative);
}

.form-consent[data-invalid="true"] input {
  outline: 2px solid var(--color-feedback-negative);
  outline-offset: 2px;
  border-radius: var(--radius-xs);
}

.form-status {
  display: none;
  gap: var(--space-m);
  margin-top: var(--space-xl);
  padding: var(--space-l);
  border-radius: var(--radius-l);
  font-size: var(--type-body-m);
  line-height: 1.55;
}

.form-status[data-state="success"] {
  display: flex;
  background: var(--color-feedback-positive-surface);
  color: var(--color-on-feedback-positive);
}

.form-status[data-state="error"] {
  display: flex;
  background: var(--color-feedback-negative-surface);
  color: var(--color-feedback-negative);
}

/* ══ 9. Footer ═════════════════════════════════════════════════════════════ */

.site-footer {
  padding-block: var(--space-section) var(--space-xxxl);
  background: var(--color-surface-footer);
}

/* Trois colonnes depuis le retrait de la colonne « Votre métier » : la
   marque, puis les deux publics. La première reste plus large — elle porte le
   logo et la baseline, pas une liste de liens. */
.footer-grid {
  display: grid;
  grid-template-columns: minmax(0, 1.4fr) repeat(2, minmax(0, 1fr));
  gap: var(--space-xxxl);
}

.footer__logo img {
  height: 40px;
  width: auto;
}

.footer__tagline {
  max-width: 34ch;
  margin-top: var(--space-l);
  font-size: var(--type-body-m);
  line-height: 1.6;
  color: var(--color-content-secondary-warm);
}

.footer__heading {
  margin-bottom: var(--space-m);
  font-size: var(--type-label-s);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--color-content-tertiary);
}

.footer__list li + li {
  margin-top: var(--space-s);
}

.footer__list a {
  font-size: var(--type-body-m);
  color: var(--color-content-secondary-warm);
  transition: color var(--duration-fast) var(--ease-out);
}

.footer__list a:hover {
  color: var(--color-brand);
}

.footer-bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-l);
  margin-top: var(--space-xxxxl);
  padding-top: var(--space-xl);
  border-top: 1px solid var(--color-border-default);
  font-size: var(--type-body-s);
  color: var(--color-content-tertiary);
}

.footer__legal {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-s);
}

.footer__legal a {
  color: var(--color-content-secondary-warm);
  transition: color var(--duration-fast) var(--ease-out);
}

.footer__legal a:hover {
  color: var(--color-brand);
}

/* ══ 9 bis. Preuve produit ═════════════════════════════════════════════════
   Trois maquettes ajoutées à la page commerçants. Elles ne sont pas des
   illustrations : elles rendent visible ce que la page se contentait
   d'affirmer (catalogue enrichi, espace commerçant, mise en avant Premium).

   Comme les blocs `.app-*`, elles sont construites en HTML/CSS plutôt qu'en
   captures : poids nul, net à tous les zooms, texte réellement sélectionnable
   et traduisible, et aucun risque sur le LCP.                                */

/* ── Avant / après enrichissement de fiche ──────────────────────────────── */

.enrich {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
  align-items: center;
  gap: var(--space-l);
  padding: var(--space-xl);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-xl);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-lifted);
}

.enrich__label {
  margin-bottom: var(--space-m);
  font-size: var(--type-label-s);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-content-tertiary);
}

/* Le libellé brut imite une ligne de ticket : chasse fixe, capitales, prix
   aligné à droite. C'est ce qui rend l'avant/après reconnaissable pour un
   commerçant qui tient sa propre caisse. */
.enrich__raw {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-m);
  padding: var(--space-l) var(--space-m);
  border: 1px dashed var(--color-border-strong);
  border-radius: var(--radius-s);
  background: var(--color-background-secondary);
  font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace;
  font-size: var(--type-body-s);
  letter-spacing: 0.02em;
  color: var(--color-content-secondary);
}

.enrich__arrow {
  display: grid;
  place-items: center;
  width: 34px;
  height: 34px;
  border-radius: var(--radius-pill);
  background: var(--color-brand-container);
  color: var(--color-on-brand-container);
}

.enrich__facts {
  display: grid;
  gap: 3px;
  margin-top: var(--space-s);
  font-size: var(--type-body-s);
  line-height: 1.45;
  color: var(--color-content-secondary-warm);
}

/* ── Espace commerçant + vitrine côté client ────────────────────────────── */

.duo {
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
  align-items: center;
  gap: var(--space-l);
}

.phone--sm {
  width: min(232px, 100%);
  padding: 9px;
  border-radius: 34px;
}

.phone--sm .phone__screen {
  padding: var(--space-xl) var(--space-m) var(--space-xl);
  border-radius: 26px;
}

.console {
  padding: var(--space-xl);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-l);
  background: var(--color-surface-card);
  box-shadow: var(--shadow-lifted);
}

.console__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-s);
  padding-bottom: var(--space-m);
  border-bottom: 1px solid var(--color-border-subtle);
  font-size: var(--type-label-m);
  font-weight: 500;
  color: var(--color-content-tertiary);
}

.console__list li {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding: var(--space-m) 0;
  border-bottom: 1px solid var(--color-border-subtle);
}

.console__who {
  font-size: var(--type-body-s);
  color: var(--color-content-secondary-warm);
}

.console__who strong {
  color: var(--color-content-primary);
}

.console__foot {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  margin-top: var(--space-l);
  font-size: var(--type-body-s);
  font-weight: 500;
  color: var(--color-brand);
}

/* ── Démonstrations de fonctionnalités (Plié Pro Premium) ────────────────
   Un tableau comparatif nomme les fonctions ; il ne les montre pas. Ces deux
   figures rendent la mise en avant et les actualités telles qu'un client les
   voit, et la distinction Free / Premium se lit dans la maquette au lieu de
   vivre dans une colonne de coches.                                       */

.feature-demos {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(32px, 5vw, 64px);
  margin-top: var(--space-xxxxl);
}

.feature-demo {
  display: grid;
  gap: var(--space-xxl);
  justify-items: center;
}

.feature-demo__caption {
  max-width: 42ch;
  text-align: center;
}

.feature-demo__title {
  margin-bottom: var(--space-m);
  font-size: var(--type-title-m);
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-on-ink);
  text-wrap: balance;
}

.feature-demo__text {
  font-size: var(--type-body-m);
  line-height: 1.6;
  color: var(--color-on-ink-muted);
  text-wrap: pretty;
}

.feature-demo__text strong {
  color: var(--color-on-ink);
  font-weight: 600;
}

/* Cadre d'écran — 375 px, la largeur d'un téléphone courant. C'est cette
   largeur-là qui donne « une carte et demie » à l'écran, exactement ce que
   voit un client : rétrécir le cadre ou les cartes ferait tenir plus de
   contenu et la maquette cesserait de montrer le produit. Le fond reprend
   `backgroundPrimary`, celui de la page d'accueil. */
.app-frame {
  width: 375px;
  max-width: 100%;
  padding: var(--space-l) 0 var(--space-xl);
  border-radius: var(--radius-xl);
  background: var(--color-background-primary);
  color: var(--color-content-primary);
  box-shadow: var(--shadow-lifted);
  overflow: hidden;
}

.app-frame__label {
  padding-inline: var(--space-l);
  margin-bottom: var(--space-m);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-content-tertiary);
}

/* ── StorePromotionCarouselSection.kt ────────────────────────────────────
   Carte blanche à coins de 16 dp, en-tête cliquable (padding 16/12), icône
   ronde de 40 dp, titre 16 sp semibold, sous-titre 12 sp. Les couleurs du
   composable sont codées en dur (#140F0D, #411626) ; ici elles passent par
   les tokens sémantiques équivalents, conformément à DESIGN.md §8.        */

.app-promo-card {
  margin-inline: var(--space-s);
  padding-block: 10px 24px;
  border-radius: 16px;
  background: var(--color-surface-card);
}

.app-promo-card__head {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  padding: var(--space-m) var(--space-l);
}

.app-promo-card__icon {
  display: grid;
  flex-shrink: 0;
  place-items: center;
  width: 40px;
  height: 40px;
  border-radius: var(--radius-pill);
  background: var(--color-image-background);
  font-size: 20px;
}

.app-promo-card__store {
  display: grid;
  flex: 1 1 auto;
  min-width: 0;
}

.app-promo-card__store strong {
  font-size: 16px;
  font-weight: 600;
  color: var(--color-content-primary);
}

.app-promo-card__store span {
  font-size: 12px;
  color: var(--color-brand);
}

/* Le chevron « voir tout » du composable pointe à droite ; le sprite n'expose
   qu'un caret vers le bas, pivoté ici plutôt que d'ajouter un glyphe pour un
   seul usage décoratif. */
.app-promo-card__caret {
  flex-shrink: 0;
  transform: rotate(-90deg);
  color: var(--color-content-primary);
}

/* Rangée de ProductCardItem : 160 px de large, l'écart de 12 dp du LazyRow.
   Elle déborde volontairement du cadre — c'est un carrousel horizontal. */
.app-promo-card__row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 160px;
  gap: var(--space-m);
  padding-inline: var(--space-l);
  overflow: hidden;
}

/* ── HighlightPreviewCard.kt ─────────────────────────────────────────────
   318 dp de haut, ratio 9/16, coins de 12 dp. Photo de fond floutée, voile
   vertical allant du transparent à #0F0F0F à 90 %, icône ronde blanche de
   48 dp, titre 16 sp et sous-titre 12 sp, tous deux BLANCS, posés en bas
   avec 12 dp d'écart.                                                     */

.app-story-row {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 179px;
  gap: var(--space-m);
  padding-inline: var(--space-s);
  overflow: hidden;
}

.app-story {
  position: relative;
  height: 318px;
  border-radius: 12px;
  background: var(--color-image-background);
  overflow: hidden;
}

.app-story--pinned {
  outline: 2px solid var(--color-interactive-gold);
  outline-offset: -2px;
}

/* Tient lieu de photo tant que les vraies images ne sont pas branchées —
   même statut que les 🍅 / 🧀 des autres maquettes. Le flou reproduit le
   `cloudy` du composable. */
.app-story__photo {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 92px;
  filter: blur(2px);
}

.app-story__scrim {
  position: absolute;
  inset: 0;
  background: linear-gradient(to bottom, rgb(15 15 15 / 0%), rgb(15 15 15 / 90%));
}

.app-story__icon {
  position: absolute;
  top: 12px;
  left: 12px;
  display: grid;
  place-items: center;
  width: 48px;
  height: 48px;
  border-radius: var(--radius-pill);
  background: var(--color-background-primary);
  font-size: 24px;
}

.app-story__pin {
  position: absolute;
  top: 12px;
  right: 12px;
  display: grid;
  place-items: center;
  width: 26px;
  height: 26px;
  border-radius: var(--radius-pill);
  background: var(--color-interactive-gold);
  color: var(--color-on-gold);
}

.app-story__text {
  position: absolute;
  right: 12px;
  bottom: 16px;
  left: 12px;
  display: grid;
  gap: var(--space-m);
}

/* Blanc en dur : ces deux textes sont posés sur un voile sombre, pas sur une
   surface du thème — c'est aussi ce que fait le composable. */
.app-story__title {
  font-size: 16px;
  font-weight: 600;
  line-height: 1.25;
  color: #fff;
}

.app-story__subtitle {
  font-size: 12px;
  line-height: 1.3;
  color: #fff;
}

/* Intertitre de liste dans le cadre d'écran (« Autour de vous »). */
.app-list-label {
  padding-inline: var(--space-l);
  margin-top: var(--space-xl);
  margin-bottom: var(--space-s);
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-content-tertiary);
}

/* La liste « autour de vous » sert dans les deux maquettes. */

.promo-screen__list {
  display: grid;
  gap: var(--space-s);
  padding-inline: var(--space-l);
}

.promo-screen__list li {
  display: flex;
  align-items: center;
  gap: var(--space-m);
  font-size: var(--type-body-s);
  color: var(--color-content-secondary-warm);
}

.promo-screen__rank {
  display: grid;
  flex-shrink: 0;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: var(--radius-pill);
  background: var(--color-background-secondary);
  font-size: var(--type-label-s);
  color: var(--color-content-tertiary);
}
/* ── Grille des métiers ──────────────────────────────────────────────────
   Un gérant de supérette ou un pharmacien doit pouvoir se reconnaître avant
   de lire la suite. Cartes volontairement plus légères que `.card` : c'est un
   panneau de qualification, pas un argumentaire.                          */

.trades {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-xl);
}

.trade {
  display: grid;
  gap: var(--space-s);
  padding: var(--space-xl);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-l);
  background: var(--color-surface-card);
}

.trade__icon {
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  margin-bottom: var(--space-xs);
  border-radius: var(--radius-m);
  background: var(--color-brand-container);
  color: var(--color-on-brand-container);
}

.trade__name {
  font-size: var(--type-title-s);
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-content-primary);
}

.trade__text {
  font-size: var(--type-body-s);
  line-height: 1.55;
  color: var(--color-content-secondary-warm);
}

/* ── Simulateur de revenu ────────────────────────────────────────────────
   Le seul endroit de la page où le commerçant manipule SES chiffres. « 10 %
   HT » se comprend ; « 1 462 € encaissés » se projette.                   */

.sim {
  margin-top: var(--space-xxxl);
  padding: var(--space-xxl);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-xl);
  background: var(--color-surface-warm);
}

.sim__title {
  margin-bottom: var(--space-xl);
  font-size: var(--type-title-m);
  font-weight: 600;
  color: var(--color-content-primary);
}

.sim__controls {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-xxl);
}

.sim__field label {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-m);
  margin-bottom: var(--space-s);
  font-size: var(--type-body-m);
  font-weight: 500;
  color: var(--color-content-secondary-warm);
}

.sim__field output {
  font-size: var(--type-title-s);
  font-weight: 600;
  color: var(--color-brand);
  font-variant-numeric: tabular-nums;
}

/* `accent-color` suffit à teindre la piste et la poignée sur tous les
   navigateurs courants : pas de reconstruction du curseur, donc pas de perte
   d'accessibilité clavier. */
.sim__field input[type="range"] {
  width: 100%;
  accent-color: var(--color-brand);
}

.sim__results {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-l);
  margin-top: var(--space-xxl);
}

.sim__result {
  padding: var(--space-l);
  border-radius: var(--radius-m);
  background: var(--color-background-primary);
  text-align: center;
}

.sim__result dt {
  font-size: var(--type-body-s);
  line-height: 1.35;
  color: var(--color-content-tertiary);
}

.sim__result dd {
  margin-top: var(--space-xs);
  font-size: var(--type-headline-s);
  font-weight: 700;
  color: var(--color-content-primary);
  font-variant-numeric: tabular-nums;
}

/* Le net est le chiffre que le commerçant retient : il est le seul mis en
   couleur de marque. */
.sim__result--net {
  background: var(--color-brand-container);
}

.sim__result--net dt {
  color: var(--color-on-brand-container);
}

.sim__result--net dd {
  color: var(--color-on-brand-container);
}

.sim__note {
  margin-top: var(--space-xl);
  font-size: var(--type-body-s);
  line-height: 1.6;
  color: var(--color-content-tertiary);
}

/* ── Logiciels de caisse compatibles ─────────────────────────────────────
   Un formulaire à deux champs occupait cette place et promettait une réponse
   sous 48 h. Afficher les éditeurs intégrés répond à l'objection sur-le-champ :
   la question « est-ce que ça marche avec ma caisse » se règle à l'œil, sans
   laisser d'adresse e-mail pour l'apprendre.                              */

/* La cible du CTA « Ma caisse est-elle compatible ? » est ce bloc, PAS le haut
   de sa section : le split le place en bas de colonne, et viser la section
   déposait le lecteur au-dessus du vide sur un écran d'ordinateur portable.

   Pas de `scroll-margin-top` ici : le `scroll-padding-top: 96px` posé sur
   `html` dégage déjà le bandeau collant, et les deux s'ADDITIONNENT — la cible
   se retrouvait à 192 px du haut, soit un tiers du bloc poussé hors de l'écran. */
.pos-block {
  margin-top: var(--space-xxxl);
  padding: var(--space-xl);
  border: 1px solid var(--color-border-default);
  border-radius: var(--radius-l);
  background: var(--color-surface-warm);
}

.pos-block__title {
  margin-bottom: var(--space-l);
  font-size: var(--type-title-s);
  font-weight: 600;
  line-height: 1.4;
  text-wrap: pretty;
}

/* `auto-fill` plutôt qu'un nombre de colonnes figé : la liste s'allongera à
   mesure que des intégrations s'ouvrent, et la grille doit encaisser sans
   qu'on revienne toucher au breakpoint. */
.pos-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: var(--space-m);
}

.pos-card {
  display: grid;
  place-items: center;
  min-height: 62px;
  padding: var(--space-m);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-m);
  background: var(--color-background-primary);
  text-align: center;
}

/* Les logos ont des proportions très inégales — de 132×130 pour l'un à 320×80
   pour l'autre. Les contraindre en LARGEUR seule ferait des cartes deux fois
   plus hautes pour les logos carrés ; borner aussi la hauteur les met tous au
   même poids optique, ce qui est le seul rendu acceptable pour une grille de
   compatibilité. `object-fit: contain` garde chaque ratio intact. */
.pos-card img {
  max-width: 112px;
  max-height: 34px;
  width: auto;
  height: auto;
  object-fit: contain;
}

.pos-block__note {
  margin-top: var(--space-l);
  font-size: var(--type-body-s);
  line-height: 1.55;
  color: var(--color-content-tertiary);
}

.pos-block__note a {
  color: var(--color-brand);
  font-weight: 500;
}

/* ── Pages de texte (mentions légales, confidentialité) ──────────────────
   Colonne de lecture étroite : ces pages sont faites pour être lues en
   continu, pas parcourues comme une landing.                              */

.legal {
  max-width: 74ch;
}

.legal h2 {
  margin-top: var(--space-xxxxl);
  margin-bottom: var(--space-l);
  font-size: var(--type-title-l);
  font-weight: 600;
  line-height: 1.25;
  color: var(--color-content-primary);
}

.legal p {
  margin-bottom: var(--space-l);
  font-size: var(--type-body-l);
  line-height: 1.65;
  color: var(--color-content-secondary-warm);
}

.legal a {
  color: var(--color-brand);
  font-weight: 500;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.legal__list {
  display: grid;
  gap: var(--space-m);
  margin-bottom: var(--space-l);
  padding-left: var(--space-xl);
  list-style: disc;
  font-size: var(--type-body-l);
  line-height: 1.6;
  color: var(--color-content-secondary-warm);
}

.legal .compare {
  margin-bottom: var(--space-xxl);
}

/* Marque les informations juridiques qu'un site ne peut pas inventer et qui
   restent à fournir. Volontairement criard : un placeholder discret finit en
   production. */
.legal mark {
  padding: 2px 6px;
  border-radius: var(--radius-xs);
  background: var(--color-feedback-warning-surface);
  font-size: var(--type-body-m);
  font-weight: 500;
  color: var(--color-content-primary);
}

/* ── L'équipe ────────────────────────────────────────────────────────────
   Cinq visages avant le formulaire. La grille est en `auto-fit` plutôt qu'en
   nombre fixe de colonnes : cinq membres ne se divisent proprement ni par
   trois ni par quatre, et une dernière rangée orpheline est plus visible ici
   qu'ailleurs — c'est la seule grille de la page dont chaque cellule est un
   portrait, donc dont les trous se lisent.                                 */

.team {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: var(--space-xxl) var(--space-xl);
  justify-items: center;
  max-width: 900px;
  margin: 0 auto;
}

.team__member {
  display: grid;
  justify-items: center;
  gap: var(--space-m);
  text-align: center;
}

/* Portrait rond de 140 px. La pastille à initiale n'est pas un état
   transitoire du composant, c'est son SOCLE : la photographie se pose PAR
   DESSUS, en `<img>` positionné dans la pastille, et ne la remplace pas.

   Pourquoi superposer plutôt que substituer. Les cinq portraits n'arrivent pas
   ensemble — il en manque toujours un, aujourd'hui celui de Mary. Empilés,
   les deux états cohabitent sans condition : la photo présente masque
   l'initiale, la photo absente laisse voir la pastille. Aucun basculement à
   opérer le jour du dépôt, et jamais de portrait à moitié posé en page
   publique.

   ⚠️ L'`alt` de la photo est VIDE, et c'est ce qui fait tenir la dégradation.
   Un `alt` renseigné se peint en toutes lettres par-dessus l'initiale quand le
   fichier manque — le mot déborde du cercle, en travers de la lettre. Un `alt`
   vide s'efface : le navigateur ne peint rien du tout et la pastille se
   retrouve intacte. Rien ne se perd pour un lecteur d'écran, le prénom étant
   déjà dans le `<figcaption>` juste dessous — un `alt="Adrien"` le ferait
   annoncer deux fois. */
.team__photo {
  position: relative;
  display: grid;
  place-items: center;
  width: 140px;
  height: 140px;
  border-radius: var(--radius-pill);
  background: var(--color-brand-container);
  font-size: var(--type-display-s);
  font-weight: 600;
  line-height: 1;
  color: var(--color-on-brand-container);
}

.team__photo img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border-radius: inherit;
  /* Les portraits ne sont pas tous cadrés pareil : `cover` recadre plutôt que
     de déformer, quitte à rogner les angles. */
  object-fit: cover;
}

.team__name {
  font-size: var(--type-title-s);
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-content-primary);
}

.team__role {
  margin-top: var(--space-xs);
  font-size: var(--type-body-s);
  line-height: 1.4;
  color: var(--color-content-secondary-warm);
}

/* Crédit LaRef. Fond « warm » et non `--surface-card` : la section est déjà
   blanche, une carte blanche sur blanc ne se détacherait pas du bloc des
   portraits. */
.team-credit {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xl);
  max-width: 900px;
  margin: var(--space-xxxxl) auto 0;
  padding: var(--space-xxl);
  border: 1px solid var(--color-border-subtle);
  border-radius: var(--radius-l);
  background: var(--color-background-secondary);
}

.team-credit__body {
  flex: 1 1 320px;
}

/* Logo LaRef. Même `alt=""` que les portraits, et pour la même raison : le
   titre juste dessous nomme LaRef en toutes lettres et porte le lien, de sorte
   qu'aucune information ne se perd si le fichier n'est pas encore déposé.

   ⚠️ C'est un logo de tiers : il se sert depuis le dépôt, jamais en lien
   direct vers laref.co. Une page qui va chercher l'actif chez son propriétaire
   casse le jour où il le déplace, et prévient ce dernier de chaque visite. */
.team-credit__logo {
  display: block;
  width: auto;
  height: 32px;
  margin-bottom: var(--space-m);
}

.team-credit__title {
  margin-bottom: var(--space-s);
  font-size: var(--type-title-m);
  font-weight: 600;
  line-height: 1.3;
  color: var(--color-content-primary);
}

.team-credit__title a {
  color: var(--color-brand);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.team-credit__text {
  font-size: var(--type-body-m);
  line-height: 1.6;
  color: var(--color-content-secondary-warm);
  text-wrap: pretty;
}

/* ══ 10. Motion & responsive ═══════════════════════════════════════════════ */

/* Scroll reveal — opt-in via [data-reveal]; JS flips [data-revealed].
   Scoped to `.js`, set by an inline script in <head>. Without JS the rule never
   applies, so content is visible instead of stuck at opacity 0 — the animation
   is an enhancement, never a precondition for reading the page. */
.js [data-reveal] {
  opacity: 0;
  transform: translateY(18px);
  transition:
    opacity var(--duration-slow) var(--ease-out),
    transform var(--duration-slow) var(--ease-out);
}

.js [data-reveal][data-revealed="true"] {
  opacity: 1;
  transform: none;
}

@media (max-width: 1024px) {
  .hero__inner,
  .split {
    grid-template-columns: minmax(0, 1fr);
  }

  .split--reverse .split__media {
    order: 0;
  }

  .phone-wrap {
    max-width: 340px;
    margin-inline: auto;
  }

  .phone-callout--tl {
    left: -2%;
  }

  .phone-callout--br {
    right: -2%;
  }

  .grid--4,
  .steps--4,
  .trades {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .footer-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .step:not(:last-child)::after {
    display: none;
  }

  /* Les deux écrans de l'espace commerçant se réempilent, le téléphone
     repasse au centre plutôt que collé au bord. */
  .duo {
    grid-template-columns: minmax(0, 1fr);
    justify-items: center;
    gap: var(--space-xxl);
  }
}

@media (max-width: 860px) {
  .nav__toggle {
    display: flex;
    flex-direction: column;
  }

  .nav__links,
  .nav__actions {
    display: none;
  }

  /* Mobile drawer — the nav collapses into a stacked panel under the header. */
  .nav.is-open {
    flex-wrap: wrap;
    height: auto;
    padding-bottom: var(--space-xl);
  }

  .nav.is-open .nav__links,
  .nav.is-open .nav__actions {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    gap: var(--space-m);
    width: 100%;
    margin-left: 0;
  }

  .nav.is-open .nav__links {
    padding-top: var(--space-s);
    border-top: 1px solid var(--color-border-subtle);
  }

  .site-header--pro .nav.is-open .nav__links {
    border-top-color: var(--color-ink-border);
  }

  .nav.is-open .nav__link {
    padding-block: var(--space-m);
  }

  .grid--2,
  .grid--3,
  .steps,
  .stats,
  .trades,
  .field-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Les portraits restent à DEUX par ligne, seuls contre le reste de la page
     qui s'empile : une colonne de cinq visages de 140 px fait défiler un écran
     entier pour cinq mots. La pastille rétrécit d'autant. */
  .team {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-xl) var(--space-m);
  }

  .team__photo {
    width: 108px;
    height: 108px;
    font-size: var(--type-title-l);
  }

  .team-credit {
    padding: var(--space-xl);
  }

  .team-credit .btn {
    width: 100%;
  }

  /* Les trois résultats du simulateur restent EN LIGNE : empilés, on perd la
     lecture « encaissé → commission → ce qui reste », qui est tout le propos. */
  .sim__controls {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-xl);
  }

  .sim {
    padding: var(--space-xl);
  }

  /* Les deux figures illustrent des fonctions distinctes, pas une comparaison :
     elles s'empilent sans rien perdre. */
  .feature-demos {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 560px) {
  .grid--4,
  .steps--4 {
    grid-template-columns: minmax(0, 1fr);
  }

  .footer-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: var(--space-xxl);
  }

  .phone-callout {
    display: none;
  }

  /* L'avant/après passe en pile : la flèche pivote pour continuer à lire de
     haut en bas plutôt que de pointer dans le vide. */
  .enrich {
    grid-template-columns: minmax(0, 1fr);
    justify-items: stretch;
  }

  .enrich__arrow {
    justify-self: center;
    /* `transform: rotate()` plutôt que la propriété `rotate:` seule : le site
       est servi tel quel, sans transpilation, et la propriété indépendante est
       plus récente que la fonction de transformation. Même raison que la
       syntaxe historique des media queries ci-dessus. */
    transform: rotate(90deg);
  }

  /* Deux cartouches de logiciel par ligne : en dessous, les noms les plus
     longs se coupent. */
  .pos-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .btn--lg {
    width: 100%;
  }

  .store-badges {
    flex-direction: column;
  }

  .store-badge {
    justify-content: center;
  }
}

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

  .js [data-reveal] {
    opacity: 1;
    transform: none;
  }
}

@media print {
  .site-header,
  .cta-band,
  .phone-wrap {
    display: none;
  }
}

/* ── Icon alignment inside inline contexts ────────────────────────────────
   Glyphs sitting next to text need the same optical baseline the emoji they
   replaced had — nudged up a hair, since a 256-viewport Phosphor path fills
   its box more than a typographic character does. */
.phone-callout .icon,
.app-ticket__perk .icon,
.pill .icon {
  margin-top: -1px;
  color: inherit;
}

.store-badge .icon {
  color: inherit;
}

.card__icon .icon {
  color: inherit;
}
