/* at_placement — feuille du NOYAU, commune au front et à l'aperçu de l'éditeur.
   Écrite par le pont (Placement_Bridge en PHP, atgf-placement-bridge.js dans l'aperçu), qui
   pose des classes GÉNÉRIQUES sur toute cible : `.atp-host` (+ `--flow` | `--grid`
   [`--balanced`] [`--dense`]) sur le conteneur, `.atp-item` (+ `--ideal`, `--hidden`) sur
   chaque élément. Audit : docs/audit-at-placement.md (lot 2).

   Les formules lisent trois variables d'ADAPTATEUR, que chaque cible fait pointer sur les
   siennes (le builder : attps-builder/assets/css/atb-placement.css ; la cible générique :
   plus bas) :
     --atp-w   poids effectif de l'élément (/12)      --atp-mw  largeur mini de l'élément
     --atp-gap écart des colonnes du conteneur
   K = garder les poids (`--atp-keep`, 0/1), F = pleine ligne (`--atp-full`, 0/1). Avec
   K = F = 0, la formule est EXACTEMENT celle, historique, des colonnes du builder.

   Spécificités (à préserver, elles battent les règles historiques du builder) :
   colonnes (0,3,0), idéalement (0,4,0), voisins d'un idéalement (0,6,0), masqué (0,3,0),
   grille (0,2,0) / (0,3,0), Flex (0,0,0) / (0,3,0). */

/* --- Variables propres à un élément : jamais héritées ------------------------------
   Un conteneur imbriqué dans un élément ne reçoit ni sa place en grille, ni sa pleine
   ligne, ni son poids (audit 1.8 : grille dans une case de grille empilée). */
@property --atp-full { syntax: '*'; inherits: false; }
@property --atp-span-c { syntax: '*'; inherits: false; }
@property --atp-span-r { syntax: '*'; inherits: false; }
@property --atp-start-c { syntax: '*'; inherits: false; }
@property --atp-start-r { syntax: '*'; inherits: false; }
@property --atp-aspect { syntax: '*'; inherits: false; }
@property --atp-rank { syntax: '*'; inherits: false; }
@property --atp-count { syntax: '*'; inherits: false; }
@property --atp-w { syntax: '*'; inherits: false; }
@property --atp-mw { syntax: '*'; inherits: false; }
@property --atp-item-align { syntax: '*'; inherits: false; }
/* L'élément est-il conteneur de requêtes (`inline-size` pour les colonnes et éléments du
   builder, posé par leur adaptateur) : rendu en quittant Bandeau / Carrousel « auto », où il
   ne peut pas l'être (le confinement en ligne annule sa largeur de contenu). */
@property --atp-item-ct { syntax: '*'; inherits: false; }
/* Flex : taille d'un élément (grandir, rétrécir, base, mini, maxi) et conteneur de requêtes. */
@property --atp-grow { syntax: '*'; inherits: false; }
@property --atp-shrink { syntax: '*'; inherits: false; }
@property --atp-basis { syntax: '*'; inherits: false; }
@property --atp-fmin { syntax: '*'; inherits: false; }
@property --atp-fmax { syntax: '*'; inherits: false; }
@property --atp-fct { syntax: '*'; inherits: false; }

/* --- Variables du conteneur : lues par ses éléments, remises à zéro à chaque conteneur
   placé (un conteneur imbriqué repart de ses propres réglages). */
.atp-host {
    --atp-keep: 0;
    --atp-tracks: initial;
    --atp-cols: initial;
    --atp-row: initial;
    --atp-n: initial;
    --atp-min: initial;
    --atp-repeat: initial;
    --atp-slide: initial;
    --atp-snap: initial;
    --atp-snap-type: initial;
    --atp-pv: initial;
    --atp-edges: initial;
    --atp-slide-ct: initial;
    --atp-bleed: initial;
}

/* --- Flex (`flexbox`) : flex pur -----------------------------------------------------
   Défauts : rangée, à la ligne, au début ; chaque élément à la taille de son contenu
   (0 1 auto), sans mini imposé. Réglages : direction, retour, répartition, lignes, hauteur
   (déclarations du pont) ; grandir / rétrécir / base / mini / maxi (variables ci-dessous).
   Un élément à la taille de son contenu n'est pas conteneur de requêtes : `--atp-fct` le
   rend conteneur quand sa base est une longueur (étude .claude/etude-mode-flex).
   Hôte sans spécificité (`:where`) : le CSS d'une cible (sections, lignes : déjà en colonne,
   centrées) et les utilitaires posés sur l'hôte gardent la main ; le pont n'émet que l'écart. */
:where(.atp-host.atp-host--flexbox) {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: flex-start;
    align-content: normal;
}

.atp-host.atp-host--flexbox > .atp-item {
    flex: var(--atp-grow, 0) var(--atp-shrink, 1) var(--atp-basis, auto);
    min-width: var(--atp-fmin, auto);
    max-width: var(--atp-fmax, none);
    container-type: var(--atp-fct, normal);
}

/* --- Colonnes (flex) : formule mixée ------------------------------------------------ */
.atp-host.atp-host--flow > .atp-item {
    flex-grow: calc(var(--atp-w, 6) * (1 - var(--atp-keep, 0)) * (1 - var(--atp-full, 0)));
    flex-shrink: calc(1 - var(--atp-full, 0));
    flex-basis: calc(((clamp(var(--atp-mw, 250px), calc((100% / 12) * var(--atp-w, 6)), 100%) - var(--atp-gap, 0rem)) * (1 - var(--atp-keep, 0)) + clamp(min(100%, var(--atp-mw, 250px)), calc((100% / 12) * var(--atp-w, 6) - var(--atp-gap, 0rem) * (12 - var(--atp-w, 6)) / 12), 100%) * var(--atp-keep, 0)) * (1 - var(--atp-full, 0)) + 100% * var(--atp-full, 0));
    max-width: 100%;
}

/* « Idéalement » : base au mini, reçoit en priorité la place libre ; en gardant les
   poids, grandit de son mini jusqu'à sa travée, pas au-delà ; en pleine ligne, 100 %. */
.atp-host.atp-host--flow > .atp-item.atp-item--ideal {
    flex-grow: calc((var(--atp-w, 6) * 1000 * (1 - var(--atp-keep, 0)) + var(--atp-keep, 0)) * (1 - var(--atp-full, 0)));
    flex-basis: calc(min(100%, var(--atp-mw, 250px)) * var(--atp-keep, 0) * (1 - var(--atp-full, 0)) + 100% * var(--atp-full, 0));
    max-width: calc(100% - (100% - calc((100% / 12) * var(--atp-w, 6) - var(--atp-gap, 0rem) * (12 - var(--atp-w, 6)) / 12)) * var(--atp-keep, 0) * (1 - var(--atp-full, 0)));
}

/* Voisins d'un « idéalement » (visible) : part EXACTE des écarts ; une pleine ligne
   reste pleine (audit 1.9). */
.atp-host.atp-host--flow:has(> .atp-item--ideal:not(.atp-item--hidden)) > .atp-item:not(.atp-item--ideal) {
    flex-basis: calc(clamp(var(--atp-mw, 250px), calc((100% / 12) * var(--atp-w, 6) - var(--atp-gap, 0rem) * (12 - var(--atp-w, 6)) / 12), 100%) * (1 - var(--atp-full, 0)) + 100% * var(--atp-full, 0));
}

/* --- Masqué (un point de rupture peut le réafficher : `display` de la cible dans sa règle) --- */
.atp-host .atp-item.atp-item--hidden {
    display: none;
}

/* --- Grille ----------------------------------------------------------------------
   Fixe : pistes (`--atp-cols`, jetons fr / px / minmax…), départ et span par élément,
   pleine ligne = colonne 1 sur 12 (bornée aux pistes), rangées auto / égales / au
   moins / fixes / au ratio. Équilibrée : au plus N colonnes, une de moins sous le mini. */
.atp-host.atp-host--grid {
    display: grid;
    grid-template-columns: var(--atp-cols, repeat(var(--atp-tracks, 3), minmax(0, 1fr)));
    grid-auto-rows: var(--atp-row, auto);
    align-items: stretch;
}

.atp-host.atp-host--grid.atp-host--balanced {
    /* `--atp-repeat: auto-fill` (« garder la largeur des colonnes ») : les pistes vides restent,
       un élément seul garde sa largeur de colonne au lieu de s'étirer (auto-fit, défaut). */
    grid-template-columns: repeat(var(--atp-repeat, auto-fit), minmax(min(100%, max(var(--atp-min, 250px), calc((100% - (var(--atp-n, 3) - 1) * var(--atp-gap, 0rem)) / var(--atp-n, 3)))), 1fr));
}

.atp-host.atp-host--grid.atp-host--dense {
    grid-auto-flow: row dense;
}

.atp-host.atp-host--grid > .atp-item {
    flex: none;
    min-width: 0;
    max-width: none;
    grid-column: var(--atp-start-c, auto) / span min(var(--atp-span-c, 1), var(--atp-tracks, 3));
    grid-row: var(--atp-start-r, auto) / span var(--atp-span-r, 1);
    aspect-ratio: var(--atp-aspect, auto);
}

.atp-host.atp-host--grid.atp-host--balanced > .atp-item {
    grid-column: auto;
    grid-row: auto;
    aspect-ratio: auto;
}

/* --- Mosaïque (étude édition § 29.1) --------------------------------------------------------
   Une grille (pistes, écarts, largeur en pistes, masqués, points de rupture) dont le script du noyau fait
   une mosaïque : rangées fines de 4 px, sans écart, chaque élément sur `--atp-mspan` rangées (sa hauteur +
   l'écart voulu), calé en haut. Sans script : colonnes CSS (lecture colonne par colonne, pas de largeur
   double) — `atp-masonry-rt` = le script a pris la main, `atp-masonry-on` = mosaïque active à ce point. */
.atp-host.atp-host--grid.atp-host--masonry > .atp-item {
    grid-row: auto;
    aspect-ratio: auto;
}

.atp-host.atp-host--grid.atp-host--masonry:not(.atp-masonry-rt) {
    display: block;
    column-count: var(--atp-tracks, 3);
    column-gap: var(--atp-gap, 1rem);
}

.atp-host.atp-host--grid.atp-host--masonry:not(.atp-masonry-rt) > .atp-item {
    width: auto;
    margin-block-end: var(--atp-gap, 1rem);
    break-inside: avoid;
}

.atp-host.atp-masonry-on {
    display: grid;
    grid-auto-rows: 4px !important;
    row-gap: 0 !important;
    align-items: start !important;
}

.atp-host.atp-masonry-on > .atp-item {
    grid-row: auto / span var(--atp-mspan, 1) !important;
    align-self: start !important;
}

/* --- Carrousel (défilement natif) et Bandeau --------------------------------------------
   Modes de la BASE ; à un point de rupture, le pont écrit les mêmes déclarations dans la
   règle du point (Placement_Bridge::MODE_HOST / MODE_ITEM). Le script du noyau
   (atgf-placement-rt.js, lit `data-atp-modes`) ajoute contrôles, défilement automatique,
   copies du bandeau et classes d'état `atp-is-*` : le rendu serveur suffit à la mise en page.
   Carrousel : `--atp-slide` = largeur d'un élément (par vue, aperçu, « au plus N » via
   `--atp-pv` posé par le script), `--atp-snap` / `--atp-snap-type` = accroche. */
.atp-host.atp-host--carousel {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: stretch;
    min-width: 0;
    overflow-x: auto;
    overflow-y: hidden;
    overscroll-behavior-x: contain;
    scroll-snap-type: var(--atp-snap-type, x mandatory);
    scrollbar-width: none;
    column-gap: var(--atp-gap, 0rem);
    /* Débord vertical (`--atp-bleed`) : la bande défilante coupe tout ce qui dépasse, ombres
       des cartes comprises ; padding compensé par une marge négative (hauteur inchangée). */
    padding-block: var(--atp-bleed, 0px);
    margin-block: calc(-1 * var(--atp-bleed, 0px));
}

.atp-host.atp-host--carousel > .atp-item {
    flex: 0 0 var(--atp-slide, 100%);
    min-width: 0;
    max-width: none;
    scroll-snap-align: var(--atp-snap, start);
    container-type: var(--atp-slide-ct, var(--atp-item-ct, normal));
}

.atp-host.atp-host--carousel::-webkit-scrollbar,
.atp-host.atp-is-carousel::-webkit-scrollbar {
    display: none;
}

/* Bandeau : les éléments débordent de la disposition (qui garde la largeur de sa boîte) ;
   la boîte écrête, le script translate la disposition. À un point, l'écrêtage est dans la
   règle du point (ou à la base de la boîte pour un point conteneur). */
.atp-host.atp-host--marquee {
    display: flex;
    flex-direction: row;
    flex-wrap: nowrap;
    align-items: center;
    min-width: 0;
    column-gap: var(--atp-gap, 0rem);
}

.atp-host.atp-host--marquee > .atp-item {
    flex: none;
    min-width: 0;
    max-width: none;
    container-type: normal;
}

:has(> .atp-host.atp-host--marquee) {
    overflow-x: clip;
}

@keyframes atp-marquee {
    from { transform: translate3d(var(--atp-mq-from, 0px), 0, 0); }
    to { transform: translate3d(var(--atp-mq-to, 0px), 0, 0); }
}

.atp-is-marquee.atp-mq-run {
    animation: atp-marquee var(--atp-mq-dur, 20s) linear infinite;
    will-change: transform;
}

.atp-is-marquee.atp-mq-right {
    animation-direction: reverse;
}

.atp-is-marquee.atp-is-paused {
    animation-play-state: paused;
}

/* Masque de bord (`--atp-edges`, recopié sur la boîte par le script). */
.atp-mq-edges {
    -webkit-mask-image: linear-gradient(to right, transparent, #000 var(--atp-edges, 0px), #000 calc(100% - var(--atp-edges, 0px)), transparent);
    mask-image: linear-gradient(to right, transparent, #000 var(--atp-edges, 0px), #000 calc(100% - var(--atp-edges, 0px)), transparent);
}

/* Moteur Swiper (effets, boucle infinie) : il pilote la disposition par transform. */
.atp-host.atp-is-swiper {
    overflow: visible !important;
    scroll-snap-type: none !important;
    column-gap: 0 !important;
}

.atp-host.atp-is-swiper > .atp-item {
    flex: 0 0 auto !important;
    height: auto;
}

.atp-nav__dot.swiper-pagination-bullet {
    opacity: 1;
}

.atp-nav__dot.swiper-pagination-bullet-active {
    background: var(--atp-nav-accent, currentColor);
    transform: scale(1.25);
}

.atp-nav--overlay .atp-nav__dot.swiper-pagination-bullet-active {
    background: var(--atp-nav-accent, #1d2327);
}

.atp-swiper-box {
    overflow: hidden;
}

.atp-host.atp-is-swiper.atp-linear {
    transition-timing-function: linear !important;
}

/* --- Contrôles (créés par le script dans la boîte) --------------------------------------
   Classes stables, habillage par variables : --atp-nav-size, --atp-nav-bg, --atp-nav-fg,
   --atp-nav-accent, --atp-nav-radius. `overlay` : flèches au milieu, puces en bas ;
   `below` : une rangée sous le carrousel. */
.atp-nav {
    --atp-nav-size: 2.5rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
    flex: 0 0 100%;
    width: 100%;
    box-sizing: border-box;
    pointer-events: none;
}

.atp-nav[hidden],
.atp-nav [hidden] {
    display: none !important;
}

.atp-nav > * {
    pointer-events: auto;
}

.atp-nav--below {
    padding-top: 0.75rem;
}

.atp-nav__bar {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.75rem;
}

/* Superposés : la couche couvre la boîte (sans capter les clics), flèches au milieu, barre
   (puces, fraction, progression, pause) en bas. */
.atp-nav--overlay {
    position: absolute;
    inset: 0;
    z-index: 3;
    display: block;
}

.atp-nav--overlay .atp-nav__arrow {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
}

.atp-nav--overlay .atp-nav__prev {
    left: 0.75rem;
}

.atp-nav--overlay .atp-nav__next {
    right: 0.75rem;
}

.atp-nav--overlay .atp-nav__bar {
    position: absolute;
    right: 0;
    bottom: 0.75rem;
    left: 0;
    pointer-events: none;
}

.atp-nav--overlay .atp-nav__bar > * {
    pointer-events: auto;
}

.atp-nav__arrow,
.atp-nav__pause,
.atp-mq-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--atp-nav-size);
    height: var(--atp-nav-size);
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: var(--atp-nav-radius, 999px);
    background: var(--atp-nav-bg, rgba(255, 255, 255, 0.92));
    color: var(--atp-nav-fg, #1d2327);
    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.18);
    cursor: pointer;
    line-height: 1;
    font: inherit;
}

.atp-nav__arrow svg,
.atp-nav__pause svg,
.atp-mq-toggle svg {
    width: 45%;
    height: 45%;
    fill: none;
    stroke: currentColor;
    stroke-width: 2.5;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.atp-nav__arrow:disabled {
    opacity: 0.35;
    cursor: default;
}

.atp-nav__dots {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
}

.atp-nav__dot {
    width: 0.625rem;
    height: 0.625rem;
    margin: 0;
    padding: 0;
    border: 0;
    border-radius: 999px;
    background: var(--atp-nav-dot, rgba(0, 0, 0, 0.25));
    cursor: pointer;
}

.atp-nav__dot[aria-current="true"] {
    background: var(--atp-nav-accent, currentColor);
    transform: scale(1.25);
}

.atp-nav--overlay .atp-nav__dot {
    /* Sur une photo comme sur une carte blanche : pastille sombre cerclée de blanc. */
    background: var(--atp-nav-dot, rgba(0, 0, 0, 0.3));
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.75);
}

.atp-nav--overlay .atp-nav__dot[aria-current="true"] {
    background: var(--atp-nav-accent, #1d2327);
}

.atp-nav__fraction {
    min-width: 3.5em;
    text-align: center;
    font-variant-numeric: tabular-nums;
}

.atp-nav--overlay .atp-nav__fraction {
    padding: 0.125rem 0.625rem;
    border-radius: 999px;
    background: var(--atp-nav-bg, rgba(255, 255, 255, 0.92));
    color: var(--atp-nav-fg, #1d2327);
}

.atp-nav__progress {
    flex: 0 1 12rem;
    height: 0.25rem;
    border-radius: 999px;
    background: var(--atp-nav-dot, rgba(0, 0, 0, 0.15));
    overflow: hidden;
}

.atp-nav__progress > span {
    display: block;
    height: 100%;
    width: 100%;
    background: var(--atp-nav-accent, currentColor);
    transform-origin: left center;
    transform: scaleX(var(--atp-progress, 0));
}

.atp-sr {
    position: absolute !important;
    width: 1px;
    height: 1px;
    margin: -1px;
    padding: 0;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
    border: 0;
}

/* Pause d'un carrousel automatique sans indicateur : même coin discret que le bandeau. */
.atp-nav--overlay .atp-nav__pause--corner {
    --atp-nav-size: 2rem;
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
    opacity: 0;
    transition: opacity 0.2s;
}

.atp-cz:hover > .atp-nav .atp-nav__pause--corner,
.atp-nav .atp-nav__pause--corner:focus-visible,
.atp-nav .atp-nav__pause--corner[aria-pressed="true"] {
    opacity: 1;
}

/* Pause du bandeau (WCAG 2.2.2) : discrète, visible au survol et au clavier. */
.atp-mq-toggle {
    --atp-nav-size: 2rem;
    position: absolute;
    right: 0.5rem;
    bottom: 0.5rem;
    z-index: 3;
    opacity: 0;
    transition: opacity 0.2s;
}

.atp-mq-box:hover > .atp-mq-toggle,
.atp-mq-toggle:focus-visible,
.atp-mq-toggle[aria-pressed="true"] {
    opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
    .atp-is-marquee.atp-mq-run {
        animation: none;
    }
}

/* --- Cible générique `item` : n'importe quelle liste générée ---------------------------
   `.atp-list` > `.atp-list__item`, posées par le pont ; variables d'élément `--atp-item-*`
   (poids, mini, alignement), écart `--atp-gap`. Le socle flex n'est pas fourni par un
   thème : il est ici. */
.atp-list.atp-host {
    box-sizing: border-box;
    column-gap: var(--atp-gap, 0rem);
    row-gap: var(--atp-gap, 0rem);
}

.atp-list.atp-host--flow {
    display: flex;
    flex-wrap: wrap;
    align-content: flex-start;
}

.atp-list.atp-host > .atp-list__item {
    --atp-item-weight-eff: var(--atp-item-weight, 6);
    --atp-w: var(--atp-item-weight-eff, 6);
    --atp-mw: var(--atp-item-min-width, 250px);
    box-sizing: border-box;
    align-self: var(--atp-item-align, auto);
    min-width: min(100%, var(--atp-item-min-width, 250px));
}
