/* hall.css : le hall des apps (`/apps`), dans la veine de la landing claire.

   UN SÉLECTEUR : LA LISTE À GAUCHE, L'APP CHOISIE À DROITE.
   Deux dessins ont été essayés avant celui-ci. De grandes cartes avec leur
   texte et leur bouton : c'était la landing posée une seconde fois, alors que
   la personne a déjà cliqué « Commencer ». Puis quatre icônes seules, comme un
   écran de téléphone : on ne lisait plus ce que fait chaque app.

   Ici la liste se parcourt d'un coup d'œil (un nom, une ligne de fonction), et
   le panneau de droite ne détaille qu'UNE app à la fois, celle qu'on survole.
   Le texte n'est plus étalé sur la page : il répond à un geste.

   CE QUI CHANGE PAR RAPPORT À LA LANDING. Le hall est DANS le produit : il
   étend base.html, garde la barre du haut et suit le thème clair ou sombre.
   Tout passe par les jetons de theme.css (`--mr-*`), et chaque teinte est un
   MÉLANGE de la couleur d'état de l'app avec le fond de carte du thème : la
   même règle donne un vert pâle sur crème et un vert sourd sur encre.

   Cette page ne charge plus apps.css. Les pages qui s'en servent encore
   (projets, recherche, Sonar) ne sont pas touchées. */

.hall {
    /* L'UNITÉ DE LA PAGE. Le produit fixe le rem à 16 px et la barre du haut
       en dépend : on ne peut pas faire grandir le rem comme sur la landing.
       `--u` joue ce rôle pour le hall seul.

       ELLE SUIT LA LARGEUR ET LA HAUTEUR, ET PREND LA PLUS PETITE DES DEUX.
       Le sélecteur doit tenir dans un écran sans défiler : calée sur la
       largeur seule, l'unité le faisait déborder d'un portable large et
       bas. Mesures : 18,9 px à 1920 par 1080, 15,1 à 1440 par 900, 13,4 à
       1366 par 768, 36 en 4K. */
    --u: clamp(12px, min(1.05vw, 1.75vh), 36px);
    --titre: 'Bricolage Grotesque', 'Inter', -apple-system, sans-serif;
    --detente: cubic-bezier(0.16, 1, 0.3, 1);
    /* La couleur d'une app sans teinte déclarée. Posée ici et pas sur la
       ligne ni sur le volet : déclarée sur eux, elle arrivait après
       `.hall--flair` dans la feuille et l'écrasait, et le panneau sortait gris. */
    --accent: var(--mr-gris);

    /* Le sélecteur tient dans l'écran et s'y centre : 64 px, c'est la barre
       du haut. */
    /* `border-box` : sans lui la hauteur minimale ne compte que le contenu,
       le remplissage s'y ajoute, et la page dépassait l'écran de 104 px. On
       pouvait la faire défiler alors qu'il n'y avait rien dessous. */
    box-sizing: border-box;
    display: flex;
    align-items: center;
    min-height: calc(100vh - 64px);
    min-height: calc(100dvh - 64px);
    padding: calc(var(--u) * 2.5) clamp(20px, 4vw, 48px) calc(var(--u) * 4);
    color: var(--mr-text);
    font-family: var(--mr-sans);
}

.hall-cadre {
    display: grid;
    grid-template-columns: minmax(0, 0.82fr) minmax(0, 1fr);
    gap: calc(var(--u) * 2.5);
    align-items: stretch;
    width: 100%;
    max-width: calc(var(--u) * 70);
    margin: 0 auto;
}

/* ===== La colonne de gauche ===== */
.hall-liste { display: flex; flex-direction: column; justify-content: center; gap: calc(var(--u) * 0.2); }

/* `!important` sur les tailles : mobile.css impose les siennes à tous les
   h1, h2 et h3 sous 768 px, avec `!important`. */
.hall-titre {
    margin: 0 0 calc(var(--u) * 1.5) calc(var(--u) * 1);
    color: var(--mr-text-strong);
    font-family: var(--titre);
    font-weight: 600;
    font-size: calc(var(--u) * 2.1) !important;
    line-height: 1.05;
    letter-spacing: -0.035em;
}

.hall-ligne {
    position: relative;
    display: flex;
    align-items: center;
    gap: calc(var(--u) * 1);
    padding: calc(var(--u) * 0.85) calc(var(--u) * 1);
    border-radius: calc(var(--u) * 1.25);
    color: var(--mr-text);
    text-decoration: none;
    transition: background 0.3s ease;
}

.hall--flair { --accent: var(--mr-vert); }
.hall--trace { --accent: var(--mr-orange); }
.hall--badge { --accent: var(--mr-violet); }
.hall--sonar { --accent: var(--mr-bleu); }

/* La ligne choisie prend la teinte de son app : c'est elle qui relie la
   liste au panneau d'en face, qui est de la même couleur. */
.hall-ligne.est-choisie { background: color-mix(in srgb, var(--accent) 13%, var(--mr-surface-card)); }

.hall-ligne:focus-visible {
    outline: 2px solid var(--mr-text-strong);
    outline-offset: 2px;
}

.hall-icone {
    flex: none;
    display: grid;
    place-items: center;
    width: calc(var(--u) * 3.25);
    height: calc(var(--u) * 3.25);
    border-radius: 24%;
    overflow: hidden;
    font: 600 calc(var(--u) * 1.5) var(--titre);
}

.hall-icone img { width: 100%; height: 100%; display: block; object-fit: cover; }

/* Le fond ne vaut que pour la lettre de repli : sous une image, il déborde
   dans ses coins transparents et lui dessine un liseré. */
.hall-icone--lettre { background: var(--mr-btn-bg); color: var(--mr-btn-text); }

.hall-mots { min-width: 0; }

/* Le nom ET la fonction, jamais l'un sans l'autre : le nom porte la marque,
   la fonction dit à un débutant ce que l'app fait. */
.hall-nom {
    display: block;
    color: var(--mr-text-strong);
    font-family: var(--titre);
    font-weight: 600;
    font-size: calc(var(--u) * 1.3);
    line-height: 1.15;
    letter-spacing: -0.025em;
}

.hall-fonction {
    display: block;
    margin-top: calc(var(--u) * 0.1);
    color: var(--mr-text-muted);
    font-size: calc(var(--u) * 0.95);
    line-height: 1.3;
}

/* Le chevron n'apparaît que sur la ligne choisie : il dit « c'est celle-ci
   qui s'ouvre », et glisse vers l'app. */
.hall-fleche {
    flex: none;
    width: calc(var(--u) * 1.25);
    height: calc(var(--u) * 1.25);
    margin-left: auto;
    fill: none;
    stroke: var(--accent);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
    opacity: 0;
    transform: translateX(calc(var(--u) * -0.5));
    transition: opacity 0.3s ease, transform 0.4s var(--detente);
}

.hall-ligne.est-choisie .hall-fleche { opacity: 1; transform: none; }

.hall-ligne--bientot { opacity: 0.5; }

/* ===== Les outils internes =====
   Sous la liste et d'un autre dessin, parce que ce ne sont pas des apps du
   produit : mêlées aux autres, rien ne dirait qu'elles sont d'une autre
   nature. */
.hall-interne {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: calc(var(--u) * 0.5);
    /* Le même retrait des deux côtés, celui du contenu des lignes au-dessus.
       Il n'était posé qu'à gauche : le trait partait de l'aplomb des icônes
       et filait jusqu'au bord droit de la liste, 15 px plus loin que le
       texte qu'il souligne. */
    margin: calc(var(--u) * 1.5) calc(var(--u) * 1) 0;
    padding-top: calc(var(--u) * 1.25);
    border-top: 1px solid var(--mr-border);
}

.hall-interne-titre {
    margin: 0 calc(var(--u) * 0.35) 0 0;
    color: var(--mr-text-muted);
    font: 400 calc(var(--u) * 0.85) var(--mr-sans) !important;
}

.hall-outil {
    display: inline-flex;
    align-items: center;
    gap: calc(var(--u) * 0.5);
    padding: calc(var(--u) * 0.35) calc(var(--u) * 0.85) calc(var(--u) * 0.35) calc(var(--u) * 0.35);
    border: 1px solid var(--mr-border);
    border-radius: 999px;
    background: var(--mr-surface-card);
    color: var(--mr-text-strong);
    font-size: calc(var(--u) * 0.875);
    font-weight: 500;
    text-decoration: none;
    transition: border-color 0.2s ease;
}

.hall-outil img { width: calc(var(--u) * 1.6); height: calc(var(--u) * 1.6); border-radius: 24%; display: block; }
.hall-outil:hover { border-color: var(--mr-border-strong); }

/* ===== Le panneau de droite =====
   Tous les volets sont empilés au même endroit et un seul est visible. Les
   empiler plutôt que réécrire un seul volet permet un fondu de l'un à
   l'autre, teinte comprise. */
.hall-scene {
    position: relative;
    min-height: calc(var(--u) * 33);
    border-radius: calc(var(--u) * 2.5);
    overflow: hidden;
    background: var(--mr-surface-card);
}

/* Un liseré par-dessus les volets : sans lui, un panneau peu teinté se fond
   dans la page en thème clair et on ne lit plus sa forme. */
.hall-scene::after {
    content: '';
    position: absolute;
    inset: 0;
    z-index: 2;
    border: 1px solid var(--mr-border);
    border-radius: inherit;
    pointer-events: none;
}

.hall-volet {
    position: absolute;
    inset: 0;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-end;
    padding: calc(var(--u) * 3);
    background: color-mix(in srgb, var(--accent) 15%, var(--mr-surface-card));
    opacity: 0;
    visibility: hidden;
    transition: opacity 0.45s ease, visibility 0s linear 0.45s;
}

.hall-volet.est-choisie {
    opacity: 1;
    visibility: visible;
    transition: opacity 0.45s ease, visibility 0s;
}

/* Une lueur de la couleur de l'app, en haut à droite, là où flotte l'icône. */
.hall-volet::before {
    content: '';
    position: absolute;
    right: -10%;
    top: -20%;
    width: 80%;
    aspect-ratio: 1;
    border-radius: 50%;
    background: radial-gradient(closest-side, color-mix(in srgb, var(--accent) 34%, transparent), transparent);
    pointer-events: none;
}

.hall-volet > * { position: relative; }

.hall-volet-icone {
    position: absolute;
    right: calc(var(--u) * 3);
    top: calc(var(--u) * 3);
    width: calc(var(--u) * 9);
    height: calc(var(--u) * 9);
    border-radius: 24%;
    box-shadow: 0 calc(var(--u) * 1.5) calc(var(--u) * 2.5) calc(var(--u) * -1) rgba(0, 0, 0, 0.4);
}

.hall-volet-nom {
    margin: 0;
    color: var(--mr-text-strong);
    font-family: var(--titre);
    font-weight: 600;
    font-size: calc(var(--u) * 4.25) !important;
    line-height: 0.95;
    letter-spacing: -0.045em;
}

.hall-volet-fonction {
    margin: calc(var(--u) * 0.6) 0 0;
    color: var(--accent);
    font-size: calc(var(--u) * 1.15);
    font-weight: 600;
}

.hall-volet-accroche {
    max-width: 24em;
    margin: calc(var(--u) * 0.75) 0 calc(var(--u) * 1.75);
    color: var(--mr-text);
    font-size: calc(var(--u) * 1.1);
    line-height: 1.45;
}

.hall-ouvrir {
    display: inline-flex;
    align-items: center;
    padding: calc(var(--u) * 0.9) calc(var(--u) * 1.6);
    border-radius: 999px;
    background: var(--accent);
    color: var(--mr-surface-card);
    font-size: calc(var(--u) * 1);
    font-weight: 600;
    line-height: 1;
    text-decoration: none;
    transition: transform 0.3s var(--detente), filter 0.2s ease;
}

.hall-ouvrir:hover { transform: translateY(-2px); filter: brightness(1.08); }
.hall-ouvrir:active { transform: scale(0.97); }

/* ===== Le mouvement =====
   Les entrées sont en animation CSS à remplissage « backwards » : l'état de
   départ n'existe que pendant l'animation, donc rien ne peut rester caché. */
@media (prefers-reduced-motion: no-preference) {
    .hall-titre { animation: hall-monter 0.8s var(--detente) backwards; }

    .hall-ligne {
        animation: hall-monter 0.7s var(--detente) backwards;
        animation-delay: calc(0.1s + var(--i, 0) * 70ms);
    }

    .hall-interne { animation: hall-monter 0.7s var(--detente) 0.5s backwards; }
    .hall-scene { animation: hall-surgir 1s var(--detente) 0.15s backwards; }

    /* Le contenu du volet choisi se repose à chaque changement : l'icône
       tombe en place, le texte monte. C'est ce qui fait sentir que le panneau
       répond à la ligne qu'on vient de survoler. */
    .hall-volet.est-choisie .hall-volet-icone {
        animation:
            hall-icone 0.7s cubic-bezier(0.34, 1.56, 0.64, 1) backwards,
            hall-flotter 5s ease-in-out 0.7s infinite alternate;
    }
    .hall-volet.est-choisie :is(.hall-volet-nom, .hall-volet-fonction, .hall-volet-accroche, .hall-ouvrir) {
        animation: hall-monter 0.6s var(--detente) backwards;
    }
    .hall-volet.est-choisie .hall-volet-fonction { animation-delay: 50ms; }
    .hall-volet.est-choisie .hall-volet-accroche { animation-delay: 100ms; }
    .hall-volet.est-choisie .hall-ouvrir { animation-delay: 150ms; }

    .hall-volet::before { animation: hall-deriver 14s ease-in-out infinite alternate; }

    @keyframes hall-monter { from { opacity: 0; transform: translateY(18px); } }
    @keyframes hall-surgir { from { opacity: 0; transform: scale(0.95); } }
    @keyframes hall-icone { from { opacity: 0; transform: scale(0.7) rotate(-10deg); } }
    /* Par `translate`, la propriété séparée : sur `transform`, cette boucle
       écraserait l'entrée de l'icône. */
    @keyframes hall-flotter { to { translate: 0 calc(var(--u) * -0.6); } }
    @keyframes hall-deriver { to { transform: translate(-12%, 14%) scale(1.15); } }
}

/* Sous 900 px il n'y a plus de place pour deux colonnes, et pas de survol :
   le panneau part, et chaque ligne devient une carte teintée à toucher. */
@media (max-width: 900px) {
    /* Sur un téléphone la hauteur ne dit rien de la place disponible : la
       page défile. L'unité revient à une taille fixe, lisible au pouce. */
    .hall { --u: 16px; align-items: flex-start; min-height: 0; }
    .hall-cadre { grid-template-columns: 1fr; }
    .hall-scene { display: none; }
    .hall-titre { margin-left: 0; font-size: calc(var(--u) * 1.75) !important; }
    .hall-liste { gap: calc(var(--u) * 0.6); }
    .hall-ligne, .hall-ligne.est-choisie { background: color-mix(in srgb, var(--accent) 13%, var(--mr-surface-card)); }
    .hall-ligne .hall-fleche { opacity: 1; transform: none; }
    .hall-interne { margin-left: 0; }
}
