/* ── Colonne droite : poussée dans la grille. Rail d'icônes immobile à droite ; au repli seul le corps passe à 0. ── */
#side { position: relative; grid-column: 3; grid-row: 2; display: grid; grid-template-columns: minmax(0, 1fr) var(--rail); min-width: 0; min-height: 0; box-shadow: inset 1px 0 0 var(--line); } /* trait sans largeur : le rail garde son x au pixel */
.side-body { min-width: 0; overflow-y: auto; overflow-x: hidden; }
.side-inner { width: calc(var(--r-open) - var(--rail)); padding: var(--s3) var(--s4) var(--s5); }
/* Les trois zones du panneau ne sont que des CONTENEURS : display:contents les
   efface de la mise en page, leurs enfants restent enfants de .side-inner. Elles
   existent pour que le redessin d'une zone ne touche pas les autres — l'ecran
   vivant est dans #side-live, que renderSide ne vide jamais. */
#side-head, #side-live, #side-rest { display: contents; }
#side-live[hidden] { display: none; }
.rail { display: flex; flex-direction: column; align-items: center; gap: var(--s1); padding-top: var(--s2); }
.badge { position: absolute; top: 2px; right: 0; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--accent-fill); color: var(--on-accent); font: 600 var(--t-label)/16px var(--sans); font-variant-numeric: tabular-nums; text-align: center; }
.sec-head { display: flex; align-items: baseline; gap: var(--s2); margin: var(--s2) 0; color: var(--ink-2); font-size: var(--t-label); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.sec-head .n { font-variant-numeric: tabular-nums; }
.req-list { margin-bottom: var(--s2); }
#side .req { margin: 0 0 var(--s2); }
#side .req .from { display: block; margin-left: 0; }
/* Une demande traitée quitte la liste : sa hauteur se referme, les cartes restantes glissent (reflow fonctionnel). */
#side .req.leaving { overflow: hidden; opacity: 0; margin-bottom: 0; padding-top: 0; padding-bottom: 0; border-width: 0; transition: height 220ms ease-out, margin 220ms ease-out, padding 220ms ease-out, opacity 150ms ease-out; }
.empty-line { display: flex; align-items: center; gap: 6px; margin: var(--s2) 0 var(--s3); color: var(--ink-2); font-size: var(--t-meta); }
.empty-line .icon { width: 14px; height: 14px; }
.hist-head { display: flex; align-items: center; gap: 6px; width: 100%; height: 30px; color: var(--ink-2); font-size: var(--t-label); font-weight: 600; text-transform: uppercase; letter-spacing: .06em; }
.hist-head .icon { width: 14px; height: 14px; transition: transform var(--move) ease-out; }
.hist-head[aria-expanded="true"] .icon { transform: rotate(90deg); }
.hist-head .n { font-variant-numeric: tabular-nums; }
.hist { margin-bottom: var(--s3); }
.hist-row { display: grid; grid-template-columns: 14px minmax(0, 1fr) max-content max-content; gap: var(--s2); align-items: center; width: 100%; min-height: 32px; text-align: left; font-size: var(--t-meta); border-top: 1px solid var(--line); }
.hist > .hist-row:first-child { border-top: 0; }
.hist-row:hover { background: var(--hover); }
.hist-row .icon { width: 14px; height: 14px; }
.hist-row .hs { font-size: var(--t-body); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.hist-row .hst, .hist-row .hat { color: var(--ink-2); white-space: nowrap; font-variant-numeric: tabular-nums; }
.hist-items { margin: 0 0 var(--s2); padding-left: calc(14px + var(--s2)); color: var(--ink-2); font-size: var(--t-meta); }
.hist-items p { margin: 0 0 2px; color: var(--ink); }
.hist-items ul { margin: 0; padding-left: 16px; }
.hist-items li { overflow-wrap: anywhere; }
.rt-list { margin-bottom: var(--s5); }
.rt { padding: 7px 0; border-top: 1px solid var(--line); }
.rt:first-child { border-top: 0; }
.rt .nm { font-size: var(--t-body); overflow-wrap: anywhere; }
.rt button.nm { display: block; width: 100%; text-align: left; }
.rt button.nm:hover { text-decoration: underline; }
#side .rt-form { grid-template-columns: minmax(0, 1fr); gap: var(--s2); margin-top: var(--s3); }
.hint.rt-err { color: var(--err); } .rt-err:empty { display: none; }
.rt .meta { display: flex; gap: var(--s2); font-size: var(--t-meta); color: var(--ink-2); font-variant-numeric: tabular-nums; align-items: center; flex-wrap: wrap; }
.rt .owner { color: var(--ink); }
.rt .st.on { color: var(--ok); }
.rt-act { color: var(--ink-2); font-size: var(--t-meta); }
.rt-act:hover { color: var(--ink); }
.empty { margin: 0 0 var(--s5); color: var(--ink-2); font-size: var(--t-body); }
/* En-tête d'une vue de la colonne droite (recherche, écran) : titre, actions, croix. */
.p-head { display: flex; align-items: center; gap: var(--s1); min-height: var(--mono-w); margin-bottom: var(--s2); }
.p-title { flex: 1; min-width: 0; font-size: var(--t-body); font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.count { min-height: 18px; margin: var(--s2) 0; color: var(--ink-2); font-size: var(--t-meta); }
.results { margin: 0 calc(-1 * var(--s2)); }
.res { display: block; width: 100%; padding: var(--s2); border-radius: var(--r2); text-align: left; }
.res:hover { background: var(--hover); }
.res[aria-selected="true"] { background: var(--current); }
.res-meta { display: flex; justify-content: space-between; gap: var(--s2); color: var(--ink-2); font-size: var(--t-meta); }
.res-meta .who { color: var(--ink); font-weight: 600; }
.res-text { margin-top: 2px; font-size: var(--t-body); line-height: 1.4; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
/* Écran du bot : cadre 16:9, bureau dessiné en SVG avec les tokens du thème. */
.p-head .av { margin-right: var(--s1); }
/* Bureau de la machine du bot en grand, puis vignettes des autres écrans (un clic = en grand). */
.frame.big { margin-bottom: var(--s1); }
/* L'ecran EN GRAND : #side-live (en-tete, ecran, legende) passe par-dessus le logiciel ; l'iframe ne bouge pas
   dans le document, donc noVNC ne se reconnecte pas. Toute la fenetre : deux niveaux seulement, miniature et
   grand. Pas de voile : un clic dehors atteint sa cible. */
#side-live.grand { position: fixed; inset: 0; z-index: 30; display: flex; flex-direction: column; gap: var(--s2); padding: var(--s3); background: var(--surface); }
/* Dans l'app (data-shell), la modale couvre la bande .bar/.brand qui deplace la fenetre : on la perce, sinon un
   clic sur Fermer deplace la fenetre. Sur macOS, l'en-tete degage les boutons de la fenetre. */
:root[data-shell] #side-live.grand { -webkit-app-region: no-drag; }
:root[data-shell="darwin"] #side-live.grand .p-head { padding-left: calc(var(--nav-pad) + var(--lights-w)); }
#side-live.grand .frame.big { flex: 1 1 auto; min-height: 0; aspect-ratio: auto; margin: 0; }
#side-live.grand #screen-caption { display: none; }
#big-cards:empty { display: none; }
#big-cards { display: flex; gap: var(--s2); flex-wrap: wrap; }
#big-cards .main-card { margin: 0; max-width: 480px; }
.main-mini { display: flex; align-items: center; justify-content: center; width: 160px; padding: 0; color: var(--ink-2); cursor: pointer; }
.main-mini:hover { color: var(--ink); }
.main-mini img { display: block; width: 100%; height: auto; }
.shots { display: grid; grid-template-columns: repeat(auto-fill, 124px); /* vignette = largeur fixe : on ajoute des colonnes */ gap: var(--s2); margin: var(--s2) 0 var(--s4); }
.shot { display: flex; flex-direction: column; gap: var(--s1); padding: var(--s1); border-radius: var(--r2); text-align: left; min-width: 0; }
.shot:hover { background: var(--hover); }
.shot .offline { font-size: var(--t-meta); }
.shot-cap { display: flex; align-items: flex-start; gap: var(--s1); font-size: var(--t-meta); line-height: 1.3; color: var(--ink-2); }
.shot-cap .av { margin-top: -2px; }
.frame { position: relative; aspect-ratio: 16 / 9; border: 1px solid var(--line); border-radius: var(--r2); overflow: hidden; background: var(--desk-wall); }
.frame svg { display: block; width: 100%; height: 100%; }
/* L'ecran REEL du bot, relaye par /api/bureau/ : il remplit le cadre comme le
   bureau dessine qu'il remplace ; en grand, c'est #side-live qui grandit. */
.frame .desk-live { display: block; width: 100%; height: 100%; border: 0; }
/* Le pointeur du bot : un repere fixe, sans animation ; il ne prend aucun clic (pointer-events). */
.frame .pointeur-zone { position: absolute; inset: 0; margin: auto; max-width: 100%; max-height: 100%; pointer-events: none; }
.pointeur { position: absolute; width: 14px; height: 14px; margin: -7px 0 0 -7px; border: 2px solid var(--accent-fill); border-radius: 50%; background: color-mix(in srgb, var(--accent-fill) 35%, transparent); box-shadow: 0 0 0 1px rgba(0, 0, 0, .55); box-sizing: border-box; }
/* Le bot demande la main : une carte compacte SOUS l'ecran qu'elle concerne.
   Bornee comme une carte, jamais etiree : la zone, elle, n'est pas bornee. */
.main-card { display: flex; flex-direction: column; gap: var(--s1); margin: var(--s1) 0 var(--s4); padding: var(--s2); border: 1px solid var(--line); border-radius: var(--r2); background: var(--surface); }
/* L'en-tete de la carte SE RABAT : dans le panneau etroit, la mention « Vous
   avez la main » passe a la ligne au lieu d'ecraser le titre. */
.main-head { display: flex; align-items: center; flex-wrap: wrap; gap: var(--s1); }
/* Le titre a sa PROPRE classe et NON .p-title : celui-la tronque en points de
   suspension, ce qui a raison pour un nom de bot dans un en-tete de section et
   tort ici — mesure du 2026-10-04 dans le panneau etroit du Pi, « Le bot
   demande ... ». Un libelle se rabat sur deux lignes, il ne se tronque pas. */
.main-titre { flex: 1 1 auto; min-width: 0; font-size: var(--t-body); font-weight: 600; }
.main-raison { margin: 0; color: var(--ink); font-size: var(--t-body); }
.main-card .caption { margin: 0; }
.main-card .row { display: flex; gap: var(--s1); flex-wrap: wrap; }
/* L'etat de l'ordinateur (veille, reveil, injoignable, connexion) couvre l'ecran ; aucune animation. */
.frame .voile { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: var(--s2); padding: var(--s2); background: var(--surface); color: var(--ink-2); font-size: var(--t-body); text-align: center; }
.frame .voile[hidden] { display: none; }
.voile .caption { margin: 0; }
.frame .offline { position: absolute; inset: 0; display: flex; align-items: center; justify-content: center; background: color-mix(in srgb, var(--bg) 72%, transparent); color: var(--ink-2); font-size: var(--t-body); }
.d-wall { fill: var(--desk-wall); } .d-bar { fill: var(--desk-bar); } .d-win { fill: var(--surface); stroke: var(--line); stroke-width: .6; }
.d-title { fill: var(--desk-bar); } .d-line { fill: var(--ink-2); opacity: .35; } .d-icon { fill: var(--accent); }
.caption { margin: 0 0 var(--s4); color: var(--ink-2); font-size: var(--t-meta); }

/* Mods (mods.js) : la zone des elements que yumi.mount() reserve aux mods de
   l'utilisateur. Leur contenu est a eux ; la page ne fixe que la place. */
.mods:not([hidden]) { display: flex; flex-direction: column; gap: var(--s2); margin-top: var(--s4); padding-top: var(--s3); border-top: 1px solid var(--line); }
