/* ============================================================
   BB TOOLS - bb-core.css
   Charte graphique commune a tous les generateurs.
   Chaque page definit ses trois variables d'accent avant de
   charger ce fichier ; tout le reste est identique partout.
   ============================================================ */
/* ============================================================
   BB TOOLS - CHARTE GRAPHIQUE COMMUNE
   Chaque app de la suite reprend ce bloc et change --accent.
   kick=ambre  snare=cyan  hats=vert  loops=magenta
   ============================================================ */
:root{

  --bg:#0d0e10;
  --panel:#16181c;
  --panel-2:#1c1f24;
  --panel-3:#23272e;
  --line:#2a2e35;
  --line-soft:#212429;

  --text:#e6e8ec;
  --text-dim:#8b919c;
  --text-faint:#5a606b;

  --ok:#4ec9a0;
  --warn:#ff5f56;

  --r:4px;
  --font:'Segoe UI',system-ui,-apple-system,sans-serif;
  --mono:'Consolas','SF Mono',ui-monospace,monospace;
}
*{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{
  background:var(--bg);color:var(--text);font-family:var(--font);
  font-size:13px;overflow:auto;user-select:none;
  -webkit-font-smoothing:antialiased;
}
button,input,select{font-family:inherit;color:inherit}

/* ---------- structure ---------- */
.app{display:flex;flex-direction:column;height:100vh;min-height:680px;gap:8px;padding:8px}

header{
  /* 6 px et non 8 : vingt elements dans l'en-tete, la gouttiere pesait 160 px a
     elle seule - autant que le rack Duree entier. */
  display:flex;align-items:center;gap:6px;
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  padding:0 10px;height:46px;flex:0 0 auto;overflow:hidden;
}
.brand{
  display:flex;align-items:baseline;gap:7px;margin-right:2px;white-space:nowrap;
  flex:0 1 auto;min-width:0;overflow:hidden;
}
.brand .n{flex:0 0 auto}
.brand .s{overflow:hidden;text-overflow:ellipsis;min-width:0}
.brand a{text-decoration:none;transition:color .12s}
.brand .n{font-size:15px;font-weight:700;letter-spacing:.14em;color:var(--accent)}
.brand .n:hover{color:#fff}
.brand .s{font-size:9px;letter-spacing:.22em;color:var(--text-faint);text-transform:uppercase}
.brand .s:hover{color:var(--accent)}
.spacer{flex:1}

main{display:flex;flex-direction:column;gap:8px;flex:1;min-height:0}
.zone{
  background:var(--panel);border:1px solid var(--line);border-radius:var(--r);
  display:flex;flex-direction:column;min-height:0;
}
.zone > h2{
  font-size:9px;letter-spacing:.2em;text-transform:uppercase;color:var(--text-faint);
  padding:7px 10px 6px;border-bottom:1px solid var(--line-soft);
  display:flex;align-items:center;gap:8px;flex:0 0 auto;
}
.zone > h2 .tag{color:var(--accent-dim);letter-spacing:.1em}
.zone-body{padding:10px;display:flex;gap:10px;min-height:0}

#zoneMain{flex:1 1 auto;min-height:0}
#zoneMain .zone-body{flex-direction:column;flex:1;min-height:0}
/* La rangee du bas se dimensionne sur son contenu (flex:0 0 auto) et non sur une
   hauteur ecrite en dur. Avec 206 px figes, ajouter un reglage a un rack le
   faisait deborder en silence : c'etait deja le cas du rack Sortie depuis
   l'arrivee du limiteur, et du Compresseur depuis le sous-bloc Transient shaper.
   Le visualiseur d'onde, au-dessus, cede la place et garde son plancher. */
.bottom{display:grid;grid-template-columns:200px 1fr 1fr 190px;gap:8px;flex:0 0 auto;min-height:0}
main > .zone:first-child{min-height:200px}
.bottom .zone{min-height:0;overflow:hidden}
.bottom .zone-body{flex:1;min-height:0}

/* ---------- canvas ---------- */
.scope{
  position:relative;flex:1 1 auto;min-height:130px;
  background:#0a0b0d;border:1px solid var(--line-soft);border-radius:var(--r);
  overflow:hidden;
}
.scope canvas{position:absolute;inset:0;width:100%;height:100%;display:block}
.scope .hud{
  position:absolute;top:6px;left:8px;right:8px;display:flex;gap:14px;
  font-family:var(--mono);font-size:10px;color:var(--text-faint);pointer-events:none;
}
.scope .hud b{color:var(--text-dim);font-weight:500}
.scope .hud .v{color:var(--accent)}
.scope .legend{
  position:absolute;bottom:5px;right:8px;display:flex;gap:12px;
  font-family:var(--mono);font-size:9px;color:var(--text-faint);pointer-events:none;
}
.scope .legend i{display:inline-block;width:9px;height:2px;vertical-align:middle;margin-right:4px}

/* ---------- groupes de contrôles ---------- */
.racks{display:flex;gap:10px;flex:0 0 auto}
.rack{
  flex:1;background:var(--panel-2);border:1px solid var(--line-soft);
  border-radius:var(--r);padding:8px 9px 9px;min-width:0;
}
.rack > h3{
  font-size:8px;letter-spacing:.18em;text-transform:uppercase;color:var(--text-faint);
  margin-bottom:7px;display:flex;align-items:center;justify-content:space-between;
}
.grid{display:grid;gap:7px 10px}
.g2{grid-template-columns:1fr 1fr}
.g3{grid-template-columns:1fr 1fr 1fr}
.g5{grid-template-columns:repeat(5,1fr)}

/* ---------- contrôle horizontal ---------- */
.ctrl{min-width:0}
.ctrl .top{display:flex;justify-content:space-between;align-items:baseline;gap:6px;margin-bottom:3px}
.ctrl label{font-size:10px;color:var(--text-dim);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ctrl .val{font-family:var(--mono);font-size:10px;color:var(--accent);white-space:nowrap}
.ctrl.off .val{color:var(--text-faint)}

input[type=range]{
  -webkit-appearance:none;appearance:none;width:100%;height:14px;background:transparent;cursor:ew-resize;
}
input[type=range]::-webkit-slider-runnable-track{
  height:3px;background:#0c0d0f;border:1px solid var(--line);border-radius:2px;
}
input[type=range]::-webkit-slider-thumb{
  -webkit-appearance:none;width:9px;height:15px;margin-top:-7px;border-radius:1px;
  background:linear-gradient(180deg,#cfd3da,#8a909a);border:1px solid #05060700;
  box-shadow:0 0 0 1px #05060a,0 1px 3px #000;
}
input[type=range]:hover::-webkit-slider-thumb{background:linear-gradient(180deg,var(--accent),var(--accent-dim))}
input[type=range]:active::-webkit-slider-thumb{background:linear-gradient(180deg,#fff,var(--accent))}
input[type=range]:focus{outline:none}
input[type=range]::-moz-range-track{height:3px;background:#0c0d0f;border:1px solid var(--line);border-radius:2px}
input[type=range]::-moz-range-thumb{width:8px;height:14px;border-radius:1px;border:1px solid #05060a;background:#a9afba}

/* ---------- barre du mode administrateur ---------- */
.adminbar{
  display:flex;align-items:center;gap:6px;flex:0 0 auto;height:34px;padding:0 10px;
  background:#1a1410;border:1px solid #6b4a12;border-radius:var(--r);
  font-size:10px;color:var(--text-dim);
}
.adminbar .tag{
  font-family:var(--mono);font-size:9px;letter-spacing:.16em;color:#e0a020;
  border:1px solid #6b4a12;border-radius:2px;padding:2px 6px;
}
.adminbar #adEtat{font-family:var(--mono);font-size:9px;color:var(--text-faint)}

/* ---------- egaliseur graphique ---------- */
.eqbox{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}
.eqbox canvas{
  position:absolute;inset:0;width:100%;height:100%;display:block;
  background:#0a0b0d;border:1px solid var(--line-soft);border-radius:var(--r);
  cursor:crosshair;
}
.eqinfo{
  position:absolute;top:4px;left:7px;right:7px;display:flex;gap:12px;
  font-family:var(--mono);font-size:9px;color:var(--text-faint);pointer-events:none;
}
.eqinfo b{color:var(--text-dim);font-weight:500}
.eqinfo .v{color:var(--accent)}

/* ---------- clavier piano ---------- */
.piano{
  position:relative;display:flex;height:42px;margin-top:3px;
  user-select:none;background:#0a0b0d;border:1px solid var(--line);border-radius:2px;
  padding:1px;overflow:hidden;
}
.piano .w{
  flex:1 1 0;min-width:0;background:#d6d9de;border-right:1px solid #0a0b0d;
  border-radius:0 0 2px 2px;cursor:pointer;position:relative;transition:background .08s;
}
.piano .w:last-child{border-right:0}
.piano .w:hover{background:#fff}
.piano .w.on{background:var(--accent)}
.piano .b{
  position:absolute;top:0;height:62%;background:#1b1e23;border:1px solid #000;
  border-radius:0 0 2px 2px;cursor:pointer;z-index:2;transition:background .08s;
}
.piano .b:hover{background:#343a42}
.piano .b.on{background:var(--accent);border-color:var(--accent-dim)}
.piano .oct{
  position:absolute;bottom:1px;left:0;right:0;text-align:center;
  font-family:var(--mono);font-size:7px;color:#8a8f97;pointer-events:none;
}
.piano .w.on .oct{color:#000}

select{
  width:100%;min-width:0;background:#0c0d0f;border:1px solid var(--line);border-radius:2px;
  padding:3px 4px 3px 6px;font-size:11px;cursor:pointer;
  text-overflow:ellipsis;
}
select:hover{border-color:var(--accent-dim)}
select:focus{outline:none;border-color:var(--accent)}

/* ---------- faders verticaux (ADSR) ---------- */
.vfaders{display:flex;gap:2px;justify-content:space-around;align-items:stretch;flex:1;height:100%;min-height:0}
.vf{display:flex;flex-direction:column;align-items:center;gap:5px;flex:1;min-width:0;height:100%}
.vf .val{font-family:var(--mono);font-size:10px;color:var(--accent);flex:0 0 auto}
.vf label{font-size:9px;letter-spacing:.12em;color:var(--text-dim);text-transform:uppercase;flex:0 0 auto}
.vf .slot{flex:1 1 auto;display:flex;justify-content:center;min-height:0;position:relative}
.vf input[type=range]{
  writing-mode:vertical-lr;direction:rtl;width:14px;height:100%;
  position:absolute;top:0;bottom:0;cursor:ns-resize;
}
.vf input[type=range]::-webkit-slider-runnable-track{width:3px;height:100%}
.vf input[type=range]::-webkit-slider-thumb{width:15px;height:9px;margin-top:0;margin-left:-6px}

/* ---------- boutons ---------- */
.btn{flex:0 0 auto;
  background:var(--panel-2);border:1px solid var(--line);border-radius:2px;
  padding:6px 11px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;
  cursor:pointer;white-space:nowrap;transition:.1s;
}
.btn:hover{border-color:var(--accent-dim);color:var(--accent)}
.btn:active{background:var(--accent);color:#000;border-color:var(--accent)}
.btn.primary{border-color:var(--accent-dim);color:var(--accent)}
.btn.primary:hover{background:var(--accent-glow)}
.btn.play{min-width:112px;text-align:center}
.btn.play.on{background:var(--accent);color:#000;border-color:var(--accent)}
.btn.tiny{padding:3px 7px;font-size:9px;letter-spacing:.06em;text-transform:none}

/* ---------- sélecteur d'intervalle de boucle ---------- */
.lsel{
  display:inline-flex;border:1px solid var(--line);border-radius:2px;
  overflow:hidden;background:var(--panel-2);flex:0 0 auto;
}
.lsel button{
  background:none;border:0;border-right:1px solid var(--line);cursor:pointer;
  padding:0 7px;height:24px;font-family:var(--mono);font-size:10px;
  color:var(--text-faint);transition:.1s;
}
.lsel button:last-child{border-right:0}
.lsel button:hover{color:var(--accent);background:var(--accent-glow)}
.lsel button.on{background:var(--accent);color:#000}

/* ---------- slots de capture ---------- */
.slots{display:flex;gap:4px}
.qs{
  display:inline-flex;border:1px solid var(--line);border-radius:2px;
  overflow:hidden;background:var(--panel-2);
}
.qs button{background:none;border:0;cursor:pointer;padding:0;font-family:var(--mono);transition:.1s}
.qs .cap{
  width:19px;height:24px;font-size:11px;line-height:1;color:var(--text-faint);
  border-right:1px solid var(--line);
}
.qs .cap:hover{background:var(--accent);color:#000}
.qs .rec{width:21px;height:24px;font-size:10px;color:var(--text-faint)}
.qs .rec.filled{color:var(--accent)}
.qs .rec:hover{background:var(--accent-glow);color:var(--accent)}
.qs .rec.filled:hover{background:var(--accent);color:#000}

/* ---------- versions A/B des reglages ---------- */
.ab{
  display:inline-flex;border:1px solid var(--line);border-radius:2px;
  overflow:hidden;background:var(--panel-2);margin-right:4px;
}
.ab button{
  background:none;border:0;cursor:pointer;padding:0;height:24px;
  font-family:var(--mono);font-size:10px;color:var(--text-faint);transition:.1s;
}
.ab button#abA,.ab button#abB{width:19px;border-right:1px solid var(--line)}
.ab button:hover{background:var(--accent-glow);color:var(--accent)}
.ab button.on{background:var(--accent);color:#000}
.ab .cp{width:26px;letter-spacing:-.4px}

/* Le rack Duree loge dans l'en-tete : le fader de tempo garde sa taille et la
   liste de longueur prend tout le reste. Sans cette regle elle restait a sa
   largeur intrinseque, son texte collait au bord et aux fenetres etroites
   c'est elle qui se faisait ecraser en premier. */
#rkDur .ctrl:last-child{flex:1 1 auto;min-width:0}
#rkDur .ctrl:first-child{flex:0 0 auto}
/* En fenetre etroite, c'est la marque qui cede en premier - elle est faite pour -
   et non le rack Duree, dont le texte deviendrait illisible. D'ou un coefficient
   de compression tres faible ici : sans lui, le rack le plus large absorbe
   mecaniquement l'essentiel du manque de place. */
#rkDur{flex-shrink:.25}

/* ---------- sous-bloc dans un rack ----------
   Un traitement distinct loge dans le meme rack qu'un autre : sans encadre, on
   ne peut pas savoir d'ou viennent ses reglages. Le gris est un cran au-dessus
   de celui du rack, pour se detacher sans creer un deuxieme rack. */
.sousbloc{
  grid-column:1/-1;background:var(--panel-3);border:1px solid var(--line);
  border-radius:3px;padding:6px 8px 8px;
}
.sousbloc > h4{
  font-size:8px;letter-spacing:.16em;text-transform:uppercase;color:var(--text-faint);
  font-weight:600;margin-bottom:6px;
}

.toggle{
  display:flex;align-items:center;gap:5px;font-size:10px;color:var(--text-dim);cursor:pointer;
  white-space:nowrap;flex:0 0 auto;
}
.toggle .box{
  width:26px;height:13px;border-radius:7px;background:#0c0d0f;border:1px solid var(--line);
  position:relative;transition:.12s;flex:0 0 auto;
}
.toggle .box::after{
  content:'';position:absolute;top:1px;left:1px;width:9px;height:9px;border-radius:50%;
  background:var(--text-faint);transition:.12s;
}
.toggle.on .box{background:var(--accent-glow);border-color:var(--accent-dim)}
.toggle.on .box::after{left:14px;background:var(--accent)}
.toggle.on{color:var(--accent)}

kbd{
  font-family:var(--mono);font-size:9px;background:#0c0d0f;border:1px solid var(--line);
  border-bottom-width:2px;border-radius:3px;padding:1px 5px;color:var(--text-dim);
}

/* ---------- vumètre GR ---------- */
.meter-wrap{display:flex;gap:9px;align-items:stretch;flex:0 0 auto}
.meter{
  width:26px;background:#0a0b0d;border:1px solid var(--line-soft);border-radius:2px;
  position:relative;overflow:hidden;
}
.meter .fill{
  position:absolute;top:0;left:0;right:0;height:0%;
  background:linear-gradient(180deg,var(--accent),#ff6a3d);
  transition:height .045s linear;
}
.meter .hold{position:absolute;left:0;right:0;height:1px;background:#fff;opacity:.7;top:0}
.meter .ticks{position:absolute;inset:0;pointer-events:none}
.meter .ticks span{
  position:absolute;left:0;right:0;height:1px;background:#ffffff10;
}
.meter-lab{
  display:flex;flex-direction:column;justify-content:space-between;
  font-family:var(--mono);font-size:8px;color:var(--text-faint);padding:1px 0;
}
.gr-read{font-family:var(--mono);font-size:10px;color:var(--accent);text-align:center;margin-top:4px}

/* ---------- barre d'info ---------- */
.status{
  display:flex;align-items:center;gap:16px;flex:0 0 auto;height:24px;padding:0 4px;
  white-space:nowrap;overflow:hidden;
  font-family:var(--mono);font-size:10px;color:var(--text-faint);
}
.status .v{color:var(--text-dim)}
.status .warn{color:var(--warn)}
.status .ok{color:var(--ok)}
.hint{margin-left:auto;color:var(--text-faint)}

.sep{width:1px;height:22px;background:var(--line)}

/* ---------- écran trop petit ----------
   Une trentaine de réglages, un visualiseur et quatre zones de traitement ne
   tiennent pas sur un téléphone. Plutôt que de livrer une interface écrasée,
   on l'annonce et on renvoie vers l'ordinateur. */
.tooSmall{display:none}
@media (max-width:899px), (max-height:599px){
  body{overflow:auto}
  .app{display:none}
  .tooSmall{
    display:flex;flex-direction:column;justify-content:center;
    min-height:100vh;padding:32px 26px;gap:18px;max-width:520px;margin:0 auto;
  }
  .tooSmall .n{font-size:19px;font-weight:700;letter-spacing:.16em;color:var(--accent)}
  .tooSmall h1{font-size:23px;line-height:1.25;font-weight:700}
  .tooSmall p{font-size:14.5px;line-height:1.6;color:var(--text-dim)}
  .tooSmall .url{