// Librería de tracks de fábrica para la pestaña Projects.
// Filosofía: IR AÑADIENDO (para pinchar). La siembra es SOLO-AÑADIR: nunca borra
// nada; al subir DEFAULT_VERSION se agregan los que falten por nombre.
//
// Familias:
//   base NN   → loops clásicos, foco en el groove (los primeros que hicimos)
//   acid N    → piezas largas que evolucionan sobre una tensión conceptual
//   detalle   → showcase de instrumentos/sonidos (rhodes, piano, pads, vibráfono, FM)
//   techno ·  → temas ~7 min con arrange() (intro→capas→drop→break→outro)
//   acid largo· temas ~7 min con estructura de directo: intro melódica → drop →
//              beat melódico (piano/flauta) → subida → clímax (todo junto + 2º
//              beat + melodía rompiendo ~50s) → descenso ~35s. Cajas VARIADAS.
//   remixes   → 50 remixes techno de melodías famosas 80s/90s/2000s (128-172
//              compases con arrange()), en remix-projects.mjs
//
// Para añadir tu propio pack: crea un modulo con el mismo formato
// {name, folder, code} y concatenalo abajo en DEFAULT_PROJECTS.
import { RETRO_REMIXES } from './remix-projects.mjs';

export const DEFAULT_VERSION = 7;

const CLASSICS = [
  {
    name: 'base 01 · 303 clásico',
    code: `// base 01 · 303 clásico (acid house)
setcpm(130/4)
$: s("bd*4").bank("RolandTR909").gain(1.1)
$: s("~ cp ~ cp").bank("RolandTR909").gain(.55)
$: s("hh*8").bank("RolandTR909").gain(.4).pan(sine.range(.35,.65))
$: note("c2 c2 eb2 c2 g1 c2 bb1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(300,1900).slow(8)).lpq(12).lpenv(4).lpd(.12)
  .distort("1.3:.35").gain(.85)`,
  },
  {
    name: 'base 02 · hard acid',
    code: `// base 02 · hard acid techno
setcpm(138/4)
$: s("bd*4").bank("RolandTR909").gain(1.2).shape(.3)
$: s("~ ~ cp ~").bank("RolandTR909").gain(.5).room(.2)
$: s("hh*16").bank("RolandTR909").gain(perlin.range(.1,.5))
$: note("c2 c2 c3 eb2 c2 g2 f2 c2").fast(2)
  .s("sawtooth").lpf(saw.range(400,2600).slow(4)).lpq(14).lpenv(5).lpd(.09)
  .distort("2:.3").crush(8).gain(.8)`,
  },
  {
    name: 'base 03 · hipnótico',
    code: `// base 03 · hipnótico rolling
setcpm(132/4)
$: s("bd*4").bank("RolandTR909")
$: s("hh*8").bank("RolandTR909").gain(.35).pan(.4)
$: s("~ oh ~ ~").bank("RolandTR909").gain(.3)
$: note("c2 eb2 g2 c3 bb2 g2 eb2 c2").fast(2)
  .s("sawtooth").lpf(sine.range(500,1400).slow(16)).lpq(10).lpenv(3).lpd(.15)
  .distort("1:.4").room(.15).gain(.8)`,
  },
  {
    name: 'base 04 · deep dub',
    code: `// base 04 · deep dub acid
setcpm(126/4)
$: s("bd*4").bank("RolandTR808").gain(1.1)
$: s("~ cp").bank("RolandTR808").gain(.4).room(.4).size(4)
$: s("hh*8").bank("RolandTR808").gain(.3)
$: note("c2 ~ c2 eb2 ~ g1 c2 ~").fast(2)
  .s("sawtooth").lpf(sine.range(250,900).slow(12)).lpq(9).lpenv(3).lpd(.2)
  .delay(.4).dt(.375).dfb(.4).room(.3).gain(.8)`,
  },
  {
    name: 'base 05 · screaming',
    code: `// base 05 · screaming acid
setcpm(140/4)
$: s("bd*4").bank("RolandTR909").gain(1.2)
$: s("cp*2").bank("RolandTR909").gain(.4).degradeBy(.5)
$: s("hh*16").bank("RolandTR909").gain(.3)
$: note("c3 c3 eb3 c3 bb2 c3 g2 c3").fast(2)
  .s("square").lpf(sine.range(600,3500).slow(6)).lpq(18).lpenv(6).lpd(.08)
  .distort("2.5:.25").gain(.7)`,
  },
  {
    name: 'base 06 · rave stabs',
    code: `// base 06 · rave acid
setcpm(135/4)
$: s("bd*4").bank("RolandTR909").gain(1.1)
$: s("~ cp").bank("RolandTR909").gain(.55)
$: s("hh*8").bank("RolandTR909").gain(.4)
$: note("c3,eb3,g3").struct("x ~ x x ~ x ~ ~").s("supersaw").lpf(1200).room(.3).gain(.45)
$: note("c2 c2 eb2 g2 c2 bb1 c2 g1").fast(2)
  .s("sawtooth").lpf(saw.range(400,2000).slow(8)).lpq(13).lpenv(4).lpd(.1)
  .distort("1.5:.3").gain(.8)`,
  },
  {
    name: 'base 07 · minimal',
    code: `// base 07 · minimal acid
setcpm(128/4)
$: s("bd*4").bank("RolandTR909").gain(1.1)
$: s("~ ~ ~ hh").bank("RolandTR909").gain(.4)
$: note("c2 ~ ~ c2 ~ eb2 ~ ~").fast(2)
  .s("sawtooth").lpf(sine.range(300,1600).slow(10)).lpq(11).lpenv(4).lpd(.14)
  .distort("1:.4").gain(.85)`,
  },
  {
    name: 'base 08 · rumble',
    code: `// base 08 · rumble acid techno
setcpm(134/4)
$: s("bd*4").bank("RolandTR909").gain(1.2).shape(.4)
$: s("bd*4").bank("RolandTR909").lpf(120).room(.6).size(6).gain(.7)
$: s("hh*16").bank("RolandTR909").gain(.25)
$: note("c2 c2 c2 eb2 c2 g1 c2 bb1").fast(2)
  .s("sawtooth").lpf(sine.range(350,1700).slow(8)).lpq(13).lpenv(4).lpd(.1)
  .distort("1.8:.3").gain(.75)`,
  },
  {
    name: 'base 09 · detroit',
    code: `// base 09 · detroit acid
setcpm(130/4)
$: s("bd*4").bank("RolandTR909").gain(1.1)
$: s("~ cp").bank("RolandTR909").gain(.5)
$: s("hh*8").bank("RolandTR909").gain(.35).pan(sine.range(.3,.7))
$: note("<[c3,eb3,g3] [bb2,d3,f3]>").struct("x ~ x ~ ~ x ~ ~").s("sawtooth").lpf(1500).lpq(6).room(.4).gain(.4)
$: note("c2 eb2 g2 c2 bb1 c2 g1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(400,1800).slow(8)).lpq(12).lpenv(4).lpd(.11)
  .distort("1.2:.35").gain(.8)`,
  },
  {
    name: 'base 10 · fast groove',
    code: `// base 10 · fast hard acid
setcpm(142/4)
$: s("bd*4").bank("RolandTR909").gain(1.2).shape(.3)
$: s("~ cp ~ cp").bank("RolandTR909").gain(.45)
$: s("hh*16").bank("RolandTR909").gain(perlin.range(.15,.45))
$: s("~ oh").bank("RolandTR909").gain(.3).degradeBy(.3)
$: note("c2 c2 eb2 c2 f2 c2 g2 bb1").fast(2)
  .s("sawtooth").lpf(saw.range(450,2800).slow(4)).lpq(15).lpenv(5).lpd(.08)
  .distort("2.2:.25").crush(7).gain(.78)`,
  },
];

const CONCEPTS = [
  {
    name: 'acid 1 · persistencia / efímero',
    code: `// acid 1 · persistencia / efímero
// el bombo y el bajo PERMANECEN; todo lo demás aparece y se desvanece
setcpm(130/4)
$: s("bd*4").bank("RolandTR909").gain(1.1)
$: note("c2 c2 eb2 c2 g1 c2 bb1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(450,1500).slow(32)).lpq(11).lpenv(4).lpd(.12)
  .distort("1.2:.4").gain(.8)
$: s("hh*16").bank("RolandTR909").gain(perlin.range(0,.5))
  .degradeBy("<.2 .5 .8 .4>".slow(4))
$: s("cp").bank("RolandTR909").gain(.4).mask("<0 0 1 0 1 1 0 1>")
$: note("c5 eb5 g5 bb4").fast(2)
  .s("sawtooth").lpf(2600).gain(.22).room(.5).delay(.4)
  .degradeBy(.7).mask("<0 1 0 0 1 0>")`,
  },
  {
    name: 'acid 2 · expansión / contención',
    code: `// acid 2 · expansión / contención
setcpm(132/4)
$: s("bd*4").bank("RolandTR909").gain(1.15)
$: s("~ cp").bank("RolandTR909").gain(.45).room(sine.range(.1,.6).slow(32))
$: s("hh*8").bank("RolandTR909").gain(.35).pan(sine.range(.2,.8).slow(16))
$: note("c2 eb2 g2 c3 bb2 g2 eb2 c2").fast(2)
  .s("sawtooth").lpf(sine.range(300,3200).slow(32)).lpq(sine.range(6,16).slow(32))
  .lpenv(4).lpd(.12).distort("1.3:.35")
  .room(sine.range(0,.4).slow(32)).gain(.8)`,
  },
  {
    name: 'acid 3 · caos / orden',
    code: `// acid 3 · caos / orden
setcpm(136/4)
$: s("bd*4").bank("RolandTR909").gain(1.15).degradeBy("<0 0 0 .3 0 .5>".slow(2))
$: s("hh*16").bank("RolandTR909").gain(.3).degradeBy(sine.range(0,.8).slow(24))
$: s("rim*8").bank("RolandTR909").euclid("<4 5 7 3 8 5>",8).gain(.35)
$: note("c2 eb2 g2 c2 bb1 c2 g1 c2").fast(2)
  .s("sawtooth").lpf(saw.range(400,2200).slow(8)).lpq(13).lpenv(4).lpd(.1)
  .distort("1.6:.3")
  .someCyclesBy(.35, x=>x.ply("<1 2 3>").speed(rand.range(.9,1.1)))
  .gain(.8)`,
  },
  {
    name: 'acid 4 · tensión / disolución',
    code: `// acid 4 · tensión / disolución
setcpm(138/4)
$: s("bd*4").bank("RolandTR909").gain(1.2).mask("<1 1 1 1 1 1 1 0>")
$: s("hh*16").bank("RolandTR909").gain(saw.range(.1,.5).slow(16))
$: s("~ cp").bank("RolandTR909").gain(.4)
$: note("c2 c2 eb2 c2 g2 c2 bb1 c2").fast(2)
  .s("sawtooth").lpf(saw.range(500,3500).slow(16)).lpq(saw.range(8,20).slow(16))
  .lpenv(4).lpd(.1).distort("1.8:.3")
  .every(16, x=>x.room(.7).gain(.45).lpf(600)).gain(.8)`,
  },
  {
    name: 'acid 5 · densidad / vacío',
    code: `// acid 5 · densidad / vacío
setcpm(128/4)
$: s("bd*4").bank("RolandTR808").gain(1.1).mask("<1 1 1 1 0 0 1 1>")
$: s("hh*16").bank("RolandTR808").gain(.3).degradeBy(sine.range(0,.9).slow(16))
$: note("c2 eb2 g1 c2 bb1 eb2 g2 c2").fast(2)
  .s("sawtooth").lpf(sine.range(350,1500).slow(16)).lpq(10).lpenv(3).lpd(.15)
  .ply("<1 1 2 1 4 1 1 2>".slow(2)).distort("1.3:.4").mask("<1 1 1 1 0 1 1 1>").gain(.8)
$: note("g4 bb4 c5").fast(2)
  .s("square").lpf(2200).gain(.18).degradeBy(.6).room(.4).mask("<0 0 1 1 0 0 0 1>")`,
  },
  {
    name: 'acid 6 · mecánico / orgánico',
    code: `// acid 6 · mecánico / orgánico
setcpm(134/4)
$: s("bd*4").bank("RolandTR909").gain(1.15)
$: s("hh*16").bank("RolandTR909").gain(perlin.range(.15,.45)).swingBy(.1, 16)
$: s("~ cp").bank("RolandTR909").gain(.4)
$: note("c2 c2 eb2 c2 g1 c2 f2 c2").fast(2)
  .s("sawtooth").lpf(sine.range(400,1800).slow(20).add(perlin.range(-200,200))).lpq(12)
  .lpenv(4).lpd(.11).distort("1.4:.35").gain(perlin.range(.7,.9))`,
  },
  {
    name: 'acid 7 · ascenso / caída',
    code: `// acid 7 · ascenso / caída
setcpm(140/4)
$: s("bd*4").bank("RolandTR909").gain(1.2)
$: s("hh*8").bank("RolandTR909").gain(.35)
$: s("~ cp ~ cp").bank("RolandTR909").gain(.4)
$: note("c2 eb2 g2 c2 bb1 c2 g1 c2").fast(2)
  .add(note("<0 0 5 5 7 7 12 7 5 0 -5 0>".slow(2)))
  .s("sawtooth").lpf(sine.range(500,2600).slow(24)).lpq(13).lpenv(4).lpd(.1)
  .distort("1.6:.3").gain(.78)`,
  },
  {
    name: 'acid 8 · presencia / ausencia',
    code: `// acid 8 · presencia / ausencia
setcpm(130/4)
$: s("bd*4").bank("RolandTR909").gain(1.1).mask("<1 1 1 1 1 1 0 0>")
$: s("hh*16").bank("RolandTR909").gain(.28).mask("<1 1 0 1 1 0 1 0>")
$: note("c2 eb2 g2 c3 g2 eb2 bb1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(400,1800).slow(24)).lpq(12).lpenv(4).lpd(.12)
  .distort("1.3:.35").room(.35).delay(.5).dt(.5).dfb(.5)
  .mask("<1 1 0 0 1 1 1 0>").gain(.82)`,
  },
  {
    name: 'acid 9 · repetición / mutación',
    code: `// acid 9 · repetición / mutación
setcpm(133/4)
$: s("bd*4").bank("RolandTR909").gain(1.15)
$: s("hh*16").bank("RolandTR909").gain(.3).every(4, x=>x.ply(2))
$: s("~ cp").bank("RolandTR909").gain(.4)
$: note("c2 c2 eb2 c2 g1 c2 bb1 c2").fast(2)
  .s("sawtooth")
  .every(8, x=>x.rev())
  .every(6, x=>x.add(note("<0 3 5>")))
  .chunk(4, x=>x.speed(1.5))
  .lpf(sine.range(400,2000).slow(16)).lpq(13).lpenv(4).lpd(.1)
  .distort("1.5:.3").gain(.8)`,
  },
  {
    name: 'acid 10 · luz / sombra',
    code: `// acid 10 · luz / sombra
setcpm(137/4)
$: s("bd*4").bank("RolandTR909").gain(1.2).shape(sine.range(0,.4).slow(32))
$: s("hh*16").bank("RolandTR909").gain(sine.range(.05,.45).slow(24))
$: s("~ cp").bank("RolandTR909").gain(.4)
$: note("c2 c2 eb2 c2 g1 c2 bb1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(250,3200).slow(32)).lpq(sine.range(8,16).slow(32))
  .lpenv(sine.range(2,6).slow(32)).lpd(.1).distort("1.5:.3")
  .room(sine.range(.05,.3).slow(32)).gain(.8)`,
  },
];

const DETALLE = [
  {
    name: 'detalle · detroit rhodes',
    code: `// detalle · detroit rhodes
// acordes de Rhodes (gm_epiano2) sobre un groove profundo + ácido suave
setcpm(126/4)
$: s("bd*4").bank("RolandTR909").gain(1.05)
$: s("~ cp").bank("RolandTR909").gain(.4)
$: s("hh*8").bank("RolandTR909").gain(.3).pan(sine.range(.4,.6))
$: note("<[c3,eb3,g3,bb3] [f3,ab3,c4] [g3,bb3,d4] [eb3,g3,bb3]>")
  .s("gm_epiano2").room(.45).gain(.5).lpf(2600).velocity(.8)
$: note("c2 eb2 g2 c2 bb1 c2 g1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(400,1600).slow(16)).lpq(11).lpenv(4).lpd(.12)
  .distort("1.1:.4").gain(.7)`,
  },
  {
    name: 'detalle · deep piano + sub',
    code: `// detalle · deep piano + sub
// piano melancólico (stabs) sobre un sub-bajo seno redondo
setcpm(124/4)
$: s("bd*4").bank("RolandTR808").gain(1.1)
$: s("~ ~ ~ hh").bank("RolandTR808").gain(.3)
$: note("c1 ~ c1 ~ eb1 ~ g0 ~").fast(2).s("sine").lpf(220).gain(.9)
$: note("<c4 eb4 g4 ~ bb3 ~ g4 f4>")
  .s("piano").room(.5).gain(.45).delay(.3).dt(.33).degradeBy(.2)
$: note("c2 eb2 g2 c2").fast(2)
  .s("sawtooth").lpf(1200).lpq(9).lpenv(3).lpd(.15).distort("1:.4").gain(.55)`,
  },
  {
    name: 'detalle · cosmos pad + coro',
    code: `// detalle · cosmos pad + coro
// pad cálido que respira y un coro etéreo que aparece a ratos
setcpm(128/4)
$: s("bd*4").bank("RolandTR909").gain(1.05)
$: s("hh*8").bank("RolandTR909").gain(.25).mask("<1 1 0 1>")
$: note("<c3 eb3 g2 ab2>").s("gm_pad_warm").slow(2)
  .lpf(sine.range(600,2200).slow(24)).room(.6).gain(.5)
$: note("<[c4,g4] [eb4,bb4]>").s("gm_choir_aahs").slow(4)
  .room(.7).gain(.3).mask("<0 1 0 1>")
$: note("c2 eb2 g2 c2 bb1 c2 g1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(400,1500).slow(20)).lpq(11).lpenv(4).lpd(.12)
  .distort("1.1:.4").gain(.68)`,
  },
  {
    name: 'detalle · cristales vibra + FM',
    code: `// detalle · cristales vibra + FM
// vibráfono cristalino + campanitas FM sobre techno acid
setcpm(132/4)
$: s("bd*4").bank("RolandTR909").gain(1.1)
$: s("~ cp").bank("RolandTR909").gain(.4)
$: s("hh*16").bank("RolandTR909").gain(.25)
$: note("c5 eb5 g5 bb5 g5 eb5 c5 g4")
  .s("gm_vibraphone").room(.5).gain(.35).delay(.4).dt(.375).degradeBy(.3)
$: note("c6 g5").struct("x ~ ~ x ~ x ~ ~")
  .s("sine").fm(4).fmh(2).gain(.2).room(.6).degradeBy(.4)
$: note("c2 eb2 g2 c2 bb1 c2 g1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(400,1800).slow(16)).lpq(12).lpenv(4).lpd(.1)
  .distort("1.4:.35").gain(.7)`,
  },
];

// 8 subgéneros de techno, largos (~7 min con arrange: intro→capas→drop→break→outro),
// bancos variados combinados y teoría moderna (modos menores/frigios, armonía modal,
// capas de bombo, rumble, sidechain con gain).
const ESTILOS = [
  {
    name: 'techno · acid',
    code: `// techno · acid — Do frigio · 138 BPM · ~7 min
// bancos: RolandTR909 (bombo/clap) + RolandTR606 (hats, la pareja de la TB-303)
setcpm(138/4)
const kick = s("bd*4").bank("RolandTR909").gain(1.1)
const clap = s("~ cp").bank("RolandTR909").gain(.5)
const hats = s("hh*16").bank("RolandTR606").gain(perlin.range(.12,.4))
const ohh  = s("~ oh ~ oh").bank("RolandTR606").gain(.3)
const acid = note("c2 c2 db2 c2 g1 c2 ab1 c2").fast(2)
  .s("sawtooth").lpf(sine.range(400,2600).slow(16)).lpq(15).lpenv(5).lpd(.11).distort("1.6:.3")
const acidHi = acid.add(note(12)).gain(.5).degradeBy(.4).delay(.3)
arrange(
  [16, kick],
  [16, stack(kick, hats)],
  [24, stack(kick, hats, clap)],
  [32, stack(kick, hats, clap, acid)],
  [24, stack(hats, acid.room(.6).gain(.7))],
  [64, stack(kick, hats, ohh, clap, acid, acidHi)],
  [48, stack(kick, hats, clap, acid)],
  [16, stack(kick, hats.gain(.2))]
)`,
  },
  {
    name: 'techno · detroit',
    code: `// techno · detroit — La menor · 125 BPM · ~7 min
// bancos: RolandTR909 (bombo) + RolandTR808 (clap) + RolandTR707 (hats). Rhodes + cuerdas
setcpm(125/4)
const kick = s("bd*4").bank("RolandTR909").gain(1.05)
const clap = s("~ cp").bank("RolandTR808").gain(.45)
const hats = s("hh*8").bank("RolandTR707").gain(.3).pan(sine.range(.4,.6))
const ride = s("~ ~ oh ~").bank("RolandTR707").gain(.25)
const rhodes = n("<0 3 5 4>").scale("A3:minor")
  .off(.25, x=>x.add(note("7,12"))).s("gm_epiano2").room(.4).gain(.4).lpf(2600)
const strings = n("<0 5 3 4>").scale("A4:minor").s("gm_string_ensemble_1").slow(2).room(.6).gain(.26)
const bass = note("a1 ~ a1 c2 ~ e2 g1 ~").fast(2).s("sawtooth").lpf(700).lpq(6).lpenv(3).lpd(.14).gain(.7)
arrange(
  [16, kick],
  [16, stack(kick, hats)],
  [24, stack(kick, hats, bass)],
  [32, stack(kick, hats, clap, bass, rhodes)],
  [24, stack(hats, rhodes.room(.7), strings)],
  [32, stack(kick, hats, ride, clap, bass, rhodes, strings)],
  [48, stack(kick, hats, clap, bass, rhodes)],
  [16, stack(kick, rhodes.gain(.3))]
)`,
  },
  {
    name: 'techno · dub',
    code: `// techno · dub — Do menor · 122 BPM · ~7 min (Basic Channel)
// bancos: RolandTR808 (bombo) + RolandTR606 (rim/hats). Acordes con delay dub infinito
setcpm(122/4)
const kick = s("bd*4").bank("RolandTR808").gain(1.1)
const rim  = s("~ rim").bank("RolandTR606").gain(.3)
const hats = s("hh*8").bank("RolandTR606").gain(.2).degradeBy(.3)
const chord = note("<[c3,eb3,g3] [bb2,d3,f3]>").struct("~ x ~ ~")
  .s("sawtooth").lpf(sine.range(500,1300).slow(24)).lpq(8)
  .room(.7).delay(.6).dt(.75).dfb(.6).gain(.32)
const sub  = note("c1 ~ ~ ~ eb1 ~ ~ ~").fast(2).s("sine").lpf(180).gain(.9)
const hiss = s("white*8").gain(perlin.range(0,.12)).hpf(6000)
arrange(
  [16, stack(kick, sub)],
  [16, stack(kick, sub, hats)],
  [24, stack(kick, sub, hats, rim)],
  [32, stack(kick, sub, hats, rim, chord)],
  [24, stack(chord.room(.85).gain(.4), hiss, sub)],
  [40, stack(kick, sub, hats, rim, chord, hiss)],
  [48, stack(kick, sub, hats, chord)],
  [16, stack(kick, chord.gain(.25))]
)`,
  },
  {
    name: 'techno · hard / schranz',
    code: `// techno · hard/schranz — 145 BPM · ~7 min · bombo en capas + rumble + distorsión
// bancos: RolandTR909 + RolandTR808 (bombo doble) + LinnDrum (clap)
setcpm(145/4)
const kick = s("bd*4").bank("RolandTR909").gain(1.2).shape(.35)
const sub  = s("bd*4").bank("RolandTR808").lpf(90).gain(.7)
const rumble = s("bd*4").bank("RolandTR909").lpf(150).room(.7).size(8).gain(.55)
const hats = s("hh*16").bank("RolandTR909").gain(.35).degradeBy(.1)
const clap = s("~ cp ~ cp").bank("LinnDrum").gain(.4)
const stab = note("c2 c2 c2 eb2").fast(4).s("sawtooth").lpf(saw.range(500,3000).slow(4)).lpq(12).distort("2.4:.25").crush(6).gain(.7)
const riser = s("white*4").gain(saw.range(0,.5).slow(16)).hpf(4000)
arrange(
  [16, stack(kick, sub)],
  [16, stack(kick, sub, hats)],
  [24, stack(kick, sub, rumble, hats)],
  [32, stack(kick, sub, rumble, hats, clap, stab)],
  [24, stack(hats, stab.room(.6), riser)],
  [76, stack(kick, sub, rumble, hats, clap, stab)],
  [48, stack(kick, sub, rumble, hats, stab)],
  [16, stack(kick, hats.gain(.2))]
)`,
  },
  {
    name: 'techno · minimal',
    code: `// techno · minimal — Do menor · 128 BPM · ~7 min · hueco e hipnótico
// bancos: RolandTR808 (bombo) + CasioRZ1 (click) + RolandTR727 (perc) + RolandTR606 (hats)
setcpm(128/4)
const kick = s("bd*4").bank("RolandTR808").gain(1.05)
const click = s("~ ~ rim ~").bank("CasioRZ1").gain(.4)
const perc = s("~ lt ~ ht").bank("RolandTR727").gain(.3).pan(sine.range(.3,.7).slow(8))
const hats = s("hh*8").bank("RolandTR606").gain(.22).degradeBy(sine.range(.1,.6).slow(16))
const blip = note("c4 ~ eb4 ~ ~ g3 ~ ~").fast(2).s("square").lpf(1400).lpq(8).gain(.25).delay(.4).dt(.375).dfb(.4)
const bass = note("c2 ~ ~ c2 ~ ~ eb2 ~").fast(2).s("sine").lpf(400).gain(.7)
arrange(
  [16, stack(kick, bass)],
  [16, stack(kick, bass, hats)],
  [24, stack(kick, bass, hats, click)],
  [32, stack(kick, bass, hats, click, perc, blip)],
  [24, stack(bass, hats, blip.room(.6))],
  [44, stack(kick, bass, hats, click, perc, blip)],
  [48, stack(kick, bass, hats, perc, blip)],
  [16, stack(kick, bass)]
)`,
  },
  {
    name: 'techno · industrial',
    code: `// techno · industrial — Do frigio · 132 BPM · ~7 min · oscuro, metálico, ruido
// bancos: RolandTR909 (bombo distorsionado) + EmuSP12 (perc). FM metálico + drone
setcpm(132/4)
const kick = s("bd*4").bank("RolandTR909").gain(1.2).shape(.5).distort("1.5:.4")
const metal = note("c5 ~ g4 ~").fast(2).s("sine").fm(9).fmh(3.51).gain(.28).room(.5).delay(.3)
const perc = s("~ rim ~ rim").bank("EmuSP12").gain(.35).crush(6)
const noise = s("white*16").gain(perlin.range(.05,.3)).hpf(3000).lpf(9000)
const drone = note("c1").s("sawtooth").lpf(sine.range(120,500).slow(24)).lpq(10).distort("1.2:.4").gain(.6)
const scream = note("c3 db3 c3 eb3").fast(2).s("square").lpf(saw.range(400,4000).slow(8)).lpq(16).distort("2.2:.2").gain(.5)
arrange(
  [16, stack(kick, drone)],
  [16, stack(kick, drone, noise)],
  [24, stack(kick, drone, noise, perc)],
  [32, stack(kick, drone, noise, perc, metal)],
  [24, stack(drone, noise.gain(.4), metal.room(.8))],
  [56, stack(kick, drone, noise, perc, metal, scream)],
  [48, stack(kick, drone, noise, perc, scream)],
  [16, stack(kick, drone)]
)`,
  },
  {
    name: 'techno · hipnótico (rolling)',
    code: `// techno · hipnótico rolling — La menor · 134 BPM · ~7 min (Berlin/Berghain)
// bancos: RolandTR909 + AlesisHR16 + RolandTR727. Polimetría 3-contra-4
setcpm(134/4)
const kick = s("bd*4").bank("RolandTR909").gain(1.1)
const hats = s("hh*16").bank("RolandTR909").gain(.28)
const roll = s("lt*3").bank("AlesisHR16").gain(.3).pan(sine.range(.35,.65))
const clap = s("~ cp").bank("RolandTR909").gain(.4)
const perc = s("mt ~ ht ~ ~ lt").bank("RolandTR727").gain(.28)
const bass = note("a1 a1 a1 c2 a1 a1 g1 a1").fast(2).s("sawtooth").lpf(sine.range(300,900).slow(32)).lpq(8).lpenv(3).lpd(.12).gain(.72)
const stab = note("a3,c4,e4").struct("~ ~ x ~ ~ ~ ~ x").s("sawtooth").lpf(1500).lpq(6).room(.5).gain(.3).degradeBy(.3)
arrange(
  [16, stack(kick, bass)],
  [16, stack(kick, bass, hats)],
  [24, stack(kick, bass, hats, roll)],
  [32, stack(kick, bass, hats, roll, clap, perc)],
  [24, stack(bass, hats, roll, stab.room(.7))],
  [52, stack(kick, bass, hats, roll, clap, perc, stab)],
  [48, stack(kick, bass, hats, roll, perc)],
  [16, stack(kick, bass)]
)`,
  },
  {
    name: 'techno · melódico',
    code: `// techno · melódico — Fa menor · 124 BPM · ~7 min (Afterlife/Tale of Us)
// bancos: RolandTR909 (bombo suave) + RolandTR808 (hats/clap). Arp + pad, progresión i-VI-III-VII
setcpm(124/4)
const kick = s("bd*4").bank("RolandTR909").gain(1.0)
const hats = s("hh*8").bank("RolandTR808").gain(.28).pan(sine.range(.4,.6))
const clap = s("~ cp").bank("RolandTR808").gain(.35).room(.3)
const arp = n("0 2 4 7 4 2").scale("<F:minor Db:major Ab:major Eb:major>")
  .s("supersaw").fast(2).lpf(sine.range(700,2600).slow(16)).lpq(6).room(.5).delay(.4).dt(.375).gain(.3)
const pad = n("0").scale("<F3:minor Db3:major Ab3:major Eb3:major>")
  .off(.5, x=>x.add(note("3,7"))).s("gm_pad_warm").slow(2).room(.7).gain(.4).lpf(sine.range(500,1800).slow(32))
const bass = note("<f1 db1 ab1 eb1>").s("sine").lpf(400).gain(.85)
arrange(
  [16, stack(pad)],
  [16, stack(kick, pad)],
  [24, stack(kick, hats, bass, pad)],
  [32, stack(kick, hats, clap, bass, pad, arp)],
  [24, stack(pad, arp.room(.8), bass)],
  [36, stack(kick, hats, clap, bass, pad, arp)],
  [48, stack(kick, hats, bass, pad, arp)],
  [16, stack(pad.gain(.3))]
)`,
  },
];

// Temas de acid LARGOS con estructura de directo (intro melódica → drop →
// beat melódico → subida → clímax → descenso). Cada uno en otra tonalidad,
// con otras cajas de ritmos y otro instrumento melódico. Verificados headless.
const LARGOS = [
  {
    name: 'acid largo · rojo · Cm 132 (909/606/808)',
    code: `// acid rojo · Do menor · 132 BPM · ~7:16
// intro melódico → drop → beat+piano → flauta pegadiza → subida → clímax → descenso
setcpm(132/4)
const acid = note("c1 [c2 c1] eb1 c1 g1 c1 [bb1 c2] g1").s("sawtooth")
  .lpf(sine.range(450,2200).slow(4)).lpq(15).lpenv(5).lpa(.01).lpd(.14).lps(0).distort("1.3:.35")
const acidBuild  = acid.lpf(saw.range(450,3200).slow(40)).lpq(16).distort("1.4:.35")
const acidClimax = acid.lpf(sine.range(700,3200).slow(2)).lpq(17).distort("1.6:.3").jux(rev)
const k    = s("bd*4").bank("RolandTR909").gain(1.1)
const kOut = s("bd*4").bank("RolandTR909").gain(saw.range(1,0).slow(20))
const clap   = s("~ cp ~ cp").bank("RolandTR909")
const hats   = s("hh*8").bank("RolandTR606").gain("[.3 .5]*2")
const hats16 = s("hh*16").bank("RolandTR606").gain(".25 .4").pan(sine.range(.3,.7).fast(3))
const ohh    = s("~ oh ~ oh").bank("RolandTR808").gain(.4)
const ride   = s("~ ~ rd ~").bank("LinnDrum").gain(.35)
const rims   = s("rim(3,8)").bank("OberheimDMX").gain(.4)
const roll   = s("sd*16").bank("RolandTR909").gain(saw.range(.05,.9).slow(40))
const toms   = s("lt mt ht lt").bank("RolandTR808").gain(.5).sometimesBy(.3, x=>x.fast(2))
const clave  = s("cp(3,8)").bank("RolandTR707").gain(.5)
const pad    = note("<[c3,eb3,g3] [ab2,c3,eb3] [f2,ab2,c3] [g2,bb2,d3]>").s("gm_pad_warm").slow(2).gain(.5).room(.7).lpf(1300)
const box    = note("c5 eb5 g5 c6 g5 eb5 g5 eb5").s("gm_music_box").gain(.4).delay(.35).room(.5)
const piano  = note("<[g4 bb4 c5 bb4 g4 eb4 f4 g4] [g4 bb4 c5 d5 c5 bb4 g4 f4]>").s("gm_epiano1").room(.4).delay(.3).gain(.6)
const flauta = note("<[g4 bb4 c5 d5 eb5 d5 c5 bb4] [g4 bb4 c5 f5 eb5 c5 bb4 g4]>").s("gm_pan_flute").room(.5).delay(.3).dfb(.4).gain(.6)
const flautaBreak = note("[g4 bb4 c5 d5 eb5 d5 c5 bb4]").s("gm_pan_flute").room(.5).delay(.35).gain(.6).jux(rev).every(2, x=>x.fast(2))
const flautaOut   = note("c5 bb4 g4 eb4 c4 bb3 g3 c3").s("gm_pan_flute").slow(2).room(.85).gain(saw.range(.6,0).slow(20))
const riser = note("c6").s("gm_fx_atmosphere").gain(saw.range(.1,.5).slow(40)).hpf(saw.range(400,6000).slow(40))
const bleep = note("c4 eb4 g4 c5").fast(2).s("square").lpf(sine.range(900,3200).fast(2)).lpq(10).euclidLegato(5,8).gain(.4).delay(.25).room(.3)
const crash = s("cr").bank("RolandTR909").gain(.4).room(.5).slow(4)
arrange(
  [32, stack(pad, box, hats.gain(sine.range(0,.35).slow(8)).hpf(7000))],
  [48, stack(k, clap, hats, ohh, acid)],
  [32, stack(k, clap, hats, ride, piano, acid.lpq(11).distort("1:.35"))],
  [40, stack(k, clap, hats16, rims, flauta, acid.lpq(13))],
  [40, stack(k, clap, hats16.gain(saw.range(.2,.6).slow(40)), roll, acidBuild, riser, crash)],
  [28, stack(k, clap, hats16, clave, toms, acidClimax, flautaBreak, bleep)],
  [20, stack(kOut, s("~ cp ~ ~").bank("RolandTR909").gain(saw.range(.7,0).slow(20)),
             flautaOut, acid.lpf(saw.range(2000,200).slow(20)).gain(saw.range(.9,0).slow(20)))]
)`,
  },
  {
    name: 'acid largo · azul · Am 128 (808/Linn/RhythmAce)',
    code: `// acid azul · La menor · 128 BPM · ~7:30 (hipnótico y profundo)
// intro melódico → drop → beat+kalimba → marimba pegadiza → subida → clímax → descenso
setcpm(128/4)
const acid = note("a1 [a2 a1] c2 a1 e2 a1 [g1 a1] e1").s("sawtooth")
  .lpf(sine.range(400,1800).slow(6)).lpq(12).lpenv(4).lpa(.02).lpd(.16).lps(0).distort("0.7:.35").delay(.15)
const acidBuild  = acid.lpf(saw.range(400,2800).slow(40)).lpq(14).distort("0.9:.35")
const acidClimax = acid.lpf(sine.range(600,2800).slow(2)).lpq(15).distort("1.1:.3").jux(rev)
const k    = s("bd*4").bank("RolandTR808").gain(1.1).lpf(4000)
const kOut = s("bd*4").bank("RolandTR808").lpf(4000).gain(saw.range(1,0).slow(20))
const clap   = s("~ cp ~ cp").bank("LinnDrum").gain(.8)
const hats   = s("hh*8").bank("RhythmAce").gain(".25 .4")
const hats16 = s("hh*16").bank("RhythmAce").gain(".2 .35").pan(sine.range(.35,.65).fast(2))
const ohh    = s("~ oh ~ oh").bank("KorgMinipops").gain(.35)
const ride   = s("~ ~ rd ~").bank("LinnDrum").gain(.3)
const perc   = s("perc(3,8)").bank("RhythmAce").gain(.4)
const roll   = s("sd*16").bank("LinnDrum").gain(saw.range(.05,.8).slow(40))
const toms   = s("lt mt ht lt").bank("RolandTR808").gain(.45).sometimesBy(.3, x=>x.fast(2))
const clave  = s("cp(3,8)").bank("KorgMinipops").gain(.4)
const pad    = note("<[a2,c3,e3] [f2,a2,c3] [d2,f2,a2] [e2,g2,b2]>").s("gm_pad_new_age").slow(2).gain(.5).room(.8).lpf(1400)
const vibra  = note("a5 c6 e6 a6 e6 c6 e6 c6").s("gm_vibraphone").gain(.35).delay(.4).room(.6)
const kalimba= note("<[a4 c5 e5 a5 e5 c5 e5 c5] [a4 c5 d5 e5 d5 c5 a4 c5]>").s("gm_kalimba").room(.5).delay(.3).gain(.6)
const marimba= note("<[a4 c5 d5 e5 g5 e5 d5 c5] [a4 c5 e5 g5 a5 g5 e5 d5]>").s("gm_marimba").room(.5).delay(.3).dfb(.4).gain(.6)
const marimbaBreak = note("[a4 c5 d5 e5 g5 e5 d5 c5]").s("gm_marimba").room(.5).delay(.35).gain(.6).jux(rev).every(2, x=>x.fast(2))
const marimbaOut   = note("e5 c5 a4 g4 e4 c4 a3 a2").s("gm_marimba").slow(2).room(.85).gain(saw.range(.6,0).slow(20))
const riser = note("a5").s("gm_fx_atmosphere").gain(saw.range(.1,.5).slow(40)).hpf(saw.range(400,6000).slow(40))
const bleep = note("a4 c5 e5 a5").fast(2).s("square").lpf(sine.range(800,2800).fast(2)).lpq(9).euclidLegato(5,8).gain(.38).delay(.3).room(.4)
const crash = s("cr").bank("LinnDrum").gain(.35).room(.6).slow(4)
arrange(
  [32, stack(pad, vibra, hats.gain(sine.range(0,.3).slow(8)).hpf(6500))],
  [48, stack(k, clap, hats, ohh, acid)],
  [32, stack(k, clap, hats, ride, kalimba, acid.lpq(10).distort("0.5:.35"))],
  [40, stack(k, clap, hats16, perc, marimba, acid.lpq(12))],
  [40, stack(k, clap, hats16.gain(saw.range(.15,.5).slow(40)), roll, acidBuild, riser, crash)],
  [28, stack(k, clap, hats16, clave, toms, acidClimax, marimbaBreak, bleep)],
  [20, stack(kOut, s("~ cp ~ ~").bank("LinnDrum").gain(saw.range(.65,0).slow(20)),
             marimbaOut, acid.lpf(saw.range(1800,180).slow(20)).gain(saw.range(.9,0).slow(20)))]
)`,
  },
  {
    name: 'acid largo · verde · E frigio 134 psy (707/DMX/SP12)',
    code: `// acid verde · Mi frigio (psy) · 134 BPM · ~7:10 (bajo rolling a contratiempo)
// intro melódico → drop → beat+koto → sitar pegadizo → subida → clímax → descenso
setcpm(134/4)
const acid = note("[~ e1 e1 e1] [~ e1 e1 e1] [~ c2 c2 c2] [~ d2 d2 d2]").s("sawtooth")
  .lpf(sine.range(400,2400).slow(4)).lpq(16).lpenv(5).lpa(.01).lpd(.1).lps(0).distort("1.2:.3")
const acidBuild  = acid.lpf(saw.range(400,3400).slow(40)).lpq(17).distort("1.3:.3")
const acidClimax = acid.lpf(sine.range(700,3400).slow(2)).lpq(18).distort("1.5:.25").jux(rev)
const k    = s("bd*4").bank("RolandTR707").gain(1)
const kOut = s("bd*4").bank("RolandTR707").gain(saw.range(1,0).slow(20))
const clap   = s("~ cp ~ cp").bank("OberheimDMX")
const hats   = s("hh*8").bank("EmuSP12").gain(".3 .5")
const hats16 = s("hh*16").bank("EmuSP12").gain(".25 .4").pan(sine.range(.3,.7).fast(3))
const ohh    = s("~ oh ~ oh").bank("OberheimDMX").gain(.4)
const ride   = s("~ ~ rd ~").bank("OberheimDMX").gain(.3)
const rims   = s("rim(5,8)").bank("CasioRZ1").gain(.4)
const roll   = s("sd*16").bank("OberheimDMX").gain(saw.range(.05,.9).slow(40))
const toms   = s("lt mt ht lt").bank("RolandTR707").gain(.5).sometimesBy(.3, x=>x.fast(2))
const cowbell= s("cb(5,8)").bank("CasioRZ1").gain(.4)
const pad    = note("<[e3,g3,b3] [f3,a3,c4] [g3,b3,d4] [e3,g3,b3]>").s("gm_pad_metallic").slow(2).gain(.5).room(.75).lpf(1400)
const box    = note("e5 g5 b5 e6 b5 g5 b5 g5").s("gm_music_box").gain(.4).delay(.35).room(.5)
const koto   = note("<[e4 g4 a4 b4 a4 g4 a4 g4] [e4 g4 b4 c5 b4 a4 g4 a4]>").s("gm_koto").room(.4).delay(.3).gain(.6)
const sitar  = note("<[e4 f4 g4 a4 b4 a4 g4 f4] [e4 g4 b4 c5 b4 a4 g4 e4]>").s("gm_sitar").room(.5).delay(.3).dfb(.4).gain(.6)
const sitarBreak = note("[e4 f4 g4 a4 b4 a4 g4 f4]").s("gm_sitar").room(.5).delay(.35).gain(.6).jux(rev).every(2, x=>x.fast(2))
const sitarOut   = note("b4 a4 g4 f4 e4 d4 c4 e3").s("gm_sitar").slow(2).room(.85).gain(saw.range(.6,0).slow(20))
const riser = note("e6").s("gm_fx_atmosphere").gain(saw.range(.1,.5).slow(40)).hpf(saw.range(400,6000).slow(40))
const bleep = note("e4 g4 b4 e5").fast(2).s("square").lpf(sine.range(900,3400).fast(2)).lpq(11).euclidLegato(7,16).gain(.4).delay(.25).room(.3)
const crash = s("cr").bank("OberheimDMX").gain(.4).room(.5).slow(4)
arrange(
  [32, stack(pad, box, hats.gain(sine.range(0,.35).slow(8)).hpf(7000))],
  [48, stack(k, clap, hats, ohh, acid)],
  [32, stack(k, clap, hats, ride, koto, acid.lpq(13).distort("1:.3"))],
  [40, stack(k, clap, hats16, rims, sitar, acid.lpq(14))],
  [40, stack(k, clap, hats16.gain(saw.range(.2,.6).slow(40)), roll, acidBuild, riser, crash)],
  [28, stack(k, clap, hats16, cowbell, toms, acidClimax, sitarBreak, bleep)],
  [20, stack(kOut, s("~ cp ~ ~").bank("OberheimDMX").gain(saw.range(.7,0).slow(20)),
             sitarOut, acid.lpf(saw.range(2200,180).slow(20)).gain(saw.range(.9,0).slow(20)))]
)`,
  },
];

// cada familia vive en su carpeta (la pestaña Projects las muestra plegables)
const enCarpeta = (list, folder) => list.map((p) => ({ ...p, folder }));

export const DEFAULT_PROJECTS = [
  ...enCarpeta(CLASSICS, 'bases'),
  ...enCarpeta(CONCEPTS, 'acid conceptual'),
  ...enCarpeta(DETALLE, 'detalle'),
  ...enCarpeta(ESTILOS, 'techno estilos'),
  ...enCarpeta(LARGOS, 'acid largo'),
  ...RETRO_REMIXES,
].map((p, i) => ({
  ...p,
  created_at: i + 1,
}));
