/* ============================================================================
   ASTROPOST — Disposition
   ----------------------------------------------------------------------------
   Les trois dispositions du jeu, et les grilles.

   LA RÈGLE QUI COMPTE : le seuil est une LARGEUR DISPONIBLE, jamais un modèle
   d'appareil. Un iPad en écran partagé doit se comporter comme un téléphone.

   Sur le web, cela veut dire mesurer le CONTENEUR et non la fenêtre. Deux
   moyens, dans cet ordre de préférence :

   1. `@container` (requêtes de conteneur) — la bonne réponse, et elle est
      disponible dans tous les navigateurs courants depuis 2023.
   2. Un `ResizeObserver` sur la zone défilante, qui pose un attribut.

   Ce fichier utilise les deux : les requêtes de conteneur pour ce qui est
   purement visuel, et l'attribut `data-layout` pour ce que le code doit
   savoir (afficher une barre latérale ou une barre d'onglets, par exemple —
   ce n'est pas un choix de CSS, c'est un choix de structure).

   PIÈGE VÉRIFIÉ DANS L'APPLICATION : la largeur doit être mesurée sur la zone
   défilante ELLE-MÊME, jamais sur du contenu déjà borné — sinon la mesure
   boucle sur elle-même et l'écran oscille.
   ========================================================================= */

/* ┌───────────────────────────────────────────────────────────────────────────
   │ COUCHE DE CASCADE — à lire avant de s'étonner d'une priorité
   │
   │ Ce fichier est enveloppé dans `@layer astropost`. Conséquence : toute
   │ règle NON couchée l'emporte sur celles d'ici, quelle que soit sa
   │ spécificité et quel que soit l'ordre de chargement.
   │
   │ C'est voulu. Une application qui définit déjà `.ap-button` dans sa propre
   │ feuille garde SA version, sans avoir à surenchérir en spécificité ni à
   │ surveiller l'ordre des <link>. Le système de design fournit le socle ;
   │ l'application tranche.
   │
   │ Sans cette couche, ce fichier écrasait silencieusement 32 classes de
   │ l'application web — dont son bouton principal, qui perdait son fond.
   │ Le défaut a été vu à l'écran, pas deviné.
   └────────────────────────────────────────────────────────────────────────── */

@layer astropost {

  /* ── Les deux bornes de largeur ─────────────────────────────────────────── */

  /* Ce qui se lit d'une traite : une fiche, un panneau, un rapport. */
  .ap-reading-column {
    width: 100%;
    max-width: var(--reading-width);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  /* Un écran principal, qui peut porter plusieurs colonnes. */
  .ap-page {
    width: 100%;
    max-width: var(--page-width);
    margin-inline: auto;
    padding-inline: var(--gutter);
  }

  /* ── La zone défilante, qui porte la mesure ─────────────────────────────── */

  .ap-scroll {
    container-type: inline-size;
    container-name: screen;
    overflow-y: auto;
    overscroll-behavior-y: contain;
    /* Le ciel ne défile pas : il est en `fixed` sur le corps. */
  }

  /* ── Grilles de cartes ──────────────────────────────────────────────────── */

  /* Une suite de cartes : empilée à l'étroit, en colonnes quand il y a la
     place. Une liste bornée à 660 px au milieu d'une fenêtre de Mac laissait
     les deux tiers de l'écran vides. */
  .ap-card-flow {
    display: grid;
    gap: var(--space-md);
    grid-template-columns: 1fr;
    max-width: var(--reading-width);
    margin-inline: auto;
  }

  @container screen (min-width: 1000px) {
    .ap-card-flow {
      max-width: none;
      grid-template-columns: repeat(auto-fit, minmax(var(--card-min-width), 1fr));
      align-items: start;
    }
  }

  /* Grille de chiffres — ressources, statistiques. Plus serrée : ces cartes
     portent des nombres, pas des phrases. */
  .ap-tile-grid {
    display: grid;
    gap: var(--space-sm);
    grid-template-columns: repeat(auto-fit, minmax(var(--tile-min-width), 1fr));
  }

  /* ── Le tableau de bord, à deux zones ───────────────────────────────────── */

  /* Étroit : tout s'empile, dans l'ordre où on lit sur un téléphone.
     Large : une colonne de lecture (le guide, l'observation en cours) et, à
     côté, une grille de cartes qui remplit ce qui reste. */
  .ap-dashboard {
    display: grid;
    gap: var(--space-md);
    grid-template-columns: 1fr;
  }

  @container screen (min-width: 1000px) {
    .ap-dashboard {
      grid-template-columns: var(--reading-width) minmax(0, 1fr);
      align-items: start;
    }
  }

  /* ── Un écran principal et sa colonne d'appoint ─────────────────────────── */

  /* Le sujet de l'écran à gauche, ce qui l'accompagne à droite. L'annuaire
     de la communauté est le sujet ; les cartes disent qui l'on est et
     comment on cherche. Posées AU-DESSUS, elles repoussaient la liste sous
     la ligne de flottaison — on ouvrait « Communauté » sans voir un seul
     observatoire.

     L'ORDRE DU BALISAGE met l'appoint en premier, et c'est voulu : sur un
     téléphone il n'y a ni gauche ni droite, et la carte qui porte le code et
     la bascule de visibilité doit se lire avant une liste qui peut compter
     cinquante lignes. La grille la replace à droite dès qu'il y a la place.

     `align-items: start` empêche la colonne courte de s'étirer à la hauteur
     de la longue — une carte de 200 px tirée sur 900 px est un cadre vide. */

  .ap-with-aside {
    display: grid;
    gap: var(--space-md);
    grid-template-columns: 1fr;
  }

  @container screen (min-width: 1000px) {
    .ap-with-aside {
      /* Étroite : c'est une colonne d'APPOINT, pas une seconde moitié
         d'écran. 340 px suffisent à une carte lisible, et tout ce qu'on
         lui prend revient au sujet. */
      grid-template-columns: minmax(0, 1fr) clamp(280px, 21%, 340px);
      grid-template-areas: "main aside";
      align-items: start;
    }
    .ap-with-aside > .ap-with-aside__main  { grid-area: main; }
    .ap-with-aside > .ap-with-aside__aside { grid-area: aside; }
  }

  /* ── Les trois dispositions de navigation ───────────────────────────────── */

  /* La coquille de l'application. `data-layout` est posé par le code :
     "compact" (barre d'onglets) ou "regular" (barre latérale). */
  .ap-shell {
    display: grid;
    min-height: 100vh;
    min-height: 100dvh;
  }

  /* MOBILE — moins de 1 000 px : barre d'onglets en bas. */
  .ap-shell[data-layout="compact"] {
    grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas:
      "topbar"
      "content"
      "tabbar";
  }
  .ap-shell[data-layout="compact"] > .ap-sidebar { display: none; }

  /* TABLETTE ET DESKTOP — 1 000 px et plus : barre latérale fixe.

     La barre du haut TRAVERSE, au-dessus de la latérale : elle porte
     l'identité de la partie, pas l'en-tête d'un écran. La latérale ne la
     redit donc plus. */
  .ap-shell[data-layout="regular"] {
    grid-template-columns:
      clamp(var(--sidebar-min), var(--sidebar-width), var(--sidebar-max))
      minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-areas:
      "topbar  topbar"
      "sidebar content";
  }
  .ap-shell[data-layout="regular"] > .ap-tabbar { display: none; }

  .ap-shell > .ap-topbar  { grid-area: topbar; }
  .ap-shell > .ap-content { grid-area: content; min-width: 0; }
  .ap-shell > .ap-sidebar { grid-area: sidebar; }
  .ap-shell > .ap-tabbar  { grid-area: tabbar; }

  /* Repli si le code n'a pas encore posé l'attribut : on suppose le téléphone.
     Une interface qui démarre en mode large puis se replie fait un saut visible
     au chargement ; l'inverse est plus discret. */
  .ap-shell:not([data-layout]) {
    grid-template-rows: auto minmax(0, 1fr) auto;
    grid-template-areas: "topbar" "content" "tabbar";
  }
  .ap-shell:not([data-layout]) > .ap-sidebar { display: none; }

  /* ── La carte du ciel : la seule exception ──────────────────────────────── */

  /* UI_UX.md : le contenu défilant est borné en largeur et centré. LA CARTE DU
     CIEL FAIT EXCEPTION — elle gagne à occuper l'écran. */
  .ap-sky-screen {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
    touch-action: none;   /* le déplacement est géré par le code */
    cursor: grab;
  }
  .ap-sky-screen:active { cursor: grabbing; }

  /* ── Pile de navigation ─────────────────────────────────────────────────── */

  /* Profil et réglages sont des PAGES POUSSÉES, jamais des panneaux : ce sont
     des écrans entiers, avec le retour habituel, et rien de l'écran précédent
     derrière eux. */
  .ap-pushed-page {
    display: flex;
    flex-direction: column;
    min-height: 100%;
  }

  /* La barre de titre d'une page poussée. */
  .ap-nav-bar {
    position: sticky;
    top: 0;
    z-index: var(--z-sidebar);
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--gutter);
    /* Un fond translucide qui laisse voir le ciel défiler derrière. */
    background: color-mix(in srgb, var(--app-background) 82%, transparent);
    backdrop-filter: blur(16px);
    border-bottom: 1px solid var(--hairline);
  }

  .ap-nav-bar__title {
    flex: 1;
    text-align: center;
    font-size: var(--text-headline);
    font-weight: var(--weight-semibold);
  }

  /* ── Utilitaires d'empilement ───────────────────────────────────────────── */

  .ap-stack        { display: flex; flex-direction: column; gap: var(--space-md); }
  .ap-stack--sm    { gap: var(--space-sm); }
  .ap-stack--xs    { gap: var(--space-xs); }
  .ap-stack--lg    { gap: var(--space-lg); }

  .ap-row          { display: flex; align-items: center; gap: var(--space-sm); }
  .ap-row--between { justify-content: space-between; }
  .ap-row--wrap    { flex-wrap: wrap; }
  .ap-row--baseline{ align-items: first baseline; }

  .ap-spacer       { flex: 1 1 auto; }

}
