Custom CSS
The settings dropdown contains a text field labeled "Custom CSS." Anything you paste there is injected into the page as a <style> tag, so it overrides the built-in theme. The CSS is stored as its own file at f8ful/f8xt/custom.css in your cloud storage (separate from config.json) and also cached in localStorage so it can be applied before React hydrates. Keeping CSS in its own file means it cannot break the JSON config, no matter what you paste.
If you lock yourself out with a rule like * { display: none }, open browser DevTools, go to Application > Local Storage, and delete the f8xt_custom_css key. You may also need to delete f8ful/f8xt/custom.css from your cloud storage.
Section selectors
Every major UI section carries a data-f8xt attribute. Target it with an attribute selector:
| Selector | Targets |
|---|---|
[data-f8xt="app"] | Entire application root |
[data-f8xt="header"] | Top header bar |
[data-f8xt="sidebar"] | Sidebar panel |
[data-f8xt="sidebar-tabs"] | Tab bar inside the sidebar |
[data-f8xt="note-tree"] | Note tree inside the sidebar |
[data-f8xt="main-content"] | Content area next to the sidebar |
[data-f8xt="split"] | Editor and preview split container |
[data-f8xt="editor"] | Plain-text editor pane |
[data-f8xt="preview"] | Markdown preview pane |
[data-f8xt="backlinks"] | Backlinks panel |
[data-f8xt="status-bar"] | Bottom status bar |
[data-f8xt="mobile-tab-bar"] | Mobile bottom navigation |
CSS variables
The theme is driven by CSS custom properties set on :root (light mode) and .dark (dark mode). Override them in your custom CSS to change colors, spacing, and radii without touching individual selectors.
Core colors
| Variable | Light default | Dark default | Used for |
|---|---|---|---|
--background | #FFFFFF | #0A0A0A | Page background |
--foreground | #0A0A0A | #F5F5F5 | Body text |
--accent-color | #FFD700 | #FFD700 | Accent highlight; links, selection, active states |
--accent-color-foreground | #000000 | #000000 | Text on accent backgrounds |
--primary | #0A0A0A | #FFD700 | Primary buttons, key UI |
--primary-foreground | #FFFFFF | #0A0A0A | Text on primary |
--secondary | #F5F5F5 | #1A1A1A | Secondary backgrounds (inputs, tags) |
--secondary-foreground | #0A0A0A | #F5F5F5 | Text on secondary |
--muted | #F0F0F0 | #1A1A1A | Muted backgrounds (code blocks, subtle areas) |
--muted-foreground | #6B6B6B | #999999 | Dimmed text (hints, timestamps) |
--accent | #FFD700 | #FFD700 | Tailwind accent token |
--accent-foreground | #0A0A0A | #0A0A0A | Text on Tailwind accent |
--destructive | #DC2626 | #EF4444 | Error and danger states |
--border | #E5E5E5 | rgba(255,255,255,0.1) | Borders and dividers |
--input | #E5E5E5 | rgba(255,255,255,0.12) | Input borders |
--ring | #FFD700 | #FFD700 | Focus ring color |
--card | #FAFAFA | #141414 | Card backgrounds |
--card-foreground | #0A0A0A | #F5F5F5 | Text in cards |
--popover | #FFFFFF | #141414 | Popover and dropdown backgrounds |
--popover-foreground | #0A0A0A | #F5F5F5 | Text in popovers |
Sidebar variables
| Variable | Light default | Dark default | Used for |
|---|---|---|---|
--sidebar | #FAFAFA | #111111 | Sidebar background |
--sidebar-foreground | #0A0A0A | #F5F5F5 | Sidebar text |
--sidebar-primary | #0A0A0A | #FFD700 | Sidebar primary elements |
--sidebar-primary-foreground | #FFFFFF | #0A0A0A | Text on sidebar primary |
--sidebar-accent | #FFF8DC | #1A1A00 | Sidebar hover/active backgrounds |
--sidebar-accent-foreground | #0A0A0A | #FFD700 | Text on sidebar accent |
--sidebar-border | #E5E5E5 | rgba(255,255,255,0.08) | Sidebar borders |
--sidebar-ring | #FFD700 | #FFD700 | Sidebar focus ring |
Chart variables
| Variable | Light default | Dark default |
|---|---|---|
--chart-1 | #FFD700 | #FFD700 |
--chart-2 | #0A0A0A | #F5F5F5 |
--chart-3 | #6B6B6B | #999999 |
--chart-4 | #E5E5E5 | #333333 |
--chart-5 | #B8B8B8 | #666666 |
Layout variables
| Variable | Default | Used for |
|---|---|---|
--radius | 0.625rem | Base corner radius. The settings slider changes this. |
--radius-sm | calc(var(--radius) - 4px) | Small corners (checkboxes, badges) |
--radius-md | calc(var(--radius) - 2px) | Medium corners (buttons, inputs) |
--radius-lg | var(--radius) | Large corners (cards, panels) |
--radius-xl | calc(var(--radius) + 4px) | Extra-large corners (modals) |
Content class names
These classes are applied to rendered markdown and the rich text editor. They are defined in globals.css and stable across releases.
| Class | Targets |
|---|---|
.markdown-content | Rendered markdown output in the preview pane |
.rich-text-editor | WYSIWYG editor content area |
.wiki-link | Wiki-link spans ([[page name]]) |
.wiki-link-icon | Small arrow icon inside wiki-links |
.accent-highlight | Highlighted text (==mark me==) |
.math-block | Block-level KaTeX equation |
.math-inline | Inline KaTeX equation |
.katex-error | KaTeX parse error display |
.footnote | Footnote block |
.paper-texture | Landing page paper background |
.sticky-texture | Landing page sticky-note background |
Font variables
Five fonts are loaded. Override the variable to change the font family used throughout the app.
| Variable | Default font | Used for |
|---|---|---|
--font-geist-sans | Geist Sans | Body text, UI elements |
--font-geist-mono | Geist Mono | Code blocks, editor, monospace text |
--font-caveat | Caveat | Handwritten-style text in notes |
--font-permanent-marker | Permanent Marker | Bold handwritten style |
--font-indie-flower | Indie Flower | Casual handwritten style |
Examples
Paste any of these into the Custom CSS field to see the effect immediately.
Widen the sidebar
[data-f8xt="sidebar"] {
width: 320px !important;
min-width: 320px !important;
}Change the accent color to green
:root {
--accent-color: #22C55E;
--accent-color-foreground: #000000;
}
.dark {
--accent-color: #22C55E;
--accent-color-foreground: #000000;
}Hide the status bar
[data-f8xt="status-bar"] {
display: none !important;
}Increase editor font size
[data-f8xt="editor"] textarea {
font-size: 16px !important;
line-height: 1.8 !important;
}Change wiki-link color
.wiki-link {
color: #3B82F6 !important;
border-bottom-color: #3B82F6 !important;
}Rounded code blocks
.markdown-content pre,
.rich-text-editor pre {
border-radius: 12px !important;
padding: 1.25em !important;
}Custom scrollbar
::-webkit-scrollbar {
width: 8px;
}
::-webkit-scrollbar-thumb {
background: var(--accent-color);
border-radius: 4px;
}How it works
- You type or paste CSS into the text field in Settings > Custom CSS.
- The
setCustomCSSstore action creates or updates a<style id="f8xt-user-css">element in<head>. - The CSS string is cached to
localStorageasf8xt_custom_cssfor fast page loads. - After a 3-second debounce, the CSS is written to
f8ful/f8xt/custom.cssin your cloud storage as a plain text file. This is a separate file fromconfig.json, so CSS content cannot break the JSON config. Your custom CSS follows you to any device logged into the same cloud account. - On page load, a blocking
<script>in<head>reads the localStorage cache and injects the style before React renders, preventing a flash of unstyled content. - When the cloud files are read on startup,
custom.cssis loaded separately fromconfig.jsonand applied, overwriting the localStorage cache. - Clearing the text field removes the
<style>element, deletes the localStorage key, and deletescustom.cssfrom cloud storage. - The "Reset all" button also clears custom CSS from both localStorage and cloud storage.
- Custom CSS is included when you export a
.configfile and restored on import.
Targeting dark mode
The <html> element gets the class dark when dark mode is active. Scope your rules with .dark to apply them only in dark mode:
/* Only in dark mode */
.dark [data-f8xt="sidebar"] {
border-right: 1px solid rgba(255, 255, 255, 0.05);
}
/* Only in light mode */
:not(.dark) [data-f8xt="header"] {
border-bottom: 1px solid #d4d4d4;
}