Something went wrong. Try again.
A warm, tech-dystopian color scheme inspired by corrupted hardware and failing systems. digitalrust.katsuricata.com
theme color-scheme color-theme warm color
Something went wrong. Try again.
16 kB · 633 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634// SPDX-FileCopyrightText: 2025-2026 Kat Suricata <https://KatSuricata.com/>// SPDX-License-Identifier: (CC-BY-4.0+ OR Apache-2.0+)
import type { ThemeRegistration } from 'shiki';import { type ModeId, resolveRoleValue } from '#lib/palette.js';
/* * The scope to colour assignments are design decisions from the syntax spec. * The values come from the role tokens in palette.ts, so neither theme can * drift from the palette, and the two modes cannot drift from each other. */function buildTheme(mode: ModeId): ThemeRegistration { const t = (token: string) => resolveRoleValue(token, mode);
return { name: mode === 'dark' ? 'digital-rust' : 'digital-rust-safe-mode', type: mode === 'dark' ? 'dark' : 'light', colors: { 'editor.background': t('dr-surface-base'), 'editor.foreground': t('dr-text-primary'), 'editorLineNumber.foreground': t('dr-gutter-fg'), 'editorLineNumber.activeForeground': t('dr-gutter-fg-active'), 'editor.selectionBackground': t('dr-editor-selection-bg'), 'editor.inactiveSelectionBackground': t('dr-editor-selection-inactive-bg'), 'editorIndentGuide.background': t('dr-gutter-fg'), 'editorIndentGuide.activeBackground': t('dr-editor-indent-guide-active'), 'editorWhitespace.foreground': t('dr-editor-whitespace'), 'editorCursor.foreground': t('dr-cursor'), 'editor.lineHighlightBackground': t('dr-editor-line-highlight-bg'), 'editor.findMatchBackground': t('dr-editor-find-match-bg'), 'editor.findMatchBorder': t('dr-editor-find-match-border'), 'editor.findMatchHighlightBackground': t('dr-editor-find-match-highlight-bg'), 'editorBracketMatch.background': t('dr-gutter-fg'), 'editorBracketMatch.unexpectedBracketForeground': t('dr-editor-unexpected-bracket') }, tokenColors: [ // ─── Comments ─── { name: 'Comments', scope: ['comment', 'punctuation.definition.comment', 'comment.line.shebang'], settings: { foreground: t('dr-syntax-comment'), fontStyle: 'italic' } },
// ─── Keywords & Storage ─── { name: 'Keywords, Storage', scope: [ 'keyword', 'keyword.control', 'keyword.control.import', 'keyword.control.conditional', 'keyword.control.loop', 'storage.type', 'storage.modifier' ], settings: { foreground: t('dr-syntax-keyword') } },
// ─── Functions & Methods ─── { name: 'Functions', scope: ['entity.name.function', 'meta.function-call', 'support.function'], settings: { foreground: t('dr-syntax-function') } },
// ─── Classes & Types ─── { name: 'Classes, Types', scope: [ 'entity.name.type', 'entity.name.class', 'support.type', 'support.class', 'meta.type.annotation', 'entity.other.inherited-class' ], settings: { foreground: t('dr-syntax-type') } },
// ─── Strings & Text ─── { name: 'Strings', scope: [ 'string', 'punctuation.definition.string', 'string.quoted', 'string.regexp', 'constant.other.character-class.regexp', 'constant.character.escape' ], settings: { foreground: t('dr-syntax-string') } },
// ─── Numbers ─── { name: 'Numbers', scope: ['constant.numeric'], settings: { foreground: t('dr-syntax-number') } },
// ─── Constants & Special Values ─── { name: 'Constants, Booleans, Null, Special Values', scope: [ 'constant.language.boolean', 'constant.language.null', 'constant.language', 'constant.language.nan', 'constant.language.infinity', 'variable.language.this', 'variable.language.super', 'variable.language.self', 'variable.other.constant', 'constant.other.constant', 'variable.other.enummember', 'entity.name.constant' ], settings: { foreground: t('dr-syntax-constant') } },
// ─── Attributes & Decorators ─── { name: 'Attributes, Decorators', scope: [ 'meta.decorator', 'entity.name.function.decorator', 'meta.attribute', 'punctuation.definition.annotation', 'punctuation.decorator' ], settings: { foreground: t('dr-syntax-type'), fontStyle: 'italic' } },
// ─── Built-ins & Standard Library ─── { name: 'Built-ins', scope: [ 'support.function', 'support.class', 'support.type', 'support.constant', 'support.variable' ], settings: { foreground: t('dr-syntax-builtin') } },
// ─── Variables & Identifiers ─── { name: 'Variables', scope: [ 'variable', 'variable.parameter', 'variable.other', 'variable.other.readwrite' ], settings: { foreground: t('dr-text-primary') } },
// ─── Operators & Punctuation ─── { name: 'Operators, Punctuation', scope: [ 'keyword.operator', 'punctuation.separator', 'punctuation.terminator', 'punctuation.accessor', 'punctuation.definition.parameters', 'punctuation.definition.array', 'punctuation.definition.dictionary', 'punctuation.section.block', 'punctuation.definition.generic', 'punctuation.definition.typeparameters', 'keyword.operator.regex', 'meta.brace' ], settings: { foreground: t('dr-syntax-punctuation') } },
// ─── Markup Tags (HTML/XML) ─── { name: 'Markup Tags', scope: ['entity.name.tag', 'meta.tag', 'meta.tag.sgml'], settings: { foreground: t('dr-syntax-type') } },
// ─── Markup Attributes ─── { name: 'Markup Attributes', scope: ['entity.other.attribute-name'], settings: { foreground: t('dr-syntax-builtin') } },
// ─── Errors ─── // Raw Amber Alert fails AA on dark surfaces. The text variant passes. { name: 'Errors', scope: ['invalid', 'invalid.illegal', 'invalid.deprecated'], settings: { foreground: t('dr-syntax-error') } },
// ─── Configuration Languages (JSON/YAML/TOML) ─── { name: 'JSON/YAML/TOML Keys', scope: [ 'support.type.property-name.json', 'entity.name.tag.yaml', 'support.type.property-name.toml', 'keyword.other.definition' ], settings: { foreground: t('dr-syntax-type') } },
// ─── CSS ─── { name: 'CSS Properties', scope: [ 'support.type.property-name.css', 'support.type.vendored.property-name.css' ], settings: { foreground: t('dr-syntax-builtin') } }, { name: 'CSS Classes/IDs', scope: [ 'entity.other.attribute-name.class.css', 'entity.other.attribute-name.id.css' ], settings: { foreground: t('dr-syntax-type') } }, { name: 'CSS Pseudo-classes/Elements', scope: [ 'entity.other.attribute-name.pseudo-class.css', 'entity.other.attribute-name.pseudo-element.css' ], settings: { foreground: t('dr-syntax-builtin') } }, { name: 'CSS At-rules', scope: [ 'keyword.control.at-rule.css', 'keyword.control.at-rule.import.css', 'keyword.control.at-rule.media.css', 'keyword.control.at-rule.keyframes.css', 'meta.at-rule' ], settings: { foreground: t('dr-syntax-keyword') } }, { name: 'CSS Keywords (auto, inherit, etc.)', scope: ['support.constant.property-value.css'], settings: { foreground: t('dr-syntax-constant') } },
// ─── Markdown ─── { name: 'Markdown Headings', scope: [ 'markup.heading', 'entity.name.section.markdown', 'punctuation.definition.heading.markdown' ], settings: { foreground: t('dr-syntax-keyword'), fontStyle: 'bold' } }, { name: 'Markdown Emphasis (bold)', scope: ['markup.bold.markdown'], settings: { foreground: t('dr-text-primary'), fontStyle: 'bold' } }, { name: 'Markdown Emphasis (italic)', scope: ['markup.italic.markdown'], settings: { foreground: t('dr-text-primary'), fontStyle: 'italic' } }, { name: 'Markdown Code', scope: [ 'markup.inline.raw', 'markup.raw.inline', 'markup.fenced_code', 'punctuation.definition.raw.markdown' ], settings: { foreground: t('dr-syntax-string'), background: t('bad-sector-20') } }, { name: 'Markdown Blockquotes', scope: ['markup.quote'], settings: { foreground: t('dr-text-secondary'), fontStyle: 'italic' } }, { name: 'Markdown Links', scope: [ 'markup.underline.link', 'string.other.link.title.markdown', 'constant.other.reference.link.markdown' ], settings: { foreground: t('dr-text-link'), fontStyle: 'underline' } }, { name: 'Markdown Link URLs', scope: [ 'markup.underline.link.markdown', 'meta.link.reference.markdown', 'meta.link.inline.markdown' ], settings: { foreground: t('dr-syntax-builtin') } }, { name: 'Markdown List Markers', scope: [ 'punctuation.definition.list.begin.markdown', 'punctuation.definition.list_item.markdown' ], settings: { foreground: t('dr-syntax-punctuation') } }, { name: 'Markdown Horizontal Rule', scope: ['meta.separator.markdown'], settings: { foreground: t('dr-border-color') } },
// ─── Diff / Git ─── { name: 'Diff Header (hunk)', scope: ['meta.diff.header', 'meta.diff.range.unified'], settings: { foreground: t('dr-syntax-blue') } }, { name: 'Diff Commit Hashes', scope: ['constant.other.hash.diff'], settings: { foreground: t('dr-syntax-builtin') } }, { name: 'Diff File Paths / Metadata', scope: [ 'meta.diff.header.from-file', 'meta.diff.header.to-file', 'entity.name.file.diff', 'meta.diff.index' ], settings: { foreground: t('dr-syntax-function') } }, { name: 'Diff Inserted (+ marker)', scope: ['punctuation.definition.inserted.diff', 'punctuation.definition.plus.diff'], settings: { foreground: t('dr-syntax-string') } }, { name: 'Diff Deleted (- marker)', scope: ['punctuation.definition.deleted.diff', 'punctuation.definition.minus.diff'], settings: { foreground: t('dr-danger') } }, { name: 'Diff Modified (~ marker)', scope: ['punctuation.definition.changed.diff', 'punctuation.definition.tilde.diff'], settings: { foreground: t('dr-syntax-type') } }, { name: 'Diff Added Lines', scope: ['markup.inserted', 'meta.diff.line.inserted', 'diff.inserted'], settings: { foreground: t('dr-text-primary'), background: t('memory-leek-15') } }, { name: 'Diff Deleted Lines', scope: ['markup.deleted', 'meta.diff.line.deleted', 'diff.deleted'], settings: { foreground: t('dr-text-quiet'), background: t('amber-alert-15') } }, { name: 'Diff Modified Lines', scope: ['markup.changed', 'meta.diff.line.changed', 'diff.changed'], settings: { foreground: t('dr-text-primary'), background: t('dead-thread-10') } },
// ─── Shell / CLI ─── { name: 'Shell Shebang & Comments', scope: [ 'comment.line.number-sign.shell', 'comment.line.fish', 'comment.line.double-slash' ], settings: { foreground: t('dr-syntax-comment'), fontStyle: 'italic' } }, { name: 'Shell Commands', scope: ['entity.name.command.shell', 'support.function.builtin.shell'], settings: { foreground: t('dr-syntax-function') } }, { name: 'Shell Flags & Options', scope: [ 'keyword.operator.option.shell', 'entity.other.option.shell', 'string.unquoted.argument.shell' ], settings: { foreground: t('dr-syntax-keyword') } },
// ─── SQL ─── { name: 'SQL Functions', scope: ['support.function.aggregate.sql', 'support.function.sql'], settings: { foreground: t('dr-syntax-function') } }, { name: 'SQL Types', scope: ['support.type.sql', 'storage.type.sql'], settings: { foreground: t('dr-syntax-type') } },
// ─── Rust-Specific ─── { name: 'Rust Lifetimes', scope: ['entity.name.lifetime.rust', 'punctuation.definition.lifetime.rust'], settings: { foreground: t('dr-syntax-type'), fontStyle: 'italic' } }, { name: 'Rust Macros', scope: ['entity.name.function.macro.rust', 'meta.macro.rust'], settings: { foreground: t('dr-syntax-function') } }, { name: 'Rust Attributes', scope: ['meta.attribute.rust', 'punctuation.definition.attribute.rust'], settings: { foreground: t('dr-syntax-type'), fontStyle: 'italic' } },
// ─── C/C++ Preprocessor ─── { name: 'Preprocessor Directives', scope: [ 'keyword.control.import.include', 'keyword.control.preprocessor', 'meta.preprocessor', 'keyword.control.preprocessor.define', 'keyword.control.preprocessor.if', 'keyword.control.preprocessor.elif', 'keyword.control.preprocessor.else', 'keyword.control.preprocessor.endif', 'keyword.control.preprocessor.include', 'keyword.control.preprocessor.import', 'keyword.control.preprocessor.undef', 'keyword.control.preprocessor.error', 'keyword.control.preprocessor.warning', 'keyword.control.preprocessor.pragma' ], settings: { foreground: t('dr-syntax-keyword') } }, { name: 'Preprocessor Macro Names', scope: ['entity.name.function.preprocessor', 'entity.name.constant.preprocessor'], settings: { foreground: t('dr-syntax-constant') } }, { name: 'Preprocessor Include Paths', scope: [ 'string.quoted.double.include.c', 'string.quoted.other.lt-gt.include.c', 'string.include' ], settings: { foreground: t('dr-syntax-string') } },
// ─── String Interpolation Delimiters ─── { name: 'Interpolation Delimiters', scope: [ 'punctuation.definition.template-expression', 'punctuation.section.embedded', 'meta.template.expression' ], settings: { foreground: t('dr-syntax-punctuation') } },
// ─── Haskell / ML / Functional ─── { name: 'Type Constructors (Haskell/ML)', scope: ['constant.other.capitalized-type.haskell', 'entity.name.type.data.haskell'], settings: { foreground: t('dr-syntax-type') } }, { name: 'Data Constructors (Haskell/ML)', scope: [ 'constant.other.capitalized-constructor.haskell', 'entity.name.function.constructor.haskell' ], settings: { foreground: t('dr-syntax-constant') } }, { name: 'Type Variables (Haskell/ML)', scope: ['variable.other.generic-type.haskell', 'variable.other.type.haskell'], settings: { foreground: t('dr-syntax-type'), fontStyle: 'italic' } }, { name: 'Functional Arrows (::, =>, ->)', scope: [ 'keyword.other.double-colon.haskell', 'keyword.other.fat-arrow.haskell', 'keyword.other.arrow.haskell', 'keyword.operator.type-annotation', 'keyword.operator.arrow' ], settings: { foreground: t('dr-syntax-punctuation') } } ] };}
export const digitalRustTheme = buildTheme('dark');export const digitalRustLightTheme = buildTheme('safe-mode');