Merge pull request #1295 from daslyfe/jade/uwu2000

feat: Theme improvements
This commit is contained in:
Jade (Rose) Rowland 2025-03-02 11:08:31 -05:00 committed by GitHub
commit 530339ed8f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
23 changed files with 177 additions and 72 deletions

View File

@ -67,6 +67,7 @@ export function initEditor({ initialCode = '', onChange, onEvaluate, onStop, roo
const initialSettings = Object.keys(compartments).map((key) => const initialSettings = Object.keys(compartments).map((key) =>
compartments[key].of(extensions[key](parseBooleans(settings[key]))), compartments[key].of(extensions[key](parseBooleans(settings[key]))),
); );
initTheme(settings.theme); initTheme(settings.theme);
let state = EditorState.create({ let state = EditorState.create({
doc: initialCode, doc: initialCode,

View File

@ -4,6 +4,7 @@ import blackscreen, { settings as blackscreenSettings } from './themes/blackscre
import whitescreen, { settings as whitescreenSettings } from './themes/whitescreen.mjs'; import whitescreen, { settings as whitescreenSettings } from './themes/whitescreen.mjs';
import teletext, { settings as teletextSettings } from './themes/teletext.mjs'; import teletext, { settings as teletextSettings } from './themes/teletext.mjs';
import algoboy, { settings as algoboySettings } from './themes/algoboy.mjs'; import algoboy, { settings as algoboySettings } from './themes/algoboy.mjs';
import CutiePi, { settings as CutiePiSettings } from './themes/CutiePi.mjs';
import terminal, { settings as terminalSettings } from './themes/terminal.mjs'; import terminal, { settings as terminalSettings } from './themes/terminal.mjs';
import abcdef, { settings as abcdefSettings } from './themes/abcdef.mjs'; import abcdef, { settings as abcdefSettings } from './themes/abcdef.mjs';
import androidstudio, { settings as androidstudioSettings } from './themes/androidstudio.mjs'; import androidstudio, { settings as androidstudioSettings } from './themes/androidstudio.mjs';
@ -55,6 +56,7 @@ export const themes = {
androidstudio, androidstudio,
duotoneDark, duotoneDark,
githubDark, githubDark,
CutiePi,
gruvboxDark, gruvboxDark,
materialDark, materialDark,
nord, nord,
@ -98,6 +100,7 @@ export const settings = {
duotoneLight: duotoneLightSettings, duotoneLight: duotoneLightSettings,
duotoneDark: duotoneDarkSettings, duotoneDark: duotoneDarkSettings,
eclipse: eclipseSettings, eclipse: eclipseSettings,
CutiePi: CutiePiSettings,
githubLight: githubLightSettings, githubLight: githubLightSettings,
githubDark: githubDarkSettings, githubDark: githubDarkSettings,
gruvboxDark: gruvboxDarkSettings, gruvboxDark: gruvboxDarkSettings,

45
packages/codemirror/themes/CutiePi.mjs vendored Normal file
View File

@ -0,0 +1,45 @@
/**
* @name Cutie Pi
* by Switch Angel
*/
import { tags as t } from '@lezer/highlight';
import { createTheme } from './theme-helper.mjs';
const deepPurple = '#5c019a';
const yellowPink = '#fbeffc';
const grey = '#272C35';
const pinkAccent = '#fee1ff';
const lightGrey = '#465063';
const bratGreen = '#9acd3f';
const lighterGrey = '#97a1b7';
const pink = '#f6a6fd';
export const settings = {
background: 'white',
lineBackground: 'transparent',
foreground: deepPurple,
caret: '#797977',
selection: yellowPink,
selectionMatch: '#2B323D',
gutterBackground: grey,
gutterForeground: lightGrey,
gutterBorder: 'transparent',
lineHighlight: pinkAccent,
};
export default createTheme({
theme: 'light',
settings,
styles: [
{
tag: [t.function(t.variableName), t.function(t.propertyName), t.url, t.processingInstruction],
color: deepPurple,
},
{ tag: [t.tagName, t.heading], color: settings.foreground },
{ tag: t.comment, color: lighterGrey },
{ tag: [t.variableName, t.propertyName, t.labelName], color: pink },
{ tag: [t.attributeName, t.number], color: '#d19a66' },
{ tag: t.className, color: grey },
{ tag: t.keyword, color: deepPurple },
{ tag: [t.string, t.regexp, t.special(t.propertyName)], color: bratGreen },
],
});

View File

@ -5,7 +5,7 @@
"module": "tidal.mjs", "module": "tidal.mjs",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/felixroos/hs2js.git" "url": "git+https://github.com/tidalcycles/strudel/tree/main/packages/tidal"
}, },
"keywords": [ "keywords": [
"haskell", "haskell",

Binary file not shown.

View File

@ -0,0 +1,7 @@
100% free for personal and commercial use.
However it's limited on basic latin only,
contact riedjal@gmail.com for full glyph (based on ANSI encoding)
and OTF features (alternates).
src: https://www.dafont.com/cute-aurora.font?text=%24%3A+s%28%22bd%285%2C8%29%22%29.superimpose%28x+%3D%3E+x.note%28%22c2%22%29.midi%28device%29%29

View File

@ -9,11 +9,11 @@ import UserFacingErrorMessage from '@src/repl/components/UserFacingErrorMessage'
// } // }
export default function UdelsEditor(Props) { export default function UdelsEditor(Props) {
const { context } = Props; const { context, ...editorProps } = Props;
const { containerRef, editorRef, error, init, pending, started, handleTogglePlay } = context; const { containerRef, editorRef, error, init, pending, started, handleTogglePlay } = context;
return ( return (
<div className={'h-full flex w-full flex-col relative'}> <div className={'h-full flex w-full flex-col relative'} {...editorProps}>
<Loader active={pending} /> <Loader active={pending} />
<BigPlayButton started={started} handleTogglePlay={handleTogglePlay} /> <BigPlayButton started={started} handleTogglePlay={handleTogglePlay} />
<div className="grow flex relative overflow-hidden"> <div className="grow flex relative overflow-hidden">

View File

@ -4,7 +4,7 @@ export default function UdelsHeader(Props) {
const { numWindows, setNumWindows } = Props; const { numWindows, setNumWindows } = Props;
return ( return (
<header id="header" className="flex text-white z-[100] text-lg select-none bg-neutral-900"> <header id="header" className="flex text-white z-[100] text-lg select-none bg-neutral-800">
<div className="px-4 items-center gap-2 flex space-x-2 md:pt-0 select-none"> <div className="px-4 items-center gap-2 flex space-x-2 md:pt-0 select-none">
<h1 onClick={() => {}} className={'text-l cursor-pointer flex gap-4'}> <h1 onClick={() => {}} className={'text-l cursor-pointer flex gap-4'}>
<div className={'mt-[1px] cursor-pointer'}>🌀</div> <div className={'mt-[1px] cursor-pointer'}>🌀</div>

View File

@ -9,10 +9,12 @@ import UdelsEditor from '@components/Udels/UdelsEditor';
import ReplEditor from './components/ReplEditor'; import ReplEditor from './components/ReplEditor';
import EmbeddedReplEditor from './components/EmbeddedReplEditor'; import EmbeddedReplEditor from './components/EmbeddedReplEditor';
import { useReplContext } from './useReplContext'; import { useReplContext } from './useReplContext';
import { useSettings } from '@src/settings.mjs';
export function Repl({ embedded = false }) { export function Repl({ embedded = false }) {
const isEmbedded = embedded || isIframe(); const isEmbedded = embedded || isIframe();
const Editor = isUdels() ? UdelsEditor : isEmbedded ? EmbeddedReplEditor : ReplEditor; const Editor = isUdels() ? UdelsEditor : isEmbedded ? EmbeddedReplEditor : ReplEditor;
const context = useReplContext(); const context = useReplContext();
return <Editor context={context} />; const { fontFamily } = useSettings();
return <Editor context={context} style={{ fontFamily }} />;
} }

View File

@ -9,10 +9,10 @@ import { Header } from './Header';
// } // }
export default function EmbeddedReplEditor(Props) { export default function EmbeddedReplEditor(Props) {
const { context } = Props; const { context, ...editorProps } = Props;
const { pending, started, handleTogglePlay, containerRef, editorRef, error, init } = context; const { pending, started, handleTogglePlay, containerRef, editorRef, error, init } = context;
return ( return (
<div className="h-full flex flex-col relative"> <div className="h-full flex flex-col relative" {...editorProps}>
<Loader active={pending} /> <Loader active={pending} />
<Header context={context} embedded={true} /> <Header context={context} embedded={true} />
<BigPlayButton started={started} handleTogglePlay={handleTogglePlay} /> <BigPlayButton started={started} handleTogglePlay={handleTogglePlay} />

View File

@ -11,7 +11,7 @@ export function Header({ context, embedded = false }) {
const { started, pending, isDirty, activeCode, handleTogglePlay, handleEvaluate, handleShuffle, handleShare } = const { started, pending, isDirty, activeCode, handleTogglePlay, handleEvaluate, handleShuffle, handleShare } =
context; context;
const isEmbedded = typeof window !== 'undefined' && (embedded || window.location !== window.parent.location); const isEmbedded = typeof window !== 'undefined' && (embedded || window.location !== window.parent.location);
const { isZen, isButtonRowHidden, isCSSAnimationDisabled } = useSettings(); const { isZen, isButtonRowHidden, isCSSAnimationDisabled, fontFamily } = useSettings();
return ( return (
<header <header
@ -22,6 +22,7 @@ export function Header({ context, embedded = false }) {
isZen ? 'h-12 w-8 fixed top-0 left-0' : 'sticky top-0 w-full py-1 justify-between', isZen ? 'h-12 w-8 fixed top-0 left-0' : 'sticky top-0 w-full py-1 justify-between',
isEmbedded ? 'flex' : 'md:flex', isEmbedded ? 'flex' : 'md:flex',
)} )}
style={{ fontFamily }}
> >
<div className="px-4 flex space-x-2 md:pt-0 select-none"> <div className="px-4 flex space-x-2 md:pt-0 select-none">
<h1 <h1
@ -46,7 +47,7 @@ export function Header({ context, embedded = false }) {
} }
}} }}
> >
<span className="block rotate-90"></span> <span className="block text-foreground rotate-90"></span>
</div> </div>
{!isZen && ( {!isZen && (
<div className="space-x-2"> <div className="space-x-2">

View File

@ -10,13 +10,13 @@ import { useSettings } from '@src/settings.mjs';
// } // }
export default function ReplEditor(Props) { export default function ReplEditor(Props) {
const { context } = Props; const { context, ...editorProps } = Props;
const { containerRef, editorRef, error, init, pending } = context; const { containerRef, editorRef, error, init, pending } = context;
const settings = useSettings(); const settings = useSettings();
const { panelPosition, isZen } = settings; const { panelPosition, isZen } = settings;
return ( return (
<div className="h-full flex flex-col relative"> <div className="h-full flex flex-col relative" {...editorProps}>
<Loader active={pending} /> <Loader active={pending} />
<Header context={context} /> <Header context={context} />
<div className="grow flex relative overflow-hidden"> <div className="grow flex relative overflow-hidden">

View File

@ -6,7 +6,7 @@ function IncButton({ children, className, ...buttonProps }) {
<button <button
tabIndex={-1} tabIndex={-1}
className={cx( className={cx(
'border border-transparent p-1 text-center text-sm transition-all hover:bg-foreground active:bg-lineBackground disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none', 'border border-transparent p-1 text-center hover:text-background text-sm transition-all hover:bg-foreground active:bg-lineBackground disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none',
className, className,
)} )}
type="button" type="button"

View File

@ -1,53 +1,32 @@
import { logger } from '@strudel/core';
import useEvent from '@src/useEvent.mjs';
import cx from '@src/cx.mjs'; import cx from '@src/cx.mjs';
import { nanoid } from 'nanoid';
import { useCallback, useState } from 'react';
import { useSettings } from '../../../settings.mjs'; import { useSettings } from '../../../settings.mjs';
import { useStore } from '@nanostores/react';
import { $strudel_log_history } from '../useLogger';
export function ConsoleTab() { export function ConsoleTab() {
const [log, setLog] = useState([]); const log = useStore($strudel_log_history);
const { fontFamily, fontSize } = useSettings(); const { fontFamily } = useSettings();
useLogger(
useCallback((e) => {
const { message, type, data } = e.detail;
setLog((l) => {
const lastLog = l.length ? l[l.length - 1] : undefined;
const id = nanoid(12);
// if (type === 'loaded-sample' && lastLog.type === 'load-sample' && lastLog.url === data.url) {
if (type === 'loaded-sample') {
// const loadIndex = l.length - 1;
const loadIndex = l.findIndex(({ data: { url }, type }) => type === 'load-sample' && url === data.url);
l[loadIndex] = { message, type, id, data };
} else if (lastLog && lastLog.message === message) {
l = l.slice(0, -1).concat([{ message, type, count: (lastLog.count ?? 1) + 1, id, data }]);
} else {
l = l.concat([{ message, type, id, data }]);
}
return l.slice(-20);
});
}, []),
);
return ( return (
<div <div id="console-tab" className="break-all w-full first-line:text-sm p-2 h-full" style={{ fontFamily }}>
id="console-tab" <div className="bg-background h-full w-full overflow-auto space-y-1 p-2 rounded-md">
className="break-all px-4 dark:text-white text-stone-900 text-sm py-2 space-y-1" {log.map((l, i) => {
style={{ fontFamily, fontSize }} const message = linkify(l.message);
> const color = l.data?.hap?.value?.color;
{log.map((l, i) => { return (
const message = linkify(l.message); <div
const color = l.data?.hap?.value?.color; key={l.id}
return ( className={cx(
<div l.type === 'error' ? 'text-background bg-foreground' : 'text-foreground',
key={l.id} l.type === 'highlight' && 'underline',
className={cx(l.type === 'error' && 'text-red-500', l.type === 'highlight' && 'underline')} )}
style={color ? { color } : {}} style={color ? { color } : {}}
> >
<span dangerouslySetInnerHTML={{ __html: message }} /> <span dangerouslySetInnerHTML={{ __html: message }} />
{l.count ? ` (${l.count})` : ''} {l.count ? ` (${l.count})` : ''}
</div> </div>
); );
})} })}
</div>
</div> </div>
); );
} }
@ -72,7 +51,3 @@ function linkify(inputText) {
return replacedText; return replacedText;
} }
function useLogger(onTrigger) {
useEvent(logger.key, onTrigger);
}

View File

@ -5,6 +5,7 @@ import { FilesTab } from './FilesTab';
import { Reference } from './Reference'; import { Reference } from './Reference';
import { SettingsTab } from './SettingsTab'; import { SettingsTab } from './SettingsTab';
import { SoundsTab } from './SoundsTab'; import { SoundsTab } from './SoundsTab';
import { useLogger } from '../useLogger';
import { WelcomeTab } from './WelcomeTab'; import { WelcomeTab } from './WelcomeTab';
import { PatternsTab } from './PatternsTab'; import { PatternsTab } from './PatternsTab';
import { ChevronLeftIcon, XMarkIcon } from '@heroicons/react/16/solid'; import { ChevronLeftIcon, XMarkIcon } from '@heroicons/react/16/solid';
@ -115,6 +116,7 @@ function PanelNav({ children, className, settings, ...props }) {
} }
function PanelContent({ context, tab }) { function PanelContent({ context, tab }) {
useLogger();
switch (tab) { switch (tab) {
case tabNames.patterns: case tabNames.patterns:
return <PatternsTab context={context} />; return <PatternsTab context={context} />;

View File

@ -56,8 +56,8 @@ function PatternButtons({ patterns, activePattern, onClick, started }) {
const viewingPatternData = parseJSON(viewingPatternStore); const viewingPatternData = parseJSON(viewingPatternStore);
const viewingPatternID = viewingPatternData.id; const viewingPatternID = viewingPatternData.id;
return ( return (
<div className="font-mono text-sm"> <div className="">
{Object.values(patterns ?? {}) {Object.values(patterns)
.reverse() .reverse()
.map((pattern) => { .map((pattern) => {
const id = pattern.id; const id = pattern.id;

View File

@ -26,7 +26,7 @@ export function Reference() {
}, [search]); }, [search]);
return ( return (
<div className="flex h-full w-full p-2 text-foreground overflow-hidden"> <div className="flex h-full w-full p-2 overflow-hidden">
<div className="h-full flex flex-col gap-2 w-1/3 max-w-72 "> <div className="h-full flex flex-col gap-2 w-1/3 max-w-72 ">
<div class="w-full flex"> <div class="w-full flex">
<Textbox className="w-full" placeholder="Search" value={search} onChange={setSearch} /> <Textbox className="w-full" placeholder="Search" value={search} onChange={setSearch} />
@ -35,7 +35,7 @@ export function Reference() {
{visibleFunctions.map((entry, i) => ( {visibleFunctions.map((entry, i) => (
<a <a
key={i} key={i}
className="cursor-pointer flex-none hover:bg-lineHighlight overflow-x-hidden px-1 text-ellipsis" className="cursor-pointer text-foreground flex-none hover:bg-lineHighlight overflow-x-hidden px-1 text-ellipsis"
onClick={() => { onClick={() => {
const el = document.getElementById(`doc-${i}`); const el = document.getElementById(`doc-${i}`);
const container = document.getElementById('reference-container'); const container = document.getElementById('reference-container');
@ -75,7 +75,9 @@ export function Reference() {
))} ))}
</ul> </ul>
{entry.examples?.map((example, j) => ( {entry.examples?.map((example, j) => (
<pre key={j}>{example}</pre> <pre className="bg-background" key={j}>
{example}
</pre>
))} ))}
</section> </section>
))} ))}

View File

@ -66,6 +66,7 @@ const themeOptions = Object.fromEntries(Object.keys(themes).map((k) => [k, k]));
const fontFamilyOptions = { const fontFamilyOptions = {
monospace: 'monospace', monospace: 'monospace',
Courier: 'Courier', Courier: 'Courier',
CutiePi: 'CutiePi',
JetBrains: 'JetBrains', JetBrains: 'JetBrains',
Hack: 'Hack', Hack: 'Hack',
FiraCode: 'FiraCode', FiraCode: 'FiraCode',
@ -108,7 +109,7 @@ export function SettingsTab({ started }) {
const shouldAlwaysSync = isUdels(); const shouldAlwaysSync = isUdels();
const canChangeAudioDevice = AudioContext.prototype.setSinkId != null; const canChangeAudioDevice = AudioContext.prototype.setSinkId != null;
return ( return (
<div className="text-foreground p-4 space-y-4 w-full"> <div className="text-foreground p-4 space-y-4 w-full" style={{ fontFamily }}>
{canChangeAudioDevice && ( {canChangeAudioDevice && (
<FormItem label="Audio Output Device"> <FormItem label="Audio Output Device">
<AudioDeviceSelector <AudioDeviceSelector
@ -141,7 +142,7 @@ export function SettingsTab({ started }) {
<FormItem label="Theme"> <FormItem label="Theme">
<SelectInput options={themeOptions} value={theme} onChange={(theme) => settingsMap.setKey('theme', theme)} /> <SelectInput options={themeOptions} value={theme} onChange={(theme) => settingsMap.setKey('theme', theme)} />
</FormItem> </FormItem>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> <div className="grid grid-cols-1 md:grid-cols-2 gap-4 font-sans">
<FormItem label="Font Family"> <FormItem label="Font Family">
<SelectInput <SelectInput
options={fontFamilyOptions} options={fontFamilyOptions}

View File

@ -53,7 +53,7 @@ export function SoundsTab() {
}); });
return ( return (
<div id="sounds-tab" className="px-4 flex flex-col w-full h-full dark:text-white text-stone-900"> <div id="sounds-tab" className="px-4 flex flex-col w-full h-full text-foreground">
<Textbox placeholder="Search" value={search} onChange={(v) => setSearch(v)} /> <Textbox placeholder="Search" value={search} onChange={(v) => setSearch(v)} />
<div className="pb-2 flex shrink-0 flex-wrap"> <div className="pb-2 flex shrink-0 flex-wrap">
@ -70,7 +70,7 @@ export function SoundsTab() {
<ImportSoundsButton onComplete={() => settingsMap.setKey('soundsFilter', 'user')} /> <ImportSoundsButton onComplete={() => settingsMap.setKey('soundsFilter', 'user')} />
</div> </div>
<div className="min-h-0 max-h-full grow overflow-auto font-mono text-sm break-normal pb-2"> <div className="min-h-0 max-h-full grow overflow-auto text-sm break-normal pb-2">
{soundEntries.map(([name, { data, onTrigger }]) => { {soundEntries.map(([name, { data, onTrigger }]) => {
return ( return (
<span <span

View File

@ -1,11 +1,12 @@
import cx from '@src/cx.mjs'; import { useSettings } from '@src/settings.mjs';
const { BASE_URL } = import.meta.env; const { BASE_URL } = import.meta.env;
const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL; const baseNoTrailing = BASE_URL.endsWith('/') ? BASE_URL.slice(0, -1) : BASE_URL;
export function WelcomeTab({ context }) { export function WelcomeTab({ context }) {
const { fontFamily } = useSettings();
return ( return (
<div className="prose dark:prose-invert min-w-full pt-2 font-sans pb-8 px-4 "> <div className="prose dark:prose-invert min-w-full pt-2 font-sans pb-8 px-4 " style={{ fontFamily }}>
<h3> welcome</h3> <h3> welcome</h3>
<p> <p>
You have found <span className="underline">strudel</span>, a new live coding platform to write dynamic music You have found <span className="underline">strudel</span>, a new live coding platform to write dynamic music

View File

@ -0,0 +1,33 @@
import useEvent from '@src/useEvent.mjs';
import { logger } from '@strudel/core';
import { nanoid } from 'nanoid';
import { atom } from 'nanostores';
export const $strudel_log_history = atom([]);
function useLoggerEvent(onTrigger) {
useEvent(logger.key, onTrigger);
}
function getUpdatedLog(log, event) {
const { message, type, data } = event.detail;
const lastLog = log.length ? log[log.length - 1] : undefined;
const id = nanoid(12);
if (type === 'loaded-sample') {
const loadIndex = log.findIndex(({ data: { url }, type }) => type === 'load-sample' && url === data.url);
log[loadIndex] = { message, type, id, data };
} else if (lastLog && lastLog.message === message) {
log = log.slice(0, -1).concat([{ message, type, count: (lastLog.count ?? 1) + 1, id, data }]);
} else {
log = log.concat([{ message, type, id, data }]);
}
return log.slice(-20);
}
export function useLogger() {
useLoggerEvent((event) => {
const log = $strudel_log_history.get();
const newLog = getUpdatedLog(log, event);
$strudel_log_history.set(newLog);
});
}

View File

@ -1,6 +1,7 @@
@font-face { @font-face {
font-family: 'PressStart'; font-family: 'PressStart';
src: url('/fonts/PressStart2P/PressStart2P-Regular.ttf'); src: url('/fonts/PressStart2P/PressStart2P-Regular.ttf');
size-adjust: 65%;
} }
@font-face { @font-face {
font-family: 'BigBlueTerminal'; font-family: 'BigBlueTerminal';
@ -14,6 +15,11 @@
font-family: 'galactico'; font-family: 'galactico';
src: url('/fonts/galactico/Galactico-Basic.otf'); src: url('/fonts/galactico/Galactico-Basic.otf');
} }
@font-face {
font-family: 'CutiePi';
src: url('/fonts/CutiePi/Cute_Aurora_demo.ttf');
size-adjust: 120%;
}
@font-face { @font-face {
font-family: 'JetBrains'; font-family: 'JetBrains';
src: url('/fonts/JetBrains/JetBrainsMono.woff2'); src: url('/fonts/JetBrains/JetBrainsMono.woff2');
@ -21,6 +27,7 @@
@font-face { @font-face {
font-family: 'Monocraft'; font-family: 'Monocraft';
src: url('/fonts/Monocraft/Monocraft.ttf'); src: url('/fonts/Monocraft/Monocraft.ttf');
size-adjust: 90%;
} }
@font-face { @font-face {
font-family: 'Hack'; font-family: 'Hack';
@ -41,10 +48,12 @@
@font-face { @font-face {
font-family: 'teletext'; font-family: 'teletext';
src: url('/fonts/teletext/EuropeanTeletext.ttf'); src: url('/fonts/teletext/EuropeanTeletext.ttf');
size-adjust: 90%;
} }
@font-face { @font-face {
font-family: 'mode7'; font-family: 'mode7';
src: url('/fonts/mode7/MODE7GX3.TTF'); src: url('/fonts/mode7/MODE7GX3.TTF');
size-adjust: 82%;
} }
.prose > h1:not(:first-child) { .prose > h1:not(:first-child) {

View File

@ -46,6 +46,29 @@ module.exports = {
'code::after': { 'code::after': {
content: 'none', content: 'none',
}, },
color: 'var(--foreground)',
a: {
color: 'var(--foreground)',
},
h1: {
color: 'var(--foreground)',
},
h2: {
color: 'var(--foreground)',
},
h3: {
color: 'var(--foreground)',
},
h4: {
color: 'var(--foreground)',
},
pre: {
color: 'var(--foreground)',
background: 'var(--background)',
},
code: {
color: 'var(--foreground)',
},
}, },
}, },
}; };