VS Code Color Theme

Forró

Theme

Warm collective memory translated into code, with Black northeastern roots, dance halls, migrant routes and intergenerational scenes carried across dark & light variants.

WCAG 2.1 AA 10 Variants 884 Tests OKLCH

See it in action

Real syntax highlighting rendered from the actual theme files, with samples rooted in scenes, dancers, songs and communities that keep forró moving.

from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}
from dataclasses import dataclass, field
from enum import Enum
from typing import Callable


class Ritmo(Enum):
    BAIAO = [0, 2, 4, 6]
    XOTE = [0, 3, 6, 9]
    COCO = [0, 2, 3, 5]
    XAXADO = [0, 2, 5, 7]


@dataclass
class ArtistaForro:
    """Uma voz do forró entre rádio, salão e estrada."""
    nome: str
    cidade: str
    funcao: str
    geracao: str
    repertorio: list[str] = field(default_factory=list)

    def puxar_roda(self, ritmo: Ritmo = Ritmo.XOTE, bpm: int = 126) -> Callable[[], list[str]]:
        passos = ritmo.value

        def levada() -> list[str]:
            return [f"{self.nome}:{bpm + passo}" for passo in passos]

        return levada

    def adicionar_cancao(self, titulo: str, ano: int) -> None:
        self.repertorio.append(f"{titulo} ({ano})")
        print(f"♪ {self.nome} compartilha: {titulo}")


def abrir_roda(participantes: list[str]) -> None:
    pares = zip(participantes[::2], participantes[1::2])
    for esquerda, direita in pares:
        print(f"{esquerda} dança com {direita}")


# Different generations, regions and voices of forró.
artistas = {
    "Marinês": ArtistaForro("Marinês", "Campina Grande", "cantora", "pioneira"),
    "Anastácia": ArtistaForro("Anastácia", "Recife", "compositora", "legado"),
    "Dominguinhos": ArtistaForro("Dominguinhos", "Garanhuns", "sanfona", "ponte"),
    "Lucy Alves": ArtistaForro("Lucy Alves", "João Pessoa", "multi-instrumentista", "contemporânea"),
}

for artista in artistas.values():
    ritmo = Ritmo.BAIAO if artista.nome == "Dominguinhos" else Ritmo.XOTE
    print(artista.puxar_roda(ritmo, bpm=132)())

circuito = ["Recife", "Caruaru", "João Pessoa", "São Paulo"]
print(" -> ".join(circuito))
abrir_roda(["Lia", "Beto", "Cris", "Duda"])
class Triangulo {
  #cenas = new Map();
  #bpm;

  constructor(afinacao = 440) {
    this.afinacao = afinacao;
    this.#bpm = 120;
  }

  static fromArtista(nome) {
    // Forró evolves through communities, dance halls, radios and migrants.
    const estilos = {
      Marinês: { bpm: 132, swing: 0.64 },
      Anastácia: { bpm: 126, swing: 0.61 },
      Mestrinho: { bpm: 142, swing: 0.57 },
      'Lucy Alves': { bpm: 136, swing: 0.69 },
    };
    const config = estilos[nome] ?? { bpm: 128, swing: 0.6 };
    const tri = new Triangulo();
    tri.#bpm = config.bpm;
    tri.#cenas.set(nome, config);
    return tri;
  }

  marcar(compasso, subdivisao = 4) {
    const intervalo = 60_000 / (this.#bpm * subdivisao);
    const notas = Array.from({ length: compasso * subdivisao }, (_, i) => ({
      tempo: i * intervalo,
      acento: i % subdivisao === 0,
    }));
    return notas.filter((n) => n.acento);
  }

  abrirPista(casais) {
    return casais.filter(({ energia }) => energia > 0.7);
  }

  get tocando() {
    return this.#bpm > 0;
  }
}

// Forró is built collectively: triangle, zabumba, accordion and dance.
const zabumba = { grave: 'TUM', agudo: 'TÁ', ghost: '.' };
const triangulo = Triangulo.fromArtista('Lucy Alves');

const primeiraLevada = triangulo.marcar(4);
const casais = [
  { nomes: ['Lia', 'João'], cidade: 'Recife', energia: 0.82 },
  { nomes: ['Cris', 'Beto'], cidade: 'São Paulo', energia: 0.68 },
  { nomes: ['Duda', 'Nina'], cidade: 'Campina Grande', energia: 0.91 },
];
const circuito = ['Recife', 'Caruaru', 'São Paulo'];
const encontros = ['salão', 'festa junina', 'forró universitário'];
const pista = triangulo.abrirPista(casais);

console.log('Salão em movimento:', primeiraLevada, zabumba, pista.length);
console.log('Circuito migrante:', circuito.join(' -> '));
console.log('Encontros:', encontros.join(', '));

const generos = ['xote', 'baião', 'arrasta-pé', 'coco', 'xaxado'];
for (const genero of generos) {
  console.log(`♫ ${genero}: ${triangulo.afinacao}Hz`);
}
#include <array>
#include <iostream>
#include <string>
#include <vector>

struct Encontro {
    std::string titulo;
    std::string artista;
    std::string cidade;
    int casais;

    double giros_por_minuto(double bpm) const {
        return casais > 0 ? bpm / (casais / 2.0) : bpm;
    }

    friend std::ostream& operator<<(std::ostream& os, const Encontro& e) {
        return os << e.titulo << " - " << e.artista << " em " << e.cidade
                  << " (" << e.casais << " casais)";
    }
};

class CenaForro {
    std::string nome_;
    std::vector<int> pulsos_;
    double bpm_;

public:
    static constexpr std::array<int, 4> XOTE = {0, 3, 6, 9};

    explicit CenaForro(std::string nome, double bpm = 126.0)
        : nome_(nome)
        , pulsos_(XOTE.begin(), XOTE.end())
        , bpm_(bpm) {}

    Encontro abrir_salao(
        const std::string& titulo,
        const std::string& artista,
        const std::string& cidade,
        int casais
    ) const {
        return {titulo, artista, cidade, casais};
    }

    void imprimir_pulso() const {
        std::cout << "♪ " << nome_ << "\n";
        for (size_t i = 0; i < pulsos_.size(); ++i) {
            std::cout << "  pulso " << i << ": " << pulsos_[i] + bpm_ / 60.0 << "\n";
        }
    }
};

int main() {
    // Rhythms and melodies carried across generations.
    CenaForro eu_so_quero_um_xodo("Eu Só Quero um Xodó", 126.0);
    CenaForro feira_de_mangaio("Feira de Mangaio", 132.0);

    eu_so_quero_um_xodo.imprimir_pulso();
    feira_de_mangaio.imprimir_pulso();

    auto salao = feira_de_mangaio.abrir_salao(
        "Feira de Mangaio",
        "Anastácia, Lucy Alves e Juliana Linhares",
        "São Paulo",
        24
    );
    std::cout << "Pista em movimento: " << salao << "\n";
    std::cout << "Giros por minuto: " << salao.giros_por_minuto(132.0) << "\n";
    return 0;
}

Five variants, shared pulse

Each variant carries a different atmosphere — quiet rehearsal rooms, crowded dance floors, radios on the road and the calm after the party.

Forró Roots Grounded terracotta and forest tones for a shared, steady pulse
Forró Íntimo Softer, quieter hues for late sets, study sessions and after-hours flow
Forró Nordeste Vivo Bright accents tuned to radios, festas and busy dance floors
Forró Pé de Serra Wood, leather and percussion warmth for close-room movement
Forró PD Cool greens and blues for contemporary stages and city nights

Crafted with care

Accessibility

WCAG 2.1 AA Compliant

Every token meets contrast minimums — 4.5:1 for primary tokens, 3:1 for de-emphasised elements. Verified by 884 automated tests.

Color Science

OKLCH Perceptual Space

Contrast fixes are computed in OKLCH, adjusting only lightness to preserve the original hue and chroma of each color.

Quality

Tested on Every Commit

Pre-commit hooks run the full contrast test suite automatically. No regressions ship to the marketplace.

Culture

A Living Tradition

The showcase samples move through pioneers, women bandleaders, contemporary voices, migrant dance floors and collective gatherings instead of a single fixed canon.

Get started

Install from the Visual Studio Code Marketplace

Install Extension ext install yerko-escalona.forro-theme