/* ==========================================================================
   synaxess.ca — feuille de style unique
   Palette, typographie et composants : docs/DIRECTION.md
   ========================================================================== */

:root {
  /* Couleur — une seule teinte d'accent, en trois valeurs */
  --fond: #070B14;
  --surface: #0E1626;
  --surface-elevee: #152134;
  --bordure: #1E2D45;
  --texte: #E8EDF5;
  --texte-second: #96A7C0;   /* 8,05:1 sur --fond · 7,39:1 sur --surface */
  --accent: #1FA5DC;
  --accent-profond: #218FCB;
  --accent-clair: #4FC3F0;

  --titre: 'Bricolage Grotesque', 'Segoe UI', system-ui, sans-serif;
  --corps: 'Instrument Sans', 'Segoe UI', system-ui, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, 'Cascadia Mono', monospace;

  --largeur: 1200px;
  --gouttiere: clamp(20px, 5vw, 48px);
  --section: 96px;          /* mobile */
  --rayon: 4px;             /* angles a 4 px, jamais arrondis */
}

@media (min-width: 900px) {
  :root { --section: 160px; }
}

/* --- Bases ------------------------------------------------------------- */

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

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

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

body {
  margin: 0;
  background: var(--fond);
  color: var(--texte);
  font: 400 17px/1.6 var(--corps);
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3, h4 {
  font-family: var(--titre);
  font-weight: 800;
  letter-spacing: -0.03em;
  line-height: 1.06;
  margin: 0;
  text-wrap: balance;
}

h1 { font-size: clamp(2.35rem, 6.2vw, 4.3rem); }
h2 { font-size: clamp(1.85rem, 3.8vw, 2.85rem); }
h3 { font-size: 1.22rem; font-weight: 700; letter-spacing: -0.02em; line-height: 1.25; }

p { margin: 0 0 1.1em; max-width: 68ch; }
p:last-child { margin-bottom: 0; }

a { color: var(--accent-clair); text-decoration-thickness: 1px; text-underline-offset: 3px; }
a:hover { color: var(--texte); }

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

strong { font-weight: 500; color: var(--texte); }

::selection { background: var(--accent-profond); color: #fff; }

:focus-visible {
  outline: 2px solid var(--accent-clair);
  outline-offset: 3px;
  border-radius: 2px;
}

/* Lien d'evitement, pour la navigation au clavier */
.evitement {
  position: absolute; left: -9999px; top: 0; z-index: 100;
  background: var(--accent); color: #04121B; padding: 12px 18px;
  font: 500 0.85rem/1 var(--mono); text-decoration: none;
}
.evitement:focus { left: 12px; top: 12px; }

/* --- Contenants -------------------------------------------------------- */

.contenant {
  width: 100%;
  max-width: var(--largeur);
  margin-inline: auto;
  padding-inline: var(--gouttiere);
}

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

/* Grille de 12 colonnes, exploitee en asymetrie */
.grille {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: clamp(24px, 3vw, 40px);
}
.col-7 { grid-column: 1 / -1; }
.col-8 { grid-column: 1 / -1; }
.decale { grid-column: 1 / -1; }

@media (min-width: 900px) {
  .col-7 { grid-column: 1 / span 7; }
  .col-8 { grid-column: 1 / span 8; }
  .decale { grid-column: 4 / span 9; }   /* contenu decale, jamais centre */
}

.trait { border: 0; border-top: 1px solid var(--bordure); margin: 0; }

/* L'en-tete est collant : sans cette marge, une cible d'ancre atterrit
   dessous et le visiteur croit que le lien n'a rien fait. */
[id] { scroll-margin-top: 96px; }

/* --- Etiquette de section ---------------------------------------------- */
/* Le composant le plus distinctif du site. En mono, il dit « on construit
   des choses » avant meme qu'on ait lu la phrase. */

.etiquette {
  display: block;
  font: 500 0.72rem/1 var(--mono);
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 22px;
}
.etiquette b { font-weight: 500; color: var(--accent-clair); }

/* --- En-tete ----------------------------------------------------------- */

.entete {
  position: sticky; top: 0; z-index: 40;
  background: var(--fond);
  border-bottom: 1px solid var(--bordure);
}

.entete__interieur {
  display: flex; align-items: center; justify-content: space-between;
  gap: 24px; min-height: 68px;
}

.verrou {
  display: inline-flex; align-items: center; gap: 0.55em;
  text-decoration: none; color: var(--texte);
}
.verrou img { height: 26px; width: auto; }
.verrou span {
  font-family: var(--titre); font-weight: 800; font-size: 1.28rem;
  letter-spacing: -0.015em; text-transform: uppercase; line-height: 1;
}
.verrou b { font-weight: 800; color: var(--accent-clair); }

.navigation { display: flex; align-items: center; gap: clamp(14px, 2.2vw, 30px); }

/* `:not(.bouton)` n'est pas une precaution theorique. Sans lui, cette regle
   — specificite 0,1,1 — ecrase la couleur de texte du bouton principal, qui
   n'est qu'a 0,1,0. Le bouton de l'en-tete affichait alors du gris-bleu clair
   sur fond accent : 1,15 : 1, mesure. C'est l'element le plus clique du site,
   et c'etait le moins lisible. */
.navigation a:not(.bouton) {
  color: var(--texte-second); text-decoration: none;
  font-size: 0.95rem;
}
.navigation a:not(.bouton):hover,
.navigation a:not(.bouton)[aria-current="page"] { color: var(--texte); }
.navigation a:not(.bouton)[aria-current="page"] { font-weight: 500; }

/* Sélecteur de langue : manuel et discret. Aucune détection automatique —
   un visiteur francophone qui atterrit en anglais parce que son système est
   en anglais serait un mauvais départ au Québec. */
.langues {
  display: inline-flex; align-items: center; gap: 7px; margin: 0;
  font: 500 0.74rem/1 var(--mono); letter-spacing: 0.1em;
}
.langues span, .langues a { color: var(--texte-second); text-decoration: none; }
.langues a:hover { color: var(--texte); }
.langues [aria-current] { color: var(--accent-clair); }
.langues .sep { color: var(--bordure); }

/* La navigation passe en liste compacte sous 720 px : pas de menu deroulant
   a construire, donc rien qui puisse casser sans JavaScript. */
@media (max-width: 719px) {
  .entete__interieur { flex-direction: column; align-items: flex-start; gap: 10px; padding-block: 12px; }
  .navigation { flex-wrap: wrap; gap: 16px; }
  .navigation .bouton { display: none; }
}

/* --- Boutons ----------------------------------------------------------- */

.bouton {
  display: inline-flex; align-items: center; gap: 10px;
  padding: 13px 22px;
  border-radius: var(--rayon);
  font: 500 0.95rem/1 var(--corps);
  text-decoration: none;
  border: 1px solid transparent;
  cursor: pointer;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}
/* Texte du bouton : `--fond`, pas une valeur inventee. #04121B donnait
   6,75 : 1; #070B14 donne 7,00 et vient de la palette.
   Contre-intuitif mais mesure : assombrir le FOND ferait baisser le rapport,
   pas monter. Accent profond #218FCB avec ce meme texte tomberait a 5,49. */
.bouton--principal { background: var(--accent); color: var(--fond); font-weight: 500; }
.bouton--principal:hover { background: var(--accent-clair); color: var(--fond); }
.bouton--contour { border-color: var(--bordure); color: var(--texte); }
.bouton--contour:hover { border-color: var(--accent); color: var(--texte); }
.bouton .fleche { transition: transform .18s ease; }
.bouton:hover .fleche { transform: translateX(3px); }

@media (prefers-reduced-motion: reduce) {
  .bouton, .bouton .fleche { transition: none; }
}

/* --- Heros ------------------------------------------------------------- */

.heros {
  position: relative;
  min-height: min(100svh, 860px);
  display: flex; align-items: center;
  padding-block: clamp(72px, 12vh, 130px);
  border-bottom: 1px solid var(--bordure);
  overflow: hidden;
}

/* Le canvas est un fond. Il ne porte aucune information, il est
   aria-hidden, et le texte ne l'attend jamais. */
.reseau {
  position: absolute; inset: 0;
  width: 100%; height: 100%;
  z-index: 0;
  /* Fondu d'une seule teinte vers la transparence, pour fondre le canvas
     dans le fond. Aucun degrade de deux couleurs sur ce site. */
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 52%, transparent 96%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 52%, transparent 96%);
}

/* Halo statique en CSS : le heros a un fond meme sans JavaScript. */
.heros::before {
  content: ''; position: absolute; z-index: 0;
  inset: -20% -10% auto auto; width: 70vw; height: 70vw; max-width: 780px; max-height: 780px;
  background: radial-gradient(circle, rgba(31,165,220,.13) 0%, rgba(31,165,220,0) 68%);
  pointer-events: none;
}

/* Voile d'une seule teinte vers la transparence : le reseau reste dense a
   droite, ou il se voit, et s'efface derriere le titre, ou il generait la
   lecture. Aucun trait ne doit passer dans une lettre. */
.heros::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  /* Sur mobile le texte occupe toute la largeur : un voile lateral effacerait
     le reseau au complet. On le remplace par un voile vertical plus doux, qui
     laisse respirer le haut du champ et retient seulement ce qui passe
     derriere le titre. */
  background: linear-gradient(to bottom,
    rgba(7, 11, 20, .22) 0%, rgba(7, 11, 20, .58) 30%, rgba(7, 11, 20, .68) 100%);
}

@media (min-width: 900px) {
  .heros::after {
    background: linear-gradient(100deg,
      #070B14 0%, rgba(7, 11, 20, .92) 22%, rgba(7, 11, 20, .55) 44%, rgba(7, 11, 20, 0) 66%);
  }
}

.heros__contenu { position: relative; z-index: 2; }

.heros h1 { margin-bottom: 26px; }
.heros__sous {
  font-size: clamp(1.06rem, 1.7vw, 1.22rem);
  color: var(--texte-second);
  max-width: 56ch;
  margin-bottom: 34px;
}
.heros__actions { display: flex; flex-wrap: wrap; gap: 14px; align-items: center; }
.heros__note {
  font: 500 0.78rem/1.5 var(--mono);
  letter-spacing: 0.06em; color: var(--texte-second);
}

/* --- Le probleme ------------------------------------------------------- */

.accroche {
  font-family: var(--titre); font-weight: 700;
  font-size: clamp(1.5rem, 3vw, 2.1rem);
  letter-spacing: -0.025em; line-height: 1.2;
  margin: 0 0 44px; max-width: 22ch;
}

/* --- Points d'accroche -------------------------------------------------- */
/* La retenue est une règle de ton, pas une règle de rythme. Une page de
   3 000 mots sans aucun moment fort se lit comme un document plutôt que
   comme un argumentaire : l'œil n'a nulle part où se poser et le lecteur
   décroche avant l'argument qui l'aurait convaincu.
   Le relief vient de la composition — jamais du vocabulaire. Ces phrases
   sont extraites du texte courant, pas ajoutées par-dessus. */

.point-accroche { padding-block: clamp(38px, 5vw, 68px); }

.accroche-isolee {
  font-family: var(--titre); font-weight: 700;
  font-size: clamp(1.42rem, 2.9vw, 2.05rem);
  letter-spacing: -0.025em; line-height: 1.22;
  color: var(--texte);
  max-width: 21ch;
  margin: 0;
  padding-left: clamp(18px, 2.2vw, 30px);
  border-left: 2px solid var(--accent);
  text-wrap: balance;
}

/* Changement de fond : une section entière posée sur la surface, bornée par
   deux traits. Ne jamais l'appliquer à une section qui contient des cartes —
   elles sont déjà sur --surface et disparaîtraient. */
.section--surface {
  background: var(--surface);
  border-top: 1px solid var(--bordure);
  border-bottom: 1px solid var(--bordure);
}

/* --- Bandeau de réseau sur les pages intérieures ------------------------ */
/* L'accueil porte le réseau plein écran; les pages intérieures en portent une
   bande courte et réduite derrière leur titre. Sans elle, elles paraissent
   appartenir à un autre site que l'accueil. Avec, la continuité est établie
   sans que le geste fort du héros soit dilué. */

.entete-page { position: relative; overflow: hidden; }

.reseau--bande {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  -webkit-mask-image: linear-gradient(to bottom, #000 0%, #000 34%, transparent 88%);
          mask-image: linear-gradient(to bottom, #000 0%, #000 34%, transparent 88%);
}

.entete-page::after {
  content: ''; position: absolute; inset: 0; z-index: 1; pointer-events: none;
  background: linear-gradient(to bottom,
    rgba(7, 11, 20, .34) 0%, rgba(7, 11, 20, .66) 46%, rgba(7, 11, 20, .86) 100%);
}
@media (min-width: 900px) {
  .entete-page::after {
    background: linear-gradient(100deg,
      #070B14 0%, rgba(7, 11, 20, .94) 26%, rgba(7, 11, 20, .6) 48%, rgba(7, 11, 20, .1) 74%);
  }
}
.entete-page > .contenant { position: relative; z-index: 2; }

.situations { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.situations li {
  border-top: 1px solid var(--bordure);
  padding: 26px 0 26px 0;
  display: grid; gap: 6px 26px;
  align-items: baseline;
}
.situations li:last-child { border-bottom: 1px solid var(--bordure); }
.situations .num {
  font: 500 0.72rem/1 var(--mono); letter-spacing: 0.15em; color: var(--accent);
}
.situations p { margin: 0; font-size: clamp(1.02rem, 1.5vw, 1.13rem); }

@media (min-width: 760px) {
  .situations li { grid-template-columns: 60px 1fr; }
}

/* --- Cartes ------------------------------------------------------------ */

.cartes {
  display: grid; gap: clamp(16px, 2vw, 24px);
  grid-template-columns: 1fr;
}
@media (min-width: 760px) { .cartes { grid-template-columns: repeat(2, 1fr); } }

.carte {
  position: relative;
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  padding: clamp(24px, 3vw, 34px);
  box-shadow: none;                    /* aucune ombre */
  transition: border-color .2s ease;
}
/* Au survol : la bordure passe a l'accent et un trait se dessine en haut.
   Pas de soulevement, pas d'agrandissement. */
.carte::before {
  content: ''; position: absolute; left: -1px; top: -1px; height: 2px; width: 0;
  background: var(--accent);
  transition: width .28s ease;
}
.carte:hover, .carte:focus-within { border-color: var(--accent-profond); }
.carte:hover::before, .carte:focus-within::before { width: calc(100% + 2px); }

@media (prefers-reduced-motion: reduce) {
  .carte, .carte::before { transition: none; }
}

.carte h3 { margin-bottom: 12px; }
.carte p { color: var(--texte-second); font-size: 0.98rem; margin-bottom: 0; }
.carte .exemple {
  margin-top: 16px; padding-top: 16px; border-top: 1px solid var(--bordure);
  font: 500 0.78rem/1.55 var(--mono); color: var(--texte-second);
  letter-spacing: 0.01em;
}

/* --- Les domaines, en hiérarchie --------------------------------------- */
/* Les quatre domaines n'ont pas la même importance : les systèmes sur mesure
   sont le cœur de l'offre, les sites vitrines en sont la porte d'entrée. Une
   grille de quatre cases identiques affirmerait qu'ils se valent — la mise en
   page mentirait, et affaiblirait le positionnement en même temps. */

.domaines {
  display: grid; gap: clamp(16px, 2vw, 24px);
  grid-template-columns: 1fr;
}
@media (min-width: 820px) {
  .domaines { grid-template-columns: repeat(2, 1fr); }
  .domaine--tete { grid-column: 1 / -1; }
}

.domaine--tete { padding: clamp(26px, 3.6vw, 44px); }
.domaine--tete .etiquette { margin-bottom: 16px; }
.domaine--tete h3 {
  font-size: clamp(1.38rem, 2.4vw, 1.85rem);
  font-weight: 800; margin-bottom: 16px;
}
.domaine--tete > p { font-size: 1.04rem; max-width: 58ch; }
.domaine--tete .exemple { font-size: 0.82rem; max-width: 58ch; }

/* La porte d'entrée : une ligne et un prix, pas un quatrième pilier. */
.porte {
  margin-top: clamp(30px, 3.6vw, 46px);
  padding-top: clamp(24px, 3vw, 34px);
  border-top: 1px solid var(--bordure);
  display: grid; gap: 22px; align-items: start;
}
@media (min-width: 820px) {
  .porte { grid-template-columns: 1fr auto; gap: 56px; align-items: center; }
  .porte__prix { text-align: right; }
}
.porte h3 { font-size: 1.12rem; margin-bottom: 10px; }
.porte p { color: var(--texte-second); font-size: 0.97rem; max-width: 62ch; }
.porte .porte__montant {
  font-family: var(--titre); font-weight: 800; font-size: 1.55rem;
  letter-spacing: -0.02em; color: var(--texte);
  margin: 0 0 8px; white-space: nowrap;
}
.porte__prix a {
  font: 500 0.8rem/1 var(--mono); letter-spacing: 0.08em;
  color: var(--accent-clair); text-decoration: none; white-space: nowrap;
}
.porte__prix a:hover { color: var(--texte); }

/* --- Demarche ---------------------------------------------------------- */

.etapes { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.etape {
  border-top: 1px solid var(--bordure);
  padding: clamp(26px, 3vw, 38px) 0;
  display: grid; gap: 10px 34px;
}
.etape:last-child { border-bottom: 1px solid var(--bordure); }
.etape__n {
  font: 500 0.72rem/1 var(--mono); letter-spacing: 0.15em;
  color: var(--accent); padding-top: 5px;
}
.etape h3 { margin-bottom: 8px; }
.etape p { color: var(--texte-second); margin-bottom: 0; }

@media (min-width: 760px) {
  .etape { grid-template-columns: 130px 1fr; }
}

/* --- Bloc de donnees --------------------------------------------------- */
/* Employe une ou deux fois au maximum, la ou il prouve quelque chose. */

.bloc-donnees {
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  padding: clamp(20px, 2.4vw, 28px);
  font: 500 0.82rem/1.85 var(--mono);
  color: var(--texte-second);
  overflow-x: auto;
}
.bloc-donnees .fl { color: var(--accent); }
.bloc-donnees .ok { color: var(--texte); }
.bloc-donnees b { font-weight: 500; color: var(--texte); }

/* --- Differenciateurs -------------------------------------------------- */

.raisons { display: grid; gap: clamp(28px, 3.4vw, 48px); grid-template-columns: 1fr; }
@media (min-width: 900px) { .raisons { grid-template-columns: repeat(3, 1fr); } }
.raison h3 { margin-bottom: 10px; }
.raison p { color: var(--texte-second); margin-bottom: 0; font-size: 0.98rem; }
.raison .etiquette { margin-bottom: 14px; }

/* --- Tarifs ------------------------------------------------------------ */

.tarifs { display: grid; gap: clamp(16px, 2vw, 24px); grid-template-columns: 1fr; }
@media (min-width: 760px) { .tarifs { grid-template-columns: repeat(2, 1fr); } }

.tarif { display: flex; flex-direction: column; }
.tarif__prix {
  font-family: var(--titre); font-weight: 800; font-size: 2.3rem;
  letter-spacing: -0.03em; line-height: 1; margin: 4px 0 14px;
}
.tarif ul { margin: 0 0 0; padding: 0; list-style: none; }
.tarif li {
  padding: 9px 0 9px 22px; position: relative;
  color: var(--texte-second); font-size: 0.96rem;
  border-top: 1px solid var(--bordure);
}
.tarif li::before {
  content: ''; position: absolute; left: 0; top: 18px;
  width: 9px; height: 1px; background: var(--accent);
}

.mention-recurrent {
  margin-top: 22px; padding: 16px 18px;
  border: 1px solid var(--bordure); border-left: 2px solid var(--accent);
  border-radius: var(--rayon); background: var(--surface);
  color: var(--texte-second); font-size: 0.94rem;
}
.mention-recurrent strong { color: var(--texte); }

/* --- Formulaire -------------------------------------------------------- */

.formulaire { display: grid; gap: 20px; max-width: 620px; }
.champ { display: grid; gap: 7px; }
.champ label { font: 500 0.78rem/1.2 var(--mono); letter-spacing: 0.1em; text-transform: uppercase; color: var(--texte-second); }
.champ .obligatoire { color: var(--accent); }

.champ input, .champ textarea {
  font: 400 1rem/1.5 var(--corps);
  color: var(--texte);
  background: var(--surface);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  padding: 12px 14px;
  width: 100%;
  transition: border-color .18s ease;
}
.champ textarea { min-height: 160px; resize: vertical; }
.champ input:focus, .champ textarea:focus { border-color: var(--accent); outline: none; }
.champ input:focus-visible, .champ textarea:focus-visible { outline: 2px solid var(--accent-clair); outline-offset: 1px; }
.champ input::placeholder, .champ textarea::placeholder { color: #5C6E88; }

/* Pot de miel : invisible a l'ecran, hors du flux de tabulation */
.pot-de-miel {
  position: absolute; left: -9999px; width: 1px; height: 1px;
  overflow: hidden;
}

.erreur-formulaire {
  border: 1px solid var(--bordure); border-left: 2px solid #E4574C;
  background: var(--surface); border-radius: var(--rayon);
  padding: 14px 16px; color: var(--texte); font-size: 0.95rem;
}

.coordonnees { display: grid; gap: 26px; }
.coordonnees dt { font: 500 0.72rem/1 var(--mono); letter-spacing: 0.15em; text-transform: uppercase; color: var(--accent); margin-bottom: 8px; }
.coordonnees dd { margin: 0; font-size: 1.05rem; }
.coordonnees a { color: var(--texte); text-decoration: none; border-bottom: 1px solid var(--bordure); }
.coordonnees a:hover { border-color: var(--accent); }

/* --- Pied de page ------------------------------------------------------ */

.pied {
  border-top: 1px solid var(--bordure);
  padding-block: 56px 40px;
  color: var(--texte-second);
  font-size: 0.92rem;
}
.pied__haut { display: grid; gap: 34px; margin-bottom: 40px; }
@media (min-width: 760px) { .pied__haut { grid-template-columns: 1.4fr 1fr 1fr; } }
.pied h4 { font: 500 0.72rem/1 var(--mono); letter-spacing: 0.15em; text-transform: uppercase; color: var(--accent); margin-bottom: 16px; }
.pied ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; }
.pied a { color: var(--texte-second); text-decoration: none; }
.pied a:hover { color: var(--texte); }
.pied__signature {
  font: 500 0.68rem/1.6 var(--mono); letter-spacing: 0.12em;
  text-transform: uppercase; color: #6B7C96; margin-top: 10px;
}
.pied__bas {
  border-top: 1px solid var(--bordure); padding-top: 24px;
  display: flex; flex-wrap: wrap; gap: 8px 24px; justify-content: space-between;
  font-size: 0.85rem;
}

/* --- Revelations au defilement ----------------------------------------- */
/* L'etat masque n'est applique que si JavaScript s'execute : sans lui, le
   contenu est simplement visible. C'est la regle la plus importante du
   fichier — une page blanche parce qu'un script n'a pas charge serait le
   pire echec possible sur ce site. */

.js .reveler {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .5s ease, transform .5s ease;
  transition-delay: var(--retard, 0ms);
  will-change: opacity, transform;
}
.js .reveler.revele { opacity: 1; transform: none; will-change: auto; }

@media (prefers-reduced-motion: reduce) {
  .js .reveler { opacity: 1; transform: none; transition: none; }
}
