/* =====================================================================
   DNAZERO — Portfolio · Styles spécifiques aux MODULES
   Portfolio, Playground (blog) et Deezer.
   Chargé APRÈS style-front.css : réutilise ses variables (--*), sa grille
   et ses composants de base (.block-head, .btn-x…).
   ===================================================================== */

/* =====================================================================
   PORTFOLIO — grille de projets (modulaire, vectorheart)
   ===================================================================== */
.pf-grid {
    list-style: none; margin: 0; padding: 0;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--gutter);
}
@media (max-width: 960px) { .pf-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .pf-grid { grid-template-columns: 1fr; } }

/* Sélection aléatoire (home) : pool mélangé, 6 affichés (tirage client),
   numérotation 01..06 via compteur CSS (les masqués n'incrémentent pas). */
.pf-grid[data-shuffle] { counter-reset: pfnum; }
.pf-grid[data-shuffle] > .pf-card { counter-increment: pfnum; }
.pf-grid[data-shuffle] > .pf-card .pf-num::before { content: counter(pfnum, decimal-leading-zero); }
.pf-grid[data-shuffle] > .pf-card:nth-child(n+7) { display: none; }

.pf-card { position: relative; }
.pf-card > a {
    display: flex; flex-direction: column;
    height: 100%;
    border: 1px solid var(--line);
    background: var(--surface);
    transition: border-color .18s ease, transform .18s ease;
}
.pf-card > a:hover { border-color: var(--accent); transform: translateY(-4px); }

/* Traits de coupe au survol (clin d'œil print) : deux équerres en dehors du
   cadre, angles opposés, couleur accent. */
.pf-card > a::before,
.pf-card > a::after {
    content: ""; position: absolute; z-index: 3;
    width: 14px; height: 14px;
    border: 0 solid var(--accent);
    opacity: 0; transition: opacity .2s ease;
    pointer-events: none;
}
.pf-card > a::before { top: -7px; left: -7px; border-top-width: 1px; border-left-width: 1px; }
.pf-card > a::after  { bottom: -7px; right: -7px; border-bottom-width: 1px; border-right-width: 1px; }
.pf-card > a:hover::before,
.pf-card > a:hover::after { opacity: 1; }

.pf-num {
    position: absolute; top: 0; right: 0; z-index: 2;
    font-family: var(--font-mono); font-size: 12px; letter-spacing: .1em;
    color: var(--on-accent); background: var(--accent);
    padding: 4px 9px;
}
.pf-media {
    position: relative; display: block;
    aspect-ratio: 4 / 3; overflow: hidden;
    background: var(--paper-2);
    border-bottom: 1px solid var(--line);
}
.pf-media img {
    width: 100%; height: 100%; object-fit: cover;
    filter: grayscale(1) contrast(1.05);
    transition: filter .3s ease, transform .5s ease;
}
.pf-card > a:hover .pf-media img { filter: grayscale(0); transform: scale(1.04); }
.pf-noimg { position: absolute; inset: 0;
    background:
        repeating-linear-gradient(45deg, transparent 0 10px, var(--grid-overlay) 10px 11px);
}
.pf-body { padding: calc(var(--u) * 2) calc(var(--u) * 2.5) calc(var(--u) * 2.5); flex: 1;
    display: flex; flex-direction: column; }
.tagline {
    font-family: var(--font-mono); font-size: 11px;
    letter-spacing: .18em; text-transform: uppercase;
    color: var(--accent-ink); margin-bottom: 8px;
}
.pf-title { font-size: 1.3rem; font-weight: 700; letter-spacing: -.01em; line-height: 1.1; }
.pf-meta { margin-top: auto; padding-top: calc(var(--u) * 1.5);
    font-family: var(--font-mono); font-size: 12px; color: var(--muted); }

/* Barre de filtres */
.pf-filters {
    display: flex; flex-wrap: wrap; gap: 10px;
    margin-bottom: calc(var(--u) * 4);
}
.chip {
    font-family: var(--font-mono); font-size: 12px;
    letter-spacing: .1em; text-transform: uppercase;
    padding: 9px 16px;
    border: 1px solid var(--line);
    color: var(--ink); cursor: pointer;
    transition: all .15s ease;
}
.chip:hover { border-color: var(--accent); color: var(--accent); }
.chip.is-on { background: var(--ink); color: var(--paper); border-color: var(--ink); }

/* Pagination (portfolio + playground) */
.pager {
    display: flex; align-items: center; justify-content: center;
    gap: calc(var(--u) * 3);
    margin-top: calc(var(--u) * 6);
    padding-top: calc(var(--u) * 3);
    border-top: 1px solid var(--line);
}
.pager a {
    font-family: var(--font-mono); font-size: 13px;
    letter-spacing: .1em; text-transform: uppercase;
    padding: 10px 18px; border: 1px solid var(--line-strong);
    transition: background .15s ease, color .15s ease;
}
.pager a:hover { background: var(--accent); color: var(--on-accent); border-color: var(--accent); }
.pager-pos { font-family: var(--font-mono); color: var(--muted); letter-spacing: .15em; }

/* =====================================================================
   PROJET / BILLET (single) — commun portfolio + playground
   ===================================================================== */
.pf-single, .blog-single { grid-column: 1 / -1; }
.crumb {
    font-family: var(--font-mono); font-size: 12px;
    letter-spacing: .14em; text-transform: uppercase;
    color: var(--muted); margin-bottom: calc(var(--u) * 3);
}
.crumb a:hover { color: var(--accent); }
.crumb span { color: var(--accent-ink); margin: 0 6px; }

/* L'en-tête projet/billet est partagé : voir .entry-header (+ .banner) plus bas. */

/* Contenu riche (commun projet + billet) — voir style-content.css, mutualisé
   avec l'admin (chargé après style-modules.css dans site/page.html). */

.back { margin-top: calc(var(--u) * 6); padding-top: calc(var(--u) * 3);
    border-top: 1px solid var(--line); }
.back a { font-family: var(--font-mono); font-size: 13px; letter-spacing: .1em;
    text-transform: uppercase; }
.back a:hover { color: var(--accent); }

/* =====================================================================
   PLAYGROUND (blog)
   ===================================================================== */
.blog-list, .blog-small { grid-column: 1 / -1; }

.blog-row {
    display: grid; grid-template-columns: 320px 1fr; gap: var(--gutter);
    padding: calc(var(--u) * 4) 0;
    border-bottom: 1px solid var(--line);
}
.blog-row:first-of-type { border-top: 1px solid var(--line); }
.blog-row .thumb { overflow: hidden; border: 1px solid var(--line); align-self: start; }
.blog-row .thumb img { aspect-ratio: 16/10; object-fit: cover; width: 100%;
    filter: grayscale(1); transition: filter .3s ease, transform .5s ease; }
.blog-row .thumb:hover img { filter: grayscale(0); transform: scale(1.03); }

/* Vignette typographique générée (billet sans image) : date en display,
   trame diagonale héritée du motif, même gabarit 16/10 que les photos.
   Partagée liste complète (.blog-row) et teaser home (.blog-mini). */
.thumb-gen {
    aspect-ratio: 16 / 10;
    display: grid; align-content: end; gap: 2px;
    padding: calc(var(--u) * 2);
    background:
        repeating-linear-gradient(45deg, transparent 0 10px, var(--grid-overlay) 10px 11px),
        var(--paper-2);
    transition: border-color .18s ease;
}
.thumb-gen:hover, .blog-mini a:hover .thumb-gen { border-color: var(--accent); }
.thumb-gen .tg-idx {
    font-family: var(--font-mono); font-size: 12px; letter-spacing: .2em;
    color: var(--accent-ink); margin-bottom: auto;
}
.thumb-gen .tg-date {
    font-family: var(--font-display); font-weight: 700;
    font-size: clamp(2.4rem, 5vw, 3.6rem); line-height: .9;
    letter-spacing: -.02em;
    color: transparent; -webkit-text-stroke: 1.5px var(--ink); text-stroke: 1.5px var(--ink);
}
.thumb-gen .tg-yr {
    font-family: var(--font-mono); font-size: 13px; letter-spacing: .18em;
    color: var(--muted);
}
.blog-row .meta { font-family: var(--font-mono); font-size: 12px; letter-spacing: .08em;
    color: var(--muted); margin: 0 0 8px; }
.blog-row h2 { font-size: clamp(1.5rem, 2.4vw, 2.1rem); margin: 0 0 calc(var(--u) * 1.5);
    text-transform: none; }
.blog-row h2 a:hover { color: var(--accent); }
.blog-row .more, .blog-mini .more {
    font-family: var(--font-mono); font-size: 12px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--accent-ink); }
.blog-row .more { display: inline-block; transition: transform .2s cubic-bezier(.2, .7, .2, 1); }
.blog-row .more:hover { transform: translateX(4px); }
@media (max-width: 680px) { .blog-row { grid-template-columns: 1fr; } }

/* En-tête de page « single » — PARTAGÉ projet (portfolio) + billet (playground).
   Structuré par défaut ; devient une bannière full-bleed avec .banner (voir plus bas). */
.entry-header {
    margin-bottom: calc(var(--u) * 5);
    padding-bottom: calc(var(--u) * 3);
    border-bottom: 2px solid var(--line-strong);
}
.entry-header h1 { margin: 0 0 calc(var(--u) * 3); max-width: 24ch; text-transform: none; }
.post-meta {
    list-style: none; margin: 0; padding: 0;
    display: flex; flex-wrap: wrap; gap: calc(var(--u) * 5);
}
.post-meta li { display: grid; gap: 4px; }
.post-meta .lbl {
    font-family: var(--font-mono); font-size: 11px;
    letter-spacing: .16em; text-transform: uppercase; color: var(--muted);
}
.post-meta .val { font-size: 1.05rem; font-weight: 700; }
.post-meta .val time { font-weight: 700; }
.post-meta .val a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 600px) { .post-meta { gap: calc(var(--u) * 3); } }

/* Bannière pleine largeur (full-bleed) quand la page a une image (projet OU billet) :
   image en fond, voile dégradé, titre + méta en surimpression.
   (Nécessite `html, body { overflow-x: clip }` défini dans style-front.css.) */
.entry-header.banner {
    position: relative;
    width: 100vw;
    margin-left: calc(50% - 50vw);          /* sort de l'empagement, bord à bord */
    margin-top: calc(var(--u) * -8);        /* colle sous l'en-tête (annule le padding du contenu) */
    margin-bottom: calc(var(--u) * 6);
    min-height: clamp(320px, 52vh, 520px);
    display: flex;
    align-items: flex-end;
    overflow: hidden;
    border-bottom: 0;                        /* le filet est remplacé par l'image */
    padding-bottom: 0;
}
.banner-img {
    position: absolute; inset: 0;
    width: 100%; height: 100%; object-fit: cover;
    /* Duotone : image désaturée, teintée par le calque accent ci-dessous.
       Les covers hétéroclites (photo, print, écran) deviennent une série. */
    filter: grayscale(1) contrast(1.1) brightness(.92);
}
/* Calque de teinte (duotone encre/orange). Empilement : image → teinte
   (::before) → scrim (ordre d'arbre) → grain (::after) → texte (z-index 2). */
.entry-header.banner::before {
    content: ""; position: absolute; inset: 0; z-index: 1;
    background: var(--accent);
    mix-blend-mode: color; opacity: .55;
    pointer-events: none;
}
/* Grain (texture tactile) : bruit SVG en surimpression discrète. */
.entry-header.banner::after {
    content: ""; position: absolute; inset: 0; z-index: 1;
    background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='160' height='160'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/></filter><rect width='100%25' height='100%25' filter='url(%23n)' opacity='0.6'/></svg>");
    mix-blend-mode: overlay; opacity: .16;
    pointer-events: none;
}
.banner-scrim {
    position: absolute; inset: 0; z-index: 1;
    background: linear-gradient(to top,
        rgba(8, 8, 10, .88) 0%, rgba(8, 8, 10, .45) 45%, rgba(8, 8, 10, .12) 100%);
}
.banner .banner-inner {
    position: relative; z-index: 2;
    width: 100%; max-width: var(--max);
    margin-inline: auto;
    padding: calc(var(--u) * 5) var(--pad-x) calc(var(--u) * 4);
}
/* Texte en surimpression : toujours clair, indépendant du thème */
.banner .crumb { color: rgba(255, 255, 255, .82); }
.banner .crumb a:hover { color: var(--accent); }
.banner .crumb span { color: var(--accent); }
.banner h1 { color: #fff; max-width: 24ch; }
.banner .post-meta .lbl { color: rgba(255, 255, 255, .72); }
.banner .post-meta .val,
.banner .post-meta .val time { color: #fff; }
.banner .post-meta .val a { color: #fff; }

/* Ancres de sections (h2 du contenu riche, posées par modules.js). */
.blog-single .rich h2 .h-anchor {
    margin-left: .4em;
    font-family: var(--font-mono); font-size: .7em;
    color: var(--accent-ink);
    opacity: 0; transition: opacity .2s ease;
}
.blog-single .rich h2:hover .h-anchor,
.blog-single .rich .h-anchor:focus-visible { opacity: 1; }

/* Chapeau : intro du billet, avant le contenu riche. */
.blog-single .chapo {
    font-size: 1.2rem; font-weight: 600; line-height: 1.5;
    max-width: 62ch; color: var(--accent-ink);
    margin: 0 0 calc(var(--u) * 4);
    padding-left: calc(var(--u) * 3);
    border-left: 2px solid var(--accent);
}

/* Maillage interne « Pour aller plus loin » après le contenu (même grille
   que le teaser home .blog-mini). */
.related { margin-top: calc(var(--u) * 6); padding-top: calc(var(--u) * 3);
    border-top: 1px solid var(--line); }
.related h2 { font-size: 1.4rem; text-transform: none; margin: 0 0 calc(var(--u) * 3); }
.related ul { list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gutter); }
@media (max-width: 860px) { .related ul { grid-template-columns: 1fr; } }
.related li { border-top: 2px solid var(--line-strong); }
.related a { display: block; padding-top: calc(var(--u) * 2); height: 100%; }
.related time { font-family: var(--font-mono); font-size: 12px; letter-spacing: .1em;
    color: var(--accent-ink); display: block; margin-bottom: var(--u); }
.related .t { display: block; font-size: 1.15rem; font-weight: 700; line-height: 1.15;
    margin-bottom: calc(var(--u) * 1.5); }
.related .more { font-family: var(--font-mono); font-size: 12px; letter-spacing: .1em;
    text-transform: uppercase; color: var(--accent-ink); }
.related a:hover .t { color: var(--accent); }

/* Teaser playground (home) */
.blog-mini { list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gutter); }
@media (max-width: 860px) { .blog-mini { grid-template-columns: 1fr; } }
/* Cartes alignées sur la liste complète (.blog-row) : trois liens distincts
   (vignette, titre, « Lire la suite → »), comme les rangées de /playground. */
.blog-mini .thumb { display: block; overflow: hidden;
    border: 1px solid var(--line); margin-bottom: calc(var(--u) * 2); }
.blog-mini .thumb img { display: block; aspect-ratio: 16/10; object-fit: cover; width: 100%;
    filter: grayscale(1); transition: filter .3s ease, transform .5s ease; }
.blog-mini .thumb:hover img { filter: grayscale(0); transform: scale(1.03); }
.blog-mini .meta { margin: 0 0 8px; font-family: var(--font-mono); font-size: 12px;
    letter-spacing: .08em; color: var(--muted); }
.blog-mini .t { margin: 0 0 calc(var(--u) * 1.5); font-size: 1.25rem; font-weight: 700;
    line-height: 1.1; }
.blog-mini .t a:hover { color: var(--accent); }
.blog-mini .x { margin: 0 0 calc(var(--u) * 1.5); color: var(--muted); font-size: .95rem; }
.blog-mini .more { display: inline-block; transition: transform .2s cubic-bezier(.2, .7, .2, 1); }
.blog-mini .more:hover { transform: translateX(4px); }

/* =====================================================================
   Dernière écoute Deezer (home, à droite du hero)
   ===================================================================== */
.deezer-dock { grid-column: 9 / 13; align-self: start; justify-self: end; width: 100%; max-width: 260px; }
@media (max-width: 860px) { .deezer-dock { grid-column: 1 / -1; justify-self: start; max-width: 320px; } }

.dz-card {
    border: 1px solid var(--line);
    background: var(--surface);
    padding: calc(var(--u) * 2) calc(var(--u) * 2) calc(var(--u) * 2.5);
    display: grid; gap: 6px; justify-items: center; text-align: center;
}
.dz-label {
    justify-self: start;
    font-family: var(--font-mono); font-size: 11px; letter-spacing: .16em;
    text-transform: uppercase; color: var(--accent-ink);
    margin-bottom: calc(var(--u) * 1.5);
}

/* Pochette = disque vinyle (rond, anneau, trou central). */
.dz-cover {
    position: relative; width: 150px; height: 150px; margin: 0 auto calc(var(--u) * 1.5);
    border-radius: 50%; overflow: hidden; background: #000;
    box-shadow: 0 0 0 6px var(--paper-2), 0 0 0 7px var(--line);
}
.dz-art { width: 100%; height: 100%; object-fit: cover; }
.dz-hole {
    position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);
    width: 14px; height: 14px; border-radius: 50%; z-index: 2; pointer-events: none;
    background: var(--paper); box-shadow: 0 0 0 2px rgba(0, 0, 0, .45);
}
/* Bouton play/stop au centre de la pochette. */
.dz-play {
    position: absolute; inset: 0; margin: auto; width: 48px; height: 48px; z-index: 3;
    display: grid; place-items: center; cursor: pointer;
    border: none; border-radius: 50%;
    background: color-mix(in srgb, var(--ink) 72%, transparent); color: var(--paper);
    transition: transform .15s ease, background .15s ease, color .15s ease;
}
.dz-play:hover { transform: scale(1.08); background: var(--accent); color: var(--on-accent); }
.dz-ico { width: 20px; height: 20px; fill: currentColor; }
.dz-ico-stop { display: none; }
.dz-card.is-playing .dz-ico-play { display: none; }
.dz-card.is-playing .dz-ico-stop { display: block; }

/* Rotation type vinyle : pilotée en JS (trigger.js, Web Animations API) pour
   pouvoir terminer le tour en cours jusqu'au retour à 0° à l'arrêt. */

.dz-song {
    font-weight: 700; font-size: .98rem; line-height: 1.15;
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dz-artist {
    font-family: var(--font-mono); font-size: 12px; color: var(--muted);
    max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.dz-empty .dz-na { font-family: var(--font-mono); font-size: 12px; padding: calc(var(--u) * 2) 0; }

/* Réinitialisation d'animation propre aux modules sous prefers-reduced-motion. */
@media (prefers-reduced-motion: reduce) { .pf-card > a:hover { transform: none; } }
