/* ==========================================================================
   article-style.css — feuille de style PARTAGÉE entre l'éditeur de blocs
   (public/articles.html, via Editor.js) et la page de lecture publique
   (/article, rendue côté serveur par api/article-page.js via
   api/_article-render.js).

   C'est la seule source de vérité typographique de "ce à quoi ressemble un
   article SKIT" : toute évolution du style visuel des articles se fait ICI,
   pas dans les deux pages séparément.
   ========================================================================== */

:root {
    --article-bg: #050505;
    --article-bg-soft: #0b0b0b;
    --article-text: #ffffff;
    --article-text-dim: rgba(255, 255, 255, 0.68);
    --article-text-muted: rgba(255, 255, 255, 0.4);
    --article-line: rgba(255, 255, 255, 0.18);
    --article-accent: #00d4ff;
    --article-accent-dark: #0099cc;
    /* Rouge dominant du logo (public/logo.png) — utilisé pour la mention
       "SKIT" au-dessus des titres d'article, pas pour l'accent général. */
    --article-brand-red: #df030f;
    /* Largeur de la colonne de lecture — ~65-75 caractères par ligne,
       comme la plupart des sites d'actualité en ligne (Medium, NYT, The
       Verge...), même quand la photo de couverture occupe tout l'écran :
       s'élargit jusqu'à 720px sur grand écran sans jamais dépasser l'espace
       disponible sur mobile/tablette (width:100% sur .article-column fait
       toujours foi en dessous de ce plafond). Partagée par le canvas
       d'édition ET les pages publiques : on écrit dans le même gabarit que
       ce qui sera publié. */
    --article-max-width: clamp(600px, 55vw, 720px);
    --article-font-body: 'Manrope', sans-serif;
    --article-font-display: 'Space Grotesk', sans-serif;
    /* Radius autonome (article-style.css doit fonctionner seul sur la page
       /article, qui ne charge pas admin-style.css). */
    --article-radius: 16px;
}

/* Thème clair — appliqué quand <html data-theme="light">, posé par le même
   sélecteur/toggle que le chrome de l'éditeur (articles.html). N'affecte la
   page /article que si elle pose elle-même l'attribut (ce qu'elle ne fait
   pas aujourd'hui : le rendu public reste sombre par choix éditorial, seul
   l'outil de rédaction propose le thème clair). */
[data-theme="light"] {
    --article-bg: #f5f5f7;
    --article-bg-soft: #ffffff;
    --article-text: #111111;
    --article-text-dim: rgba(0, 0, 0, 0.68);
    --article-text-muted: rgba(0, 0, 0, 0.42);
    --article-line: rgba(0, 0, 0, 0.12);
    --article-accent: #0099cc;
    --article-accent-dark: #00d4ff;
}

/* Conteneur générique : à poser sur le canvas d'édition ET sur le corps de
   la page publique pour que les deux partagent largeur/typographie. */
.article-column {
    max-width: var(--article-max-width);
    margin: 0 auto;
    width: 100%;
    color: var(--article-text);
    font-family: var(--article-font-body);
    line-height: 1.7;
}


/* Image de couverture en pleine largeur de fenêtre : sort du conteneur
   centré (technique du "bleed" par marges négatives en vw), hauteur qui
   suit la fenêtre plutôt que d'être figée. Un voile radial (::before) fait
   fumer les quatre bords de la photo dans le fond de la page, et un
   dégradé bas (::after) garantit en plus la lisibilité du titre/méta
   (.article-hero-text) posé À CHEVAL dessus. */
.article-hero {
    position: relative;
    width: 100vw;
    height: min(78vh, 680px);
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    margin-bottom: 1.6rem;
    overflow: hidden;
    display: flex;
    align-items: flex-end;
}

.article-hero img {
    position: absolute;
    inset: 0;
    display: block;
    width: 100%;
    height: 100%;
    object-fit: cover;
    z-index: 0;
}

/* Voile "fumé" : fondu vers le fond de la page sur les quatre bords, pas
   seulement en bas — un dégradé radial couvre naturellement haut/bas/côtés
   d'un coup, contrairement à plusieurs dégradés linéaires empilés. */
.article-hero::before {
    content: '';
    position: absolute;
    inset: 0;
    background:
        radial-gradient(ellipse 80% 75% at center, transparent 30%, rgba(5, 5, 5, 0.98) 100%),
        linear-gradient(to bottom, rgba(5, 5, 5, 0.75) 0%, transparent 26%, transparent 74%, rgba(5, 5, 5, 0.75) 100%);
    z-index: 1;
    pointer-events: none;
}

.article-hero::after {
    content: '';
    position: absolute;
    left: 0; right: 0; bottom: 0;
    height: 68%;
    background: linear-gradient(to top, rgba(5, 5, 5, 0.95) 0%, rgba(5, 5, 5, 0.5) 55%, rgba(5, 5, 5, 0) 100%);
    z-index: 2;
    pointer-events: none;
}

.article-hero-text {
    position: relative;
    z-index: 3;
    width: 100%;
    max-width: var(--article-max-width);
    margin: 0 auto;
    padding: 0 1.5rem 2.2rem;
    text-shadow: 0 2px 20px rgba(0, 0, 0, 0.65);
}

.article-hero-text .article-eyebrow,
.article-hero-text .article-h1 {
    margin-bottom: 0.7rem;
}

.article-hero-text .article-meta {
    margin-bottom: 0;
}

@media (max-width: 640px) {
    .article-hero {
        height: min(58vh, 480px);
    }
}

.article-eyebrow {
    font-family: var(--article-font-display);
    font-size: 0.75rem;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    /* Rouge de la marque (logo), pas le cyan --article-accent utilisé
       ailleurs pour les liens/surlignages. */
    color: var(--article-brand-red);
    margin-bottom: 0.8rem;
}

.article-h1 {
    font-family: var(--article-font-display);
    font-size: clamp(1.8rem, 4vw, 2.6rem);
    font-weight: 700;
    line-height: 1.2;
    margin: 0 0 1rem;
}

/* Auteur (photo + pseudo) à droite de la date, dans .article-meta. */
.article-meta-sep {
    opacity: 0.5;
}

.article-meta-author {
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
}

/* Photo en background-image sur un carré fixe plutôt qu'un <img> : une
   photo de profil peut être n'importe quelle résolution (les uploads ne
   sont pas recompressés) — un <img> garde une dimension intrinsèque qui
   peut fausser la mise en page tant que le navigateur n'a pas fini
   d'appliquer les règles de taille, alors qu'un fond n'a aucune taille
   propre : il ne peut pas influencer la mise en page, quelle que soit la
   résolution de la source. */
.article-meta-author-avatar {
    width: 22px;
    height: 22px;
    flex-shrink: 0;
    border-radius: 50%;
    background-color: var(--article-bg-soft);
    background-size: cover;
    background-position: center;
    box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.3);
}

.article-h2 {
    font-family: var(--article-font-display);
    font-size: 1.5rem;
    font-weight: 700;
    line-height: 1.3;
    margin: 2rem 0 0.8rem;
}

.article-h3 {
    font-family: var(--article-font-display);
    font-size: 1.2rem;
    font-weight: 600;
    line-height: 1.3;
    margin: 1.6rem 0 0.6rem;
}

.article-meta {
    display: flex;
    gap: 0.6rem;
    align-items: center;
    color: var(--article-text-muted);
    font-size: 0.85rem;
    margin-bottom: 2rem;
}

.article-p {
    font-size: 1.05rem;
    color: var(--article-text-dim);
    margin: 0 0 1.2rem;
}

.article-p b, .article-p strong { color: var(--article-text); font-weight: 700; }
.article-p a, .article-quote a { color: var(--article-accent); text-decoration: underline; text-underline-offset: 2px; }
.article-p mark, .article-p .cdx-marker { background: rgba(0, 212, 255, 0.25); color: var(--article-text); padding: 0 0.15em; }
.article-p code, .article-p .inline-code { background: var(--article-bg-soft); border: 1px solid var(--article-line); border-radius: 3px; padding: 0.1em 0.4em; font-size: 0.9em; }

/* Guillemet géant : plus de barre/fond, la citation devient un temps fort
   typographique (Space Grotesk large et gras) plutôt qu'un aparté discret.
   Le guillemet est un ::before décoratif, pas de changement de markup côté
   rendu serveur/editor. */
.article-quote {
    position: relative;
    margin: 2.4rem 0;
    padding: 0 0 0 2.2rem;
    font-family: var(--article-font-display);
    font-size: 1.5rem;
    font-weight: 700;
    font-style: normal;
    line-height: 1.25;
    color: var(--article-text);
}

.article-quote::before {
    content: '\201C';
    position: absolute;
    left: -0.5rem;
    top: -1.7rem;
    font-family: var(--article-font-display);
    font-size: 5.5rem;
    font-weight: 700;
    color: rgba(223, 3, 15, 0.28);
    line-height: 1;
    pointer-events: none;
}

.article-quote-caption {
    margin-top: 0.7rem;
    font-family: var(--article-font-display);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    font-style: normal;
    color: var(--article-brand-red);
}

.article-list {
    margin: 0 0 1.2rem 1.4rem;
    color: var(--article-text-dim);
    font-size: 1.05rem;
}

.article-list li {
    margin-bottom: 0.4rem;
}

.article-figure {
    margin: 1.8rem 0;
}

.article-figure-img {
    display: block;
    width: 100%;
    max-height: 640px;
    object-fit: cover;
    border-radius: var(--article-radius);
    background: var(--article-bg-soft);
}

/* Fondu à l'apparition plutôt qu'un "pop" brutal une fois l'image
   téléchargée — posé via onload inline (voir article-render.js et les
   pages qui injectent du HTML par innerHTML, pas de vrai listener JS
   possible sur une chaîne de caractères). Le texte, lui, ne dépend jamais
   du chargement des images : il est déjà dans le DOM au moment où le
   fondu démarre. */
.fade-img {
    opacity: 0;
    transition: opacity 0.35s ease;
}
.fade-img.is-loaded {
    opacity: 1;
}

.article-figure.article-cover img {
    max-height: 460px;
}

.article-figcaption {
    margin-top: 0.6rem;
    font-size: 0.85rem;
    color: var(--article-text-muted);
    text-align: center;
}

.article-divider {
    border: none;
    border-top: 1px solid var(--article-line);
    margin: 2.2rem 0;
}

/* ── Bloc "Texte + Image" (editor/text-image-tool.js) ───────────────────
   Mêmes classes utilisées dans l'éditeur (via le tool) et sur la page
   publique (api/_article-render.js) : un seul jeu de règles pour les
   deux, cohérent avec le reste de article-style.css. */
.ti-block {
    display: flex;
    align-items: stretch;
    gap: 1.5rem;
    margin: 1.8rem 0;
}

.ti-layout-image-right {
    flex-direction: row-reverse;
}

.ti-image-side {
    flex: 0 0 38%;
    position: relative;
}

.ti-text-side {
    flex: 1;
    min-width: 0;
    padding-top: 0.2rem;
}

.ti-image {
    display: block;
    width: 100%;
    border-radius: var(--article-radius);
    object-fit: cover;
    /* Bande filante : l'image reste épinglée dans sa colonne pendant que le
       texte défile à côté — .ti-block passe en align-items:stretch pour
       que cette colonne fasse toute la hauteur du bloc de texte. Décalage
       sous le header sticky (voir .site-header, ~72px). */
    position: sticky;
    top: 88px;
}

.ti-image-placeholder {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.4rem;
    width: 100%;
    aspect-ratio: 4 / 3;
    border: 2px dashed var(--article-line);
    border-radius: var(--article-radius);
    background: none;
    color: var(--article-text-muted);
    font-family: var(--article-font-body);
    font-size: 0.85rem;
    cursor: pointer;
    transition: border-color 0.2s, color 0.2s;
}

.ti-image-placeholder:hover {
    border-color: var(--article-accent);
    color: var(--article-text);
}

.ti-image-placeholder span:first-child {
    font-size: 1.6rem;
}

.ti-image-loading {
    display: flex;
    align-items: center;
    justify-content: center;
    aspect-ratio: 4 / 3;
    color: var(--article-text-muted);
    font-size: 0.8rem;
    border: 1px dashed var(--article-line);
    border-radius: var(--article-radius);
}

.ti-image-change {
    position: absolute;
    top: 0.5rem;
    right: 0.5rem;
    padding: 0.3rem 0.6rem;
    background: rgba(0, 0, 0, 0.65);
    border: 1px solid var(--article-line);
    border-radius: 4px;
    color: #fff;
    font-family: var(--article-font-body);
    font-size: 0.7rem;
    cursor: pointer;
    opacity: 0;
    transition: opacity 0.15s;
}

.ti-image-side:hover .ti-image-change {
    opacity: 1;
}

.ti-text {
    font-size: 1.05rem;
    color: var(--article-text-dim);
    line-height: 1.6;
    outline: none;
}

.ti-text:empty:before {
    content: attr(data-placeholder);
    color: var(--article-text-muted);
    font-style: italic;
}

.ti-text b, .ti-text strong { color: var(--article-text); font-weight: 700; }
.ti-text a { color: var(--article-accent); text-decoration: underline; text-underline-offset: 2px; }

@media (max-width: 640px) {
    .ti-block, .ti-layout-image-right {
        flex-direction: column;
    }
    .ti-image-side {
        flex-basis: auto;
        width: 100%;
    }
    .ti-image {
        position: static;
    }
}

/* ── Habillage d'Editor.js pour qu'il ressemble au rendu ci-dessus ──────
   Editor.js génère ses propres classes (.ce-*) ; on les surcharge plutôt
   que de les remplacer, pour ne pas casser son JS interne. */

.codex-editor {
    color: var(--article-text);
    font-family: var(--article-font-body);
}

.codex-editor__redactor {
    padding-bottom: 4rem !important;
}

.ce-block__content,
.ce-toolbar__content {
    max-width: var(--article-max-width) !important;
}

.ce-paragraph {
    font-size: 1.05rem;
    line-height: 1.7;
    color: var(--article-text-dim);
}

.ce-paragraph[data-placeholder]:empty::before {
    color: var(--article-text-muted);
}

.ce-header {
    font-family: var(--article-font-display);
    color: var(--article-text);
}

h1.ce-header { font-size: clamp(1.8rem, 4vw, 2.6rem); font-weight: 700; }
h2.ce-header { font-size: 1.5rem; font-weight: 700; }
h3.ce-header { font-size: 1.2rem; font-weight: 600; }

/* Le plugin @editorjs/quote injecte lui-même sa propre feuille de style
   (bordure bleue, padding) au chargement — après article-style.css dans
   le <head>, donc prioritaire à spécificité égale. !important nécessaire
   pour reprendre la main sur ces valeurs par défaut du plugin tiers.
   Même traitement "guillemet géant" que .article-quote côté rendu public. */
.cdx-quote {
    position: relative;
    border-left: none !important;
    background: none !important;
    padding-left: 2.2rem !important;
}
.cdx-quote::before {
    content: '\201C';
    position: absolute;
    left: -0.3rem;
    top: -1.7rem;
    font-family: var(--article-font-display);
    font-size: 5.5rem;
    font-weight: 700;
    color: rgba(223, 3, 15, 0.28);
    line-height: 1;
    pointer-events: none;
}
.cdx-quote__text,
.cdx-quote__caption {
    font-family: var(--article-font-body);
}

.cdx-quote__text {
    font-family: var(--article-font-display);
    font-size: 1.5rem;
    font-weight: 700;
    font-style: normal;
    color: var(--article-text);
}

.cdx-quote__caption {
    font-family: var(--article-font-display);
    font-size: 0.7rem;
    font-weight: 600;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--article-brand-red);
}

.cdx-list {
    font-size: 1.05rem;
    color: var(--article-text-dim);
}

.image-tool__image-picture {
    border-radius: var(--article-radius);
    border: 1px solid var(--article-line);
}

.image-tool__caption {
    font-family: var(--article-font-body);
    color: var(--article-text-muted);
}

.cdx-marker {
    background: rgba(0, 212, 255, 0.25);
}

.inline-code {
    background: var(--article-bg-soft);
    border: 1px solid var(--article-line);
    border-radius: 3px;
    padding: 0.1em 0.4em;
}

.ce-inline-toolbar,
.ce-conversion-toolbar,
.ce-settings,
.ce-toolbar__plus,
.ce-toolbar__settings-btn,
.ce-popover {
    font-family: var(--article-font-body);
    background: var(--article-bg-soft) !important;
    border-color: var(--article-line) !important;
    border-radius: 10px !important;
    color: var(--article-text) !important;
}

.ce-toolbar__plus,
.ce-toolbar__settings-btn {
    border-radius: 8px !important;
}

.ce-inline-tool,
.ce-toolbar__plus,
.ce-toolbar__settings-btn {
    color: var(--article-text-dim) !important;
}

.ce-inline-tool:hover,
.ce-toolbar__plus:hover,
.ce-toolbar__settings-btn:hover,
.ce-popover-item:hover {
    background: rgba(0, 212, 255, 0.12) !important;
    color: var(--article-accent) !important;
}

.ce-inline-tool--active {
    color: var(--article-accent) !important;
}
