-
Notifications
You must be signed in to change notification settings - Fork 0
Authoring Themes
Felipe Lippelt edited this page May 27, 2026
·
1 revision
A theme is the skin (colors, font, banner, sound). A scenario is the campaign content. One theme can host several scenarios — see Authoring: Scenarios.
src/themes/<id>.json skin + defaultScenario
src/themes/scenarios/<theme>/<id>/ campaign
-
palette— drives the CSS variables (--bg,--fg,--accent,--muted,--error,--bg-soft). -
font— must be a font declared via@font-faceinsrc/styles/base.css. The project ships self-hosted families (see Architecture). -
crt.typeSpeed— characters per tick of the typewriter;crt.glow— phosphor blur radius. -
screensaver— the idle animation:matrix,starfield,rain,sweep,static, orbounce. -
sounds— all synthesized in-browser (no assets). Omit any to fall back to sensible defaults. -
locks— theme-wide defaults for the crack/decrypt progress bars; a file can override per-entry (see Locked Files). -
boot— lines played after the whoosh; linetype:normal·ok·err·muted.
Import it in src/themes/index.js
and add it to the THEME_LIST array. Optionally add its id to DEMO_IDS to
include it in the curated demo build.
{
"id": "meu-sistema",
"name": "Nome legível",
"header": "texto no topo da tela",
"prompt": "prefixo",
"user": "operador",
"palette": { "bg": "#000", "bgSoft": "#001a00", "fg": "#33ff33",
"accent": "#a0ffa0", "muted": "#1a661a", "error": "#ff5252" },
"font": "'3270 Nerd Font Mono'", // declarada em src/styles/base.css
"fontSize": "18px",
"crt": { "glow": "8px", "typeSpeed": 14 },
"screensaver": "starfield", // matrix | starfield | rain | sweep | static | bounce
"sounds": { // opcional — defaults sensatos se ausente
"keystroke": { "cutoff": 2200, "duration": 0.02 },
"beep": { "freq": 880, "duration": 0.06, "type": "sine" },
"whoosh": { "duration": 0.6, "freqStart": 140, "freqEnd": 1800, "tone": 0.5 }
},
"locks": { "crackDefault": 5000, "decryptDefault": 1500,
"crackLabel": "BRUTE-FORCING", "decryptLabel": "DECRYPTING" },
"banner": "ASCII art / box-drawing opcional",
"boot": [ { "text": "linha de boot", "type": "ok" } ],
"extraHelp": [ " cmd descrição extra no help" ],
"unknownHint": "fallback quando o comando não existe",
"defaultScenario": "minha-campanha"
}-
palette— alimenta as variáveis CSS (--bg,--fg,--accent,--muted,--error,--bg-soft). -
font— precisa ser uma fonte declarada via@font-faceemsrc/styles/base.css. O projeto já traz famílias self-hosted (veja Arquitetura). -
crt.typeSpeed— caracteres por tick do typewriter;crt.glow— raio de blur do fósforo. -
screensaver— a animação ociosa:matrix,starfield,rain,sweep,staticoubounce. -
sounds— tudo sintetizado no navegador (sem assets). Omita qualquer um pra usar os defaults. -
locks— defaults do tema para as barras de crack/decrypt; um arquivo pode sobrescrever por entrada (veja Arquivos Trancados). -
boot— linhas tocadas após o whoosh;typeda linha:normal·ok·err·muted.
Importe-o em src/themes/index.js
e adicione ao array THEME_LIST. Opcionalmente adicione o id em DEMO_IDS
pra incluí-lo no build de demo curado.
{ "id": "my-system", "name": "Readable name", "header": "text at the top of the screen", "prompt": "prefix", "user": "operator", "palette": { "bg": "#000", "bgSoft": "#001a00", "fg": "#33ff33", "accent": "#a0ffa0", "muted": "#1a661a", "error": "#ff5252" }, "font": "'3270 Nerd Font Mono'", // declared in src/styles/base.css "fontSize": "18px", "crt": { "glow": "8px", "typeSpeed": 14 }, "screensaver": "starfield", // matrix | starfield | rain | sweep | static | bounce "sounds": { // optional — sane defaults if absent "keystroke": { "cutoff": 2200, "duration": 0.02 }, "beep": { "freq": 880, "duration": 0.06, "type": "sine" }, "whoosh": { "duration": 0.6, "freqStart": 140, "freqEnd": 1800, "tone": 0.5 } }, "locks": { "crackDefault": 5000, "decryptDefault": 1500, "crackLabel": "BRUTE-FORCING", "decryptLabel": "DECRYPTING" }, "banner": "optional ASCII / box-drawing art", "boot": [ { "text": "boot line", "type": "ok" } ], "extraHelp": [ " cmd extra help description" ], "unknownHint": "fallback when a command doesn't exist", "defaultScenario": "my-campaign" }