/* ==========================================
   POLICES — hébergées en local, aucun appel externe
   ========================================== */
@font-face {
    font-family: 'Spectral';
    src: url('fonts/Spectral-SemiBold.woff2') format('woff2');
    font-weight: 600;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Spectral';
    src: url('fonts/Spectral-Bold.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Alegreya Sans';
    src: url('fonts/AlegreyaSans-Regular.woff2') format('woff2');
    font-weight: 400;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Alegreya Sans';
    src: url('fonts/AlegreyaSans-Medium.woff2') format('woff2');
    font-weight: 500;
    font-style: normal;
    font-display: swap;
}
@font-face {
    font-family: 'Alegreya Sans';
    src: url('fonts/AlegreyaSans-Bold.woff2') format('woff2');
    font-weight: 700;
    font-style: normal;
    font-display: swap;
}

html {
    font-size: 18px;
}

/* ==========================================
   THÈMES — 12 variables de couleur, + --danger-ink (G34b, 13e variable)
   ========================================== */
:root {
    --font-title: 'Spectral', Georgia, serif;
    --font-main: 'Alegreya Sans', system-ui, sans-serif;
    --font-mono: ui-monospace, Menlo, Consolas, monospace;
    --banner-height: 46px;

    /* grimoire (défaut) */
    --bg: #14100D;
    --surface: #1E1814;
    --surface-alt: #26201A;
    --line: #3A2F26;
    --line-strong: #54443A;
    --ink: #E6DCC8;
    --ink-muted: #9A8A74;
    --accent: #8A6415;
    --accent-bright: #D9A441;
    --danger: #A8321F;
    --danger-ink: #E08D78;
    --success: #4E7A3F;
    --warning: #B8860B;

    /* Couleurs des objets de carte (titre/texte libre) : volontairement
       identiques quel que soit le thème choisi pour l'interface, puisqu'elles
       représentent une "encre" sur la carte elle-même, pas la coquille du site. */
    --map-title-ink: #fdf6e3;
    --map-freetext-ink: #dbe9ff;
    --map-marker-ink: #fff;   /* contours de marqueurs et libellés de POI */
    --map-halo: #000;         /* halo de lisibilité derrière les textes */

    /* Lot E, correctif §1 — décollement des objets cliquables : liseré de
       découpe + ombre portée. Mêmes raisons que ci-dessus : fixes quel que
       soit le thème, puisqu'elles représentent la physique de la carte. */
    --map-sticker-edge: #fffcf4;   /* liseré blanc cassé de découpe */
    --map-sticker-shadow: #080b14; /* variante assombrie de l'encre, jamais du noir pur */
}

[data-theme="parchemin"] {
    --bg: #EFE3C8;
    --surface: #F7EED8;
    --surface-alt: #E7D9B8;
    --line: #CDB98F;
    --line-strong: #B09A6B;
    --ink: #2A1D12;
    --ink-muted: #665238;
    --accent: #9C7F4A;
    --accent-bright: #6E2233; /* bordeaux de cire : cire pour ce qui compte, or pour ce qui décore */
    --danger: #C0392B;
    --danger-ink: #A8291C;
    --success: #2F6D2F;
    --warning: #8A6415;
}

[data-theme="necromant"] {
    --bg: #080A09;
    --surface: #0E1210;
    --surface-alt: #1A211D;
    --line: #1C2420;
    --line-strong: #2B3833;
    --ink: #C4CBC2;
    --ink-muted: #808C7A;
    --accent: #3E6B50;
    --accent-bright: #7BD9A2;
    --danger: #8A3030;
    --success: #4E7A5C;
    --warning: #B08A3A;
}

/* ==========================================
   ÉCHELLE TYPOGRAPHIQUE — 6 valeurs en rem, ce sont les SEULES tailles du site
   (hors bordures/radius/cibles tactiles/glyphes SVG, qui restent en px)
   0.7rem  micro-libellé et titres de section (capitales)
   0.8rem  libellés de champ, en-têtes de colonne, cellules de tableau,
           métadonnées, compteurs
   0.95rem texte courant, noms d'objets, valeurs de champ, libellés de boutons
   1.45rem titres de cartes, titres de fenêtres modales
   1.75rem titre de page
   3.9rem  frontispice (PARAVENT sur l'accueil)
   ========================================== */
.frontispiece-title {
    font: 700 3.9rem var(--font-title);
    letter-spacing: 11px;
    text-transform: uppercase;
    color: var(--accent-bright);
    margin-left: 11px;
}

.page-title,
h1 {
    font: 700 1.75rem var(--font-title);
    color: var(--accent-bright);
    margin: 0;
}

.card-title,
.modal-title {
    font: 700 1.45rem var(--font-title);
    color: var(--ink);
    margin: 0;
}

.section-title,
h2 {
    display: flex;
    align-items: center;
    gap: 10px;
    font: 600 0.7rem var(--font-main);
    letter-spacing: 2.8px;
    text-transform: uppercase;
    color: var(--ink-muted);
    margin: 0;
}
.section-title::after {
    content: '';
    flex: 1;
    height: 1px;
    background: var(--line);
}

.object-name {
    font: 600 0.95rem var(--font-title);
    color: var(--ink);
}

.meta-text {
    font: 400 0.8rem var(--font-main);
    color: var(--ink-muted);
}

.micro-label {
    font: 600 0.7rem var(--font-main);
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--ink-muted);
}

/* Rythme vertical (G32.3) — en rem, pour ne pas se resserrer quand le texte grossit */
:root {
    --space-label-field: 0.45rem;
    --space-field-field: 1.35rem;
    --space-after-section-title: 1.8rem;
    --space-between-sections: 2.2rem;
}

/* ==========================================
   ÉLÉMENTS COMMUNS
   ========================================== */
body {
    margin: 0;
    padding: 0;
    font: 400 0.95rem/1.5 var(--font-main);
    background-color: var(--bg);
    color: var(--ink);
}

/* Motif de page (G24) : le bandeau (partials/banner.php) est le premier
   enfant de <body>, hors de tout conteneur ; .page porte les marges du
   contenu qui suit. Aucune page ne doit remettre du padding sur body. */
.page {
    padding: 30px;
    box-sizing: border-box;
}

.zone {
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: 4px;
    padding: 20px;
    margin-bottom: var(--space-between-sections);
}
.zone h2 {
    padding-bottom: var(--space-after-section-title);
}

table {
    width: 100%;
    border-collapse: collapse;
}
th, td {
    text-align: left;
    border-bottom: 1px solid var(--line);
    vertical-align: middle;
}
label,
th,
td,
.field-label {
    font: 500 0.8rem var(--font-main);
    color: var(--ink-muted);
}
td {
    font-weight: 400;
    color: var(--ink);
}

textarea {
    display: block;
    margin: 0;
}

input[type="text"], textarea, select {
    background-color: var(--surface-alt);
    color: var(--ink);
    border: 1px solid var(--line-strong);
    border-radius: 3px;
    font: 400 0.95rem var(--font-main);
}

/* ==========================================
   BOUTONS DE THÈME — partagés entre le bandeau et le frontispice
   Taille fixée par le contexte (32px bandeau, 34px accueil) via width/height
   inline ou une classe contextuelle ; ce qui suit est l'apparence commune.
   ========================================== */
.theme-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    background: transparent;
    border: none;
    border-radius: 3px;
    padding: 0;
    box-sizing: border-box;
    color: var(--ink-muted);
    cursor: pointer;
    transition: 0.15s;
}
.theme-btn-active {
    color: var(--accent-bright);
    background: color-mix(in srgb, var(--accent-bright) 12%, transparent);
}
@media (max-width: 900px) {
    .theme-btn {
        min-width: 44px;
        min-height: 44px;
    }
}

/* ==========================================
   BANDEAU (partials/banner.php)
   Doit disparaître quand la carte passe en plein écran (mécanique ajoutée
   au lot 3, mais le point d'accroche CSS est prévu dès maintenant).
   ========================================== */
.site-banner {
    position: sticky;
    top: 0;
    z-index: 20;
    height: var(--banner-height);
    background: var(--surface-alt);
    border-bottom: 1px solid var(--line-strong);
    display: flex;
    align-items: center;
    padding: 0 20px;
    gap: 14px;
}
body.map-fullscreen .site-banner {
    display: none;
}

.banner-brand {
    display: flex;
    align-items: center;
    gap: 8px;
    line-height: 1;
    text-decoration: none;
    color: var(--ink);
}
.banner-mark-icon {
    display: none;
    color: var(--accent-bright);
    opacity: 0.62;
}
.banner-mark-icon-mirror {
    transform: scaleX(-1);
}
html:not([data-theme]) .banner-mark-icon-grimoire,
[data-theme="grimoire"] .banner-mark-icon-grimoire,
[data-theme="parchemin"] .banner-mark-icon-parchemin,
[data-theme="necromant"] .banner-mark-icon-necromant {
    display: inline-flex;
}
.banner-brand-name {
    font: 600 0.8rem var(--font-title);
    letter-spacing: 2.6px;
    text-transform: uppercase;
    margin-left: 2.6px;
}

.banner-breadcrumb {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    overflow: hidden;
}
.banner-crumb-sep {
    color: var(--line-strong);
    font-size: 0.8rem;
}
.banner-crumb-link {
    font: 400 0.8rem var(--font-title);
    color: var(--accent-bright);
    text-decoration: none;
    white-space: nowrap;
}
.banner-crumb-link:hover {
    text-decoration: underline;
}
.banner-crumb-current {
    font: 400 0.8rem var(--font-title);
    color: var(--ink-muted);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.banner-themes {
    display: flex;
    gap: 4px;
    flex-shrink: 0;
}
.banner-themes .theme-btn {
    width: 32px;
    height: 32px;
}
.banner-themes .theme-btn svg {
    width: 17px;
    height: 17px;
}

/* ==========================================
   ÉTATS VIDES — bloc réutilisable, section 9 du brief
   Seul endroit où le picto de thème est purement décoratif.
   ========================================== */
.empty-state {
    text-align: center;
    padding: 60px 20px;
}
.empty-state-icon {
    display: none;
    opacity: 0.28;
    color: var(--accent);
    margin-bottom: 16px;
}
html:not([data-theme]) .empty-state-icon-grimoire,
[data-theme="grimoire"] .empty-state-icon-grimoire,
[data-theme="parchemin"] .empty-state-icon-parchemin,
[data-theme="necromant"] .empty-state-icon-necromant {
    display: inline-flex;
}
.empty-state-text {
    font: 400 0.95rem var(--font-title);
    color: var(--ink-muted);
    margin: 0 0 16px;
}

/* ==========================================
   FILETS D'ANGLE — réservés aux surfaces "à la table" (cartes de l'accueil,
   tuiles du soundboard). Ne jamais les mettre sur un panneau d'administration :
   leur absence identifie justement les écrans de préparation.
   Chaque contexte garde localement sa taille et son décalage.
   ========================================== */
.corner-accent {
    position: absolute;
    opacity: 0.6;
    pointer-events: none;
}

/* ==========================================
   CONTRÔLES NATIFS — curseurs et cases à cocher/radio suivent l'accent du
   thème plutôt que la couleur système du navigateur (G1)
   ========================================== */
input[type="range"],
input[type="checkbox"],
input[type="radio"] {
    accent-color: var(--accent-bright);
}

::placeholder {
    color: var(--ink-muted);
    opacity: 1; /* indispensable : neutralise l'atténuation par défaut de Firefox */
}

select:has(option[value=""]:checked) {
    color: var(--ink-muted);
}

.field-info-icon {
    display: inline-flex;
    color: var(--ink-muted);
    cursor: help;
    margin-left: 4px;
    vertical-align: middle;
}
.field-info-icon:hover {
    color: var(--accent-bright);
}

/* Bouton d'icône rond — UNE SEULE définition pour tout le site (G12/G36) :
   cercle au contour, jamais plein, pour ne pas concurrencer visuellement
   l'action principale de l'écran (G22). aspect-ratio ET flex: none sont
   tous deux nécessaires : le premier empêche l'étirement, le second empêche
   la compression par le conteneur (colonne de tableau en %, par exemple). */
.icon-btn-round {
    width: 34px;
    height: 34px;
    aspect-ratio: 1;
    flex: none;
    border-radius: 50%;
    border: 1px solid var(--accent-bright);
    background: color-mix(in srgb, var(--accent-bright) 12%, transparent);
    color: var(--accent-bright);
    display: inline-flex;
    align-items: center;
    justify-content: center;
    padding: 0;
    line-height: 1;
    cursor: pointer;
    transition: filter 0.15s;
}
.icon-btn-round:hover {
    filter: brightness(1.15);
}
.icon-btn-round svg {
    display: block;
}
.icon-btn-round--lg {
    width: 40px;
    height: 40px;
}
.icon-btn-round .icon-play {
    /* Centrage optique (G4/G36) : un triangle pointant à droite n'est jamais
       optiquement centré quand il est géométriquement centré. Décalage sur
       le triangle SEUL, jamais sur le bouton, sinon l'icône de pause
       (symétrique) se décale à son tour. */
    transform: translateX(1px);
}
@media (pointer: coarse) {
    .icon-btn-round {
        width: 44px;
        height: 44px;
    }
}

/* ==========================================
   NOTATION EN PICTOS DE THÈME — définition unique du site (G35). Livre
   (grimoire), rouleau (parchemin) ou crâne (necromant) : plein = acquis,
   contour = non acquis. Même tracé dans les deux états (silhouette
   identique), seul le remplissage change — l'information ne repose donc
   jamais sur la seule couleur.
   ========================================== */
.rating {
    display: inline-flex;
    gap: 3px;
    align-items: center;
}
.rating-item {
    background: none;
    border: none;
    cursor: pointer;
    padding: 4px 3px;
    line-height: 1;
}
.rating-item svg {
    display: block;
    width: 14px;
    height: 14px;
}
.rating-glyph {
    display: none;
}
html:not([data-theme]) .rating-glyph-grimoire,
[data-theme="grimoire"] .rating-glyph-grimoire,
[data-theme="parchemin"] .rating-glyph-parchemin,
[data-theme="necromant"] .rating-glyph-necromant {
    display: inline-flex;
}
.rating-item.on {
    color: var(--accent-bright);
}
.rating-item.off {
    color: color-mix(in srgb, var(--ink) 34%, var(--surface-alt));
}
@media (pointer: coarse) {
    .rating-item {
        padding: 11px 6px;
    }
}
/* Popup de notation : un seul son à la fois, la notation EST l'action
   principale de cet écran-là, le glyphe peut donc être plus grand. */
.rating--lg .rating-item svg {
    width: 24px;
    height: 24px;
}

/* Recette d'un bouton destructif (G34b) : le trait/fond portent le signal,
   --danger-ink porte la lisibilité du texte (un rouge assez vif pour se
   distinguer contraste peu sur un fond clair — les deux ne peuvent pas être
   la même valeur, voir le thème parchemin). */
.btn-danger-outline {
    border: 1px solid var(--danger);
    background: color-mix(in srgb, var(--danger) 15%, transparent);
    color: var(--danger-ink);
}

/* ==========================================
   FOCUS CLAVIER — une seule règle, valable pour tout le site
   ========================================== */
:focus-visible {
    outline: 2px solid var(--accent-bright);
    outline-offset: 2px;
}

/* ==========================================
   BANDEAU DE NOTIFICATION — remplace les alert() (assets/notice.js)
   ========================================== */
.notice-banner {
    position: fixed;
    bottom: 20px;
    left: 50%;
    transform: translateX(-50%);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-left: 3px solid var(--danger);
    border-radius: 3px;
    padding: 12px 18px;
    box-shadow: 0 8px 24px rgba(0,0,0,0.4);
    font: 400 0.95rem var(--font-main);
    color: var(--ink);
    z-index: 1000;
    cursor: pointer;
}
.notice-banner.notice-ok {
    border-left-color: var(--success);
}

/* ==========================================
   GÉOMÉTRIE — valeurs uniques, aucune autre dans le site
   3px  : boutons, champs, onglets, boutons de thème
   4px  : cartes, panneaux, tuiles, menus déroulants
   14px : étiquettes de filtre UNIQUEMENT (forme de gélule)
   50%  : boutons d'icône ronds (lecture/pause) UNIQUEMENT
   Filets 1px solid --line ou --line-strong, toujours pleins (jamais
   dashed, sauf l'unique carte "à venir" de l'accueil).
   Ombres réservées au bandeau collant et aux menus déroulants — pas aux
   cartes ni aux tuiles.
   ========================================== */

/* ==========================================
   LOT E, CORRECTIF §1 — décollement des points d'intérêt de carte.
   SOURCE UNIQUE des valeurs de liseré/ombre pour map_builder.php ET map.php.
   Rendu en calque HTML (jamais en <image> SVG) : les drop-shadow en px se
   mesurent alors sans ambiguïté à l'écran, quel que soit le zoom courant —
   une <image> dans un viewBox à l'échelle mesurerait ces px dans l'espace
   carte, pas à l'écran, et l'effet deviendrait invisible ou disproportionné.

   --poi-shadow-coeff est fourni en inline style par objet, dérivé du cran
   choisi (cran.px / 96) — un seul coefficient calculé à partir des crans
   déjà définis dans config.php, jamais une valeur recopiée par objet.
   ========================================== */
.poi-sticker-layer {
    position: absolute;
    inset: 0;
    pointer-events: none;
}
.poi-sticker {
    position: absolute;
    transform: translate(-50%, -50%);
    display: flex;
    flex-direction: column;
    align-items: center;
    pointer-events: none;
}
.poi-sticker-hit {
    position: absolute;
    /* top fixé en JS/PHP à la moitié de la hauteur RÉELLE de l'icône —
       jamais 0 : l'icône démarre en haut de la boîte flex (.poi-sticker),
       donc son centre vertical est à icône.hauteur / 2, pas au sommet de
       la boîte. Fixer top ici serait faux dès que la taille change. */
    left: 50%;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    pointer-events: auto;
    cursor: pointer;
    background: transparent;
}
.poi-sticker-hit.no-link {
    cursor: default;
    pointer-events: none;
}

.poi-sticker-icon {
    display: block;
    object-fit: contain;
    pointer-events: none;
    transform-origin: center bottom; /* ancré par le bas (§1.3) : grandit vers le haut, jamais sur le nom */
    transition: filter 190ms ease, transform 190ms ease;
    filter:
        drop-shadow(0 0 1.3px var(--map-sticker-edge))
        drop-shadow(0 0 1.3px var(--map-sticker-edge))
        drop-shadow(0 0 1.3px color-mix(in srgb, var(--map-sticker-edge) 90%, transparent))
        drop-shadow(0 calc(1px * var(--poi-shadow-coeff, 1)) calc(1.5px * var(--poi-shadow-coeff, 1)) color-mix(in srgb, var(--map-sticker-shadow) 60%, transparent))
        drop-shadow(0 calc(3px * var(--poi-shadow-coeff, 1)) calc(3px * var(--poi-shadow-coeff, 1)) color-mix(in srgb, var(--map-sticker-shadow) 58%, transparent))
        drop-shadow(0 calc(6px * var(--poi-shadow-coeff, 1)) calc(9px * var(--poi-shadow-coeff, 1)) color-mix(in srgb, var(--map-sticker-shadow) 62%, transparent));
}
/* Marqueur de secours (aucune icône assignée) : même traitement, cercle plat. */
.poi-sticker-fallback {
    border-radius: 50%;
    background: var(--danger);
    border: 2px solid var(--map-marker-ink);
    box-sizing: border-box;
    transform-origin: center bottom;
    transition: filter 190ms ease, transform 190ms ease;
    filter:
        drop-shadow(0 0 1.3px var(--map-sticker-edge))
        drop-shadow(0 calc(1px * var(--poi-shadow-coeff, 1)) calc(1.5px * var(--poi-shadow-coeff, 1)) color-mix(in srgb, var(--map-sticker-shadow) 60%, transparent))
        drop-shadow(0 calc(3px * var(--poi-shadow-coeff, 1)) calc(3px * var(--poi-shadow-coeff, 1)) color-mix(in srgb, var(--map-sticker-shadow) 58%, transparent));
}
.poi-sticker-fallback.poi-linked { background: var(--accent-bright); }

.poi-sticker:hover .poi-sticker-icon,
.poi-sticker.force-hover .poi-sticker-icon {
    transform: scale(1.16);
    filter:
        drop-shadow(0 0 1.3px var(--map-sticker-edge))
        drop-shadow(0 0 1.3px var(--map-sticker-edge))
        drop-shadow(0 0 1.3px color-mix(in srgb, var(--map-sticker-edge) 90%, transparent))
        drop-shadow(0 calc(3px * var(--poi-shadow-coeff, 1)) calc(3px * var(--poi-shadow-coeff, 1)) color-mix(in srgb, var(--map-sticker-shadow) 68%, transparent))
        drop-shadow(0 calc(9px * var(--poi-shadow-coeff, 1)) calc(7px * var(--poi-shadow-coeff, 1)) color-mix(in srgb, var(--map-sticker-shadow) 72%, transparent))
        drop-shadow(0 calc(18px * var(--poi-shadow-coeff, 1)) calc(24px * var(--poi-shadow-coeff, 1)) color-mix(in srgb, var(--map-sticker-shadow) 80%, transparent));
}
.poi-sticker:hover .poi-sticker-fallback,
.poi-sticker.force-hover .poi-sticker-fallback {
    transform: scale(1.16);
}

/* En attente (§1, §7) : à plat, désaturé — ne s'est PAS encore décollé.
   Ne s'applique JAMAIS côté joueurs (le rendu "en attente" n'existe que
   côté MJ) : voir map.php, qui ne pose jamais cette classe. */
.poi-sticker.pending .poi-sticker-icon,
.poi-sticker.pending .poi-sticker-fallback {
    transform: none !important;
    filter:
        grayscale(1) opacity(.55)
        drop-shadow(0 0 1.2px color-mix(in srgb, var(--map-sticker-edge) 50%, transparent))
        drop-shadow(0 1px 2px color-mix(in srgb, var(--map-sticker-shadow) 22%, transparent)) !important;
}

.poi-sticker-name {
    font-family: var(--font-main);
    font-size: 15px;
    font-weight: 500;
    color: var(--map-marker-ink);
    white-space: nowrap;
    pointer-events: none;
    text-shadow:
        0 0 1.5px color-mix(in srgb, var(--map-sticker-shadow) 95%, transparent),
        0 1px 3px color-mix(in srgb, var(--map-sticker-shadow) 55%, transparent);
    transition: transform 140ms ease, font-weight 140ms ease, text-shadow 140ms ease;
}
.poi-sticker:hover .poi-sticker-name,
.poi-sticker.force-hover .poi-sticker-name {
    font-weight: 700;
    transform: scale(1.15);
    text-shadow:
        0 0 2px color-mix(in srgb, var(--map-sticker-shadow) 100%, transparent),
        0 0 6px color-mix(in srgb, var(--map-sticker-shadow) 90%, transparent),
        0 2px 5px color-mix(in srgb, var(--map-sticker-shadow) 70%, transparent);
}
.poi-sticker.pending .poi-sticker-name {
    opacity: 0.6;
}

.poi-sticker.selected .poi-sticker-hit {
    outline: 1.5px dashed var(--accent-bright);
    outline-offset: -1px;
}