/*
 * Les réglages : un second menu à gauche, la page à droite.
 *
 * Deux colonnes dans le contenu, et non une troisième dans la charpente : ce menu-ci n'existe
 * que sur ces pages. La charpente, elle, porte le menu de l'application, qui ne bouge pas
 * quand on entre dans les réglages.
 */

/* La page des réglages n'est pas un texte : elle n'a pas à se plafonner à une largeur de
   lecture, sans quoi les deux colonnes se disputeraient une seule. Le gabarit du paquet
   n'offre pas de prise sur la balise `main`, on la reconnaît donc à ce qu'elle porte. */
.app-main:has(.settings-layout) {
    max-width: none;
}

.settings-layout {
    display: grid;
    gap: var(--app-space-lg);
    grid-template-columns: minmax(0, 1fr);
}

/*
 * À partir de deux colonnes possibles, le menu prend une largeur fixe et la page le reste. Le
 * seuil est celui du reste de l'application.
 *
 * Le menu suit le défilement : la page peut être longue, et remonter chercher une rubrique
 * n'est pas une façon de naviguer.
 */
@media (min-width: 64rem) {
    .settings-layout {
        grid-template-columns: var(--settings-nav-width, 15rem) minmax(0, 1fr);
    }

    /* Le décalage est nul, et c'est ce qui garde l'intitulé du menu à la hauteur de celui du
       cadre : la marge intérieure de la zone de contenu fait déjà l'écart avec la barre du
       haut, et un décalage de plus ferait descendre le menu de cette même mesure — sur les
       pages assez longues pour qu'il ait où descendre, et sur elles seules. */
    .settings-nav {
        position: sticky;
        top: 0;
        align-self: start;
        padding-right: var(--app-space-lg);
        border-right: 1px solid var(--app-line);
    }
}

.settings-nav {
    display: flex;
    flex-direction: column;
    gap: var(--app-space-lg);
}

/* Un groupe : son intitulé, puis ses entrées. L'intitulé est celui des cadres — les mêmes
   petites capitales sur filet, pour que les deux menus se lisent comme une même page. */
.settings-nav-group {
    display: flex;
    flex-direction: column;
    gap: var(--app-space-xs);
}

/*
 * Une entrée porte son dessin devant son nom. Les couleurs, le retrait et l'état de la page en
 * cours restent ceux du paquet : ce menu est sur fond clair, celui pour lequel le composant a
 * été dessiné.
 */
.settings-nav .app-nav-item {
    display: flex;
    align-items: center;
    gap: var(--app-space-sm);
    min-height: 2.5rem;
}

/*
 * La mesure posée ci-dessus est plus généreuse que celle du composant, et c'est ce qui la rendait
 * dangereuse : elle l'emportait aussi là où le doigt vise, et y ramenait l'entrée quatre pixels
 * sous la mesure tactile.
 */
@media (max-width: 37.5rem) {
    .settings-nav .app-nav-item {
        min-height: var(--app-touch);
    }
}

/* Le dessin suit la teinte de son entrée, sans la devancer. Un cran au-dessus du texte : à sa
   mesure exacte, il disparaîtrait. */
.settings-nav-icon {
    display: inline-flex;
    flex: 0 0 auto;
    font-size: var(--app-text-lg);
    color: inherit;
}

/* La colonne de droite garde une largeur de lecture : un formulaire étalé sur mille pixels se
   parcourt des yeux au lieu de se remplir. */
.settings-page {
    max-width: var(--app-content-width);
}

/*
 * Un groupe replié. `<details>` plutôt qu'un contrôleur : le pli est un comportement du
 * navigateur, il tient sans JavaScript, et la recherche de la page l'ouvre toute seule sur ce
 * qu'elle trouve — le même choix que les familles des écrans de mise au point.
 *
 * L'intitulé garde ses petites capitales sur filet : c'est le même repère que dans un menu
 * déplié, et le triangle suffit à dire qu'il s'ouvre.
 */
.settings-nav[data-folded] .settings-nav-group > summary {
    cursor: pointer;
}

.settings-nav[data-folded] .settings-nav-group > summary:hover {
    color: var(--app-ink);
}

/* Le chevron tient le bord droit, et bascule quand le groupe s'ouvre : c'est lui qui dit que la
   ligne s'ouvre, et dans quel sens elle va. */
.settings-nav-fold {
    display: inline-flex;
    flex: 0 0 auto;
    margin-left: auto;
    transition: transform var(--app-motion, .15s) ease;
}

.settings-nav-group[open] > summary .settings-nav-fold {
    transform: rotate(180deg);
}

/* L'écart entre l'intitulé et ses entrées ne vient plus de la grille du groupe, que `<details>`
   ne porte pas : il se pose sous l'intitulé. */
.settings-nav[data-folded] .settings-nav-group[open] > summary {
    margin-bottom: var(--app-space-xs);
}

/* Une rubrique qui en complète une autre se rattache à elle par un trait, et se décale sous elle.
   Le retrait seul ne suffisait pas : deux cases un peu décalées se lisent comme deux cases. Le
   trait, lui, dit la dépendance avant qu'on ait lu la phrase — et rend prévisible le décochage en
   chaîne, puisque ce qui pend d'une rubrique part avec elle. */
.module-needs {
    margin-left: var(--app-space-md);
    padding-left: var(--app-space-md);
    border-left: 2px solid var(--app-line);
}

/* Le nom d'un module, précédé du même dessin que son entrée de menu. Le dessin est ce qui relie
   la case à la rubrique qu'elle commande : les deux se reconnaissent d'un coup d'œil, sans avoir
   à relire le nom. */
.module-name {
    display: inline-flex;
    align-items: center;
    gap: var(--app-space-sm);
}

/* Une ligne de liste qui porte un nom à gauche et une commande à droite — un espace et sa
   bascule, un membre et sa pastille. */
.workspace-row,
.member-row {
    display: flex;
    align-items: center;
    gap: var(--app-space-sm);
}

.workspace-row .app-list-title,
.member-row .app-list-title {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Les deux dessins du transfert : celui qui l'ouvre au bout d'une ligne de membre, et ceux qui
   annoncent les sortes sur sa page. Même taille que le texte qu'ils accompagnent, un cran
   au-dessus : à leur mesure exacte, ils disparaissent. */
.member-handover-icon,
.handover-icon {
    display: inline-flex;
    flex: 0 0 auto;
    font-size: var(--app-text-lg);
    color: inherit;
}

/* Le dessin d'une sorte se lit moins fort que son compte : c'est le chiffre qu'on vient
   chercher, le dessin ne fait que dire de quoi il parle. */
.handover-icon {
    color: var(--app-ink-soft);
}

/*
 * Un champ dont l'intitulé tient à gauche de sa commande.
 *
 * Trois champs courts empilés avec leur étiquette font six lignes pour trois renseignements,
 * et l'œil ne retombe plus sur une colonne commune. Les intitulés partagent donc une largeur,
 * et les commandes s'alignent.
 *
 * Sous la largeur où les deux tiennent côte à côte, la disposition du paquet reprend : une
 * étiquette écrasée contre son champ se lit moins bien qu'une étiquette au-dessus.
 */
@media (min-width: 40rem) {
    .app-field[data-inline] {
        flex-direction: row;
        align-items: center;
        gap: var(--app-space-md);
    }

    .app-field[data-inline] > :is(label, .app-field-label) {
        flex: 0 0 var(--settings-label-width, 11rem);
    }

    .app-field[data-inline] > :is(input, select, .app-theme-picker) {
        flex: 1 1 auto;
        min-width: 0;
    }
}

/*
 * La liste des souvenirs défile dans son cadre.
 *
 * Deux cents lignes repousseraient le champ qui en ajoute et le reste de la page hors de
 * l'écran, et la page se lirait à la molette avant de se lire tout court. La hauteur est celle
 * d'une dizaine de lignes : de quoi voir qu'il y en a d'autres sans que le cadre domine.
 */
.memory-list {
    max-height: 22rem;
    overflow-y: auto;
}

/*
 * Un parcours et ses étapes.
 *
 * Un filet sépare un parcours du suivant, et rien de plus : une carte par parcours redonnerait
 * l'empilement de bordures que le reste des réglages a retiré. Ce qui distingue un parcours
 * d'un autre est son nom, pas sa boîte.
 */
.journey-block + .journey-block {
    padding-top: var(--app-space-md);
    border-top: 1px solid var(--app-border);
}

/*
 * Le nom du parcours et son retrait sur la même ligne, le champ prenant la place qui reste.
 *
 * Ils repassent l'un sous l'autre quand la largeur ne suffit plus : un champ de texte écrasé
 * à trois caractères ne se corrige pas.
 */
.journey-head {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--app-space-sm);
}

.journey-head > form:first-child {
    flex: 1 1 18rem;
}

.journey-head > form:first-child .app-field {
    flex: 1 1 auto;
    min-width: 0;
}

/*
 * Une étape : son rang, son nom, et les gestes qui la déplacent ou la retirent.
 *
 * Le rang est un repère et non une donnée — c'est la place qu'on lit, celle que le tableau des
 * projets suivra. Il est donc dessiné, et sorti du champ des technologies d'assistance : la
 * liste ordonnée le dit déjà.
 */
.journey-step {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--app-space-xs);
}

.journey-step > form:nth-child(2) {
    flex: 1 1 14rem;
}

.journey-step > form:nth-child(2) .app-field {
    flex: 1 1 auto;
    min-width: 0;
}

/*
 * Le numéro EST la poignée du glissement : le reste de la ligne se saisit mal — un champ de texte
 * et quatre boutons y ont déjà leur geste. Il ne prend le curseur de saisie que là où le
 * glissement existe, c'est-à-dire quand le contrôleur est en place.
 */
.journey-step-rank {
    flex: 0 0 auto;
    min-width: 1.75rem;
    color: var(--app-ink-muted);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.journey-js .journey-step-rank {
    cursor: grab;
}

.journey-js .journey-step-rank:active {
    cursor: grabbing;
}

/*
 * Les deux flèches disparaissent quand le glissement existe : elles font la même chose, en cinq
 * clics et cinq rechargements là où un geste suffit. Elles restent le chemin entier de qui n'a
 * pas de script — c'est le contrôleur, et lui seul, qui pose « journey-js ».
 */
.journey-js .journey-step form:has([value="monter"]),
.journey-js .journey-step form:has([value="descendre"]) {
    display: none;
}

/* L'emplacement laissé libre pendant le glissement, et la ligne qui suit le pointeur. */
.journey-step-slot {
    border: 2px dashed var(--app-accent);
    border-radius: var(--app-radius-ui);
    background: var(--app-accent-soft);
}

.journey-step-slot * {
    visibility: hidden;
}

.journey-step-drag {
    box-shadow: var(--app-shadow-pop);
}

/*
 * ── Une seule hauteur par ligne ──────────────────────────────────────────────────────────────
 * Le champ compact du paquet et le bouton compact du paquet ne font pas la même hauteur — 37 px
 * contre 23 — et une ligne qui mêle les deux se lit comme un montage. Les deux prennent donc la
 * hauteur des commandes carrées de l'application, celle du bouton à trois points d'une fiche.
 */
.journey-head,
.journey-step {
    align-items: center;
}

.journey-head :is(.app-btn, .app-field input),
.journey-step :is(.app-btn, .app-field input) {
    height: 2.25rem;
    padding-block: 0;
}

/*
 * ── La corbeille ─────────────────────────────────────────────────────────────────────────────
 * Une ligne par chose jetée : son dessin, son nom, ce que c'est, quand ça part, et de quoi la
 * remettre. Les quatre premiers se lisent de gauche à droite, le bouton se vise au bout.
 *
 * Le nom prend toute la place restante, et le reste ne bouge pas : c'est ce qui permet de
 * parcourir une colonne de dates sans la déchiffrer ligne par ligne.
 */
.trash-line {
    display: flex;
    gap: var(--app-space-md);
    align-items: center;
}

.trash-icon {
    flex: 0 0 auto;
    color: var(--app-ink-muted);
}

.trash-what {
    display: flex;
    flex: 1 1 auto;
    flex-wrap: wrap;
    gap: var(--app-space-2xs) var(--app-space-sm);
    align-items: baseline;
    min-width: 0;
}

.trash-name {
    overflow-wrap: anywhere;
}

/* Ce que c'est, en second : on reconnaît d'abord un nom, on vérifie ensuite la sorte. */
.trash-kind {
    color: var(--app-ink-muted);
    font-size: var(--app-text-sm);
}

.trash-when {
    flex: 0 0 auto;
    color: var(--app-ink-muted);
    font-size: var(--app-text-sm);
    white-space: nowrap;
}

/*
 * Sous la largeur d'un téléphone, la date passe sous le nom plutôt que d'écraser les deux : une
 * ligne de corbeille qui se coupe en quatre colonnes d'un centimètre ne se lit plus.
 */
@media (width < 40rem) {
    .trash-line {
        flex-wrap: wrap;
    }

    .trash-when {
        flex-basis: 100%;
        order: 3;
    }
}
