/* ==========================================================================
   Radar 132 — styles.css
   Design system PAR-DESSUS Tailwind (chargé après tailwind.css dans index.html).
   Thème : brand #1e3a8a · alerte #dc2626 · fond #f8fafc · police Inter.

   Organisation :
     0.  Variables :root (tokens de design)
     1.  Thème sombre — 3 sélecteurs cohérents
     2.  Skeletons & shimmer
     3.  Micro-interactions globales & focus-visible
     4.  Animation d'entrée des cartes (stagger)
     5.  Header & navigation par pôle (.pole-btn / .active-pole)
     6.  Cartes d'articles (#news-grid article / .news-card)
     7.  Nouveaux composants carte (.news-card__open, .news-card__actions,
         .share-btn, .bookmark-btn, .card-source-link)
     8.  Contrôles de l'interface (#theme-toggle, #bookmark-filter,
         #refresh-indicator, #loading-indicator, #alert-toast,
         #data-source-note)
     9.  Champs de formulaire (#search-input, #category-filter, #sort-filter)
    10.  Modale (#modal-overlay — slide-up, body.modal-open)
    11.  Utilitaires (.hidden)
    12.  Responsive (mobile → 4K)
    13.  Impression (@media print)
    14.  Mouvement réduit (@media prefers-reduced-motion)
   ========================================================================== */


/* ==========================================================================
   0. VARIABLES :root — TOKENS DE DESIGN
   Toutes les valeurs de l'application sont centralisées ici. Le thème sombre
   redéfinit les tokens colorés sans changer les tokens de géométrie.
   ========================================================================== */
:root {
  /* Couleurs brand */
  --brand:          #1e3a8a;   /* bleu brand (header, accents, ring focus) */
  --alert:          #dc2626;   /* rouge alerte (bandeau, liseré, badges) */

  /* Couleurs sémantiques (mode clair par défaut) */
  --bg:             #f8fafc;   /* fond de page (slate-50) */
  --card-bg:        #ffffff;   /* fond des cartes */
  --text:           #1e293b;   /* texte principal (slate-800) */
  --muted:          #64748b;   /* texte secondaire (slate-500) */
  --border:         #e2e8f0;   /* bordures légères (slate-200) */

  /* Géométrie (inchangée quel que soit le thème) */
  --radius:         0.5rem;    /* border-radius standard (cartes, champs) */
  --radius-lg:      0.75rem;   /* border-radius large (modale) */

  /* Ombres */
  --shadow-sm:      0 1px 3px  rgba(15, 23, 42, 0.08),
                    0 1px 2px  rgba(15, 23, 42, 0.04);
  --shadow-md:      0 4px 12px rgba(15, 23, 42, 0.12),
                    0 2px 6px  rgba(15, 23, 42, 0.06);
  --shadow-lg:      0 12px 28px rgba(15, 23, 42, 0.18),
                    0 4px 10px  rgba(15, 23, 42, 0.10);

  /* Transitions */
  --transition:     200ms ease;

  /* Espacements (système 4 px) */
  --space-1:        0.25rem;   /*  4 px */
  --space-2:        0.5rem;    /*  8 px */
  --space-3:        0.75rem;   /* 12 px */
  --space-4:        1rem;      /* 16 px */
  --space-5:        1.25rem;   /* 20 px */
  --space-6:        1.5rem;    /* 24 px */
}


/* ==========================================================================
   1. THÈME SOMBRE — 3 SÉLECTEURS COHÉRENTS
   ─────────────────────────────────────────
   • @media (prefers-color-scheme:dark) : suit le système (attribut absent)
   • [data-theme="dark"]                : thème forcé en sombre
   • [data-theme="light"]               : force le mode clair même si OS=dark

   L'attribut data-theme est posé sur <html> par theme-init.js (AVANT les CSS)
   pour éviter tout flash. Les sélecteurs data-theme ont priorité CSS naturelle
   sur le @media car ils sont plus spécifiques (attribut > requête média).
   ========================================================================== */

/* --- Mode clair forcé ([data-theme="light"]) --------------------------------
   Force les tokens sur leurs valeurs claires, même si OS préfère le sombre. */
[data-theme="light"] {
  --bg:      #f8fafc;
  --card-bg: #ffffff;
  --text:    #1e293b;
  --muted:   #64748b;
  --border:  #e2e8f0;
}

/* --- Tokens communs au thème sombre ----------------------------------------
   Appliqués à la fois par la requête média ET par l'attribut data-theme. */
@media (prefers-color-scheme: dark) {
  :root {
    --bg:      #0f172a;        /* slate-900 */
    --card-bg: #1e293b;        /* slate-800 */
    --text:    #e2e8f0;        /* slate-200 */
    --muted:   #94a3b8;        /* slate-400 */
    --border:  rgba(148, 163, 184, 0.20); /* slate-400 / 20 % */
  }
}
[data-theme="dark"] {
  --bg:      #0f172a;
  --card-bg: #1e293b;
  --text:    #e2e8f0;
  --muted:   #94a3b8;
  --border:  rgba(148, 163, 184, 0.20);
}

/* --- Application des tokens à l'ensemble de la page ----------------------- */
body {
  background-color: var(--bg);
  color: var(--text);
  transition: background-color var(--transition), color var(--transition);
}

/* --- Recoloriage des éléments en thème sombre ----------------------------- */

/* Sélecteur partagé (media + attribut) — on factorise les règles visuelles */
@media (prefers-color-scheme: dark) {
  /* Fond de page */
  body { background-color: var(--bg); color: var(--text); }

  /* Header brand : conservé lisible sur fond brand */
  header {
    background-color: var(--brand) !important;
    color: #ffffff;
  }

  /* Cartes */
  #news-grid article,
  .news-card {
    background-color: var(--card-bg) !important;
    color: var(--text);
    border-color: var(--border);
  }

  /* Titres dans les cartes */
  .news-card h3,
  .news-card__open h3 {
    color: #93c5fd; /* blue-300 — contraste AA sur fond slate-800 */
  }

  /* Texte secondaire */
  .news-card p,
  .news-card time,
  .news-card .text-gray-600,
  .news-card .text-gray-500 {
    color: var(--muted) !important;
  }

  /* Séparateur pied de carte */
  .news-card .border-t {
    border-color: var(--border);
  }

  /* Champs de formulaire */
  #search-input,
  #category-filter,
  #sort-filter {
    background-color: var(--card-bg);
    color: var(--text);
    border-color: rgba(148, 163, 184, 0.35);
  }

  /* Placeholder des champs */
  #search-input::placeholder {
    color: var(--muted);
  }

  /* Modale */
  #modal-overlay .modal-content {
    background-color: var(--card-bg);
    color: var(--text);
    border: 1px solid var(--border);
  }

  /* Texte de la modale */
  #modal-overlay .modal-content h2,
  #modal-title {
    color: #93c5fd; /* blue-300 — lisible sur slate-800 */
  }

  #modal-overlay .modal-content .text-gray-600,
  #modal-overlay .modal-content .text-gray-800,
  #modal-resume {
    color: var(--text) !important;
  }

  #modal-overlay .modal-content .text-gray-400 {
    color: var(--muted);
  }

  /* Bandeau alerte : rouge conservé (pas de recoloriage, contraste natif) */
  #alert-banner {
    background-color: var(--alert);
  }

  /* État vide */
  #empty-state {
    color: var(--muted);
  }

  /* Pied de page */
  footer {
    color: var(--muted);
    border-color: var(--border);
  }

  /* Toast */
  #alert-toast {
    background-color: var(--card-bg);
    color: var(--text);
    border-color: var(--border);
    box-shadow: var(--shadow-lg);
  }

  /* Note source de données */
  #data-source-note {
    color: var(--muted);
  }
}

/* Même règles via attribut data-theme="dark" */
[data-theme="dark"] body { background-color: var(--bg); color: var(--text); }

[data-theme="dark"] header {
  background-color: var(--brand) !important;
  color: #ffffff;
}

[data-theme="dark"] #news-grid article,
[data-theme="dark"] .news-card {
  background-color: var(--card-bg) !important;
  color: var(--text);
  border-color: var(--border);
}

[data-theme="dark"] .news-card h3,
[data-theme="dark"] .news-card__open h3 {
  color: #93c5fd;
}

[data-theme="dark"] .news-card p,
[data-theme="dark"] .news-card time,
[data-theme="dark"] .news-card .text-gray-600,
[data-theme="dark"] .news-card .text-gray-500 {
  color: var(--muted) !important;
}

[data-theme="dark"] .news-card .border-t {
  border-color: var(--border);
}

[data-theme="dark"] #search-input,
[data-theme="dark"] #category-filter,
[data-theme="dark"] #sort-filter {
  background-color: var(--card-bg);
  color: var(--text);
  border-color: rgba(148, 163, 184, 0.35);
}

[data-theme="dark"] #search-input::placeholder {
  color: var(--muted);
}

[data-theme="dark"] #modal-overlay .modal-content {
  background-color: var(--card-bg);
  color: var(--text);
  border: 1px solid var(--border);
}

[data-theme="dark"] #modal-title {
  color: #93c5fd;
}

[data-theme="dark"] #modal-resume,
[data-theme="dark"] #modal-overlay .modal-content .text-gray-600,
[data-theme="dark"] #modal-overlay .modal-content .text-gray-800 {
  color: var(--text) !important;
}

[data-theme="dark"] #modal-overlay .modal-content .text-gray-400 {
  color: var(--muted);
}

[data-theme="dark"] #empty-state {
  color: var(--muted);
}

[data-theme="dark"] footer {
  color: var(--muted);
  border-color: var(--border);
}

[data-theme="dark"] #alert-toast {
  background-color: var(--card-bg);
  color: var(--text);
  border-color: var(--border);
  box-shadow: var(--shadow-lg);
}

[data-theme="dark"] #data-source-note {
  color: var(--muted);
}


/* ==========================================================================
   2. SKELETONS & SHIMMER
   Cartes fantômes affichées pendant le premier chargement des flux RSS.
   L'animation shimmer passe de gauche à droite sur un dégradé gris.
   aria-hidden="true" sur .skeleton-card (posé par A2/HTML).
   ========================================================================== */

/* Animation shimmer : dégradé qui balaye de gauche à droite */
@keyframes radar-shimmer {
  from { background-position: -400px 0; }
  to   { background-position:  400px 0; }
}

/* Bloc générique avec effet shimmer */
.skeleton {
  background: linear-gradient(
    90deg,
    #e2e8f0 25%,
    #f1f5f9 50%,
    #e2e8f0 75%
  );
  background-size: 800px 100%;
  animation: radar-shimmer 1.4s ease-in-out infinite;
  border-radius: var(--radius);
}

/* Carte fantôme complète : même géométrie qu'une .news-card */
.skeleton-card {
  background-color: var(--card-bg);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  border-left: 4px solid var(--border);
  padding: var(--space-5);
  overflow: hidden;
}

/* Ligne de chargement interne à la .skeleton-card */
.skeleton-card .skeleton-line {
  height: 0.875rem;
  margin-bottom: var(--space-3);
  border-radius: calc(var(--radius) / 2);
}

/* Largeurs différentes pour simuler du texte naturel */
.skeleton-card .skeleton-line:nth-child(1) { width: 55%; }
.skeleton-card .skeleton-line:nth-child(2) { width: 100%; height: 1.25rem; }
.skeleton-card .skeleton-line:nth-child(3) { width: 100%; }
.skeleton-card .skeleton-line:nth-child(4) { width: 85%; }
.skeleton-card .skeleton-line.skeleton-footer {
  width: 65%;
  margin-top: var(--space-4);
}

/* Thème sombre : dégradé plus sombre */
@media (prefers-color-scheme: dark) {
  .skeleton {
    background: linear-gradient(
      90deg,
      #334155 25%,
      #475569 50%,
      #334155 75%
    );
    background-size: 800px 100%;
  }
}
[data-theme="dark"] .skeleton {
  background: linear-gradient(
    90deg,
    #334155 25%,
    #475569 50%,
    #334155 75%
  );
  background-size: 800px 100%;
}


/* ==========================================================================
   3. MICRO-INTERACTIONS GLOBALES & FOCUS-VISIBLE
   Règle de base pour tous les éléments interactifs.
   :focus-visible garantit un ring AA (≥2px) visible seulement au clavier
   (pas au clic souris — UX propre), conformément à WCAG 2.1 SC 2.4.7.
   ========================================================================== */

/* Masque le ring navigateur par défaut sur :focus (garde focus-visible) */
*:focus {
  outline: none;
}

/* Ring focus visible sur TOUS les interactifs (AA : ≥2px, contrasté) */
*:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
  border-radius: var(--radius);
}

/* Sur fond brand (header), le ring doit être blanc pour contraste AA */
header *:focus-visible {
  outline-color: #ffffff;
}

/* Boutons génériques : curseur pointer + transition douce */
button {
  cursor: pointer;
  transition:
    background-color var(--transition),
    color            var(--transition),
    box-shadow       var(--transition),
    opacity          var(--transition);
}

/* État actif (press) : légère dépression visuelle */
button:active {
  transform: scale(0.97);
}


/* ==========================================================================
   4. ANIMATION D'ENTRÉE DES .news-card (STAGGER)
   Chaque carte entre par le bas avec un délai croissant (stagger).
   Les délais sont appliqués via des variables inline (--card-index) posées
   par app.js lors de la génération du HTML, ou via des sélecteurs nth-child.
   ========================================================================== */

@keyframes radar-card-in {
  from {
    opacity: 0;
    transform: translateY(16px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Toutes les cartes entrent avec l'animation */
.news-card {
  animation: radar-card-in 300ms ease both;
  /* Délai stagger via variable CSS --card-index (définie sur l'élément).
     Repli sur 0ms si la variable n'est pas définie. */
  animation-delay: calc(var(--card-index, 0) * 50ms);
}

/* Stagger via nth-child (couverture de secours si --card-index absent) */
.news-card:nth-child(1)  { animation-delay:   0ms; }
.news-card:nth-child(2)  { animation-delay:  50ms; }
.news-card:nth-child(3)  { animation-delay: 100ms; }
.news-card:nth-child(4)  { animation-delay: 150ms; }
.news-card:nth-child(5)  { animation-delay: 200ms; }
.news-card:nth-child(6)  { animation-delay: 250ms; }
.news-card:nth-child(7)  { animation-delay: 300ms; }
.news-card:nth-child(8)  { animation-delay: 350ms; }
.news-card:nth-child(9)  { animation-delay: 400ms; }
.news-card:nth-child(n+10) { animation-delay: 450ms; }


/* ==========================================================================
   5. HEADER & NAVIGATION PAR PÔLE
   ========================================================================== */

/* --- .pole-btn : état inactif ----------------------------------------------- */
.pole-btn {
  color: rgba(255, 255, 255, 0.85);
  font-weight: 600;
  border-radius: 9999px;        /* rounded-full */
  transition:
    background-color var(--transition),
    color            var(--transition),
    box-shadow       var(--transition);
  /* Cible tactile ≥ 44 px de hauteur (WCAG 2.5.5) */
  min-height: 44px;
  min-width: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Survol : voile blanc léger */
.pole-btn:hover {
  background-color: rgba(255, 255, 255, 0.20);
  color: #ffffff;
}

/* --- .active-pole : bouton de pôle actif ------------------------------------ */
/* !important nécessaire pour prendre la priorité sur les classes Tailwind
   et sur le :hover de .pole-btn ci-dessus. */
.active-pole,
.pole-btn.active-pole,
.pole-btn.active-pole:hover {
  background-color: #ffffff !important;
  color: var(--brand) !important;
  font-weight: 700 !important;
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.5);
}


/* ==========================================================================
   6. CARTES D'ARTICLES (#news-grid article / .news-card)
   ========================================================================== */

/* Carte de base : fond, ombre, coins */
#news-grid article,
.news-card {
  background-color: var(--card-bg);
  border-radius: var(--radius);
  box-shadow: var(--shadow-sm);
  overflow: hidden;
  transition:
    transform   var(--transition),
    box-shadow  var(--transition),
    background-color var(--transition);
}

/* Survol : soulèvement + ombre renforcée */
#news-grid article:hover,
.news-card:hover {
  transform: translateY(-3px);
  box-shadow: var(--shadow-lg);
}

/* État actif (clic) : légère compression */
#news-grid article:active,
.news-card:active {
  transform: translateY(-1px);
  box-shadow: var(--shadow-md);
}

/* Titre des cartes : couleur brand */
.news-card h3 {
  color: var(--brand);
}

/* Texte secondaire dans les cartes */
.news-card .text-gray-600,
.news-card p {
  color: var(--muted);
}


/* ==========================================================================
   7. COMPOSANTS CARTE NOUVEAUX
   (.news-card__open, .news-card__actions, .share-btn, .bookmark-btn,
    .card-source-link)
   ========================================================================== */

/* --- .news-card__open -------------------------------------------------------
   Bouton principal (déclencheur de modale) qui couvre le contenu informatif
   de la carte. Doit être visuellement transparent (pas de style bouton),
   mais entièrement accessible au clavier.
   WCAG : aria-haspopup="dialog" + aria-label sur l'élément. */
.news-card__open {
  display: block;
  width: 100%;
  text-align: left;
  background: transparent;
  border: none;
  padding: var(--space-5);
  cursor: pointer;
  border-radius: var(--radius);
  /* Transition douce pour le focus-visible */
  transition: background-color var(--transition);
}

.news-card__open:hover {
  /* Légère teinte au survol pour feedback */
  background-color: rgba(30, 58, 138, 0.03);
}

[data-theme="dark"] .news-card__open:hover {
  background-color: rgba(255, 255, 255, 0.03);
}

/* Focus visible : ring brand interne à la carte */
.news-card__open:focus-visible {
  outline: 3px solid var(--brand);
  outline-offset: 2px;
}

/* --- .news-card__actions ----------------------------------------------------
   Barre d'actions sous le contenu : partage + marque-page + lien source.
   Séparée du contenu principal pour ne pas interférer avec le déclencheur. */
.news-card__actions {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-5) var(--space-4);
  border-top: 1px solid var(--border);
}

/* --- .share-btn & .bookmark-btn --------------------------------------------
   Boutons d'action secondaires. Cibles tactiles ≥ 44×44 px (WCAG 2.5.5). */
.share-btn,
.bookmark-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: var(--space-2);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--radius);
  color: var(--muted);
  font-size: 1.1rem;
  transition:
    background-color var(--transition),
    color            var(--transition),
    border-color     var(--transition),
    transform        var(--transition);
}

/* Survol des boutons d'action */
.share-btn:hover {
  background-color: rgba(30, 58, 138, 0.08);
  color: var(--brand);
  border-color: rgba(30, 58, 138, 0.20);
}

/* Bouton partage : icône de partage (défini par A2 avec du texte ou emoji) */
.share-btn:active {
  transform: scale(0.93);
}

/* Bookmark inactif (défaut) */
.bookmark-btn {
  color: var(--muted);
}

/* Bookmark actif (aria-pressed="true") : couleur brand */
.bookmark-btn[aria-pressed="true"] {
  color: var(--brand);
  background-color: rgba(30, 58, 138, 0.08);
  border-color: rgba(30, 58, 138, 0.20);
}

.bookmark-btn:hover {
  background-color: rgba(30, 58, 138, 0.08);
  color: var(--brand);
  border-color: rgba(30, 58, 138, 0.20);
}

.bookmark-btn:active {
  transform: scale(0.93);
}

/* --- .card-source-link -------------------------------------------------------
   Lien « Source ↗ » vers l'article d'origine. Affiché seulement si url != null.
   Style discret mais accessible ; fond et contour au focus. */
.card-source-link {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-left: auto; /* pousse le lien vers la droite de la barre d'actions */
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--brand);
  text-decoration: none;
  padding: var(--space-1) var(--space-2);
  border-radius: calc(var(--radius) / 2);
  border: 1px solid transparent;
  min-height: 44px;
  min-width: 44px;
  justify-content: center;
  transition:
    background-color var(--transition),
    border-color     var(--transition),
    color            var(--transition);
}

.card-source-link:hover {
  background-color: rgba(30, 58, 138, 0.08);
  border-color: rgba(30, 58, 138, 0.25);
  text-decoration: underline;
}

.card-source-link:visited {
  color: #7c3aed; /* violet-600 — standard lien visité, contraste AA */
}

[data-theme="dark"] .card-source-link:visited {
  color: #a78bfa; /* violet-400 — contraste AA sur fond sombre */
}


/* ==========================================================================
   8. CONTRÔLES DE L'INTERFACE
   (#theme-toggle, #bookmark-filter, #refresh-indicator, #loading-indicator,
    #alert-toast, #data-source-note)
   ========================================================================== */

/* --- #theme-toggle ----------------------------------------------------------
   Bouton de bascule du thème clair/sombre, dans le header.
   Cible tactile ≥ 44×44 px. Rond, translucide sur fond brand. */
#theme-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: var(--space-2);
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.30);
  border-radius: 9999px;
  color: #ffffff;
  font-size: 1.1rem;
  transition:
    background-color var(--transition),
    border-color     var(--transition),
    transform        var(--transition);
}

#theme-toggle:hover {
  background: rgba(255, 255, 255, 0.28);
  border-color: rgba(255, 255, 255, 0.50);
}

#theme-toggle:active {
  transform: scale(0.93);
}

/* aria-pressed="true" : état sombre actif → icône ☀ visible */
#theme-toggle[aria-pressed="true"] {
  background: rgba(255, 255, 255, 0.30);
  border-color: rgba(255, 255, 255, 0.60);
}

/* --- #bookmark-filter --------------------------------------------------------
   Bouton de filtre « À lire plus tard », dans le header ou la barre de filtres.
   Même style compact que #theme-toggle. */
#bookmark-filter {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  min-width: 44px;
  min-height: 44px;
  padding: var(--space-2) var(--space-3);
  background: rgba(255, 255, 255, 0.15);
  border: 1px solid rgba(255, 255, 255, 0.30);
  border-radius: 9999px;
  color: #ffffff;
  font-size: 0.8125rem;
  font-weight: 600;
  transition:
    background-color var(--transition),
    border-color     var(--transition);
}

#bookmark-filter:hover {
  background: rgba(255, 255, 255, 0.28);
}

/* Filtre actif (aria-pressed="true") : fond blanc, texte brand */
#bookmark-filter[aria-pressed="true"] {
  background: #ffffff;
  color: var(--brand);
  border-color: #ffffff;
}

/* --- #refresh-indicator ------------------------------------------------------
   Indicateur discret d'auto-refresh (petit point animé ou texte).
   Rôle status + aria-live="polite" (posés dans index.html par A4). */
#refresh-indicator {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 0.6875rem;
  color: rgba(255, 255, 255, 0.70);
  /* Transition douce lors de l'apparition/disparition */
  opacity: 1;
  transition: opacity var(--transition);
}

/* Quand le contenu est vide, masquer visuellement (mais garder pour AT) */
#refresh-indicator:empty {
  opacity: 0;
}

/* --- #loading-indicator ------------------------------------------------------
   Spinner pendant le premier chargement des flux RSS.
   Centré dans <main>. */
#loading-indicator {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-4);
  padding: var(--space-6);
  color: var(--muted);
  font-size: 0.875rem;
}

/* Cercle tournant */
#loading-indicator::before {
  content: '';
  display: block;
  width: 2.5rem;
  height: 2.5rem;
  border: 3px solid var(--border);
  border-top-color: var(--brand);
  border-radius: 50%;
  animation: radar-spin 0.8s linear infinite;
}

@keyframes radar-spin {
  to { transform: rotate(360deg); }
}

/* --- #alert-toast -----------------------------------------------------------
   Toast flottant « Nouvelles alertes détectées ».
   Positionné en bas à droite, au-dessus du contenu (z-index > cartes).
   role="status" + aria-live="polite" (posés dans index.html par A4). */
#alert-toast {
  position: fixed;
  bottom: var(--space-6);
  right: var(--space-6);
  z-index: 80;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) var(--space-4);
  background-color: var(--card-bg);
  color: var(--text);
  border: 1px solid var(--border);
  border-left: 4px solid var(--alert);
  border-radius: var(--radius);
  box-shadow: var(--shadow-md);
  font-size: 0.875rem;
  font-weight: 600;
  max-width: 320px;
  /* Animation d'entrée par le bas */
  animation: radar-toast-in 300ms ease both;
}

@keyframes radar-toast-in {
  from {
    opacity: 0;
    transform: translateY(12px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

/* Quand .hidden est retiré, le toast apparaît avec animation */
#alert-toast.hidden {
  display: none !important;
}

/* --- #data-source-note -------------------------------------------------------
   Indicateur en pied de page : « Données en direct » vs « Mode démonstration ».
   aria-live="polite" mis à jour par app.js. */
#data-source-note {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  font-size: 0.6875rem;
  font-weight: 500;
  color: var(--muted);
}

/* Point coloré devant la note (vert = live, orange = demo) */
#data-source-note[data-live="true"]::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #16a34a; /* green-600 */
  animation: radar-pulse 2s ease-in-out infinite;
}

#data-source-note[data-live="false"]::before {
  content: '';
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background-color: #d97706; /* amber-600 */
}

@keyframes radar-pulse {
  0%, 100% { opacity: 1; }
  50%       { opacity: 0.4; }
}


/* ==========================================================================
   9. CHAMPS DE FORMULAIRE
   (#search-input, #category-filter, #sort-filter)
   ========================================================================== */

#search-input,
#category-filter,
#sort-filter {
  background-color: #ffffff;
  color: var(--text);
  border: 1px solid rgba(148, 163, 184, 0.50);
  border-radius: var(--radius);
  padding: var(--space-2) var(--space-3);
  font-size: 0.875rem;
  transition:
    border-color var(--transition),
    box-shadow   var(--transition),
    background-color var(--transition);
  /* Cible tactile ≥ 44 px de hauteur */
  min-height: 44px;
}

/* Focus : ring brand + bordure brand (AA : ring ≥ 2px contrasté) */
#search-input:focus,
#search-input:focus-visible,
#category-filter:focus,
#category-filter:focus-visible,
#sort-filter:focus,
#sort-filter:focus-visible {
  outline: none;
  border-color: var(--brand);
  box-shadow: 0 0 0 3px rgba(30, 58, 138, 0.25);
}

#search-input::placeholder {
  color: #94a3b8; /* slate-400 */
}


/* ==========================================================================
   10. MODALE (#modal-overlay — slide-up, body.modal-open)
   ========================================================================== */

/* Overlay : fond semi-opaque, centrage flex, au-dessus de tout */
#modal-overlay {
  position: fixed;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--space-4);
  background-color: rgba(0, 0, 0, 0.65);
  z-index: 100;
}

/* Animation slide-up du contenu de la modale */
#modal-overlay .modal-content,
#modal-overlay > * {
  animation: radar-modal-slide-up 250ms cubic-bezier(0.16, 1, 0.3, 1) both;
  border-radius: var(--radius-lg);
}

@keyframes radar-modal-slide-up {
  from {
    opacity: 0;
    transform: translateY(24px) scale(0.97);
  }
  to {
    opacity: 1;
    transform: translateY(0) scale(1);
  }
}

/* Scroll-lock de l'arrière-plan pendant l'ouverture de la modale */
body.modal-open {
  overflow: hidden !important;
}

/* Bouton de fermeture de la modale */
#modal-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  border-radius: 9999px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  font-size: 1.5rem;
  transition:
    background-color var(--transition),
    color            var(--transition),
    border-color     var(--transition);
}

#modal-close:hover {
  background-color: rgba(0, 0, 0, 0.06);
  color: var(--text);
  border-color: var(--border);
}

[data-theme="dark"] #modal-close:hover {
  background-color: rgba(255, 255, 255, 0.08);
}


/* ==========================================================================
   11. UTILITAIRES
   ========================================================================== */

/* .hidden : masquage universel (compatible avec Tailwind) */
.hidden {
  display: none !important;
}


/* ==========================================================================
   12. RESPONSIVE MOBILE → 4K
   La grille est gérée par Tailwind (grid-cols-1/2/3) ; on ajuste ici le
   conteneur principal et les zones à très haute résolution.
   ========================================================================== */

/* Conteneur de base : max-w-6xl (72rem / 1152px) géré par Tailwind.
   On élargit proprement à partir de 1536 px (2XL) et 1920 px (4K). */

/* 2XL (≥ 1536 px) : légèrement plus large */
@media (min-width: 1536px) {
  .max-w-6xl {
    max-width: 80rem; /* 1280 px */
  }
}

/* Wide / QHD (≥ 1920 px) : 4 colonnes dans la grille pour rentabiliser l'espace */
@media (min-width: 1920px) {
  .max-w-6xl {
    max-width: 96rem; /* 1536 px */
  }

  /* Passe à 4 colonnes sur très grand écran */
  #news-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Mobile : cibles tactiles et espacement confortables */
@media (max-width: 640px) {
  /* Toast : pleine largeur sur mobile */
  #alert-toast {
    left: var(--space-4);
    right: var(--space-4);
    bottom: var(--space-4);
    max-width: none;
  }

  /* Modale : plein bas sur mobile (sheet) */
  #modal-overlay {
    align-items: flex-end;
    padding: 0;
  }

  #modal-overlay .modal-content {
    max-height: 92vh;
    border-bottom-left-radius: 0;
    border-bottom-right-radius: 0;
    border-top-left-radius: var(--radius-lg);
    border-top-right-radius: var(--radius-lg);
  }
}


/* ==========================================================================
   13. IMPRESSION (@media print)
   ========================================================================== */
@media print {
  /* Masquer navigation, filtres, champs de recherche */
  nav,
  .pole-btn,
  #search-input,
  #category-filter,
  #sort-filter,
  #theme-toggle,
  #bookmark-filter,
  #refresh-indicator,
  #loading-indicator,
  #alert-toast,
  #data-source-note,
  .news-card__actions {
    display: none !important;
  }

  /* Header simplifié sans fond coloré */
  header {
    background-color: transparent !important;
    color: #000000 !important;
    box-shadow: none !important;
    padding: 0.5rem 0 !important;
  }

  /* Bandeau alerte et modale non imprimés */
  #alert-banner,
  #modal-overlay {
    display: none !important;
  }

  /* Cartes à plat : aucune ombre ni transform */
  #news-grid article,
  .news-card {
    box-shadow: none !important;
    transform: none !important;
    cursor: auto;
    break-inside: avoid;
    border: 1px solid #cccccc !important;
    animation: none !important;
  }

  /* Liens source imprimés en noir lisible */
  .card-source-link {
    color: #000000 !important;
  }
}


/* ==========================================================================
   14. MOUVEMENT RÉDUIT (@media prefers-reduced-motion)
   Désactive TOUTES les animations et transitions pour les utilisateurs
   qui ont activé cette préférence. WCAG 2.1 SC 2.3.3.
   ========================================================================== */
@media (prefers-reduced-motion: reduce) {
  /* Suppression de toutes les animations */
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }

  /* Shimmer statique (dégradé figé sans mouvement) */
  .skeleton {
    animation: none !important;
    background: #e2e8f0;
  }

  /* Thème sombre : shimmer figé plus sombre */
  [data-theme="dark"] .skeleton {
    animation: none !important;
    background: #334155;
  }

  /* Spinner sans rotation */
  #loading-indicator::before {
    animation: none !important;
    border-top-color: var(--brand);
    opacity: 0.6;
  }

  /* Toast sans animation d'entrée */
  #alert-toast {
    animation: none !important;
  }

  /* Cartes sans animation d'entrée */
  .news-card {
    animation: none !important;
  }

  /* Indicateur de rafraîchissement sans pulse */
  #data-source-note[data-live="true"]::before {
    animation: none !important;
  }
}
