/* Medialem — tabsets and annotated screenshots (medialem/tabset, medialem/hotspots).

   Loaded only on pages carrying one of those blocks, so it must stand on its
   own: tokens come from base.css, everything else is defined here. The browser
   chrome is deliberately re-declared under .shot rather than reusing
   sections.css's .browser — that one pads its body for the mock listing, where
   this one has to sit flush against a screenshot.

   Transcribed from new-design/saas-marketplace.html, with the design's
   `.reveal.in` written as `.reveal.visible` (site.js adds `visible`). */

/* ================= TABSET ================= */
/* Onglets façon navigateur : barre claire, panneau fusionné avec l'onglet actif.

   Deux axes de variante, tous deux rendus par Medialem\View\Tabs :

     is-light / is-dark            la surface sur laquelle la barre se pose
     is-horizontal / is-vertical   barre au-dessus, ou rail à gauche

   Le rail vertical n'est pas un choix esthétique : six onglets du tour produit
   mesurent déjà 1126px dans une barre de 1130px, donc les huit de la page
   Tarifs ne tiennent pas sur une ligne. À 1000px et en dessous le rail devient
   un accordéon — 232px de rail à côté d'un panneau n'est pas une mise en page
   de téléphone, et la barre défilante ne sauve pas huit onglets. */
.tabset {
    border: 1px solid var(--line);
    border-radius: 20px;
    overflow: hidden;
    box-shadow: 0 16px 44px rgba(0, 51, 80, 0.09);
    background: #fff;
}

.tabs {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
    align-items: flex-end;
    position: relative;
    background: var(--mist);
    padding: 14px 14px 0;
    border-bottom: 1px solid var(--line);
}

/* ----- Rail vertical ----- */
.tabset.is-vertical {
    display: grid;
    grid-template-columns: 232px minmax(0, 1fr);
    align-items: stretch;
}

.tabset.is-vertical .tabs {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    padding: 16px 0 16px 16px;
    border-bottom: none;
    border-right: 1px solid var(--line);
}

.tabset.is-vertical .tab-btn {
    bottom: 0;
    text-align: left;
    border-radius: 13px 0 0 13px;
    border-bottom: 1px solid transparent;
    border-right: none;
}

.tabset.is-vertical .tab-btn[aria-selected="true"] {
    box-shadow: -6px 0 18px rgba(0, 51, 80, 0.06);
}

/* Masque le filet du rail derrière l'onglet actif, comme la barre horizontale
   le masque sous le sien : l'onglet et le panneau ne font qu'une surface. */
.tabset.is-vertical .tab-btn[aria-selected="true"]::after {
    left: auto;
    right: -1px;
    top: 1px;
    bottom: 1px;
    height: auto;
    width: 2px;
}

.tab-btn {
    position: relative;
    bottom: -1px;
    display: inline-flex;
    align-items: center;
    gap: 9px;
    font-family: var(--font-body);
    font-weight: 700;
    font-size: 0.92rem;
    color: var(--muted);
    background: transparent;
    border: 1px solid transparent;
    border-bottom: none;
    border-radius: 13px 13px 0 0;
    padding: 0.75em 1.2em;
    cursor: pointer;
    transition:
        color 0.18s ease,
        background 0.18s ease,
        border-color 0.18s ease;
}

.tab-btn svg {
    width: 16px;
    height: 16px;
    flex: none;
    opacity: 0.7;
    transition: opacity 0.18s ease;
}

.tab-btn:hover {
    background: rgba(255, 255, 255, 0.7);
    color: var(--navy);
}

.tab-btn:hover svg {
    opacity: 1;
}

.tab-btn[aria-selected="true"] {
    background: #fff;
    color: var(--navy);
    border-color: var(--line);
    box-shadow: 0 -6px 18px rgba(0, 51, 80, 0.06);
}

.tab-btn[aria-selected="true"] svg {
    opacity: 1;
    color: var(--coral);
}

/* Masque le filet de la barre sous l'onglet actif : il fusionne avec le panneau. */
.tab-btn[aria-selected="true"]::after {
    content: "";
    position: absolute;
    left: 1px;
    right: 1px;
    bottom: -1px;
    height: 2px;
    background: #fff;
}

.tab-btn:focus-visible {
    outline: 3px solid var(--coral);
    outline-offset: -3px;
}

/* ----- Variante sombre -----
   La barre claire est une surface : cadre, ombre, onglet actif fusionné avec le
   panneau. Sur marine il n'y a plus de surface à fusionner, donc l'onglet actif
   se marque au trait corail et le cadre disparaît. Même balisage, même script,
   même clavier — comme les trois `variant` de medialem/feature-grid. */
.tabset.is-dark {
    border: none;
    border-radius: 0;
    overflow: visible;
    box-shadow: none;
    background: none;
}

.tabset.is-dark > .tabs,
.tabs.is-dark {
    background: none;
    border-bottom: 1px solid rgba(255, 255, 255, 0.16);
    padding: 0;
    gap: 4px;
}

.tabset.is-dark > .tabs .tab-btn,
.tabs.is-dark .tab-btn {
    bottom: -1px;
    color: rgba(255, 255, 255, 0.66);
    border: none;
    border-radius: 12px 12px 0 0;
    padding: 0.85em 1.15em;
}

.tabset.is-dark > .tabs .tab-btn:hover,
.tabs.is-dark .tab-btn:hover {
    background: rgba(255, 255, 255, 0.07);
    color: #fff;
}

.tabset.is-dark > .tabs .tab-btn[aria-selected="true"],
.tabs.is-dark .tab-btn[aria-checked="true"] {
    color: #fff;
    background: rgba(255, 255, 255, 0.06);
    box-shadow: none;
}

/* Le trait corail remplace la fusion onglet/panneau de la variante claire.
   `aria-selected` pour un tablist, `aria-checked` pour le radiogroup des
   formules : chacun n'existe que dans son contexte, d'où deux sélecteurs et
   non quatre. */
.tabset.is-dark > .tabs .tab-btn[aria-selected="true"]::after,
.tabs.is-dark .tab-btn[aria-checked="true"]::after {
    content: "";
    position: absolute;
    left: 12px;
    right: 12px;
    bottom: -1px;
    height: 3px;
    border-radius: 3px 3px 0 0;
    background: var(--coral);
}

.tabset.is-dark > .tabs .tab-btn svg {
    opacity: 0.8;
}

.tabset.is-dark > .tabs .tab-btn[aria-selected="true"] svg {
    opacity: 1;
    color: var(--coral);
}

.tabset.is-dark > .tab-wrap {
    background: none;
    padding: 0;
}

.tab-wrap {
    padding: 42px 42px 46px;
    background: #fff;
}

.tab-panel {
    display: none;
    animation: tabFadeUp 0.35s ease;
}

.tab-panel.active {
    display: block;
}

/* La grille deux colonnes appartient à la capture, pas au panneau. Elle était
   posée sur .tab-panel.active, ce qui allait tant qu'un tabset ne contenait
   que des captures — et devenait faux dès qu'un panneau portait une grille de
   fonctionnalités ou une rangée de tarifs. */
.annotated-shot {
    display: grid;
    grid-template-columns: 1.15fr 0.85fr;
    gap: 44px;
    align-items: start;
}

/* Rail vertical : le panneau n'a plus la largeur pour trois colonnes, donc la
   capture passe au-dessus de sa légende (ce que fait aussi le site actuel). */
.tabset.is-vertical .annotated-shot {
    grid-template-columns: minmax(0, 1fr);
    gap: 26px;
}

/* ---- Chapeau d'un panneau `grid` ----

   Le tablist de la page Tarifs ne contient pas six fois la même chose : après
   les six captures viennent « Espace admin » (un chapeau à côté d'une capture,
   puis huit paires titre + paragraphe) et « Site vitrine » (une capture pleine
   largeur au-dessus de deux paires). Les cartes viennent de FeatureCards, que
   medialem/feature-grid partage ; ce chapeau-là n'appartient qu'à un panneau
   d'onglet, donc il vit ici et pas dans sections.css. */
.tab-feat-lead {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
    align-items: center;
    margin-bottom: 34px;
}

.tab-feat-lead.is-split {
    grid-template-columns: 1fr 1fr;
}

.tab-feat-copy h3 {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--navy);
    font-size: 1.35rem;
    line-height: 1.15;
    margin-bottom: 10px;
}

.tab-feat-copy p {
    color: var(--muted);
}

.tab-feat-img {
    border-radius: var(--radius);
    overflow: hidden;
    box-shadow: var(--shadow-card-hover);
    background: #fff;
    /* Sans ceci une capture large dépasse sa piste et élargit la page. */
    min-width: 0;
}

.tab-feat-img img {
    display: block;
    width: 100%;
    height: auto;
}

@keyframes tabFadeUp {
    from {
        opacity: 0;
        transform: translateY(10px);
    }

    to {
        opacity: 1;
        transform: none;
    }
}

@media (prefers-reduced-motion: reduce) {
    .tab-panel {
        animation: none;
    }
}

/* ================= CAPTURE ANNOTÉE ================= */
.shot {
    position: relative;
    /* Les éléments de grille valent min-width:auto par défaut : sans ceci, une
       capture large pousse la colonne au-delà de sa piste. */
    min-width: 0;
}

.shot .browser {
    position: relative;
    border-radius: 18px;
    /* visible, pas hidden : les bulles des points chauds débordent du cadre. */
    overflow: visible;
    box-shadow: 0 24px 60px rgba(0, 51, 80, 0.2);
    min-width: 0;
}

.shot .browser-bar {
    background: #012a42;
    border-radius: 18px 18px 0 0;
    padding: 13px 18px;
    display: flex;
    align-items: center;
    gap: 8px;
}

.shot .browser-bar i {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.25);
}

.shot .browser-bar i:first-child {
    background: var(--coral);
}

.shot .browser-url {
    margin-left: 10px;
    background: rgba(255, 255, 255, 0.1);
    color: #bbd3e2;
    font-size: 0.82rem;
    font-weight: 600;
    padding: 5px 16px;
    border-radius: 999px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.shot .browser-body {
    background: #fff;
    border-radius: 0 0 18px 18px;
    overflow: visible;
}

.shot .browser-body img {
    display: block;
    width: 100%;
    height: auto;
    border-radius: 0 0 18px 18px;
}

.annotated {
    position: relative;
}

.shot-copy h3 {
    font-family: var(--font-display);
    font-weight: 700;
    color: var(--navy);
    font-size: 1.35rem;
    line-height: 1.15;
    margin-bottom: 10px;
}

.shot-copy .desc {
    color: var(--muted);
    margin-bottom: 22px;
}

/* ---- Légendes ---- */
.feat-points {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.feat-points li {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    background: var(--mist);
    border: 1px solid var(--line);
    border-radius: 14px;
    padding: 13px 16px;
    font-size: 0.95rem;
    transition:
        background 0.2s ease,
        border-color 0.2s ease;
}

.feat-points li b {
    color: var(--navy);
}

.feat-points .dot {
    width: 26px;
    height: 26px;
    flex: none;
    margin-top: 1px;
    border-radius: 9px;
    background: #fff;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--coral);
    border: 1px solid var(--line);
}

.feat-points .dot.num {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 0.82rem;
}

/* Écho du survol d'un point chaud. */
.feat-points li.hl {
    border-color: var(--coral);
    background: var(--coral-tint);
}

/* ---- Points chauds ---- */
.hotspots {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.hotspot {
    position: absolute;
    translate: -50% -50%;
    pointer-events: auto;
    width: 26px;
    height: 26px;
    padding: 0;
    border-radius: 50%;
    border: 3px solid #fff;
    cursor: pointer;
    background-image: var(--grad-coral);
    color: #fff;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 0.76rem;
    line-height: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 4px 14px rgba(0, 20, 35, 0.4);
    z-index: 2;
    transition: transform 0.18s ease;
}

.hotspot:hover,
.hotspot.open {
    transform: scale(1.18);
    z-index: 4;
}

.hotspot::after {
    content: "";
    position: absolute;
    inset: -6px;
    border-radius: 50%;
    border: 2px solid var(--coral);
    animation: hotspotRing 2.4s ease-out infinite;
    opacity: 0;
    pointer-events: none;
}

@keyframes hotspotRing {
    0% {
        transform: scale(0.85);
        opacity: 0.8;
    }

    70% {
        transform: scale(1.6);
        opacity: 0;
    }

    100% {
        opacity: 0;
    }
}

@media (prefers-reduced-motion: reduce) {
    .hotspot::after {
        animation: none;
    }
}

.hotspot:focus-visible {
    outline: 3px solid var(--coral);
    outline-offset: 3px;
}

.hotspot .tip {
    position: absolute;
    bottom: calc(100% + 12px);
    left: 50%;
    transform: translateX(-50%);
    background: var(--navy);
    color: #fff;
    font-family: var(--font-body);
    font-weight: 600;
    font-size: 0.82rem;
    padding: 8px 14px;
    border-radius: 10px;
    white-space: nowrap;
    max-width: 240px;
    box-shadow: 0 12px 30px rgba(0, 20, 35, 0.35);
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.18s ease;
    z-index: 5;
    pointer-events: none;
}

.hotspot .tip::after {
    content: "";
    position: absolute;
    top: 100%;
    left: 50%;
    translate: -50% 0;
    border: 6px solid transparent;
    border-top-color: var(--navy);
}

/* Orientation posée au rendu, d'après les coordonnées du point : une bulle
   près d'un bord s'ouvre vers l'intérieur de la capture. */
.hotspot.tip-bottom .tip {
    bottom: auto;
    top: calc(100% + 12px);
}

.hotspot.tip-bottom .tip::after {
    top: auto;
    bottom: 100%;
    border-top-color: transparent;
    border-bottom-color: var(--navy);
}

.hotspot.tip-left .tip {
    left: auto;
    right: -10px;
    transform: none;
}

.hotspot.tip-left .tip::after {
    left: auto;
    right: 14px;
    translate: 0 0;
}

.hotspot.tip-right .tip {
    left: -10px;
    transform: none;
}

.hotspot.tip-right .tip::after {
    left: 14px;
    translate: 0 0;
}

.hotspot:hover .tip,
.hotspot:focus-visible .tip,
.hotspot.open .tip {
    opacity: 1;
    visibility: visible;
}

/* ================= RESPONSIVE ================= */
@media (max-width: 1000px) {
    .annotated-shot {
        grid-template-columns: minmax(0, 1fr);
        gap: 30px;
    }

    /* En accordéon le panneau fait toute la largeur, mais la capture du
       chapeau et son texte ne tiennent plus côte à côte sur un téléphone. */
    .tab-feat-lead.is-split {
        grid-template-columns: minmax(0, 1fr);
        gap: 24px;
    }

    /* ===== Le rail vertical devient un accordéon =====

       Un rail de 232px à côté d'un panneau n'est pas une mise en page de
       téléphone, et la barre défilante ne marche pas non plus à huit onglets :
       1427px d'onglets dans 343px de barre, deux visibles sur huit. Le panneau
       ouvert vient donc se placer sous SON propre onglet, et on ne traverse
       plus huit lignes de navigation pour atteindre le contenu.

       Le DOM ne change pas d'une largeur à l'autre : `display: contents` fait
       des onglets et des panneaux les enfants directs de la grille, et `order`
       les entrelace. Les rôles ARIA restent posés sur les mêmes éléments à
       toutes les largeurs, donc rien à resynchroniser en JavaScript. Les paires
       ci-dessous couvrent dix onglets ; au-delà, les suivants retomberaient sur
       `order: 0`, donc en tête. */
    .tabset.is-vertical {
        display: grid;
        grid-template-columns: minmax(0, 1fr);
    }

    .tabset.is-vertical .tabs,
    .tabset.is-vertical .tab-wrap {
        display: contents;
    }

    .tabset.is-vertical .tab-btn:nth-child(1) {
        order: 0;
    }

    .tabset.is-vertical .tab-panel:nth-child(1) {
        order: 1;
    }

    .tabset.is-vertical .tab-btn:nth-child(2) {
        order: 2;
    }

    .tabset.is-vertical .tab-panel:nth-child(2) {
        order: 3;
    }

    .tabset.is-vertical .tab-btn:nth-child(3) {
        order: 4;
    }

    .tabset.is-vertical .tab-panel:nth-child(3) {
        order: 5;
    }

    .tabset.is-vertical .tab-btn:nth-child(4) {
        order: 6;
    }

    .tabset.is-vertical .tab-panel:nth-child(4) {
        order: 7;
    }

    .tabset.is-vertical .tab-btn:nth-child(5) {
        order: 8;
    }

    .tabset.is-vertical .tab-panel:nth-child(5) {
        order: 9;
    }

    .tabset.is-vertical .tab-btn:nth-child(6) {
        order: 10;
    }

    .tabset.is-vertical .tab-panel:nth-child(6) {
        order: 11;
    }

    .tabset.is-vertical .tab-btn:nth-child(7) {
        order: 12;
    }

    .tabset.is-vertical .tab-panel:nth-child(7) {
        order: 13;
    }

    .tabset.is-vertical .tab-btn:nth-child(8) {
        order: 14;
    }

    .tabset.is-vertical .tab-panel:nth-child(8) {
        order: 15;
    }

    .tabset.is-vertical .tab-btn:nth-child(9) {
        order: 16;
    }

    .tabset.is-vertical .tab-panel:nth-child(9) {
        order: 17;
    }

    .tabset.is-vertical .tab-btn:nth-child(10) {
        order: 18;
    }

    .tabset.is-vertical .tab-panel:nth-child(10) {
        order: 19;
    }

    /* Au-delà de dix onglets les paires ci-dessus s'arrêtent. Sans ce garde-fou
       les suivants retombent sur `order: 0`, où l'égalité se tranche par l'ordre
       du DOM — tous les boutons puis tous les panneaux — ce qui casse aussi la
       paire du premier onglet et désaccorde l'ordre visuel de l'ordre clavier.
       Renvoyés à la fin, ils restent au moins appariés et lisibles. */
    .tabset.is-vertical .tab-btn:nth-child(n + 11),
    .tabset.is-vertical .tab-panel:nth-child(n + 11) {
        order: 99;
    }

    /* En-tête d'accordéon : pleine largeur, texte à gauche, chevron à droite.

       `white-space: normal` annule le `nowrap` que la barre défilante pose plus
       bas sur `.tab-btn` : ici il n'y a rien à faire défiler, et `.tabset` étant
       en `overflow: hidden`, un libellé trop long serait coupé sans ellipse ni
       barre de défilement. Les libellés livrés tiennent, mais plus au premier
       agrandissement de police du navigateur. */
    .tabset.is-vertical .tab-btn {
        bottom: 0;
        width: 100%;
        white-space: normal;
        justify-content: flex-start;
        gap: 12px;
        padding: 1em 18px;
        border: none;
        border-top: 1px solid var(--line);
        border-radius: 0;
        background: #fff;
    }

    .tabset.is-vertical .tab-btn:first-child {
        border-top: none;
    }

    .tabset.is-vertical .tab-btn[aria-selected="true"] {
        background: var(--mist);
        box-shadow: none;
    }

    /* Le chevron remplace le filet corail : sur un accordéon ce qui compte est
       de dire quel en-tête est ouvert, pas de fusionner avec un panneau. */
    .tabset.is-vertical .tab-btn::after {
        content: "";
        position: static;
        width: 9px;
        height: 9px;
        margin-left: auto;
        border: solid var(--muted);
        border-width: 0 2px 2px 0;
        rotate: 45deg;
        translate: 0 -2px;
        background: none;
        transition:
            rotate 0.18s ease,
            border-color 0.18s ease;
    }

    /* Reprend toutes les valeurs du filet vertical du rail : cette règle-là est
       aussi spécifique que celle-ci et la précède, donc sans ces annulations
       l'onglet ouvert hérite d'un chevron de 2px de large. */
    .tabset.is-vertical .tab-btn[aria-selected="true"]::after {
        position: static;
        left: auto;
        right: auto;
        top: auto;
        bottom: auto;
        width: 9px;
        height: 9px;
        border-color: var(--coral);
        rotate: -135deg;
        translate: 0 2px;
    }

    .tabset.is-vertical .tab-panel.active {
        padding: 24px 18px 28px;
        background: var(--mist);
        border-top: 1px solid var(--line);
    }

    /* Six tabs run to ~1130px, three phone screens. The scrollbar is hidden
       because it sits over the tabs, so the affordance is the pair of edge
       shadows below: the classic four-layer trick, where the two `local`
       layers travel with the content and mask the `scroll` shadow behind them
       until there is actually something off-screen in that direction. So a
       shadow shows on the left only once you have scrolled, and on the right
       only while more remains. tabset.js also scrolls the selected tab into
       view, which is what makes the keyboard arrows usable here. */
    .tabs {
        flex-wrap: nowrap;
        overflow-x: auto;
        scrollbar-width: none;
        -ms-overflow-style: none;
        scroll-snap-type: x proximity;
        scroll-padding-left: 14px;
        background:
            linear-gradient(90deg, var(--mist) 40%, rgba(239, 246, 250, 0)) left center / 30px 100% no-repeat
                local,
            linear-gradient(90deg, rgba(239, 246, 250, 0), var(--mist) 60%) right center / 30px 100% no-repeat
                local,
            radial-gradient(farthest-side at 0 50%, rgba(0, 51, 80, 0.3), rgba(0, 51, 80, 0)) left center /
                22px 100% no-repeat scroll,
            radial-gradient(farthest-side at 100% 50%, rgba(0, 51, 80, 0.3), rgba(0, 51, 80, 0)) right
                center / 22px 100% no-repeat scroll,
            var(--mist);
    }

    /* La barre sombre n'hérite pas des ombres de bord de la barre claire.
       Celles-ci masquent leur couche `scroll` avec deux couches `local`
       peintes de la couleur du fond ; le fond du bandeau tarifaire est un
       dégradé, où cette couche opaque laisse une tache. Un masque dégradé
       n'irait pas non plus : à l'arrêt il effacerait le début du premier
       onglet. Ici l'onglet coupé au bord est l'affordance, et tabset.js ramène
       l'onglet sélectionné dans le champ. */
    .tabset.is-dark > .tabs,
    .tabs.is-dark {
        background: none;
    }

    .tabs::-webkit-scrollbar {
        display: none;
    }

    .tab-btn {
        flex: none;
        white-space: nowrap;
        scroll-snap-align: start;
    }

    .tab-wrap {
        padding: 28px 22px 30px;
    }
}

@media (max-width: 640px) {
    .hotspot {
        width: 22px;
        height: 22px;
        font-size: 0.68rem;
    }

    .hotspot .tip {
        white-space: normal;
        width: max-content;
        max-width: 180px;
    }
}

/* ================= IMPRESSION ================= */
/* Une requête print s'évalue contre la boîte de page, ~739px : `max-width: 1000px`
   correspond donc et l'accordéon s'applique, panneaux repliés compris. Sur cette
   page l'offre entière est derrière des onglets, donc on déplie tout. */
@media print {
    .tab-panel,
    .type-price,
    .plan-terms {
        display: block !important;
        visibility: visible !important;
        opacity: 1 !important;
    }

    .reveal {
        opacity: 1 !important;
        transform: none !important;
    }
}
