/* Thème et remise à zéro : ce qui n'appartient à aucun composant.
   Le style de chaque section vit dans son `.spd`, où il est mis en portée. */

:root {
  color-scheme: light dark;

  --marque: #f59e0b;
  --marque-douce: #fef3c7;
  --marque-forte: #b45309;
  --sur-marque: #ffffff;

  --fond: #fffdf9;
  --fond-doux: #f7f4ee;
  --bordure: #e8e3d9;
  --bordure-forte: #d8d1c3;
  --texte: #14161b;
  --texte-doux: #5d6068;

  /* La lueur derrière l'éclair. Une couleur à part, parce qu'elle doit rester
     très diluée dans les deux thèmes sans suivre la marque au pixel. */
  --lueur: rgb(245 158 11 / 16%);

  --rayon: 0.75rem;
  --ombre: 0 1px 2px rgb(60 40 10 / 5%), 0 16px 40px rgb(60 40 10 / 7%);
  --largeur: 62rem;
}

/**
 * La page du REPL tient dans l'écran, et ne le fait pas défiler.
 *
 * L'en-tête et le pied gardent la mesure du site — ce sont les mêmes qu'ailleurs,
 * et les décaler ferait sauter la navigation d'une page à l'autre. C'est le **plan
 * de travail** qui prend la place : toute la largeur, et la hauteur que l'en-tête
 * et le pied laissent. C'est lui qui défile, jamais la page.
 *
 * Sous 56rem l'éditeur et l'aperçu s'empilent : une hauteur fixe les écraserait,
 * donc la page reprend son défilement normal.
 */
@media (min-width: 56rem) {
  .plan-de-travail {
    height: 100dvh;
    overflow: hidden;
  }
}

/**
 * Le sombre, deux fois — et il faut le dire, parce que la duplication est voulue.
 *
 * Il s'applique quand le système le demande **et** qu'aucun choix ne l'a emporté,
 * ou quand le visiteur a choisi « sombre » quel que soit son système. CSS ne sait
 * pas nommer un bloc de déclarations pour le réutiliser : les deux copies doivent
 * donc changer ensemble. `light-dark()` s'en passerait, au prix d'une page sans
 * aucune couleur sur un navigateur qui ne le connaît pas.
 */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='clair']) {
    --marque-douce: rgb(245 158 11 / 14%);
    --marque-forte: #fbbf24;
    --sur-marque: #1a1205;

    --fond: #0b0d11;
    --fond-doux: #12151c;
    --bordure: #222732;
    --bordure-forte: #303643;
    --texte: #e9ebef;
    --texte-doux: #979ba6;

    --lueur: rgb(245 158 11 / 20%);
    --ombre: 0 1px 2px rgb(0 0 0 / 45%), 0 16px 40px rgb(0 0 0 / 35%);
  }
}

:root[data-theme='sombre'] {
    --marque-douce: rgb(245 158 11 / 14%);
    --marque-forte: #fbbf24;
    --sur-marque: #1a1205;

    --fond: #0b0d11;
    --fond-doux: #12151c;
    --bordure: #222732;
    --bordure-forte: #303643;
    --texte: #e9ebef;
    --texte-doux: #979ba6;

    --lueur: rgb(245 158 11 / 20%);
    --ombre: 0 1px 2px rgb(0 0 0 / 45%), 0 16px 40px rgb(0 0 0 / 35%);
}

/* Le choix vaut aussi pour ce que le navigateur dessine lui-même : ascenseurs,
   champs, menus déroulants. Sans cela, une page claire garderait des contrôles
   sombres. */
:root[data-theme='clair'] {
  color-scheme: light;
}

:root[data-theme='sombre'] {
  color-scheme: dark;
}

/* --- Le bouton de thème --------------------------------------------------- */

/* Ces règles sont globales, et non dans un composant : le bouton apparaît dans
   l'en-tête du site **et** dans celui du guide, qui sont deux composants
   distincts, et c'est le script en ligne qui l'anime dans les deux cas. */

.theme {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2rem;
  height: 2rem;
  padding: 0;
  font: inherit;
  font-size: 0.9375rem;
  line-height: 1;
  color: var(--texte);
  background: var(--fond-doux);
  border: 1px solid var(--bordure);
  border-radius: 999px;
  cursor: pointer;
}

.theme:hover {
  border-color: var(--marque);
}

/* **Le glyphe montre ce vers quoi le clic mène**, et c'est le CSS qui choisit :
   le script n'a donc ni à traduire un libellé, ni à réétiqueter un bouton que le
   framework écrit après lui. */
.theme .vers-clair {
  display: none;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='clair']) .theme .vers-clair {
    display: inline;
  }

  :root:not([data-theme='clair']) .theme .vers-sombre {
    display: none;
  }
}

:root[data-theme='sombre'] .theme .vers-clair {
  display: inline;
}

:root[data-theme='sombre'] .theme .vers-sombre {
  display: none;
}

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

body {
  margin: 0;
  /* La pile système : aucune police à télécharger, donc aucun texte invisible le
     temps du chargement. Un site qui vante la légèreté ne commence pas par
     deux cents kilo-octets de fonte. */
  font-family: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  line-height: 1.65;
  color: var(--texte);
  background: var(--fond);
  -webkit-font-smoothing: antialiased;
}

#app {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

h1,
h2,
h3 {
  margin: 0;
  line-height: 1.15;
  text-wrap: balance;
}

p {
  margin: 0;
}

a {
  color: inherit;
}

code,
pre {
  font-family: ui-monospace, 'SFMono-Regular', 'Cascadia Code', 'Consolas', monospace;
}

:focus-visible {
  outline: 2px solid var(--marque);
  outline-offset: 3px;
  border-radius: 0.25rem;
}

/* --- La prose du guide ---------------------------------------------------- */

/* Ces règles sont ici, et non dans le composant qui les affiche, pour une raison
   de fond : le corps d'une page de guide est du HTML **inséré** — il vient des
   fichiers Markdown du dépôt. Il ne porte donc aucune classe de portée, puisque
   le style d'un composant ne s'applique qu'à ce que le composant écrit lui-même.
   Habiller du contenu venu d'ailleurs est le travail de la feuille globale. */

.prose {
  /* Une mesure de lecture, pas la largeur de l'écran : au-delà d'environ
     75 caractères, l'œil perd la ligne en revenant à la marge. */
  max-width: 68ch;
  font-size: 1.0625rem;
}

.prose > * + * {
  margin-top: 1.25rem;
}

.prose h2,
.prose h3,
.prose h4 {
  margin-top: 2.5rem;
  scroll-margin-top: 1.5rem;
  letter-spacing: -0.015em;
}

.prose h2 {
  padding-top: 1.5rem;
  border-top: 1px solid var(--bordure);
  font-size: 1.5rem;
}

/* Les fichiers du guide séparent leurs chapitres par un filet. Là où il précède un
   titre, celui-ci n'a pas à en tracer un second. */
.prose hr + h2 {
  margin-top: 0;
  padding-top: 0;
  border-top: none;
}

.prose h3 {
  font-size: 1.1875rem;
}

.prose h4 {
  font-size: 1rem;
}

.prose a {
  color: var(--marque-forte);
  text-decoration-thickness: 1px;
  text-underline-offset: 0.15em;
}

.prose strong {
  font-weight: 650;
}

.prose ul,
.prose ol {
  padding-left: 1.375rem;
}

.prose li + li {
  margin-top: 0.375rem;
}

.prose blockquote {
  margin-inline: 0;
  padding: 0.25rem 0 0.25rem 1.125rem;
  border-left: 3px solid var(--marque);
  color: var(--texte-doux);
}

.prose hr {
  height: 1px;
  margin: 2.5rem 0;
  border: none;
  background: var(--bordure);
}

/* Le code en ligne se distingue par son fond, pas par une couleur : un mot en
   ambre au milieu d'une phrase se lirait comme un lien. */
.prose code {
  /* Les ligatures d'une police de programmation transforment `===` en un glyphe
     unique. Charmant dans un éditeur, trompeur dans une documentation : ce qui est
     montré doit être ce qu'on tape. */
  font-variant-ligatures: none;
  padding: 0.1em 0.35em;
  background: var(--fond-doux);
  border: 1px solid var(--bordure);
  border-radius: 0.25rem;
  font-size: 0.875em;
}

.prose pre {
  overflow-x: auto;
  padding: 1rem 1.125rem;
  background: var(--fond-doux);
  border: 1px solid var(--bordure);
  border-radius: var(--rayon);
  font-size: 0.8125rem;
  line-height: 1.65;
  tab-size: 2;
}

/* Dans un bloc, le fond et la bordure sont déjà ceux du bloc. */
.prose pre code {
  padding: 0;
  background: none;
  border: none;
  font-size: inherit;
}

/* Un tableau de documentation est large par nature : c'est lui qui défile, jamais
   la page. Le conteneur est posé par le générateur, autour de chaque tableau. */
.tableau {
  overflow-x: auto;
}

.prose table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.9375rem;
}

.prose th,
.prose td {
  padding: 0.5rem 0.875rem;
  border-bottom: 1px solid var(--bordure);
  text-align: left;
  vertical-align: top;
}

.prose th {
  white-space: nowrap;
  font-weight: 600;
}

.prose td code {
  white-space: nowrap;
}

/* Le réglage du système fait loi : une animation peut réellement rendre quelqu'un
   malade, et c'est ainsi qu'il le dit. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
