/* Geist — self-hosted (no Google Fonts request: the privacy policy promises
   zero third-party calls from this site, and CNIL flags remote Google Fonts). */
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("/assets/fonts/geist-400.woff2") format("woff2");
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: url("/assets/fonts/geist-500.woff2") format("woff2");
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: url("/assets/fonts/geist-600.woff2") format("woff2");
}
@font-face {
  font-family: "Geist";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url("/assets/fonts/geist-700.woff2") format("woff2");
}


/* Pivot landing — design system.
   Light is the default (bare :root); dark tokens live under
   html[data-theme="dark"]. The inline guard in every page always stamps an
   explicit data-theme (stored choice, else prefers-color-scheme). */

:root {
  --background: 0 0% 100%;
  --foreground: 240 10% 3.9%;
  --card: 0 0% 100%;
  --card-foreground: 240 10% 3.9%;
  --muted: 240 4.8% 95.9%;
  --muted-foreground: 240 3.8% 46.1%;
  --primary: 142.1 76.2% 36.3%;
  --primary-foreground: 355.7 100% 97.3%;
  --secondary: 240 4.8% 95.9%;
  --border: 240 5.9% 90%;
  --ring: 142.1 76.2% 36.3%;
  --radius: 0.5rem;
  --glow: hsl(142.1 76.2% 36.3% / 0.2);
  /* Brand gradients from the original hero */
  --grad-pink-a: #f596d3;
  --grad-pink-b: #d247bf;
  --grad-blue-a: #61dafb;
  --grad-blue-b: #03a3d7;
  color-scheme: light;
}

html[data-theme="dark"] {
  --background: 20 14.3% 4.1%;
  --foreground: 0 0% 95%;
  --card: 24 9.8% 10%;
  --card-foreground: 0 0% 95%;
  --muted: 0 0% 15%;
  --muted-foreground: 240 5% 64.9%;
  --primary: 142.1 70.6% 45.3%;
  --primary-foreground: 144.9 80.4% 10%;
  --secondary: 240 3.7% 15.9%;
  --border: 240 3.7% 15.9%;
  --ring: 142.4 71.8% 29.2%;
  --glow: hsl(142.1 70.6% 45.3% / 0.28);
  color-scheme: dark;
}

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
  background: hsl(var(--background));
  color: hsl(var(--foreground));
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: hsl(var(--primary) / 0.35); }

img, svg, video, iframe { max-width: 100%; }

a { color: inherit; }

.container { max-width: 72rem; margin-inline: auto; padding-inline: 1.25rem; }
@media (min-width: 640px) { .container { padding-inline: 2rem; } }

/* ── Typography ─────────────────────────────────────────────── */
h1, h2, h3 { line-height: 1.15; margin: 0; letter-spacing: -0.02em; }
h1 { font-size: clamp(2.4rem, 6vw, 3.9rem); font-weight: 800; }
h2 { font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 800; }
h3 { font-size: 1.15rem; font-weight: 700; }
p { margin: 0; }

.grad-pink {
  background: linear-gradient(90deg, var(--grad-pink-a), var(--grad-pink-b));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.grad-blue {
  background: linear-gradient(90deg, var(--grad-blue-a), var(--grad-blue-b));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.grad-green {
  background: linear-gradient(90deg, hsl(var(--primary) / 0.65), hsl(var(--primary)));
  -webkit-background-clip: text; background-clip: text; color: transparent;
}

.muted { color: hsl(var(--muted-foreground)); }

.section { padding-block: 5.5rem; }
.section-alt { background: hsl(var(--muted) / 0.5); }
html[data-theme="dark"] .section-alt { background: hsl(var(--card) / 0.45); }
.section-head { max-width: 46rem; margin-inline: auto; text-align: center; }
.section-head p { margin-top: 1.1rem; font-size: 1.06rem; color: hsl(var(--muted-foreground)); }

/* ── Header ─────────────────────────────────────────────────── */
.site-header {
  position: fixed; inset-inline: 0; top: 0; z-index: 60;
  border-bottom: 1px solid transparent;
  transition: background 0.3s ease, border-color 0.3s ease, padding 0.3s ease;
  padding-block: 0.9rem;
}
.site-header.scrolled {
  background: hsl(var(--background) / 0.82);
  backdrop-filter: blur(12px);
  -webkit-backdrop-filter: blur(12px);
  border-color: hsl(var(--border) / 0.7);
  padding-block: 0.45rem;
}
.header-inner { display: flex; align-items: center; gap: 1rem; }
.brand { display: inline-flex; align-items: center; gap: 0.55rem; font-weight: 800; font-size: 1.2rem; text-decoration: none; }
.brand img { width: 30px; height: 30px; }
/* pivot-icon.svg is authored light-on-dark: invert it on light backgrounds. */
.brand img { filter: invert(1); }
html[data-theme="dark"] .brand img { filter: none; }
.main-nav { display: none; gap: 1.4rem; margin-inline: auto; }
.main-nav a { text-decoration: none; font-size: 0.92rem; font-weight: 500; color: hsl(var(--muted-foreground)); transition: color 0.2s; }
.main-nav a:hover { color: hsl(var(--foreground)); }
@media (min-width: 860px) { .main-nav { display: flex; } }
.header-actions { display: flex; align-items: center; gap: 0.5rem; margin-left: auto; }
/* Les pages légales et support n'ont pas de `.main-nav` : sans elle, rien ne
   pousse les actions à droite, elles se collaient au logo. On ne neutralise
   donc `margin-left: auto` que lorsque la nav est présente pour le faire. */
@media (min-width: 860px) { .main-nav + .header-actions { margin-left: 0; } }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.25rem; height: 2.25rem; border-radius: var(--radius);
  border: none; background: transparent; color: hsl(var(--muted-foreground));
  cursor: pointer; transition: background 0.2s, color 0.2s;
  font-size: 1rem; text-decoration: none;
}
.icon-btn:hover { background: hsl(var(--secondary)); color: hsl(var(--foreground)); }
.lang-switch { font-size: 0.78rem; font-weight: 700; letter-spacing: 0.06em; width: auto; padding-inline: 0.55rem; }

/* The toggle shows the icon of the theme it would switch TO. */
html:not([data-theme="dark"]) .theme-icon-sun { display: none; }
html[data-theme="dark"] .theme-icon-moon { display: none; }

/* ── Buttons ────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5rem;
  border-radius: var(--radius); border: 1px solid transparent;
  font-weight: 600; font-size: 0.95rem; text-decoration: none; cursor: pointer;
  padding: 0.7rem 1.35rem; transition: background 0.2s, border-color 0.2s, transform 0.15s;
  font-family: inherit;
}
.btn:active { transform: translateY(1px); }
.btn-primary {
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  box-shadow: 0 0 24px -6px var(--glow);
}
.btn-primary:hover { background: hsl(var(--primary) / 0.85); }
.btn-outline { border-color: hsl(var(--border)); background: transparent; color: hsl(var(--foreground)); }
.btn-outline:hover { background: hsl(var(--secondary)); }
.btn-sm { padding: 0.45rem 0.95rem; font-size: 0.88rem; }
/* Without this, `disabled` changed nothing on screen during submission. */
.btn:disabled { opacity: 0.55; cursor: default; }
.btn:disabled:active { transform: none; }

:where(a, button, input, summary):focus-visible {
  outline: 2px solid hsl(var(--ring));
  outline-offset: 2px;
  border-radius: var(--radius);
}

/* ── Hero ───────────────────────────────────────────────────── */
.hero { position: relative; overflow: hidden; padding-top: 8.5rem; padding-bottom: 4.5rem; }
.hero-bg {
  position: absolute; inset: 0; pointer-events: none;
  background:
    radial-gradient(ellipse 75% 55% at 50% -12%, hsl(var(--primary) / 0.13), transparent),
    radial-gradient(circle at 1px 1px, hsl(var(--foreground) / 0.06) 1px, transparent 0);
  background-size: auto, 42px 42px;
  mask-image: linear-gradient(to bottom, black 62%, transparent);
  -webkit-mask-image: linear-gradient(to bottom, black 62%, transparent);
}
.hero-glow {
  position: absolute; left: 18%; top: 30%; width: 420px; height: 260px;
  border-radius: 999px; background: hsl(var(--primary) / 0.3); filter: blur(140px);
  animation: glow-slide 5s linear infinite alternate; pointer-events: none;
}
@keyframes glow-slide {
  from { transform: translateX(-90px); opacity: 0.25; }
  to { transform: translateX(90px); opacity: 0.6; }
}
.hero-grid { position: relative; display: grid; gap: 3rem; align-items: center; }
@media (min-width: 960px) { .hero-grid { grid-template-columns: 1.05fr 0.95fr; } }

.hero-badge {
  display: inline-flex; align-items: center; gap: 0.5rem;
  border: 1px solid hsl(var(--primary) / 0.4); border-radius: 999px;
  background: hsl(var(--primary) / 0.08);
  padding: 0.32rem 0.85rem; font-size: 0.8rem; font-weight: 600;
  color: hsl(var(--primary)); margin-bottom: 1.4rem;
}
.hero-badge .dot {
  width: 7px; height: 7px; border-radius: 999px; background: hsl(var(--primary));
  animation: pulse 2s ease-in-out infinite;
}
@keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.35; } }

.hero-sub { margin-top: 1.4rem; font-size: 1.12rem; color: hsl(var(--muted-foreground)); max-width: 34rem; }

/* ── Email capture form ─────────────────────────────────────── */
.lead-form { margin-top: 2rem; display: flex; flex-direction: column; gap: 0.6rem; max-width: 30rem; }
.lead-row { display: flex; flex-direction: column; gap: 0.6rem; }
@media (min-width: 520px) { .lead-row { flex-direction: row; } }
.lead-form input[type="email"] {
  flex: 1; min-width: 0;
  border: 1px solid hsl(var(--border)); border-radius: var(--radius);
  background: hsl(var(--card)); color: hsl(var(--foreground));
  /* 16px exactly: below that, iOS zooms the page on focus. */
  padding: 0.72rem 1rem; font-size: 16px; font-family: inherit;
  transition: border-color 0.2s;
}
.lead-form input[type="email"]::placeholder { color: hsl(var(--muted-foreground) / 0.8); }
.lead-form input[type="email"]:focus { border-color: hsl(var(--primary)); outline: none; }
/* Honeypot — visually gone, still focusable-proof */
.lead-form .hp-field { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.lead-note { font-size: 0.82rem; color: hsl(var(--muted-foreground)); display: flex; flex-wrap: wrap; gap: 0.35rem 1.1rem; }
.lead-note span::before { content: "✓"; color: hsl(var(--primary)); margin-right: 0.35rem; font-weight: 700; }
.lead-consent { font-size: 0.75rem; color: hsl(var(--muted-foreground)); }
.lead-consent a { color: hsl(var(--primary)); }
.lead-msg { font-size: 0.9rem; font-weight: 600; margin: 0; }
.lead-msg:not(:empty) { min-height: 1.3em; }
.lead-msg.ok { color: hsl(var(--primary)); }
.lead-msg.err { color: hsl(0 72% 45%); }
html[data-theme="dark"] .lead-msg.err { color: hsl(0 84% 65%); }

/* ── Hero visual: viewer iframe or CSS 3D fallback ──────────── */
.hero-visual { position: relative; }
.viewer-frame {
  position: relative; border-radius: calc(var(--radius) * 2);
  border: 1px solid hsl(var(--border));
  background: hsl(var(--card));
  box-shadow: 0 0 60px -12px var(--glow);
  overflow: hidden; aspect-ratio: 1 / 1; max-height: 480px; width: 100%;
}
/* Hero: oversize the stage like the original site's hero viewer column.
   Spills mostly to the right (page margin) so it never covers the hero copy.
   Taller than wide (5/6): the fit-to-frame then keys on the WIDTH (product
   size unchanged) and the extra height is pure headroom — legs and floor
   smudge get vertical breathing room at every tilt angle. */
@media (min-width: 960px) {
  .hero-visual .viewer-frame--bare {
    width: 128%;
    margin-left: -6%;
    aspect-ratio: 5 / 6;
    max-height: 800px;
    /* Lift the stage so the top of the product lines up with the H1. */
    transform: translateY(-44px);
  }
}
.viewer-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
/* The embedded viewer page declares color-scheme:light; the iframe element
   must match or the browser composites an opaque white backdrop behind it
   (transparent embeds turn into a white square on the dark landing). */
.viewer-frame iframe { color-scheme: light; }
.viewer-hint {
  position: absolute; bottom: 0.8rem; left: 50%; transform: translateX(-50%);
  font-size: 0.78rem; color: hsl(var(--muted-foreground));
  background: hsl(var(--background) / 0.7); backdrop-filter: blur(6px);
  padding: 0.25rem 0.8rem; border-radius: 999px; border: 1px solid hsl(var(--border) / 0.6);
  pointer-events: none; white-space: nowrap;
}

/* Provenance badge: a quiet credit that only shows while the visitor is
   already engaging with the viewer (hover / keyboard focus on the frame).
   Hover on the frame still fires while the pointer sits over its iframe,
   so no script is needed. It lives OUTSIDE .viewer-frame — a sibling in
   .hero-visual — because the frame's radial mask would fade anything
   pinned near its bottom edge. Touch devices never hover: the badge stays
   hidden there, which keeps the hero clean on mobile. */
.viewer-badge {
  position: absolute; bottom: 1.4rem; left: 50%; transform: translate(-50%, 4px);
  font-size: 0.72rem; letter-spacing: 0.01em; color: hsl(var(--muted-foreground));
  background: hsl(var(--background) / 0.7); backdrop-filter: blur(6px);
  padding: 0.2rem 0.7rem; border-radius: 999px; border: 1px solid hsl(var(--border) / 0.6);
  pointer-events: none; white-space: nowrap;
  opacity: 0; transition: opacity 0.35s ease, transform 0.35s ease;
}
.viewer-frame:hover + .viewer-badge,
.viewer-frame:focus-within + .viewer-badge { opacity: 1; transform: translate(-50%, 0); }

/* Frameless variant: the 3D content floats directly on the page (hero).
   The viewer is embedded with ?transparent=1, so no stage is needed.
   The radial mask fades content out near the frame edges: the soft floor
   smudge around a scan can legitimately exceed the fitted framing, and a
   fade reads as depth-of-field instead of a hard crop line. */
.viewer-frame--bare { border: 0; background: transparent; box-shadow: none; }
.viewer-frame--bare.has-viewer {
  -webkit-mask-image: radial-gradient(ellipse 78% 78% at 50% 50%, #000 58%, transparent 97%);
  mask-image: radial-gradient(ellipse 78% 78% at 50% 50%, #000 58%, transparent 97%);
}

/* CSS-only placeholder shown until a demo scan id is configured */
.cube-stage { position: absolute; inset: 0; display: grid; place-items: center; perspective: 900px; }
.cube { position: relative; width: 130px; height: 130px; transform-style: preserve-3d; animation: cube-spin 14s linear infinite; }
@keyframes cube-spin { from { transform: rotateX(-18deg) rotateY(0); } to { transform: rotateX(-18deg) rotateY(360deg); } }
.cube span {
  position: absolute; inset: 0; border: 1.5px solid hsl(var(--primary) / 0.75);
  background: hsl(var(--primary) / 0.05); border-radius: 6px;
}
.cube span:nth-child(1) { transform: rotateY(0deg) translateZ(65px); }
.cube span:nth-child(2) { transform: rotateY(90deg) translateZ(65px); border-color: var(--grad-pink-b); }
.cube span:nth-child(3) { transform: rotateY(180deg) translateZ(65px); }
.cube span:nth-child(4) { transform: rotateY(270deg) translateZ(65px); border-color: var(--grad-blue-b); }
.cube span:nth-child(5) { transform: rotateX(90deg) translateZ(65px); }
.cube span:nth-child(6) { transform: rotateX(-90deg) translateZ(65px); }
.cube-floor {
  position: absolute; bottom: 18%; width: 220px; height: 30px; border-radius: 50%;
  background: radial-gradient(ellipse, hsl(var(--primary) / 0.25), transparent 70%);
  filter: blur(6px);
}

/* ── Stats strip ────────────────────────────────────────────── */
.stats { display: grid; gap: 1.5rem; grid-template-columns: repeat(2, 1fr); margin-top: 4rem; }
@media (min-width: 860px) { .stats { grid-template-columns: repeat(4, 1fr); } }
.stat { text-align: center; }
.stat strong { display: block; font-size: 2.3rem; font-weight: 800; color: hsl(var(--primary)); letter-spacing: -0.03em; }
.stat p { font-size: 0.9rem; color: hsl(var(--muted-foreground)); margin-top: 0.3rem; }
.stats-note { text-align: center; font-size: 0.78rem; color: hsl(var(--muted-foreground)); margin-top: 1.6rem; }

/* ── Cards ──────────────────────────────────────────────────── */
.cards { display: grid; gap: 1.4rem; margin-top: 3.2rem; }
.cards-3 { grid-template-columns: 1fr; }
@media (min-width: 860px) { .cards-3 { grid-template-columns: repeat(3, 1fr); } }
.cards-2 { grid-template-columns: 1fr; }
@media (min-width: 860px) { .cards-2 { grid-template-columns: repeat(2, 1fr); } }

.card {
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: hsl(var(--card) / 0.6); backdrop-filter: blur(4px);
  padding: 1.6rem; transition: border-color 0.3s, box-shadow 0.3s, transform 0.3s;
}
.card:hover { border-color: hsl(var(--primary) / 0.5); box-shadow: 0 0 30px -8px var(--glow); transform: translateY(-2px); }
.card h3 { margin-bottom: 0.55rem; }
.card p { font-size: 0.94rem; color: hsl(var(--muted-foreground)); }
.card .icon-tile {
  display: inline-flex; align-items: center; justify-content: center;
  width: 2.7rem; height: 2.7rem; border-radius: var(--radius);
  background: hsl(var(--primary) / 0.12); color: hsl(var(--primary));
  font-size: 1.25rem; margin-bottom: 1rem;
}

/* ── How it works ───────────────────────────────────────────── */
.steps { display: grid; gap: 2.2rem; margin-top: 3.4rem; }
@media (min-width: 860px) { .steps { grid-template-columns: repeat(3, 1fr); } }
.step { text-align: center; padding-inline: 0.4rem; }
.step-num {
  display: inline-flex; align-items: center; justify-content: center;
  width: 4rem; height: 4rem; border-radius: 999px;
  border: 2px solid hsl(var(--primary)); color: hsl(var(--primary));
  font-weight: 800; font-size: 1.25rem; margin-bottom: 1.2rem;
  box-shadow: 0 0 20px -4px var(--glow);
}
.step h3 { margin-bottom: 0.6rem; }
.step p { font-size: 0.94rem; color: hsl(var(--muted-foreground)); text-align: left; }

/* ── Chips ──────────────────────────────────────────────────── */
/* list-style reset: <li> stays a list-item inside a flex container, so the
   markers would otherwise show as bullets between the chips. */
.chips { display: flex; flex-wrap: wrap; gap: 0.6rem; justify-content: center; margin: 2.4rem 0 0; padding: 0; list-style: none; }
.chip {
  border: 1px solid hsl(var(--border)); border-radius: 999px;
  padding: 0.35rem 1rem; font-size: 0.85rem; font-weight: 500;
  color: hsl(var(--muted-foreground)); background: hsl(var(--card) / 0.5);
}

/* ── Gallery of real scans ──────────────────────────────────── */
.gallery { display: grid; gap: 1.2rem; grid-template-columns: repeat(2, 1fr); margin-top: 3rem; }
@media (min-width: 860px) { .gallery { grid-template-columns: repeat(3, 1fr); } }
.gallery-card {
  position: relative; margin: 0; overflow: hidden;
  display: block; text-decoration: none; color: inherit; /* cards are <a> */
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: hsl(var(--card)); aspect-ratio: 1 / 1;
  transition: border-color 0.3s, box-shadow 0.3s, transform 0.3s;
}
/* <img> for the one scan whose splat is too heavy to turntable. */
.gallery-card video, .gallery-card img { width: 100%; height: 100%; object-fit: cover; display: block; }
.gallery-label {
  position: absolute; inset-inline: 0; bottom: 0; padding: 1.8rem 0.9rem 0.7rem;
  font-size: 0.88rem; font-weight: 600; color: #fff;
  background: linear-gradient(to top, rgb(0 0 0 / 0.65), transparent);
  pointer-events: none;
}
/* "1A — expandable glass pill": at rest a frosted-glass "3D" chip whose cube
   slowly orbits; on card hover/focus the pill stretches to reveal the verb.
   No brand color sits on the photo — the card border carries the accent. */
.gallery-badge {
  position: absolute; top: 0.85rem; right: 0.85rem; display: none;
  align-items: center; gap: 8px; padding: 7px 12px; border-radius: 999px;
  background: rgb(23 23 23 / 0.42);
  -webkit-backdrop-filter: blur(14px) saturate(140%);
  backdrop-filter: blur(14px) saturate(140%);
  border: 1px solid rgb(255 255 255 / 0.16);
  box-shadow: 0 6px 20px rgb(0 0 0 / 0.28);
  font-size: 12px; color: #fff;
}
.badge-cube {
  width: 13px; height: 13px; display: grid; place-items: center;
  animation: badge-orbit 7s cubic-bezier(0.5, 0, 0.5, 1) infinite;
  transform-style: preserve-3d;
}
.badge-cube > span {
  width: 9px; height: 9px; display: block;
  border: 1.5px solid #fff; border-radius: 2px; opacity: 0.92;
}
.badge-3d { font-weight: 600; letter-spacing: 0.06em; }
.badge-label {
  display: block; overflow: hidden; white-space: nowrap;
  max-width: 0; opacity: 0; margin-left: -8px; /* swallow the flex gap while collapsed */
  font-weight: 500; letter-spacing: 0.04em; color: rgb(255 255 255 / 0.86);
  transition: max-width 0.34s cubic-bezier(0.2, 0.8, 0.2, 1), opacity 0.24s ease, margin-left 0.34s cubic-bezier(0.2, 0.8, 0.2, 1);
}
.gallery-card.has-viewer:hover .badge-label,
.gallery-card.has-viewer:focus-visible .badge-label { max-width: 80px; opacity: 1; margin-left: -4px; }
@keyframes badge-orbit { 0%, 100% { transform: rotateY(0deg); } 50% { transform: rotateY(180deg); } }
@media (prefers-reduced-motion: reduce) { .badge-cube { animation: none; } }
.gallery-card.has-viewer { cursor: pointer; }
.gallery-card.has-viewer .gallery-badge { display: inline-flex; }
.gallery-card.has-viewer:hover, .gallery-card.has-viewer:focus-visible {
  border-color: hsl(var(--primary) / 0.6);
  box-shadow: 0 0 30px -8px var(--glow);
  transform: translateY(-2px);
}

/* ── Viewer comparison ──────────────────────────────────────── */
/* Always two columns: stacked, the Shopify render (the weak one) would come
   first and fill the screen, so the block would sell the wrong viewer. */
.compare { display: grid; gap: 0.6rem; margin-top: 2rem; grid-template-columns: 1fr 1fr; }
@media (min-width: 700px) { .compare { gap: 1.4rem; margin-top: 3rem; } }
.compare figure {
  margin: 0; overflow: hidden;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: hsl(var(--card));
}
.compare figure.compare-winner { border-color: hsl(var(--primary) / 0.6); box-shadow: 0 0 30px -8px var(--glow); }
.compare video { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
/* Light theme (default): the recordings have a near-white background that
   never exactly matches the card color, so a hard square seam shows. Same
   trick as the hero: fade the edges so the video melts into the card. In dark
   theme the white video reads as a deliberate media rectangle — keep it crisp. */
.compare video {
  -webkit-mask-image: radial-gradient(ellipse 62% 62% at 50% 50%, #000 52%, transparent 95%);
  mask-image: radial-gradient(ellipse 62% 62% at 50% 50%, #000 52%, transparent 95%);
}
html[data-theme="dark"] .compare video {
  -webkit-mask-image: none;
  mask-image: none;
}
.compare figcaption { padding: 0.65rem 0.75rem 0.85rem; font-size: 0.78rem; color: hsl(var(--muted-foreground)); }
@media (min-width: 700px) { .compare figcaption { padding: 0.9rem 1.1rem 1.1rem; font-size: 0.88rem; } }
.compare figcaption strong { display: block; color: hsl(var(--foreground)); margin-bottom: 0.2rem; }

/* ── Pricing ────────────────────────────────────────────────── */
.pricing-banner {
  margin: 2.6rem auto 0; max-width: 44rem; text-align: center;
  border: 1px dashed hsl(var(--primary) / 0.55); border-radius: var(--radius);
  background: hsl(var(--primary) / 0.07); padding: 0.85rem 1.2rem;
  font-size: 0.94rem; font-weight: 600; color: hsl(var(--primary));
}
.plans { display: grid; gap: 1.4rem; margin-top: 2.6rem; align-items: stretch; }
@media (min-width: 700px) { .plans { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1080px) { .plans { grid-template-columns: repeat(4, 1fr); } }
.plan {
  display: flex; flex-direction: column;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: hsl(var(--card) / 0.6); padding: 1.7rem 1.5rem;
}
.plan.featured { border-color: hsl(var(--primary)); box-shadow: 0 0 40px -10px var(--glow); position: relative; }
.plan-tag {
  position: absolute; top: -0.8rem; left: 50%; transform: translateX(-50%);
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  border-radius: 999px; font-size: 0.72rem; font-weight: 700; letter-spacing: 0.05em;
  padding: 0.22rem 0.85rem; text-transform: uppercase; white-space: nowrap;
}
.plan h3 { font-size: 1rem; text-transform: uppercase; letter-spacing: 0.08em; color: hsl(var(--muted-foreground)); }
.plan .price { margin-top: 0.7rem; font-size: 2.2rem; font-weight: 800; letter-spacing: -0.03em; }
.plan .price small { font-size: 0.9rem; font-weight: 500; color: hsl(var(--muted-foreground)); }
.plan ul { list-style: none; padding: 0; margin: 1.2rem 0 1.6rem; display: grid; gap: 0.55rem; }
.plan li { font-size: 0.9rem; color: hsl(var(--muted-foreground)); padding-left: 1.4rem; position: relative; }
.plan li::before { content: "✓"; position: absolute; left: 0; color: hsl(var(--primary)); font-weight: 700; }
.plan .btn { margin-top: auto; }
.pricing-note { text-align: center; font-size: 0.82rem; color: hsl(var(--muted-foreground)); margin-top: 2rem; max-width: 44rem; margin-inline: auto; }

/* ── FAQ ────────────────────────────────────────────────────── */
.faq { max-width: 46rem; margin: 3rem auto 0; }
.faq details { border-bottom: 1px solid hsl(var(--border)); }
.faq summary {
  cursor: pointer; list-style: none; display: flex; justify-content: space-between; align-items: center;
  gap: 1rem; padding: 1.1rem 0.2rem; font-weight: 600; font-size: 0.98rem;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.3rem; color: hsl(var(--primary)); transition: transform 0.25s; flex-shrink: 0; }
.faq details[open] summary::after { transform: rotate(45deg); }
.faq details p { padding: 0 0.2rem 1.2rem; font-size: 0.93rem; color: hsl(var(--muted-foreground)); }
.faq-contact { text-align: center; margin-top: 2.4rem; font-size: 0.95rem; }
.faq-contact a { color: hsl(var(--primary)); font-weight: 600; }

/* ── Final CTA ──────────────────────────────────────────────── */
.final-cta { text-align: center; position: relative; overflow: hidden; }
.final-cta .lead-form { margin-inline: auto; align-items: center; }
.final-cta .lead-row { width: 100%; justify-content: center; }
.final-cta .lead-note { justify-content: center; }

/* ── Footer ─────────────────────────────────────────────────── */
.site-footer { border-top: 1px solid hsl(var(--border) / 0.7); padding-block: 3.2rem 6.5rem; }
@media (min-width: 860px) { .site-footer { padding-bottom: 3.2rem; } }
.footer-grid { display: grid; gap: 2.2rem; }
@media (min-width: 860px) { .footer-grid { grid-template-columns: 2fr 1fr 1fr 1fr; } }
.site-footer h3 { font-size: 0.85rem; text-transform: uppercase; letter-spacing: 0.08em; color: hsl(var(--muted-foreground)); margin-bottom: 0.9rem; }
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.5rem; }
.site-footer a { text-decoration: none; font-size: 0.92rem; color: hsl(var(--muted-foreground)); }
.site-footer a:hover { color: hsl(var(--foreground)); }
.footer-brand p { margin-top: 0.8rem; font-size: 0.9rem; color: hsl(var(--muted-foreground)); max-width: 20rem; }
.footer-bottom { margin-top: 2.8rem; padding-top: 1.4rem; border-top: 1px solid hsl(var(--border) / 0.5); font-size: 0.82rem; color: hsl(var(--muted-foreground)); display: flex; flex-wrap: wrap; gap: 0.6rem 1.6rem; }

/* ── Mobile sticky CTA ──────────────────────────────────────── */
.mobile-cta {
  position: fixed; inset-inline: 0; bottom: 0; z-index: 55;
  background: hsl(var(--background) / 0.92); backdrop-filter: blur(10px);
  border-top: 1px solid hsl(var(--border)); padding: 0.7rem 1rem;
}
.mobile-cta .btn { width: 100%; }
@media (min-width: 860px) { .mobile-cta { display: none; } }

/* ── Legal pages ────────────────────────────────────────────── */
.legal { max-width: 46rem; margin-inline: auto; padding: 8.5rem 1.25rem 5rem; }
.legal h1 { font-size: 2.2rem; }
.legal .legal-date { margin-top: 0.8rem; font-size: 0.9rem; color: hsl(var(--muted-foreground)); }
.legal h2 { font-size: 1.25rem; font-weight: 700; margin-top: 2.6rem; }
.legal p, .legal li { font-size: 0.96rem; color: hsl(var(--muted-foreground)); margin-top: 0.8rem; }
.legal ul { padding-left: 1.2rem; }
.legal a { color: hsl(var(--primary)); }
/* `.legal a` est en (0,2,0) et battait `.btn-primary` : le bouton plein
   ressortait vert sur vert, donc invisible. */
.legal a.btn-primary { color: hsl(var(--primary-foreground)); }
.legal a.btn-outline, .legal a.btn-sm { color: hsl(var(--foreground)); }
.legal strong { color: hsl(var(--foreground)); }
/* A .btn inside a .legal page: `.legal a` is more specific than `.btn-*`, so
   without these the primary button's label is painted with the link colour,
   i.e. green on green. Used by the support page's "email us" button. */
.legal .btn-primary { color: hsl(var(--primary-foreground)); }
.legal .btn-outline { color: hsl(var(--foreground)); }

/* ── Blog ───────────────────────────────────────────────────── */
/* Long-form reading column. Wider than .legal would be comfortable at this
   length, so the measure is set in ch rather than rem: it tracks the font and
   lands near 70 characters, which is where sustained reading stays easy. */
.article { max-width: 44rem; margin-inline: auto; padding: 8.5rem 1.25rem 5rem; }
.article h1 { font-size: clamp(1.9rem, 4.4vw, 2.6rem); line-height: 1.12; letter-spacing: -0.025em; text-wrap: balance; }
.article .article-meta { margin-top: 1rem; font-size: 0.86rem; color: hsl(var(--muted-foreground)); display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; }
.article .lede { margin-top: 1.6rem; font-size: 1.1rem; line-height: 1.6; color: hsl(var(--foreground)); }
.article h2 { font-size: 1.35rem; font-weight: 700; margin-top: 3rem; letter-spacing: -0.015em; text-wrap: balance; }
.article h3 { font-size: 1.05rem; font-weight: 600; margin-top: 2rem; }
.article p, .article li { font-size: 1rem; line-height: 1.68; color: hsl(var(--muted-foreground)); margin-top: 0.9rem; }
.article ul, .article ol { padding-left: 1.3rem; }
.article li { margin-top: 0.5rem; }
.article a { color: hsl(var(--primary)); text-underline-offset: 3px; }
.article strong { color: hsl(var(--foreground)); }
.article hr { margin: 3rem 0 0; border: 0; border-top: 1px solid hsl(var(--border)); }

/* Quoted documentation. The whole point of these posts is that the facts are
   first-hand, so a quote has to look like a quote and carry its source. */
.article blockquote {
  margin: 1.4rem 0 0; padding: 0.9rem 1.2rem;
  border-left: 2px solid hsl(var(--primary)); background: hsl(var(--secondary) / 0.5);
  border-radius: 0 var(--radius) var(--radius) 0;
}
.article blockquote p { margin-top: 0; color: hsl(var(--foreground)); font-size: 0.97rem; }
.article blockquote p + p { margin-top: 0.7rem; }
.article blockquote cite { display: block; margin-top: 0.6rem; font-size: 0.8rem; font-style: normal; color: hsl(var(--muted-foreground)); }

.article code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.88em; background: hsl(var(--secondary)); border: 1px solid hsl(var(--border)); border-radius: 4px; padding: 0.1em 0.35em; }
.article pre { margin-top: 1.2rem; padding: 1rem 1.1rem; background: hsl(var(--secondary)); border: 1px solid hsl(var(--border)); border-radius: var(--radius); overflow-x: auto; }
.article pre code { background: none; border: 0; padding: 0; font-size: 0.86rem; line-height: 1.55; }

/* Closing note about Pivot. Visibly set apart from the article body so the
   reader can see where the reporting stops and the pitch starts. */
.article .endnote { margin-top: 2rem; padding: 1.2rem 1.3rem; border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 1.5); background: hsl(var(--card)); }
.article .endnote p { margin-top: 0; }
.article .endnote p + p { margin-top: 0.7rem; }

/* Index */
.blog-index { max-width: 44rem; margin-inline: auto; padding: 8.5rem 1.25rem 5rem; }
.blog-index h1 { font-size: clamp(1.9rem, 4.4vw, 2.6rem); letter-spacing: -0.025em; }
.blog-index > p { margin-top: 1rem; font-size: 1rem; color: hsl(var(--muted-foreground)); }
.post-list { list-style: none; margin: 2.8rem 0 0; padding: 0; display: grid; gap: 1rem; }
.post-list li { margin: 0; }
.post-list a { display: block; padding: 1.4rem 1.5rem; border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 1.5); background: hsl(var(--card)); text-decoration: none; }
.post-list a:hover { border-color: hsl(var(--foreground) / 0.22); }
.post-list h2 { font-size: 1.12rem; font-weight: 650; letter-spacing: -0.015em; color: hsl(var(--foreground)); text-wrap: balance; }
.post-list p { margin-top: 0.5rem; font-size: 0.94rem; line-height: 1.6; color: hsl(var(--muted-foreground)); }
.post-list time { display: block; margin-bottom: 0.5rem; font-size: 0.78rem; letter-spacing: 0.04em; text-transform: uppercase; color: hsl(var(--muted-foreground)); }

/* ── Reveal on scroll ───────────────────────────────────────── */
/* Scoped to html.js (added by landing.js) so content stays visible without JS. */
html.js .reveal { opacity: 0; transform: translateY(24px); transition: opacity 0.7s ease-out, transform 0.7s ease-out; }
html.js .reveal.visible { opacity: 1; transform: none; }

/* Hero load-in stagger */
.hero [data-stagger] { opacity: 0; transform: translateY(16px); animation: rise 0.7s ease-out forwards; }
/* LCP: the h1 must paint immediately — it only slides, never hides. */
.hero h1[data-stagger] { opacity: 1; animation-name: rise-move; }
@keyframes rise-move { to { transform: none; } }
.hero [data-stagger="1"] { animation-delay: 0.05s; }
.hero [data-stagger="2"] { animation-delay: 0.15s; }
.hero [data-stagger="3"] { animation-delay: 0.25s; }
.hero [data-stagger="4"] { animation-delay: 0.35s; }
.hero [data-stagger="5"] { animation-delay: 0.45s; }
@keyframes rise { to { opacity: 1; transform: none; } }

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .hero [data-stagger], html.js .reveal { opacity: 1; transform: none; animation: none; transition: none; }
  .hero-glow, .cube, .hero-badge .dot { animation: none; }
}

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}

.skip-link {
  position: absolute; left: 1rem; top: -3rem; z-index: 100;
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  padding: 0.5rem 1rem; border-radius: var(--radius); font-weight: 600; text-decoration: none;
  transition: top 0.2s;
}
.skip-link:focus { top: 1rem; }


/* ============================================================
   Refonte UI — direction « Sobre produit / Bento » (A3).
   Overrides appliqués après la base ; la cascade fait foi.
   ============================================================ */

/* Variante A — « Sobre produit » : neutre, contrasté, zéro glow (réf. linear/vercel) */

:root {
  --background: 0 0% 99%;
  --card: 0 0% 100%;
  --muted: 0 0% 95.5%;
  --muted-foreground: 0 0% 42%;
  --secondary: 0 0% 95%;
  --border: 0 0% 90%;
  --radius: 0.5rem;
  --glow: transparent;
}
html[data-theme="dark"] {
  --background: 0 0% 3.9%;
  --card: 0 0% 6.5%;
  --card-foreground: 0 0% 95%;
  --muted: 0 0% 12%;
  --muted-foreground: 0 0% 63%;
  --secondary: 0 0% 10.5%;
  --border: 0 0% 14.5%;
  --glow: transparent;
}

body { font-family: "Geist", ui-sans-serif, system-ui, sans-serif; }

h1 { font-weight: 600; letter-spacing: -0.045em; font-size: clamp(2.4rem, 5.5vw, 3.6rem); line-height: 1.08; }
h2 { font-weight: 600; letter-spacing: -0.035em; }
h3 { font-weight: 600; }
.brand { font-weight: 650; }

/* Un seul accent : plus de dégradés */
.grad-pink, .grad-blue, .grad-green {
  background: none; -webkit-background-clip: border-box; background-clip: border-box;
  color: inherit;
}
.grad-pink { color: hsl(var(--primary)); }

.hero-glow { display: none; }
.hero-bg {
  background: radial-gradient(ellipse 65% 45% at 50% -10%, hsl(var(--foreground) / 0.055), transparent);
  mask-image: none; -webkit-mask-image: none;
}
.hero-badge {
  border-color: hsl(var(--border)); background: hsl(var(--card));
  color: hsl(var(--muted-foreground)); font-weight: 500;
}
.hero-badge .dot { background: hsl(var(--primary)); }

.btn { font-weight: 500; }
.btn-primary { box-shadow: none; }

.section { padding-block: 6.5rem; }
.section-alt { background: transparent; border-block: 1px solid hsl(var(--border) / 0.7); }
html[data-theme="dark"] .section-alt { background: transparent; }

.stats { gap: 0; border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2); overflow: hidden; }
.stat { padding: 1.5rem 1.2rem; }
.stat strong { color: hsl(var(--foreground)); font-weight: 600; letter-spacing: -0.04em; }
@media (min-width: 860px) { .stat + .stat { border-left: 1px solid hsl(var(--border)); } }
@media (max-width: 859.98px) {
  .stat:nth-child(even) { border-left: 1px solid hsl(var(--border)); }
  .stat:nth-child(n+3) { border-top: 1px solid hsl(var(--border)); }
}

.card { background: hsl(var(--card)); backdrop-filter: none; }
.card:hover { box-shadow: none; transform: none; border-color: hsl(var(--foreground) / 0.22); }
.card .icon-tile {
  background: hsl(var(--secondary)); color: hsl(var(--foreground));
  border: 1px solid hsl(var(--border)); font-size: 1.05rem;
  width: 2.4rem; height: 2.4rem;
}

.step-num {
  width: 2.4rem; height: 2.4rem; border-radius: var(--radius);
  border: 1px solid hsl(var(--border)); color: hsl(var(--muted-foreground));
  font-size: 0.92rem; font-weight: 600; box-shadow: none;
}

.chip { background: hsl(var(--card)); }

.gallery-card.has-viewer:hover, .gallery-card.has-viewer:focus-visible {
  box-shadow: none; transform: none; border-color: hsl(var(--foreground) / 0.3);
}
.compare figure.compare-winner { box-shadow: none; border-color: hsl(var(--primary) / 0.7); }

.pricing-banner {
  border: 1px solid hsl(var(--border)); background: hsl(var(--card));
  color: hsl(var(--foreground)); font-weight: 500;
}
.pricing-banner strong { color: hsl(var(--primary)); }
.plan { background: hsl(var(--card)); }
.plan.featured { box-shadow: none; }
.plan .price { font-weight: 600; }

.viewer-frame { box-shadow: none; }

/* A3 — « Bento » : tuiles à spans variés, stats en cartes, galerie mosaïque */
:root { --radius: 0.7rem; }

.card {
  border-radius: calc(var(--radius) * 2);
  background: linear-gradient(180deg, hsl(var(--card)), hsl(var(--background)) 140%);
  padding: 1.8rem;
}
.card:hover { border-color: hsl(var(--foreground) / 0.25); }

@media (min-width: 860px) {
  .cards-3 { grid-template-columns: repeat(6, 1fr); }
  .cards-3 .card { grid-column: span 2; }
  /* Sections de 3 cartes : 4 + 2 puis pleine largeur si 6 cartes */
  #why .cards-3 .card:nth-child(1) { grid-column: span 4; }
  #why .cards-3 .card:nth-child(2) { grid-column: span 2; }
  #why .cards-3 .card:nth-child(3) { grid-column: span 6; display: grid; grid-template-columns: auto 1fr; column-gap: 1.4rem; align-items: center; }
  #why .cards-3 .card:nth-child(3) .icon-tile { grid-row: span 2; margin-bottom: 0; }
  #features .cards-3 .card:nth-child(4) { grid-column: span 3; }
  #features .cards-3 .card:nth-child(5) { grid-column: span 3; }
  #features .cards-3 .card:nth-child(6) { grid-column: span 6; }
}

.stats { gap: 1rem; border: 0; border-radius: 0; overflow: visible; }
.stat {
  text-align: left; border: 1px solid hsl(var(--border));
  border-radius: calc(var(--radius) * 2); padding: 1.5rem 1.4rem;
  background: linear-gradient(180deg, hsl(var(--card)), hsl(var(--background)) 140%);
}
.stat + .stat { border-left: 1px solid hsl(var(--border)); }
.stat:nth-child(even), .stat:nth-child(n+3) { border-color: hsl(var(--border)); border-top: 1px solid hsl(var(--border)); }
.stat strong { font-size: 2.4rem; }

/* 4 objets, une bande sobre : 2×2 sur mobile, une rangée de 4 en desktop. */
@media (min-width: 860px) {
  .gallery { grid-template-columns: repeat(4, 1fr); }
}
.gallery-card { border-radius: calc(var(--radius) * 2); }

.cards-2 .card { padding: 2rem; }

/* ── Showcase : une rangée titrée par typologie de scan ─────── */
/* Desktop montre les deux ; le commutateur (mobile) n'en garde qu'une. */
.look-group { margin-top: 2.6rem; }
.look-group + .look-group { margin-top: 3.2rem; }
.look-title {
  font-family: var(--mono); font-size: 0.74rem; font-weight: 500;
  letter-spacing: 0.1em; text-transform: uppercase;
  color: hsl(var(--muted-foreground));
}
.look-desc {
  margin-top: 0.5rem; max-width: 42rem;
  font-size: 0.98rem; color: hsl(var(--muted-foreground));
}
.look-group .gallery { margin-top: 1.4rem; }
@media (min-width: 860px) { .look-group .gallery { grid-template-columns: repeat(3, 1fr); } }

.plan { border-radius: calc(var(--radius) * 2); background: linear-gradient(180deg, hsl(var(--card)), hsl(var(--background)) 140%); }
.plan.featured { background: hsl(var(--secondary) / 0.5); }

.compare figure { border-radius: calc(var(--radius) * 2); }
.faq details { border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 1.5); margin-bottom: 0.7rem; padding-inline: 1.1rem; }
.faq details:last-of-type { border-bottom: 1px solid hsl(var(--border)); }


/* ============================================================
   Nouveaux composants 2026-09 : mock fiche produit, parcours
   scrollé (#how-it-works), bande « vêtements portés ».
   Tokens uniquement → clair et sombre tenus d'office.
   ============================================================ */

/* ── Mock fiche produit (.pdp-mock) ─────────────────────────── */
/* Generic storefront look on purpose: no Shopify branding, and the visible
   caption says it's an illustrative preview. Reused inside journey panel 2. */
.pdp-mock {
  max-width: 56rem; margin: 3rem auto 0;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: hsl(var(--card)); overflow: hidden;
}
.pdp-chrome {
  display: flex; align-items: center; gap: 6px; padding: 0.6rem 0.9rem;
  border-bottom: 1px solid hsl(var(--border));
}
.pdp-dot { width: 9px; height: 9px; border-radius: 999px; background: hsl(var(--muted-foreground) / 0.35); }
.pdp-url {
  margin-left: 0.6rem; font-size: 0.72rem; color: hsl(var(--muted-foreground));
  background: hsl(var(--secondary)); border-radius: 999px; padding: 0.15rem 0.8rem;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  min-width: 0; /* flex item: allow the ellipsis instead of forcing width */
}
.pdp-body { display: grid; gap: 1.5rem; padding: 1.5rem; }
@media (min-width: 700px) { .pdp-body { grid-template-columns: 1.2fr 1fr; } }
.pdp-media {
  position: relative; border-radius: var(--radius); overflow: hidden;
  background: #fff; aspect-ratio: 4 / 3;
}
.pdp-poster {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; display: block;
  transition: opacity 0.6s ease;
}
/* landing.js adds is-live once the mounted viewer has painted: the still
   fades out so it never overlaps the live object at a different angle. */
.pdp-media.is-live .pdp-poster { opacity: 0; }
/* Live transparent viewer mounted over the poster by landing.js. The iframe
   must pin color-scheme:light like every other viewer embed (white-box gotcha). */
.pdp-media iframe {
  position: absolute; inset: 0; width: 100%; height: 100%; border: 0;
  color-scheme: light;
}
.pdp-info { display: flex; flex-direction: column; gap: 0.55rem; }
.pdp-vendor { font-size: 0.68rem; letter-spacing: 0.1em; color: hsl(var(--muted-foreground)); }
.pdp-title { font-size: 1.25rem; font-weight: 600; letter-spacing: -0.02em; }
.pdp-price { font-size: 1.05rem; }
.pdp-skeleton { height: 0.6rem; border-radius: 999px; background: hsl(var(--muted)); width: 90%; }
.pdp-skeleton--short { width: 60%; }
.pdp-buy {
  margin-top: 0.5rem; text-align: center; font-size: 0.9rem; font-weight: 500;
  border-radius: var(--radius); padding: 0.65rem 1rem;
  background: hsl(var(--foreground)); color: hsl(var(--background));
}
.pdp-caption {
  padding: 0.7rem 1.1rem; border-top: 1px solid hsl(var(--border));
  font-size: 0.75rem; color: hsl(var(--muted-foreground));
}

/* ── Parcours scrollé (#how-it-works) — deck de panneaux sticky ── */
/* Pure CSS sticky stack (no JS-driven heights → no CLS); landing.js only adds
   is-active / is-covered so micro-animations run on the visible panel. */
.journey { display: grid; gap: 1.4rem; margin-top: 3rem; }
.journey-panel {
  position: sticky; top: calc(4.5rem + var(--panel-peek, 0rem));
  display: grid; gap: 1.6rem; align-items: center;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: hsl(var(--card)); padding: 1.6rem;
  min-height: min(72vh, 620px);
}
.journey-panel:nth-child(2) { --panel-peek: 1rem; }
.journey-panel:nth-child(3) { --panel-peek: 2rem; }
/* Grid/flex items default to min-width:auto — the pdp-mock's nowrap URL would
   otherwise force the whole panel wider than a phone viewport. */
.journey-panel, .journey-copy, .journey-visual { min-width: 0; }
@media (min-width: 860px) { .journey-panel { grid-template-columns: 0.9fr 1.1fr; padding: 2.5rem; } }
.journey-copy .step-num { margin-bottom: 1rem; }
.journey-copy h3 { font-size: 1.35rem; letter-spacing: -0.025em; margin-bottom: 0.7rem; }
.journey-copy p { font-size: 0.96rem; color: hsl(var(--muted-foreground)); }
/* Covered panels stay fully opaque (a translucent card would let the one
   beneath bleed through while both sit at the sticky top) — the "recede"
   effect is scale + a slight dim via filter. */
html.js .journey-panel { transition: transform 0.4s ease, filter 0.4s ease; }
html.js .journey-panel.is-covered { transform: scale(0.97); filter: brightness(0.96) saturate(0.85); }

/* Panneau 1 : vraie capture de l'app (frame de l'enregistrement iPhone) */
.phone-mock {
  position: relative; width: min(260px, 74%); margin-inline: auto;
  border: 1px solid hsl(var(--border)); border-radius: 2.2rem;
  background: #101010;
  box-shadow: inset 0 0 0 6px #101010, 0 20px 50px -24px rgb(0 0 0 / 0.45);
  overflow: hidden;
}
.phone-mock--shot { aspect-ratio: 480 / 924; }
.phone-shot {
  position: absolute; inset: 6px; width: calc(100% - 12px); height: calc(100% - 12px);
  object-fit: cover; border-radius: 1.9rem; display: block;
}

/* Panneau 2 : réutilise .pdp-mock en compact */
.pdp-mock--journey { margin: 0 auto; max-width: 30rem; }
.pdp-mock--journey .pdp-body { grid-template-columns: 1fr; padding: 1rem; gap: 1rem; }
.pdp-mock--journey .pdp-caption { display: none; }

/* Panneau 3 : réglages « Tune viewer », calqués sur la vraie app Shopify */
.settings-mock {
  max-width: 24rem; margin-inline: auto; width: 100%;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 1.5);
  background: hsl(var(--background)); padding: 1.1rem;
}
.settings-title {
  font-size: 0.82rem; font-weight: 600; letter-spacing: -0.01em;
  margin-bottom: 0.7rem;
}
.settings-preview {
  aspect-ratio: 16 / 10; border-radius: var(--radius); overflow: hidden;
  background: #fff; border: 1px solid hsl(var(--border));
  display: grid; place-items: center;
  margin-bottom: 0.9rem; transition: background 0.6s ease;
}
.settings-preview img { width: 100%; height: 100%; object-fit: cover; mix-blend-mode: multiply; }
/* Le fauteuil doit tenir en entier dans les deux maquettes du parcours :
   `cover` lui coupait les pieds. Hors parcours, le cadre a le même rapport que
   l'image, donc `contain` ne change rien. */
.settings-preview img,
.pdp-mock--journey .pdp-poster { object-fit: contain; }
.preset-row { display: flex; gap: 6px; margin-bottom: 0.6rem; }
.preset-pill {
  flex: 1; text-align: center; font-size: 0.74rem; font-weight: 500;
  border: 1px solid hsl(var(--border)); border-radius: 999px; padding: 0.3rem 0.4rem;
  color: hsl(var(--muted-foreground)); transition: border-color 0.3s, color 0.3s;
}
.preset-pill.is-selected {
  border-color: hsl(var(--foreground)); color: hsl(var(--foreground)); font-weight: 600;
}
.settings-row {
  display: flex; justify-content: space-between; align-items: center; gap: 1rem;
  padding: 0.55rem 0.2rem; font-size: 0.85rem;
  border-top: 1px solid hsl(var(--border) / 0.7);
}
.ui-toggle {
  width: 34px; height: 20px; border-radius: 999px; background: hsl(var(--muted));
  position: relative; flex-shrink: 0; transition: background 0.3s;
}
.ui-toggle::after {
  content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px;
  border-radius: 999px; background: hsl(var(--background)); border: 1px solid hsl(var(--border));
  transition: left 0.3s;
}
/* Nuancier « fond de scène » — mêmes teintes que l'app (blanc, #f4f2ee, beige,
   anthracite, noir) ; la pastille sélectionnée porte un anneau vert. */
.ui-swatches { display: inline-flex; gap: 5px; }
.ui-swatches i {
  width: 17px; height: 17px; border-radius: 999px;
  border: 1px solid hsl(var(--border));
}
.ui-swatches .sw-white { background: #ffffff; }
.ui-swatches .sw-warm { background: #f4f2ee; }
.ui-swatches .sw-beige { background: #e7dfd2; }
.ui-swatches .sw-dark { background: #2b2b2b; }
.ui-swatches .sw-black { background: #0a0a0a; }
.ui-swatches .is-selected {
  box-shadow: 0 0 0 2px hsl(var(--background)), 0 0 0 3.5px hsl(var(--primary));
}
.ui-slider {
  width: 72px; height: 4px; border-radius: 999px; background: hsl(var(--muted));
  position: relative; flex-shrink: 0;
}
.ui-slider i {
  position: absolute; top: 50%; left: 55%; transform: translate(-50%, -50%);
  width: 12px; height: 12px; border-radius: 999px;
  background: hsl(var(--primary));
}
/* Le panneau actif « joue » les réglages : rotation ON, fond chaud appliqué. */
html.js .journey-panel.is-active .ui-toggle { background: hsl(var(--primary)); }
html.js .journey-panel.is-active .ui-toggle::after { left: 16px; }
html.js .journey-panel.is-active .settings-preview { background: #f4f2ee; }
.settings-caption {
  display: block; margin-top: 0.7rem; font-size: 0.7rem;
  color: hsl(var(--muted-foreground)); text-align: center;
}

/* Mobile : un panneau sticky cache tout ce qui dépasse du viewport (le
   suivant recouvre avant qu'on ait pu le voir) — chaque panneau doit donc
   tenir dans l'écran : visuels bornés en hauteur, mock fiche produit compacté. */
@media (max-width: 699.98px) {
  /* Budget réel d'un panneau : 100svh − top sticky (64px) − barre CTA mobile
     fixe (~70px). Tout doit tenir sous ~640px sur un écran de 844. */
  .journey-panel { padding: 1.1rem; min-height: 0; gap: 0.9rem; top: 4rem; --panel-peek: 0rem !important; }
  .journey-copy .step-num { margin-bottom: 0.6rem; }
  .journey-copy h3 { font-size: 1.1rem; margin-bottom: 0.45rem; }
  .journey-copy p { font-size: 0.86rem; line-height: 1.5; }
  .phone-mock { width: auto; height: min(38svh, 340px); aspect-ratio: 480 / 924; max-width: 100%; }
  .pdp-mock--journey { max-width: 21rem; }
  .pdp-mock--journey .pdp-chrome { display: none; }
  .pdp-mock--journey .pdp-body { padding: 0.8rem; gap: 0.7rem; }
  /* Le média prend la hauteur restante (voir .journey-visual) : plus de
     ratio figé, donc plus de fauteuil rogné en haut et en bas. */
  .pdp-mock--journey .pdp-media { aspect-ratio: auto; }
  .pdp-mock--journey .pdp-vendor,
  .pdp-mock--journey .pdp-skeleton { display: none; }
  .pdp-mock--journey .pdp-info { gap: 0.35rem; }
  .pdp-mock--journey .pdp-title { font-size: 1rem; }
  .pdp-mock--journey .pdp-price { font-size: 0.92rem; }
  .pdp-mock--journey .pdp-buy { padding: 0.45rem 1rem; font-size: 0.85rem; margin-top: 0.2rem; }
  .settings-mock { padding: 0.9rem; }
  .settings-preview { aspect-ratio: auto; margin-bottom: 0.6rem; padding: 6px; box-sizing: border-box; }
  .settings-title { margin-bottom: 0.5rem; }
  .settings-row { padding: 0.4rem 0.15rem; font-size: 0.82rem; }
  .preset-pill { padding: 0.24rem 0.4rem; }
  .settings-caption { margin-top: 0.5rem; }
}

/* Fallback du parcours : reduced-motion = pile statique (le deck sticky reste
   actif sur mobile — seule la largeur change la mise en page interne). */
@media (prefers-reduced-motion: reduce) {
  .journey-panel { position: static !important; min-height: 0; transform: none !important; opacity: 1 !important; }
}

/* ── Bande « vêtements portés » (#apparel) ──────────────────── */
.highlight-band {
  display: grid; gap: 2rem; margin-top: 1.4rem; padding: 2rem;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: linear-gradient(180deg, hsl(var(--card)), hsl(var(--background)) 140%);
}
@media (min-width: 860px) {
  .highlight-band { grid-template-columns: 1.1fr 0.9fr; align-items: center; padding: 2.5rem; }
}
.highlight-kicker {
  font-size: 0.75rem; font-weight: 600; letter-spacing: 0.08em; text-transform: uppercase;
  color: hsl(var(--primary)); margin-bottom: 0.6rem;
}
.highlight-band h3 { font-size: 1.5rem; letter-spacing: -0.025em; }
.highlight-copy > p:not(.highlight-kicker):not(.highlight-note) {
  margin-top: 0.8rem; color: hsl(var(--muted-foreground)); font-size: 0.98rem;
}
.highlight-points { list-style: none; padding: 0; margin: 1.2rem 0 0; display: grid; gap: 0.5rem; }
.highlight-points li {
  font-size: 0.9rem; color: hsl(var(--muted-foreground));
  padding-left: 1.4rem; position: relative;
}
.highlight-points li::before {
  content: "✓"; position: absolute; left: 0; color: hsl(var(--primary)); font-weight: 700;
}
.highlight-note { margin-top: 1.2rem; font-size: 0.75rem; color: hsl(var(--muted-foreground)); font-style: italic; }
/* Placeholder honnête : silhouette abstraite + orbite du téléphone */
.apparel-placeholder {
  position: relative; aspect-ratio: 4 / 5; max-width: 300px; width: 100%; margin-inline: auto;
  border-radius: calc(var(--radius) * 2); background: hsl(var(--secondary)); overflow: hidden;
}
.apparel-silhouette {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  width: 46%; height: 78%; background: hsl(var(--muted-foreground) / 0.28);
  clip-path: polygon(38% 0, 62% 0, 66% 8%, 82% 14%, 86% 46%, 74% 46%, 76% 100%, 24% 100%, 26% 46%, 14% 46%, 18% 14%, 34% 8%);
}
/* La pièce portée : une veste posée sur la silhouette, dans une teinte à part
   pour lire « c'est le vêtement qu'on scanne ». */
.apparel-garment {
  position: absolute; left: 50%; bottom: 0; transform: translateX(-50%);
  width: 46%; height: 78%; background: hsl(150 18% 42% / 0.55);
  clip-path: polygon(38% 2%, 62% 2%, 66% 9%, 82% 15%, 86% 44%, 74% 44%, 74% 52%, 26% 52%, 26% 44%, 14% 44%, 18% 15%, 34% 9%);
}
.apparel-orbit {
  position: absolute; left: 50%; top: 58%; width: 120%; height: 28%;
  transform: translate(-50%, -50%);
  border: 1.5px dashed hsl(var(--primary) / 0.6); border-radius: 50%;
}
.apparel-phone {
  position: absolute; width: 18px; height: 34px; border-radius: 5px;
  border: 1.5px solid hsl(var(--primary)); background: hsl(var(--background));
  left: 50%; top: 58%; margin: -17px 0 0 -9px;
  animation: apparel-orbit 8s linear infinite;
}
/* The phone rides the dashed ellipse (60% x / 14% of the placeholder's height
   ≈ the .apparel-orbit radii); translate() uses the element's own em-free px. */
@keyframes apparel-orbit {
  0%   { transform: translate(90px, 0) scale(0.9); }
  25%  { transform: translate(0, 40px) scale(1); }
  50%  { transform: translate(-90px, 0) scale(0.9); }
  75%  { transform: translate(0, -40px) scale(0.82); }
  100% { transform: translate(90px, 0) scale(0.9); }
}
@media (prefers-reduced-motion: reduce) {
  .apparel-phone { animation: none; transform: translate(90px, 0); }
}

/* ── Ad traffic: fit the hero form above the fold ────────────── */
/* Visitors arriving from a Meta ad land in the in-app WebView, where the
   Meta chrome leaves ~620px of usable height. The hero form sat at 542px
   with its submit button behind the fixed .mobile-cta bar — unreachable.
   Reclaiming the hero's top padding pulls the whole form above the fold. */
@media (max-width: 859.98px) {
  .hero { padding-top: 5.2rem; padding-bottom: 2.5rem; }
  /* Fail-open: the bar is visible by default, JS hides it when a lead form
     is on screen. The reverse would leave no CTA at all if landing.js fails
     to load in the WebView. */
  .mobile-cta.is-hidden { display: none; }
}

/* ── Thank-you page: the platform question ──────────────────── */
/* Asked here and not in the signup form: Pivot is Shopify-only, so the answer
   decides whether a lead is usable — but a second field in the hero form
   would push the submit button back under the fold on the in-app WebView. */
.ty-ask {
  margin-top: 1.5rem; padding-top: 1.5rem;
  border-top: 1px solid hsl(var(--border));
  max-width: 34rem; width: 100%;
}
.ty-ask-q { font-size: 0.95rem; color: hsl(var(--muted-foreground)); margin-bottom: 0.9rem; }
.ty-ask-opts { display: flex; flex-wrap: wrap; gap: 0.5rem; justify-content: center; }
.ty-ask-done:not(:empty) {
  margin-top: 0.9rem; font-size: 0.9rem; font-weight: 600; color: hsl(var(--primary));
}

/* ── Funnel diagram (where 3D sits) ───────────────────────────── */
.funnel { margin: 0; }
.fn-em { color: hsl(var(--primary)); font-weight: 600; }

.fn-sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
.fn-sprite symbol { fill: none; stroke-linecap: round; stroke-linejoin: round; }
.fn-icon {
  fill: none;
  stroke: hsl(var(--muted-foreground));
  stroke-width: 1.7;
  opacity: .75;
}
.fn-icon--lead { stroke: hsl(var(--primary)); opacity: 1; stroke-width: 1.9; }
.fs-icon {
  width: 17px;
  height: 17px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  vertical-align: -3px;
  margin-right: .4rem;
  opacity: .8;
}
.fs-step--lead .fs-icon { opacity: 1; }
.funnel-wide { display: block; }
.funnel-wide svg { display: block; width: 100%; height: auto; }
.funnel-stack { display: none; }

.fn-axis {
  stroke: hsl(var(--border));
  stroke-width: 2;
}
.fn-drop {
  stroke: hsl(var(--border));
  stroke-width: 1.5;
  stroke-dasharray: 3 5;
}
.fn-drop--lead {
  stroke: hsl(var(--primary));
  stroke-dasharray: none;
  stroke-width: 2;
}
.fn-node {
  fill: hsl(var(--background));
  stroke: hsl(var(--muted-foreground));
  stroke-width: 2.5;
}
.fn-node--lead {
  fill: hsl(var(--primary));
  stroke: hsl(var(--primary));
  filter: drop-shadow(0 0 14px var(--glow));
}
.fn-app {
  fill: hsl(var(--muted-foreground));
  font-size: 19px;
  font-weight: 500;
  text-anchor: middle;
}
.fn-stage--lead .fn-app {
  fill: hsl(var(--primary));
  font-weight: 700;
}
.fn-moment {
  fill: hsl(var(--foreground));
  font-size: 21px;
  font-weight: 600;
  text-anchor: middle;
}
.fn-moment--lead { fill: hsl(var(--primary)); }
.fn-what {
  fill: hsl(var(--muted-foreground));
  font-size: 15px;
  text-anchor: middle;
}
.fn-arrowhead { fill: hsl(var(--border)); }

.funnel figcaption {
  margin: 2rem auto 0;
  max-width: 62ch;
  text-align: center;
  color: hsl(var(--muted-foreground));
  font-size: 1rem;
  line-height: 1.7;
}

/* sous 760px le schéma horizontal devient illisible : on bascule en pile verticale.
   Le trafic de campagne est 100 % mobile, pas de scroll horizontal ici. */
@media (max-width: 760px) {
  .funnel-wide { display: none; }
  .funnel { margin-top: 3rem; }
  .funnel-stack {
    display: block;
    /* centré et resserré : le schéma ne doit pas manger la moitié de l'écran */
    margin: 0 auto;
    max-width: 19rem;
    padding: 0 0 0 1.6rem;
    list-style: none;
    position: relative;
  }
  .funnel-stack::before {
    content: "";
    position: absolute;
    left: 6px; top: .55rem; bottom: 1.7rem;
    width: 2px;
    background: hsl(var(--border));
  }
  .fs-step { position: relative; padding-bottom: 1.6rem; }
  .fs-step:last-child { padding-bottom: 0; }
  .fs-dot {
    position: absolute;
    left: -1.75rem; top: .45rem;
    width: 14px; height: 14px;
    border-radius: 50%;
    background: hsl(var(--background));
    border: 2.5px solid hsl(var(--muted-foreground));
    box-sizing: border-box;
  }
  .fs-step--lead .fs-dot {
    background: hsl(var(--primary));
    border-color: hsl(var(--primary));
    box-shadow: 0 0 14px var(--glow);
  }
  .fs-app {
    margin: 0;
    font-size: .95rem;
    font-weight: 500;
    color: hsl(var(--muted-foreground));
  }
  .fs-step--lead .fs-app { color: hsl(var(--primary)); font-weight: 700; }
  .fs-moment {
    margin: .05rem 0 .15rem;
    font-size: 1.15rem;
    font-weight: 600;
    color: hsl(var(--foreground));
  }
  .fs-step--lead .fs-moment { color: hsl(var(--primary)); }
  .fs-what {
    margin: 0;
    font-size: .9rem;
    line-height: 1.45;
    color: hsl(var(--muted-foreground));
  }
  .funnel figcaption { text-align: left; margin-top: 2.5rem; }
}

/* ============================================================
   Refonte mobile « 6 écrans » (design doc Pivot Mobile).
   Tout ce qui touche à la mise en page est borné à < 860px : le
   desktop garde la direction A3 « Sobre produit / Bento ».
   Tokens uniquement → clair et sombre tenus d'office.
   ============================================================ */

/* Pas de Geist Mono auto-hébergée : la pile système tient le rôle. */
:root { --mono: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; }

/* Portée : .is-mobile-only n'existe qu'en dessous du point de rupture,
   .is-desktop-only disparaît en dessous. !important car certaines cibles
   (.card .icon-tile) sont plus spécifiques que la classe utilitaire. */
.is-mobile-only { display: none; }

/* ── Burger (caché en desktop, la nav reste une rangée) ────── */
.nav-toggle { display: none; }

/* ── Comparatif : une scène + une légende, aux deux largeurs ── */
/* En desktop la scène est une grille de deux panneaux côte à côte et le
   curseur n'existe pas ; en mobile les panneaux se superposent (voir plus bas). */
.compare[data-compare] { display: block; grid-template-columns: none; }
.compare-stage { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; }
.compare-pane {
  margin: 0; overflow: hidden;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: hsl(var(--card));
}
.compare-pane--std { order: 1; }
.compare-pane--pivot { order: 2; border-color: hsl(var(--primary) / 0.85); }
.compare-pane video { width: 100%; aspect-ratio: 4 / 3; object-fit: cover; display: block; }
.compare-legend { display: grid; grid-template-columns: 1fr 1fr; gap: 1.4rem; margin-top: 0.9rem; }
.compare-legend p { font-size: 0.88rem; color: hsl(var(--muted-foreground)); }
.compare-legend strong { display: block; color: hsl(var(--foreground)); margin-bottom: 0.2rem; }
.compare-legend-win strong { color: hsl(var(--primary)); }
/* Ce que « viewer intégré » veut dire, pour qui n'a jamais publié de 3D. */
.compare-note {
  max-width: 44rem; margin: 1.1rem auto 0; text-align: center;
  font-size: 0.88rem; line-height: 1.5; color: hsl(var(--muted-foreground));
  text-wrap: pretty;
}

/* ── Étiquette « Founding » du bandeau tarifs (remplace l'emoji) ── */
.pricing-tag {
  flex: none; display: inline-block; vertical-align: 0.05em;
  background: hsl(var(--primary)); color: hsl(var(--primary-foreground));
  border-radius: 999px; padding: 0.2rem 0.6rem; margin-right: 0.45rem;
  font-family: var(--mono); font-size: 0.62rem; font-weight: 600;
  letter-spacing: 0.08em; text-transform: uppercase;
}

/* ── Barre CTA fixe : safe-area + escamotage quand un formulaire est à l'écran ── */
.mobile-cta {
  padding-bottom: calc(0.7rem + env(safe-area-inset-bottom, 0px));
  transition: transform 0.25s ease, opacity 0.25s ease;
}
.mobile-cta.is-hidden { transform: translateY(115%); opacity: 0; pointer-events: none; }
@media (prefers-reduced-motion: reduce) { .mobile-cta { transition: none; } }

/* ════════════════════ Écrans téléphone ════════════════════ */
@media (max-width: 859.98px) {
  .is-desktop-only { display: none !important; }

  /* ── 0 · Chrome : un seul libellé de CTA (la barre fixe), nav en burger ── */
  /* Le CTA du header fait doublon avec la barre fixe ; « Back to site » des
     pages légales, lui, est le seul chemin de retour : il doit rester. */
  .header-actions .btn-primary { display: none; }
  .nav-toggle { display: inline-flex; }
  .main-nav {
    position: absolute; inset-inline: 0; top: 100%;
    display: none; flex-direction: column; gap: 0; margin-inline: 0;
    background: hsl(var(--background));
    border-bottom: 1px solid hsl(var(--border));
    padding: 0 1.25rem 0.8rem;
  }
  .site-header.nav-open {
    background: hsl(var(--background) / 0.98);
    -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px);
    border-color: hsl(var(--border) / 0.7);
  }
  .site-header.nav-open .main-nav { display: flex; }
  .main-nav a {
    padding: 0.85rem 0; font-size: 1rem; color: hsl(var(--foreground));
    border-top: 1px solid hsl(var(--border) / 0.7);
  }

  .section { padding-block: 3.6rem; }
  .section-head { text-align: left; margin-inline: 0; }
  .section-head h2 { font-size: clamp(1.6rem, 6.6vw, 1.95rem); }
  .section-kicker {
    display: block; font-family: var(--mono); font-size: 0.68rem;
    letter-spacing: 0.1em; text-transform: uppercase;
    color: hsl(var(--muted-foreground)); margin-bottom: 0.55rem;
  }
  .site-footer { padding-bottom: calc(6.5rem + env(safe-area-inset-bottom, 0px)); }

  /* ── 1a · Hero : la 3D d'abord, puis le titre, puis l'e-mail ── */
  .hero { padding-top: 5.4rem; padding-bottom: 2.8rem; }
  .hero-grid { gap: 1.5rem; }
  .hero-visual { order: -1; }
  /* Le vrai viewer 3D, fond transparent, sur téléphone aussi. */
  .hero-visual .viewer-frame--bare { aspect-ratio: 39 / 34; max-height: none; }
  /* Le badge de provenance se révèle au survol en desktop ; sur un écran
     tactile il n'y a pas de survol, donc il reste posé, en verre dépoli. */
  .hero-visual .viewer-badge {
    opacity: 1; transform: none;
    left: auto; right: 0.75rem; bottom: 0.5rem;
    font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.02em;
    padding: 0.3rem 0.7rem;
    background: hsl(var(--background) / 0.55);
    -webkit-backdrop-filter: blur(10px) saturate(140%);
    backdrop-filter: blur(10px) saturate(140%);
    border-color: hsl(var(--border) / 0.45);
    transition: none;
  }
  /* `.viewer-frame:hover + .viewer-badge` est en (0,3,0) : sans ces deux
     lignes il regagne la cascade au premier contact du doigt et le badge
     saute d'un demi-tour de largeur. */
  .hero-visual .viewer-frame:hover + .viewer-badge,
  .hero-visual .viewer-frame:focus-within + .viewer-badge { transform: none; }
  .hero h1 { font-size: clamp(1.95rem, 8.4vw, 2.45rem); line-height: 1.06; }
  .hero-sub { margin-top: 0.85rem; font-size: 1rem; }
  .lead-form { margin-top: 1.4rem; max-width: none; }
  .lead-note {
    justify-content: center; gap: 0.3rem 0.55rem;
    font-family: var(--mono); font-size: 0.66rem;
    letter-spacing: 0.06em; text-transform: uppercase;
  }
  .lead-note span::before { content: none; margin-right: 0; }
  .lead-note span + span::before {
    content: "·"; margin-right: 0.5rem; color: hsl(var(--muted-foreground) / 0.6);
  }
  .lead-consent { font-size: 0.7rem; }


  /* ── 1c · Fonctionnement : les 3 étapes en story ── */
  .journey-tabs {
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 0.4rem; margin-top: 1.5rem;
  }
  .journey-tab {
    display: flex; flex-direction: column; gap: 0.5rem;
    padding: 0 0 0.2rem; border: 0; background: none; cursor: pointer;
    font-family: inherit; text-align: left; color: hsl(var(--muted-foreground));
  }
  .journey-tab-bar {
    height: 3px; border-radius: 2px; background: hsl(var(--border));
    transition: background 0.3s ease;
  }
  .journey-tab.is-done .journey-tab-bar { background: hsl(var(--foreground)); }
  .journey-tab-label { font-family: var(--mono); font-size: 0.68rem; }
  .journey-tab[aria-current] { color: hsl(var(--foreground)); }

  .journey { margin-top: 1.1rem; gap: 0; }
  .journey-panel {
    position: static; top: auto; display: none; min-height: 0;
    border: 0; background: transparent; padding: 0; gap: 1.1rem;
  }
  /* Le deck desktop réduit les panneaux couverts ; sur téléphone il n'y a
     qu'un panneau, et ce transform écrasait l'animation d'entrée. */
  html.js .journey-panel.is-covered { transform: none; filter: none; }
  .journey-panel.is-current { display: grid; animation: step-in 0.3s ease-out both; }
  .journey[data-dir="back"] .journey-panel.is-current { animation-name: step-in-back; }
  /* Les trois visuels faisaient 371 / 312 / 417 px : le panneau sautait de
     106 px d'une étape à l'autre. Une hauteur commune supprime le saut. */
  .journey-visual { height: 44svh; max-height: 380px; min-height: 280px; display: grid; place-items: center; }
  /* Chaque maquette remplit le cadre commun, sinon elle flotte au milieu
     d'une zone trop grande (le fauteuil de l'étape 2 devenait minuscule). */
  .journey-visual > * { height: 100%; max-height: 100%; }
  .phone-mock { height: 100%; width: auto; }
  /* `place-items: center` laisse l'enfant à sa largeur intrinsèque : les deux
     maquettes sans ratio doivent réclamer la largeur, le téléphone non. */
  .pdp-mock--journey, .settings-mock { width: 100%; }
  .pdp-mock--journey { max-width: 21rem; display: flex; flex-direction: column; }
  .pdp-mock--journey .pdp-body { flex: 1; min-height: 0; display: flex; flex-direction: column; }
  .pdp-mock--journey .pdp-media { flex: 1; min-height: 0; }
  .settings-mock { display: flex; flex-direction: column; overflow: hidden; }
  .settings-mock .settings-preview { flex: 1; min-height: 0; }
  /* Le panneau de réglages a plus de lignes que le cadre commun n'en tient :
     on garde les deux qui se voient bouger quand l'étape est active. */
  .settings-rows .settings-row:last-child { display: none; }
  .settings-caption { display: none; }
  /* Sans JS : pile complète, pas de commandes orphelines. */
  html:not(.js) .journey-panel { display: grid; }
  html:not(.js) .journey-panel + .journey-panel { margin-top: 2.2rem; }
  html:not(.js) .journey-tabs, html:not(.js) .journey-nav { display: none; }
  /* Idem pour les autres commandes : sans JS elles ne filtrent rien, et tout
     le contenu qu'elles pilotent reste affiché (voir plus bas). */
  html:not(.js) .journey-tabs, html:not(.js) .journey-nav,
  html:not(.js) .look-switch, html:not(.js) .plan-switch,
  html:not(.js) .nav-toggle { display: none; }
  .journey-panel .step-num { display: none; }
  .journey-visual { order: 1; }
  .journey-copy { order: 2; }
  .journey-copy h3 { font-size: 1.22rem; }
  .journey-copy p { font-size: 0.94rem; line-height: 1.55; }

  .journey-nav {
    display: flex; align-items: center; justify-content: space-between; margin-top: 1.5rem;
  }
  .journey-arrow {
    width: 44px; height: 44px; flex: none; border-radius: 999px;
    border: 1px solid hsl(var(--border)); background: transparent;
    color: hsl(var(--foreground)); cursor: pointer;
    display: inline-flex; align-items: center; justify-content: center;
  }
  .journey-arrow--next {
    background: hsl(var(--foreground)); color: hsl(var(--background));
    border-color: hsl(var(--foreground));
  }
  .journey-hint { font-family: var(--mono); font-size: 0.72rem; color: hsl(var(--muted-foreground)); }

  /* ── 1d · Showcase : l'onglet de rendu filtre les exemples ── */
  .look-switch {
    display: grid; grid-template-columns: 1fr 1fr; gap: 4px; margin-top: 1.4rem;
    background: hsl(var(--secondary)); border-radius: 999px; padding: 4px;
  }
  .look-tab {
    height: 40px; border: 0; border-radius: 999px; background: transparent;
    font-family: inherit; font-size: 0.88rem; font-weight: 500; cursor: pointer;
    color: hsl(var(--muted-foreground)); transition: background 0.25s ease, color 0.25s ease;
  }
  .look-tab[aria-pressed="true"] {
    background: hsl(var(--card)); color: hsl(var(--foreground)); font-weight: 600;
    box-shadow: 0 1px 2px hsl(var(--foreground) / 0.1);
  }
  .look-group { margin-top: 0; }
  .look-group + .look-group { margin-top: 0; }
  .look-desc { margin-top: 0.9rem; min-height: 4.4rem; font-size: 0.95rem; }
  html.js .look-group[data-look]:not(.is-current) { display: none; }

  .gallery {
    display: flex; gap: 0.75rem; margin-top: 1.2rem;
    overflow-x: auto; scroll-snap-type: x mandatory;
    scrollbar-width: none; -ms-overflow-style: none;
    margin-inline: -1.25rem; padding-inline: 1.25rem;
    /* Sans ça le snap aligne la première carte sur le bord du conteneur et
       défile de la valeur du padding : la carte finit collée à l'écran. */
    scroll-padding-inline: 1.25rem;
  }
  .gallery::-webkit-scrollbar { display: none; }
  .gallery-card { flex: 0 0 min(78%, 280px); scroll-snap-align: start; aspect-ratio: 7 / 9; }
  .chips { justify-content: flex-start; margin-top: 1.6rem; }
  .chip { font-size: 0.78rem; padding: 0.3rem 0.8rem; }

  /* ── 1b · Comparaison : les deux viewers superposés + curseur ── */
  .compare { margin-top: 1.2rem; }
  .compare-stage {
    display: block; position: relative; aspect-ratio: 35 / 44;
    border-radius: calc(var(--radius) * 2); overflow: hidden; background: hsl(var(--muted));
  }
  .compare-pane {
    position: absolute; inset: 0; border: 0; border-radius: 0;
    background: none; overflow: hidden;
  }
  .compare-pane video {
    width: 100%; height: 100%; aspect-ratio: auto; object-fit: cover;
    /* Le masque radial du desktop laisserait voir à travers le recouvrement. */
    -webkit-mask-image: none; mask-image: none;
  }
  /* Pivot sert de fond, le viewer standard est révélé depuis la gauche. */
  .compare-pane--std { clip-path: inset(0 calc(100% - var(--compare-pos, 50%)) 0 0); }
  .compare-ui { display: block; position: absolute; inset: 0; pointer-events: none; }
  .compare-line {
    position: absolute; top: 0; bottom: 0; left: var(--compare-pos, 50%);
    width: 2px; margin-left: -1px; background: #fff;
    /* Les deux rendus ont un fond quasi blanc : la ligne a besoin d'un liseré. */
    box-shadow: 0 0 0 1px rgb(0 0 0 / 0.14);
  }
  .compare-knob {
    position: absolute; top: 50%; left: var(--compare-pos, 50%);
    width: 44px; height: 44px; margin: -22px 0 0 -22px; border-radius: 50%;
    background: #fff; color: #111; box-shadow: 0 4px 14px rgb(0 0 0 / 0.18);
    display: flex; align-items: center; justify-content: center;
  }
  .compare-tag {
    position: absolute; top: 0.7rem; border-radius: 999px; padding: 0.3rem 0.7rem;
    font-family: var(--mono); font-size: 0.64rem;
    letter-spacing: 0.06em; text-transform: uppercase;
  }
  .compare-tag--std { left: 0.7rem; background: #fff; color: #111; }
  .compare-tag--pivot { right: 0.7rem; background: hsl(var(--primary)); color: #fff; }
  .compare-range {
    display: block;
    position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; border: 0;
    -webkit-appearance: none; appearance: none; background: transparent; cursor: ew-resize;
  }
  .compare-range::-webkit-slider-thumb {
    -webkit-appearance: none; width: 48px; height: 48px; border-radius: 50%;
    background: transparent; cursor: ew-resize;
  }
  .compare-range::-moz-range-thumb {
    width: 48px; height: 48px; border: 0; border-radius: 50%; background: transparent;
  }
  .compare-range::-moz-range-track { background: transparent; }
  /* Sans JS le curseur ne bouge rien : on garde les deux vues empilées. */
  html:not(.js) .compare-stage { display: grid; grid-template-columns: 1fr; aspect-ratio: auto; }
  html:not(.js) .compare-pane { position: static; }
  html:not(.js) .compare-ui, html:not(.js) .compare-range { display: none; }
  .compare-legend { gap: 0.8rem; margin-top: 0.9rem; }
  .compare-legend p { font-size: 0.82rem; line-height: 1.4; }
  .compare-note { margin-top: 0.9rem; text-align: left; font-size: 0.84rem; }

  /* ── 1e · Tarifs : 4 onglets, une carte, Pro par défaut ── */
  .pricing-banner {
    margin-top: 1.3rem; max-width: none; text-align: left;
    display: flex; align-items: center; gap: 0.1rem;
    border-style: solid; font-size: 0.86rem; font-weight: 400; line-height: 1.35;
  }
  .plan-switch { display: flex; gap: 0.3rem; margin-top: 1rem; }
  .plan-tab {
    flex: 1; min-width: 0; height: 36px; border-radius: 999px;
    border: 1px solid hsl(var(--border)); background: transparent;
    color: hsl(var(--muted-foreground)); font-family: inherit;
    font-size: 0.78rem; font-weight: 500; cursor: pointer;
    transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
  }
  .plan-tab[aria-pressed="true"] {
    background: hsl(var(--foreground)); color: hsl(var(--background));
    border-color: hsl(var(--foreground));
  }
  .plans { margin-top: 1rem; }
  html.js .plans .plan:not(.is-current) { display: none; }
  .plan.featured { box-shadow: none; }
  .plan-tag {
    position: static; transform: none; align-self: flex-start;
    margin-bottom: 0.7rem;
  }
  .pricing-note { text-align: left; margin-top: 1.2rem; font-size: 0.74rem; }

  /* ── 1f · FAQ en accordéon, lignes de 52 px ── */
  .faq { margin-top: 1.4rem; }
  .faq details {
    border: 0; border-top: 1px solid hsl(var(--border));
    border-radius: 0; margin-bottom: 0; padding-inline: 0;
  }
  .faq details:last-of-type { border-bottom: 1px solid hsl(var(--border)); }
  .faq summary { min-height: 52px; padding: 0.85rem 0; font-size: 0.95rem; line-height: 1.3; }
  .faq details p { padding: 0 0 0.9rem; font-size: 0.9rem; }
  .faq-contact { text-align: left; margin-top: 1.6rem; font-size: 0.9rem; }
}

/* Mouvement réduit : l'avance automatique des étapes est déjà coupée côté JS ;
   ici on neutralise les transitions des onglets et du curseur. */
@media (prefers-reduced-motion: reduce) {
  .journey-tab-bar, .look-tab, .plan-tab { transition: none; }
}


@media (max-width: 859.98px) {
  /* Boutons : pilule noire (l'accent vert reste pour les étiquettes et les ✓). */
  .btn { border-radius: 999px; padding: 0.95rem 1.4rem; font-size: 1rem; font-weight: 600; }
  .btn-sm { padding: 0.45rem 0.95rem; font-size: 0.88rem; }
  .btn-primary { background: hsl(var(--foreground)); color: hsl(var(--background)); }
  .btn-primary:hover { background: hsl(var(--foreground) / 0.85); }
  .lead-form input[type="email"] { border-radius: 999px; padding: 0.95rem 1.25rem; }

}


/* ============================================================
   Écrans 1g / 1h / 1i du design mobile : « Why Pivot » chiffré,
   fonctionnalités en liste, formulaire final en bloc inversé.
   ============================================================ */

/* ── 1g · Le coût comme argument ────────────────────────────── */
.cost-compare {
  display: grid; grid-template-columns: 1fr 1fr; margin-top: 2rem;
  border: 1px solid hsl(var(--border)); border-radius: calc(var(--radius) * 2);
  background: hsl(var(--card)); overflow: hidden; max-width: 36rem; margin-inline: auto;
}
.cost-cell { display: flex; flex-direction: column; gap: 0.35rem; padding: 1.2rem 1.1rem; }
.cost-cell + .cost-cell { border-left: 1px solid hsl(var(--border)); }
.cost-label {
  font-family: var(--mono); font-size: 0.64rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: hsl(var(--muted-foreground));
}
.cost-cell--win .cost-label { color: hsl(var(--primary)); }
.cost-price { font-size: 1.65rem; line-height: 1.1; font-weight: 600; letter-spacing: -0.03em; }
.cost-price--old { color: hsl(var(--muted-foreground)); }
.cost-note { font-size: 0.82rem; line-height: 1.35; color: hsl(var(--muted-foreground)); }

/* La phrase qui situe la 3D dans le tunnel : avant la décision, pas après. */
.why-funnel {
  max-width: 36rem; margin: 2rem auto 0; padding-top: 1.1rem;
  border-top: 1px solid hsl(var(--border));
  font-size: 0.95rem; line-height: 1.45; text-wrap: pretty;
}
.why-funnel strong { color: hsl(var(--primary)); }

/* ── 1h · La coche des fonctionnalités (liste mobile seulement) ── */
.feat-tick { display: none; color: hsl(var(--primary)); }

/* ── 1i · Bloc final inversé (le seul bloc coloré de la page) ── */
/* Volontairement sombre dans les deux thèmes : c'est un bloc « inversé »,
   pas une surface qui suit le thème. */
.cta-card { display: contents; }

@media (max-width: 859.98px) {
  /* Ordre des 9 écrans du design. Le DOM suit déjà l'ordre desktop ; seuls
     « fonctionnalités » et « funnel » remontent avant le showcase ici. */
  main { display: flex; flex-direction: column; }
  main > .hero { order: 1; }
  main > #compare { order: 2; }
  main > #why { order: 3; }
  main > #how-it-works { order: 4; }
  main > #features { order: 5; }
  main > #funnel { order: 6; }
  main > #showcase { order: 7; }
  main > #pricing { order: 8; }
  main > #faq { order: 9; }
  main > .final-cta { order: 10; }

  /* 1g — tableau de coût plein cadre, puis 3 lignes au lieu de 3 cartes */
  .cost-compare { margin-top: 1.3rem; }
  /* Les deux notes n'ont pas le même nombre de lignes : on les colle en bas
     pour que les cellules se lisent comme deux colonnes, pas deux blocs. */
  .cost-cell { padding: 1rem 0.9rem; }
  .cost-note { margin-top: auto; padding-top: 0.5rem; font-size: 0.76rem; line-height: 1.35; }
  .cost-price { font-size: 1.55rem; }
  .cost-label { font-size: 0.6rem; }
  #why .cards-3 { margin-top: 1.5rem; gap: 1.15rem; }
  #why .cards-3 .card {
    display: grid; grid-template-columns: 2.5rem 1fr; column-gap: 0.85rem;
    border: 0; background: none; padding: 0; align-items: start;
  }
  #why .cards-3 .card:hover { border: 0; }
  #why .card .icon-tile {
    grid-row: span 2; margin: 0; width: 2.5rem; height: 2.5rem;
    border: 0; border-radius: 0.75rem;
    background: hsl(var(--primary) / 0.12); color: hsl(var(--primary));
  }
  #why .card h3 { font-size: 0.95rem; margin-bottom: 0.15rem; }
  #why .card p { font-size: 0.82rem; line-height: 1.4; }
  .why-funnel { margin-top: 1.5rem; font-size: 0.9rem; }

  /* 1h — les 6 cartes deviennent 6 lignes avec une coche verte */
  .feat-tick { display: block; }
  #features .cards-3 { margin-top: 1.2rem; gap: 0; }
  #features .cards-3 .card {
    display: grid; grid-template-columns: 1.4rem 1fr; column-gap: 0.75rem;
    align-items: start; border: 0; border-top: 1px solid hsl(var(--border));
    border-radius: 0; background: none; padding: 0.95rem 0;
  }
  #features .cards-3 .card:hover { border-color: hsl(var(--border)); }
  #features .feat-tick { grid-row: span 2; margin-top: 0.1rem; }
  #features .card h3 { font-size: 0.95rem; margin-bottom: 0.15rem; }
  #features .card p { font-size: 0.82rem; line-height: 1.4; }

  /* 1i — bloc final sombre, CTA vert, le seul élément coloré de l'écran */
  .final-cta { padding-block: 2rem 3.6rem; }
  .final-cta .container { padding-inline: 1rem; }
  .cta-card {
    display: block; background: #121212; color: #fff;
    border-radius: calc(var(--radius) * 2.4); padding: 1.75rem 1.25rem 1.5rem;
  }
  html[data-theme="dark"] .cta-card { background: #171716; border: 1px solid hsl(var(--border)); }
  .cta-card .section-head { text-align: left; }
  .cta-card .section-head h2 { color: #fff; font-size: clamp(1.6rem, 6.6vw, 1.9rem); }
  .cta-card .section-head p { color: #b5b5ae; font-size: 0.95rem; margin-top: 0.7rem; }
  /* Plus spécifique que .cta-card .section-head p, qui grise tout le bloc. */
  .cta-card .section-head .cta-kicker { color: hsl(var(--primary)); }
  .cta-card .lead-form { margin-top: 1.2rem; align-items: stretch; }
  .cta-card .lead-row { width: auto; }
  .cta-card .lead-form input[type="email"] {
    background: #1b1b1a; border-color: #3a3a37; color: #fff;
  }
  .cta-card .lead-form input[type="email"]::placeholder { color: #8a8a84; }
  .cta-card .btn-primary { background: hsl(var(--primary)); color: #fff; }
  .cta-card .btn-primary:hover { background: hsl(var(--primary) / 0.85); }
  .cta-card .lead-note { color: #8a8a84; }
  .cta-card .lead-note span + span::before { color: #55554f; }
  .cta-card .lead-consent { color: #8a8a84; text-align: center; }
  .cta-card .lead-consent a { color: #b5b5ae; }
  .cta-card .lead-msg.ok { color: hsl(142 70% 60%); }

  /* Footer compacté : marque, 2 colonnes, mentions légales en ligne */
  .site-footer { padding-block: 2.4rem; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 1.4rem; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-brand p { font-size: 0.85rem; }
  /* Produit et contact côte à côte (ordre du design) : les mentions légales
     passent après, en ligne, sur toute la largeur. */
  .site-footer nav[aria-label="Legal"], .site-footer nav[aria-label="Mentions légales"] {
    grid-column: 1 / -1; order: 1;
  }
  .site-footer a { font-size: 0.86rem; overflow-wrap: anywhere; }
  .site-footer nav[aria-label="Legal"] ul,
  .site-footer nav[aria-label="Mentions légales"] ul { display: flex; gap: 1.1rem; }
  .footer-bottom { margin-top: 1.8rem; font-size: 0.72rem; gap: 0.3rem 1rem; }
  .footer-bottom span:nth-child(2) { display: none; }
}

/* Entrée d'une étape du parcours (téléphone). Le sens suit la navigation :
   la classe data-dir est posée par landing.js. */
@keyframes step-in { from { opacity: 0; transform: translateX(14px); } }
@keyframes step-in-back { from { opacity: 0; transform: translateX(-14px); } }
@media (prefers-reduced-motion: reduce) {
  .journey-panel.is-current { animation: none; }
}

/* Téléphones courts (iPhone SE et compagnie) : la maquette de réglages ne tient
   pas dans le cadre commun, l'aperçu se réduisait à ~100 px et le fauteuil y
   était illisible. On retire une ligne de plus et on resserre les marges pour
   lui rendre de la hauteur. */
@media (max-width: 859.98px) and (max-height: 740px) {
  .settings-mock { padding: 0.7rem; }
  .settings-title { font-size: 0.76rem; margin-bottom: 0.4rem; }
  .settings-rows .settings-row:first-child { display: none; }
  .preset-row { margin-bottom: 0.45rem; }
  .preset-pill { font-size: 0.68rem; }
  .settings-row { padding: 0.3rem 0.15rem; font-size: 0.78rem; }
}
