/* ==========================================================================
   QUICK SWING — VITRINE LABORATOIRE v2 (page d'accueil)
   Bandeaux plein écran, taxonomie couleur par catégorie, animations signature.
   Toutes les valeurs d'espacement sont en clamp()/rem fixes : on n'y référence
   jamais --wp--preset--spacing--2xl (absent des styles globaux générés côté
   live -> tout un padding shorthand qui le contient devient invalide et
   s'effondre à 0, d'où le premier titre "collé" au hero avant ce correctif).
   ========================================================================== */

/* --- Bandeaux plein écran --- */
.qs-band,
.wp-block-group.qs-band--contact {
    /* WordPress ajoute automatiquement un margin-block-start entre blocs
       frères via :where(.is-layout-flow) > * (24px par défaut). Chaque
       bandeau gère déjà son propre espacement avec son padding interne :
       on neutralise ce gap pour qu'ils restent bien accolés, sans double
       espace ni liseré de la couleur de fond du dessous qui transparaît. */
    margin-block: 0;
}
.qs-band {
    position: relative;
    box-sizing: border-box;
    width: 100%;
    padding-block: clamp(3.5rem, 8vw, 6.5rem);
    padding-inline: clamp(1.25rem, 5vw, 3rem);
    overflow: clip;
}
.qs-band > .qs-band__inner {
    max-width: var(--qs-band-max, 1280px);
    margin-inline: auto;
}
.qs-band--tight > .qs-band__inner { max-width: 760px; }
.qs-band--base   { background: var(--wp--preset--color--base); }
.qs-band--surface{ background: var(--wp--preset--color--surface); }

/* Trait "circuit" en haut de bandeau — reprend .is-style-laser du thème */
.qs-band__rule {
    position: absolute;
    top: 0; left: 0; right: 0;
    height: 1px;
    background: linear-gradient(90deg, transparent, var(--qs-neon-a50), transparent);
    box-shadow: 0 0 12px var(--qs-neon-a40);
}

/* --- Halo derrière le H1 (soudure visuelle avec le hero) --- */
.qs-intro { text-align: center; }
.qs-intro::before {
    content: '';
    position: absolute;
    top: -10%;
    left: 50%;
    width: min(900px, 100vw);
    height: 420px;
    transform: translateX(-50%);
    background: radial-gradient(closest-side, var(--qs-neon-a15), transparent 70%);
    pointer-events: none;
    z-index: 0;
}
.qs-intro > .qs-band__inner { position: relative; z-index: 1; }

/* Indicateur "signal actif" à côté de l'eyebrow */
.qs-eyebrow-row {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    margin: 0 0 1rem;
}
.qs-live-dot {
    width: 7px;
    height: 7px;
    border-radius: 50%;
    background: var(--qs-neon);
    box-shadow: 0 0 8px var(--qs-neon), 0 0 16px var(--qs-neon-a50);
    animation: qs-pulse 1.8s ease-in-out infinite;
    flex-shrink: 0;
}
.qs-eyebrow {
    font-family: var(--wp--preset--font-family--jetbrains-mono, monospace);
    font-size: var(--wp--preset--font-size--sm);
    font-weight: 600;
    letter-spacing: 0.22em;
    text-transform: uppercase;
    color: var(--wp--preset--color--accent);
    margin: 0;
}
@keyframes qs-pulse {
    0%, 100% { opacity: 1; transform: scale(1); }
    50%      { opacity: .4; transform: scale(0.7); }
}

.qs-intro__title {
    margin: 0;
    font-weight: 900;
    line-height: 1.08;
    font-size: var(--wp--preset--font-size--display);
    text-shadow: 2px 0 var(--wp--preset--color--accent), -2px 0 var(--wp--preset--color--accent-alt);
}
.qs-intro__lede {
    max-width: 700px;
    margin: clamp(1.25rem, 3vw, 1.75rem) auto 0;
    font-size: var(--wp--preset--font-size--lg);
    color: var(--wp--preset--color--gray-300);
    line-height: 1.7;
}

.qs-skill-pills {
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.6rem;
    margin: clamp(1.75rem, 4vw, 2.5rem) 0 0;
    padding: 0;
    list-style: none;
    font-family: var(--wp--preset--font-family--jetbrains-mono, monospace);
}
.qs-skill-pills li {
    border: 1px solid var(--qs-neon-a30);
    border-radius: 999px;
    padding: 0.45rem 1.05rem;
    font-size: 0.78rem;
    letter-spacing: .02em;
    color: var(--wp--preset--color--gray-300);
    background: var(--qs-neon-a04);
    white-space: nowrap;
    transition: border-color .25s ease, color .25s ease, background .25s ease;
}
.qs-skill-pills li:hover {
    border-color: var(--qs-neon-a50);
    color: var(--wp--preset--color--contrast);
    background: var(--qs-neon-a08);
}

/* --- Stats --- */
.qs-stats-grid {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: clamp(1.5rem, 4vw, 2.5rem);
    text-align: center;
}
@media (max-width: 640px) {
    .qs-stats-grid { grid-template-columns: repeat(2, 1fr); }
}
.qs-stat-number {
    color: var(--wp--preset--color--accent);
    font-weight: 900;
    font-size: var(--wp--preset--font-size--display);
    margin: 0 0 0.4rem;
    text-shadow: 0 0 24px var(--qs-neon-a30);
}
.qs-stat-label {
    color: var(--wp--preset--color--gray-300);
    font-size: var(--wp--preset--font-size--sm);
    font-family: var(--wp--preset--font-family--jetbrains-mono, monospace);
    text-transform: uppercase;
    letter-spacing: .04em;
    margin: 0;
}

/* --- En-tête de section --- */
.qs-section-head {
    text-align: center;
    max-width: 640px;
    margin: 0 auto clamp(2rem, 5vw, 2.75rem);
}
.qs-section-head .wp-block-heading {
    color: var(--wp--preset--color--accent);
    margin: 0 0 0.75rem;
}
.qs-section-head p {
    color: var(--wp--preset--color--gray-300);
    margin: 0;
    line-height: 1.6;
}

/* --- Filter bar --- */
.qs-filter-bar {
    display: flex;
    gap: 0.6rem;
    margin: 0 0 0.5rem;
    padding: 0 0 0.5rem;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    -ms-overflow-style: none;
    mask-image: linear-gradient(90deg, transparent 0, #000 24px, #000 calc(100% - 24px), transparent 100%);
}
.qs-filter-bar::-webkit-scrollbar { display: none; }
@media (min-width: 700px) {
    .qs-filter-bar {
        flex-wrap: wrap;
        justify-content: center;
        /* Largeur plafonnée volontairement : sur les 7 boutons, ça force un
           retour propre à 4 + 3 plutôt qu'un dernier bouton isolé tout seul
           sur sa ligne quand ça déborde pile d'un item. */
        max-width: 42rem;
        margin-inline: auto;
        overflow: visible;
        mask-image: none;
    }
}
.qs-filter-btn {
    scroll-snap-align: start;
    flex-shrink: 0;
    display: inline-flex;
    align-items: center;
    gap: 0.45rem;
    font: inherit;
    font-family: var(--wp--preset--font-family--jetbrains-mono, monospace);
    font-size: 0.78rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    color: var(--wp--preset--color--gray-300);
    background: transparent;
    border: 1px solid var(--qs-neon-a20);
    border-radius: 999px;
    padding: 0.6rem 1.2rem;
    cursor: pointer;
    transition: color .25s ease, border-color .25s ease, background .25s ease, box-shadow .25s ease, transform .2s ease;
}
.qs-filter-btn .qs-cat-dot {
    width: 7px; height: 7px; border-radius: 50%;
    background: var(--cat, var(--qs-neon));
    box-shadow: 0 0 6px var(--cat, var(--qs-neon));
    flex-shrink: 0;
}
.qs-filter-btn:hover {
    border-color: color-mix(in srgb, var(--cat, var(--qs-neon)) 55%, transparent);
    color: var(--wp--preset--color--contrast);
}
.qs-filter-btn.is-active {
    color: #000;
    background: var(--cat, var(--qs-neon));
    border-color: var(--cat, var(--qs-neon));
    box-shadow: 0 0 22px color-mix(in srgb, var(--cat, var(--qs-neon)) 45%, transparent);
}
.qs-filter-btn.is-active .qs-cat-dot { background: #000; box-shadow: none; }
.qs-filter-btn:focus-visible,
.qs-projet-card:focus-visible {
    outline: 2px solid var(--wp--preset--color--accent);
    outline-offset: 3px;
}

.qs-showcase-count {
    text-align: center;
    font-family: var(--wp--preset--font-family--jetbrains-mono, monospace);
    font-size: 0.78rem;
    letter-spacing: .04em;
    color: var(--wp--preset--color--gray-500);
    margin: 0 0 clamp(1.75rem, 4vw, 2.5rem);
}

/* --- Grid --- */
.qs-showcase-grid {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: clamp(1.1rem, 2.5vw, 1.75rem);
}
@media (max-width: 960px) {
    .qs-showcase-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 640px) {
    .qs-showcase-grid { grid-template-columns: 1fr; }
}

.qs-projet-card {
    /* .is-style-card-hover apporte position/overflow/le halo ::before via
       une règle CSS classique (donc déjà appliquée), mais son fond/bordure/
       rayon proviennent normalement de styles/sections/card-hover.json,
       généré par WordPress uniquement pour de vrais blocs core/group passés
       par le rendu Gutenberg. Ces cartes sont du HTML brut dans un bloc
       wp:html : elles ne reçoivent jamais cette règle générée, d'où des
       coins droits sur la boîte alors que le ::before (rayon déclaré en dur
       dans block-styles.css) restait bien arrondi. On réplique donc ici les
       mêmes valeurs que card-hover.json, en dur. */
    border-radius: 16px;
    border: 1px solid rgba(255, 255, 255, 0.06);
    background: rgba(255, 255, 255, 0.02);
    display: flex;
    flex-direction: column;
    text-decoration: none !important;
    color: inherit;
    opacity: 0;
    transform: translateY(22px);
    transition: opacity .55s ease, transform .55s ease,
                box-shadow .45s cubic-bezier(.23,1,.32,1),
                transform .45s cubic-bezier(.23,1,.32,1);
}
.qs-projet-card.is-hidden { display: none; }
.qs-projet-card.is-cascade-in { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
    .qs-projet-card { opacity: 1; transform: none; transition: none; }
}

/* Correctif du liseré lumineux hérité de .is-style-card-hover : sur un
   conic-gradient, la couleur dépend de l'angle depuis le centre, ce qui
   déforme le tracé dans les coins arrondis (surtout sur un rectangle large
   comme ces cartes). Le masque qui dessine le contour arrondi ne change
   pas — on remplace juste le dégradé conique par un balayage linéaire
   diagonal, dont la couleur ne dépend que d'un axe : les coins restent nets
   quel que soit le rayon. Couleur alignée sur la catégorie de la carte. */
.qs-projet-card.is-style-card-hover::before {
    /* Sans z-index, ce ::before reste derrière l'image (un vrai élément DOM)
       dans l'ordre d'empilement : la lumière ne traversait donc que la zone
       de texte, jamais la partie couverte par la photo. On le fait passer
       au-dessus de tout le contenu de la carte (::after du spotlight inclus)
       pour qu'elle fasse bien le tour complet. pointer-events:none est déjà
       hérité de la règle de base, donc les clics traversent toujours. */
    z-index: 3;
    background: linear-gradient(115deg,
        transparent 35%,
        var(--cat, var(--qs-neon)) 50%,
        transparent 65%);
    background-size: 260% 260%;
    background-position: 0% 0%;
    animation: none;
}
.qs-projet-card.is-style-card-hover:hover::before {
    animation: qs-card-sweep 1.6s ease-in-out infinite;
}
@keyframes qs-card-sweep {
    0%   { background-position: 0% 0%; }
    100% { background-position: 100% 100%; }
}
@media (prefers-reduced-motion: reduce) {
    .qs-projet-card.is-style-card-hover:hover::before { animation: none; opacity: 1; }
}

.qs-projet-card__image-wrap {
    position: relative;
    display: block;
    aspect-ratio: 16 / 10;
}
.qs-projet-card__image-wrap img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
    transition: transform .5s ease;
}
.qs-projet-card:hover .qs-projet-card__image-wrap img {
    transform: scale(1.06);
}

/* Pastille de catégorie — icône générée en CSS mask, une seule source par catégorie */
.qs-cat-badge {
    position: absolute;
    top: 0.65rem;
    left: 0.65rem;
    width: 30px;
    height: 30px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(6, 8, 10, 0.72);
    backdrop-filter: blur(6px);
    -webkit-backdrop-filter: blur(6px);
    border: 1px solid color-mix(in srgb, var(--cat) 45%, transparent);
    box-shadow: 0 0 14px color-mix(in srgb, var(--cat) 40%, transparent);
    z-index: 2;
}
.qs-cat-badge::before {
    content: '';
    width: 16px;
    height: 16px;
    background-color: var(--cat);
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
}

/* Halo spot qui suit le curseur — uniquement sur pointeurs fins (souris) */
@media (hover: hover) and (pointer: fine) {
    .qs-projet-card { position: relative; }
    .qs-projet-card::after {
        content: '';
        position: absolute;
        inset: 0;
        border-radius: 16px;
        background: radial-gradient(240px circle at var(--mx, 50%) var(--my, 50%),
            color-mix(in srgb, var(--cat, var(--qs-neon)) 16%, transparent), transparent 70%);
        opacity: 0;
        transition: opacity .35s ease;
        pointer-events: none;
        z-index: 1;
    }
    .qs-projet-card:hover::after { opacity: 1; }
}

.qs-projet-card__body {
    padding: clamp(1.1rem, 2.5vw, 1.5rem);
    display: flex;
    flex-direction: column;
    gap: 0.6rem;
    flex: 1;
    position: relative;
    z-index: 1;
}
.qs-projet-card__title {
    font-size: var(--wp--preset--font-size--lg);
    font-weight: 700;
    color: var(--wp--preset--color--contrast);
    margin: 0;
}
.qs-projet-card__pitch {
    font-size: var(--wp--preset--font-size--sm);
    color: var(--wp--preset--color--gray-300);
    line-height: 1.6;
    flex: 1;
    margin: 0;
}
.qs-projet-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}
.qs-tag {
    font-family: var(--wp--preset--font-family--jetbrains-mono, monospace);
    font-size: 0.68rem;
    font-weight: 600;
    letter-spacing: 0.03em;
    text-transform: uppercase;
    color: var(--cat, var(--wp--preset--color--accent));
    border: 1px solid color-mix(in srgb, var(--cat, var(--wp--preset--color--accent)) 35%, transparent);
    border-radius: 999px;
    padding: 0.25rem 0.65rem;
    white-space: nowrap;
}
.qs-projet-card__cta {
    margin-top: 0.2rem;
    display: inline-flex;
    align-items: center;
    gap: 0.5rem;
    font-size: var(--wp--preset--font-size--sm);
    font-weight: 700;
    letter-spacing: 0.03em;
    color: var(--wp--preset--color--contrast);
}
.qs-projet-card__cta svg { transition: transform .25s ease; }
.qs-projet-card:hover .qs-projet-card__cta { color: var(--cat, var(--qs-neon)); }
.qs-projet-card:hover .qs-projet-card__cta svg { transform: translateX(4px); }

/* --- Taxonomie couleur par catégorie (dérivée des tokens du thème,
   alignée sur les 6 catégories réelles du menu du site) --- */
.qs-projet-card[data-cat="cam-music"],
.qs-filter-btn[data-qs-filter="cam-music"] { --cat: var(--wp--preset--color--accent); }

.qs-projet-card[data-cat="mic-react"],
.qs-filter-btn[data-qs-filter="mic-react"] { --cat: var(--wp--preset--color--accent-2); }

.qs-projet-card[data-cat="games"],
.qs-filter-btn[data-qs-filter="games"] { --cat: var(--wp--preset--color--accent-alt); }

.qs-projet-card[data-cat="midi-visual"],
.qs-filter-btn[data-qs-filter="midi-visual"] { --cat: var(--wp--preset--color--accent-3); }

.qs-projet-card[data-cat="cam-fun"],
.qs-filter-btn[data-qs-filter="cam-fun"] { --cat: color-mix(in srgb, var(--wp--preset--color--accent-2) 50%, var(--wp--preset--color--accent-3) 50%); }

.qs-projet-card[data-cat="music"],
.qs-filter-btn[data-qs-filter="music"] { --cat: color-mix(in srgb, var(--wp--preset--color--accent) 50%, var(--wp--preset--color--accent-alt) 50%); }

/* --- Icônes de catégorie (mask CSS, un seul jeu de définitions) --- */
.qs-projet-card[data-cat="cam-music"] .qs-cat-badge::before,
.qs-filter-btn[data-qs-filter="cam-music"] .qs-cat-dot { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='5' cy='12' r='2' fill='black'/%3E%3Cpath d='M7 12V3l6-1.3V7' stroke='black' stroke-width='1.4' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3Ccircle cx='11' cy='8' r='1.8' fill='black'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='5' cy='12' r='2' fill='black'/%3E%3Cpath d='M7 12V3l6-1.3V7' stroke='black' stroke-width='1.4' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3Ccircle cx='11' cy='8' r='1.8' fill='black'/%3E%3C/svg%3E"); }

.qs-projet-card[data-cat="mic-react"] .qs-cat-badge::before,
.qs-filter-btn[data-qs-filter="mic-react"] .qs-cat-dot { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect x='6' y='1.5' width='4' height='7' rx='2' stroke='black' stroke-width='1.3' fill='none'/%3E%3Cpath d='M4 8a4 4 0 0 0 8 0M8 12v2.5M5.5 14.5h5' stroke='black' stroke-width='1.3' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Crect x='6' y='1.5' width='4' height='7' rx='2' stroke='black' stroke-width='1.3' fill='none'/%3E%3Cpath d='M4 8a4 4 0 0 0 8 0M8 12v2.5M5.5 14.5h5' stroke='black' stroke-width='1.3' fill='none' stroke-linecap='round'/%3E%3C/svg%3E"); }

.qs-projet-card[data-cat="games"] .qs-cat-badge::before,
.qs-filter-btn[data-qs-filter="games"] .qs-cat-dot { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='4' r='2.2' fill='black'/%3E%3Cpath d='M8 6.2V11M4 14h8' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Ccircle cx='8' cy='4' r='2.2' fill='black'/%3E%3Cpath d='M8 6.2V11M4 14h8' stroke='black' stroke-width='1.6' stroke-linecap='round'/%3E%3C/svg%3E"); }

.qs-projet-card[data-cat="midi-visual"] .qs-cat-badge::before,
.qs-filter-btn[data-qs-filter="midi-visual"] .qs-cat-dot { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 8h2.5l1.5-5 3 10 1.5-5H15' stroke='black' stroke-width='1.4' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 8h2.5l1.5-5 3 10 1.5-5H15' stroke='black' stroke-width='1.4' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"); }

.qs-projet-card[data-cat="cam-fun"] .qs-cat-badge::before,
.qs-filter-btn[data-qs-filter="cam-fun"] .qs-cat-dot { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 8s2.7-4.5 7-4.5S15 8 15 8s-2.7 4.5-7 4.5S1 8 1 8Z' stroke='black' stroke-width='1.4' fill='none'/%3E%3Ccircle cx='8' cy='8' r='2' fill='black'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M1 8s2.7-4.5 7-4.5S15 8 15 8s-2.7 4.5-7 4.5S1 8 1 8Z' stroke='black' stroke-width='1.4' fill='none'/%3E%3Ccircle cx='8' cy='8' r='2' fill='black'/%3E%3C/svg%3E"); }

.qs-projet-card[data-cat="music"] .qs-cat-badge::before,
.qs-filter-btn[data-qs-filter="music"] .qs-cat-dot { -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 10V6M5.3 12V4M8.7 13V3M12 12V4M14 10V6' stroke='black' stroke-width='1.6' stroke-linecap='round' fill='none'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M2 10V6M5.3 12V4M8.7 13V3M12 12V4M14 10V6' stroke='black' stroke-width='1.6' stroke-linecap='round' fill='none'/%3E%3C/svg%3E"); }

/* --- Contact --- */
.qs-band--contact {
    background: linear-gradient(135deg,
        var(--wp--preset--color--base) 0%,
        color-mix(in srgb, var(--wp--preset--color--accent-alt) 10%, var(--wp--preset--color--base)) 55%,
        color-mix(in srgb, var(--wp--preset--color--accent-alt) 14%, transparent) 100%);
    text-align: center;
}
.qs-band--contact > p {
    color: var(--wp--preset--color--gray-300);
    max-width: 520px;
    margin-inline: auto;
}
