/* =====================================================================
   Tirage — feuille de style unique.

   CHARTE REPRISE DE « TOUTES NOS COULEURS » (touteslescouleurs.local),
   à la demande de Fabien. Le parti pris y était : la page s'efface.
   Niveaux de gris stricts, aucune ombre, rayons de 3 px, une barre
   d'en-tête sombre, un bouton plein foncé, des alertes à filet gauche.

   Il vaut ici pour une autre raison, mais il vaut : ce que le visiteur
   doit lire, c'est l'élément qui vient de lui être attribué. Une
   interface colorée lui disputerait le regard.

   Tout est écrit en VARIABLES (--bg / --fg / --border / --font). C'est ce
   qui permet au back-office de rebasculer en sombre en les redéfinissant,
   sans surcharger un seul composant (voir admin/assets/admin.css).
   ===================================================================== */

/* --- Police du site : Social Gothic --------------------------------
   Fournie en OTF, ~29 Ko par graisse. `font-display: swap` : le texte
   s'affiche tout de suite dans la police de repli puis bascule — jamais
   de texte invisible pendant le téléchargement. */
@font-face {
    font-family: "Social Gothic";
    src: url("../fonts/social-gothic-regular.otf") format("opentype");
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Social Gothic";
    src: url("../fonts/social-gothic-medium.otf") format("opentype");
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Social Gothic";
    src: url("../fonts/social-gothic-demibold.otf") format("opentype");
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: "Social Gothic";
    src: url("../fonts/social-gothic-bold.otf") format("opentype");
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

:root {
    /* Fond crème plutôt que blanc pur (moins agressif), texte gris très
       foncé plutôt que noir (moins tranchant à la lecture longue). */
    --bg: #eeedea;
    --bg-soft: #ffffff;
    --fg: #1a1a1a;
    --fg-dim: #6a6a6a;
    --border: #d9d4c8;
    --focus: #1a1a1a;

    /* Contexte sombre : la barre d'en-tête et le back-office. Tous deux ont
       leur raison d'être sombres — l'une encadre la page, l'autre est un
       outil interne. */
    --bg-dark: #0d0d0d;
    --bg-dark-soft: #171717;
    --fg-on-dark: #f2f2f2;
    --fg-dim-on-dark: #8c8c8c;
    --border-on-dark: #2a2a2a;

    --font: "Social Gothic", "Helvetica Neue", Helvetica, Arial, sans-serif;
    /* Police neutre pour les contenus longs et pour le back-office : une
       police d'affichage y fatigue et n'apporte rien. */
    --font-reading: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
    --max-width: 720px;
}

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

/* L'attribut `hidden` doit TOUJOURS l'emporter.
   Le navigateur ne lui applique `display: none` que via sa feuille par
   défaut : n'importe quelle règle d'auteur posant un `display` (un
   `display: grid` sur un conteneur, par exemple) gagne en spécificité et
   laisse l'élément à l'écran alors que le code le croit caché. Le bug est
   silencieux et se rejoue à chaque nouveau composant. On le ferme ici, une
   fois, au lieu de répéter un `.machin[hidden]` par cas. */
[hidden] {
    display: none !important;
}

html {
    -webkit-text-size-adjust: 100%;
    scrollbar-gutter: stable;
}

body {
    margin: 0;
    min-height: 100vh;
    background: var(--bg);
    color: var(--fg);
    font-family: var(--font-reading);
    font-size: 16px;
    line-height: 1.6;
    -webkit-font-smoothing: antialiased;
}

/* Le front controller écrit data-open. Un seul attribut décide lequel des deux
   blocs (formulaire / message de fermeture) existe à l'écran : pas de bascule
   en JavaScript, donc pas de clignotement au chargement. */
body[data-open="1"] #closed-card { display: none; }
body[data-open="0"] #form-card { display: none; }

a {
    color: var(--fg);
    text-underline-offset: 3px;
}

/* Visible au clavier uniquement : un contour permanent parasiterait la
   page, mais sans lui la navigation au clavier devient impossible. */
:focus-visible {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

/* ---------------------------------------------------------------------
   En-tête
   --------------------------------------------------------------------- */

.site-header {
    display: flex;
    flex-wrap: wrap;
    gap: 1rem 2rem;
    align-items: baseline;
    justify-content: space-between;
    padding: 1.5rem 1.5rem 1rem;
    /* Garde la police d'affichage même quand le corps de page est en police
       système : c'est un élément d'identité, constant d'une page à l'autre. */
    font-family: var(--font);
    background: var(--bg-dark);
    color: var(--fg-on-dark);
}

/* Dans la barre, les liens reprennent le contexte sombre : la règle globale
   `a { color: var(--fg) }` viserait un texte foncé illisible. */
.site-header a {
    color: var(--fg-on-dark);
}

.site-title {
    margin: 0;
    font-size: 1.1rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.site-title a {
    text-decoration: none;
}

.site-nav {
    display: flex;
    gap: 1.5rem;
    font-size: 0.9rem;
}

.site-nav a {
    color: var(--fg-dim-on-dark);
    text-decoration: none;
    transition: color 0.15s;
}

.site-nav a:hover {
    color: var(--fg-on-dark);
}

/* ---------------------------------------------------------------------
   Page
   --------------------------------------------------------------------- */

.page {
    max-width: var(--max-width);
    margin: 0 auto;
    padding: 2rem 1.5rem 6rem;
}

.page h1 {
    margin-top: 0;
    font-size: 1.6rem;
}

.page h2 {
    margin-top: 2.5rem;
    font-size: 1.1rem;
}

.lede {
    font-size: 1.05rem;
}

.muted {
    color: var(--fg-dim);
    font-size: 0.9rem;
}

hr {
    margin: 2.5rem 0;
    border: 0;
    border-top: 1px solid var(--border);
}

/* Texte riche venu du back-office. */
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose :is(p, li) { color: #2b2b2b; }
.prose h2 { margin: 1.75rem 0 0.5rem; font-size: 1.1rem; }
.prose h3 { margin: 1.5rem 0 0.5rem; font-size: 0.95rem; color: var(--fg-dim); }
.prose ul, .prose ol { padding-left: 1.2rem; }

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

.fields {
    display: grid;
    gap: 0 1rem;
    grid-template-columns: 1fr 1fr;
}

@media (max-width: 32rem) {
    .fields { grid-template-columns: 1fr; }
}

.field {
    margin-bottom: 1rem;
}

.field label {
    display: block;
    margin-bottom: 0.35rem;
    font-size: 0.9rem;
}

.field__hint {
    margin: 0.35rem 0 0;
    color: var(--fg-dim);
    font-size: 0.8rem;
}

input[type="text"],
input[type="email"],
input[type="password"],
input[type="search"],
input[type="number"],
select,
textarea {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 3px;
    background: var(--bg-soft);
    color: var(--fg);
    font-family: inherit;
    /* 16 px minimum : en dessous, iOS zoome sur le champ au focus et le
       visiteur se retrouve avec une page décadrée. */
    font-size: 1rem;
}

input:focus,
select:focus,
textarea:focus {
    border-color: var(--fg-dim);
}

input[aria-invalid="true"] {
    border-color: #e05252;
}

textarea {
    line-height: 1.55;
    resize: vertical;
}

textarea.mono {
    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
    font-size: 0.85rem;
}

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

.btn {
    position: relative;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    padding: 0.7rem 1.4rem;
    border: 1px solid var(--fg);
    border-radius: 3px;
    background: var(--fg);
    color: var(--bg);
    font-family: inherit;
    font-size: 0.95rem;
    font-weight: 500;
    line-height: 1.2;
    cursor: pointer;
    transition: opacity 0.15s;
}

.btn:hover:not(:disabled) { opacity: 0.85; }

.btn:disabled { opacity: 0.4; cursor: not-allowed; }

/* `.btn` EST déjà le bouton d'action plein : --primary n'a rien à ajouter.
   La classe reste dans le balisage pour dire l'intention, et pour que le
   jour où la charte distinguerait les deux, il n'y ait qu'ici à changer. */
.btn--primary { }

.btn--ghost {
    border-color: var(--border);
    background: transparent;
    color: var(--fg);
}

.btn--danger {
    border-color: #e05252;
    background: transparent;
    color: #e05252;
}

.btn--small {
    padding: 0.4rem 0.8rem;
    font-size: 0.85rem;
}

.btn--block { width: 100%; }

/* Attente : le libellé s'efface au profit du disque, sans que le bouton
   change de taille. Un bouton qui rétrécit pendant l'envoi fait sauter la
   mise en page au moment précis où l'on regarde le résultat. */
.btn__spinner { display: none; }

.btn.is-busy .btn__label { visibility: hidden; }

.btn.is-busy .btn__spinner {
    display: block;
    position: absolute;
    width: 1.05em;
    height: 1.05em;
    border: 2px solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spin 0.6s linear infinite;
}

@keyframes spin { to { transform: rotate(360deg); } }

@media (prefers-reduced-motion: reduce) {
    .btn.is-busy .btn__spinner { animation-duration: 1.6s; }
}

/* ---------------------------------------------------------------------
   Alertes
   --------------------------------------------------------------------- */

.alert {
    margin-bottom: 1.5rem;
    padding: 0.9rem 1rem;
    border: 1px solid var(--border);
    border-left-width: 3px;
    border-radius: 3px;
    background: var(--bg-soft);
    font-size: 0.9rem;
}

.alert--error { border-left-color: #e05252; }
.alert--success { border-left-color: #4caf7d; }
.alert--warning { border-left-color: #d8a33a; }

/* ---------------------------------------------------------------------
   Popup de résultat
   --------------------------------------------------------------------- */

.modal {
    width: min(32rem, calc(100vw - 2rem));
    max-height: calc(100vh - 2rem);
    padding: 0;
    border: 1px solid var(--border);
    border-radius: 3px;
    background: var(--bg-soft);
    color: var(--fg);
    font-family: var(--font-reading);
}

.modal::backdrop {
    background: rgba(13, 13, 13, 0.6);
}

/* Colonne à hauteur bornée : seul le corps défile, l'en-tête et le bouton de
   validation restent visibles. Sur un mobile avec six thèmes, un défilement
   de la boîte entière ferait disparaître le bouton hors de l'écran. */
.modal__inner {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 2rem);
}

.modal__head {
    position: relative;
    padding: 1.25rem 3rem 1.1rem 1.25rem;
    border-bottom: 1px solid var(--border);
    /* La popup est le moment où le tirage se dévoile : elle porte la police
       d'affichage, comme la barre d'en-tête. */
    font-family: var(--font);
}

.modal__kicker {
    margin: 0 0 0.15rem;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-dim);
}

.modal__title {
    margin: 0;
    font-size: 1.3rem;
    font-weight: 600;
}

.modal__close {
    position: absolute;
    top: 0.9rem;
    right: 0.9rem;
    width: 2rem;
    height: 2rem;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 3px;
    background: transparent;
    color: var(--fg-dim);
    font-size: 1.5rem;
    line-height: 1;
    cursor: pointer;
}

.modal__close:hover { background: var(--bg); color: var(--fg); }

.modal__body { padding: 1.25rem; overflow-y: auto; }

.modal__foot {
    padding: 1.1rem 1.25rem 1.25rem;
    border-top: 1px solid var(--border);
    background: var(--bg);
}

.modal__warning {
    margin: 0 0 0.8rem;
    font-size: 0.85rem;
    line-height: 1.5;
    color: var(--fg-dim);
}

.modal__success { margin-top: 1.25rem; }

.choice-hint {
    margin: 0 0 1rem;
    padding: 0.5rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 3px;
    font-size: 0.85rem;
    text-align: center;
}

/* ---------------------------------------------------------------------
   Les cartes de thèmes
   --------------------------------------------------------------------- */

.draw { list-style: none; margin: 0; padding: 0; display: grid; gap: 0.75rem; }

/* Fond crème dans une popup blanche : les cartes se détachent sans qu'on
   ait à leur ajouter une ombre, que la charte s'interdit. C'est le même
   couple que le pied de popup. */
.draw__item {
    padding: 0.9rem 1rem;
    border: 1px solid var(--border);
    border-radius: 3px;
    background: var(--bg);
}

.draw__head { margin-bottom: 0.35rem; }

.draw__theme {
    margin: 0;
    font-size: 0.75rem;
    font-weight: 600;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--fg-dim);
}

.draw__desc { margin: 0.15rem 0 0; font-size: 0.8rem; color: var(--fg-dim); }
.draw__desc:empty { display: none; }

/* L'élément retenu est LE contenu de la page une fois le tirage validé :
   c'est le seul endroit où la police d'affichage passe en grande taille. */
.draw__value {
    margin: 0;
    font-family: var(--font);
    font-size: 1.35rem;
    font-weight: 600;
    line-height: 1.25;
    animation: pop 0.3s ease-out;
}

@keyframes pop {
    from { opacity: 0; transform: translateY(-4px); }
    to { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
    .draw__value { animation: none; }
}

.draw__note {
    margin: 0.6rem 0 0;
    font-size: 0.8rem;
    color: var(--fg-dim);
}

/* ---------------------------------------------------------------------
   Les propositions

   Un <fieldset> dépouillé de son apparence native : sans ce triplet
   border/margin/padding à zéro, le navigateur dessine son propre cadre,
   qui redouble celui de la carte et ne suit aucune variable de la charte.
   --------------------------------------------------------------------- */

.draw__options {
    display: grid;
    gap: 0.4rem;
    margin: 0;
    padding: 0;
    border: 0;
}

/* Toute la ligne est cliquable, pas seulement le petit rond : sur mobile,
   viser un radio de 16 px est une cible que la moitié des gens manquent. */
.option {
    display: flex;
    align-items: center;
    gap: 0.6rem;
    padding: 0.6rem 0.75rem;
    border: 1px solid var(--border);
    border-radius: 3px;
    background: var(--bg-soft);
    cursor: pointer;
}

.option:hover { border-color: var(--fg-dim); }

.option__input {
    flex: none;
    margin: 0;
    /* Le rond suit la couleur du texte plutôt que le bleu du système : c'est
       la seule teinte que la charte s'autorise. */
    accent-color: var(--fg);
}

.option__label {
    font-family: var(--font);
    font-size: 1.05rem;
    font-weight: 500;
    line-height: 1.3;
}

/* La proposition retenue. Le fond foncé la sort du lot sans ombre ni
   couleur d'accent : c'est le même vocabulaire que le bouton d'action.
   :has() permet de teindre le label DEPUIS l'état de l'input qu'il
   contient, ce qu'aucun sélecteur ne savait faire avant lui. */
.option:has(.option__input:checked) {
    border-color: var(--fg);
    background: var(--fg);
    color: var(--bg-soft);
}

.option:has(.option__input:checked) .option__input {
    accent-color: var(--bg-soft);
}

/* Le focus vit sur le LABEL, pas sur l'input : l'input est de taille
   dérisoire et son contour, à peine visible, se perdrait contre le bord de
   la carte. C'est la ligne entière qui doit s'annoncer au clavier. */
.option:has(.option__input:focus-visible) {
    outline: 2px solid var(--focus);
    outline-offset: 2px;
}

/* Le temps de l'aller-retour serveur. Discret volontairement : le choix est
   déjà coché à l'écran, ce n'est pas une attente, c'est une confirmation. */
.draw.is-saving { opacity: 0.75; }

/* Masqué à l'œil, lu par les lecteurs d'écran. Sert à la légende de chaque
   groupe de propositions, qui répète le nom du thème déjà affiché juste
   au-dessus : redondant à l'écran, indispensable à l'oreille. */
.visually-hidden {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip-path: inset(50%);
    white-space: nowrap;
}
