/**
 * Studio de placement — habillage.
 *
 * Le studio herite des jetons du theme Flori Green quand ils existent
 * (--c-cream, --c-ink, --c-wine, --rail-w…), et fournit ses propres valeurs
 * de repli sinon : le plugin reste installable ailleurs sans rien casser, et
 * suit automatiquement le mode sombre du theme.
 *
 * Parti pris de mise en page : c'est un APERCU, pas un configurateur. Le
 * corps occupe toute la largeur utile et toute la hauteur de l'ecran ; les
 * reglages flottent par-dessus dans une colonne etroite qu'on peut escamoter
 * d'un clic pour ne garder que l'image.
 */

/* ── LA PALETTE DU STUDIO ─────────────────────────────────────────────
   Elle suit le site, et elle sait tenir debout sans lui.

   Les jetons `--c-*` etaient ceux d'une peau abandonnee : ils n'existent
   plus nulle part, et le studio tournait donc entierement sur ses replis.
   Il lit maintenant les jetons du bento — `--creme`, `--case`, `--encre` —
   avec les memes valeurs en repli. Une extension doit fonctionner meme sous
   un autre habillage : les replis ne sont pas des vestiges, ce sont les
   valeurs qu'on assume.

   Le mode sombre est plus bas, et c'etait LE bug du bouton : le studio
   ecoutait `[data-theme="dark"]` alors que le theme pose `sombre`, en
   francais, depuis le lot 3.6.0. Il ne basculait jamais. */
.fgs {
  --fgs-ivory: var(--creme, #f4f1e6);
  --fgs-paper: var(--creme, #f4f1e6);
  --fgs-card: var(--case, #e9e4d2);
  --fgs-ink: var(--encre, #1b1905);
  --fgs-soft: var(--encre-doux, #5c5738);
  --fgs-accent: var(--brique, #8c3315);
  --fgs-on-accent: var(--on-ox, #fbf6ea);
  --fgs-danger: #9b2d24;
  --fgs-skin-border: rgba(0, 0, 0, .14);
  --fgs-line: var(--line, rgba(29, 22, 19, .16));
  --fgs-line-strong: var(--line, rgba(29, 22, 19, .32));
  --fgs-display: var(--font-display, "Fraunces", Georgia, serif);
  --fgs-sans: var(--font-sans, "Instrument Sans", system-ui, sans-serif);
  --fgs-label: var(--ui-label, .72rem);
  --fgs-small: var(--ui-small, .84rem);
  --fgs-body: var(--ui-body, .94rem);
  --fgs-h2: var(--ui-h2, 2rem);
  --fgs-h3: var(--ui-h3, 1.1rem);
  --fgs-track: var(--tracking-label, .12em);

  /* Largeur de la colonne de navigation du theme. Sert a calculer le
     debordement pleine largeur sans passer sous le rail. */
  --fgs-rail: 0px;
  --fgs-panel-w: 23rem;

  position: relative;
  margin: 0;
  color: var(--fgs-ink);
  font-family: var(--fgs-sans);
}

.fgs-sr {
  position: absolute;
  width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* ==========================================================================
   Pleine largeur
   --------------------------------------------------------------------------
   Le studio vit dans la colonne de contenu du theme, elle-meme decalee par
   la colonne de navigation. On ressort de cette colonne pour occuper tout
   l'espace disponible, sans jamais passer sous le rail.
   ========================================================================== */

/**
 * Le studio doit occuper toute la zone de contenu — donc tout l'ecran sauf
 * la colonne de navigation quand elle est deployee.
 *
 * Une formule du type `margin-inline: calc(50% - 50vw)` suppose que le bloc
 * parent est centre dans la fenetre. Ici il ne l'est pas : il vit dans la
 * colonne de droite d'une grille. Le studio mesure donc lui-meme, au
 * demarrage et a chaque redimensionnement, la distance qui le separe du bord
 * du rail et du bord de la fenetre, et l'ecrit dans ces deux variables.
 *
 * Les valeurs de repli couvrent le cas ou le script ne tourne pas : le bloc
 * reste alors dans le flux, sans debordement, ce qui est toujours lisible.
 */
.fgs-shell {
  position: relative;
  /* Le studio revient DANS la page.
     Il en sortait pour occuper tout l'ecran, bords carres, et donnait
     l'impression de quitter le site. Il garde donc les marges de la colonne
     de contenu et le rayon des cartes. */
  margin: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--fgs-panel-w);
  height: min(78dvh, 46rem);
  min-height: 30rem;
  background: var(--fgs-ivory);
  border: 1px solid var(--fgs-line);
  border-radius: var(--r-case, 1.4rem);
  overflow: hidden;
  transition: grid-template-columns 240ms cubic-bezier(.16, 1, .3, 1);
}

/* Les reglages escamotes : la colonne se ferme, la scene prend la place. */
.fgs-shell[data-panel="off"] { grid-template-columns: minmax(0, 1fr) 0; }

/* ── LE MODE SOMBRE ───────────────────────────────────────────────────
   Trois portes, et il en faut trois :

   1. `[data-theme="sombre"]` — le choix explicite, celui que posent les
      deux boutons de bascule. C'etait `"dark"`, et c'est pour ca que le
      bouton ne faisait rien.
   2. `[data-theme="dark"]` — l'ancienne valeur. Une visiteuse qui l'a
      enregistree avant le renommage ne doit pas se retrouver avec un
      studio clair dans un site sombre.
   3. `prefers-color-scheme` sans choix explicite — le reglage du systeme.

   Les valeurs sont celles du bento en sombre, avec repli. */
html[data-theme="sombre"] .fgs,
html[data-theme="dark"] .fgs {
  --fgs-ivory: var(--creme, #14150a);
  --fgs-paper: var(--case, #20220f); /* le panneau prend la couleur des cases : il valait `--creme`, donc la couleur de la page, et plus rien ne separait les reglages du fond */
  --fgs-card: var(--case, #20220f);
  --fgs-ink: var(--encre, #efedd9);
  --fgs-soft: var(--encre-doux, #a8a98a);
  --fgs-accent: var(--brique, #c4491a);
  --fgs-line: var(--line, rgba(239, 237, 217, .18));
  --fgs-line-strong: var(--line, rgba(239, 237, 217, .34));
  --fgs-skin-border: rgba(255, 255, 255, .16);
  --fgs-danger: #f0a196;
}
@media (prefers-color-scheme: dark) {
  html:not([data-theme="clair"]):not([data-theme="light"]) .fgs {
    --fgs-ivory: var(--creme, #14150a);
    --fgs-paper: var(--case, #20220f); /* le panneau prend la couleur des cases : il valait `--creme`, donc la couleur de la page, et plus rien ne separait les reglages du fond */
    --fgs-card: var(--case, #20220f);
    --fgs-ink: var(--encre, #efedd9);
    --fgs-soft: var(--encre-doux, #a8a98a);
    --fgs-accent: var(--brique, #c4491a);
    --fgs-line: var(--line, rgba(239, 237, 217, .18));
    --fgs-line-strong: var(--line, rgba(239, 237, 217, .34));
    --fgs-skin-border: rgba(255, 255, 255, .16);
    --fgs-danger: #f0a196;
  }
}

@supports not (height: 100dvh) {
  .fgs-shell { height: 40rem; }
}

/* ==========================================================================
   Scene
   ========================================================================== */

.fgs-viewport {
  position: relative;
  min-width: 0;
  /* Filet de sol, comme un plateau d'atelier. */
  background-image: linear-gradient(to bottom, transparent calc(100% - 1px), var(--fgs-line) calc(100% - 1px));
}

.fgs-canvas {
  display: block;
  width: 100%;
  height: 100%;
  touch-action: none; /* le pincement pilote le zoom, pas la page */
  cursor: grab;
  outline-offset: -3px;
}
.fgs-canvas:active { cursor: grabbing; }

/**
 * Poignee du motif selectionne.
 *
 * Un anneau fin, centre sur le motif actif. Il dit deux choses d'un coup :
 * quel motif est selectionne, et qu'on peut l'attraper. Il ne capte pas le
 * pointeur — c'est la scene qui gere la saisie, avec une tolerance autour de
 * ce point.
 */
.fgs-handle {
  position: absolute;
  z-index: 2;
  width: 46px;
  height: 46px;
  margin: -23px 0 0 -23px;
  border: 1px solid var(--fgs-accent);
  border-radius: 50%;
  pointer-events: none;
  transition: transform 140ms ease, opacity 140ms ease;
}
.fgs-handle button {
  position: absolute;
  width: 44px;
  height: 44px;
  padding: 0;
  border: 1px solid var(--fgs-accent);
  border-radius: 50%;
  background: var(--fgs-paper);
  color: var(--fgs-accent);
  pointer-events: auto;
  cursor: grab;
}
.fgs-handle-move { inset: 0; opacity: .01; }
.fgs-handle-size { right: -22px; bottom: -22px; }
.fgs-handle-size::after { content: ''; display: block; width: 12px; height: 12px; margin: auto; border: 1px solid currentColor; }
.fgs-handle-rotate { left: -22px; top: -22px; }
.fgs-handle-rotate::after { content: ''; display: block; width: 13px; height: 13px; margin: auto; border: 1px solid currentColor; border-left-color: transparent; border-radius: 50%; }
.fgs-handle::after {
  content: "";
  position: absolute;
  inset: 50% auto auto 50%;
  width: 5px; height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: 50%;
  background: var(--fgs-accent);
}
.fgs-handle.is-hot { transform: scale(1.14); }

@media (pointer: coarse) {
  .fgs-handle { width: 58px; height: 58px; margin: -29px 0 0 -29px; }
}
@media (prefers-reduced-motion: reduce) {
  .fgs-handle { transition: none; }
}

/* Retour visuel pendant qu'une image est glissee sur la scene. */
.fgs-is-dropping .fgs-viewport::after {
  content: "";
  position: absolute;
  inset: .75rem;
  border: 1px dashed var(--fgs-accent);
  pointer-events: none;
}
.fgs-canvas:focus-visible { outline: 2px solid var(--fgs-accent); }

.fgs-boot {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  justify-items: center;
  gap: .9rem;
  color: var(--fgs-soft);
  font-size: var(--fgs-label);
  letter-spacing: var(--fgs-track);
  text-transform: uppercase;
}
.fgs-boot p { margin: 0; }
.fgs-boot-mark {
  width: 26px; height: 26px;
  border: 1px solid var(--fgs-line-strong);
  border-top-color: var(--fgs-accent);
  border-radius: 50%;
  animation: fgs-spin 900ms linear infinite;
}
@keyframes fgs-spin { to { transform: rotate(360deg); } }

/* --- Barre haute, posee sur la scene -------------------------------------- */

/* Les reglages occupent la colonne de droite : la barre d'outils reste donc
   a droite de la SCENE, sans rien recouvrir. */
.fgs-topbar {
  position: absolute;
  top: 0; left: 0; right: 0;
  display: flex;
  align-items: center;
  justify-content: flex-end;
  /* La barre revient a la ligne au lieu de pousser « Recadrer » hors du
     cadre et de deposer « Reglages » par-dessus la scene. */
  flex-wrap: wrap;
  gap: .5rem 1rem;
  padding: .85rem clamp(1rem, 2.5vw, 2rem);
  pointer-events: none; /* la scene reste attrapable sous la barre */
}
.fgs-topbar > * { pointer-events: auto; }

/* La ligne d'aide est definie plus bas, avec sa pastille : deux blocs pour
   un meme selecteur, c'etait une couche corrective — celui-ci ne servait
   qu'a etre ecrase. */

.fgs-tools { display: flex; gap: .35rem; flex-wrap: wrap; justify-content: flex-end; }

.fgs-icon-btn {
  min-height: 44px;
  padding: 0 .85rem;
  border: 1px solid var(--fgs-line);
  border-radius: 0;
  background: color-mix(in srgb, var(--fgs-paper) 86%, transparent);
  color: var(--fgs-ink);
  font-family: inherit;
  font-size: var(--fgs-label);
  letter-spacing: var(--fgs-track);
  text-transform: uppercase;
  cursor: pointer;
  transition: border-color 160ms ease, color 160ms ease, background 160ms ease;
}
.fgs-icon-btn:hover:not(:disabled) { border-color: var(--fgs-ink); }
.fgs-icon-btn:disabled { opacity: .34; cursor: default; }
.fgs-icon-btn--strong[aria-expanded="true"] {
  border-color: var(--fgs-accent);
  background: var(--fgs-accent);
  color: var(--fgs-on-accent);
}

/* ==========================================================================
   Panneau de reglages — en surcouche, escamotable
   ========================================================================== */

/**
 * La scene reste le module d'ancrage. Les reglages forment une bande de
 * modules francs sur sa gauche et peuvent toujours etre escamotes.
 *
 * Le texte doit rester lisible sur une peau claire comme sur le fond ivoire :
 * chaque libelle porte donc son propre voile, tres discret, plutot qu'un
 * grand aplat qui masquerait la scene.
 */
.fgs-panel {
  position: relative;
  z-index: 3;
  /* Elle etait posee EN SURCOUCHE sur la scene, en `pointer-events: none`
     pour laisser tourner le corps derriere. Consequence : la molette passait
     au travers et zoomait la scene au lieu de faire defiler la colonne. Les
     blocs 05, 06 et 07 — l'ajustement, les motifs poses, l'export — etaient
     donc inatteignables. D'ou « la colonne de droite est completement
     bloquee » et « on ne peut pas retirer l'image ».
     C'est maintenant une vraie colonne, a cote de la scene : elle defile,
     et elle ne recouvre plus rien. */
  min-height: 0;
  min-width: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--fgs-paper);
  border: 0;
  border-left: 1px solid var(--fgs-line-strong);
  padding: 0;
}
.fgs-panel[hidden] { display: block; }              /* on anime, on ne coupe pas */

/* Les blocs se partagent un meme plan et sont separes par des filets. */
.fgs-panel .fgs-block {
  background: transparent;
  padding: 1rem 1.25rem;
  margin: 0;
  border: 0;
  border-top: 1px solid var(--fgs-line);
}

/* Blocs : des filets fins, jamais de cartes. */
.fgs-block { padding: .9rem 0; border-top: 1px solid var(--fgs-line); }
.fgs-block:first-child { border-top: 0; padding-top: 0; }

.fgs-legend {
  display: flex;
  align-items: baseline;
  gap: .6rem;
  margin: 0 0 .6rem;
  font-family: var(--fgs-sans);
  font-size: var(--fgs-label);
  font-weight: 600;
  letter-spacing: var(--fgs-track);
  text-transform: uppercase;
}
/* Le numero d'etape : une PASTILLE, pas un chiffre pale.
   Mesure sur le site en sombre : brique #c4491a sur case #20220f donnait
   3,33:1 a 12 px — sous le seuil de 4,5 — et l'opacite de .7 par-dessus
   descendait plus bas encore. Le chiffre ouvrait la section et c'etait le
   moins lisible de tout le panneau.
   Renverse : la brique passe au FOND, le texte est le creme du site.

   La valeur est ECRITE, pas prise dans `--fgs-accent` : en sombre l'accent
   passe a #c4491a et le couple ne donnait plus que 4,51:1 — au-dessus du
   seuil, mais sans marge, sur un texte de 11 px. La brique foncee du site,
   celle du bouton d'invitation juste a cote, donne 7,49:1 et la donne dans
   LES DEUX modes : la pastille cesse de dependre du theme. */
.fgs-legend span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.55em;
  padding: .18em .38em;
  border-radius: 999px;
  background: #8c3315;
  color: #fbf6ea;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: .92em;
  line-height: 1;
}

.fgs-sub {
  margin: .9rem 0 .5rem;
  font-size: var(--fgs-label);
  letter-spacing: var(--fgs-track);
  text-transform: uppercase;
  color: var(--fgs-soft);
}
.fgs-note { margin: .5rem 0 0; color: var(--fgs-soft); font-size: var(--fgs-small); line-height: 1.45; }
.fgs-note--tight { margin-top: .35rem; }
.fgs-empty {
  margin: 0;
  padding: .7rem .8rem;
  border-left: 1px solid var(--fgs-line-strong);
  color: var(--fgs-soft);
  font-size: var(--fgs-small);
  line-height: 1.5;
}
.fgs-error {
  margin: .6rem 0 0;
  padding: .5rem .7rem;
  border: 1px solid var(--fgs-danger);
  background: color-mix(in srgb, var(--fgs-danger) 7%, transparent);
  color: var(--fgs-danger);
  font-size: var(--fgs-small);
  line-height: 1.4;
}

/* --- Pastilles : meme grammaire que les filtres du portfolio -------------- */

.fgs-views { display: flex; flex-wrap: wrap; gap: .3rem; }
.fgs-chip {
  min-height: 44px;
  padding: .25rem .7rem;
  border: 1px solid var(--fgs-line);
  border-radius: 0;
  background: none;
  color: var(--fgs-soft);
  font-family: inherit;
  font-size: var(--fgs-small);
  cursor: pointer;
  transition: border-color 160ms ease, color 160ms ease, background 160ms ease;
}
.fgs-chip:hover { border-color: var(--fgs-line-strong); color: var(--fgs-ink); }
.fgs-chip[aria-pressed="true"] {
  border-color: var(--fgs-accent);
  background: var(--fgs-accent);
  color: var(--fgs-on-accent);
}

/* --- Carnations ----------------------------------------------------------- */

.fgs-skins { display: flex; gap: .4rem; }
.fgs-skin {
  width: 44px; height: 44px;
  display: grid; place-items: center;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 50%;
  background: none;
  cursor: pointer;
}
.fgs-skin span[aria-hidden] {
  display: block;
  width: 26px; height: 26px;
  border: 1px solid var(--fgs-skin-border);
  border-radius: 50%;
}
.fgs-skin:hover { border-color: var(--fgs-line-strong); }
/* L'etat choisi ne repose pas que sur la couleur : le cercle exterieur se dessine. */
.fgs-skin[aria-pressed="true"] { border-color: var(--fgs-ink); }

/* --- Import --------------------------------------------------------------- */

.fgs-file { display: block; }
.fgs-file input {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden; clip: rect(0, 0, 0, 0);
}
.fgs-file-face {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  padding: 0 .9rem;
  border: 1px dashed var(--fgs-line-strong);
  color: var(--fgs-ink);
  font-size: var(--fgs-small);
  cursor: pointer;
  transition: border-color 160ms ease, background 160ms ease;
}
.fgs-file-face:hover { border-color: var(--fgs-accent); background: rgba(0, 0, 0, .02); }
.fgs-file input:focus-visible + .fgs-file-face { outline: 2px solid var(--fgs-accent); outline-offset: 3px; }
.fgs-trim { display: grid; gap: .45rem; margin-top: .65rem; font-size: var(--fgs-small); color: var(--fgs-soft); }
.fgs-trim label { display: grid; grid-template-columns: auto 1fr; align-items: center; gap: .45rem; }
.fgs-trim input[type="range"] { min-height: 44px; accent-color: var(--fgs-accent); }

/* --- Flashes -------------------------------------------------------------- */

/* Pas de defilement imbrique : la liste s'etend, c'est le panneau qui
   defile. Enfermees dans 12 rem, les dernieres pastilles etaient coupees en
   bas et invisibles sans effort — constat de l'audit du 24/08. */
/* Onze vignettes de la taille d'une case a cocher, chacune sous un nom
   tronque a « Lignes veg… », le meme nom repete huit fois : on ne voyait ni
   les dessins ni ce qui les distinguait, et la repetition donnait
   l'impression d'un affichage casse. Quatre decisions.

   `contain` REMPLACE `cover`. C'etait le vrai defaut : un flash rogne au
   carre ne montre plus que le centre de son remplissage — d'ou ces
   rectangles de texture rouge qui se ressemblaient tous. Un dessin se
   montre entier ou ne se montre pas.

   Les tuiles GRANDISSENT — trois par rangee au lieu de quatre. Un motif est
   un trait : sous 44 px il n'en reste qu'une tache grise.

   Le dessin repose sur une PLAQUE CLAIRE constante, et elle ne suit pas le
   theme. Les motifs sont des traits sombres sur fond transparent : en mode
   sombre ils s'effacaient dans le panneau. La plaque n'est pas une couleur
   d'interface, c'est le papier sur lequel le motif est dessine.

   Le nom SORT de la grille. Tronque a trois mots il n'apprenait rien et
   faisait beaucoup de bruit ; il reste dans l'infobulle et pour les
   lecteurs d'ecran, donc personne ne le perd. */
.fgs-flashes {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: .5rem;
  margin: 0; padding: 0;
  list-style: none;
}
.fgs-flash {
  display: block; width: 100%;
  padding: 0; border: 0;
  background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.fgs-flash img {
  display: block; width: 100%;
  aspect-ratio: 1; object-fit: contain;
  padding: .35rem;
  background: #f4f1e6;
  border: 1px solid var(--fgs-line);
  border-radius: calc(var(--r-case, 1.4rem) * .4);
  transition: border-color 160ms ease, transform 160ms ease;
}
/* Le nom quitte la grille sans quitter la page : il reste annonce. */
.fgs-flash span {
  position: absolute;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}
.fgs-flash:hover img { transform: translateY(-2px); border-color: var(--fgs-accent); }
.fgs-flash:focus-visible img { outline: 2px solid var(--fgs-accent); outline-offset: 2px; }
/* Celui qui est pose : un liseré plein, pas une nuance de gris. */
.fgs-flash[aria-pressed="true"] img {
  border-color: var(--fgs-accent);
  box-shadow: 0 0 0 2px var(--fgs-accent);
}

/* --- Reglages ------------------------------------------------------------- */

.fgs-field { margin-bottom: .7rem; }
.fgs-field label {
  display: flex; justify-content: space-between; gap: 1rem;
  margin-bottom: .2rem;
  font-size: var(--fgs-label);
  letter-spacing: var(--fgs-track);
  text-transform: uppercase;
  color: var(--fgs-soft);
}
.fgs-field output { font-variant-numeric: tabular-nums; color: var(--fgs-ink); }
.fgs-field input[type="range"] {
  width: 100%; height: 44px; margin: 0;
  background: none; accent-color: var(--fgs-accent); cursor: pointer;
}

/* --- Motifs poses --------------------------------------------------------- */

.fgs-layers { margin: 0; padding: 0; list-style: none; }
.fgs-layer { display: flex; align-items: stretch; gap: .4rem; border-bottom: 1px solid var(--fgs-line); }
.fgs-layer-pick {
  display: flex; align-items: center; gap: .7rem;
  flex: 1 1 auto; min-height: 44px; padding: .3rem 0;
  border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer;
}
.fgs-layer-num { font-variant-numeric: tabular-nums; font-size: var(--fgs-label); letter-spacing: var(--fgs-track); color: var(--fgs-soft); }
.fgs-layer-label strong { display: block; font-weight: 500; font-size: var(--fgs-small); }
.fgs-layer-label small { display: block; font-size: var(--fgs-label); color: var(--fgs-soft); }
.fgs-layer.is-selected .fgs-layer-num,
.fgs-layer.is-selected .fgs-layer-label strong { color: var(--fgs-accent); }
.fgs-layer-remove {
  flex: none; width: 44px;
  border: 0; background: none; color: var(--fgs-soft);
  font-size: var(--fgs-h3); line-height: 1; cursor: pointer;
}
.fgs-layer-remove:hover { color: var(--fgs-danger); }

/* --- Boutons -------------------------------------------------------------- */

.fgs-row { display: flex; flex-wrap: wrap; gap: .4rem; margin-bottom: .5rem; }
.fgs-btn {
  display: inline-flex; align-items: center; justify-content: center;
  flex: 1 1 auto; min-height: 44px; padding: 0 .9rem;
  border: 1px solid var(--fgs-line-strong);
  background: none; color: var(--fgs-ink);
  font-family: inherit; font-size: var(--fgs-small);
  text-decoration: none; cursor: pointer;
  transition: background 160ms ease, border-color 160ms ease, color 160ms ease;
}
.fgs-btn--quiet:hover { border-color: var(--fgs-ink); }
.fgs-btn--primary {
  width: 100%;
  border-color: var(--fgs-accent);
  background: var(--fgs-accent);
  color: var(--fgs-on-accent);
  font-weight: 600;
}
.fgs-btn--primary:hover { filter: brightness(1.12); }

/* ==========================================================================
   Telephone et tablette — le panneau devient un tiroir bas
   ========================================================================== */

@media (max-width: 900px) {
  /* Une seule colonne : la scene en haut, les reglages dessous. Le cadre
     s'etire au contenu au lieu de forcer une hauteur d'ecran, sinon les
     reglages sont hors champ des l'arrivee. */
  .fgs-shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 52dvh auto;
    height: auto;
    min-height: 0;
  }
  .fgs-shell[data-panel="off"] {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 52dvh 0;
  }
  .fgs-panel {
    max-height: 60dvh;
    padding: .9rem clamp(1rem, 4vw, 1.5rem) calc(1rem + env(safe-area-inset-bottom));
    border-left: 0;
    border-top: 1px solid var(--fgs-line-strong);
    touch-action: pan-y;
  }
  .fgs-panel .fgs-block {
    background: none;
    backdrop-filter: none;
    padding: .7rem 0;
    margin: 0;
    border-left: 0;
    border-top: 1px solid var(--fgs-line);
  }
  .fgs-panel .fgs-block:first-child { border-top: 0; }

  .fgs-flashes { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .fgs-topbar { padding: .6rem .8rem; }
}

@media (prefers-reduced-motion: reduce) {
  .fgs-panel { transition: none; }
  .fgs-boot-mark { animation: none; border-top-color: var(--fgs-line-strong); }
}

/* ==========================================================================
   Repli
   ========================================================================== */

.fgs-fallback {
  border-block: 1px solid var(--fgs-line-strong);
  padding: clamp(2rem, 6vw, 4rem) 0;
}
.fgs-fallback-inner { max-width: 54ch; }
.fgs-eyebrow {
  margin: 0 0 .8rem;
  font-size: var(--fgs-label);
  letter-spacing: var(--fgs-track);
  text-transform: uppercase;
  color: var(--fgs-accent);
}
.fgs-fallback h3 {
  margin: 0 0 1rem;
  font-family: var(--fgs-display);
  font-size: var(--fgs-h2);
  font-weight: 400;
  line-height: 1.12;
}
.fgs-fallback p { margin: 0 0 1rem; color: var(--fgs-soft); line-height: 1.6; }
.fgs-fallback .fgs-row { margin-top: 1.6rem; }
.fgs-fallback .fgs-btn { flex: 0 1 auto; }
.fgs-retry {
  margin-top: 1rem; min-height: 44px;
  border: 0; border-bottom: 1px solid var(--fgs-line-strong);
  background: none; color: var(--fgs-ink);
  font-family: inherit; font-size: var(--fgs-label);
  letter-spacing: var(--fgs-track); text-transform: uppercase; cursor: pointer;
}
.fgs-fallback-code {
  margin-top: 1.2rem;
  font-family: var(--fgs-sans);
  font-size: var(--fgs-label);
  letter-spacing: .08em;
  color: var(--fgs-soft);
}

/* ==========================================================================
   Simulation jointe (page de contact)
   ========================================================================== */

.fgs-attached {
  display: flex; gap: 1rem; align-items: flex-start;
  margin: 0 0 1.6rem; padding: 1rem;
  border: 1px solid var(--fgs-line-strong);
}
.fgs-attached-thumb {
  flex: none; width: 108px; height: 108px;
  object-fit: cover; border: 1px solid var(--fgs-line);
}
.fgs-attached-body { display: flex; flex-direction: column; gap: .2rem; min-width: 0; }
.fgs-attached-body strong { font-size: var(--fgs-body); }
.fgs-attached-body span,
.fgs-attached-body small { color: var(--fgs-soft); font-size: var(--fgs-small); line-height: 1.45; }
.fgs-attached-actions { display: flex; flex-wrap: wrap; gap: 1rem; margin-top: .6rem; }
.fgs-attached-remove,
.fgs-attached-back {
  min-height: 44px; display: inline-flex; align-items: center;
  padding: 0; border: 0; border-bottom: 1px solid var(--fgs-line-strong);
  background: none; color: var(--fgs-ink);
  font-family: inherit; font-size: var(--fgs-small);
  letter-spacing: var(--fgs-track); text-transform: uppercase;
  text-decoration: none; cursor: pointer;
}
.fgs-attached-remove:hover { color: var(--fgs-danger); }

/* --- Focus ---------------------------------------------------------------- */

.fgs :where(button, a, input, [tabindex]):focus-visible {
  outline: 2px solid var(--fgs-accent);
  outline-offset: 3px;
}

@media print {
  .fgs-panel, .fgs-topbar, .fgs-fallback { display: none; }
  .fgs-shell { height: auto; }
}

/* ==========================================================================
   L'image importee
   --------------------------------------------------------------------------
   Une image posee ne pouvait etre que remplacee, jamais retiree. Son nom est
   affiche — on sait ce qu'on a mis — et le bouton la retire vraiment : champ
   de fichier vide, motif en attente efface.
   ========================================================================== */

.fgs-imported {
  display: flex;
  align-items: center;
  gap: .6rem;
  flex-wrap: wrap;
  margin-top: .6rem;
}
.fgs-imported-name {
  flex: 1 1 8rem;
  min-width: 0;
  margin: 0;
  color: var(--fgs-soft);
  font-size: var(--fgs-small);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ==========================================================================
   LE PANNEAU COMPACT — 03/09
   ==========================================================================

   « J'aimerais que les reglages soient tous disponibles sans scroller dans
   la barre des reglages. »

   Le panneau empilait sept blocs en une colonne de 23 rem : il fallait
   defiler pour atteindre l'ajustement et l'export, et on ne savait pas
   qu'ils existaient. Trois changements, aucun sur le JavaScript :

   1. AU-DESSUS DE 1300 px, le panneau s'elargit et ses blocs se rangent
      en DEUX colonnes. La hauteur est divisee par deux, tout tient.
   2. Les curseurs passent sur une ligne avec leur libelle : deux lignes
      par reglage devenaient six lignes pour trois reglages.
   3. Les espacements se resserrent partout — c'est un panneau d'outils,
      pas une page de lecture.

   La refonte ergonomique complete du studio — commandes autour du motif,
   poignees directes aux coins — reste un chantier a part. Ceci rend le
   panneau utilisable ; ca ne le remplace pas. */

/* Le panneau se mesure LUI-MEME, pas la fenetre.
   ------------------------------------------------------------------
   La version precedente declenchait ses regles sur la largeur de la
   FENETRE : a 1300 px, le panneau passait en deux colonnes... alors qu'il
   ne fait que 290 px de large. Deux colonnes de 145 px, et tout debordait —
   le texte d'aide coupe a droite, une barre de defilement horizontale sous
   la scene, le bouton « Retirer l'image » hors du cadre.

   Une requete de CONTENEUR mesure le panneau lui-meme. C'est exactement ce
   qu'il faut : ce panneau n'a aucun rapport de taille avec la fenetre, il a
   la largeur que la scene lui laisse.

   Les navigateurs qui ne connaissent pas @container ignorent tout le bloc
   et gardent la colonne simple : c'est le repli, et il est correct. */
.fgs-panel {
  container-type: inline-size;
  container-name: reglages;
}

/* Rien ne doit jamais forcer la largeur du panneau. Une URL, un nom de
   fichier ou un mot long suffisent a pousser une colonne au-dela de sa
   place, et c'est la barre de defilement horizontale qu'on voit apparaitre
   sous toute la scene. */
.fgs-panel,
.fgs-panel * { min-width: 0; }
.fgs-panel :where(p, span, label, output, li, a) { overflow-wrap: anywhere; }

@container reglages (min-width: 30rem) {
  /* Deux colonnes SEULEMENT quand le panneau est reellement large. */
  .fgs-panel {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-content: start;
    gap: 0 1.1rem;
  }
  /* Les planches de flashes et de motifs prennent la largeur : ce sont des
     planches, elles se regardent en entier. */
  .fgs-panel > .fgs-block:first-child,
  .fgs-panel > .fgs-block:nth-child(4) { grid-column: 1 / -1; }
  .fgs-panel .fgs-block { padding: .7rem 0; }
  .fgs-panel .fgs-block:nth-child(-n+2) { border-top: 0; }
}

/* Un reglage sur une ligne — le libelle, le curseur, la valeur — mais
   seulement si le panneau a la place. Sous 22 rem, le curseur passe sous
   son libelle : mieux vaut deux lignes lisibles qu'une ligne ecrasee. */
@container reglages (min-width: 22rem) {
  .fgs-field {
    display: grid;
    grid-template-columns: minmax(4.5rem, auto) minmax(0, 1fr);
    align-items: center;
    gap: .4rem .7rem;
    margin-bottom: .5rem;
  }
  .fgs-field > label { margin: 0; }
  .fgs-field > input[type="range"] { margin: 0; width: 100%; }
}

/* La densite des vignettes suit elle aussi la largeur du panneau. */
@container reglages (min-width: 26rem) {
  .fgs-flashes { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}
@container reglages (max-width: 18rem) {
  .fgs-flashes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Le resserrement general : c'est un panneau d'outils, pas une page de
   lecture. */
.fgs-panel .fgs-legend { margin-bottom: .45rem; }
.fgs-panel .fgs-note { margin-block: .3rem; }
.fgs-sub { margin: .6rem 0 .35rem; }

/* La planche de motifs peut etre longue : elle defile DANS son bloc plutot
   que de pousser l'ajustement et l'export hors du panneau. */
.fgs-flashes--motifs {
  max-height: min(30dvh, 18rem);
  overflow-y: auto;
  overscroll-behavior: contain;
  padding-right: .2rem;
}

/* Le champ d'import : son bouton et son aide tenaient sur une ligne trop
   longue et sortaient du cadre. */
.fgs-panel :where(.fgs-upload, .fgs-import) { max-width: 100%; }
.fgs-panel button:not(.fgs-flash) { max-width: 100%; white-space: normal; }

/* ── TELEPHONE : la scene d'abord, les reglages en tiroir ──────────
   Sur un ecran etroit, un panneau de reglages sous la scene pousse la scene
   hors de vue des qu'on ouvre un bloc. Les planches defilent donc
   horizontalement, et le panneau garde une hauteur bornee. */
@media (max-width: 560px) {
  .fgs-flashes {
    display: flex;
    gap: .4rem;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
    padding-bottom: .3rem;
  }
  .fgs-flashes > li { flex: 0 0 6rem; scroll-snap-align: start; }
  .fgs-flashes--motifs { max-height: none; overflow-y: visible; }
  .fgs-panel { max-height: 58dvh; }
  /* Une cible tactile ne descend pas sous 44 px, curseurs compris. */
  .fgs-field input[type="range"] { height: 44px; }
}


/* ==========================================================================
   LES DEUX ETATS — 04/09
   ==========================================================================

   APERCU : la silhouette, et rien d'autre. Le panneau de reglages n'existe
   pas — pas cache, pas replie : absent. C'est une case du bento comme les
   autres, et elle ne prend pas plus de place qu'une autre.

   PLEIN ECRAN : le studio sort du flux et prend la fenetre. C'est la seule
   facon de rendre l'interface utilisable — sept blocs de reglages a cote
   d'une scene 3D ne tiennent pas dans une colonne de page.

   On ne change pas de page : `position: fixed` suffit, donc la navigation
   reprend exactement ou elle etait quand on referme. */

/* ── ETAT 1 : L'APERCU ───────────────────────────────────────────── */
.fgs[data-mode="apercu"] .fgs-panel { display: none; }
.fgs[data-mode="apercu"] .fgs-shell {
  grid-template-columns: minmax(0, 1fr);
  height: auto;
  min-height: 0;
}
.fgs[data-mode="apercu"] .fgs-viewport { aspect-ratio: 16 / 9; min-height: 22rem; }
.fgs[data-mode="apercu"] .fgs-topbar { display: none; }
.fgs[data-mode="apercu"] .fgs-sortie { display: none; }
/* La scene ne se manipule pas tant qu'on n'a pas ouvert : un clic qui fait
   tourner un corps alors qu'on voulait faire defiler la page est une
   surprise desagreable. */
.fgs[data-mode="apercu"] canvas { pointer-events: none; }

.fgs-invite {
  position: absolute;
  inset: 0;
  z-index: 4;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: .5rem;
  padding: 1.5rem;
  text-align: center;
  cursor: pointer;
  /* Un voile LEGER : on doit voir la silhouette derriere — c'est elle qui
     donne envie d'ouvrir. */
  background: linear-gradient(to top,
    rgb(0 0 0 / .34), rgb(0 0 0 / .10));
}
.fgs[data-mode="plein"] .fgs-invite { display: none; }
.fgs-invite-titre {
  margin: 0;
  font-family: var(--fgs-serif, Georgia, serif);
  font-size: clamp(1.8rem, 4vw, 3rem);
  line-height: 1;
  color: #fbf6ea;
}
.fgs-invite-note {
  margin: 0;
  max-width: 32ch;
  font-size: .95rem;
  line-height: 1.45;
  color: #fbf6ea;
  opacity: .88;
}
.fgs-invite-btn {
  margin-top: .8rem;
  min-height: 52px;
  padding: 0 28px;
  border: 0;
  border-radius: 999px;
  cursor: pointer;
  background: #8c3315;
  color: #fbf6ea;
  font: inherit;
  font-size: .82rem;
  font-weight: 600;
  letter-spacing: .08em;
  text-transform: uppercase;
  transition: transform .3s ease;
}
.fgs-invite-btn:hover { transform: translateY(-2px); }
.fgs-invite-btn:focus-visible { outline: 2px solid #fbf6ea; outline-offset: 3px; }

/* ── ETAT 2 : LE PLEIN ECRAN ─────────────────────────────────────── */
.fgs[data-mode="plein"] {
  position: fixed;
  inset: 0;
  z-index: 90;
  margin: 0;
  padding: 0;
  background: var(--fgs-paper, #f4f1e6);
}
.fgs[data-mode="plein"] .fgs-shell {
  height: 100dvh;
  border-radius: 0;
  grid-template-columns: minmax(0, 1fr) 34rem;
}
.fgs[data-mode="plein"] .fgs-viewport { aspect-ratio: auto; border-radius: 0; }
/* La sortie se voit : elle est pleine, la seule de la barre. */
.fgs-sortie {
  background: #8c3315;
  color: #fbf6ea;
  border-color: #8c3315;
}
@media (max-width: 900px) {
  .fgs[data-mode="plein"] .fgs-shell {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: 46dvh minmax(0, 1fr);
  }
}
@media (prefers-reduced-motion: reduce) {
  .fgs-invite-btn { transition: none; }
}

/* ==========================================================================
   LE PLEIN ECRAN, AERE — 04/09
   ==========================================================================

   « Completement casse, il faut qu'il y ait de l'espace, que ce soit aere,
   revoir l'UI en mode bento. »

   Le panneau etait une colonne de blocs colles a des filets, herites d'une
   epoque ou il fallait tenir dans 23 rem. En plein ecran, la place ne manque
   plus : chaque bloc devient une CASE, comme partout ailleurs sur le site.
   Meme rayon, meme fond, meme ecart — et le fond de la page passe entre
   elles, exactement comme dans le bento.

   Les valeurs ne sont pas reprises des jetons du theme : le studio est une
   extension, il doit tenir debout meme avec un autre theme. Elles sont donc
   ecrites ici, une fois, et alignees sur celles du bento. */

.fgs[data-mode="plein"] {
  --fgs-ecart: 16px;
  --fgs-rayon: 20px;
}

/* La barre du site reste atteignable : on peut basculer clair / sombre et
   sortir sans quitter l'outil. Elle etait couverte par le plein ecran. */
.fgs[data-mode="plein"] { top: 0; }
.fgs[data-mode="plein"] .fgs-shell {
  padding: var(--fgs-ecart);
  gap: var(--fgs-ecart);
  background: transparent;
}
.fgs[data-mode="plein"] .fgs-viewport {
  border-radius: var(--fgs-rayon);
  border: 0;
  overflow: hidden;
}

/* ── CHAQUE BLOC EST UNE CASE ──────────────────────────────────────── */
.fgs[data-mode="plein"] .fgs-panel {
  display: flex;
  flex-direction: column;
  gap: var(--fgs-ecart);
  padding: 0;
  background: transparent;
  border: 0;
}
.fgs[data-mode="plein"] .fgs-panel .fgs-block {
  padding: 1.1rem 1.2rem;
  margin: 0;
  border: 0;
  border-radius: var(--fgs-rayon);
  background: var(--fgs-card, #e9e4d2);
}
/* Deux colonnes de cases quand le panneau est large : c'est ce qui evite
   de defiler, sans ecraser les contenus. */
@container reglages (min-width: 30rem) {
  .fgs[data-mode="plein"] .fgs-panel {
    display: grid;
    grid-template-columns: 1fr 1fr;
    align-content: start;
    gap: var(--fgs-ecart);
  }
  .fgs[data-mode="plein"] .fgs-panel > .fgs-block:first-child,
  .fgs[data-mode="plein"] .fgs-panel > .fgs-block:nth-child(4) {
    grid-column: 1 / -1;
  }
}

/* Les planches respirent : les vignettes ont de l'air entre elles, et la
   liste des motifs ne pousse plus le reste hors du panneau. */
.fgs[data-mode="plein"] .fgs-flashes { gap: .5rem; }
.fgs[data-mode="plein"] .fgs-flashes--motifs { max-height: min(38dvh, 24rem); }
.fgs[data-mode="plein"] .fgs-legend { margin-bottom: .7rem; }
.fgs[data-mode="plein"] .fgs-field { margin-bottom: .7rem; }

/* La barre d'outils flotte au-dessus de la scene, arrondie comme une case. */
.fgs[data-mode="plein"] .fgs-topbar {
  top: var(--fgs-ecart);
  left: var(--fgs-ecart);
  right: var(--fgs-ecart);
  gap: .5rem;
}

/* Sur telephone : la scene en haut, les cases dessous, et on defile. Deux
   colonnes de cases sur 375 px ne sont plus des cases. */
@media (max-width: 900px) {
  .fgs[data-mode="plein"] .fgs-shell {
    grid-template-rows: 44dvh minmax(0, 1fr);
  }
  .fgs[data-mode="plein"] .fgs-panel { max-height: none; }
}

/* Le panneau replie ne reserve PLUS de place en plein ecran.
   ------------------------------------------------------------------
   La regle de plein ecran fixait la deuxieme colonne a 34 rem sans
   condition, ce qui ecrasait `[data-panel="off"]`. Resultat mesure en ligne
   le 04/09 : le panneau etait en visibility:hidden — donc invisible — mais
   la grille lui gardait 544 px. Un tiers d'ecran blanc et vide.

   Ecrit APRES la regle generale pour la corriger a specificite egale : les
   deux visent le meme element, c'est l'ordre qui tranche. */
.fgs[data-mode="plein"] .fgs-shell[data-panel="off"] {
  grid-template-columns: minmax(0, 1fr) 0;
}
@media (max-width: 900px) {
  .fgs[data-mode="plein"] .fgs-shell[data-panel="off"] {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) 0;
  }
}

/* La bascule clair / sombre, dans la barre du studio.
   La barre du site est couverte par le plein ecran : sans ce bouton, on ne
   peut plus changer de mode sans refermer l'outil. */
.fgs-theme {
  display: inline-grid;
  place-items: center;
  width: 44px;
  height: 44px;
  padding: 0;
  border-radius: 999px;
}
.fgs-theme svg { width: 18px; height: 18px; }
.fgs[data-mode="apercu"] .fgs-theme { display: none; }

/* ── LA LIGNE D'AIDE ──────────────────────────────────────────────────
   « Clic gauche : poser… · clic droit : tourner… · molette : zoomer » :
   du texte brut posé sur la scène, à la couleur du corps, sans fond. Sur
   une peau claire il devenait illisible, et il n'appartenait à rien.

   C'est une PASTILLE : un fond qui garantit son contraste quelle que soit
   l'image derrière, et le rayon des cases du site pour qu'elle appartienne
   au même monde.

   Sur un écran tactile, ces instructions sont fausses — il n'y a ni clic
   droit ni molette. On les remplace par les gestes du doigt. */
.fgs-hint {
  padding: .5rem .9rem;
  border-radius: 999px;
  /* Le fond seul ne suffisait pas : `--fgs-paper` EST la couleur de la
     scene, en clair comme en sombre. La pastille se posait donc sur son
     propre jumeau et restait invisible — le texte avait l'air pose a nu sur
     le corps. Le filet lui donne un bord quel que soit le fond derriere. */
  background: color-mix(in srgb, var(--fgs-card) 92%, transparent);
  border: 1px solid var(--fgs-line);
  color: var(--fgs-ink);
  font-size: var(--fgs-label);
  letter-spacing: .02em;
  line-height: 1.3;
  backdrop-filter: blur(8px);
  max-width: min(52ch, 100%);
}
@supports not (background: color-mix(in srgb, red 50%, transparent)) {
  .fgs-hint { background: var(--fgs-card); }
}

/* Au doigt, les instructions changent : on le dit avec du CSS plutôt que
   d'écrire deux phrases dans le balisage, parce que le serveur ne sait pas
   sur quoi la page va s'ouvrir. */
@media (pointer: coarse) {
  .fgs-hint { font-size: 0; }
  .fgs-hint::after {
    content: "Touchez pour poser · glissez pour tourner · pincez pour zoomer";
    font-size: var(--fgs-label);
  }
}
/* Sous 860 px elle était simplement masquée : on ne dit plus comment ça
   marche à la personne qui en a le plus besoin. Elle passe sous la barre
   d'outils plutôt que de disparaître. */
@media (max-width: 860px) {
  .fgs-hint { display: block; order: 3; flex: 1 0 100%; margin-top: .5rem; }
  .fgs-topbar { flex-wrap: wrap; }
}

/* ── LE TACTILE ───────────────────────────────────────────────────────
   Les cibles descendaient sous 44 px sur téléphone, et la scène captait
   le glissement vertical : on ne pouvait plus faire défiler la page. */
@media (pointer: coarse) {
  .fgs-icon-btn,
  .fgs-chip,
  .fgs-skin { min-height: 44px; }
  .fgs-flash { min-height: 0; }
  /* La scène ne prend que les gestes horizontaux et le pincement : le
     glissement vertical reste à la page, sinon on est prisonnier du
     canevas dès qu'on veut descendre. En plein écran, elle prend tout —
     là, il n'y a plus de page derrière. */
  .fgs[data-mode="apercu"] .fgs-viewport { touch-action: pan-y pinch-zoom; }
  .fgs[data-mode="plein"] .fgs-viewport { touch-action: none; }
}
