/* ============================================================================
   BIBLIOTHEQUE UI JABS  -  moderne.css
   Depend de : theme.css, buttons.css

   Les fonctions CSS qui suppriment du JavaScript. Chacune remplace un schema
   qui demandait, il y a deux ans, une bibliotheque ou plusieurs dizaines de
   lignes de code.

   Chaque fiche indique son etat de disponibilite. La regle tenue partout :
   une fonction recente est employee en AMELIORATION, jamais en fondation.
   Le repli n'est pas une degradation, c'est le comportement normal du site
   pour qui n'a pas la derniere version de son navigateur.
   ========================================================================= */

/* ===========================================================================
   FAMILLE A  -  ELEMENTS FLOTTANTS SANS JAVASCRIPT
   ======================================================================== */

/* @v CSS-A1
@nom Popover natif
@usage L'attribut popover donne le comportement complet d'un panneau flottant : ouverture, fermeture au clic exterieur, fermeture sur Echap, gestion du focus et de la pile. Zero ligne de JavaScript.
@large
@html
<div class="cm-demo">
  <button class="btn btn--secondaire" popovertarget="pop-demo">Ouvrir le panneau {{icon:chevron-down}}</button>
  <div id="pop-demo" popover class="cm-pop">
    <strong>Panneau natif</strong>
    <p>Fermeture au clic exterieur et sur Echap, sans une ligne de code. La pile d'empilement est geree par le navigateur.</p>
    <button class="btn btn--plein btn--sm" popovertarget="pop-demo" popovertargetaction="hide">Fermer</button>
  </div>
</div>
@tw &lt;button popovertarget="x"&gt; + &lt;div id="x" popover&gt; &mdash; disponible partout depuis 2024
@end */
.cm-pop {
  width: 300px;
  padding: var(--sp-4);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  box-shadow: var(--sh-4);
  color: var(--c-text);
}
.cm-pop strong { display: block; font-size: var(--fs-md); font-weight: var(--fw-bold); margin-bottom: 5px; }
.cm-pop p { margin: 0 0 var(--sp-3); font-size: var(--fs-sm); color: var(--c-text-soft); line-height: 1.55; }
/* Le voile derriere le popover, stylable directement. */
.cm-pop::backdrop { background: rgba(10,12,18,.18); }
.cm-demo { display: flex; flex-wrap: wrap; gap: var(--sp-3); align-items: center; min-height: 60px; }
/* @endv */

/* @v CSS-A2
@nom Ancrage de position
@usage Le panneau se positionne par rapport a son declencheur, et bascule tout seul quand il manque de place. C'est ce qui remplace les bibliotheques de positionnement flottant et leurs calculs au defilement.
@large
@html
<div class="cm-demo">
  <button class="btn btn--secondaire cm-ancre" popovertarget="pop-ancre" style="anchor-name:--a1">En bas {{icon:chevron-down}}</button>
  <div id="pop-ancre" popover class="cm-pop cm-pop--ancre" style="position-anchor:--a1">
    <strong>Ancre automatique</strong>
    <p>Positionne sous le bouton, bascule au-dessus s'il n'y a pas la place en bas.</p>
  </div>
  <span class="cm-note">position-area: block-end span-inline-end<br>position-try-fallbacks: flip-block, flip-inline</span>
</div>
@tw anchor-name sur le declencheur, position-anchor sur le panneau
@end */
.cm-pop--ancre {
  margin: 6px 0 0;
  /* Se place sous l'ancre, aligne a gauche. */
  position-area: block-end span-inline-end;
  /* Bascule si la place manque, plutot que de sortir de l'ecran. */
  position-try-fallbacks: flip-block, flip-inline;
}
.cm-note {
  font-family: var(--font-mono);
  font-size: 11px;
  line-height: 1.6;
  color: var(--c-text-muted);
  padding: var(--sp-2) var(--sp-3);
  border-radius: var(--r-sm);
  background: var(--c-surface-2);
}
/* Repli : sans ancrage, le panneau reste centre a l'ecran, ce qui est le
   comportement natif d'un popover. Rien ne casse. */
@supports not (position-area: block-end) {
  .cm-pop--ancre { margin: 0; }
}
/* @endv */

/* @v CSS-A3
@nom Info-bulle sans JavaScript
@usage Popover et ancrage combines : la bulle suit son declencheur, se ferme seule, et se replace quand elle depasse. Le tout en CSS, avec le comportement clavier inclus.
@large
@html
<div class="cm-demo">
  <button class="btn btn--icone btn--secondaire" popovertarget="bulle1" style="anchor-name:--b1" aria-label="Aide">{{icon:alerte}}</button>
  <div id="bulle1" popover class="cm-bulle" style="position-anchor:--b1">Le prix indique comprend la pose et la mise en service.</div>
  <button class="btn btn--secondaire" popovertarget="bulle2" style="anchor-name:--b2">Exporter {{icon:download}}</button>
  <div id="bulle2" popover class="cm-bulle" style="position-anchor:--b2">Genere un fichier Excel avec la mise en page de la societe.</div>
</div>
@tw popover=hint pour une bulle qui ne ferme pas les autres panneaux ouverts
@end */
.cm-bulle {
  max-width: 240px;
  margin: 0 0 8px;
  padding: 7px 11px;
  border: none;
  border-radius: var(--r-sm);
  background: var(--c-text);
  color: var(--c-surface);
  font-size: var(--fs-xs);
  line-height: 1.45;
  position-area: block-start;
  position-try-fallbacks: flip-block;
}
.cm-bulle::backdrop { background: transparent; }
/* @endv */

/* ===========================================================================
   FAMILLE B  -  SELECTION ET PORTEE
   ======================================================================== */

/* @v CSS-B1
@nom Le selecteur de parent
@usage :has() permet enfin de styler un element selon ce qu'il contient. C'est ce qui supprime la plupart des classes ajoutees en JavaScript pour refleter un etat.
@large
@html
<div class="demo-col demo-col--large">
  <label class="cm-carte-choix"><input type="checkbox"><span class="coche__boite"></span><span><strong>Pose comprise</strong><small>Intervention sous 3 semaines</small></span><em>+ 1 200 EUR</em></label>
  <label class="cm-carte-choix"><input type="checkbox" checked><span class="coche__boite"></span><span><strong>Extension de garantie</strong><small>5 ans pieces et main d'oeuvre</small></span><em>+ 340 EUR</em></label>
  <div class="cm-total">Total des options : <strong>340,00 EUR</strong></div>
  <span class="cm-note">.carte:has(:checked) { border-color: var(--c-primary) }<br>form:has(:invalid) button[type=submit] { opacity: .5 }</span>
</div>
@tw :has(:checked), :has(> img), form:has(:invalid) &mdash; disponible partout depuis 2023
@end */
.cm-carte-choix {
  display: flex; align-items: center; gap: var(--sp-3);
  padding: var(--sp-4);
  border: 1.5px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
  cursor: pointer;
  transition: border-color var(--t-fast), background-color var(--t-fast);
}
.cm-carte-choix input { position: absolute; opacity: 0; width: 0; height: 0; }
.cm-carte-choix > span:last-of-type { display: flex; flex-direction: column; flex: 1; }
.cm-carte-choix strong { font-size: var(--fs-md); font-weight: var(--fw-semi); }
.cm-carte-choix small { font-size: var(--fs-xs); color: var(--c-text-muted); }
.cm-carte-choix em { font-style: normal; font-weight: var(--fw-bold); }
/* La carte reagit a l'etat de la case qu'elle contient. */
.cm-carte-choix:has(input:checked) {
  border-color: var(--c-primary);
  background: color-mix(in srgb, var(--c-primary-soft) 50%, var(--c-surface));
}
.cm-total { padding: var(--sp-3); border-radius: var(--r-md); background: var(--c-surface-2); font-size: var(--fs-sm); }
/* @endv */

/* @v CSS-B2
@nom Portee de style
@usage @scope limite des regles a un sous-arbre, et coupe la cascade a une frontiere. Il remplace les prefixes de classe defensifs et les guerres de specificite.
@large
@html
<div class="mv-code">
  <pre><code>/* Les regles ne s'appliquent qu'a l'interieur de .carte,
   et s'arretent avant toute .carte imbriquee */
@scope (.carte) to (.carte .carte) {
  h3 { font-size: 18px; font-weight: 700; }
  p  { color: var(--c-text-soft); }
  a  { color: var(--c-primary); }
}

/* :scope designe la racine, et la proximite l'emporte sur
   la specificite : plus besoin de surenchere de selecteurs */
@scope (.theme-sombre) {
  :scope { background: #14181f; color: #e8eef6; }
  a { color: #7fb3ff; }
}</code></pre>
  <p class="thm-note">Sans <code>@scope</code>, isoler un composant demandait soit un prefixe sur chaque classe,
  soit une surenchere de specificite. La limite haute (<code>to</code>) est ce qui manquait le plus :
  elle permet a un composant de ne pas styler ses propres copies imbriquees.</p>
</div>
@tw @scope (.racine) to (.limite) { ... } &mdash; disponible dans tous les moteurs depuis 2025
@end */
/* @endv */

/* @v CSS-B3
@nom Requetes de conteneur
@usage Un composant qui s'adapte a la largeur de SON conteneur, pas a celle de la fenetre. C'est la seule facon d'avoir un composant vraiment reutilisable dans une colonne etroite comme en pleine page.
@large
@html
<div class="cm-conteneurs">
  <div class="cm-boite" style="width:100%"><div class="cm-adapt"><div class="cm-adapt__img"></div><div><strong>Dossier 2026-103</strong><p>Neuilly-sur-Marne &mdash; PAC air/eau 11 kW</p><span class="doc-etiq doc-etiq--ok">Signe</span></div></div></div>
  <div class="cm-boite" style="width:340px"><div class="cm-adapt"><div class="cm-adapt__img"></div><div><strong>Dossier 2026-103</strong><p>Neuilly-sur-Marne &mdash; PAC air/eau 11 kW</p><span class="doc-etiq doc-etiq--ok">Signe</span></div></div></div>
  <div class="cm-boite" style="width:210px"><div class="cm-adapt"><div class="cm-adapt__img"></div><div><strong>Dossier 2026-103</strong><p>Neuilly-sur-Marne</p><span class="doc-etiq doc-etiq--ok">Signe</span></div></div></div>
</div>
@tw container-type: inline-size sur le parent, @container (min-width: X) pour l'enfant
@end */
.cm-conteneurs { display: flex; flex-direction: column; gap: var(--sp-3); align-items: flex-start; width: 100%; }
.cm-boite { container-type: inline-size; max-width: 100%; }
.cm-adapt {
  display: flex; flex-direction: column; gap: var(--sp-3);
  padding: var(--sp-3);
  border: 1px solid var(--c-border);
  border-radius: var(--r-lg);
  background: var(--c-surface);
}
.cm-adapt__img { aspect-ratio: 16 / 9; border-radius: var(--r-md); background: linear-gradient(140deg, #4a6fa5, #8a6a4a); flex: none; }
.cm-adapt strong { display: block; font-size: var(--fs-md); font-weight: var(--fw-bold); }
.cm-adapt p { margin: 3px 0 var(--sp-2); font-size: var(--fs-sm); color: var(--c-text-muted); }
/* Le meme composant, trois formes, selon la largeur du conteneur. */
@container (min-width: 300px) {
  .cm-adapt { flex-direction: row; align-items: center; }
  .cm-adapt__img { width: 90px; aspect-ratio: 1; }
}
@container (min-width: 520px) {
  .cm-adapt { padding: var(--sp-4); gap: var(--sp-4); }
  .cm-adapt__img { width: 130px; aspect-ratio: 16 / 10; }
  .cm-adapt strong { font-size: var(--fs-xl); }
}
/* @endv */

/* ===========================================================================
   FAMILLE C  -  MISE EN PAGE ET TEXTE
   ======================================================================== */

/* @v CSS-C1
@nom Champ qui grandit
@usage field-sizing: content fait grandir un champ ou une zone de texte avec son contenu. Il remplace le calcul de hauteur en JavaScript qu'on trouvait dans toutes les zones de saisie.
@large
@html
<div class="demo-col demo-col--large">
  <div class="champ"><label class="champ__label">Zone qui s'adapte</label><textarea class="saisie cm-grandit" rows="1">Cette zone grandit avec son contenu, sans une ligne de JavaScript. Ajoutez du texte pour la voir s'etendre, jusqu'a la limite fixee par max-height.</textarea></div>
  <div class="champ"><label class="champ__label">Champ qui s'ajuste a la valeur</label><input class="saisie cm-grandit cm-grandit--min" value="4 280,00"></div>
  <span class="cm-note">field-sizing: content; max-height: 200px;</span>
</div>
@tw field-sizing: content &mdash; Chrome et Edge depuis 2024, Safari 26, Firefox en cours
@end */
.cm-grandit { field-sizing: content; max-height: 200px; min-height: 44px; }
.cm-grandit--min { width: auto; min-width: 120px; }
/* @endv */

/* @v CSS-C2
@nom Ajustement optique du texte
@usage text-box-trim retire l'espace au-dessus des majuscules et sous la ligne de base. C'est ce qui permet d'aligner vraiment un titre sur une icone ou un bord, sans marge negative bricolee.
@large
@html
<div class="cm-trim">
  <div><span class="cm-trim__etiq">Sans ajustement</span><div class="cm-trim__boite"><h4>Titre de section</h4></div></div>
  <div><span class="cm-trim__etiq">Avec text-box-trim</span><div class="cm-trim__boite"><h4 class="cm-coupe">Titre de section</h4></div></div>
</div>
@tw text-box: trim-both cap alphabetic &mdash; Chrome et Safari, non encore dans Firefox
@end */
.cm-trim { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-4); }
.cm-trim__etiq { display: block; margin-bottom: 6px; font-size: 10px; font-weight: var(--fw-bold); text-transform: uppercase; letter-spacing: .07em; color: var(--c-text-muted); }
.cm-trim__boite { padding: var(--sp-3); border: 1px dashed var(--c-primary); border-radius: var(--r-sm); background: var(--c-surface); }
.cm-trim h4 { margin: 0; font-size: 26px; font-weight: 800; letter-spacing: -.02em; }
/* Le cadre epouse la hauteur des lettres, pas celle de la police. */
.cm-coupe { text-box: trim-both cap alphabetic; }
@media (max-width: 560px) { .cm-trim { grid-template-columns: 1fr; } }
/* @endv */

/* @v CSS-C3
@nom Grille en lanes
@usage La mise en page en briques decalees, native. Elle remplace les bibliotheques de masonry et leurs recalculs a chaque redimensionnement. Encore recente : le repli est une grille reguliere, ce qui reste parfaitement correct.
@large
@html
<div class="cm-lanes">
  <figure style="--h:150px"><div style="--t:linear-gradient(140deg,#4a6fa5,#c9d9e8)"></div><figcaption>Facade</figcaption></figure>
  <figure style="--h:210px"><div style="--t:linear-gradient(140deg,#a8643c,#f0d9b5)"></div><figcaption>Combles</figcaption></figure>
  <figure style="--h:120px"><div style="--t:linear-gradient(140deg,#3d6b4f,#c3ddc9)"></div><figcaption>Local technique</figcaption></figure>
  <figure style="--h:180px"><div style="--t:linear-gradient(140deg,#6b4a72,#ddc9dc)"></div><figcaption>Unite exterieure</figcaption></figure>
  <figure style="--h:135px"><div style="--t:linear-gradient(140deg,#8a3b3b,#e8c4c4)"></div><figcaption>Tableau</figcaption></figure>
  <figure style="--h:195px"><div style="--t:linear-gradient(140deg,#35485c,#b9c6cd)"></div><figcaption>Toiture</figcaption></figure>
</div>
@tw grid-template-rows: masonry (Safari 26) &mdash; repli en colonnes CSS partout ailleurs
@end */
/* Repli universel : colonnes CSS. Le rendu est proche, sans l'ordre exact. */
.cm-lanes { columns: 3; column-gap: var(--sp-3); width: 100%; }
.cm-lanes figure { break-inside: avoid; margin: 0 0 var(--sp-3); }
.cm-lanes div { height: var(--h); border-radius: var(--r-md); background: var(--t); }
.cm-lanes figcaption { padding-top: 6px; font-size: var(--fs-xs); color: var(--c-text-muted); }
/* Quand la grille en lanes est disponible, on la prefere : l'ordre de lecture
   suit alors les lignes, ce que les colonnes CSS ne savent pas faire. */
@supports (grid-template-rows: masonry) {
  .cm-lanes {
    columns: auto;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: masonry;
    gap: var(--sp-3);
  }
  .cm-lanes figure { margin: 0; }
}
@media (max-width: 640px) { .cm-lanes { columns: 2; } }
/* @endv */

/* @v CSS-C4
@nom Couleurs derivees
@usage color-mix() et les couleurs relatives permettent de deduire une palette entiere d'une seule teinte. Un client fournit sa couleur, les survols, fonds doux et bordures s'en deduisent.
@large
@html
<div class="cm-couleurs" style="--marque:#b8002e">
  <div style="background:var(--marque)"><span>--marque</span></div>
  <div style="background:color-mix(in srgb, var(--marque) 82%, black)"><span>survol &mdash; 18 % de noir</span></div>
  <div style="background:color-mix(in srgb, var(--marque) 12%, white);color:var(--marque)"><span>fond doux &mdash; 12 %</span></div>
  <div style="background:color-mix(in srgb, var(--marque) 30%, white);color:var(--c-text)"><span>bordure &mdash; 30 %</span></div>
  <div style="background:oklch(from #b8002e calc(l + .28) c h)"><span>eclairci en oklch</span></div>
  <div style="background:oklch(from #b8002e l c calc(h + 180))"><span>complementaire</span></div>
</div>
@tw color-mix(in srgb, X 12%, white) et oklch(from X calc(l + .28) c h)
@end */
.cm-couleurs { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: var(--sp-2); width: 100%; }
.cm-couleurs > div {
  display: grid; place-items: center;
  min-height: 74px;
  padding: var(--sp-2);
  border-radius: var(--r-md);
  color: #fff;
  text-align: center;
}
.cm-couleurs span { font-family: var(--font-mono); font-size: 10.5px; font-weight: var(--fw-bold); }
/* @endv */

/* @v CSS-C5
@nom Logique conditionnelle
@usage if() introduit une condition dans une valeur, sans classe ni media query. Encore tres recent : a n'employer que la ou le repli est acceptable.
@large
@html
<div class="mv-code">
  <pre><code>/* Une seule regle, trois resultats selon un attribut */
.etiquette {
  background: if(
    style(--ton: succes): var(--c-success-soft);
    style(--ton: alerte): var(--c-warn-soft);
    else: var(--c-surface-3)
  );
}

/* Ce qu'on ecrivait avant : trois regles et trois classes */
.etiquette             { background: var(--c-surface-3); }
.etiquette--succes     { background: var(--c-success-soft); }
.etiquette--alerte     { background: var(--c-warn-soft); }</code></pre>
  <p class="thm-note"><strong>Encore experimental</strong> &mdash; Chrome 137 et suivants seulement, au moment ou ces lignes
  sont ecrites. La forme a trois classes reste la bonne fondation ; <code>if()</code> se pose par-dessus quand
  il permet d'eviter une combinatoire de classes qui deviendrait ingerable.</p>
</div>
@tw if(style(--x: valeur): A; else: B) &mdash; experimental, prevoir le repli
@end */
/* @endv */

/* @v CSS-C6
@nom Transitions entre vues
@usage Les View Transitions animent le passage d'un etat a l'autre dans la meme page : le filtre change, les lignes qui restent glissent a leur nouvelle place au lieu de clignoter.
@large
@html
<div class="mv-code">
  <pre><code>// Une seule ligne enveloppe le changement de contenu
document.startViewTransition(() =&gt; {
  liste.innerHTML = nouvellesLignes;
});

/* Chaque element qui doit etre suivi porte un nom unique */
.ligne[data-id="103"] { view-transition-name: ligne-103; }

/* La duree et la courbe se reglent en CSS */
::view-transition-group(*) {
  animation-duration: 280ms;
  animation-timing-function: cubic-bezier(.2,0,0,1);
}

/* Entre deux PAGES, une seule declaration suffit */
@view-transition { navigation: auto; }</code></pre>
  <p class="thm-note">C'est ce qui remplace FLIP dans la plupart des cas : le navigateur mesure les positions,
  applique la difference et anime, sans qu'on ait a le faire soi-meme. Les navigateurs qui ne le connaissent
  pas executent simplement le changement sans animation, ce qui reste correct.</p>
</div>
@tw document.startViewTransition() + view-transition-name
@end */
/* @endv */
