/*
 * theme-socle.css — socle graphique commun aux deux applications
 * (Principe V amendé A5, ADR-009 révisé, ADR-010,
 *  specs/001-preparation-et-acces/contracts/theme-socle.md).
 *
 * COPIÉ À L'IDENTIQUE, octet pour octet, dans app-conseiller/app/static/ et
 * app-recruteur/app/static/ — scripts/verifier-theme-identique.sh (réécrit en
 * T011) échoue si les deux copies divergent.
 *
 * Contenu : échelle typographique, formes, cibles tactiles, réinitialisation,
 * breakpoints, classes de disposition, composants réimplémentés (barre
 * d'application, snackbar, rail, puces). AUCUNE valeur de couleur littérale —
 * seulement la CONSOMMATION des rôles via var(--md-sys-color-*), dont les
 * VALEURS vivent dans palette.css (par persona), chargé AVANT ce fichier.
 *
 * Ce qui ne relève PAS du socle : les valeurs de rôles (palette.css) et le
 * gabarit visuel de smartphone décoratif, propre à app-conseiller
 * (gabarit-smartphone.css).
 */

/* ---------------------------------------------------------------------- *
 * Police Rubik auto-hébergée (T145, annule et remplace le choix de famille
 * de T137 — mécanisme d'auto-hébergement conservé) — fichiers .woff2
 * statiques dans ./polices/, aucun chargement réseau (T020,
 * FR-001-03/SC-001-07). Source : dépôt Google Fonts
 * https://github.com/google/fonts/tree/main/ofl/rubik (licence OFL 1.1,
 * voir polices/LICENCE-rubik.txt), police variable (axe wght) instanciée en
 * 4 graisses statiques réellement consommées par l'échelle typographique
 * ci-dessous et par T146 (400, 500, 600, 700). Arbitrage directeur
 * (2026-09-23, audit § E) : les captures de l'app réelle montrent Rubik, pas
 * Roboto ni Roboto Flex (la maquette se trompait de famille) — rend T143
 * sans objet.
 * ---------------------------------------------------------------------- */
@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("Rubik"), url("polices/rubik-400.woff2") format("woff2");
}

@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("Rubik Medium"), url("polices/rubik-500.woff2") format("woff2");
}

@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local("Rubik SemiBold"), url("polices/rubik-600.woff2") format("woff2");
}

@font-face {
  font-family: "Rubik";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: local("Rubik Bold"), url("polices/rubik-700.woff2") format("woff2");
}

/* ---------------------------------------------------------------------- *
 * Typographie — échelle M3 complète (m3.material.io/styles/typography).
 * Rubik auto-hébergée en premier (ci-dessus, T145), pile de secours système
 * conservée en repli — aucune police distante (ADR-009, Principe I).
 * Convention M3 officielle : quatre variables par style
 * (--md-sys-typescale-<style>-{font,size,line-height,weight}).
 * ---------------------------------------------------------------------- */
:root {
  --md-ref-typeface-brand: Rubik, system-ui, -apple-system, "Segoe UI", sans-serif;
  --md-ref-typeface-plain: Rubik, system-ui, -apple-system, "Segoe UI", sans-serif;

  --md-sys-typescale-display-large-font: var(--md-ref-typeface-brand);
  --md-sys-typescale-display-large-size: 57px;
  --md-sys-typescale-display-large-line-height: 64px;
  --md-sys-typescale-display-large-weight: 400;

  --md-sys-typescale-display-medium-font: var(--md-ref-typeface-brand);
  --md-sys-typescale-display-medium-size: 45px;
  --md-sys-typescale-display-medium-line-height: 52px;
  --md-sys-typescale-display-medium-weight: 400;

  --md-sys-typescale-display-small-font: var(--md-ref-typeface-brand);
  --md-sys-typescale-display-small-size: 24px;
  --md-sys-typescale-display-small-line-height: 32px;
  --md-sys-typescale-display-small-weight: 700;

  --md-sys-typescale-headline-large-font: var(--md-ref-typeface-brand);
  --md-sys-typescale-headline-large-size: 32px;
  --md-sys-typescale-headline-large-line-height: 40px;
  --md-sys-typescale-headline-large-weight: 400;

  --md-sys-typescale-headline-medium-font: var(--md-ref-typeface-brand);
  --md-sys-typescale-headline-medium-size: 28px;
  --md-sys-typescale-headline-medium-line-height: 36px;
  --md-sys-typescale-headline-medium-weight: 400;

  --md-sys-typescale-headline-small-font: var(--md-ref-typeface-brand);
  --md-sys-typescale-headline-small-size: 20px;
  --md-sys-typescale-headline-small-line-height: 26px;
  --md-sys-typescale-headline-small-weight: 700;

  --md-sys-typescale-title-large-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-title-large-size: 19px;
  --md-sys-typescale-title-large-line-height: 26px;
  --md-sys-typescale-title-large-weight: 700;

  --md-sys-typescale-title-medium-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-title-medium-size: 16px;
  --md-sys-typescale-title-medium-line-height: 21px;
  --md-sys-typescale-title-medium-weight: 500;

  --md-sys-typescale-title-small-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-title-small-size: 14px;
  --md-sys-typescale-title-small-line-height: 20px;
  --md-sys-typescale-title-small-weight: 500;

  --md-sys-typescale-body-large-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-body-large-size: 16px;
  --md-sys-typescale-body-large-line-height: 24px;
  --md-sys-typescale-body-large-weight: 400;

  --md-sys-typescale-body-medium-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-body-medium-size: 14px;
  --md-sys-typescale-body-medium-line-height: 20px;
  --md-sys-typescale-body-medium-weight: 400;

  --md-sys-typescale-body-small-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-body-small-size: 13px;
  --md-sys-typescale-body-small-line-height: 18px;
  --md-sys-typescale-body-small-weight: 400;

  --md-sys-typescale-label-large-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-label-large-size: 14px;
  --md-sys-typescale-label-large-line-height: 20px;
  --md-sys-typescale-label-large-weight: 500;

  --md-sys-typescale-label-medium-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-label-medium-size: 12px;
  --md-sys-typescale-label-medium-line-height: 16px;
  --md-sys-typescale-label-medium-weight: 500;

  --md-sys-typescale-label-small-font: var(--md-ref-typeface-plain);
  --md-sys-typescale-label-small-size: 11px;
  --md-sys-typescale-label-small-line-height: 16px;
  --md-sys-typescale-label-small-weight: 500;
}

/* ---------------------------------------------------------------------- *
 * Formes — échelle M3 (m3.material.io/styles/shape).
 * ---------------------------------------------------------------------- */
:root {
  --md-sys-shape-corner-none: 0px;
  --md-sys-shape-corner-extra-small: 4px;
  --md-sys-shape-corner-small: 8px;
  --md-sys-shape-corner-medium: 12px;
  --md-sys-shape-corner-large: 16px;
  --md-sys-shape-corner-extra-large: 28px;
  --md-sys-shape-corner-full: 9999px;
}

/* ---------------------------------------------------------------------- *
 * Cibles tactiles — accessibilité (constitution).
 * ---------------------------------------------------------------------- */
:root {
  --crust-touch-target-min: 48px;
}

/* ---------------------------------------------------------------------- *
 * Élévations — box-shadow M3 (m3.material.io/styles/elevation), tokens de
 * la charte v2 (T009, research.md D3). Exprimées depuis le rôle
 * --md-sys-color-shadow (hex opaque, conservé tel quel — D3), jamais un
 * noir littéral : la maquette utilisait `rgba(<triplet nu> / .30)`, ici
 * `color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent)`, qui a
 * la même valeur numérique tant que --md-sys-color-shadow reste opaque.
 * ---------------------------------------------------------------------- */
:root {
  --md-sys-elevation-1:
    0 1px 2px color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent),
    0 1px 3px 1px color-mix(in srgb, var(--md-sys-color-shadow) 15%, transparent);
  --md-sys-elevation-2:
    0 1px 2px color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent),
    0 2px 6px 2px color-mix(in srgb, var(--md-sys-color-shadow) 15%, transparent);
  --md-sys-elevation-3:
    0 1px 3px color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent),
    0 4px 8px 3px color-mix(in srgb, var(--md-sys-color-shadow) 15%, transparent);
}

/* ---------------------------------------------------------------------- *
 * Mouvement — tokens M3 (m3.material.io/styles/motion), charte v2 (T009,
 * research.md D3). Durées et courbes reprises de la maquette de référence.
 * ---------------------------------------------------------------------- */
:root {
  --md-sys-motion-duration-short4: 150ms;
  --md-sys-motion-duration-medium2: 300ms;
  --md-sys-motion-duration-medium4: 450ms;
  --md-sys-motion-easing-emphasized: cubic-bezier(0.2, 0, 0, 1);
  --md-sys-motion-easing-standard: cubic-bezier(0.2, 0, 0, 1);
  --md-sys-motion-spring: linear(0, 0.009, 0.035 4.2%, 0.141, 0.281 9.1%, 0.683 18%, 0.813, 0.907, 0.963, 0.994, 1);
}

/* ---------------------------------------------------------------------- *
 * Rôles de couleur additionnels de la charte v2 (T009, research.md D3).
 *
 * --md-sys-color-success : indicateur de présence (FR-001-31). Ses VALEURS
 *   (clair et sombre, + on/-container) vivent dans palette.css : elles sont
 *   émises par generate_theme.py à partir de la teinte verte de la charte,
 *   identiques aux deux personas. Le socle ne fait que les consommer.
 * --md-sys-color-chip-time : cible arbitrée (T074/T149, audit du
 *   2026-09-23, § E) — fond clair du chip horaire, convergence captures
 *   réelles + maquette v7 (`workspace-7/…/tokens.css:44-45`). T161 : resync
 *   demandée par le commentaire ci-dessus n'a jamais eu lieu après T154
 *   (régénération Vibrant) — `surface-container-high` (#ebe6f5) s'est
 *   éloigné de la cible mesurée (#f0eff5) une fois la palette régénérée en
 *   Vibrant (plus saturée sur tous les paliers de conteneur) ; `surface-
 *   container` est le rôle le plus proche de cette cible dans la nouvelle
 *   palette (écart total ≈10 vs ≈14 pour `-high`, mesuré composante à
 *   composante). Alias, littéral-free (Principe V) ; à resynchroniser de
 *   nouveau si une future régénération de palette change ce choix.
 * --md-sys-color-outline-strong : cible arbitrée (T074/T153, audit du
 *   2026-09-23, § E) — la maquette de référence ne fournit aucune valeur
 *   propre, mais les captures réelles (filets de liste sombres, ≈ `#25323b`
 *   mesuré) convergent avec la maquette v7 sur un filet plus foncé que
 *   `outline`. Déclaré en ALIAS `var()` d'un rôle M3 existant (littéral-free) :
 *   `on-surface-variant`.
 * ---------------------------------------------------------------------- */
:root {
  --md-sys-color-chip-time: var(--md-sys-color-surface-container);
  --md-sys-color-outline-strong: var(--md-sys-color-on-surface-variant);
}

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

body {
  margin: 0;
  background: var(--md-sys-color-background);
  color: var(--md-sys-color-on-background);
  font-family: var(--md-ref-typeface-plain);
}

/* ---------------------------------------------------------------------- *
 * Breakpoints M3 (ADR-009) : Compact < 600dp · Medium 600-839 ·
 * Expanded 840-1199 · Large >= 1200 (Extra-large traité comme Large).
 * En rendu web, 1dp = 1px (aucune mise à l'échelle d'écran physique ici).
 * ---------------------------------------------------------------------- */

/* ---------------------------------------------------------------------- *
 * Classes de disposition — mises en page canoniques M3 absentes de
 * Material Web Components (ADR-007 conséquence négative, ADR-009).
 *
 * .crust-layout-une-zone      : Compact/Medium, une seule colonne de contenu.
 * .crust-layout-list-detail   : Expanded/Large, deux zones côte à côte
 *                                (liste à gauche, détail à droite).
 * .crust-layout-supporting-pane : Expanded/Large, contenu principal + panneau
 *                                de support (largeur fixe) à droite.
 * ---------------------------------------------------------------------- */
.crust-layout-une-zone {
  display: block;
  max-width: 100%;
  overflow-x: hidden;
}

.crust-layout-list-detail,
.crust-layout-supporting-pane {
  display: block;
  max-width: 100%;
  overflow-x: hidden;
}

@media (min-width: 840px) {
  .crust-layout-list-detail {
    display: grid;
    grid-template-columns: minmax(320px, 1fr) 2fr;
    gap: 24px;
    align-items: start;
  }

  .crust-layout-supporting-pane {
    display: grid;
    grid-template-columns: 1fr minmax(240px, 320px);
    gap: 24px;
    align-items: start;
  }
}

/* Enveloppe rail + contenu (FIX-T057) — à utiliser à la place de
 * `.crust-layout-list-detail`/`.crust-layout-supporting-pane` quand l'écran
 * n'a qu'UNE zone de contenu réelle (ex. une liste) à côté du rail : ces deux
 * autres classes dimensionnent leur première colonne pour un contenu
 * comparable en importance (`minmax(320px, 1fr)`), ce qui est correct pour
 * une vraie deuxième zone mais laisse un vide non fonctionnel si on y loge le
 * rail (80px de large). Le rail garde son affichage propre
 * (`.crust-navigation-rail`, display:none en dessous de 840px) ; seule la
 * mise en page du conteneur change ici. */
.crust-avec-rail {
  display: block;
  max-width: 100%;
  overflow-x: hidden;
}

@media (min-width: 840px) {
  .crust-avec-rail {
    display: flex;
    align-items: stretch;
  }

  .crust-avec-rail > :not(.crust-navigation-rail) {
    flex: 1;
    min-width: 0;
  }
}

/* Barre de navigation en bas (Compact/Medium) devient un rail latéral en
 * Expanded/Large — convention M3. Le composant `<md-navigation-bar>` est
 * disponible (labs) ; le rail n'a pas d'équivalent en composant (T018,
 * theme.md § Composants manquants) et est donc réimplémenté ci-dessous en
 * pur CSS/HTML, avec les mêmes tokens de couleur/forme que la barre. */
.crust-navigation-rail {
  display: none;
}

@media (min-width: 840px) {
  .crust-navigation-bas {
    display: none;
  }

  .crust-navigation-rail {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 12px;
    width: 80px;
    padding-block: 44px;
    background: var(--md-sys-color-surface);
    border-right: 1px solid var(--md-sys-color-outline-variant);
  }

  .crust-navigation-rail .crust-rail-item {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 4px;
    min-width: var(--crust-touch-target-min);
    min-height: var(--crust-touch-target-min);
    padding: 8px 12px;
    border-radius: var(--md-sys-shape-corner-large);
    color: var(--md-sys-color-on-surface-variant);
    font: var(--md-sys-typescale-label-medium-weight) var(--md-sys-typescale-label-medium-size)/var(--md-sys-typescale-label-medium-line-height) var(--md-sys-typescale-label-medium-font);
    text-decoration: none;
    cursor: pointer;
  }

  .crust-navigation-rail .crust-rail-item[aria-current="page"] {
    color: var(--md-sys-color-on-secondary-container);
  }

  .crust-navigation-rail .crust-rail-item[aria-current="page"] .crust-rail-indicator {
    background: var(--md-sys-color-secondary-container);
  }

  .crust-navigation-rail .crust-rail-indicator {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 32px;
    border-radius: var(--md-sys-shape-corner-full);
  }
}

/* ---------------------------------------------------------------------- *
 * Barre d'application (top app bar) — pas de composant `<md-*>` dans
 * @material/web (T018, theme.md § Composants manquants) : réimplémentée en
 * CSS/HTML sur les tokens M3 « small » (m3.material.io/components/top-app-bar).
 * ---------------------------------------------------------------------- */
.crust-top-app-bar {
  display: flex;
  align-items: center;
  gap: 4px;
  /* Demande directeur (gain d'espace vertical, 2026-09-26) : légère réduction
   * depuis 64px, recalée sur la maquette (`.topbar { flex: 0 0 60px; }`,
   * styles.css:131) plutôt qu'une valeur improvisée. */
  min-height: 60px;
  padding-inline: 4px;
  /* T140 (annule le fond teinté posé par T016) : en-tête neutre, comme la
   * maquette (index.html:92, .screen1__head sur var(--md-sys-color-surface))
   * — pas une couleur littérale, ce rôle M3 reste résolu par palette.css de
   * chaque sous-module.
   * T147 (audit du 2026-09-23, § E) : `surface` ne rend pas le blanc pur
   * mesuré sur les captures une fois la palette régénérée (T154, #fdf8ff/
   * #fcf8ff selon le persona) — recalé sur `surface-container-lowest`, qui
   * vaut #ffffff dans les deux palettes. Ombre portée elevation-2 ajoutée,
   * comme la maquette (styles.css:131-138/167-173), absente depuis T140
   * (qui n'avait repris que le fond et la couleur du titre). */
  background: var(--md-sys-color-surface-container-lowest);
  color: var(--md-sys-color-on-surface);
  box-shadow: var(--md-sys-elevation-2);
}

.crust-top-app-bar .crust-top-app-bar-titre {
  flex: 1;
  text-align: left;
  font: var(--md-sys-typescale-title-large-weight) var(--md-sys-typescale-title-large-size)/var(--md-sys-typescale-title-large-line-height) var(--md-sys-typescale-title-large-font);
  /* T140 (annule la casse majuscule posée par T016) : titre en casse
   * normale, comme la maquette (.screen1__title). */
  /* T146 (audit du 2026-09-23, § E) : graisse 500, pas 700 — les captures
   * de l'app réelle contredisent la maquette sur ce point. Le rôle
   * title-large partagé reste à 700 pour ses autres consommateurs (titres
   * de carte et de feuille d'en-tête, cibles à 600) : pas de cible commune,
   * surcharge au niveau du composant plutôt qu'au niveau du rôle. */
  font-weight: 500;
  padding-inline-start: 12px;
}

/* ---------------------------------------------------------------------- *
 * Snackbar — pas de composant `<md-*>` dans @material/web (T018, theme.md
 * § Composants manquants) : réimplémentée en CSS/HTML + `<dialog>` ou zone
 * `aria-live`, sur les tokens M3 (m3.material.io/components/snackbar).
 * L'ombre utilise le token d'élévation --md-sys-elevation-3 (défini plus
 * haut depuis le rôle --md-sys-color-shadow, pas de noir littéral).
 * ---------------------------------------------------------------------- */
.crust-snackbar {
  position: fixed;
  left: 50%;
  bottom: 24px;
  transform: translateX(-50%);
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: var(--crust-touch-target-min);
  max-width: min(90vw, 560px);
  padding: 8px 8px 8px 16px;
  border-radius: var(--md-sys-shape-corner-extra-small);
  background: var(--md-sys-color-inverse-surface);
  color: var(--md-sys-color-inverse-on-surface);
  font: var(--md-sys-typescale-body-medium-weight) var(--md-sys-typescale-body-medium-size)/var(--md-sys-typescale-body-medium-line-height) var(--md-sys-typescale-body-medium-font);
  box-shadow: var(--md-sys-elevation-3);
}

/* ---------------------------------------------------------------------- *
 * Puces M3 (assistives/tonales) et bouton chevron des cartes d'accueil,
 * repris à l'identique de la maquette de référence
 * (cahier-des-charges/workspace/app-m3-evenements/css/styles.css, règles
 * .chip / .chip--tonal / .icon-btn--filled) — revue graphique du
 * 2026-09-09 : l'existant sert de base, la fonctionnalité cible s'y ajoute
 * sans le réinventer.
 * ---------------------------------------------------------------------- */
.crust-carte-ligne {
  display: flex;
  align-items: center;
  gap: 8px;
}

.crust-chip {
  height: 32px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  border-radius: var(--md-sys-shape-corner-small);
  font: var(--md-sys-typescale-label-large-weight) 13px/var(--md-sys-typescale-label-large-line-height) var(--md-sys-typescale-label-large-font);
  white-space: nowrap;
}

.crust-chip svg {
  width: 17px;
  height: 17px;
  flex: none;
}

.crust-chip--tonal {
  background: var(--md-sys-color-secondary-container);
  color: var(--md-sys-color-primary);
}

.crust-chip--outline {
  background: transparent;
  border: 1px solid var(--md-sys-color-outline-variant);
  color: var(--md-sys-color-on-surface-variant);
}

/* T149 (3) : chip horaire neutre (audit du 2026-09-23, § E) — fond clair
 * `chip-time`, texte/icône `on-surface`, remplaçant les deux traitements
 * divergents posés jusqu'ici (tonal lavande sur l'accueil, outline sur le
 * détail). */
.crust-chip--time {
  background: var(--md-sys-color-chip-time);
  color: var(--md-sys-color-on-surface);
}

.crust-chip--compte {
  font-weight: 500;
}

.crust-icon-chevron {
  margin-left: auto;
  width: 36px;
  height: 36px;
  flex: none;
  display: inline-grid;
  place-items: center;
  border-radius: var(--md-sys-shape-corner-full);
  background: var(--md-sys-color-primary);
  color: var(--md-sys-color-on-primary);
}

.crust-icon-chevron svg {
  width: 20px;
  height: 20px;
}
