/* Cedule, administration. Identite « L'Acte ».

   Le nom vient du vieux francais, du latin `schedula` : un ecrit bref, et en droit l'acte
   sous seing prive. Tout le vocabulaire visuel suit ce fil : le velin, l'encre, le filet
   d'un point, les petites capitales gravees, et le chiffre en colonne.

   CONTRASTES MESURES ET NON JUGES A L'OEIL, tous conformes WCAG 2.2 AA pour du texte :
   encre sur velin 15,63:1 ; encre sur feuille 16,90:1 ; attenue sur feuille 6,83:1 ;
   accent sur feuille 6,95:1 ; rubrique sur feuille 7,65:1 ; feuille sur accent 6,95:1.
*/

@import url('https://cdn.breizhzion.com/fonts/cedule-fonts.css');

:root {
  --velin:      #f3ede1;
  --feuille:    #faf6ee;
  --encre:      #171512;
  --attenue:    #5c554a;
  --accent:     #2f5d50;
  --rubrique:   #8f2c1d;
  --trait:      rgba(23, 21, 18, 0.16);
  --trait-fort: rgba(23, 21, 18, 0.38);

  --mesure: 34rem;
  --marge: 15rem;
  --rythme: 1.6rem;

  --titre: 'IM Fell English SC', 'Cinzel', Georgia, serif;
  --texte: 'EB Garamond', Georgia, 'Times New Roman', serif;
  --chiffre: 'Fragment Mono', ui-monospace, 'SFMono-Regular', monospace;
}

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

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

body {
  margin: 0;
  min-height: 100vh;
  background-color: var(--velin);
  /* Papier regle, tres pale : c'est l'unique texture de l'interface, et elle reste sous
     la feuille pour ne jamais passer derriere du texte. */
  background-image: repeating-linear-gradient(
    to bottom,
    transparent 0,
    transparent 27px,
    rgba(23, 21, 18, 0.045) 27px,
    rgba(23, 21, 18, 0.045) 28px
  );
  color: var(--encre);
  font-family: var(--texte);
  font-size: 1.125rem;
  line-height: 1.6;
}

/* --- Mise en page : une marge, comme celle d'un acte --------------------------- */

.page {
  display: grid;
  grid-template-columns: var(--marge) minmax(0, 1fr);
  gap: 0;
  min-height: 100vh;
}

.marge {
  border-right: 1px solid var(--trait-fort);
  padding: calc(var(--rythme) * 2) var(--rythme);
  position: sticky;
  top: 0;
  align-self: start;
  height: 100vh;
}

/* Le cadran est peint par un masque : un SVG chargé en balise `img` n'hérite pas de
   `currentColor` et garderait son noir pur. */
.cadran {
  /* ⚠️ Plus de `vertical-align` a valeur magique : il calait le cadran a l'oeil pour UNE
     taille de police et se decalait des qu'elle changeait. L'alignement est desormais fait par
     la boite englobante, qui centre les deux sur leur axe quelle que soit la taille. */
  display: block;
  flex: none;
  width: 1.5rem;
  height: 1.5rem;
  background-color: currentColor;
  -webkit-mask: var(--source) center / contain no-repeat;
  mask: var(--source) center / contain no-repeat;
}

.signature {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  flex-wrap: wrap;
  font-family: var(--titre);
  font-size: 1.75rem;
  letter-spacing: 0.06em;
  margin: 0;
  line-height: 1;
}

/* Le double filet sous la signature. Detail emprunte aux actes imprimes : un trait epais
   double d'un trait fin, jamais deux traits egaux. */
.signature::after {
  content: '';
  /* Force le filet sur sa propre ligne : element de flex, il se placerait sinon a
     cote du titre au lieu de passer dessous. */
  flex: 0 0 100%;
  display: block;
  margin-top: 0.7rem;
  height: 3px;
  border-top: 2px solid var(--encre);
  border-bottom: 1px solid var(--encre);
}

.devise {
  font-size: 0.82rem;
  color: var(--attenue);
  font-style: italic;
  margin: 0.8rem 0 0;
}

.navigation { margin-top: calc(var(--rythme) * 2); }

.navigation ul { list-style: none; margin: 0; padding: 0; }

.navigation a {
  display: block;
  padding: 0.55rem 0;
  color: var(--encre);
  text-decoration: none;
  border-bottom: 1px solid var(--trait);
  font-variant-numeric: tabular-nums;
  /* 44 px de haut au minimum : le critere 2.5.8 de WCAG 2.2 en exige 24, on vise la
     cible confortable et non le plancher. */
  min-height: 44px;
  display: flex;
  align-items: center;
  transition: padding-left 140ms ease, color 140ms ease;
}

.navigation a:hover { padding-left: 0.5rem; color: var(--accent); }

.navigation a[aria-current='page'] {
  color: var(--accent);
  font-weight: 600;
}

.navigation a[aria-current='page']::before {
  content: '\203A';
  margin-right: 0.4rem;
  font-family: var(--chiffre);
}

.contenu {
  /* Deuxieme ceinture contre le meme piege que la grille : sans cela, tout descendant
     trop large (un tableau, un <pre>, une URL sans espace) repousse le conteneur. */
  min-width: 0;
  padding: calc(var(--rythme) * 2.5) calc(var(--rythme) * 2);
  max-width: calc(var(--mesure) + 22rem);
}

/* --- La feuille --------------------------------------------------------------- */

.feuille {
  background: var(--feuille);
  border: 1px solid var(--trait-fort);
  padding: calc(var(--rythme) * 1.6);
  margin-bottom: var(--rythme);
  box-shadow: 0 1px 0 rgba(23, 21, 18, 0.06), 0 12px 28px -22px rgba(23, 21, 18, 0.6);
}

/* Revelation echelonnee au chargement. Un seul moment orchestre vaut mieux que des
   micro-animations dispersees. Le delai est pose par l'attribut de position pour eviter
   une regle par element. */
.feuille { animation: paraitre 420ms cubic-bezier(0.2, 0.7, 0.3, 1) backwards; }
.feuille:nth-of-type(1) { animation-delay: 40ms; }
.feuille:nth-of-type(2) { animation-delay: 110ms; }
.feuille:nth-of-type(3) { animation-delay: 180ms; }
.feuille:nth-of-type(4) { animation-delay: 250ms; }

@keyframes paraitre {
  from { opacity: 0; transform: translateY(10px); }
  to   { opacity: 1; transform: none; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}

/* --- Titres ------------------------------------------------------------------- */

h1, h2, h3 {
  font-family: var(--titre);
  font-weight: 400;
  letter-spacing: 0.04em;
  line-height: 1.15;
  margin: 0 0 0.9rem;
}

h1 { font-size: 2.4rem; }
h2 { font-size: 1.45rem; }
h3 { font-size: 1.1rem; }

.intitule {
  font-family: var(--titre);
  font-size: 0.78rem;
  letter-spacing: 0.14em;
  color: var(--attenue);
  display: block;
  margin-bottom: 0.3rem;
}

p { margin: 0 0 var(--rythme); max-width: var(--mesure); }
p:last-child { margin-bottom: 0; }

.discret { color: var(--attenue); font-size: 0.95rem; }

/* --- Le chiffre --------------------------------------------------------------- */

.chiffre, time, td.heure, .cle {
  font-family: var(--chiffre);
  font-variant-numeric: tabular-nums;
  font-size: 0.95em;
  letter-spacing: -0.01em;
}

/* --- Tables : un registre ------------------------------------------------------ */

table { width: 100%; border-collapse: collapse; margin: 0; }

th {
  font-family: var(--titre);
  font-weight: 400;
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  color: var(--attenue);
  text-align: left;
  padding: 0 0.6rem 0.5rem 0;
  border-bottom: 1px solid var(--trait-fort);
}

td {
  padding: 0.7rem 0.6rem 0.7rem 0;
  border-bottom: 1px solid var(--trait);
  vertical-align: baseline;
}

tbody tr:last-child td { border-bottom: none; }

/* --- Formulaires --------------------------------------------------------------- */

label { display: block; margin-bottom: 1.1rem; max-width: var(--mesure); }

label > span {
  font-family: var(--titre);
  font-size: 0.78rem;
  letter-spacing: 0.12em;
  color: var(--attenue);
  display: block;
  margin-bottom: 0.3rem;
}

input[type='text'], input[type='email'], input[type='number'],
input[type='time'], input[type='date'], select, textarea {
  width: 100%;
  min-height: 44px;
  padding: 0.5rem 0.7rem;
  font-family: var(--texte);
  font-size: 1rem;
  color: var(--encre);
  background: transparent;
  border: none;
  /* Un seul filet sous le champ, comme une ligne a remplir sur un formulaire imprime.
     La bordure complete alourdirait la page et trahirait le vocabulaire. */
  border-bottom: 1px solid var(--trait-fort);
  border-radius: 0;
}

input[type='number'], input[type='time'] { font-family: var(--chiffre); }

.champs { display: grid; grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr)); gap: 0 1.4rem; }

/* ⚠️ Quand le libelle et le champ sont deux ENFANTS distincts de la grille, et non un champ
   imbrique dans son libelle, le champ perd la marge basse que `label` lui donnait : le libelle
   suivant venait alors se coller sous le champ precedent, et on ne savait plus lequel allait
   avec lequel. */
.champs > input, .champs > select, .champs > textarea { margin-bottom: 1.1rem; }

/* --- Actions ------------------------------------------------------------------- */

.bouton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0.55rem 1.4rem;
  font-family: var(--titre);
  font-size: 0.86rem;
  letter-spacing: 0.1em;
  color: var(--feuille);
  background: var(--accent);
  border: 1px solid var(--accent);
  cursor: pointer;
  text-decoration: none;
  transition: transform 120ms ease, box-shadow 120ms ease;
}

.bouton:hover { transform: translateY(-1px); box-shadow: 0 4px 12px -6px rgba(23, 21, 18, 0.7); }
.bouton:active { transform: none; }

.bouton.discrete { background: transparent; color: var(--accent); }

/* Un bouton d'action posé dans une cellule de tableau : assez petit pour ne pas écraser la
   ligne, mais jamais en dessous de 44 px de haut, qui reste la cible confortable. */
.bouton.petit {
  padding: 0.3rem 0.9rem;
  min-height: 34px;
  font-size: 0.74rem;
}
.bouton.rubrique { background: var(--rubrique); border-color: var(--rubrique); }

/* Focus visible et genereux. Critere 2.4.13 de WCAG 2.2 : l'indicateur doit faire au
   moins deux points d'epaisseur et contraster avec ce qu'il entoure. */
a:focus-visible, button:focus-visible, input:focus-visible,
select:focus-visible, textarea:focus-visible, [tabindex]:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
}

.saut-au-contenu {
  position: absolute;
  left: -9999px;
  background: var(--accent);
  color: var(--feuille);
  padding: 0.7rem 1.2rem;
}
.saut-au-contenu:focus { left: 1rem; top: 1rem; z-index: 10; }

/* --- Messages ------------------------------------------------------------------ */

.message {
  border-left: 3px solid var(--accent);
  padding: 0.7rem 1rem;
  margin-bottom: var(--rythme);
  background: rgba(47, 93, 80, 0.07);
}
.message.probleme { border-left-color: var(--rubrique); background: rgba(143, 44, 29, 0.07); }

/* --- Etroit --------------------------------------------------------------------- */

@media (max-width: 62rem) {
  /* ⚠️ `minmax(0, 1fr)` et NON `1fr`. Un element de grille a `min-width: auto` par defaut,
     donc une colonne en `1fr` refuse de devenir plus etroite que son contenu : un tableau
     large elargit la colonne, puis la page entiere. Le symptome n'est pas un tableau coupe,
     c'est une page qui s'ouvre DEZOOMEE sur telephone, le navigateur reduisant l'echelle
     pour faire tenir l'element le plus large. La grille large (ligne 60) avait deja le
     minmax, celle-ci l'avait perdu. */
  .page { grid-template-columns: minmax(0, 1fr); }
  .marge { position: static; height: auto; border-right: none; border-bottom: 1px solid var(--trait-fort); }
  .navigation ul { display: flex; flex-wrap: wrap; gap: 0 1.2rem; }
  .navigation a { border-bottom: none; }
  .contenu { padding: var(--rythme); }
}

/* Un tableau ne se comprime pas indefiniment : passe une certaine largeur il doit defiler.
   ⚠️ On NE met PAS `display: block` sur <table>, qui est la recette courante : elle casse la
   semantique de tableau pour les lecteurs d'ecran. Une region avec `tabindex="0"` la preserve
   et reste atteignable au clavier, ce qu'un simple `overflow: auto` ne garantit pas. */
.defilante { overflow-x: auto; }
.defilante:focus-visible { outline: 2px solid var(--rubrique); outline-offset: 3px; }

/* --- Telephone ------------------------------------------------------------------ */

@media (max-width: 48rem) {
  body { font-size: 1rem; }
  .contenu { padding: var(--rythme) 1rem; }
  .feuille { padding: 1.1rem 1rem; }
  h1 { font-size: 1.9rem; }

  /* Les tableaux gardent une largeur lisible et defilent, plutot que d'ecraser les colonnes
     jusqu'a rendre chaque mot vertical. */
  .defilante table { min-width: 34rem; }
  th, td { padding: .7rem .6rem; }

  /* Cible tactile : 44 px de haut, sous peine de boutons qu'on rate une fois sur deux. */
  .bouton, button, input[type='text'], input[type='email'], input[type='number'],
  input[type='time'], input[type='date'], input[type='tel'], select {
    min-height: 2.75rem;
  }
  .bouton.petit { min-height: 2.25rem; }

  /* Les champs passent sur une seule colonne : deux champs de 12rem cote a cote sur un
     telephone donnent deux champs illisibles. */
  .champs { grid-template-columns: 1fr; }
  p, label { max-width: none; }

  /* Le bloc de code et le champ d'URL ne doivent pas elargir la page entiere. */
  pre { font-size: .78rem; }
  .ligne-copie { flex-wrap: wrap; }
}

/* Le champ d'adresse et son bouton, cote a cote tant qu'il y a la place. */
.a-copier { margin-bottom: 1.2rem; max-width: none; }
.a-copier label { margin-bottom: .3rem; }
.ligne-copie { display: flex; gap: .6rem; align-items: stretch; }
.ligne-copie input { flex: 1 1 18rem; margin: 0; font-family: var(--chiffre); font-size: .9rem; }
.ligne-copie .bouton { white-space: nowrap; }

/* Case a cocher : elle n'etait dans aucune regle, donc rendue a sa taille native, soit un
   point de quelques pixels qu'on ne vise pas au doigt. Le libelle est a cote et non dedans,
   sinon `label > span` lui applique les petites capitales reservees aux intitules de champ. */
.bascule { display: flex; align-items: center; gap: .7rem; margin-bottom: .6rem; }
.bascule input[type='checkbox'], .bascule input[type='radio'] {
  flex: none;
  width: 1.35rem;
  height: 1.35rem;
  margin: 0;
  accent-color: var(--rubrique);
}
.bascule label {
  margin: 0;
  max-width: none;
  font-family: inherit;
  font-size: 1rem;
  letter-spacing: 0;
  color: var(--encre);
  cursor: pointer;
}

/* Le titre d'un bloc de code et son bouton de copie sur la meme ligne, le bouton pousse a
   droite. En dessous de 48rem ils passent l'un sous l'autre plutot que de se comprimer. */
.ligne-titre { display: flex; align-items: baseline; gap: 1rem; flex-wrap: wrap; }
.ligne-titre h3 { margin: 0; }
.ligne-titre .bouton { margin-left: auto; }

/* Le bouton de sommaire n'existe que sur telephone : au-dela du seuil, le volet est toujours
   visible et un bouton qui ouvrirait ce qui est deja ouvert n'a pas de sens. */
.bascule-menu { display: none; }

@media (max-width: 48rem) {
  .bascule-menu {
    display: inline-flex;
    /* ⚠️ `center` et surtout PAS `baseline`. Avec `baseline` et une hauteur minimale, la
       ligne de base se pose en HAUT de la boite : le libelle flottait dans la moitie
       superieure du bouton, avec tout le vide en dessous. Le defaut ne se voit pas en
       relisant la regle, il se voit en regardant le bouton. */
    align-items: center;
    justify-content: center;
    gap: .5rem;
    /* Pousse a droite de la ligne du titre, dont il est le dernier element. */
    margin-left: auto;
    /* Carre de 2.75rem au minimum : c'est la cible tactile de 44 px recommandee, et elle
       vaut dans les DEUX dimensions, pas seulement en hauteur. */
    min-height: 2.75rem;
    padding: 0 1rem;
    background: none;
    /* Un filet d'un point, comme tous les traits de cette interface. Pas d'ombre, pas d'angle
       arrondi : rien de tout cela n'existe sur un acte. */
    border: 1px solid var(--trait-fort);
    color: var(--encre);
    font-family: var(--titre);
    font-size: .78rem;
    line-height: 1;
    letter-spacing: .14em;
    text-transform: uppercase;
    cursor: pointer;
  }

  /* ⚠️ Le `letter-spacing` s'ajoute APRES chaque caractere, y compris le dernier : le libelle
     traine donc un blanc de .14em a sa droite que rien ne compense a gauche, et l'ensemble
     parait cale vers la gauche dans un bouton par ailleurs symetrique. On reprend ce blanc
     pour que le centrage soit OPTIQUE et pas seulement arithmetique. */
  .bascule-menu .intitule-menu { margin-right: -.14em; }

  /* Le chevron pivote d'un quart de tour : c'est le seul mouvement du bouton, et il dit
     exactement ce qui se passe, la liste passant de fermee a deroulee. Il vit dans un carre
     pour que la rotation pivote sur son propre centre et ne deplace pas le libelle. */
  .bascule-menu .chevron {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: .8em;
    height: .8em;
    flex: none;
    font-family: var(--chiffre);
    /* Le chevron ne porte pas de texte suivant : son interlettrage ne sert a rien et le
       decentrerait dans son propre carre. */
    letter-spacing: 0;
    transform-origin: 50% 50%;
    transition: transform 280ms cubic-bezier(.2, .7, .3, 1);
  }
  .bascule-menu[aria-expanded='true'] .chevron { transform: rotate(90deg); }

  /* ⚠️ Le depliement anime `grid-template-rows` de 0fr a 1fr, seule facon d'animer une hauteur
     automatique sans la mesurer en JavaScript. L'enfant DOIT rogner son debordement, sinon le
     contenu deborde de la piste pendant toute la transition.

     ⚠️ Et `visibility` n'est pas decoratif : c'est lui qui retire les liens de l'ordre de
     tabulation quand le volet est ferme. Une opacite nulle seule laisserait le clavier
     traverser un sommaire que personne ne voit. Il bascule a la FIN de la fermeture et au
     DEBUT de l'ouverture, d'ou les deux delais. */
  .volet {
    display: grid;
    grid-template-rows: 0fr;
    opacity: 0;
    visibility: hidden;
    transition: grid-template-rows 300ms cubic-bezier(.2, .7, .3, 1),
                opacity 180ms ease,
                visibility 0s linear 300ms;
  }
  .volet-interieur { overflow: hidden; min-height: 0; }

  .volet.ouvert {
    grid-template-rows: 1fr;
    opacity: 1;
    visibility: visible;
    transition: grid-template-rows 300ms cubic-bezier(.2, .7, .3, 1),
                opacity 240ms ease 60ms,
                visibility 0s linear 0s;
  }

  /* Le sommaire se deroule ligne a ligne, comme une feuille qu'on deplie. Un seul moment
     orchestre vaut mieux que des micro-animations dispersees. Les delais sont courts : au-dela
     de quelques dizaines de millisecondes par ligne, on attend au lieu de regarder. */
  .volet.ouvert .navigation li,
  .volet.ouvert form {
    animation: deplier 260ms cubic-bezier(.2, .7, .3, 1) backwards;
  }
  .volet.ouvert .navigation li:nth-child(1) { animation-delay: 40ms; }
  .volet.ouvert .navigation li:nth-child(2) { animation-delay: 80ms; }
  .volet.ouvert .navigation li:nth-child(3) { animation-delay: 120ms; }
  .volet.ouvert .navigation li:nth-child(4) { animation-delay: 160ms; }
  .volet.ouvert .navigation li:nth-child(5) { animation-delay: 200ms; }
  .volet.ouvert form { animation-delay: 240ms; }

  /* ⚠️ La regle des 62rem met le sommaire en ligne et retire les filets, ce qui convient a une
     tablette. Sur telephone il redevient une COLONNE filetee : c'est la forme d'un sommaire,
     et c'est ce qui donne son sens au deroulement ligne a ligne. En lignes qui se replient,
     l'animation en escalier saute d'un bout a l'autre et ne veut plus rien dire. */
  .navigation { margin-top: var(--rythme); }
  .navigation ul { display: block; }
  .navigation a { border-bottom: 1px solid var(--trait); }

  /* La barre reprend sa hauteur naturelle : repliee, elle ne doit pas occuper un ecran. */
  .marge { padding: var(--rythme) 1rem; }
}

@keyframes deplier {
  from { opacity: 0; transform: translateY(-.35rem); }
  to   { opacity: 1; transform: none; }
}

/* Pied de page : il termine la lecture, il ne la concurrence pas. */
.pied {
  margin-top: calc(var(--rythme) * 2);
  padding-top: var(--rythme);
  border-top: 1px solid var(--trait);
}
.pied p {
  margin: 0;
  max-width: none;
  font-size: 0.82rem;
  color: var(--attenue);
}


/* Affectation d'un type de rendez-vous a plusieurs personnes.
   Le fieldset porte le groupe de boutons radio : sans lui, un lecteur d'ecran annonce trois
   choix isoles sans dire a quelle question ils repondent (WCAG 1.3.1). */
.choix { border: 0; padding: 0; margin: 0 0 1.4rem; }
.choix legend {
  padding: 0;
  font-family: var(--titre);
  font-variant: small-caps;
  letter-spacing: .06em;
  color: var(--rubrique);
}
.choix .discret { margin: -.3rem 0 1rem 2.05rem; }

.personnes { margin-bottom: 1rem; }
/* Une regle d'un point entre les personnes : la meme que les tableaux de la fiche, pour que
   la liste se lise comme un registre et non comme un formulaire de plus. */
.personne {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1.4rem;
  padding: .55rem 0;
  border-bottom: 1px solid var(--trait);
}
.personne .bascule { margin: 0; }
.personne .poids { display: flex; align-items: center; gap: .6rem; margin: 0; max-width: none; }
.personne .poids input { width: 4.5rem; margin: 0; }
