/* --- Polices ------------------------------------------------------------- */
/* Toutes auto-hébergées : une requête vers un CDN de polices serait un point de
   panne externe, et le site doit tenir tout seul. */
@font-face {
    font-family: "Manrope";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/assets/fonts/manrope-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "Manrope";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/assets/fonts/manrope-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
    font-family: "Atkinson Hyperlegible Mono";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/assets/fonts/atkinson-hyperlegible-mono-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "Atkinson Hyperlegible Mono";
    font-style: normal;
    font-weight: 400 700;
    font-display: swap;
    src: url("/assets/fonts/atkinson-hyperlegible-mono-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Bricolage Grotesque : la fonte de titrage. C'est elle qui donne une voix à
   la charte — « Manrope en gras partout » était précisément ce qui rendait la
   version précédente anonyme. Variable, donc une seule ressource pour toutes
   les graisses. */
@font-face {
    font-family: "Bricolage Grotesque";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/assets/fonts/bricolage-latin-ext.woff2") format("woff2");
    unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
    font-family: "Bricolage Grotesque";
    font-style: normal;
    font-weight: 400 800;
    font-display: swap;
    src: url("/assets/fonts/bricolage-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* --- Jetons -------------------------------------------------------------- */
:root {
    /* Palette chaude et assumée. La référence aux années 80 tient entièrement
       ici : terre cuite, moutarde, sarcelle sur papier crème. Aucune police
       bitmap, aucun biseau — mais aucune fadeur non plus. */
    --bb3-paper: #fbf6ee;
    --bb3-paperSunk: #f3ebdd;
    --bb3-ink: #241c15;
    --bb3-inkSoft: #6a5d4e;
    --bb3-line: #e3d8c6;

    /* Terre cuite : la couleur signature. Contraste 5,1:1 sur le papier, donc
       utilisable en texte comme en aplat — contrairement à l'orange vif du
       cube, qui plafonne à 3,4:1 et ne pouvait rien porter de lisible. */
    --bb3-terracotta: #c0391a;

    /* Moutarde : décorative uniquement (3,65:1), donc jamais en texte sur le
       papier — seulement en aplat avec de l'encre par-dessus. */
    --bb3-mustard: #e8a317;


    /* Les froids du mot-symbole. Deux contraintes cumulées : porter du texte sur
       le papier (les stickers bruts n'y arrivent pas — le bleu plafonne à 2,5:1),
       et rester nettement distincts de la braise de « Barbe », ce qui écarte le
       rouge, l'orange et même un jaune assombri. Toutes au-delà de 3,8:1. */
    --bb3-inkBlue: #1e7e9b;
    --bb3-inkGreen: #0a8f41;
    --bb3-inkTurquoise: #0f8a8a;
    --bb3-inkIndigo: #3b4fae;

    /* Les six couleurs de stickers, telles quelles. Elles ne servent pas de
       texte — aucune ne passerait le contraste — mais d'aplats décoratifs :
       c'est le puzzle lui-même qui colore la page. */
    --bb3-stickerWhite: #fff7ff;
    --bb3-stickerYellow: #ffea00;
    --bb3-stickerRed: #ef3923;
    --bb3-stickerBlue: #41aac8;
    --bb3-stickerOrange: #ff6d00;
    --bb3-stickerGreen: #00c853;

    /* Angles droits : la bande de couleur épaisse en tête des cartes et un
       coin arrondi se contredisaient — l'arrondi cassait la bande. Le carré
       gagne, il va aussi avec le sujet. */
    --bb3-radius: 0;
    --bb3-radiusSticker: 3px;
    /* Le relief des boutons et des cartes : une ombre pleine, décalée, dans
       l'encre. Franche sans être dure. */
    --bb3-lift: 6px;
    --bb3-container: 720px;
    /* La marge latérale de la page. Le chrome et le contenu la partagent, sinon
       leurs textes ne s'alignent pas verticalement. */
    --bb3-pageGutter: 20px;
    --bb3-gap: 28px;

    --bb3-fontTitle: "Bricolage Grotesque", "Manrope", sans-serif;
    --bb3-fontBody: "Manrope", "Segoe UI", sans-serif;
    /* La notation reste en mono conçue pour la lisibilité : dans un jeu où l'on
       lit R' et R, confondre les deux fausse une partie. */
    --bb3-fontNotation: "Atkinson Hyperlegible Mono", ui-monospace, monospace;
}
/* --- Base ---------------------------------------------------------------- */
/* Normalisation seulement. Tout sélecteur de balise générique porte
   `:not([class])` : sans cette garde, il entrerait en concurrence avec les
   styles BEM des composants, qui devraient alors se défendre à coups de
   spécificité. */
*,
*::before,
*::after {
    box-sizing: border-box;
}
body {
    /* Remise à zéro pure : n'entre en concurrence avec aucun composant.
       Les styles visuels du body vivent dans le bloc .bb3-page, qu'il porte. */
    margin: 0;
    min-width: 320px;
}
/* L'attribut `hidden` doit l'emporter sur toute déclaration `display` d'un
   composant. Sans cette règle, un bloc en `display: flex` ou `display: block`
   reste visible alors que le HTML le dit caché — le `display` de la classe bat
   celui du navigateur. C'est la seule dérogation au « !important réservé aux
   utilitaires » : ici, l'exception est justement ce qui rend l'attribut fiable. */
/* Convention : tout texte centré porte aussi `text-wrap: balance`.
   Le centrage rend visible ce que le drapeau gauche pardonne — une dernière
   ligne d'un seul mot devient un défaut d'équilibre, pas une fin de paragraphe.
   Il n'existe aucun sélecteur pour « ce qui est centré », les deux déclarations
   doivent donc être écrites ensemble à chaque fois.

   Deux choses à savoir avant de la poser. La propriété est *héritée* : la
   placer sur un conteneur couvre tous ses descendants, il vaut donc mieux la
   mettre au niveau où le centrage est décidé. Et les navigateurs cessent
   d'équilibrer au-delà de quelques lignes : elle sert les titres et les blocs
   courts, elle est sans effet sur un long paragraphe. */
[hidden] {
    display: none !important;
}
h1:not([class]),
h2:not([class]),
h3:not([class]) {
    margin: 0;
    font-family: var(--bb3-fontTitle);
    font-weight: 800;
    line-height: 1.2;
    letter-spacing: -0.015em;
}
a:not([class]) {
    color: var(--bb3-terracotta);
    text-decoration: underline;
    text-underline-offset: 3px;
}
img:not([class]),
svg:not([class]),
canvas:not([class]) {
    display: block;
    max-width: 100%;
}
/* Ligne de base d'accessibilité : doit s'appliquer partout, y compris aux
   composants. Ce n'est pas un sélecteur de balise, il n'y a donc rien à
   exclure. */
:focus-visible {
    outline: 3px solid var(--bb3-terracotta);
    outline-offset: 2px;
}
/* --- Utilitaires --------------------------------------------------------- */
/* Nom non abstrait, une seule intention, et !important assumé : c'est le seul
   endroit du projet où il est admis. */
.u-visuallyHidden {
    position: absolute !important;
    width: 1px !important;
    height: 1px !important;
    padding: 0 !important;
    margin: -1px !important;
    overflow: hidden !important;
    clip: rect(0, 0, 0, 0) !important;
    white-space: nowrap !important;
    border: 0 !important;
}
/* Porté par le <body>. La page crème *est* la surface du site : le contenu s'y
   pose directement. Seuls les vrais objets — une carte de jeu, la scène du
   cube — reçoivent un contenant. */
/* Colonne pleine hauteur : c'est ce qui permet au pied de page de rester en bas
   même sur une page courte, sans hauteur fixe ni calcul. */
.bb3-page {
    display: flex;
    flex-direction: column;
    min-height: 100vh;
    background: var(--bb3-paper);
    font-family: var(--bb3-fontBody);
    color: var(--bb3-ink);
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}
/* Même calcul de largeur que `.bb3-chrome__inner` : la colonne de texte doit
   tomber au même endroit dans le chrome et dans le contenu. */
.bb3-page__container {
    display: flex;
    flex-direction: column;
    gap: var(--bb3-gap);
    width: 100%;
    max-width: calc(var(--bb3-container) + 2 * var(--bb3-pageGutter));
    margin: 0 auto;
    padding: 40px var(--bb3-pageGutter) 64px;
}
/* L'identité du site, dans la bande de chrome de l'accueil : le mot-symbole en
   grand et l'accroche. Rien d'autre — le titre d'une page relève du bloc
   pageTitle, sous la couture. */
.bb3-masthead {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
    /* Ramené dans la colonne de lecture, contrairement à la barre de navigation
       qui tient les bords : le mot-symbole et l'accroche s'alignent ainsi sur le
       texte qui les suit, sous la couture. */
    width: 100%;
    max-width: calc(var(--bb3-container) + 2 * var(--bb3-pageGutter));
    margin: 0 auto;
    padding-bottom: 4px;
}
.bb3-masthead__identity {
    flex: initial;
}
.bb3-masthead__title {
    font-family: var(--bb3-fontTitle);
    margin: 0;
    font-size: clamp(2rem, 8vw, 3.2rem);
    font-weight: 800;
    /* Interlettrage resserré : le mot devient un bloc compact, c'est lui qui
       porte l'identité plutôt qu'un habillage. */
    /* Capitales : le mot devient un bloc plein, sans jambages qui cassent la
       ligne. L'interlettrage se desserre légèrement — resserrer des capitales
       les colle, à l'inverse des bas-de-casse. */
    text-transform: uppercase;
    letter-spacing: -0.02em;
    line-height: 0.95;
    color: var(--bb3-terracotta);
}
.bb3-masthead__tagline {
    margin: 6px 0 0;
    color: var(--bb3-inkSoft);
    font-size: 0.95rem;
}
/* Mot-symbole bicolore : « Barbe » reste chaud, « cube » circule dans les
   froids. L'opposition des températures tient donc à tout instant du cycle —
   un rouge ou un orange se confondrait avec la braise, et même un jaune
   assombri en reste trop proche. */
@keyframes bb3-masthead__cubeHue {
    0%, 100% { color: var(--bb3-inkBlue); }
    25% { color: var(--bb3-inkGreen); }
    50% { color: var(--bb3-inkTurquoise); }
    75% { color: var(--bb3-inkIndigo); }
}
.bb3-masthead__titleTail {
    color: var(--bb3-inkBlue);
    animation: bb3-masthead__cubeHue 60s linear infinite;
}
/* Un cycle de couleur lent reste une animation : on la coupe pour qui la
   refuse, en gardant la couleur de repli. */
@media (prefers-reduced-motion: reduce) {
    .bb3-masthead__titleTail {
        animation: none;
    }
}
/* Barre de navigation, en haut de la bande de chrome. Volontairement effacée :
   la page appartient au jeu, pas au compte. Elle ne contient que ce qui est
   commun à toutes les pages — c'est ce qui en fait un repère. */
.bb3-accountBar {
    display: flex;
    align-items: baseline;
    gap: 18px;
    font-size: 0.85rem;
}
/* Le mot-symbole réduit tient le bord gauche. Il reprend le traitement de
   l'en-tête pour qu'on y reconnaisse le même objet, en plus petit. */
.bb3-accountBar__site {
    color: var(--bb3-inkSoft);
    font-family: var(--bb3-fontTitle);
    font-size: 0.9rem;
    font-weight: 800;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    text-decoration: none;
}
.bb3-accountBar__site:hover {
    color: var(--bb3-terracotta);
}
/* Mot-symbole bicolore, comme dans l'en-tête : « Barbe » reste chaud, « cube »
   circule dans les froids. L'animation est définie par le bloc masthead. */
.bb3-accountBar__siteTail {
    color: var(--bb3-inkBlue);
    animation: bb3-masthead__cubeHue 60s linear infinite;
}
@media (prefers-reduced-motion: reduce) {
    .bb3-accountBar__siteTail {
        animation: none;
    }
}
/* `margin-left: auto` plutôt que `justify-content: space-between` sur le parent :
   les liens restent collés au bord droit quoi qu'il arrive, y compris si le
   mot-symbole venait à disparaître. */
.bb3-accountBar__links {
    display: flex;
    align-items: baseline;
    gap: 20px;
    margin-left: auto;
}
.bb3-accountBar__form {
    margin: 0;
}
.bb3-accountBar__link {
    background: none;
    border: 0;
    padding: 0;
    color: var(--bb3-inkSoft);
    font: inherit;
    text-decoration: none;
    border-bottom: 2px solid transparent;
    cursor: pointer;
}
.bb3-accountBar__link:hover,
.bb3-accountBar__link:focus-visible {
    color: var(--bb3-ink);
    border-bottom-color: var(--bb3-terracotta);
}
.bb3-accountBar__link--strong {
    color: var(--bb3-ink);
    font-weight: 800;
}
/* La page en cours. Le soulignement est réservé à cet état : posé sur un lien
   ordinaire, il se lisait comme « vous êtes ici » et désignait la mauvaise
   page. */
.bb3-accountBar__link--current {
    color: var(--bb3-ink);
    border-bottom-color: var(--bb3-terracotta);
    cursor: default;
}
/* Sous 480 px, le mot-symbole et trois liens ne tiennent plus sur une ligne. */
@media (max-width: 480px) {
    .bb3-accountBar {
        gap: 12px;
    }

    .bb3-accountBar__links {
        gap: 14px;
    }

    .bb3-accountBar__site {
        letter-spacing: 0.08em;
    }
}
/* Le chrome du site : bandeau d'identité, en-tête, pied de page.
   Il sort du flux de lecture et occupe toute la largeur, sur un fond légèrement
   creusé. C'est le seul endroit où le site peut parler de lui-même sans gêner
   ce que le visiteur est venu faire — le contenu, lui, reste posé à même le
   papier. */
.bb3-chrome {
    background: var(--bb3-paperSunk);
}
/* Le contenu du chrome n'est volontairement pas ramené dans la colonne de
   lecture : c'est une barre de navigation, le mot-symbole tient le bord gauche
   et les liens le bord droit. Les aligner sur le texte les aurait ramenés vers
   le centre, où ils auraient concurrencé le contenu au lieu de l'encadrer. */
/* Colonne : l'accueil empile la barre de navigation et le titre du site dans la
   même bande. Les autres pages n'ont qu'une rangée, la colonne y est sans
   effet. */
.bb3-chrome__inner {
    display: flex;
    flex-direction: column;
    gap: 18px;
    padding: 14px var(--bb3-pageGutter) 18px;
}
/* La couture : les couleurs du cube, en continu d'un bord à l'autre. C'est
   l'ancien filet de stickers, devenu la frontière entre le chrome et le
   contenu. Un dégradé à arrêts nets plutôt que des carrés : il se répète de
   lui-même quelle que soit la largeur, là où un nombre fixe de carrés aurait
   fallu étirer ou tronquer.

   La séquence est tirée au sort à chaque chargement et fournie par le serveur
   dans `--bb3-seamStops` (voir `app/php/Seam.php`). La valeur de repli n'est
   pas décorative : si le HTML est servi depuis un cache plus ancien que cette
   feuille, la bande doit rester une bande et non disparaître. */
.bb3-chrome__seam {
    height: 8px;
    background: repeating-linear-gradient(
        90deg,
        var(--bb3-seamStops,
            var(--bb3-stickerRed) 0 28px,
            var(--bb3-stickerBlue) 28px 56px,
            var(--bb3-stickerOrange) 56px 84px,
            var(--bb3-stickerGreen) 84px 112px,
            var(--bb3-stickerYellow) 112px 140px,
            var(--bb3-stickerWhite) 140px 168px)
    );
}
/* Le pied de page ferme la page par le même fond. Un filet suffit à le poser :
   une seconde couture colorée ferait deux signatures pour un seul site. */
.bb3-chrome--footer {
    margin-top: auto;
    border-top: 1px solid var(--bb3-line);
}
@media (max-width: 600px) {
    .bb3-chrome__seam {
        height: 6px;
    }

    .bb3-chrome__inner {
        padding-top: 12px;
        padding-bottom: 12px;
    }
}
/* L'objectif, au-dessus du cube : ce que le joueur doit accomplir. C'est lui
   qui déclenche l'envie, donc il vient avant le cube — et avant l'aide à la
   manipulation, qui dit « comment ». */
.bb3-objective {
    text-align: center;
    text-wrap: balance;
}
.bb3-objective__goal {
    margin: 0;
    font-family: var(--bb3-fontTitle);
    font-size: 1.15rem;
    font-weight: 800;
    letter-spacing: -0.01em;
}
/* La définition, juste en dessous : « croix blanche » ne veut rien dire pour
   qui débute. */
.bb3-objective__what {
    margin: 4px auto 0;
    max-width: 42em;
    color: var(--bb3-inkSoft);
    font-size: 0.95rem;
}
/* La scène du cube : le seul véritable « objet » de la page de jeu. Fond
   légèrement enfoncé — le renderer est en alpha et le corps des pièces est
   presque noir, un crème un peu plus dense les détache mieux qu'un blanc pur. */
.bb3-stage {
    padding: 12px;
    background: var(--bb3-paperSunk);
    border-radius: var(--bb3-radius);
}
/* Élément de nidification : prépare la scène à accueillir le canvas produit par
   Three.js, dont on ne maîtrise pas le balisage. */
.bb3-stage__screen {
    display: flex;
    justify-content: safe center;
    /* `touch-action` n'est plus posé ici. Il l'était en dur, ce qui interdisait
       de défiler au doigt même quand le cube ne se manipulait pas : sur une
       question qui montre un mouvement sans le laisser refaire, le geste ne
       tournait rien et ne défilait pas non plus. Le moteur le pose désormais
       lui-même sur sa racine, le temps qu'il écoute — lui seul sait à quel
       instant le geste lui appartient. */
}
/* Les actions, sous le cube. Colonne resserrée et centrée : sur un large écran
   deux boutons perdus sur toute la largeur de la scène ne se lisent plus comme
   une paire.

   `safe center` et non `center` : le mot-clé fait retomber l'alignement sur le
   bord de départ en cas de débordement, au lieu de laisser le contenu sortir
   par la gauche où il devient inatteignable. C'est la convention du projet. */
.bb3-stage__actions {
    display: flex;
    flex-wrap: wrap;
    justify-content: safe center;
    gap: 8px;
    max-width: 42em;
    margin: 20px auto;
}
.bb3-stage__action {
    flex: initial;
}
/* Une aide, pas une consigne : elle dit « comment », et un « comment » ne
   s'absorbe pas avant d'avoir eu envie du « quoi ». D'où le retrait. */
.bb3-stage__instruction {
    margin: 0;
    color: var(--bb3-inkSoft);
    font-size: 0.92rem;
    text-align: center;
    text-wrap: balance;
}
/* La progression passe en premier : ce bloc est le plus haut de la page de jeu,
   avant le cube. Pas de boîte — les chiffres sont assez gros pour tenir seuls,
   et c'est leur taille qui fait la signature. */
.bb3-scoreboard {
    display: flex;
    flex-wrap: wrap;
    justify-content: safe center;
    gap: 32px;
    text-align: center;
    text-wrap: balance;
}
.bb3-scoreboard__item {
    flex: initial;
    min-width: 150px;
}
.bb3-scoreboard__label {
    display: block;
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--bb3-inkSoft);
}
.bb3-scoreboard__value {
    font-family: var(--bb3-fontTitle);
    display: block;
    font-size: clamp(2.6rem, 10vw, 3.6rem);
    font-weight: 800;
    line-height: 1;
    letter-spacing: -0.05em;
}
/* Une séquence de coups sur une ligne, avec son bouton de copie à droite.
   Réutilisé pour le mélange du jour, les coups en cours et ceux du record. */
.bb3-sequence {
    display: flex;
    align-items: baseline;
    gap: 12px;
}
/* Tronquée plutôt que repliée : une séquence sur trois lignes déforme la page
   à chaque coup joué. `min-width: 0` est indispensable — sans lui un élément
   flex refuse de descendre sous sa largeur de contenu et ne tronque jamais.
   Pas de `flex: auto` : la valeur occupe sa largeur naturelle, donc le bouton
   se colle au texte au lieu de flotter au loin sur une séquence courte. Elle
   rétrécit quand même quand ça déborde, `flex-shrink` valant 1 par défaut. */
.bb3-sequence__value {
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    font-family: var(--bb3-fontNotation);
    font-size: 0.9rem;
    color: var(--bb3-terracotta);
}
.bb3-sequence__copy {
    flex: initial;
    padding: 0;
    border: 0;
    background: transparent;
    color: inherit;
    font-family: inherit;
    font-size: 0.85rem;
    font-weight: 700;
    text-decoration: underline;
    text-underline-offset: 3px;
    cursor: pointer;
    white-space: nowrap;
}
.bb3-sequence__copy:hover {
    text-decoration-thickness: 2px;
}
.bb3-sequence--empty .bb3-sequence__copy {
    visibility: hidden;
}
/* Posée sur un aplat terre cuite : la couleur par défaut y serait invisible.
   Défini ici plutôt que par une règle du bloc parent, pour que le composant
   reste maître de son apparence. */
.bb3-sequence--onAccent .bb3-sequence__value {
    color: var(--bb3-paper);
}
/* Le quiz : une question par page. La progression et l'enjeu sont dits d'entrée,
   parce que la mort subite change la façon de répondre. */
.bb3-quiz {
    display: flex;
    flex-direction: column;
    gap: 16px;
}
.bb3-quiz__progress {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin: 0;
    color: var(--bb3-inkSoft);
    font-size: 0.9rem;
}
.bb3-quiz__stake {
    font-weight: 800;
}
.bb3-quiz__question {
    font-family: var(--bb3-fontTitle);
    margin: 0;
    font-size: clamp(1.15rem, 4vw, 1.4rem);
    font-weight: 800;
    text-align: center;
    text-wrap: balance;
}
.bb3-quiz__form {
    display: flex;
    flex-direction: column;
    gap: 16px;
    margin: 0;
}
.bb3-quiz__choices {
    display: flex;
    flex-wrap: wrap;
    justify-content: safe center;
    gap: 10px;
}
/* La proposition entière est cliquable : viser un petit rond au doigt est une
   source d'erreur, et une erreur coûte la manche. */
.bb3-quiz__choice {
    display: inline-flex;
    align-items: safe center;
    gap: 8px;
    padding: 12px 18px;
    background: var(--bb3-paper);
    border: 2px solid var(--bb3-ink);
    box-shadow: var(--bb3-lift) var(--bb3-lift) 0 var(--bb3-ink);
    cursor: pointer;
}
.bb3-quiz__choice:hover {
    background: var(--bb3-paperSunk);
}
/* Le rond natif reste : il porte l'état sélectionné pour les lecteurs d'écran
   et pour la navigation au clavier, que rien ne remplacerait ici. */
.bb3-quiz__radio {
    accent-color: var(--bb3-terracotta);
}
.bb3-quiz__choiceLabel {
    font-family: var(--bb3-fontNotation);
    font-size: 1.05rem;
    font-weight: 800;
}
.bb3-quiz__played {
    margin: 0;
    text-align: center;
    font-family: var(--bb3-fontNotation);
}
/* L'écran de réussite.
   C'était le point faible du jeu : le moment que toute la partie prépare était
   rendu dans le style le plus discret de la charte, celui du texte d'aide. Il
   prend désormais la pleine largeur, en aplat terre cuite — 5,08:1 avec le
   papier, donc lisible y compris en corps normal. */
.bb3-victory {
    padding: 24px;
    background: var(--bb3-terracotta);
    border-radius: var(--bb3-radius);
    color: var(--bb3-paper);
}
/* Le surtitre du gros chiffre. Sans lui, rien ne disait si le nombre désignait
   la tentative ou le record — c'était la source de l'ambiguïté. */
.bb3-victory__label {
    display: block;
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    opacity: 0.85;
}
.bb3-victory__score {
    display: block;
    font-family: var(--bb3-fontTitle);
    font-size: clamp(3rem, 14vw, 4.5rem);
    font-weight: 800;
    line-height: 0.95;
    letter-spacing: -0.05em;
}
.bb3-victory__unit {
    font-size: 0.4em;
    font-weight: 800;
    letter-spacing: -0.01em;
}
/* Le rang, en gras : c'est la deuxième information la plus forte après le
   chiffre lui-même. */
/* Chaque information sur sa ligne : le changement de record et le rang sont
   deux faits distincts, les enchaîner sur une ligne les faisait se disputer. */
.bb3-victory__detail {
    margin: 12px 0 0;
    font-size: 1.1rem;
    font-weight: 700;
}
/* Le changement de record garde sa ligne : c'est un fait distinct du rang, et
   les enchaîner les faisait se disputer la lecture. */
.bb3-victory__line {
    display: block;
}
/* Le rang et le rappel de règle, eux, tiennent ensemble : « 2e meilleur score
   du jour » appelle immédiatement « retenter ne coûte rien ». */
.bb3-victory__rank {
    display: inline;
}
/* Le rappel de règle accompagne le rang sans lui disputer l'attention. La
   distinction joue sur trois axes — graisse, corps, italique — plutôt que sur
   l'inclinaison seule : Manrope n'a pas de vrai italique, le navigateur en
   synthétise un, et une oblique synthétique ne suffit pas à porter une
   hiérarchie. */
.bb3-victory__aside {
    /* L'espace vient du retour à la ligne du gabarit, entre les deux balises. */
    display: inline;
    font-size: 0.92rem;
    font-weight: 400;
    font-style: italic;
    opacity: 0.85;
}
.bb3-victory__hint {
    margin: 8px 0 0;
    font-size: 1.1rem;
    font-weight: 700;
}
/* Nidification : le bouton est un bloc à part entière. Sur l'aplat terre cuite
   il lui faut sa propre variante, le contour encre y serait illisible. */
.bb3-victory__actions {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 14px;
    margin-top: 18px;
}
.bb3-victory__action {
    flex: initial;
}
/* La séquence du record, en mono lisible : c'est elle qu'on relit pour
   comprendre comment on a fait, ou qu'on reproduit sur un vrai cube. */
/* Le rendez-vous du lendemain accompagne la série sans peser autant : c'est une
   information, pas une récompense. */
.bb3-victory__next {
    font-size: 0.92rem;
    font-weight: 400;
    font-style: italic;
    opacity: 0.85;
}
.bb3-victory__sequence {
    margin-top: 20px;
}
/* L'encart entre en scène : une apparition brève, jamais rejouée au
   rechargement puisqu'elle ne dure qu'un instant. */
@keyframes bb3-victory__pop {
    from { transform: scale(0.96); opacity: 0; }
    to { transform: scale(1); opacity: 1; }
}
.bb3-victory {
    animation: bb3-victory__pop 220ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
    .bb3-victory {
        animation: none;
    }
}
/* L'explication du principe, réservée au premier passage. Un lien partagé amène
   des gens qui ne savent rien du site : ils ont trois secondes pour comprendre. */
.bb3-onboarding {
    display: grid;
    gap: 16px;
}
.bb3-onboarding__title {
    margin: 0;
    font-family: var(--bb3-fontTitle);
    font-size: 1.2rem;
    font-weight: 800;
}
.bb3-onboarding__list {
    display: grid;
    gap: 12px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.bb3-onboarding__item {
    display: flex;
    align-items: baseline;
    gap: 12px;
}
/* Le numéro reprend une couleur de sticker : la même palette que le filet et
   les cartes, pour que l'ensemble tienne. Carré à coins légèrement arrondis,
   comme une facette de cube — le rond n'appartenait à aucun autre élément. */
.bb3-onboarding__step {
    flex: none;
    display: inline-flex;
    align-items: safe center;
    justify-content: safe center;
    width: 1.7em;
    height: 1.7em;
    border-radius: var(--bb3-radiusSticker);
    background: var(--bb3-stepColor, var(--bb3-stickerBlue));
    color: var(--bb3-ink);
    font-family: var(--bb3-fontTitle);
    font-weight: 800;
    font-size: 0.85rem;
    line-height: 0;
}
.bb3-onboarding__item--two { --bb3-stepColor: var(--bb3-stickerBlue); }
.bb3-onboarding__item--three { --bb3-stepColor: var(--bb3-stickerGreen); }
.bb3-onboarding__item--four { --bb3-stepColor: var(--bb3-stickerOrange); }
/* Le rouge du cube (#ef3923) ne porte pas de petit texte : mesuré, il donne
   4,22 avec l'encre et 3,98 avec du blanc — les deux sous le seuil AA de 4,5.
   Le blanc est donc *moins* lisible que l'encre ici, contrairement à ce que
   l'œil suggère.
   On garde l'encre, comme sur les trois autres puces, et on éclaircit le rouge
   de 8 % pour cette seule pastille : 4,56, au-dessus du seuil. Le jeton global
   n'est pas touché — c'est la couleur exacte de la face du cube 3D, et le filet
   de stickers doit continuer à la porter. */
.bb3-onboarding__item--one { --bb3-stepColor: #f04935; }
.bb3-onboarding__text {
    margin: 0;
}
/* L'idée principale en tête de puce : le lecteur qui balaie la page doit
   pouvoir ne lire que les quatre débuts et avoir compris. */
.bb3-onboarding__lead {
    font-weight: 800;
}
/* Le titre d'une page, sous la couture. C'est du contenu, pas de l'identité :
   il prend donc le registre du contenu — encre, bas-de-casse, pas d'espacement
   de capitales — là où le mot-symbole garde la terre cuite et les capitales.
   Confondre les deux faisait porter au nom du jeu l'habillage de la marque. */
.bb3-pageTitle {
    display: flex;
    align-items: safe center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
}
/* `min-width: 0` lève la valeur par défaut `auto`, qui empêche un élément flex
   de rétrécir sous la largeur de son contenu. Sans elle, un sous-titre un peu
   long ne se replie pas : il pousse la série à la ligne au lieu de passer
   lui-même sur deux lignes. */
.bb3-pageTitle__identity {
    flex: initial;
    min-width: 0;
}
/* Même rôle que sur l'accueil : la série tient le bord droit, y compris quand
   le titre la repousse sur une seconde ligne. */
.bb3-pageTitle__streak {
    margin-left: auto;
}
.bb3-pageTitle__title {
    font-family: var(--bb3-fontTitle);
    margin: 0;
    font-size: clamp(1.5rem, 5vw, 2rem);
    font-weight: 800;
    /* Un léger resserrement suffit en bas-de-casse : c'est la contrepartie du
       desserrement qu'exigent les capitales du mot-symbole. */
    letter-spacing: -0.01em;
    line-height: 1.1;
    color: var(--bb3-ink);
}
.bb3-pageTitle__intro {
    margin: 6px 0 0;
    color: var(--bb3-inkSoft);
    font-size: 0.95rem;
}
/* En-tête d'une section de contenu : son titre à gauche, ce qui la qualifie à
   droite. Sur l'accueil, la série se pose ici plutôt que dans le chrome — elle
   se rapporte aux jeux, pas au site. */
.bb3-sectionHead {
    display: flex;
    align-items: safe center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: 12px;
}
/* Élément d'accueil : `margin-left: auto` colle la série au bord droit même
   quand la ligne passe à la ligne, ce que `justify-content` ne fait plus dès
   que les éléments se répartissent sur deux rangées. */
.bb3-sectionHead__streak {
    margin-left: auto;
}
/* Même raison que sur pageTitle : le titre se replie plutôt que de repousser
   la série. */
.bb3-sectionHead__title {
    min-width: 0;
    font-family: var(--bb3-fontTitle);
    margin: 0;
    font-size: 1.3rem;
    font-weight: 800;
    letter-spacing: -0.01em;
}
/* Les cartes de jeu sont carrées et se rangent en grille. Une seule aujourd'hui,
   mais la grille se remplit d'elle-même quand il y en aura d'autres. */
.bb3-gameGrid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
    gap: var(--bb3-gap);
    /* Sans ça, les cartes héritent de `align-self: stretch` et sont étirées à la
       hauteur de leur rangée. Cette hauteur devient définie, et une hauteur
       définie l'emporte sur `aspect-ratio` : la carte redevenait un rectangle. */
    align-items: start;
}
/* La carte d'un jeu est une face de cube 3x3.
   Le fond du bloc joue le corps en plastique noir, et les écarts entre facettes
   le laissent voir : c'est ce qui fait lire l'objet comme un cube plutôt que
   comme une grille. */
.bb3-gameFace {
    --bb3-faceBody: #17120e;
    --bb3-faceDark: #241c15;
    --bb3-faceLight: var(--bb3-stickerWhite);

    display: grid;
    /* minmax(0, …) et non 1fr seul : une piste « 1fr » garde un minimum
       automatique, donc une barre centrale un peu haute repousserait la rangée
       et le carré redeviendrait un rectangle. C'est la même mécanique qui avait
       déjà cassé la carte précédente. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
    grid-template-rows: repeat(3, minmax(0, 1fr));
    /* Une face de cube est carrée. Sans cette contrainte, la hauteur suivrait le
       texte et l'objet cesserait d'en être un. */
    aspect-ratio: 1 / 1;
    gap: 7px;
    padding: 7px;
    background: var(--bb3-faceBody);
    border-radius: 6px;
    box-shadow: var(--bb3-lift) var(--bb3-lift) 0 var(--bb3-ink);
}
.bb3-gameFace__facet {
    display: flex;
    flex-direction: column;
    align-items: safe center;
    justify-content: safe center;
    gap: 2px;
    /* Le même arrondi que les pastilles et le filet : une seule facette dans
       tout le site. */
    border-radius: var(--bb3-radiusSticker);
    background: var(--bb3-faceDark);
    text-align: center;
    text-wrap: balance;
    overflow: hidden;
}
.bb3-gameFace__facet--edge {
    background: var(--bb3-faceLight);
}
/* La barre de la croix : les trois facettes du milieu n'en font qu'une. */
.bb3-gameFace__band {
    grid-column: 1 / -1;
    display: flex;
    flex-direction: column;
    align-items: safe center;
    justify-content: safe center;
    gap: 6px;
    padding: 10px 14px;
    border-radius: var(--bb3-radiusSticker);
    background: var(--bb3-faceLight);
    color: var(--bb3-ink);
    text-align: center;
    text-wrap: balance;
}
/* --- Coin haut gauche : quel cube, quel jour --------------------------- */
.bb3-gameFace__facet--identity {
    color: var(--bb3-paper);
    line-height: 1.1;
}
.bb3-gameFace__puzzle {
    font-family: var(--bb3-fontTitle);
    font-size: 1.1rem;
    font-weight: 800;
    /* Les capitales viennent du style, pas du texte : « 3×3 » n'y perd rien,
       et le libellé reste lisible partout ailleurs qu'ici. */
    text-transform: uppercase;
}
.bb3-gameFace__date {
    font-size: 0.7rem;
    opacity: 0.75;
}
/* --- Coin haut droit : la série --------------------------------------- */
/* Même aplat moutarde et même encre que la flamme du bandeau : une seule façon
   d'écrire une série sur tout le site. */
.bb3-gameFace__facet--streak {
    background: var(--bb3-mustard);
    color: var(--bb3-ink);
    font-size: 0.8rem;
    font-weight: 800;
    line-height: 1.15;
}
/* --- La barre centrale ------------------------------------------------- */
.bb3-gameFace__title {
    margin: 0;
    font-family: var(--bb3-fontTitle);
    font-size: clamp(1.1rem, 5vw, 1.45rem);
    font-weight: 800;
    line-height: 1.05;
}
/* Coche encre sur pastille verte : le vert seul ne dirait rien à qui ne le
   distingue pas, la forme de la coche porte l'information. */
.bb3-gameFace__check {
    display: inline-flex;
    align-items: safe center;
    justify-content: safe center;
    width: 1.15em;
    height: 1.15em;
    margin-right: 4px;
    border-radius: 999px;
    background: var(--bb3-stickerGreen);
    font-size: 0.8em;
    vertical-align: baseline;
}
.bb3-gameFace__note {
    margin: 0;
    font-size: 0.9rem;
}
.bb3-gameFace__result {
    margin: 0;
    font-family: var(--bb3-fontNotation);
    font-size: 1.05rem;
    font-weight: 800;
}
/* En ligne avec le score, comme dans l'encart de réussite : « 9 coups » et
   « meilleur score du jour » sont deux moitiés d'une même phrase. */
.bb3-gameFace__rank {
    font-family: var(--bb3-fontBody);
    font-size: 0.8rem;
    font-weight: 400;
}
/* --- Coin bas droit : l'action ----------------------------------------- */
/* La facette entière est le lien. Une cible de cette taille se vise au doigt
   sans regarder, ce qu'un bouton posé dans la carte n'offrait pas. */
.bb3-gameFace__play {
    background: var(--bb3-terracotta);
    color: var(--bb3-paper);
    font-family: var(--bb3-fontTitle);
    font-size: 1rem;
    font-weight: 800;
    line-height: 1.1;
    text-decoration: none;
    /* Même bascule que les boutons primaires : terre cuite, puis encre. */
    transition: background-color 0.12s ease-out;
}
.bb3-gameFace__play:hover,
.bb3-gameFace__play:focus-visible {
    background: var(--bb3-ink);
    color: var(--bb3-paper);
}
.bb3-gameFace__play:focus-visible {
    outline: 3px solid var(--bb3-mustard);
    outline-offset: -3px;
}
/* Sous 360 px, trois colonnes de texte deviennent illisibles : la face garde sa
   géométrie mais la typographie se resserre. */
@media (max-width: 400px) {
    .bb3-gameFace {
        gap: 5px;
        padding: 5px;
    }

    .bb3-gameFace__puzzle { font-size: 0.95rem; }
    .bb3-gameFace__date { font-size: 0.62rem; }
    .bb3-gameFace__facet--streak { font-size: 0.7rem; }
    .bb3-gameFace__play { font-size: 0.85rem; }
    .bb3-gameFace__note { font-size: 0.82rem; }
}
/* --- Motif « quiz notation » -------------------------------------------

   La face du quiz ne doit pas dessiner une croix blanche : elle annoncerait le
   mauvais jeu. Elle prend donc les couleurs du cube, la barre centrale en jaune
   et les facettes libres ailleurs dans la palette. Le jaune n'apparaît nulle
   part ailleurs sur cette face : c'est ce qui fait de la barre le sujet plutôt
   qu'un carré parmi d'autres.

   Deux facettes gardent leur rôle et leur couleur — l'identité en haut à gauche
   et l'action en bas à droite. Les repeindre les ferait passer pour de la
   décoration. */
.bb3-gameFace--notation .bb3-gameFace__band {
    background: var(--bb3-stickerYellow);
}
.bb3-gameFace--notation .bb3-gameFace__facet--topEdge {
    background: var(--bb3-stickerRed);
}
.bb3-gameFace--notation .bb3-gameFace__facet--bottomEdge {
    background: var(--bb3-stickerBlue);
}
.bb3-gameFace--notation .bb3-gameFace__facet--bottomLeft {
    background: var(--bb3-stickerGreen);
}
/* Ce coin n'est peint que lorsqu'il est vide : sinon il porte la série, dont
   l'aplat moutarde est le même sur tout le site. */
.bb3-gameFace--notation .bb3-gameFace__facet--topRight {
    background: var(--bb3-stickerOrange);
}
.bb3-button {
    display: inline-block;
    padding: 13px 22px;
    border: 2px solid var(--bb3-ink);
    box-shadow: var(--bb3-lift) var(--bb3-lift) 0 var(--bb3-ink);
    border-radius: 999px;
    background: transparent;
    color: var(--bb3-ink);
    font-family: inherit;
    font-size: 1rem;
    font-weight: 800;
    line-height: 1.2;
    text-align: center;
    text-wrap: balance;
    text-decoration: none;
    cursor: pointer;
}
.bb3-button:hover {
    background: var(--bb3-paperSunk);
}
/* Le bouton s'enfonce sur son ombre : un retour physique, deux déclarations. */
.bb3-button:active {
    transform: translate(var(--bb3-lift), var(--bb3-lift));
    box-shadow: none;
}
/* Un bouton désactivé perd son relief en plus de sa couleur : garder l'ombre
   le faisait paraître cliquable, et l'utilisateur découvrait l'inverse au
   clic. */
.bb3-button:disabled {
    border-color: var(--bb3-line);
    background: var(--bb3-paperSunk);
    color: var(--bb3-inkSoft);
    box-shadow: none;
    opacity: 0.55;
    cursor: not-allowed;
}
.bb3-button:disabled:active {
    transform: none;
}
.bb3-button--primary {
    background: var(--bb3-terracotta);
    border-color: var(--bb3-terracotta);
    color: var(--bb3-paper);
}
.bb3-button--primary:hover {
    background: var(--bb3-ink);
    border-color: var(--bb3-ink);
}
/* Variante posée sur l'aplat terre cuite de l'écran de réussite : le contour
   encre par défaut y serait invisible. */
/* Aplat moutarde avec de l'encre par-dessus : la moutarde ne contraste pas
   assez pour servir de couleur de texte. Sert à ce qui a été gagné — une série
   en cours — par opposition au terre cuite, qui appelle une action. */
.bb3-button--accent {
    background: var(--bb3-mustard);
    border-color: var(--bb3-ink);
    color: var(--bb3-ink);
}
.bb3-button--accent:hover {
    background: var(--bb3-ink);
    color: var(--bb3-paper);
}
.bb3-button--onAccent {
    background: var(--bb3-paper);
    border-color: var(--bb3-paper);
    color: var(--bb3-terracotta);
}
.bb3-button--onAccent:hover {
    background: var(--bb3-ink);
    border-color: var(--bb3-ink);
    color: var(--bb3-paper);
}
/* Le pictogramme est décoratif : le libellé porte le sens, et le lecteur
   d'écran n'a donc rien à lire de plus. */
.bb3-button__icon {
    margin-right: 6px;
    font-size: 1.1em;
    line-height: 1;
}
/* Bouton amorcé, en attente de confirmation : il prend la couleur de l'action
   pour signaler qu'un second clic est destructeur. */
.bb3-button--armed {
    background: var(--bb3-terracotta);
    border-color: var(--bb3-terracotta);
    color: var(--bb3-paper);
}
/* Bouton dépouillé : ni bord, ni fond, ni relief. Pour une action secondaire
   posée à côté d'une action principale, là où un second bouton plein ferait
   croire à deux choix de même rang. */
.bb3-button--bare {
    padding: 13px 4px;
    background: transparent;
    border-color: transparent;
    box-shadow: none;
    color: inherit;
    text-decoration: underline;
    text-underline-offset: 3px;
}
.bb3-button--bare:hover {
    background: transparent;
    text-decoration-thickness: 2px;
}
.bb3-button--bare:active {
    transform: none;
    box-shadow: none;
}
.bb3-buttonRow {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    margin: 20px 0 0;
}
/* Élément de nidification : chaque bouton est un bloc à part entière, il est
   donc accueilli seul dans son propre élément plutôt que posé directement dans
   la rangée. */
.bb3-buttonRow__item {
    flex: initial;
}
.bb3-buttonRow__feedback {
    color: var(--bb3-inkSoft);
    font-size: 0.9rem;
}
/* Message ponctuel : confirmation après redirection, ou erreur de formulaire.
   Filet épais à gauche plutôt qu'un cadre complet — la page reste sans boîtes,
   et le message garde le poids visuel qui lui revient. */
.bb3-alert {
    margin: 0;
    padding: 12px 16px;
    background: var(--bb3-paperSunk);
    border-left: 6px solid var(--bb3-inkSoft);
    color: var(--bb3-ink);
}
.bb3-alert--good {
    border-left-color: var(--bb3-inkGreen);
}
.bb3-alert--bad {
    border-left-color: var(--bb3-terracotta);
    font-weight: 800;
}
/* Formulaires. Champs carrés à bordure pleine et ombre portée dure, dans la
   même grammaire que les boutons : le formulaire fait partie du même objet
   physique que le reste du site. */
.bb3-form {
    display: flex;
    flex-direction: column;
    gap: 20px;
    margin: 0;
}
.bb3-form__field {
    display: flex;
    flex-direction: column;
    gap: 6px;
}
.bb3-form__label {
    font-weight: 800;
    color: var(--bb3-ink);
}
.bb3-form__input {
    width: 100%;
    padding: 12px 14px;
    background: var(--bb3-paper);
    border: 2px solid var(--bb3-ink);
    border-radius: 0;
    box-shadow: var(--bb3-lift);
    color: var(--bb3-ink);
    font-family: var(--bb3-fontBody);
    /* 16 px minimum : en dessous, iOS zoome à la mise au point du champ et
       casse la mise en page. */
    font-size: 1rem;
}
.bb3-form__input:focus-visible {
    outline: 3px solid var(--bb3-mustard);
    outline-offset: 2px;
}
.bb3-form__hint {
    margin: 0;
    color: var(--bb3-inkSoft);
    font-size: 0.85rem;
}
/* L'erreur reprend la couleur d'alerte et la répète en gras : la couleur seule
   ne dit rien à qui ne la distingue pas. */
.bb3-form__error {
    margin: 0;
    color: var(--bb3-terracotta);
    font-size: 0.85rem;
    font-weight: 800;
}
/* Colonne d'une page de formulaire : étroite, pour que l'œil ne cherche pas la
   ligne suivante. */
.bb3-formLayout {
    display: flex;
    flex-direction: column;
    gap: 24px;
    max-width: 26rem;
    margin: 32px 0 0;
}
.bb3-formLayout__aside {
    margin: 0;
    color: var(--bb3-inkSoft);
}
.bb3-formLayout__legal {
    margin: 0;
    padding-top: 16px;
    border-top: 1px solid var(--bb3-line);
    color: var(--bb3-inkSoft);
    font-size: 0.85rem;
}
.bb3-formLayout__link {
    color: var(--bb3-terracotta);
    font-weight: 800;
}
/* Liste de définitions du compte : une ligne par information. */
.bb3-summary {
    margin: 32px 0 0;
}
.bb3-summary__row {
    display: flex;
    flex-wrap: wrap;
    gap: 8px 16px;
    justify-content: space-between;
    padding: 12px 0;
    border-bottom: 1px solid var(--bb3-line);
}
.bb3-summary__term {
    color: var(--bb3-inkSoft);
}
.bb3-summary__value {
    margin: 0;
    font-weight: 800;
    text-align: right;
}
/* Titre d'une seconde liste sur la même page. */
.bb3-account__title {
    font-family: var(--bb3-fontTitle);
    margin: 32px 0 0;
    font-size: 1.15rem;
    font-weight: 800;
}
/* La précision qui accompagne une valeur sans lui disputer la lecture. */
.bb3-account__aside {
    display: block;
    color: var(--bb3-inkSoft);
    font-size: 0.85rem;
    font-weight: 400;
}
/* Le bilan de la veille, sous les jeux du jour. */
.bb3-recap__title {
    font-family: var(--bb3-fontTitle);
    margin: 0 0 4px;
    font-size: 1.15rem;
    font-weight: 800;
}
.bb3-recap__aside {
    display: block;
    color: var(--bb3-inkSoft);
    font-size: 0.85rem;
    font-weight: 400;
}
.bb3-recap__hint {
    margin: 16px 0 0;
    color: var(--bb3-inkSoft);
    font-size: 0.9rem;
}
.bb3-recap__link {
    color: var(--bb3-terracotta);
    font-weight: 800;
}
/* Zone de suppression de compte. Séparée du reste par un filet terre cuite et
   posée en bas de page : elle doit être trouvable sans être sur le chemin. */
.bb3-danger {
    margin-top: 24px;
    padding-top: 24px;
    border-top: 3px solid var(--bb3-terracotta);
}
.bb3-danger__title {
    font-family: var(--bb3-fontTitle);
    margin: 0 0 8px;
    font-size: 1.2rem;
    color: var(--bb3-terracotta);
}
.bb3-danger__text {
    margin: 0 0 20px;
    color: var(--bb3-ink);
}
/* Pages de texte : mentions légales, confidentialité. Mesure limitée, et rien
   d'autre — ces pages doivent être lisibles, pas décorées. */
.bb3-prose {
    max-width: 38rem;
    margin: 32px 0 0;
    color: var(--bb3-ink);
}
.bb3-prose__title {
    font-family: var(--bb3-fontTitle);
    margin: 32px 0 8px;
    font-size: 1.25rem;
}
.bb3-prose__text {
    margin: 0 0 16px;
}
.bb3-prose__list {
    margin: 0 0 16px;
    padding-left: 1.2em;
}
.bb3-prose__item {
    margin-bottom: 10px;
}
.bb3-prose__link {
    color: var(--bb3-terracotta);
    font-weight: 800;
}
/* Tableau de bord d'administration. Aucun habillage : c'est un outil de travail,
   pas une page du site. */
.bb3-admin {
    margin: 32px 0 0;
}
.bb3-admin__section {
    margin-bottom: 40px;
}
.bb3-admin__title {
    font-family: var(--bb3-fontTitle);
    margin: 0 0 4px;
    padding-bottom: 8px;
    border-bottom: 3px solid var(--bb3-ink);
    font-size: 1.3rem;
}
.bb3-admin__subtitle {
    margin: 24px 0 8px;
    font-size: 0.95rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
    color: var(--bb3-inkSoft);
}
.bb3-admin__badge {
    display: inline-block;
    margin-left: 8px;
    padding: 2px 8px;
    background: var(--bb3-paperSunk);
    border: 2px solid var(--bb3-inkSoft);
    color: var(--bb3-inkSoft);
    font-family: var(--bb3-fontBody);
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    vertical-align: middle;
}
/* Le tableau défile dans son propre conteneur : sur un téléphone, quatre
   colonnes de chiffres dépassent, et c'est au tableau de défiler — jamais à la
   page. */
.bb3-admin__scroller {
    overflow-x: auto;
}
.bb3-admin__table {
    width: 100%;
    border-collapse: collapse;
    text-align: left;
}
.bb3-admin__head {
    padding: 8px 12px 8px 0;
    border-bottom: 1px solid var(--bb3-line);
    color: var(--bb3-inkSoft);
    font-size: 0.8rem;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: 0.06em;
    white-space: nowrap;
}
.bb3-admin__cell {
    padding: 12px 12px 12px 0;
    border-bottom: 1px solid var(--bb3-line);
    font-family: var(--bb3-fontNotation);
    font-size: 1.1rem;
    white-space: nowrap;
}
.bb3-admin__cell--strong {
    font-size: 1.6rem;
    font-weight: 800;
    color: var(--bb3-terracotta);
}
.bb3-admin__note {
    margin: 8px 0 0;
    color: var(--bb3-inkSoft);
    font-size: 0.85rem;
}
.bb3-admin__muted {
    color: var(--bb3-inkSoft);
    font-weight: 400;
}
/* Bloc de texte courant, posé directement sur la page. Chaque élément porte sa
   classe plutôt que d'être atteint par son nom de balise depuis le bloc : un
   `.bb3-note p` coupleraient le style au balisage. */
.bb3-note {
    color: var(--bb3-ink);
}
.bb3-note__text {
    margin: 0 0 12px;
}
.bb3-note__text--last {
    margin-bottom: 0;
}
.bb3-note__code {
    display: inline-block;
    padding: 8px 12px;
    background: var(--bb3-paperSunk);
    border-radius: var(--bb3-radius);
    font-family: var(--bb3-fontNotation);
    word-break: break-word;
}
.bb3-note__details {
    margin-top: 16px;
    padding-top: 16px;
    border-top: 1px solid var(--bb3-line);
}
.bb3-note__summary {
    font-weight: 800;
    cursor: pointer;
}
.bb3-note__field {
    display: block;
    width: 100%;
    padding: 10px;
    background: var(--bb3-paperSunk);
    border: 1px solid var(--bb3-line);
    border-radius: var(--bb3-radius);
    color: var(--bb3-inkSoft);
    font-family: var(--bb3-fontNotation);
    font-size: 0.85rem;
}
/* Pied de page. La bande qui l'accueille porte déjà le fond et le filet : il ne
   se sépare plus lui-même, il occupe. */
.bb3-siteFooter {
    color: var(--bb3-inkSoft);
    font-size: 0.9rem;
}
.bb3-siteFooter__list {
    display: flex;
    flex-wrap: wrap;
    gap: 16px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.bb3-siteFooter__item {
    flex: initial;
}
