/* =========================================================================
   Prodecta — bloc « Analytics » : des panneaux de verre posés sur la photo
   d'une salle.

   La photo (assets/img/dashboard-gym*.webp) est le décor ; les chiffres
   flottent dessus dans des panneaux sombres et translucides, comme un
   affichage tête haute. Sur ordinateur, une grille de 12 colonnes tient
   dans un cadre 16:9 ; sur téléphone, les panneaux s'empilent sur la
   version verticale de la photo. dashboard-viz.js anime l'entrée, les
   compteurs et une parallaxe légère à la souris.
   ========================================================================= */

#kpi-dashboard {
    text-align: center;
}

.dv {
    --dv-glass: rgba(14, 16, 18, .58);
    --dv-line: rgba(255, 255, 255, .13);
    --dv-txt: rgba(255, 255, 255, .72);
    --dv-accent: #2BDE73;
    --dv-teal: #19B5A5;
    position: relative;
    isolation: isolate;
    margin: 44px auto 0;
    border-radius: 28px;
    overflow: hidden;
    background: #101214;
    aspect-ratio: 16 / 9;
    min-height: 600px;
    box-shadow: 0 30px 80px -34px rgba(10, 20, 15, .55);
    text-align: left;
    color: #fff;
}

/* ---------------------------------------------------------------- décor */
.dv-bg,
.dv-bg img {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.dv-bg img {
    object-fit: cover;
    /* Un peu plus grande que le cadre : la parallaxe ne découvre jamais
       le bord. */
    transform: translate3d(var(--bx, 0px), var(--by, 0px), 0) scale(1.06);
    transition: transform .3s ease-out;
    will-change: transform;
}

/* Voile : assombrit juste assez pour que le texte tienne sur la photo,
   sans la noyer. */
.dv-veil {
    position: absolute;
    inset: 0;
    background:
        radial-gradient(120% 90% at 50% 40%, transparent 40%, rgba(6, 8, 10, .55) 100%),
        linear-gradient(180deg, rgba(6, 8, 10, .32) 0%, rgba(6, 8, 10, .12) 45%, rgba(6, 8, 10, .5) 100%);
    pointer-events: none;
}

/* ---------------------------------------------------------------- puces */
.dv-chip {
    position: absolute;
    z-index: 3;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 7px 13px;
    border-radius: 100px;
    background: rgba(10, 12, 14, .62);
    -webkit-backdrop-filter: blur(14px);
    backdrop-filter: blur(14px);
    border: 1px solid var(--dv-line);
    color: rgba(255, 255, 255, .86);
    font-size: 10.5px;
    font-weight: 700;
    letter-spacing: 1.6px;
    text-transform: uppercase;
    white-space: nowrap;
}

.dv-chip i {
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--dv-accent);
    box-shadow: 0 0 0 3px rgba(43, 222, 115, .18);
}

.dv-chip-tl { top: 20px; left: 24px; }
.dv-chip-tr { top: 20px; right: 24px; }
.dv-chip-foot {
    bottom: 16px;
    left: 50%;
    transform: translateX(-50%);
    letter-spacing: .6px;
    text-transform: none;
    font-weight: 600;
    color: rgba(255, 255, 255, .6);
}

/* ---------------------------------------------------------------- grille */
.dv-grid {
    position: absolute;
    inset: 64px 24px 56px;
    z-index: 2;
    display: grid;
    grid-template-columns: repeat(12, minmax(0, 1fr));
    grid-template-rows: minmax(0, 1fr) minmax(0, 1fr) auto;
    gap: 18px;
}

.dv-time { grid-column: 1 / 4; grid-row: 1; }
.dv-intent { grid-column: 1 / 4; grid-row: 2; }
.dv-heat { grid-column: 4 / 10; grid-row: 1 / 3; }
.dv-ret { grid-column: 10 / 13; grid-row: 1; }
.dv-clicks { grid-column: 10 / 13; grid-row: 2; }
.dv-top { grid-column: 1 / 13; grid-row: 3; }

/* ------------------------------------------------------------- panneaux */
.dv-panel {
    --i: 0;
    --px: 0px;
    --py: 0px;
    position: relative;
    display: flex;
    flex-direction: column;
    min-width: 0;
    min-height: 0;
    padding: 16px 18px;
    border-radius: 18px;
    background: var(--dv-glass);
    -webkit-backdrop-filter: blur(18px) saturate(140%);
    backdrop-filter: blur(18px) saturate(140%);
    border: 1px solid var(--dv-line);
    box-shadow:
        0 24px 60px -24px rgba(0, 0, 0, .65),
        inset 0 1px 0 rgba(255, 255, 255, .12);
    /* Avant l'entrée : un peu plus bas, flou. */
    opacity: 0;
    transform: translate3d(var(--px), calc(var(--py) + 18px), 0);
    filter: blur(6px);
    transition:
        opacity .7s ease calc(var(--i) * 70ms),
        filter .7s ease calc(var(--i) * 70ms),
        transform .9s cubic-bezier(.22, 1, .36, 1) calc(var(--i) * 70ms);
}

.dv.is-in .dv-panel {
    opacity: 1;
    filter: none;
    transform: translate3d(var(--px), var(--py), 0);
}

/* Une fois posés, les panneaux suivent la souris sans traîner. */
.dv.is-settled .dv-panel {
    transition: transform .28s ease-out;
}

.dv-label {
    display: flex;
    align-items: center;
    gap: 7px;
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 600;
    letter-spacing: .1px;
    color: var(--dv-txt);
}

.dv-label svg {
    width: 14px;
    height: 14px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.8;
    stroke-linecap: round;
    stroke-linejoin: round;
    flex-shrink: 0;
}

.dv-big {
    margin: 0;
    font-size: clamp(28px, 2.6vw, 38px);
    font-weight: 800;
    line-height: 1.05;
    letter-spacing: -.02em;
    font-variant-numeric: tabular-nums;
    color: #fff;
}

.dv-sub {
    margin: 8px 0 0;
    font-size: 11.5px;
    line-height: 1.45;
    color: rgba(255, 255, 255, .55);
    font-variant-numeric: tabular-nums;
}

.dv-sub em {
    font-style: normal;
    color: #8FF0BA;
    font-weight: 600;
}

/* Précision posée à côté du titre : période, unité, volume. */
.dv-note {
    margin-left: auto;
    font-size: 10.5px;
    font-weight: 500;
    color: rgba(255, 255, 255, .42);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Valeur et variation sur une même ligne de base. */
.dv-row {
    display: flex;
    align-items: baseline;
    gap: 10px;
    flex-wrap: wrap;
}

.dv-delta {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 3px 8px 3px 6px;
    border-radius: 100px;
    font-size: 11.5px;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    background: rgba(43, 222, 115, .14);
    color: #8FF0BA;
    white-space: nowrap;
}

.dv-delta.is-up::before {
    content: '';
    width: 0;
    height: 0;
    border-left: 4px solid transparent;
    border-right: 4px solid transparent;
    border-bottom: 6px solid currentColor;
}

.dv-days {
    display: flex;
    justify-content: space-between;
    margin-top: 5px;
    padding: 0 2px;
    font-size: 9.5px;
    font-weight: 600;
    letter-spacing: .4px;
    color: rgba(255, 255, 255, .42);
}

/* ----------------------------------------------------- temps de visite */
.dv-spark {
    display: block;
    width: 100%;
    height: 44px;
    margin-top: auto;
    overflow: visible;
}

.dv-spark-line {
    stroke-dasharray: 400;
    stroke-dashoffset: 400;
    transition: stroke-dashoffset 1.6s cubic-bezier(.22, 1, .36, 1) .35s;
}

.dv.is-in .dv-spark-line {
    stroke-dashoffset: 0;
}

.dv-spark-dot {
    opacity: 0;
    transition: opacity .3s ease 1.7s;
}

.dv.is-in .dv-spark-dot {
    opacity: 1;
}

/* ----------------------------------------------------------- intention */
.dv-bar {
    position: relative;
    height: 8px;
    margin-top: auto;
    border-radius: 8px;
    background: rgba(255, 255, 255, .12);
}

/* Repère d'objectif : un trait blanc que la barre dépasse (ou pas). */
.dv-goal {
    position: absolute;
    top: -4px;
    bottom: -4px;
    left: var(--g, 50%);
    width: 2px;
    border-radius: 2px;
    background: #fff;
    opacity: .75;
}

.dv-bar b {
    position: absolute;
    inset: 0;
    width: var(--v, 0%);
    border-radius: inherit;
    background: linear-gradient(90deg, var(--dv-teal), var(--dv-accent));
    box-shadow: 0 0 14px rgba(43, 222, 115, .45);
    transform: scaleX(0);
    transform-origin: left center;
    transition: transform 1.3s cubic-bezier(.22, 1, .36, 1) .5s;
}

.dv.is-in .dv-bar b {
    transform: scaleX(1);
}

/* ------------------------------------------------- carte de fréquentation */
.dv-plan {
    position: relative;
    flex: 1;
    min-height: 0;
    border-radius: 12px;
    overflow: hidden;
    background: rgba(28, 60, 140, .22);
}

.dv-plan svg {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
}

.dv-plan .dv-wall {
    fill: rgba(255, 255, 255, .03);
    stroke: rgba(255, 255, 255, .42);
    stroke-width: 1.6;
}

.dv-plan .dv-room {
    fill: none;
    stroke: rgba(255, 255, 255, .22);
    stroke-width: 1;
    stroke-dasharray: 3 4;
}

.dv-plan .dv-gear {
    fill: rgba(255, 255, 255, .1);
    stroke: rgba(255, 255, 255, .28);
    stroke-width: .8;
}

/* Plan d'architecte : cloisons, portes, équipements par famille. */
.dv-plan .dv-inner {
    stroke: rgba(255, 255, 255, .34);
    stroke-width: 1.4;
    stroke-linecap: round;
}

.dv-plan .dv-door {
    fill: none;
    stroke: rgba(255, 255, 255, .22);
    stroke-width: .8;
    stroke-dasharray: 2 2;
}

.dv-plan .dv-mat {
    fill: rgba(255, 255, 255, .07);
    stroke: rgba(255, 255, 255, .18);
    stroke-width: .6;
}

.dv-plan .dv-belt {
    fill: rgba(255, 255, 255, .22);
}

.dv-plan .dv-bar {
    stroke: rgba(255, 255, 255, .45);
    stroke-width: 1.2;
    stroke-linecap: round;
}

.dv-plan .dv-rack {
    fill: rgba(255, 255, 255, .05);
    stroke: rgba(255, 255, 255, .4);
    stroke-width: 1;
}

.dv-plan .dv-turf {
    fill: rgba(140, 220, 120, .13);
    stroke: rgba(255, 255, 255, .16);
    stroke-width: .6;
}

.dv-plan .dv-turf-line {
    stroke: rgba(255, 255, 255, .28);
    stroke-width: .8;
    stroke-dasharray: 6 5;
}

.dv-plan .dv-cage {
    fill: rgba(255, 255, 255, .04);
    stroke: rgba(255, 255, 255, .42);
    stroke-width: 1.2;
}

.dv-plan .dv-cage-in {
    fill: none;
    stroke: rgba(255, 255, 255, .16);
    stroke-width: .8;
    stroke-dasharray: 3 3;
}

/* Les foyers de chaleur : des halos flous qui se superposent en écran,
   du bleu froid au rouge de la zone la plus fréquentée. */
.dv-heatlayer {
    position: absolute;
    inset: 0;
    mix-blend-mode: screen;
    pointer-events: none;
}

.dv-blob {
    position: absolute;
    width: var(--s, 40%);
    aspect-ratio: 1;
    border-radius: 50%;
    transform: translate(-50%, -50%) scale(1);
    filter: blur(10px);
    opacity: 0;
    transition: opacity 1.2s ease .6s;
    animation: dvBreathe var(--t, 7s) ease-in-out infinite alternate;
}

.dv.is-in .dv-blob {
    opacity: 1;
}

.dv-blob.is-hot {
    background: radial-gradient(circle,
        rgba(255, 46, 46, .95) 0%, rgba(255, 120, 20, .85) 22%,
        rgba(250, 210, 40, .6) 42%, rgba(120, 220, 90, .4) 60%,
        rgba(40, 140, 255, .22) 78%, transparent 84%);
}

.dv-blob.is-warm {
    background: radial-gradient(circle,
        rgba(255, 150, 30, .85) 0%, rgba(250, 210, 40, .6) 30%,
        rgba(120, 220, 90, .4) 55%, rgba(40, 140, 255, .18) 78%, transparent 84%);
}

.dv-blob.is-mild {
    background: radial-gradient(circle,
        rgba(250, 220, 60, .6) 0%, rgba(120, 220, 90, .5) 35%,
        rgba(40, 160, 255, .25) 70%, transparent 84%);
}

.dv-blob.is-cool {
    background: radial-gradient(circle,
        rgba(90, 220, 140, .45) 0%, rgba(40, 150, 255, .35) 45%, transparent 82%);
}

@keyframes dvBreathe {
    from { transform: translate(-50%, -50%) scale(1); }
    to { transform: translate(-50%, -50%) scale(1.07); }
}

.dv-tag {
    position: absolute;
    z-index: 2;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 9px 4px 7px;
    border-radius: 100px;
    background: rgba(10, 12, 14, .78);
    border: 1px solid rgba(255, 255, 255, .16);
    color: #fff;
    font-size: 11px;
    font-weight: 600;
    white-space: nowrap;
    transform: translate(-50%, -50%);
}

.dv-tag::before {
    content: '';
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, .25);
}

.dv-tag b {
    font-weight: 700;
    color: rgba(255, 255, 255, .7);
    font-variant-numeric: tabular-nums;
}

.dv-tag.is-hot {
    border-color: rgba(255, 120, 60, .5);
}

.dv-tag.is-hot::before {
    background: #ff5a3c;
    box-shadow: 0 0 0 2px rgba(255, 90, 60, .35);
}

.dv-tag.is-hot b {
    color: #ffb199;
}

.dv-legend {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-top: 10px;
    font-size: 11px;
    color: rgba(255, 255, 255, .6);
}

.dv-legend i {
    flex: 1;
    max-width: 200px;
    height: 5px;
    border-radius: 5px;
    background: linear-gradient(90deg, #2a6cff, #22c1c3, #7ee65b, #ffd23c, #ff8a1f, #ff2f2f);
}

.dv-legend-note {
    margin-left: auto;
    color: rgba(255, 255, 255, .42);
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------------ rétention */
.dv-area {
    display: block;
    width: 100%;
    height: auto;
    flex: 1;
    min-height: 0;
    overflow: visible;
}

.dv-area-fill {
    opacity: 0;
    transition: opacity 1s ease .5s;
}

.dv-area-line {
    stroke-dasharray: 320;
    stroke-dashoffset: 320;
    transition: stroke-dashoffset 1.6s cubic-bezier(.22, 1, .36, 1) .4s;
}

.dv-area-mark {
    opacity: 0;
    transition: opacity .4s ease 1.6s;
}

.dv.is-in .dv-area-fill,
.dv.is-in .dv-area-mark {
    opacity: 1;
}

.dv.is-in .dv-area-line {
    stroke-dashoffset: 0;
}

.dv-grid-lines line {
    stroke: rgba(255, 255, 255, .12);
    stroke-width: 1;
}

.dv-grid-txt text {
    font-size: 8.5px;
    font-weight: 600;
    fill: rgba(255, 255, 255, .45);
    text-anchor: end;
}

.dv-axis {
    display: flex;
    justify-content: space-between;
    margin-top: 6px;
    /* Aligné sur la zone tracée du graphique (x : 34 → 250 sur 260). */
    padding: 0 3.8% 0 13%;
    font-size: 10.5px;
    color: rgba(255, 255, 255, .5);
    font-variant-numeric: tabular-nums;
}

/* ------------------------------------------------------ clics par zone */
.dv-bars {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 12px;
    flex: 1;
    min-height: 96px;
    align-items: end;
}

.dv-bcol {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 8px;
    height: 100%;
    min-height: 0;
}

/* La valeur se lit au-dessus de chaque barre. */
.dv-bcol em {
    margin-top: auto;
    font-style: normal;
    font-size: 11.5px;
    font-weight: 700;
    color: rgba(255, 255, 255, .85);
    font-variant-numeric: tabular-nums;
    opacity: 0;
    transition: opacity .5s ease calc(1.2s + var(--k, 0) * 120ms);
}

.dv.is-in .dv-bcol em {
    opacity: 1;
}

.dv-bcol b {
    display: block;
    width: 100%;
    max-width: 44px;
    flex: 1;
    min-height: 0;
    border-radius: 8px 8px 4px 4px;
    background:
        repeating-linear-gradient(-45deg, rgba(255, 255, 255, .16) 0 3px, transparent 3px 8px),
        rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .12);
    /* La hauteur est la valeur ; l'animation ne joue que sur l'échelle. */
    height: var(--v, 0%);
    transform: scaleY(0);
    transform-origin: bottom center;
    transition: transform 1.1s cubic-bezier(.22, 1, .36, 1) calc(.45s + var(--k, 0) * 120ms);
}

.dv-bcol.is-top b {
    background: linear-gradient(180deg, var(--dv-accent), var(--dv-teal));
    border-color: transparent;
    box-shadow: 0 0 22px rgba(43, 222, 115, .4);
}

.dv.is-in .dv-bcol b {
    transform: scaleY(1);
}

.dv-bcol span {
    font-size: 10.5px;
    line-height: 1.25;
    text-align: center;
    color: rgba(255, 255, 255, .6);
}

.dv-bcol.is-top span {
    color: #fff;
    font-weight: 600;
}

/* ------------------------------------------------------- classement */
.dv-top {
    flex-direction: row;
    align-items: center;
    gap: 14px;
    padding: 12px 18px;
}

.dv-top .dv-label {
    margin: 0;
    white-space: nowrap;
}

.dv-rank {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin: 0 0 0 auto;
    padding: 0;
    list-style: none;
}

.dv-rank li {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding: 5px 13px 5px 5px;
    border-radius: 100px;
    background: rgba(255, 255, 255, .08);
    border: 1px solid rgba(255, 255, 255, .12);
    font-size: 12.5px;
    font-weight: 600;
    color: #fff;
    white-space: nowrap;
}

.dv-rank li i {
    width: 22px;
    height: 22px;
    border-radius: 50%;
    display: grid;
    place-items: center;
    background: var(--dv-accent);
    color: #06221a;
    font-size: 11px;
    font-weight: 800;
    font-style: normal;
}

.dv-rank li b {
    margin-left: 2px;
    font-weight: 600;
    color: rgba(255, 255, 255, .55);
    font-variant-numeric: tabular-nums;
}

.dv-rank li:nth-child(2) i { background: rgba(255, 255, 255, .85); }
.dv-rank li:nth-child(3) i { background: rgba(255, 255, 255, .62); }
.dv-rank li:nth-child(n+4) i { background: rgba(255, 255, 255, .3); color: #fff; }

/* ----------------------------------------------------------------- CTA */
.dv-cta {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    margin-top: 28px;
}

.dv-cta-note {
    font-size: 12.5px;
    color: var(--text-dim, rgba(26, 26, 26, .5));
}

/* --------------------------------------------------------------- tablette */
@media (max-width: 1000px) {
    .dv {
        aspect-ratio: auto;
        min-height: 0;
        padding: 64px 18px 52px;
    }

    .dv-grid {
        position: static;
        inset: auto;
        grid-template-columns: repeat(2, minmax(0, 1fr));
        grid-template-rows: none;
        gap: 14px;
    }

    .dv-heat { grid-column: 1 / 3; grid-row: auto; order: -1; min-height: 340px; }
    .dv-time, .dv-ret, .dv-intent, .dv-clicks { grid-column: auto; grid-row: auto; }
    .dv-top { grid-column: 1 / 3; grid-row: auto; }

    .dv-bars { min-height: 110px; }
}

/* ---------------------------------------------------------------- mobile */
/* Quatre panneaux au lieu de six, la carte d'abord, moins de texte : au
   téléphone, le bloc doit se lire d'un pouce. */
@media (max-width: 720px) {
    .dv {
        margin-top: 28px;
        border-radius: 22px;
        padding: 54px 12px 46px;
    }

    .dv-chip-tl { top: 14px; left: 14px; }
    .dv-chip-tr { display: none; }
    .dv-chip-foot { bottom: 12px; }

    .dv-grid {
        gap: 10px;
    }

    .dv-ret,
    .dv-clicks { display: none; }

    .dv-heat { grid-column: 1 / 3; order: 1; min-height: 0; }
    .dv-time { grid-column: 1 / 2; order: 2; }
    .dv-intent { grid-column: 2 / 3; order: 3; }
    .dv-top { grid-column: 1 / 3; order: 4; flex-direction: column; align-items: flex-start; gap: 8px; padding: 12px 14px; }

    .dv-panel { padding: 12px 13px; }
    .dv-label { font-size: 11px; }
    .dv-note,
    .dv-sub { display: none; }
    .dv-row { flex-wrap: wrap; gap: 4px 8px; }
    .dv-big { font-size: 25px; }
    .dv-bars { min-height: 90px; gap: 8px; }
    .dv-bcol span { font-size: 9.5px; }

    /* Le plan garde ses proportions : les équipements restent lisibles,
       et seules les quatre zones qui comptent portent une étiquette. */
    .dv-plan { flex: none; aspect-ratio: 8 / 5; }
    .dv-tag { font-size: 11px; padding: 4px 9px 4px 7px; }
    .dv-tag:not(.is-key) { display: none; }

    /* Le podium : trois espaces, pas cinq. */
    .dv-rank { margin-left: 0; gap: 6px; }
    .dv-rank li:nth-child(n + 4) { display: none; }
}

@media (prefers-reduced-motion: reduce) {
    .dv-panel,
    .dv.is-in .dv-panel,
    .dv-spark-line,
    .dv-bar b,
    .dv-bcol b,
    .dv-area-line,
    .dv-area-fill,
    .dv-area-mark,
    .dv-spark-dot,
    .dv-blob {
        transition: none;
        animation: none;
        opacity: 1;
        filter: none;
        transform: none;
        stroke-dashoffset: 0;
    }

    .dv-blob {
        transform: translate(-50%, -50%);
    }

    .dv-bg img {
        transition: none;
    }
}
