/* ============================================================
   ZebraPuma.Web : Shared component styles
   ============================================================ */

/* --- ZpFooter : standard cross-site footer (compact, dynamic) --- */
.zp-footer {
    position: relative;
    padding: 14px 24px 12px;
    border-top: 1px solid var(--border, #e5e7eb);
    color: var(--text-muted, #6b7280);
    text-align: center;
    font-size: 0.72rem;
    line-height: 1.5;
}
.zp-footer .zp-footer-content {
    max-width: 720px;
    margin: 0 auto;
}
/* Ecosystem wrapper (title + author + pillars + detail). Collapsible via the
   chevron toggle on the meta line. SEO-safe : content stays in the DOM
   (max-height animation, not display:none) so Google still indexes it. */
.zp-footer .zp-footer-ecosystem {
    overflow: hidden;
    max-height: 200px; /* generous ceiling, actual content ~100px */
    opacity: 1;
    transition: max-height 0.35s ease, opacity 0.25s ease;
}
.zp-footer.collapsed .zp-footer-ecosystem {
    max-height: 0;
    opacity: 0;
}
/* When collapsed, the meta line becomes the only visible line : drop its
   top spacing so it sits flush against the outer footer border. */
.zp-footer.collapsed .zp-footer-meta {
    margin-top: 0;
    padding-top: 0;
}
/* Inner divider between the ecosystem and the meta line. Direct child of
   .zp-footer (not .zp-footer-content) so it spans the FULL width of the
   footer, matching the outer .zp-footer border-top length. Uses the same
   --border variable as the outer one for visual consistency. */
.zp-footer .zp-footer-divider {
    border: none;
    border-top: 1px solid var(--border, #e5e7eb);
    margin: 14px 0 0;
    height: 0;
}
/* When collapsed, the inner divider is meaningless (only the meta line
   remains, the outer footer border already separates page from footer). */
.zp-footer.collapsed .zp-footer-divider {
    display: none;
}
/* Les liens sont soulignes en permanence : sur mobile il n'y a pas de survol,
   et la couleur seule ne peut pas porter l'information « ceci est un lien »
   (WCAG 1.4.1, technique G182). Les piliers font exception, ils portent deja
   un contour qui les designe comme actionnables. */
.zp-footer a {
    color: var(--accent, #6c8aff) !important;
    text-decoration: underline !important;
    text-underline-offset: 3px;
    text-decoration-thickness: 1px;
    transition: opacity 0.15s;
}
.zp-footer a:hover {
    opacity: 0.85;
}
/* Nom du site courant : « vous etes ici », dit avec le vocabulaire que ce bandeau
   a deja pose. Les pastilles non actives portent un CONTOUR, qui signale
   l'actionnable ; celle du site courant porte un REMPLISSAGE. Le nom recoit donc le
   meme remplissage, sans contour : il est courant, et il n'est pas cliquable.
   Rien n'est importe de l'exterieur, la grammaire du composant se suffit.

   Ni couleur ni graisse imposees : le mot herite du texte de sa ligne. L'italique a
   ete ecartee (planche /dev/site-courant.html, variantes G a I) : a 0.72rem elle
   couterait en lisibilite, et elle signifie l'emphase ou la mention, jamais la
   position courante.

   box-decoration-break : sans lui, un nom qui passe a la ligne verrait son fond se
   fendre en deux blocs, ce qui arrive des le premier ecran etroit. */
.zp-footer .zp-footer-self {
    text-decoration: none;
    background: var(--accent-soft, rgba(108, 138, 255, 0.13));
    border-radius: 4px;
    padding: 1px 6px;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}
.zp-footer .zp-footer-title {
    font-size: 0.62rem;
    text-transform: uppercase;
    letter-spacing: 1.8px;
    margin: 0 0 4px;
    color: var(--text-muted, #6b7280) !important;
    font-weight: 600;
}
.zp-footer p { margin: 2px 0; }
.zp-footer .zp-footer-author {
    color: var(--text, #e5e7eb);
    font-weight: 500;
    margin: 2px 0 4px;
    font-size: 0.74rem;
}
.zp-footer .zp-footer-by {
    color: var(--text-muted, #6b7280);
    font-weight: 400;
    font-style: italic;
    margin-right: 2px;
}
/* Pillar selector : 3 buttons clickable on line 3 */
/* Marge haute plus genereuse que le reste du bandeau : la ligne au-dessus est
   soulignee, et un soulignement consomme l'espace optique sous sa ligne de base.
   Sans ce rattrapage, les piliers paraissent colles au texte qui les precede. */
.zp-footer .zp-pillar-selector {
    margin: 10px 0 2px;
    font-size: 0.74rem;
}
/* Affordance : au repos, ces trois piliers ne se distinguaient d'un texte
   ordinaire que par leur couleur. WCAG 1.4.1 interdit de reposer sur la seule
   couleur pour signaler une information, ici « ceci est actionnable ». Ils
   portent donc un contour permanent, qui les lit comme des controles avant
   meme le premier clic. L'etat actif ajoute le remplissage.
   Le contour est pose a 70 % de l'accent : en dessous, son propre contraste
   passe sous le seuil de 3 pour 1 exige des elements d'interface (WCAG 1.4.11). */
.zp-footer .zp-pillar-link {
    display: inline-block;
    background: none;
    border: 1px solid var(--accent, #6c8aff);
    border-color: color-mix(in srgb, var(--accent, #6c8aff) 70%, transparent);
    border-radius: 999px;
    padding: 4px 10px;
    color: var(--accent, #6c8aff) !important;
    font-family: inherit;
    font-size: inherit;
    font-weight: 600;
    cursor: pointer;
    text-decoration: none !important;
    transition: background 0.15s, border-color 0.15s;
}
.zp-footer .zp-pillar-link:hover {
    background: var(--accent-soft, rgba(108, 138, 255, 0.13));
    border-color: var(--accent, #6c8aff);
    text-decoration: none !important;
}
.zp-footer .zp-pillar-link.zp-pillar-link-active {
    color: var(--accent, #6c8aff) !important;
    background: var(--accent-soft, rgba(108, 138, 255, 0.13));
    border-color: var(--accent, #6c8aff);
    text-decoration: none !important;
    font-weight: 700;
}

/* Dynamic detail line : space is ALWAYS reserved (min-height) so the layout never
   shifts when content appears on click. Empty by default = invisible blank space,
   filled on click = same vertical position. No twist effect. */
.zp-footer .zp-pillar-detail {
    margin: 4px 0 0;
    font-size: 0.72rem;
    color: var(--text-muted, #6b7280);
    line-height: 1.5;
    /* Reserve exactly one line of THIS element's own line-height (1.5em) so the
       drawer height stays constant when a pillar detail is toggled open/closed.
       Using the element's own em (not a child's nominal rem) guarantees the
       empty reservation equals the filled line box — no height jump on click. */
    min-height: 1.5em;
}
.zp-footer .zp-pillar-content:not([hidden]) {
    display: inline-block;
}
.zp-footer .zp-pillar-name {
    color: var(--text, #e5e7eb) !important;
    font-weight: 700 !important;
    letter-spacing: 0.4px;
    font-size: 0.7rem;
}
.zp-footer .zp-pillar-name:hover {
    color: var(--accent, #6c8aff) !important;
}
.zp-footer .zp-pillar-url {
    font-style: italic;
    font-size: 0.74rem;
    color: var(--accent, #6c8aff) !important;
    text-decoration: underline !important;
    text-decoration-thickness: 1px;
    text-underline-offset: 2px;
    font-weight: 600;
}
.zp-footer .zp-pillar-url:hover {
    opacity: 0.85;
}
/* URL du site courant : elle reste affichee, elle situe le visiteur, mais elle
   cesse d'etre un lien vers la page ou il se trouve deja. Elle perd donc l'accent
   et le soulignement, garde l'italique qui la designe comme une adresse, et recoit
   le meme remplissage que le nom : c'est le signe « vous etes ici » du bandeau.
   Les !important repondent a ceux de la regle ci-dessus. */
.zp-footer .zp-pillar-url--self {
    color: var(--text-muted, #6b7280) !important;
    text-decoration: none !important;
    font-weight: 500;
    background: var(--accent-soft, rgba(108, 138, 255, 0.13));
    border-radius: 4px;
    padding: 1px 6px;
    box-decoration-break: clone;
    -webkit-box-decoration-break: clone;
}
.zp-footer .zp-pillar-keywords {
    color: var(--text-muted, #a5a8b3);
}
.zp-footer .zp-pillar-colon {
    color: var(--text-muted, #6b7280);
    margin: 0 5px;
    opacity: 0.5;
}
.zp-footer .zp-footer-meta {
    font-size: 0.92rem;
    opacity: 0.95;
    margin-top: 14px;
    padding-top: 10px;
    /* No border-top here : the outer .zp-footer { border-top } already
       provides the page/footer separation. A second horizontal line inside
       the footer would create noise and have a different length than the
       outer one (constrained to .zp-footer-content max-width). */
}
.zp-footer .zp-footer-version {
    opacity: 0.85;
}
/* Drawer-handle toggle : a small rounded tab that pokes up out of the footer's
   top border, centered, like a bottom-sheet pull handle. Click pulls the
   ecosystem drawer open / pushes it shut.
   - Expanded (drawer open)   : chevron points down (⌄)  = "push me down to close"
   - Collapsed (drawer closed): chevron points up   (⌃)  = "pull me up to open"
   The tab shares the --bg-card material so it reads as a panel lifted out of
   the footer edge. A subtle opacity pulse on the icon draws the eye to incite
   discovery; it pauses on hover to confirm interactivity. */
@keyframes zp-footer-handle-pulse {
    0%, 100% { opacity: 0.65; }
    50%      { opacity: 1; }
}
.zp-footer .zp-footer-handle {
    position: absolute;
    left: 50%;
    bottom: 100%;
    transform: translateX(-50%);
    margin-bottom: -1px; /* overlap the footer border so the tab merges into it */
    box-sizing: border-box;
    width: 54px;
    height: 20px;
    display: flex;
    align-items: center;
    justify-content: center;
    background: var(--bg-card, #1a1d27);
    border: 1px solid var(--border, #e5e7eb);
    /* transparent (not none) so top and bottom borders stay symmetric : keeps
       the flex content-box centered, so the chevron sits dead-centre. The
       bottom edge overlaps the footer border via margin-bottom, staying invisible. */
    border-bottom-color: transparent;
    border-radius: 10px 10px 0 0;
    color: var(--accent, #6c8aff);
    cursor: pointer;
    padding: 0;
    transition: background 0.15s, color 0.15s;
}
.zp-footer .zp-footer-handle:hover {
    background: var(--bg-input, #22252f);
}
.zp-footer .zp-footer-handle:focus-visible {
    outline: 1px dotted var(--accent, #6c8aff);
    outline-offset: 2px;
}
/* Single SVG chevron that flips with the drawer state. SVG (not a Unicode
   arrowhead) so the V is symmetric, crisp and perfectly centered — no font
   metric quirks, no diagonal-corner artefact.
   - Expanded  : points down (⌄) = "push me down to close"
   - Collapsed : flipped 180° → points up (⌃) = "pull me up to open"
   A subtle opacity pulse draws the eye; it pauses on hover. */
.zp-footer .zp-footer-handle-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    transition: transform 0.3s ease;
    animation: zp-footer-handle-pulse 2.5s ease-in-out infinite;
}
.zp-footer .zp-footer-handle-icon svg {
    display: block;
}
.zp-footer .zp-footer-handle:hover .zp-footer-handle-icon {
    animation-play-state: paused;
    opacity: 1;
}
.zp-footer.collapsed .zp-footer-handle-icon {
    transform: rotate(180deg);
}
.zp-footer .zp-sep {
    color: var(--text-muted, #6b7280);
    margin: 0 5px;
    opacity: 0.5;
}
/* Separateur des MOTS-CLES, distinct de .zp-sep (demande Regis 26/07/2026).
   La barre oblique est le signe identitaire du pilier « Slasher » : l'employer aussi
   comme separateur d'enumeration brouille son sens. Le point median est deja en usage
   dans les pastilles de la carte (« Belgique · Maroc »), l'ecosysteme reste coherent.
   Classe separee et non remplacement global : entre les trois piliers, la barre reste. */
.zp-footer .zp-kw-sep {
    color: var(--text-muted, #6b7280);
    margin: 0 5px;
    opacity: 0.5;
}
@media (max-width: 600px) {
    .zp-footer { padding: 20px 16px; }
    .zp-footer .zp-footer-author { font-size: 0.85rem; }

    /* Pilier ouvert : l'URL sur une ligne, les mots-cles sur la suivante (demande
       Regis 26/07/2026). Ils se repliaient sinon n'importe ou, coupant l'enumeration
       au milieu. Le deux-points disparait, il n'a plus rien a separer une fois les
       deux blocs sur des lignes distinctes.
       La reservation passe de 1.5em a 3em EN MEME TEMPS : le bandeau reserve la place
       du detail pour ne pas sauter au clic (cf. commentaire de .zp-pillar-detail), et
       deux lignes affichees contre une reservee reintroduiraient exactement ce saut. */
    .zp-footer .zp-pillar-detail { min-height: 3em; }
    .zp-footer .zp-pillar-keywords { display: block; }
    .zp-footer .zp-pillar-colon { display: none; }
}


/* --- Cascade control (shared base for all dropdowns) --- */
.cascaded-dropdown { display: flex; flex-direction: column; gap: 6px; }

.cascade-separator {
    border-bottom: 1px solid var(--border);
    margin: 2px 0;
}

/* --- Drag handle for reorderable facets --- */
.cascade-level.reorderable {
    position: relative;
}

.drag-handle {
    position: absolute;
    left: -3px;
    top: 4px;
    bottom: 4px;
    width: 3px;
    user-select: none;
    z-index: 1;
    border-left: 1px solid var(--border);
    border-right: 1px solid var(--border);
    border-radius: 1px;
    opacity: 0.3;
    transition: opacity 0.2s, border-color 0.2s;
}

.cascade-level.reorderable:hover .drag-handle {
    opacity: 0.6;
}

.drag-handle:hover {
    opacity: 1 !important;
    border-color: var(--accent);
}

/* SortableJS drag states */
.sortable-ghost {
    opacity: 0.3;
}

.sortable-chosen {
    outline: 1px solid var(--accent);
    outline-offset: 1px;
    border-radius: 6px;
}

.sortable-drag {
    opacity: 0.9;
}

.cascade-level.reorderable > .ms-dropdown,
.cascade-level.reorderable > .ss-dropdown,
.cascade-level.reorderable > .rs-container { width: 100%; }

.cascade-control {
    width: 100%;
    padding: 6px 10px;
    padding-right: 28px;
    font-size: 0.82rem;
    font-family: var(--font);
    background: var(--bg-input);
    border: 1px solid var(--border);
    border-radius: 6px;
    color: var(--text);
    cursor: pointer;
    outline: none;
    box-sizing: border-box;
    height: 32px;
    appearance: none;
    -webkit-appearance: none;
    background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%236b7280' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
}

.cascade-control:focus { border-color: var(--accent); }
.cascade-control:not(.has-value) { color: var(--text-muted); font-style: italic; }
.cascade-control.has-value { color: var(--text); font-style: normal; }
.cascade-control option:first-child { color: var(--text-muted); font-style: italic; }
.cascade-control option { color: var(--text); font-style: normal; }

/* --- Shared trigger base (details/summary dropdowns) --- */
.zp-trigger {
    list-style: none;
    user-select: none;
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    line-height: calc(32px - 12px - 2px);
}

.zp-trigger::-webkit-details-marker { display: none; }

/* --- Shared panel base (dropdown options container) --- */
.zp-panel {
    display: flex;
    flex-direction: column;
    background: var(--bg-card);
    border: 1px solid var(--border);
    border-top: none;
    border-radius: 0 0 6px 6px;
    max-height: 180px;
    overflow-y: auto;
    scrollbar-width: thin;
    scrollbar-color: var(--border) transparent;
}

.zp-panel::-webkit-scrollbar { width: 5px; }
.zp-panel::-webkit-scrollbar-track { background: transparent; }
.zp-panel::-webkit-scrollbar-thumb { background: var(--border); border-radius: 3px; }

/* --- Shared option base --- */
.zp-option {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 4px 10px;
    font-size: 0.8rem;
    color: var(--text);
    text-decoration: none;
    transition: background 0.1s;
    border-bottom: 1px solid rgba(255,255,255,0.03);
}

.zp-option:last-child { border-bottom: none; }
.zp-option:hover { background: rgba(255,255,255,0.04); }
.zp-option.on { color: var(--accent); }

/* --- MultiSelectDropdown --- */
.ms-dropdown { }
.ms-details { position: relative; }
.ms-details[open] .ms-trigger { border-radius: 6px 6px 0 0; }

.ms-check {
    width: 14px;
    height: 14px;
    border: 1.5px solid var(--border);
    border-radius: 3px;
    flex-shrink: 0;
    position: relative;
    transition: all 0.15s;
}

.ms-option.on .ms-check {
    background: var(--accent);
    border-color: var(--accent);
}

.ms-option.on .ms-check::after {
    content: '';
    position: absolute;
    left: 3px;
    top: 1px;
    width: 5px;
    height: 8px;
    border: solid #fff;
    border-width: 0 2px 2px 0;
    transform: rotate(40deg);
}

.ms-option.on .ms-label { color: var(--accent); }
.ms-label { flex: 1; }
.ms-count { color: var(--text-muted); font-size: 0.7rem; min-width: 20px; text-align: right; }

/* --- SearchableDropDown (reuses zp-trigger, zp-panel, zp-option, ss-* for DRY) --- */
.sd-details { position: relative; }
.sd-details[open] .ss-trigger { border-radius: 6px 6px 0 0; }
.sd-details .zp-panel { max-height: 300px; }

/* Overlay input: hidden when closed, covers the summary when open */
.sd-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 32px;
    padding: 6px 10px;
    padding-right: 28px;
    border: 1px solid var(--accent);
    border-radius: 6px 6px 0 0;
    background: var(--bg-input);
    color: var(--text);
    font-size: 0.82rem;
    font-family: var(--font);
    outline: none;
    box-sizing: border-box;
    z-index: 2;
    opacity: 0;
    pointer-events: none;
}

.sd-details[open] .sd-overlay {
    opacity: 1;
    pointer-events: all;
}

.sd-overlay::placeholder { color: var(--text-muted); font-style: italic; }

/* Chevron click zone: invisible overlay on right side, pointer cursor */
.sd-chevron-zone {
    position: absolute;
    top: 0;
    right: 0;
    width: 28px;
    height: 32px;
    z-index: 3;
    cursor: pointer;
    opacity: 0;
    pointer-events: none;
}

.sd-details[open] .sd-chevron-zone {
    pointer-events: all;
}

/* Keyboard navigation highlight (lighter than active .on) */
.sd-highlight { background: rgba(255,255,255,0.06); color: var(--accent); opacity: 0.7; }
.sd-highlight.on { opacity: 1; }

/* Preview text in input during arrow navigation */
.sd-preview { color: var(--text-muted); font-style: italic; }

/* Chevron on overlay (mirrors cascade-control) */
.sd-overlay {
    background-image: url("data:image/svg+xml,%3Csvg width='10' height='6' viewBox='0 0 10 6' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M1 1l4 4 4-4' stroke='%236b7280' stroke-width='1.5' fill='none'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 10px center;
}

/* --- SingleSelectDropDown --- */
.ss-dropdown { }
.ss-details { position: relative; }
.ss-details[open] .ss-trigger { border-radius: 6px 6px 0 0; }

.ss-option.on { font-weight: 600; }
.ss-option.clear { color: var(--text-muted); font-style: italic; }
.ss-label { flex: 1; }
.ss-count { color: var(--text-muted); font-size: 0.7rem; min-width: 20px; text-align: right; }

/* --- FilterTag --- */
.filter-tag {
    display: inline-flex;
    align-items: stretch;
    gap: 0;
    padding: 0;
    border-radius: 20px;
    font-size: 0.82rem;
    font-weight: 500;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.15s;
    overflow: hidden;
}

.filter-tag:hover { filter: brightness(1.2); }
.ft-key { padding: 6px 10px; opacity: 0.7; }
.ft-sep { width: 1px; align-self: stretch; }
.ft-val { padding: 6px 8px; color: #fff; font-weight: 600; }
.filter-tag .filter-x { padding: 6px 10px 6px 4px; }

.filter-tag .ft-word {
    padding: 6px 8px;
    font-weight: 600;
    text-decoration: none;
}
.filter-tag .ft-word:hover { color: #fff; }
.filter-tag .ft-word:hover .filter-x { color: var(--red); opacity: 1; }

.filter-x {
    font-size: 1.1rem;
    line-height: 1;
    opacity: 0.6;
    transition: opacity 0.15s;
}

.filter-tag:hover .filter-x { opacity: 1; color: var(--red); }

/* --- RangeSlider --- */
.rs-container {
    padding: 6px 10px;
    border: 1px solid var(--border);
    border-radius: 6px;
    background: var(--bg-input);
    box-sizing: border-box;
}

.rs-bottom {
    display: flex;
    justify-content: space-between;
    align-items: center;
    position: relative;
    margin-top: 2px;
    height: 16px;
}

.rs-tick {
    font-size: 0.65rem;
    color: var(--text-muted);
}

.rs-selection {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    font-size: 0.72rem;
    color: var(--accent);
    font-weight: 600;
    white-space: nowrap;
}

.rs-track-wrapper {
    position: relative;
    height: 28px;
}

.rs-track {
    position: absolute;
    top: 12px;
    left: 0;
    right: 0;
    height: 4px;
    background: var(--border);
    border-radius: 2px;
}

.rs-fill {
    position: absolute;
    top: 0;
    height: 100%;
    background: var(--accent);
    border-radius: 2px;
}

.rs-input {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 28px;
    margin: 0;
    padding: 0;
    background: none;
    pointer-events: none;
    -webkit-appearance: none;
    appearance: none;
}

.rs-input::-webkit-slider-runnable-track {
    height: 4px;
    background: transparent;
}

.rs-input::-webkit-slider-thumb {
    -webkit-appearance: none;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--bg-card);
    cursor: pointer;
    pointer-events: all;
    margin-top: -6px;
    transition: box-shadow 0.15s;
}

.rs-input::-webkit-slider-thumb:hover {
    box-shadow: 0 0 0 4px rgba(108, 138, 255, 0.25);
}

.rs-input::-moz-range-track {
    height: 4px;
    background: transparent;
    border: none;
}

.rs-input::-moz-range-thumb {
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: var(--accent);
    border: 2px solid var(--bg-card);
    cursor: pointer;
    pointer-events: all;
}

.rs-input::-moz-range-thumb:hover {
    box-shadow: 0 0 0 4px rgba(108, 138, 255, 0.25);
}

/* .rs-ticks removed — replaced by .rs-bottom */
.rs-ticks-deprecated {
    display: none;
    font-size: 0.68rem;
    color: var(--text-muted);
    margin-top: 2px;
}

/* ============================================================
   ZpDataExplorer (zpx-) : URL-driven data consultation building
   blocks (ADR-021) : ZpDataGrid / ZpGridColumn / ZpPaginationNav.
   Adapted COPY of the admin dashboard patterns (.ejp-table and
   .chip-* from zp-admin.css, .ejp-group health borders from the
   CatalogStatus page) under a non-colliding zpx- prefix, with
   fallback values on every variable. The .ejp-* / .chip-*
   originals stay untouched until every page migrates.
   ============================================================ */

/* --- ZpDataGrid : table (generalization of .ejp-table) --- */
/* Scroll guard around each table : with table-layout fixed the table grows to
   the sum of its colgroup widths when that exceeds the container, and the
   wrapper turns the overflow into a horizontal scroll (never an overlap). */
.zpx-table-scroll { overflow-x: auto; }
.zpx-table { width: 100%; border-collapse: collapse; font-size: 0.9rem; table-layout: fixed; }
.zpx-table th {
    text-align: left;
    padding: 8px 12px;
    background: var(--bg-input, #f3f4f6);
    border-top: 1px solid var(--border, #e5e7eb);
    border-bottom: 1px solid var(--border, #e5e7eb);
    font-weight: 600;
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted, #6b7280);
    white-space: nowrap;
    /* Fixed layout safety : a header wider than its column degrades to an
       ellipsis instead of overlapping the next header. */
    overflow: hidden;
    text-overflow: ellipsis;
}
/* Opt-in utility (ZpGridColumn CssClass="zpx-wrap") : allow a multi-word header
   to wrap on two lines inside a narrow column (cells stay nowrap). */
.zpx-table th.zpx-wrap { white-space: normal; line-height: 1.25; }
.zpx-table td {
    padding: 8px 12px;
    border-bottom: 1px solid var(--border, #e5e7eb);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
/* Dense variant (ZpDataGrid CssClass="zpx-table--dense") : tighter horizontal
   padding for wide numeric grids (row rhythm preserved). Declared AFTER the th
   and td base rules : same specificity, the variant must win. */
.zpx-table--dense th,
.zpx-table--dense td { padding-left: 8px; padding-right: 8px; }
.zpx-table tr:last-child td { border-bottom: none; }
.zpx-table tbody tr:hover td { background: var(--accent-soft, rgba(108, 138, 255, 0.05)); }
.zpx-table code { font-family: var(--mono, ui-monospace, monospace); font-size: 0.85rem; }

/* Numeric column (ZpAlign.Right) : right-aligned, mono digits in cells. */
.zpx-num { text-align: right; }
.zpx-table td.zpx-num { font-family: var(--mono, ui-monospace, monospace); }
/* Centered column (ZpAlign.Center). */
.zpx-center { text-align: center; }

/* Sortable header links + active direction indicator (ZpSortState). */
.zpx-sort-link { color: inherit; text-decoration: none; }
.zpx-sort-link:hover { color: var(--text, #111827); }
.zpx-sort-link.on { color: var(--accent, #6c8aff); }
.zpx-sort-indicator { margin-left: 4px; font-size: 0.6rem; }

/* Empty result set (EmptyText). */
.zpx-empty { color: var(--text-muted, #6b7280); padding: 12px; }

/* Navigable row (RowNavigateUrl) : the whole row is a drill-down click target.
   Hoisted from the History admin page local styles (xRefIQ #483). */
.zpx-table .zpx-row-clickable { cursor: pointer; }
/* Keyboard focus ring (tabindex=0 rows), same pattern as .zpx-group-summary. */
.zpx-table .zpx-row-clickable:focus-visible { outline: 2px solid var(--accent, #6c8aff); outline-offset: -2px; }
.zpx-table .zpx-row-clickable:hover td { background: var(--accent-soft, rgba(108, 138, 255, 0.06)); }
.zpx-table .zpx-row-expanded > td { background: var(--accent-soft-strong, rgba(108, 138, 255, 0.10)); }
.zpx-table .zpx-detail-row td { cursor: default; }

/* URL-driven detail row (RowDetail) : full-width drill-down under its row. */
.zpx-table .zpx-detail-row td {
    padding: 14px 16px;
    background: var(--bg-card, #ffffff);
    border-top: 1px solid var(--border, #e5e7eb);
    border-bottom: 2px solid var(--accent, #6c8aff);
    white-space: normal;
}

/* --- ZpDataGrid : groups. One <details> card per group, health signal
       as a 4px left border (green / orange / red / yellow). --- */
.zpx-group {
    background: var(--bg-card, #ffffff);
    border: 1px solid var(--border, #e5e7eb);
    border-left-width: 4px;
    border-radius: var(--radius, 8px);
    margin-bottom: 10px;
    overflow: hidden;
    transition: border-color 0.2s;
}

/* Sous-groupes (xRefIQ #484/#485, SubGroupBy) : carte imbriquee plus discrete,
   indentee, meme signal sante par bordure gauche que les groupes. */
.zpx-subgroup {
    background: var(--bg-card, #ffffff);
    border: 1px solid var(--border, #e5e7eb);
    border-left-width: 3px;
    border-radius: var(--radius, 8px);
    margin: 0 10px 8px 22px;
    overflow: hidden;
}
.zpx-subgroup > summary.zpx-group-summary { padding: 8px 12px; font-size: 0.9rem; }
.zpx-subgroup .zpx-group-title { font-size: 0.9rem; }

/* Sante PAR LIGNE (xRefIQ #484/#485) : liseret gauche via box-shadow inset
   (une bordure sur <tr> est inconsistante entre navigateurs). La page pose la
   classe via RowCssClass. */
.zpx-table tr.zpx-row-health-healthy { box-shadow: inset 3px 0 0 var(--green, #4ade80); }
.zpx-table tr.zpx-row-health-partial { box-shadow: inset 3px 0 0 var(--orange, #fb923c); }
.zpx-table tr.zpx-row-health-failed { box-shadow: inset 3px 0 0 var(--red, #f87171); }
.zpx-table tr.zpx-row-health-neverrun { box-shadow: inset 3px 0 0 var(--yellow, #facc15); }
.zpx-group-summary {
    padding: 12px 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    gap: 16px;
    user-select: none;
}
.zpx-group-summary:hover { background: var(--accent-soft, rgba(108, 138, 255, 0.05)); }
/* Mouse click : no browser focus ring (it fights the health border) ;
   keyboard users keep it via :focus-visible (a11y). */
.zpx-group-summary:focus { outline: none; }
.zpx-group-summary:focus-visible { outline: 2px solid var(--accent, #6c8aff); outline-offset: -2px; }
.zpx-group-title strong { font-size: 1.05rem; }
.zpx-group-subtitle { color: var(--text-muted, #6b7280); font-size: 0.85rem; }
.zpx-health-healthy  { border-left-color: var(--green, #4ade80); }
.zpx-health-partial  { border-left-color: var(--orange, #fb923c); }
.zpx-health-failed   { border-left-color: var(--red, #f87171); }
.zpx-health-neverrun { border-left-color: var(--yellow, #facc15); }

/* --- ZpDataGrid : mode de groupement Flat (GroupLayout, xRefIQ #567) ---
       UNE table, UN thead, UN colgroup, puis un <tbody> par groupe : forme HTML
       canonique d'un groupement tabulaire. Additions pures : rien au-dessus n'est
       modifie, et chaque regle est ancree sur du markup que SEULE une page ayant
       demande le mode Flat (ou l'en-tete collant) fait apparaitre.

       REGLE DE PORTEE, non negociable ici : aucun selecteur de DESCENDANCE nu du
       genre `.zpx-table tbody th` ou `.zpx-table--sticky thead th`. Un consommateur
       rend sa propre table DANS une ligne de detail (RowDetail) : ses th sont alors
       des descendants du tbody de la grille, et une telle regle les capturerait en
       mode Cards par defaut, avec une specificite qui bat le style de la page.
       Chaque selecteur part donc d'une classe posee par ce mode (.zpx-group-row,
       .zpx-subgroup-row, tbody.zpx-group) ou descend en enfant direct. Verrouille
       par ZpDataGridFlatLayoutTests.CardsLayout_NestedTableInARowDetail_* --- */

/* En-tete collant (StickyHeader). Le box-shadow est OBLIGATOIRE : en
   border-collapse: collapse, la bordure basse d'un th appartient a la table et ne
   suit donc PAS la cellule collee au defilement. Le fond du th est deja opaque
   (var(--bg-input) plus haut) : ne jamais le rendre semi-transparent, les lignes
   defileraient au travers. L'offset vertical est une variable posee par la page
   (hauteur de son propre bandeau colle), pas un parametre du composant : le
   composant qui l'ignorerait serait le seul a ne pas savoir ou commence la page.
   Chaine d'enfants directs : une table imbriquee dans une ligne de detail ne doit
   pas voir ses propres en-tetes devenir collants. */
.zpx-table--sticky > thead > tr > th {
    position: sticky;
    top: var(--zpx-head-top, 0px);
    z-index: 5;
    box-shadow: inset 0 -1px 0 var(--border, #e5e7eb);
}

/* Le <tbody> porte .zpx-group : la carte (fond, contour, coins arrondis) n'a pas de
   sens sur un groupe de lignes, seul le regroupement compte. Le signal sante reste
   visible, porte par la ligne d'en-tete du groupe (.zpx-row-health-*). */
.zpx-table tbody.zpx-group {
    background: transparent;
    border: none;
    border-radius: 0;
    margin-bottom: 0;
}

/* Separation entre deux groupes consecutifs : la seule frontiere visible entre
   deux tbody, puisqu'il n'y a plus de carte pour les delimiter. */
.zpx-table tbody.zpx-group + tbody.zpx-group > tr:first-child > td,
.zpx-table tbody.zpx-group + tbody.zpx-group > tr:first-child > th {
    border-top: 2px solid var(--border, #e5e7eb);
}

/* Ligne d'en-tete d'un groupe, premiere ligne de son tbody. Les cellules viennent
   de la page (GroupRowCells) ou du repli pleine largeur. */
.zpx-table tr.zpx-group-row > td,
.zpx-table tr.zpx-group-row > th {
    background: var(--bg-input, #f3f4f6);
    font-weight: 600;
    white-space: nowrap;
}

/* Ligne d'en-tete d'un sous-groupe : meme tbody, un cran plus discret et indente. */
.zpx-table tr.zpx-subgroup-row > td,
.zpx-table tr.zpx-subgroup-row > th {
    background: var(--bg-card, #ffffff);
    font-weight: 600;
    white-space: nowrap;
}
.zpx-table tr.zpx-subgroup-row > :first-child { padding-left: 24px; }

/* Une ligne de groupe peut commencer par un <th scope="rowgroup"> : c'est la forme
   accessible d'un en-tete de groupe de lignes. Sans ce reset, il heriterait du style
   des en-tetes de COLONNES (majuscules, 0.72rem, gris) et hurlerait. Ancre sur les
   deux classes de ligne de groupe, jamais sur `tbody th` : ces classes n'existent
   que dans le mode Flat, la ou ce th est reellement emis. Le FOND n'est pas remis
   ici : il appartient aux deux regles ci-dessus, de meme specificite, qui gagneraient
   ou perdraient selon l'ordre d'ecriture. */
.zpx-table tr.zpx-group-row > th,
.zpx-table tr.zpx-subgroup-row > th {
    text-transform: none;
    font-size: inherit;
    letter-spacing: normal;
    color: inherit;
}

/* Chiffres a chasse fixe dans les lignes d'une grille aplatie : c'est la ou une
   colonne de 200 nombres ondule si la chasse varie. Restreint aux cellules filles
   des lignes d'un groupe : les grilles en mode Cards gardent leur typographie, et
   une table imbriquee dans une ligne de detail n'est pas concernee. */
.zpx-table > tbody.zpx-group > tr > .zpx-num { font-variant-numeric: tabular-nums; }

/* --- ZpPaginationNav (hoist of the History pager + .ejp-icon-btn) --- */
.zpx-pagination { display: flex; align-items: center; justify-content: center; gap: 8px; flex-wrap: wrap; }
.zpx-pagination-summary { color: var(--text-muted, #6b7280); }
.zpx-pagination-label { color: var(--text-muted, #6b7280); }
.zpx-page-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 26px;
    border-radius: calc(var(--radius, 8px) - 2px);
    background: var(--bg-input, #f3f4f6);
    border: 1px solid var(--border, #e5e7eb);
    color: var(--text-muted, #6b7280);
    text-decoration: none;
    transition: all 0.15s;
    cursor: pointer;
}
.zpx-page-btn:hover { color: var(--text, #111827); }
.zpx-page-btn svg { width: 14px; height: 14px; flex-shrink: 0; }
.zpx-page-btn.disabled,
.zpx-page-btn[aria-disabled="true"] { opacity: 0.3; pointer-events: none; }
.zpx-pagesize { display: inline-flex; align-items: center; gap: 8px; }
.zpx-pagesize .ss-dropdown { width: 80px; }

/* --- Badges : copy of the zp-admin.css .chip-* palette under a
       non-colliding name (the .chip facette collision is resolved
       by this rename, ADR-021 section 4). --- */
/* The tone modifiers only set the two --zpx-tone-* custom properties; the badge
   consumes them, and so do the colored facet chips (ValueCssClass) : one tone
   declaration, several renderings. */
.zpx-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 12px;
    font-size: 0.8rem;
    font-weight: 600;
    background: var(--zpx-tone-bg, transparent);
    color: var(--zpx-tone-fg, inherit);
}
.zpx-badge--success  { --zpx-tone-bg: rgba(74, 222, 128, 0.15);  --zpx-tone-fg: var(--green, #4ade80); }
.zpx-badge--warning  { --zpx-tone-bg: rgba(251, 146, 60, 0.15);  --zpx-tone-fg: var(--orange, #fb923c); }
.zpx-badge--failed   { --zpx-tone-bg: rgba(248, 113, 113, 0.15); --zpx-tone-fg: var(--red, #f87171); }
.zpx-badge--progress { --zpx-tone-bg: rgba(108, 138, 255, 0.15); --zpx-tone-fg: var(--accent, #6c8aff); }
.zpx-badge--skipped  { --zpx-tone-bg: rgba(139, 141, 151, 0.15); --zpx-tone-fg: var(--text-muted, #6b7280); }
.zpx-badge--unknown  { --zpx-tone-bg: rgba(250, 204, 21, 0.15);  --zpx-tone-fg: var(--yellow, #facc15); }
/* Badge as a link (e.g. stats chips toggling a facet) : same visual, plus
   hover feedback and an "active" ring when the matching filter is on. */
a.zpx-badge { text-decoration: none; cursor: pointer; }
a.zpx-badge:hover { filter: brightness(1.2); }
.zpx-badge.active { outline: 1px solid currentColor; outline-offset: 1px; }

/* --- ZpDataExplorer : two-column layout (generalization of the Search
       .results-layout of app.css, sidebar width driven by a variable). --- */
.zpx-layout {
    display: grid;
    grid-template-columns: var(--zpx-sidebar-width, 240px) 1fr;
    gap: 24px;
    align-items: start;
}
.zpx-layout--nofacets { grid-template-columns: 1fr; }
@media (max-width: 768px) {
    .zpx-layout { grid-template-columns: 1fr; }
}
/* Full-width page MARKER (ZpDataExplorer FullWidth) : the explorer only tags
   itself (it already spans 100% of its parent) ; the HOST's page wrappers opt
   their max-width out via :has(.zpx-page--full) (see app.css / zp-admin.css in
   the consuming site), keeping their own lateral padding. Page-level modality :
   content pages keep their max-width. */
.zpx-page--full { width: 100%; }
/* Right column : toolbar / segmented / stats / pagination / active view stack. */
.zpx-content { display: flex; flex-direction: column; gap: 12px; min-width: 0; }

/* --- ZpFacetsPanel : neutral facets sidebar (adapted copy of the Search
       .facets-sidebar / .facet-* patterns of app.css, fallback variables ;
       the originals stay untouched until the Search migrates). --- */
.zpx-sidebar { display: flex; flex-direction: column; gap: 10px; }
.zpx-facet-group {
    background: var(--bg-card, #ffffff);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: var(--radius, 8px);
    overflow: hidden;
    /* Positioning context for the GroupHelp icon (#468). */
    position: relative;
}
.zpx-facet-header {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    padding: 10px;
    list-style: none;
    user-select: none;
}
summary.zpx-facet-header { cursor: pointer; }
.zpx-facet-header::-webkit-details-marker { display: none; }
.zpx-facet-title {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 1px;
    color: var(--accent, #6c8aff);
    font-weight: 700;
}
.zpx-facet-chevron {
    color: var(--text-muted, #6b7280);
    font-size: 0.7rem;
    margin-left: auto;
    transition: transform 0.2s;
}
details.zpx-facet-group[open] .zpx-facet-chevron { transform: rotate(180deg); }
/* Collapsed group : the header recaps the active values ; open : hidden
   (the controls themselves show the selection). */
.zpx-facet-summary-chips {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    align-items: center;
    width: 100%;
    padding-top: 6px;
}
details.zpx-facet-group[open] .zpx-facet-summary-chips { display: none; }

/* --- Group legend (GroupHelp, #468) : native <details>, zero server state.
       The icon cannot be a child of the group <summary> (nested summary =
       invalid HTML + double toggle) : it renders AFTER the summary and the CSS
       positions it into the header row, left of the chevron. Collapsing the
       group hides it naturally (non-summary child of a closed <details>). A
       fragment rendering nothing for the group key leaves the panel :empty and
       the :has() guard hides the whole legend. --- */
.zpx-facet-help { margin: 0; }
.zpx-facet-help:has(> .zpx-facet-help-panel:empty) { display: none; }
.zpx-facet-help-icon {
    position: absolute;
    top: 10px;
    right: 32px;
    width: 16px;
    height: 16px;
    border: 1px solid var(--text-muted, #6b7280);
    border-radius: 50%;
    color: var(--text-muted, #6b7280);
    font-family: Georgia, 'Times New Roman', serif;
    font-size: 0.68rem;
    font-style: italic;
    font-weight: 600;
    line-height: 14px;
    text-align: center;
    cursor: pointer;
    list-style: none;
    user-select: none;
    box-sizing: border-box;
}
.zpx-facet-help-icon::-webkit-details-marker { display: none; }
.zpx-facet-help-icon:hover,
.zpx-facet-help[open] > .zpx-facet-help-icon {
    color: var(--accent, #6c8aff);
    border-color: var(--accent, #6c8aff);
}
/* Static groups have no chevron : the icon takes the right edge. */
.zpx-facet-group--static .zpx-facet-help-icon { right: 10px; }
/* Discreet in-flow panel at the top of the group body area. */
.zpx-facet-help-panel {
    display: flex;
    flex-direction: column;
    gap: 6px;
    padding: 8px 10px;
    border-bottom: 1px dashed var(--border, #e5e7eb);
    font-size: 0.75rem;
    line-height: 1.35;
    color: var(--text-muted, #6b7280);
}

.zpx-facet-body { padding: 10px 10px 12px; }
/* Non-interactive fixed context chips (ZpFacetGroup.FixedContext). */
.zpx-facet-fixed {
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
    margin: 0 0 10px;
    padding-bottom: 10px;
    border-bottom: 1px solid var(--border, #e5e7eb);
}
.zpx-facet-section { margin: 0 0 10px; }

/* Drag-reorder des facettes (xRefIQ #498) : poignee revelee au survol de la section,
   dans un groupe Reorderable uniquement (le markup n'emet la poignee que la).
   Les etats SortableJS (.sortable-ghost/chosen/drag) sont les globaux existants. */
.zpx-facet-sortable > .zpx-facet-section { position: relative; }
.zpx-drag-handle {
    position: absolute;
    top: 0;
    right: 0;
    cursor: grab;
    color: var(--text-muted, #6b7280);
    font-size: 0.75rem;
    line-height: 1;
    padding: 2px 4px;
    opacity: 0;
    transition: opacity 0.15s ease;
    user-select: none;
}
.zpx-facet-sortable > .zpx-facet-section:hover .zpx-drag-handle { opacity: 1; }
.zpx-drag-handle:active { cursor: grabbing; }
.zpx-facet-section:last-child { margin-bottom: 0; }
.zpx-facet-label {
    font-size: 0.7rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    color: var(--text-muted, #6b7280);
    margin-bottom: 5px;
}

/* Chips (links) + header recap chips (spans) share the same visual. */
.zpx-facet-chips { display: flex; flex-wrap: wrap; gap: 5px; }
.zpx-facet-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 10px;
    border-radius: 12px;
    font-size: 0.75rem;
    background: var(--bg-input, #f3f4f6);
    border: 1px solid var(--border, #e5e7eb);
    color: var(--text, #111827);
    text-decoration: none;
    transition: all 0.15s;
}
a.zpx-facet-chip { cursor: pointer; }
a.zpx-facet-chip:hover { border-color: var(--accent, #6c8aff); color: var(--accent, #6c8aff); }
.zpx-facet-chip.active { background: var(--accent, #6c8aff); border-color: var(--accent, #6c8aff); color: #fff; }
.zpx-facet-chip .zpx-count { font-size: 0.68rem; color: var(--text-muted, #6b7280); }
.zpx-facet-chip.active .zpx-count { color: rgba(255, 255, 255, 0.7); }
/* Inert MaxVisible truncation hint (no URL-driven "show more" in v1). */
.zpx-facet-more { font-size: 0.72rem; color: var(--text-muted, #6b7280); align-self: center; }

/* --- Colored facet chips (ValueCssClass mapping to a .zpx-badge--* tone) : the
       chip SHAPE wins over the badge shape (explicit combined rules, no order
       dependency), the tone drives the color. Filtering legend states :
       inactive = default chip skin + leading tone dot ; active = full badge
       tone + accent ring (stays distinguishable from the tone itself). --- */
.zpx-facet-chip.zpx-badge {
    display: inline-flex;
    padding: 3px 10px;
    font-size: 0.75rem;
    font-weight: 600;
    background: var(--bg-input, #f3f4f6);
    border-color: var(--border, #e5e7eb);
    color: var(--text, #111827);
}
.zpx-facet-chip.zpx-badge::before {
    content: "";
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--zpx-tone-fg, currentColor);
    flex-shrink: 0;
}
a.zpx-facet-chip.zpx-badge:hover {
    border-color: var(--zpx-tone-fg, var(--accent, #6c8aff));
    color: var(--text, #111827);
}
.zpx-facet-chip.zpx-badge.active {
    background: var(--zpx-tone-bg, var(--accent, #6c8aff));
    border-color: transparent;
    color: var(--zpx-tone-fg, #fff);
    outline: 2px solid var(--accent, #6c8aff);
    outline-offset: 1px;
}
.zpx-facet-chip.zpx-badge .zpx-count { color: inherit; opacity: 0.75; }

/* ShowValueChips legend panel under a DropDown / MultiSelect control : reads as
   "one filter + its legend" (discreet control, tight pills grid below). */
.zpx-facet-legend { margin-top: 6px; gap: 4px; }

/* Vertical link list with counts (ZpFacetKind.List). */
.zpx-facet-list { display: flex; flex-direction: column; }
.zpx-facet-item {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 3px 0;
    font-size: 0.85rem;
    /* Tone-aware: a ValueCssClass tone modifier (zpx-badge--*) wins over the default text color. */
    color: var(--zpx-tone-fg, var(--text, #111827));
    text-decoration: none;
    cursor: pointer;
}
.zpx-facet-item:hover { color: var(--zpx-tone-fg, var(--accent, #6c8aff)); filter: brightness(1.15); }
.zpx-facet-item .zpx-count { margin-left: auto; color: var(--text-muted, #6b7280); font-size: 0.75rem; }
.zpx-facet-item.active { color: var(--zpx-tone-fg, var(--accent, #6c8aff)); font-weight: 600; }

/* Single on/off link (ZpFacetKind.Toggle). */
.zpx-toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 6px 12px;
    font-size: 0.8rem;
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 8px;
    background: var(--bg-input, #f3f4f6);
    color: var(--text, #111827);
    text-decoration: none;
    cursor: pointer;
    transition: all 0.15s;
}
.zpx-toggle:hover { background: var(--border, #e5e7eb); }
.zpx-toggle.active {
    background: var(--accent, #6c8aff);
    border-color: var(--accent, #6c8aff);
    color: #fff;
    font-weight: 600;
}

/* GET form facets (TextInput / NumberInput), hidden params preserve URL state.
   #468 : consecutive input facets share ONE form (--group modifier) : stacked
   sections, then an actions row (single OK + optional Reset link). */
.zpx-facet-form { display: flex; align-items: center; gap: 6px; }
.zpx-facet-form--group { flex-direction: column; align-items: stretch; gap: 0; }
.zpx-facet-input-row { display: flex; align-items: center; gap: 6px; }
.zpx-facet-actions { display: flex; align-items: center; gap: 10px; margin-top: 2px; }
.zpx-facet-reset {
    font-size: 0.75rem;
    color: var(--text-muted, #6b7280);
    text-decoration: none;
}
.zpx-facet-reset:hover { color: var(--accent, #6c8aff); text-decoration: underline; }
.zpx-facet-input {
    flex: 1;
    min-width: 0;
    padding: 6px 10px;
    font-size: 0.82rem;
    background: var(--bg-input, #f3f4f6);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 6px;
    color: var(--text, #111827);
}
.zpx-facet-input:focus { outline: none; border-color: var(--accent, #6c8aff); }
.zpx-facet-unit { color: var(--text-muted, #6b7280); font-size: 0.75rem; flex-shrink: 0; }
.zpx-facet-ok {
    padding: 6px 10px;
    font-size: 0.78rem;
    font-weight: 600;
    background: var(--bg-input, #f3f4f6);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: 6px;
    color: var(--text-muted, #6b7280);
    cursor: pointer;
    transition: all 0.15s;
}
.zpx-facet-ok:hover { color: var(--text, #111827); border-color: var(--accent, #6c8aff); }

/* --- ZpDataExplorer : view switcher (copy of .ejp-segmented with fallbacks). --- */
.zpx-segmented {
    display: inline-flex;
    align-self: flex-start;
    border-radius: calc(var(--radius, 8px) - 2px);
    overflow: hidden;
    border: 1px solid var(--border, #e5e7eb);
}
.zpx-segmented a {
    padding: 4px 12px;
    font-size: 0.75rem;
    color: var(--text-muted, #6b7280);
    background: var(--bg-input, #f3f4f6);
    text-decoration: none;
    cursor: pointer;
    transition: all 0.15s;
    border-right: 1px solid var(--border, #e5e7eb);
    white-space: nowrap;
}
.zpx-segmented a:last-child { border-right: none; }
.zpx-segmented a:hover { background: var(--border, #e5e7eb); color: var(--text, #111827); }
.zpx-segmented a.active { background: var(--accent, #6c8aff); color: #fff; font-weight: 600; }

/* --- ZpDataExplorer : toolbar slot (sticky top, copy of .ejp-filters). --- */
.zpx-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    flex-wrap: wrap;
    padding: 6px 12px;
    background: var(--bg-card, #ffffff);
    border: 1px solid var(--border, #e5e7eb);
    border-radius: var(--radius, 8px);
    position: sticky;
    top: 0;
    z-index: 20;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
}

/* #468 : compact header (ZpDataExplorer CompactHeader), comportement HISTORIQUE
   (pages sans slots) : Toolbar slot LEFT and the full top pagination RIGHT on ONE
   row. The pager moves below as a unit when the row is too narrow. */
.zpx-toolbar--compact .zpx-toolbar-pager { margin-left: auto; display: flex; align-items: center; }
.zpx-toolbar--compact .zpx-toolbar-pager .zpx-pagination { flex-wrap: nowrap; }

/* #125 : pager CENTRÉ, OPT-IN via les slots standard .zpx-toolbar-left (colonne 1)
   et/ou .zpx-toolbar-actions (colonne 3) : le grid ne s'applique QU'AUX toolbars qui
   regroupent leur contenu dans ces conteneurs (review Copilot #127 : sans ce gate,
   des nœuds racine libres deviendraient autant d'items grid). minmax(0,1fr) laisse
   les colonnes latérales se rétrécir (min-width:auto piège du grid). Hoisted from
   the per-page CSS (History #494, price #473, customers #511). */
.zpx-toolbar--compact:has(> .zpx-toolbar-left, > .zpx-toolbar-actions) {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
    align-items: center;
}
.zpx-toolbar--compact .zpx-toolbar-left { grid-row: 1; grid-column: 1; display: inline-flex; align-items: center; gap: 10px; }
.zpx-toolbar--compact:has(> .zpx-toolbar-left, > .zpx-toolbar-actions) .zpx-toolbar-pager { grid-row: 1; grid-column: 2; margin-left: 0; }
.zpx-toolbar--compact .zpx-toolbar-actions { grid-row: 1; grid-column: 3; display: inline-flex; justify-content: flex-end; align-items: center; gap: 10px; }
@media (max-width: 1100px) {
    .zpx-toolbar--compact:has(> .zpx-toolbar-left, > .zpx-toolbar-actions) { display: flex; flex-wrap: wrap; }
    /* Sous le seuil, le pager descend en ligne dédiée pleine largeur, centré. */
    .zpx-toolbar--compact:has(> .zpx-toolbar-left, > .zpx-toolbar-actions) .zpx-toolbar-pager { flex-basis: 100%; justify-content: center; }
}

/* #468 : « Lignes » page-size combo : the SearchableDropDown panel must OVERLAY
   the content below, not open in flow (it used to push the whole grid down).
   Same recipe as the zp-admin.css overrides (.ejp-pagesize-control) but scoped
   to the zpx page-size control ONLY : the Search sidebar usages keep their
   designed in-flow panel. The bottom bar renders no page-size selector, so no
   upward-opening variant is needed. */
.zpx-pagesize .sd-details { position: relative; }
.zpx-pagesize .sd-details .zp-panel {
    position: absolute;
    top: 100%;
    right: 0;
    min-width: 120px;
    z-index: 200;
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.35);
}

/* Stats slot (chips, counters). */
.zpx-stats { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* --- ZpDataExplorer : bottom pagination (copy of .ejp-sticky-bottom). The
       bottom bar renders page links only (a page-size panel would open
       downward off-screen), so no upward-opening override is needed. --- */
.zpx-sticky-bottom {
    position: sticky;
    bottom: 0;
    z-index: 20;
    padding: 6px 0;
    background: var(--bg-card, #ffffff);
    /* Barre DOCKEE assumee (xRefIQ #494) : la bordure haute marque la frontiere avec
       les lignes qu'elle recouvre pendant le scroll, l'ombre seule lisait comme un
       chevauchement accidentel. */
    border-top: 1px solid var(--border, #e5e7eb);
    box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.15);
    /* #125 : pager du bas centre, comme celui du header compact. */
    display: flex;
    justify-content: center;
}

/* ============================================================
   ZpSinglePage — carte de visite single page (23/07/2026).
   Theming par variables --zps-* : le site hôte les définit dans
   son app.css (pattern ZpFooter) ; fallbacks neutres ci-dessous.
   ============================================================ */

/* Lien d'evitement (WCAG 2.4.1 Bypass Blocks) : hors ecran tant qu'il n'a pas
   le focus, il apparait des la premiere tabulation et mene au contenu. */
.zps-skip {
    position: absolute;
    left: 8px;
    top: -64px;
    z-index: 100;
    padding: 10px 16px;
    border-radius: 10px;
    background: var(--zps-accent, #374151);
    color: var(--zps-cta-text, #ffffff);
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: 15px;
    font-weight: 600;
    text-decoration: none;
    transition: top 0.15s ease;
}
.zps-skip:focus {
    top: 8px;
}

.zps-nav {
    position: fixed;
    top: 0; left: 0; right: 0;
    z-index: 50;
    height: 68px;
    display: flex;
    align-items: center;
    backdrop-filter: blur(14px);
    background: var(--zps-nav-bg, rgba(255, 255, 255, 0.92));
    border-bottom: 1px solid var(--zps-border, #e5e7eb);
}
.zps-nav__inner {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    width: 100%;
    max-width: 1168px;
    margin: 0 auto;
    padding: 0 24px;
}
.zps-nav__brand {
    display: flex;
    align-items: baseline;
    gap: 10px;
    text-decoration: none;
}
.zps-nav__brand-logo { height: 32px; width: auto; }
.zps-nav__brand-name {
    font-family: var(--zps-font-display, Georgia, serif);
    font-size: 18px;
    font-weight: 700;
    letter-spacing: 0.04em;
    color: var(--zps-text, #1f2937);
}
.zps-nav__brand-sub {
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.14em;
    text-transform: uppercase;
    color: var(--zps-muted, #6b7280);
}
.zps-nav__contact {
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: 14px;
    font-weight: 500;
    text-decoration: none;
    color: var(--zps-muted, #6b7280);
    transition: color 0.3s;
}
.zps-nav__contact:hover { color: var(--zps-accent, #374151); }

.zps-hero {
    display: flex;
    align-items: center;
    padding: 96px 0 12px;
    background: var(--zps-hero-bg, transparent);
}
.zps-hero__inner { max-width: 1168px; margin: 0 auto; width: 100%; padding: 0 24px; }
.zps-hero__tags {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-bottom: 26px;
}
.zps-hero__tag {
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: 13px;
    font-weight: 600;
    padding: 5px 14px;
    border-radius: 20px;
    border: 1px solid var(--zps-border, #e5e7eb);
    color: var(--zps-muted, #6b7280);
    background: var(--zps-tag-bg, rgba(0, 0, 0, 0.03));
}
.zps-hero__title {
    font-family: var(--zps-font-display, Georgia, serif);
    font-size: clamp(34px, 5.6vw, 64px);
    font-weight: 400;
    line-height: 1.12;
    color: var(--zps-title, var(--zps-text, #1f2937));
    margin: 0 0 22px;
}
.zps-accent { color: var(--zps-accent, #374151); font-style: italic; }
.zps-hero__subtitle {
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: clamp(16px, 1.8vw, 19px);
    line-height: 1.65;
    color: var(--zps-muted, #6b7280);
    max-width: 58ch;
    margin: 0 0 26px;
}
.zps-hero__actions { display: flex; gap: 12px; flex-wrap: wrap; }
.zps-hero__cta {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: 16px;
    font-weight: 600;
    text-decoration: none;
    color: var(--zps-cta-text, #ffffff);
    background: var(--zps-accent, #374151);
    padding: 14px 30px;
    border-radius: 12px;
    transition: filter 0.3s, transform 0.3s;
}
.zps-hero__cta:hover { filter: brightness(0.92); transform: translateY(-1px); }
.zps-hero__quote {
    font-family: var(--zps-font-display, Georgia, serif);
    font-style: italic;
    font-size: 15px;
    color: var(--zps-muted, #6b7280);
    opacity: 0.85;
    margin: 38px 0 0;
    padding-left: 14px;
    border-left: 2px solid var(--zps-accent, #374151);
    max-width: 62ch;
}

.zps-contact {
    padding: 12px 0 48px;
    text-align: center;
    background: var(--zps-contact-bg, transparent);
}
.zps-contact__inner { max-width: 908px; margin: 0 auto; padding: 0 24px; }
.zps-contact__title {
    font-family: var(--zps-font-display, Georgia, serif);
    font-size: clamp(26px, 3.6vw, 40px);
    font-weight: 400;
    color: var(--zps-contact-title, var(--zps-text, #1f2937));
    margin: 0 0 14px;
}
.zps-contact__text {
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: 17px;
    line-height: 1.65;
    color: var(--zps-contact-muted, var(--zps-muted, #6b7280));
    margin: 0 0 30px;
}
.zps-contact__links {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 10px;
    margin-bottom: 26px;
}
.zps-contact__link {
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: 14px;
    font-weight: 600;
    text-decoration: none;
    padding: 9px 18px;
    border-radius: 10px;
    border: 1px solid var(--zps-border, #e5e7eb);
    color: var(--zps-contact-muted, var(--zps-muted, #6b7280));
    background: var(--zps-tag-bg, rgba(0, 0, 0, 0.03));
    transition: transform 0.3s;
}
.zps-contact__link:hover { transform: translateY(-1px); }
.zps-contact__meta {
    font-family: var(--zps-font-body, system-ui, sans-serif);
    font-size: 15px;
    color: var(--zps-contact-muted, var(--zps-muted, #6b7280));
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 8px 22px;
    margin: 0;
}
.zps-contact__phone { color: inherit; text-decoration: none; }
.zps-contact__phone:hover { color: var(--zps-accent, #374151); }

@media (max-width: 640px) {
    .zps-hero { padding-top: 104px; }
    .zps-nav__brand-sub { display: none; }
}

/* Version cliquable du ZpFooter (VersionUrl -> changelog, pattern xRefIQ) */
.zp-footer .zp-footer-version-link {
    color: inherit;
    text-decoration: underline dotted;
    text-underline-offset: 3px;
}
.zp-footer .zp-footer-version-link:hover { color: var(--accent, #6c8aff); }

/* Respect de la preference systeme « moins d'animations » (WCAG 2.3.3, et
   confort des personnes sensibles au mouvement). La pulsation de la poignee et
   les transitions du tiroir sont purement decoratives : on les coupe. */
@media (prefers-reduced-motion: reduce) {
    .zp-footer .zp-footer-handle-icon { animation: none; }
    .zp-footer .zp-footer-ecosystem,
    .zp-footer .zp-footer-handle,
    .zps-skip,
    .zps-hero__cta,
    .zps-contact__link { transition: none; }
}

/* Bouton principal de la rangee contact : style derive des pills, accentue */
.zps-contact__link--primary {
    background: var(--zps-accent, #374151);
    border-color: var(--zps-accent, #374151);
    color: var(--zps-cta-text, #ffffff);
    font-weight: 700;
}
.zps-contact__link--primary:hover { filter: brightness(0.92); }


/* ZpFooter en mode calque (spec Regis 23/07/2026) : quand le contenu tient dans
   l'ecran, le footer se fixe au fond du viewport comme une surcouche de la page ;
   sinon il reste en flux normal en fin de document. La classe est posee par le
   script du composant (mesure au chargement et au resize). */
.zp-footer--overlay {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 40;
    box-shadow: 0 -6px 24px rgba(0, 0, 0, 0.08);
}

/* ============================================================
   ZpSinglePage : variantes de composition (comparatif 23/07/2026)
   a = centre sobre | b = gauche + signature slash | c = immersif
   ============================================================ */
.zps { position: relative; overflow: clip; }
.zps, .zps *, .zps *::before, .zps *::after { box-sizing: border-box; }  /* clip X ET Y : le filigrane ne doit pas gonfler la hauteur du document */
.zps > .zps-hero .zps-hero__inner,
.zps > .zps-contact .zps-contact__inner { position: relative; z-index: 1; }

/* --- A : tout centre --- */
.zps--a .zps-hero__inner { text-align: center; }
.zps--a .zps-hero__tags { justify-content: center; }
.zps--a .zps-hero__title { margin-left: auto; margin-right: auto; }
.zps--a .zps-hero__subtitle { margin-left: auto; margin-right: auto; }
.zps--a .zps-hero__actions { justify-content: center; }

/* --- B : tout a gauche + signature slash en filigrane --- */
.zps--b::before {
    content: "/";
    position: absolute;
    top: -6vh;
    right: 7vw;
    font-family: var(--zps-font-display, Georgia, serif);
    font-style: italic;
    font-size: 100vh;
    line-height: 1;
    color: var(--zps-accent, #374151);
    opacity: 0.06;
    pointer-events: none;
    z-index: 0;
}
.zps--b .zps-contact { text-align: left; }
.zps--b .zps-contact__inner { max-width: 1168px; margin: 0 auto; }
.zps--b .zps-contact__links { justify-content: flex-start; }
.zps--b .zps-contact__meta { justify-content: flex-start; }
/* couleur resserree : liens neutres, seul le CTA principal garde l'accent
   (!important : neutralise les styles inline issus du JSON pour le comparatif) */
.zps--b .zps-contact__link:not(.zps-contact__link--primary) {
    color: var(--zps-muted, #6b7280) !important;
    border-color: var(--zps-border, #e5e7eb) !important;
    background: var(--zps-tag-bg, rgba(0, 0, 0, 0.03)) !important;
}
@media (max-width: 900px) {
    .zps--b::before { display: none; }
}

/* --- C : filigrane rayures multicolores + centre --- */
.zps--c {
    background:
        repeating-linear-gradient(90deg,
            transparent 0 138px, rgba(42, 140, 130, 0.05) 138px 140px,
            transparent 140px 296px, rgba(231, 111, 81, 0.045) 296px 298px,
            transparent 298px 452px, rgba(232, 122, 46, 0.04) 452px 454px,
            transparent 454px 600px);
}
.zps--c .zps-hero__inner { text-align: center; }
.zps--c .zps-hero__tags { justify-content: center; }
.zps--c .zps-hero__title { margin-left: auto; margin-right: auto; }
.zps--c .zps-hero__subtitle { margin-left: auto; margin-right: auto; }
.zps--c .zps-hero__actions { justify-content: center; }

/* Fix variante C : les fonds opaques hero/contact masquaient le filigrane raye du wrapper */
.zps--c .zps-hero { background: transparent; }
.zps--c .zps-contact { background: transparent; }

/* --- D (exploration Regis 23/07) : nav epuree centree sans lien Contact,
   contenu centre, signature slash conservee, liens neutres --- */
.zps--d .zps-nav__inner { justify-content: center; }
.zps--d .zps-nav__contact { display: none; }
.zps--d .zps-hero__inner { text-align: center; }
.zps--d .zps-hero__tags { justify-content: center; }
.zps--d .zps-hero__title { margin-left: auto; margin-right: auto; }
.zps--d .zps-hero__subtitle { margin-left: auto; margin-right: auto; }
.zps--d .zps-hero__actions { justify-content: center; }
.zps--d .zps-contact__link:not(.zps-contact__link--primary) {
    color: var(--zps-muted, #6b7280) !important;
    border-color: var(--zps-border, #e5e7eb) !important;
    background: var(--zps-tag-bg, rgba(0, 0, 0, 0.03)) !important;
}

/* ============================================================================
   ZpToolbar + ZpLanguageSelector
   ----------------------------------------------------------------------------
   Monte du site vers la lib le 27/07/2026. Ces regles vivaient dans le CSS de
   zebrapuma.be alors que les composants vivent ici : regis.scyeur.net a pris le
   selecteur a son tour et l'a recu sans forme, les deux presentations empilees
   l'une sur l'autre. Ce qui sert plusieurs fois appartient a la lib.

   La lib porte la STRUCTURE (formes, cibles tactiles, point de rupture, bascule
   entre les deux presentations) ; le site ne porte plus que ses COULEURS, via les
   variables --zpls-*. Les valeurs de repli reproduisent la charte ZebraPuma, donc
   un site qui ne declare rien reste presentable.
   ========================================================================== */

/* Barre d'outils de l'en-tete. Les filets ne sont poses que si l'hote le demande,
   et a deux items il ne le demande pas : un separateur n'ordonne rien quand il n'y
   a rien a ordonner. */
.zpt {
    display: flex;
    align-items: center;
    gap: 14px;
    flex: none;
    min-width: 0;
}
.zpt__item { display: flex; align-items: center; min-width: 0; }
.zpt--separated .zpt__item + .zpt__item::before {
    content: "";
    width: 1px;
    height: 22px;
    margin-inline-end: 14px;
    background: var(--zpls-border, #C9C6C0);
    flex: none;
}

/* Selecteur de langue. Choix Regis 26/07/2026 : segmente quand la place existe,
   menu nomme en dessous de 900 px, « Contact » d'abord.

   NE JAMAIS poser « position » sur .zps-nav depuis un site : la lib la declare
   « fixed » et le hero passe dessous en reservant sa hauteur par padding-top. La
   repasser en « relative » la remet dans le flux, la barre est alors comptee deux
   fois et tout le contenu descend d'une hauteur de barre : c'est ce qui a fait
   ressurgir le bug de l'issue #6 le 26/07, attrape par le filet responsive. */
.zpls { display: flex; align-items: center; }

/* --- Presentation large : segmente encadre --- */
/* Forme du zpx-segmented de l'Explorer, portee a 44 px : le seuil tactile du
   projet (WCAG 2.5.8 « AAA », Material et Apple HIG s'accordent sur 44-48 px). */
.zpls__segmented {
    display: none;
    border: 1px solid var(--zpls-border, #C9C6C0);
    border-radius: 999px;
    overflow: hidden;
}
.zpls__seg-item {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    /* min-width autant que min-height : deux lettres et 12 px de marge ne font que
       41 px, sous le seuil. Mesure par le filet, pas estimee a l'oeil. */
    min-width: 44px;
    padding-inline: 12px;
    font-size: 13px;
    color: var(--zpls-text, #6B7679);
    background: var(--zpls-bg, #F7F5F1);
    text-decoration: none;
    border-right: 1px solid var(--zpls-border, #C9C6C0);   /* le filet entre les langues */
}
.zpls__seg-item:last-child { border-right: none; }
.zpls__seg-item[aria-current] {
    background: var(--zpls-current-bg, #3D474B);
    color: var(--zpls-current-text, #FFFFFF);
    font-weight: 600;
}

/* --- Presentation etroite : menu replie --- */
/* Ancre sur le bouton et non sur la barre, ce qui l'aligne mieux et evite d'avoir
   a toucher au positionnement de .zps-nav. */
.zpls__menu { position: relative; flex: none; }
.zpls__menu > summary { list-style: none; }                       /* Firefox */
.zpls__menu > summary::-webkit-details-marker { display: none; }  /* WebKit */

/* Bouton nomme, et non trois traits : atelier du 27/07/2026, option B. Le burger
   n'annoncait rien de ce qu'il contenait, alors qu'un « FR » dit ou l'on se trouve.
   Meme forme que le segmente pour que les deux presentations d'un meme selecteur se
   reconnaissent d'une largeur a l'autre. */
.zpls__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 6px;
    min-height: 44px;
    min-width: 44px;
    padding-inline: 14px;
    border: 1px solid var(--zpls-border, #C9C6C0);
    border-radius: 999px;
    background: var(--zpls-bg, #F7F5F1);
    font-size: 13px;
    font-weight: 600;
    color: var(--zpls-toggle-text, #3D474B);
    cursor: pointer;
}
.zpls__toggle-chevron {
    width: 9px;
    height: 9px;
    border-right: 1.6px solid currentColor;
    border-bottom: 1.6px solid currentColor;
    transform: translateY(-2px) rotate(45deg);
}
.zpls__menu[open] .zpls__toggle-chevron {
    transform: translateY(1px) rotate(-135deg);
}

.zpls__panel {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 30;
    min-width: 190px;
    padding: 6px;
    background: var(--zpls-panel-bg, #FFFFFF);
    border: 1px solid var(--zpls-panel-border, #DAD6CE);
    border-radius: 12px;
    box-shadow: 0 10px 28px rgba(0, 0, 0, 0.18);
}
.zpls__panel-link {
    display: flex;
    align-items: center;
    min-height: 44px;
    padding-inline: 12px;
    border-radius: 8px;
    color: var(--zpls-panel-text, #3D474B);
    text-decoration: none;
}
.zpls__panel-link[aria-current] {
    background: var(--zpls-panel-current-bg, #EEF1F2);
    font-weight: 600;
    color: var(--zpls-panel-current-text, #17191A);
}
.zpls__panel-sep {
    border: 0;
    border-top: 1px solid var(--zpls-panel-sep, #ECEAE5);
    margin: 6px 8px;
}

/* Bascule. Au large le menu disparait et le segmente prend sa place ; en dessous
   l'inverse. « display: none » retire aussi de l'arbre d'accessibilite, donc le jeu
   de liens cache n'est jamais annonce deux fois.
   900 px : la largeur ou une barre de navigation cesse de tenir ses items cote a
   cote, point de rupture « desktop » du projet. */
@media (min-width: 900px) {
    .zpls__segmented { display: inline-flex; }
    .zpls__menu { display: none; }
}

/* En dessous, le menu porte SEUL la navigation : le lien de la barre disparait,
   sans quoi « Contact » s'afficherait deux fois, dans la barre et dans le panneau.
   Le panneau prend alors toute la largeur sous l'en-tete, comme une barre depliee
   et non comme une bulle : a cette taille, une bulle de 190 px flottant sur le hero
   se lit mal et laisse un vide a sa droite.
   « fixed » et non « absolute » : la barre etant elle-meme fixed, le panneau s'y
   accroche sans qu'on ait a toucher au positionnement de .zps-nav. */
@media (max-width: 899px) {
    .zps-nav__contact { display: none; }

    .zpls__panel {
        position: fixed;
        top: var(--zp-nav-h, 68px);
        left: 0;
        right: 0;
        min-width: 0;
        padding: 8px;
        border-radius: 0;
        border-inline: 0;
        border-top: 0;
    }
}
