/* ============================================================================
   styles.css : site goReviz, DA v3.
   Aucune dépendance, aucun build. Voir tokens.css pour le système de design.
   ========================================================================== */

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

html { scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font);
  font-size: var(--fs-body);
  line-height: var(--lh-body);
  -webkit-text-size-adjust: 100%;
}

/* ── Accessibilité ─────────────────────────────────────────────────────────── */

.skip-link {
  position: absolute;
  left: -9999px;
  top: var(--s-s);
  padding: var(--s-s) var(--s-m);
  background: var(--card);
  color: var(--text);
  border: var(--border-width) solid var(--border);
  border-radius: var(--r-s);
  z-index: 10;
}
.skip-link:focus { left: var(--s-m); }

:focus-visible {
  outline: 3px solid var(--text);
  outline-offset: 3px;
  border-radius: var(--r-s);
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  * { transition: none !important; }
}

/* ── Les teintes de remplissage ────────────────────────────────────────────
   Une classe de teinte pose deux choses : le remplissage, et le décalé qu'il
   porte. Tout le reste (l'encre, la bordure) est déduit et n'est jamais une
   décision de l'appelant : c'est la loi 2, et c'est ce qui rend le bug
   « ivoire sur jaune » inexprimable ici comme dans l'app.
   ========================================================================== */

.t-yellow { --fill: var(--yellow); --offset: var(--offset-yellow); }
.t-purple { --fill: var(--purple); --offset: var(--offset-purple); }
.t-green  { --fill: var(--green);  --offset: var(--offset-green); }
.t-pink   { --fill: var(--pink);   --offset: var(--offset-pink); }
.t-blue   { --fill: var(--blue);   --offset: var(--offset-blue); }
.t-mint   { --fill: var(--mint);   --offset: var(--offset-mint); }
.t-orange { --fill: var(--orange); --offset: var(--offset-orange); }

/* Toute surface remplie : encre noire, bordure d'encre, décalé de sa teinte.
   Dans les deux thèmes, sans condition : un pastel est une surface claire. */
.fill {
  background: var(--fill);
  color: var(--on-fill);
  border: var(--border-width) solid var(--ink);
  box-shadow: 4px 4px 0 var(--offset);
}

/* ── Structure ─────────────────────────────────────────────────────────────── */

.wrap {
  max-width: var(--measure);
  margin: 0 auto;
  padding: 0 var(--s-m);
}

header.site { padding: var(--s-l) 0; }

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

/* Le logotype est une carte de l'app en miniature : rempli, bordé, décalé. */
.wordmark {
  display: inline-block;
  padding: var(--s-s) var(--s-m);
  border-radius: var(--r-s);
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 700;
  letter-spacing: -0.3px;
  text-decoration: none;
  transition: transform var(--press) ease-out, box-shadow var(--press) ease-out;
}

/* Conteneur souple : sans min-width, un élément flex refuse de rétrécir sous la
   largeur de son contenu et fait déborder toute la page sur petit écran. */
nav.site {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-s) var(--s-m);
  min-width: 0;
}

nav.site a {
  display: inline-block;
  color: var(--text-secondary);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  text-decoration: none;
  border-bottom: var(--border-width) solid transparent;
  padding: var(--s-s) 0 2px;
}
nav.site a:hover,
nav.site a[aria-current="page"] {
  color: var(--text);
  border-bottom-color: var(--text);
}

main { padding: var(--s-l) 0 var(--s-xxl); }

/* ── Typographie ───────────────────────────────────────────────────────────── */

h1 {
  font-size: var(--fs-h1);
  line-height: var(--lh-h1);
  font-weight: 700;
  letter-spacing: -0.5px;
  margin: 0 0 var(--s-m);
}
h2 {
  font-size: var(--fs-h2);
  line-height: var(--lh-h2);
  font-weight: 600;
  letter-spacing: -0.3px;
  margin: var(--s-xl) 0 var(--s-s);
}
h3 {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  font-weight: 600;
  margin: var(--s-l) 0 var(--s-xs);
}

p, li { color: var(--text-secondary); }
li { margin-bottom: var(--s-xs); }
main a { color: var(--link); text-underline-offset: 3px; }

.lede {
  font-size: var(--fs-h3);
  line-height: var(--lh-h3);
  color: var(--text);
  margin: 0 0 var(--s-l);
}

.meta {
  font-size: var(--fs-caption);
  line-height: var(--lh-caption);
  color: var(--text-muted);
}

/* ── Le pointillé : « pas encore là » ──────────────────────────────────────
   Dans cette DA, le pointillé veut TOUJOURS dire la même chose : la chose
   n'existe pas encore. Et un pointillé n'est JAMAIS rempli : un remplissage
   est précisément ce qui affirme qu'une chose est là. Les deux moitiés se
   contrediraient.

   Deux usages ici, et un seul sens :
     .todo — un champ que l'éditeur doit encore fournir ;
     .btn[aria-disabled] — un store où l'app n'est pas encore publiée.
   ========================================================================== */

.dashed {
  background: none;
  color: var(--text);
  border: var(--border-width) dashed var(--text-muted);
  box-shadow: none;
}

.todo {
  display: inline-block;
  border-radius: var(--r-s);
  padding: 0 var(--s-xs);
  font-size: var(--fs-small);
  font-weight: 600;
}

/* Un pointillé POSÉ SUR un remplissage suit la loi 2 comme tout le reste : son
   trait et son texte passent à l'encre. `--text` vaut l'ivoire en sombre : le
   laisser ici écrirait en ivoire sur du pastel clair, c'est-à-dire rien. */
.cut-face .dashed,
.fill .dashed {
  color: var(--on-fill);
  border-color: var(--on-fill-secondary);
}

/* ── Cartes ────────────────────────────────────────────────────────────────
   Une carte NEUTRE porte une ombre dure en clair, et AUCUNE en sombre : elle
   monte alors en s'éclaircissant. C'est la loi, et --shadow-neutral la porte.
   ========================================================================== */

.card {
  background: var(--card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--r-m);
  box-shadow: var(--shadow-neutral);
  padding: var(--s-l);
  margin: var(--s-l) 0;
}
.card > :first-child { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }

/* ── Le coin tranché ───────────────────────────────────────────────────────
   Trois couches, exactement comme dans l'app (où l'absence de clip-path impose
   un carré pivoté ; ici, clip-path fait le travail, avec ses propres pièges,
   documentés dans tokens.css) :

     1. `.cut::before`   le décalé riso, translaté de 4/4, même silhouette ;
     2. `.cut-face`      le liseré : un fond d'ENCRE, que la face recouvre en
                         laissant 2 px apparents. RN ne sait pas border une
                         arête oblique, le web non plus : le sandwich est le
                         seul moyen d'obtenir un trait sur la diagonale ;
     3. `.cut-face::before` la face pastel, en inset de 2 px, coupée à 21.

   UNE SEULE carte par page. Ce n'est pas un ornement : au-delà d'une
   occurrence, le signal s'éteint et il ne reste qu'une forme géométrique.

   Contrainte héritée de l'app : la carte tranchée se pose sur un APLAT. Son
   encoche ne laisse pas voir le fond, elle le repeint. Sur un dégradé ou une
   image, il n'y a rien de juste à lui donner.
   ========================================================================== */

.cut {
  position: relative;
  margin: var(--s-l) 0;
}

.cut::before {
  content: "";
  position: absolute;
  inset: 0;
  transform: translate(4px, 4px);
  background: var(--offset);
  border-radius: var(--r-m);
  clip-path: var(--cut-path);
}

.cut-face {
  position: relative;
  background: var(--ink);
  border-radius: var(--r-m);
  clip-path: var(--cut-path);
  /* 2 px de liseré + le padding de la carte. */
  padding: calc(var(--s-l) + var(--border-width));
  color: var(--on-fill);
}

.cut-face::before {
  content: "";
  position: absolute;
  inset: var(--border-width);
  background: var(--fill);
  border-radius: var(--r-inner);
  clip-path: var(--cut-path-inner);
}

/* Le contenu passe au-dessus de la face, qui est peinte après le fond d'encre. */
.cut-face > * { position: relative; }

.cut-face > :first-child { margin-top: 0; }
.cut-face > :last-child { margin-bottom: 0; }

/* Sur un remplissage : l'encre, jamais les jetons de texte du thème. Ceux-là
   basculent avec le thème, alors que la surface sous eux, non. */
.cut-face h2,
.cut-face h3,
.cut-face strong { color: var(--on-fill); }
.cut-face p,
.cut-face li,
.cut-face dd { color: var(--on-fill-secondary); }
.cut-face dt { color: var(--on-fill); }
.cut-face a { color: var(--on-fill); }
.cut-face .meta { color: var(--on-fill-secondary); }
.cut-face hr {
  border: 0;
  border-top: 1px solid var(--on-fill-divider);
  margin: var(--s-m) 0;
}

/* ── Tuiles de navigation ──────────────────────────────────────────────────
   Un groupe homogène de commandes compte pour UN remplissage, et n'a le droit
   d'être rempli en bloc que si ses membres portent des teintes DIFFÉRENTES :
   sinon on obtient un mur monochrome, dans lequel plus rien ne se détache.
   Ici, quatre teintes distinctes : le groupe se lit comme un ensemble.
   ========================================================================== */

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: var(--s-m);
  margin: var(--s-l) 0;
  padding: 0;
  list-style: none;
}
.grid li { display: flex; }
.grid .tile { flex: 1; }

.tile {
  display: block;
  padding: var(--s-m);
  min-height: 44px;
  border-radius: var(--r-m);
  text-decoration: none;
  transition: box-shadow var(--press) ease-out, transform var(--press) ease-out;
}
.tile b { display: block; font-size: var(--fs-body); font-weight: 600; }
.tile span { font-size: var(--fs-small); color: var(--on-fill-secondary); }

/* ── Boutons ───────────────────────────────────────────────────────────────── */

.actions { display: flex; gap: var(--s-m); flex-wrap: wrap; margin: var(--s-l) 0; }

.btn {
  display: inline-flex;
  align-items: center;
  padding: var(--s-m) var(--s-l);
  min-height: 44px;
  border-radius: var(--r-s);
  font-size: var(--fs-body);
  font-weight: 600;
  text-decoration: none;
  transition: box-shadow var(--press) ease-out, transform var(--press) ease-out;
}

/* ── Le seul mouvement : l'appui ───────────────────────────────────────────
   Dans l'app, un bouton pressé s'écrase dans le papier : translate(4,4), ombre
   à zéro. Pas de mise à l'échelle, pas de rebond. Le web hérite du geste.

   Le survol, lui, n'existe pas dans l'app : il faut le décider ici. Il ne
   déplace RIEN (un déplacement au survol ferait fuir la cible sous le curseur,
   et surtout il volerait son geste à l'appui). Il allonge l'ombre de 4 à 6 px.
   Et là où il n'y a pas d'ombre à allonger, c'est-à-dire sur une surface neutre
   en mode sombre, la carte monte comme la DA le prescrit pour le sombre : en
   s'éclaircissant.
   ========================================================================== */

.fill:hover,
.fill:focus-visible { box-shadow: 6px 6px 0 var(--offset); }

.fill:active {
  transform: translate(4px, 4px);
  box-shadow: none;
}

a.card:hover,
a.card:focus-visible {
  background: var(--raised);
  box-shadow: var(--shadow-neutral-lifted);
}
a.card:active {
  transform: translate(4px, 4px);
  box-shadow: none;
}

/* Un pointillé ne se soulève pas : il n'a rien à soulever. Il ne réagit qu'au
   curseur, et seulement pour dire qu'il n'y a rien à cliquer. */
.btn[aria-disabled="true"] {
  cursor: not-allowed;
  color: var(--text-muted);
}

/* ── Captures de l'application ─────────────────────────────────────────────
   Chaque capture existe en deux versions, claire et sombre, et c'est le
   navigateur qui choisit (élément <picture>, aucun script). Un site qui montre
   son mode clair à un visiteur en mode sombre se contredit lui-même.
   ========================================================================== */

.screens {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: var(--s-l);
  margin: var(--s-l) 0;
  padding: 0;
  list-style: none;
}

.screens figure { margin: 0; }

.screens img {
  display: block;
  width: 100%;
  height: auto;
  background: var(--card);
  border: var(--border-width) solid var(--border);
  border-radius: var(--r-m);
  box-shadow: var(--shadow-neutral);
}

.screens figcaption {
  margin-top: var(--s-s);
  font-size: var(--fs-small);
  line-height: var(--lh-small);
  color: var(--text-secondary);
}

/* ── Pages légales ─────────────────────────────────────────────────────────── */

/* Sommaire des documents longs : les relecteurs des stores cherchent une section précise. */
.toc { margin: var(--s-l) 0; }
.toc ol { padding-left: var(--s-l); margin: 0; }
.toc a { color: var(--text-secondary); }

/* Couples terme / définition : sous-traitants, données collectées. */
dl { margin: var(--s-m) 0; }
dt { font-weight: 600; color: var(--text); margin-top: var(--s-m); }
dd { margin: var(--s-xs) 0 0; color: var(--text-secondary); }

/* ── Pied de page ──────────────────────────────────────────────────────────── */

footer.site {
  border-top: var(--border-width) solid var(--border);
  padding: var(--s-l) 0 var(--s-xl);
}
footer.site ul {
  display: flex;
  flex-wrap: wrap;
  gap: var(--s-m);
  padding: 0;
  margin: 0 0 var(--s-m);
  list-style: none;
}
footer.site a {
  display: inline-block;
  padding: var(--s-xs) 0;
  color: var(--text-secondary);
  font-size: var(--fs-small);
  text-decoration: none;
  border-bottom: 1px solid var(--text-muted);
}
footer.site a:hover { color: var(--text); border-bottom-color: var(--text); }

/* ── Impression : les relecteurs des stores exportent ces pages en PDF ─────
   Le coin tranché ne survit pas à l'impression : `clip-path` est inégalement
   supporté par les moteurs d'export PDF, et une carte à moitié découpée sur un
   document juridique est pire qu'une carte carrée. On le neutralise, et la
   carte redevient un encadré simple. Le sens (« ceci est la section
   principale ») survit par la bordure ; c'est l'ornement qui tombe.
   ========================================================================== */

@media print {
  header.site nav, .actions, .skip-link, .toc, .screens { display: none; }

  body { background: #FFFFFF; color: #000000; }
  p, li, dd { color: #000000; }
  a { text-decoration: underline; }

  .card, .tile, .wordmark, .fill { box-shadow: none; }

  .cut::before { display: none; }
  .cut-face {
    clip-path: none;
    background: none;
    border: var(--border-width) solid #000000;
    padding: var(--s-l);
  }
  .cut-face::before { display: none; }
  .cut-face p, .cut-face li, .cut-face dd, .cut-face .meta { color: #000000; }

  /* L'URL derrière chaque lien, sinon le PDF perd l'information. */
  main a[href^="http"]::after { content: " (" attr(href) ")"; font-size: 90%; }

  .todo { border: 1px dashed #000000; background: none; }
}
