/* ── Vues du centre (Marketplace, écrans du compte) : pleine largeur de la colonne, jamais bornées. ── */
.view { padding: var(--s4) 0 var(--s5); container-type: inline-size; }
.view h2 { margin: var(--s5) 0 var(--s3); font-size: var(--t-read); font-weight: 600; }
.view h2:first-child { margin-top: 0; }
.lead { margin: 0 0 var(--s4); color: var(--ink-2); font-size: var(--t-body); }
.ok-note { color: var(--ok); font-size: var(--t-body); }
.chips { display: flex; flex-wrap: wrap; gap: 6px; }
.chip { height: 28px; padding: 0 12px; border-radius: 14px; border: 1px solid var(--line); background: var(--surface); font-size: var(--t-meta); white-space: nowrap; }
.chip:hover { border-color: var(--ink-2); }
.chip[aria-pressed="true"] { background: var(--accent-fill); border-color: var(--accent-fill); color: var(--on-accent); }
/* ── Marketplace façon App Store : onglets segmentés, « À la une », étagères par catégorie, fiche produit. ── */
.mk-top { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3); margin-bottom: var(--s4); }
.mk-top .field { flex: 0 1 300px; margin-left: auto; }
.seg { display: inline-flex; padding: 2px; border-radius: 9px; background: var(--hover); }
.seg button { height: 28px; padding: 0 16px; border-radius: 7px; font-size: var(--t-body); white-space: nowrap; }
.seg button[aria-selected="true"] { background: var(--surface); box-shadow: 0 1px 3px rgba(0, 0, 0, .18); font-weight: 600; }
.banner { display: flex; align-items: center; gap: var(--s5); padding: var(--s5); border-radius: 18px; background: color-mix(in oklab, var(--tint) 16%, var(--surface)); border: 1px solid var(--line); }
.banner-text { flex: 1; min-width: 0; }
.eyebrow { color: var(--accent); font-size: var(--t-label); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.banner h2 { margin: 6px 0; font-size: var(--t-big); }
.banner p { margin: 0 0 var(--s4); color: var(--ink-2); font-size: var(--t-read); }
.shelf { margin-top: var(--s5); }
.shelf-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s3); padding-top: var(--s3); border-top: 1px solid var(--line); }
.shelf-head h2 { margin: 0; font-size: var(--t-h1); }
.link { color: var(--accent); font-size: var(--t-body); display: inline-flex; align-items: center; gap: 2px; }
.link .icon { width: 16px; height: 16px; }
/* Élément : UNE ligne (icône, nom, une ligne de description, pilule d'action), en grille de colonnes bornées. */
.apps { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(280px, 100%), 360px)); column-gap: var(--s5); }
.app { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: var(--s3); padding: var(--s2) 0; border-bottom: 1px solid var(--line); min-width: 0; }
.app-main { display: flex; align-items: center; gap: var(--s3); min-width: 0; text-align: left; border-radius: var(--r2); }
.app-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.app-name { display: block; font-weight: 600; }
.app-desc { display: block; color: var(--ink-2); font-size: var(--t-meta); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.app-desc .av { vertical-align: middle; margin-right: 2px; }
/* Icône façon App Store : carré arrondi ; connecteur = sa couleur + son icône déclarée par son manifeste (sinon un glyphe), bot = son avatar. */
.tile { width: 56px; height: 56px; border-radius: 13px; display: inline-flex; align-items: center; justify-content: center; flex: none; box-shadow: inset 0 0 0 .5px rgba(0, 0, 0, .14); }
.tile .icon { width: 28px; height: 28px; color: var(--on-accent); }
.tile .av { width: 72%; height: 72%; }
.tile.lg { width: 112px; height: 112px; border-radius: 25px; } .tile.lg .icon { width: 54px; height: 54px; }
.tile.xl { width: 132px; height: 132px; border-radius: 30px; } .tile.xl .icon { width: 64px; height: 64px; }
.pill { height: 28px; min-width: 76px; padding: 0 14px; border-radius: 14px; background: var(--hover); color: var(--accent); font-size: var(--t-meta); font-weight: 600; display: inline-flex; align-items: center; justify-content: center; gap: 4px; white-space: nowrap; }
.pill:hover { background: var(--current); }
.pill.done { color: var(--ink-2); }
.pill .icon { width: 12px; height: 12px; }
/* Etats d'une mini-app (web/miniapp_store.go) : une tache en cours n'est pas un bouton ; le nuage (deja obtenue,
   absente ici) est l'icone seule, comme l'App Store ; une mini-app qui ne peut pas tourner ici reste lisible, eteinte. */
.pill.busy { color: var(--ink-2); font-variant-numeric: tabular-nums; cursor: default; }
.pill.busy:hover { background: var(--hover); }
.pill.icon-only { min-width: 28px; width: 28px; padding: 0; border-radius: 50%; }
.pill.icon-only .icon { width: 16px; height: 16px; }
.pill.off { color: var(--ink-3); }
.product { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s5); margin: var(--s3) 0 var(--s5); }
.product h1 { margin: 0 0 var(--s1); font-size: var(--t-big); font-weight: 600; }
.product .card-meta { margin-bottom: var(--s3); }
.card-meta { color: var(--ink-2); font-size: var(--t-meta); }
.card-text { font-size: var(--t-read); margin: 0 0 var(--s4); white-space: pre-line; } /* les paragraphes du manifeste */
/* Les captures d'une fiche : une bande qui defile, cadree au pas d'une capture, au doigt, a la molette et au clavier. */
.shots { display: flex; gap: var(--s3); overflow-x: auto; scroll-snap-type: x mandatory; margin: 0 0 var(--s4); padding-bottom: var(--s2); }
.shots img { flex: none; height: 420px; max-height: 60vh; width: auto; scroll-snap-align: start; border-radius: var(--r2); border: 1px solid var(--line); background: var(--surface); }
.shots:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.card-cols { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(240px, 100%), 340px)); gap: var(--s5); margin-bottom: var(--s4); }
.card-cols h3 { margin: 0 0 6px; color: var(--ink-2); font-size: var(--t-label); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.card-cols ul { margin: 0; padding-left: 18px; font-size: var(--t-body); }
.card-cols li { margin: 3px 0; } .card-cols .dim { color: var(--ink-2); font-size: var(--t-meta); }
.sens { display: inline-flex; align-items: center; gap: 3px; margin-left: 6px; color: var(--warn); font-size: var(--t-meta); }
.sens .icon { width: 12px; height: 12px; }
.acc { display: grid; grid-template-columns: max-content max-content; align-items: center; column-gap: var(--s5); }
.acc > .tr { display: contents; }
.acc > .tr > * { display: flex; align-items: center; gap: var(--s2); min-height: 44px; border-top: 1px solid var(--line); }
.notice { display: flex; align-items: flex-start; gap: var(--s2); padding: var(--s3); margin-bottom: var(--s4); border-radius: var(--r2); background: var(--current); font-size: var(--t-body); }
.notice .icon { color: var(--accent); width: 16px; height: 16px; margin-top: 2px; }
/* Formulaires : paires libellé | champ, colonne de libellés à la largeur du plus long (fit-content), 2 paires si la place. */
.form { display: grid; grid-template-columns: fit-content(220px) minmax(0, 1fr); gap: var(--s3) var(--s4); align-items: start; }
@container (min-width: 900px) { .form.two { grid-template-columns: repeat(2, fit-content(220px) minmax(0, 1fr)); } }
@container (max-width: 420px) { .form, .form.two { grid-template-columns: minmax(0, 1fr); } .flabel { padding: 0; } }
.flabel { padding: 8px 0; color: var(--ink-2); font-size: var(--t-label); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; line-height: 16px; }
.fcell { min-width: 0; }
.hint { margin-top: var(--s1); color: var(--ink-2); font-size: var(--t-meta); }
.form + .lead { margin-top: var(--s4); }
.form-actions { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: center; gap: var(--s3); margin-top: var(--s2); }
select.field { appearance: auto; }
textarea.field { height: auto; min-height: 120px; padding: 8px 10px; resize: vertical; font: var(--t-body)/1.5 var(--sans); }
/* Crédit : jauge sobre (un trait), formules en cartes bornées. */
.meter { height: 6px; border-radius: 3px; background: var(--line); overflow: hidden; }
.meter > span { display: block; height: 100%; border-radius: 3px; background: var(--accent-fill); }
.gauge { min-width: 240px; padding: var(--s2) 10px 10px; margin-bottom: var(--s1); border-bottom: 1px solid var(--line); }
.gauge-row { display: flex; justify-content: space-between; gap: var(--s3); margin-bottom: 6px; color: var(--ink-2); font-size: var(--t-meta); font-variant-numeric: tabular-nums; white-space: nowrap; }
.gauge-row b { color: var(--ink); font-weight: 600; }
.plan-now { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s4); padding: var(--s4); border: 1px solid var(--line); border-radius: var(--r3); background: var(--surface); }
.plan-now .meter { flex: 1 1 220px; }
.plans { display: grid; grid-template-columns: repeat(auto-fill, minmax(min(220px, 100%), 280px)); gap: var(--s4); }
.plan { display: flex; flex-direction: column; gap: var(--s2); padding: var(--s4); border: 1px solid var(--line); border-radius: var(--r3); background: var(--surface); }
.plan.current { border-color: var(--accent); }
.plan-name { font-weight: 600; font-size: var(--t-read); }
.price { font-size: var(--t-big); font-weight: 600; font-variant-numeric: tabular-nums; }
.price small { font-size: var(--t-meta); color: var(--ink-2); font-weight: 400; }
.plan ul { margin: 0; padding-left: 18px; color: var(--ink-2); font-size: var(--t-body); flex: 1; }
.switch-row { display: flex; align-items: center; gap: var(--s3); margin-top: var(--s4); }
/* Tableaux : une ligne par objet, colonnes à la largeur de leur contenu, la dernière prend le reste. */
.tbl { display: grid; align-items: center; font-size: var(--t-body); margin-bottom: var(--s2); }
.tbl > .tr { display: contents; }
.tbl > .tr > * { display: flex; align-items: center; gap: var(--s2); min-width: 0; min-height: 44px; padding-right: var(--s4); border-top: 1px solid var(--line); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.tbl > .tr:first-child > * { border-top: 0; }
.tbl > .th > * { min-height: 28px; color: var(--ink-2); font-size: var(--t-label); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.tbl .num { justify-content: flex-end; font-variant-numeric: tabular-nums; }
.tbl .dim { color: var(--ink-2); }
.tbl .meter { flex: 1; }
.tbl > .tr > *:first-child { padding-right: var(--s3); }
.tbl.members { grid-template-columns: calc(var(--mono-w) + var(--s3)) fit-content(260px) fit-content(280px) minmax(0, 1fr); } /* comptes, appareils : initiale | nom | état | reste */
.tbl.bots { grid-template-columns: calc(var(--mono-w) + var(--s3)) fit-content(220px) fit-content(220px) minmax(0, 1fr); }
.tbl.keys { grid-template-columns: fit-content(240px) minmax(0, 1fr) max-content fit-content(200px) max-content; } /* nom | cle | oeil et copie | date | revoquer */
.tbl.usage { grid-template-columns: calc(var(--mono-w) + var(--s3)) fit-content(220px) minmax(80px, 1fr) max-content max-content; }
.tbl.trash { grid-template-columns: minmax(0, 1fr) max-content; } /* nom · maison | restaurer, supprimer */
.tbl > .row-confirm { grid-column: 1 / -1; margin-bottom: var(--s2); } /* la confirmation d'une ligne, depliee dessous */
.row-confirm .acts { display: flex; gap: var(--s2); } /* ses boutons passent a la ligne ensemble */
@container (max-width: 600px) {
  .tbl .opt { display: none !important; }
  .tbl.members, .tbl.bots { grid-template-columns: calc(var(--mono-w) + var(--s3)) minmax(0, 1fr) max-content; }
  .tbl.usage { grid-template-columns: calc(var(--mono-w) + var(--s3)) minmax(0, 1fr) max-content max-content; }
}
.doc-row { display: flex; align-items: center; gap: var(--s2); width: 100%; min-height: 44px; border-top: 1px solid var(--line); text-align: left; font-size: var(--t-body); }
.doc-row .icon { width: 14px; height: 14px; color: var(--ink-2); transition: transform var(--move) ease-out; }
.doc-row[aria-expanded="true"] .icon { transform: rotate(90deg); }
.doc-body { margin: 0 0 var(--s3) 22px; color: var(--ink-2); font-size: var(--t-body); }
.doc-list { margin-bottom: var(--s4); }
/* Autorisations macOS : l'etat d'un droit, a droite de sa ligne, seulement quand il est connu. */
.aut-etat { margin-left: auto; font-size: var(--t-meta); color: var(--ink-2); }
.aut-etat.accorde { color: var(--ok); }
.aut-etat.refuse { color: var(--err); }
.doc-body > p { margin: 0 0 var(--s2); }
.aut-err { color: var(--err); }

/* ── État « nouveau » (rien de sélectionné), en-tête de bot, membres d'un groupe, éditeur d'icône. ── */
.newconv { display: flex; flex-direction: column; align-items: center; gap: var(--s3); padding-top: 16vh; text-align: center; color: var(--ink-2); }
.newconv .ico { width: 64px; height: 64px; border-radius: 18px; background: var(--hover); display: inline-flex; align-items: center; justify-content: center; }
.newconv .ico .icon { width: 30px; height: 30px; }
.newconv h2 { margin: 0; color: var(--ink); font-size: var(--t-h1); font-weight: 600; }
.newconv p { margin: 0; }
.newconv .row { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2); margin-top: var(--s2); }
.ttl { display: flex; align-items: center; gap: var(--s2); min-width: 0; }
.av-edit { position: relative; flex: none; border-radius: 50%; display: inline-flex; }
.av-edit .pen { position: absolute; right: -3px; bottom: -3px; width: 20px; height: 20px; border-radius: 50%; background: var(--surface); box-shadow: 0 1px 4px rgba(0, 0, 0, .25); display: flex; align-items: center; justify-content: center; opacity: 0; transition: opacity var(--move) ease-out; }
.av-edit.md .pen { width: 16px; height: 16px; right: -4px; bottom: -4px; }
.av-edit:hover .pen, .av-edit:focus-visible .pen { opacity: 1; }
.av-edit .pen .icon { width: 11px; height: 11px; color: var(--ink); }
.who-head { display: flex; align-items: center; gap: var(--s3); margin: var(--s1) 0 var(--s4); }
.who-head .nm { font-weight: 600; font-size: var(--t-read); } .who-head .st { color: var(--ink-2); font-size: var(--t-meta); }
.mrow { display: flex; align-items: center; gap: var(--s3); width: 100%; min-height: 48px; text-align: left; border-top: 1px solid var(--line); }
.mrow:first-of-type { border-top: 0; } .mrow:hover { background: var(--hover); }
.mrow .nm { flex: 1; min-width: 0; font-size: var(--t-body); } .mrow .st { color: var(--ink-2); font-size: var(--t-meta); white-space: nowrap; }
.mlist { margin-bottom: var(--s4); }
.ed { position: fixed; z-index: 30; max-height: calc(100vh - 24px); overflow-y: auto; overscroll-behavior: contain; width: min(392px, calc(100vw - 24px)); padding: var(--s3) var(--s4) var(--s4); background: var(--surface); border: 1px solid var(--line); border-radius: var(--r3); box-shadow: var(--shadow); }
.ed .seg { display: flex; margin-bottom: var(--s3); } .ed .seg button { flex: 1 1 auto; padding: 0 8px; } /* cinq onglets dans 392 px : ils se partagent la largeur */
.ed-pv { display: flex; align-items: center; gap: var(--s4); margin-bottom: var(--s3); }
.ed-row { display: flex; align-items: center; gap: var(--s3); padding: 6px 10px; border-radius: var(--r2); background: var(--bg); min-width: 0; }
.ed-row .nm { font-weight: 500; } .ed-row .st { color: var(--ink-2); font-size: var(--t-meta); }
.ed h4 { margin: var(--s3) 0 6px; color: var(--ink-2); font-size: var(--t-label); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.shapes { display: grid; grid-template-columns: repeat(7, 46px); gap: 4px; }
.shape-btn { width: 46px; height: 46px; border-radius: var(--r2); display: inline-flex; align-items: center; justify-content: center; }
.shape-btn:hover { background: var(--hover); }
.shape-btn[aria-pressed="true"] { background: var(--current); box-shadow: inset 0 0 0 2px var(--accent); }
.swatches { display: flex; flex-wrap: wrap; gap: var(--s2); }
.sw { width: 26px; height: 26px; border-radius: 50%; background: var(--sw); box-shadow: inset 0 0 0 1px rgba(0, 0, 0, .15); }
.sw[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--accent); }
.ed-fam { margin-bottom: var(--s2); } .ed-fam .chip { height: 24px; padding: 0 10px; }
.ed-lw { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s2); color: var(--ink-2); font-size: var(--t-label); } .ed-lw input { flex: 1; }
.zone-row { display: flex; justify-content: space-between; gap: var(--s3); width: 100%; height: 32px; padding: 0 var(--s2); border-radius: var(--r2); text-align: left; } .zone-row:hover { background: var(--hover); }
.zone-row .st { color: var(--ink-2); font-size: var(--t-label); } .zone-row[aria-expanded="true"] { background: var(--current); }
.sw.no-edge { background: linear-gradient(135deg, transparent 46%, var(--ink-2) 46% 54%, transparent 54%), var(--surface); } .sw.auto { background: var(--av-edge); }
.stage { position: relative; width: 220px; height: 220px; margin: 0 auto; overflow: hidden; background: var(--bg); border-radius: 50%; touch-action: none; cursor: grab; }
.stage[data-mask="rounded"], .pvs[data-mask="rounded"] { border-radius: 28%; } .stage[data-mask="square"], .pvs[data-mask="square"] { border-radius: 8%; }
.stage img, .pvs img { position: absolute; left: 0; top: 0; max-width: none; transform-origin: 0 0; user-select: none; -webkit-user-drag: none; pointer-events: none; }
.pvs { position: relative; overflow: hidden; border-radius: 50%; flex: none; background: var(--bg); }
.zoom { display: flex; align-items: center; gap: var(--s2); margin-top: var(--s3); }
.zoom input { flex: 1; accent-color: var(--accent-fill); }
.ed-foot { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); margin-top: var(--s4); }

/* ── L'accueil de l'app sans compte (views.js renderWelcome) : toute la fenetre, rien derriere, centre et sobre ;
   les jetons du theme, donc clair ET sombre. Dans l'app de bureau, le fond deplace la fenetre ; liens et boutons
   restent cliquables. ── */
.welcome { position: fixed; inset: 0; display: grid; grid-template-rows: 1fr auto; background: var(--bg); color: var(--ink); font-family: var(--sans); }
/* EN THEME CLAIR, l'accueil reprend le fond « bonbon » de la page d'annonce — repris tel quel de
   yumi-link/landing/mi.css, `:root[data-bg="candy"]` : un blanc rose et quatre halos pastel dans
   les coins. Le gris plat de --bg (#f5f5f7) « eclate les yeux » (Nicolas, 2026-10-15), et c'est
   vrai : un aplat dur sous un Mi tout en rondeurs.
   Les couleurs sont celles de la landing, a l'identique, pour que les deux surfaces se
   reconnaissent ; elles ne sont pas redecoupees ici en jetons, parce que ce fond n'existe QUE
   sur cet ecran — en faire un jeton laisserait croire qu'il sert ailleurs. */
.welcome {
  background:
    radial-gradient(45% 35% at 15% 15%, #ffb8d9, transparent 70%),
    radial-gradient(45% 35% at 85% 25%, #fff1a8, transparent 70%),
    radial-gradient(50% 40% at 30% 85%, #b8f2dc, transparent 70%),
    radial-gradient(45% 35% at 85% 80%, #d6c8ff, transparent 70%),
    #fff7fb;
  /* En SOMBRE, le fond NEON de la landing (son ciel par defaut, en couleurs « neon »), halos
     adoucis : 50 et 40 % au lieu de 70 et 55 % (Nicolas, 2026-10-16 : « les neons un peu moins
     forts »). Et « Yumi » dans le jaune de la marque. Poses une fois ici, lus par les deux
     regles du theme sombre. */
  --welcome-nuit:
    radial-gradient(70% 60% at 78% 12%, color-mix(in oklab, #ff2fb3 50%, transparent), transparent 70%),
    radial-gradient(60% 55% at 12% 88%, color-mix(in oklab, #00d4ff 40%, transparent), transparent 70%),
    linear-gradient(180deg, #050308, #120a1f) #050308;
  --welcome-jaune: #ffc72c;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .welcome { background: var(--welcome-nuit); }
  :root:not([data-theme="light"]) .welcome .marque-yumi { color: var(--welcome-jaune); }
}
:root[data-theme="dark"] .welcome { background: var(--welcome-nuit); }
:root[data-theme="dark"] .welcome .marque-yumi { color: var(--welcome-jaune); }
.welcome-main { align-self: center; justify-self: center; display: flex; flex-direction: column; align-items: center; gap: calc(var(--s5) * 2); padding: var(--s5); text-align: center; }
/* La mascotte est le SUJET de cet ecran, pas une puce a cote du titre : elle passe au-dessus du nom et prend la
   place qu'il faut pour qu'on voie son regard et ses gestes (demande de Nicolas, 2026-10-14). */
.welcome-brand { display: flex; flex-direction: column; align-items: center; gap: var(--s3); }
.welcome-brand h1 { margin: 0; font-size: var(--t-hero); font-weight: 600; letter-spacing: -.02em; line-height: 1.05; }
/* Bornee en HAUTEUR aussi : a 40vw seule, « Creer un compte » sortait du bas de la fenetre de l'app (900 px). */
.welcome-mi { width: clamp(240px, min(40vw, 44vh), 560px); height: clamp(240px, min(40vw, 44vh), 560px); }
/* Le nom en marques : hauteurs accordees a l'oeil, pas au gabarit des fichiers (le « Mi » est plus haut que le
   mot « Yumi »). currentColor : blanc sur le sombre, encre sur le clair — un blanc en dur disparaitrait. */
.welcome-name { display: flex; align-items: baseline; gap: .4em; margin: 0; color: var(--ink); }
.marque { display: block; fill: currentColor; }
.marque-mi { height: calc(var(--t-hero) * .78); width: auto; align-self: center; }
.marque-yumi { height: calc(var(--t-hero) * .46); width: auto; align-self: center; }
.welcome-by { font-size: calc(var(--t-hero) * .34); font-weight: 400; color: var(--ink-2); }
/* Les langues, en haut : atteignables avant d'avoir un compte, ou la barre de l'app est derriere cet ecran. */
/* Le selecteur de langue : AU MILIEU, EN HAUT. Ferme, une pastille ; ouvert, une barre de recherche et sa liste —
   dix langues aujourd'hui, et on en attend cinquante. */
/* z-index 6 : AU-DESSUS du ciel de LuMi (z-index 4). Une modale passe devant tout — LuMi
   lui volait devant (Nicolas, 2026-10-14). Et repliee la pastille fait sa propre taille :
   une boite de 320 px autour d'un mot donnait le saut « petit d'un coup gros » a l'ouverture. */
.welcome-langs { position: absolute; top: var(--s3); left: 50%; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: var(--s1); z-index: 6; width: auto; }
/* Ouvert, le selecteur s'elargit : on CHOISIT dedans, et une liste de trente langues doit
   se parcourir sans loupe (Nicolas, 2026-10-14). Replie, il reste la pastille discrete. */
.welcome-langs.ouvert { width: min(560px, 92vw); }
.welcome-langbox { width: 100%; grid-template-columns: var(--mono-w) minmax(0, 1fr); }
.welcome-langbox input { min-width: 0; border: 0; background: none; color: var(--ink); font: inherit; font-size: var(--t-read); outline: none; }
.welcome-langbox .icon { justify-self: center; color: var(--ink-2); width: 16px; height: 16px; }
/* La liste DEFILE : c'est ce qui rend le grossissement utile, et trente langues ne tiennent
   pas a l'ecran. Le fond s'arrete net en haut et en bas (overscroll-behavior) pour que la
   molette ne fasse pas bouger la page derriere. */
.welcome-langlist { position: static; width: 100%; max-height: min(52vh, 440px); overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; padding: var(--s1); }
.welcome-langlist .pop-item { width: 100%; }
/* Une ligne de langue : plus haute, son drapeau plus grand. Le NOM reste a sa taille de
   lecture — c'est la ligne qu'on agrandit pour viser, pas le texte qu'on grossit. */
/* Le dock. La LIGNE se deplace (la poussee), son ENVELOPPE grossit (la loupe) — jamais la
   largeur, sinon la barre de defilement horizontale revient. Les deux sont peintes image par
   image par grossitAuDoigt : AUCUNE transition pendant que le doigt bouge, sinon elle repart
   a chaque pixel et tout saccade (mesure du 2026-10-15). La transition ne sert qu'a l'arrivee
   et a la sortie — d'ou la classe `dock`, posee tant que le doigt est dans la liste. */
/* La ligne garde une HAUTEUR FIXE : son contenu peut enfler sans rien redistribuer, et la
   poussee reste le seul deplacement. `overflow: visible` laisse le contenu grossi depasser. */
.lang-item { gap: var(--s3); height: 46px; padding: 0 var(--s3); border-radius: 12px; overflow: visible; will-change: transform;
  transition: transform .06s cubic-bezier(.2, .8, .2, 1), background .12s ease-out; }
/* L'enflure passe par la POLICE et la largeur du drapeau, jamais par un scale() : un scale
   etire une image deja rastérisée et le texte devient flou. Ici tout se redessine net. */
.lang-item .lang-in { display: flex; align-items: center; gap: calc(var(--s3) * var(--z, 1)); min-width: 0;
  font-size: calc(var(--t-read) * var(--z, 1));
  transition: font-size .06s cubic-bezier(.2, .8, .2, 1), gap .06s cubic-bezier(.2, .8, .2, 1); }
.welcome-langlist.dock .lang-item, .welcome-langlist.dock .lang-item .lang-in { transition: none; }
.lang-item .lang-in .flag { width: calc(30px * var(--z, 1)); height: auto; flex: none; border-radius: 3px; box-shadow: 0 0 0 1px var(--line) inset;
  transition: width .06s cubic-bezier(.2, .8, .2, 1); }
.welcome-langlist.dock .lang-item .lang-in .flag { transition: none; }
.lang-item .lang-nom { font-size: 1em; }   /* suit l'enveloppe, qui porte l'enflure */
/* A venir : lisible, cherchable, mais pas choisissable. Le mot le dit, le gris le confirme. */
.lang-item.bientot { cursor: default; opacity: .55; }
.lang-item.bientot:hover { background: none; }
.lang-item .lang-bientot { margin-left: auto; flex: none; padding: 2px 8px; border-radius: var(--r-pastille); background: var(--surface); color: var(--ink-2); font-size: var(--t-label); }
/* Mouvement reduit : la liste reste une liste, le grossissement ne s'applique pas. */
@media (prefers-reduced-motion: reduce) { .lang-item, .lang-item .lang-in, .lang-item .lang-in .flag { transition: none; transform: none !important; } }
.welcome-lang { display: inline-flex; align-items: center; gap: var(--s1); padding: var(--s1) var(--s2); border: 0; border-radius: var(--r-pastille); background: none; color: var(--ink-2); font: inherit; font-size: var(--t-meta); cursor: pointer; }
/* Meme arrivee que le rail de navigation et la pastille de produit. Le scale
   ne dure que le vol : a l'arrivee le vrai texte reprend, net, sa taille native. */
.welcome-langflight { position: fixed; inset: 0; pointer-events: none; z-index: 8; }
.welcome-langflight > *, .welcome-langs > .welcome-langzoom { transform-origin: top left; transition: transform var(--hop) var(--hop-ease), opacity var(--hop) var(--hop-ease); }
.welcome-langflight > * { white-space: nowrap; }
.welcome-langdismiss { pointer-events: none; transition: opacity var(--move) ease-out; }
.welcome-langdismiss.efface { opacity: 0; }
@media (prefers-reduced-motion: reduce) { .welcome-langflight > *, .welcome-langs > .welcome-langzoom, .welcome-langdismiss { transition: none; } }
.welcome-lang:hover { background: var(--surface); }
.welcome-lang.on { background: var(--bubble); color: var(--on-bubble); }
.welcome-lang:focus-visible { outline: 2px solid var(--ring-focus); outline-offset: 2px; }
/* Le ciel de LuMi : un calque au-dessus de l'accueil, sa toile pour les paillettes. Reprend la mise en page de
   mi.yumi-lab.ai (landing/mi.css) d'ou vient le module — sans son halo, les Mi n'en portent pas chez nous. */
.lumi-sky { position: absolute; inset: 0; z-index: 4; pointer-events: none; }
/* Repere de PROFONDEUR : passe une certaine petitesse, LuMi est LOIN — il doit donc passer
   DERRIERE le texte, lui et tout ce qu'il seme (ses paillettes sont dans le meme calque).
   Sans cela il restait devant jusqu'au fond, et on ne croyait plus a l'eloignement
   (Nicolas, 2026-10-15). Le texte gagne son propre niveau, sinon il n'a rien a gagner. */
.lumi-sky.loin { z-index: 0; }
/* En gros plan, il passe DEVANT tout : texte, bouton, pied de page. Le selecteur de langue
   reste au-dessus (z-index 6) — une modale ouverte prime sur le decor. */
.lumi-sky.proche { z-index: 5; }
.welcome-main, .welcome-foot { position: relative; z-index: 2; }
.lumi-sky canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.lumi { --lumi-t: clamp(150px, 17vw, 280px); position: absolute; left: 0; top: 0; width: var(--lumi-t); height: var(--lumi-t);
  margin: calc(var(--lumi-t) / -2) 0 0 calc(var(--lumi-t) / -2); pointer-events: auto; cursor: pointer; }
/* La marge negative est la MOITIE de la taille : le module place LuMi par son CENTRE (il ecrit un translate sur
   le coin), donc une marge en em sur une boite dont la police ne fait pas la taille le decalait. */
.lumi .av, .lumi canvas { width: 100%; height: 100%; display: block; }
/* La marque en bas a droite, comme sur l'icone : discrete, et elle derive avec le pointeur. */
.welcome-mark { position: absolute; right: var(--s5); bottom: var(--s5); color: var(--ink-2); opacity: .5; transition: transform .25s ease-out; }
.welcome-mark .marque { height: calc(var(--t-hero) * .5); width: auto; }
@media (prefers-reduced-motion: reduce) { .welcome-mark { transition: none; } }
.welcome-mi canvas { width: 100%; height: 100%; display: block; }
.welcome-lead { margin: 0; max-width: 21em; font-size: var(--t-big); line-height: 1.35; color: var(--ink-2); }
.welcome-link { display: inline-flex; align-items: center; gap: var(--s1); padding: var(--s1) var(--s2); border: 0; border-radius: var(--r1); background: none; color: var(--ink); font: inherit; font-size: var(--t-read); cursor: pointer; }
.welcome-link .icon { width: 14px; height: 14px; }
.welcome-link:hover { text-decoration: underline; }
.welcome-link:focus-visible { outline: 2px solid var(--ring-focus); outline-offset: 2px; }
/* Le bouton principal : le rayon et le gris des bulles de la conversation, source unique des deux. */
.welcome-go { padding: calc(var(--s2) * 1.1) calc(var(--s4) * 1.4); border-radius: var(--r-pastille); background: var(--bubble); color: var(--on-bubble); font-size: var(--t-big); }
.welcome-go:hover { text-decoration: none; filter: brightness(1.08); }
.welcome-wait { margin: 0; font-size: var(--t-body); color: var(--ink-2); }
.welcome-foot { display: flex; flex-direction: column; align-items: center; gap: var(--s2); padding: var(--s4) var(--s4) var(--s5); font-size: var(--t-meta); color: var(--ink-2); }
.welcome-foot p { margin: 0; }
.welcome-foot a { color: inherit; text-decoration: underline; }
.welcome-foot .welcome-link { font-size: var(--t-body); color: var(--ink-2); }
/* L'accueil ne deplace PLUS la fenetre. Seul l'EN-TETE le fait (.brand et .bar, layout.css),
   comme dans n'importe quelle application : « le systeme se bat avec le deplacement de la
   fenetre, il doit etre que sur le header du logiciel, pas partout » (Nicolas, 2026-10-15).
   Couvrir tout l'ecran d'une zone de deplacement volait les gestes — on ne pouvait ni attraper
   LuMi, ni le gratter, ni le lancer. Invisible dans un navigateur, ou `-webkit-app-region`
   n'existe pas : c'est pourquoi toutes mes mesures passaient. */

/* ── La vitre brisee (vitre.js) : porte du film, film-court-b/film.css ~588-593 ──────────── */
.vitre-hote { position: fixed; inset: 0; z-index: 9; pointer-events: none; }
.vitre { position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; }
/* Le trait du film : bleu tres clair, bouts ronds, et une lueur — un trait nu parait dessine. */
.vitre path { fill: none; stroke: #eaf4ff; stroke-linecap: round; stroke-linejoin: round; filter: drop-shadow(0 0 3px rgba(170, 210, 255, .7)); }
.vitre-mi { position: absolute; left: 0; top: 0; }
/* Un bris : un eclat triangulaire de verre, decoupe au clip-path comme dans le film. */
.bris { position: absolute; opacity: 0; clip-path: polygon(0 0, 100% 30%, 40% 100%); background: linear-gradient(135deg, rgba(255, 255, 255, .95), rgba(180, 215, 255, .55)); }
/* Le flash du choc (outils.js eclair(), #eaf4ff force .45) et la secousse du cadre. */
.vitre-eclair { position: absolute; inset: 0; background: #eaf4ff; opacity: .45; animation: vitre-eclair .22s ease-out forwards; }
@keyframes vitre-eclair { to { opacity: 0; } }
.vitre-hote.secousse { animation: vitre-secousse .3s ease-out; }
@keyframes vitre-secousse {
  0% { transform: translate(0, 0); } 20% { transform: translate(-7px, 5px); }
  45% { transform: translate(6px, -4px); } 70% { transform: translate(-3px, 2px); } 100% { transform: translate(0, 0); }
}
@media (prefers-reduced-motion: reduce) { .vitre-hote.secousse, .vitre-eclair { animation: none; } .bris { display: none; } }

/* Connecteurs : le code de connexion reste noir sur blanc dans les deux themes (l'image porte sa marge blanche). */
.conn-pair { display: flex; align-items: center; gap: var(--s4); flex-wrap: wrap; margin-bottom: var(--s4); }
.conn-qr { width: 200px; height: 200px; image-rendering: pixelated; border-radius: var(--r2); border: 1px solid var(--line); }
.conn-row { display: flex; align-items: center; gap: var(--s2); flex-wrap: wrap; margin-bottom: var(--s4); }
.conn-row .field { width: auto; flex: 0 1 320px; min-width: 0; }
.unofficial { margin-left: var(--s2); font-size: var(--t-label); font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: var(--warn); }

/* Preferences > Updates: one block per version, its changes as a list (settings.js, viewUpdates). */
.upd-notes { display: grid; gap: var(--s3); }
.upd-notes h3 { margin: 0 0 var(--s1); font-size: var(--t-body); font-weight: 600; font-variant-numeric: tabular-nums; }
.upd-notes .upd-tag { margin-left: var(--s2); color: var(--ink-2); font-size: var(--t-meta); font-weight: 400; }
.upd-notes ul { margin: 0; padding-left: 18px; color: var(--ink-2); font-size: var(--t-body); }
