 Command

Sam Foreman's personal site. Vim-style keybinds for navigation; theme + font pickers below.

Theme
 Font Body Code
Reader
Keybinds
Navigation
j / ↓ Next item k / ↑ Previous item g First item in region G Last item in region zz Center focused item h / l Move left/right region ] / [ Next/previous heading } / { Next/previous block d / u Half-page down/up
Layout
<zh> / <zl> Toggle left/right sidebar <zr> Toggle reader view <zj> / <zk> Focus main/navbar <S-h/j/k/l> Focus left/main/navbar/right ⌃H / ⌃L Focus left/right sidebar ⌃J / ⌃K Focus main/navbar ⇧C / ⇧E Collapse / expand all sections
Dialogs
⌃P / : Command palette ⌃X Theme picker / Search ? Show keybinds Esc / ⌃C Close dialog
History
n Next document b Previous document ⌃O History back ⌃I History forward
 Search
about/more: 🪪 More about: Sam Foreman docs/test: Docs Test ideas: 💡 Ideas more: ➕ More now: Now projects: 📚 Projects webtui: Style posts: 📬 Posts talks: 🎙️ Talks posts/2025: 📆 2025 posts/auroragpt: 🤖 AuroraGPT posts/ai-for-physics: ⚛️ AI for Physics posts/ezpz-v1: 📝 ezpz-v1 posts/dope-slides: 💅 How to Make Dope Slides posts/ezpz-at-alcf: 🍋 ezpz @ ALCF posts/jupyter: 📗 Jupyter posts/resume: 🧑🏻‍💻 Sam Foreman’s Résumé posts/svgbob: 🫥 svgbob posts/torchtune-aurora: 🪛 Torchtune on Aurora posts/torchtune-patch-aurora: 🚑 Torchtune Patch on Aurora webtui/components/accordion: Accordion webtui/components/badge: Badge webtui/components/button: Button webtui/components/checkbox: Checkbox webtui/components/dialog: Dialog webtui/components/input: Input webtui/components/pre: Pre webtui/components/popover: Popover webtui/components/progress: Progress webtui/components/radio: Radio webtui/components/range: Range webtui/components/separator: Separator webtui/components/spinner: Spinner webtui/components/switch: Switch webtui/components/table: Table webtui/components/textarea: Textarea webtui/components/tooltip: Popover webtui/components/typography: Typography webtui/components/view: View webtui/installation/astro: Astro webtui/installation/astro: ## Scoping webtui/installation/astro: ### Frontmatter Imports webtui/installation/astro: ### ‹style› tag webtui/installation/astro: ### Full Library Import webtui/installation/nextjs: Next.js webtui/installation/vite: Vite webtui/plugins/plugin-dev: Developing Plugins webtui/plugins/plugin-dev: ### Style Layers webtui/plugins/plugin-nf: Nerd Font Plugin webtui/plugins/theme-custom: Custom Theme webtui/plugins/theme-everforest: Everforest Theme webtui/plugins/theme-catppuccin: Catppuccin Theme webtui/plugins/theme-gruvbox: Gruvbox Theme webtui/plugins/theme-nord: Nord Theme webtui/plugins/theme-vitesse: Vitesse Theme webtui/start/ascii-boxes: ASCII Boxes webtui/start/changelog: Changelog webtui/start/installation: Installation webtui/start/installation: ## Installation webtui/start/installation: ## Using CSS webtui/start/installation: ## Using ESM webtui/start/installation: ## Using a CDN webtui/start/installation: ## Full Library Import webtui/start/installation: ### CSS webtui/start/installation: ### ESM webtui/start/installation: ### CDN webtui/start/intro: Introduction webtui/start/intro: ## Features webtui/start/plugins: Plugins webtui/start/plugins: ## Official Plugins webtui/start/plugins: ### Themes webtui/start/plugins: ## Community Plugins webtui/start/theming: Theming webtui/start/theming: ## CSS Variables webtui/start/theming: ### Font Styles webtui/start/theming: ### Colors webtui/start/theming: ### Light & Dark webtui/start/theming: ## Theme Plugins webtui/start/theming: ### Using Multiple Theme Accents webtui/start/tuis-vs-guis: TUIs vs GUIs webtui/start/tuis-vs-guis: ## Monospace Fonts webtui/start/tuis-vs-guis: ## Character Cells webtui/contributing/contributing: Contributing webtui/contributing/contributing: ## Local Development webtui/contributing/contributing: ## Issues webtui/contributing/contributing: ## Pull Requests webtui/contributing/style-guide: Style Guide webtui/contributing/style-guide: ## CSS Units webtui/contributing/style-guide: ## Selectors webtui/contributing/style-guide: ## Documentation talks/auroragpt-siam25: AuroraGPT talks/ai-for-science-2024: Parallel Training Methods talks/aurora-gpt-fm-for-electric-grid/auroragpt-fm-for-electric-grid: AuroraGPT: Foundation Models for Science talks/hpc-user-forum/auroragpt: AuroraGPT talks/demo-slides: AuroraGPT: Training Foundation Models on Supercomputers talks/alcf-hpc-workshop-2024/alcf-hpc-workshop-2024: Deep Learning and Foundation Models at Scale talks/incite-hackathon-2025: ALCF Incite Hackathon 2025 talks/llms-at-scale: Training LLMs at Scale talks/llms-on-polaris: Training LLMs on Polaris talks/openskai25: Open SkAI2025 posts/2025/06: 06 posts/auroragpt/aurora-gpt: 🏎️ Megatron-DeepSpeed on Intel XPU posts/auroragpt/checkpoints: 💾 Converting Checkpoints posts/auroragpt/flash-attn-sunspot: 📸 `flash-attn` on Sunspot posts/auroragpt/determinstic-flash-attn/deterministic-flash-attn: 🎰 Deterministic `flash-attn` posts/auroragpt/long-sequences: 🚂 Loooooooong Sequence Lengths posts/auroragpt/mpi4py-reproducer: 🐛 `mpi4py` bug on Sunspot posts/auroragpt/spike-skipper: 🏔️ Spike Skipper posts/auroragpt/startup-times: 🐢 Starting Up Distributed Training on Aurora posts/auroragpt/startup-times: ## Response posts/auroragpt/startup-times: ### Measuring / Calculating Startup Time posts/auroragpt/startup-times: ## Minimal Working Example posts/ai-for-physics/diffusion: 🎲 MCMC + Diffusion Sampling posts/ai-for-physics/l2hmc-qcd: 🎢 L2HMC for LQCD posts/jupyter/l2hmc-4dsu3: 🔳 `l2hmc-qcd` Example: 4D SU(3) posts/jupyter/test: 🏁 `l2hmc` Example: 2D $U(1)$ talks/incite-hackathon-2025/ezpz: LLMs on Aurora: Hands-On talks/incite-hackathon-2025/auroragpt: LLMs on Aurora: Overview talks/openskai25/ai4science: Scientific AI at Scale: AuroraGPT talks/auroragpt/alcf-hpc-workshop-2024/auroragpt-alcf-hands-on-hpc-workshop-2024: AuroraGPT: ANL's General Purpose Scientific LLM talks/openskai25/training: Scientific AI at Scale: Distributed Training posts/2025/04/28: 🔥 Building PyTorch 2.6 from Source on Aurora posts/2025/09/12: 🍹 BlendCorpus + TorchTitan @ ALCF posts/2025/09/17: 📊 `pbs-tui`: TUI for PBS Job Scheduler Monitoring posts/2025/06/01: 📰 Nice Headings posts/2025/06/02: 🧜‍♀️ Mermaid posts/2025/06/14: 🏗️ Building PyTorch 2.8 from Source on Aurora posts/2025/10/06: 🎨 Mixing Between Distributions While Training posts/2025/11/12: 🧊 Cooling Down Checkpoints: Best Practices for Model Evaluation posts/2025/05/03: 🚧 Frameworks Issue with numpy \› 2 posts/2026/02/28: ⏱️ Comparing Launchers on Aurora posts/2026/02/28: ## torchrun posts/2026/02/28: ## ezpz posts/2026/04/27: Pre-Training AuroraGPT with TorchTitan posts/2026/04/27: ## Two-Week Summary (Apr 12–27, 2026) posts/2026/04/27: ## Detailed Breakdown posts/2026/04/27: ### Week 1: Apr 12–18 — Benchmarking, LR Finder, XPU Fixes posts/2026/04/27: #### Benchmarking (Apr 12–15) posts/2026/04/27: #### LR Finder (Apr 12–14) posts/2026/04/27: #### Scaling Study (Apr 12) posts/2026/04/27: #### Upstream Syncs (Apr 12–18, syncs 6–14) posts/2026/04/27: #### XPU Bug Fixes (Apr 18) posts/2026/04/27: #### RL Experiment (Apr 18) posts/2026/04/27: ### Week 1.5: Apr 18–25 — Production Readiness posts/2026/04/27: #### Torch 2.12 Benchmarks (Apr 18) posts/2026/04/27: #### LR Finder Extensions (Apr 20–21) posts/2026/04/27: #### XPU Fixes (Apr 23) posts/2026/04/27: #### Torch 2.13 Environment (Apr 25) posts/2026/04/27: #### 2B Scaling Study on Torch 2.13 (Apr 25) posts/2026/04/27: #### Production Training (Apr 25) posts/2026/04/27: ### Week 2: Apr 26–27 — Optimizer Competition posts/2026/04/27: #### RL Multi-Task Refactor (Apr 26) posts/2026/04/27: #### Docs Reorganization (Apr 26) posts/2026/04/27: #### Generic HF Dataset Streaming (Apr 26) posts/2026/04/27: #### New Optimizers (Apr 26) posts/2026/04/27: #### Architecture Tweaks (Apr 26–27) posts/2026/04/27: ## Competition Results posts/2026/04/27: ### Round 1–3: Speedrun — 2N, GBS=48, 1000 steps posts/2026/04/27: ### 10B Full Training — 8N, GBS=384, ~3,178 steps posts/2026/04/27: ### Round 4: Reproducible Speedrun — 2N, GAS=8, GBS=384, 1000 steps posts/2026/04/27: ## Key Discoveries posts/2026/04/27: ## Infrastructure Built posts/2026/04/27: ## High-Level posts/2026/04/27: ## Detailed Breakdown posts/2026/04/27: ### Week 1: Apr 12–18 — Benchmarking, LR Finder, XPU Fixes posts/2026/04/27: #### Benchmarking (Apr 12–15) posts/2026/04/27: #### LR Finder (Apr 12–14) posts/2026/04/27: #### Scaling Study (Apr 12) posts/2026/04/27: #### Upstream Syncs (Apr 12–18, syncs 6–14) posts/2026/04/27: #### XPU Bug Fixes (Apr 18) posts/2026/04/27: #### RL Experiment (Apr 18) posts/2026/04/27: ### Week 1.5: Apr 18–25 — Production Readiness posts/2026/04/27: #### Torch 2.12 Benchmarks (Apr 18) posts/2026/04/27: #### LR Finder Extensions (Apr 20–21) posts/2026/04/27: #### XPU Fixes (Apr 23) posts/2026/04/27: #### Torch 2.13 Environment (Apr 25) posts/2026/04/27: #### 2B Scaling Study on Torch 2.13 (Apr 25) posts/2026/04/27: #### Production Training (Apr 25) posts/2026/04/27: ### Week 2: Apr 26–27 — Optimizer Competition posts/2026/04/27: #### RL Multi-Task Refactor (Apr 26) posts/2026/04/27: #### Docs Reorganization (Apr 26) posts/2026/04/27: #### Generic HF Dataset Streaming (Apr 26) posts/2026/04/27: #### New Optimizers (Apr 26) posts/2026/04/27: #### Architecture Tweaks (Apr 26–27) posts/2026/04/27: ## Competition Results posts/2026/04/27: ### Round 1–3: 1000-step speedruns, 2 nodes, GBS=48 (17 configs) posts/2026/04/27: ### Round 4 (10B full training, 8 nodes, GBS=384, 5 configs) posts/2026/04/27: ### Round 5 (2 nodes, GAS=8, GBS=384, local dataset, 8 configs — in progress) posts/2026/04/27: ## Key Discoveries posts/2026/04/27: ## Infrastructure Built posts/2026/05/01: Running 50k Python Processes on Aurora with ezpz yeet posts/2026/06/28: Migrating from Quarto to Astro: samforeman.me → samf.sh posts/2026/06/27: Local AI Apps on ALCF: Argo, Inference Endpoints, and One Gateway posts/ai-for-physics/l2hmc-qcd/2du1: 🎢 l2hmc-qcd Example: 2D U(1) posts/2026/01/07: 🎉 Happy New Year! posts/2026/01/10: 🍋 ezpz: distributed PyTorch across any hardware posts/jupyter/l2hmc/4dsu3: 🔳 l2hmc-qcd Example: 4D SU(3) posts/ai-for-physics/l2hmc-qcd/4dsu3nb/index-broken: 🕸️ l2hmc-qcd Example: 4D SU(3) talks/2025/09/24: Training Foundation Models on Supercomputers talks/2025/10/08: AERIS: Argonne's Earth Systems Model talks/2025/10/15: Training Foundation Models on Supercomputers talks/2025/10/24: Training Foundation Models on Supercomputers posts/drafts/2025/09/22: 📝 2025 Annual Report talks/2026/06/03: Production Pre-Training at Scale: The Good, the Bad, and the Restarts talks/2025/12/16: AuroraGPT: Training Foundation Models on Supercomputers
 Theme Current: Light j/k or ↑/↓ + Enter

Custom Theme

A custom theme for WebTUI with light and dark variants

Theme

Theme example

1
2 <h1>Heading 1</h1>
3 <h2>Heading 2</h2>
4 <h3>Heading 3</h3>
5 <h4>Heading 4</h4>
6 <h5>Heading 5</h5>
7 <h6>Heading 6</h6>
8 <p>Body text with <a href="https://example.com">a link</a> and <code>inline code</code> styling.</p>
9

Badges

1
2 <span is-="badge" variant-="red">red</span>
3 <span is-="badge" variant-="orange">orange</span>
4 <span is-="badge" variant-="yellow">yellow</span>
5 <span is-="badge" variant-="green">green</span>
6 <span is-="badge" variant-="teal">teal</span>
7 <span is-="badge" variant-="aqua">aqua</span>
8 <span is-="badge" variant-="blue">blue</span>
9 <span is-="badge" variant-="purple">purple</span>
10 <span is-="badge" variant-="pink">pink</span>
11 <span is-="badge" variant-="sky">sky</span>
12 <span is-="badge" variant-="rosewater">rosewater</span>
13 <span is-="badge" variant-="flamingo">flamingo</span>
14 <span is-="badge" variant-="mauve">mauve</span>
15 <span is-="badge" variant-="maroon">maroon</span>
16 <span is-="badge" variant-="peach">peach</span>
17 <span is-="badge" variant-="sapphire">sapphire</span>
18 <span is-="badge" variant-="lavender">lavender</span>
19

Buttons

1
2 <button variant-="red">red</button>
3 <button variant-="orange">orange</button>
4 <button variant-="yellow">yellow</button>
5 <button variant-="green">green</button>
6 <button variant-="teal">teal</button>
7 <button variant-="aqua">aqua</button>
8 <button variant-="blue">blue</button>
9 <button variant-="purple">purple</button>
10 <button variant-="pink">pink</button>
11 <button variant-="sky">sky</button>
12 <button variant-="dim">dim</button>
13 <button variant-="bright">bright</button>
14

Callouts

1
2 <style>
3 .callout {
4 --callout-color: var(--blue, #118cc2);
5 --callout-bg: oklch(from var(--callout-color) calc(l * var(--oklch-scale, 1.12)) c h / 0.1);
6 --callout-summary-bg: oklch(from var(--callout-color) calc(l * var(--oklch-scale, 1.08)) c h / 0.025);
7 background-color: var(--callout-bg);
8 color: var(--callout-color);
9 margin-block: 0.5rem;
10 }
11 .callout > :not(summary) { margin-inline-start: -1ch; }
12 .callout summary {
13 background-color: var(--callout-summary-bg);
14 color: var(--callout-color);
15 font-weight: bold;
16 }
17 .callout > summary::before { content: '+'; }
18 .callout[open] > summary::before { content: 'x'; }
19 .callout p { margin: 0; color: var(--foreground1); }
20 .callout-note { --callout-color: var(--blue, #118cc2); }
21 .callout-tip { --callout-color: var(--foreground2, #838383); }
22 .callout-important { --callout-color: var(--purple, var(--accent, #9a76ce)); }
23 .callout-warning { --callout-color: var(--orange, #ee8f24); }
24 .callout-error { --callout-color: var(--red, #e05560); }
25 .callout-success { --callout-color: var(--green, #1da811); }
26 </style>
27 <details is-="accordion" class="callout callout-note" open>
28 <summary>Note</summary>
29 <p>This is a note callout with useful information.</p>
30 </details>
31 <details is-="accordion" class="callout callout-tip" open>
32 <summary>Tip</summary>
33 <p>This is a tip callout with helpful advice.</p>
34 </details>
35 <details is-="accordion" class="callout callout-important" open>
36 <summary>Important</summary>
37 <p>This is an important callout you should pay attention to.</p>
38 </details>
39 <details is-="accordion" class="callout callout-warning" open>
40 <summary>Warning</summary>
41 <p>This is a warning callout about potential issues.</p>
42 </details>
43 <details is-="accordion" class="callout callout-error" open>
44 <summary>Error</summary>
45 <p>This is an error callout indicating something went wrong.</p>
46 </details>
47 <details is-="accordion" class="callout callout-success" open>
48 <summary>Success</summary>
49 <p>This is a success callout confirming things worked.</p>
50 </details>
51

Inline callouts

Authored as > [!TYPE|inline] <content>, inline callouts collapse to a single line: a per-type Nerd Font icon (in the callout’s accent color) followed by the content, with no spelled-out type label and no expand/collapse glyph. Handy for compact label / link chips.

1
2 <style>
3 @font-face {
4 font-family: 'Symbols Nerd Font';
5 src: local('SymbolsNerdFont-Regular'), url('/fonts/nerd/SymbolsNerdFont-Regular.woff2') format('woff2');
6 font-display: swap;
7 }
8 .callout {
9 --callout-color: var(--blue, #118cc2);
10 --callout-bg: oklch(from var(--callout-color) calc(l * var(--oklch-scale, 1.12)) c h / 0.1);
11 background-color: var(--callout-bg);
12 color: var(--callout-color);
13 border-left: 2px solid var(--callout-color);
14 padding-left: 0.5ch;
15 }
16 .callout-note { --callout-color: var(--blue, #118cc2); }
17 .callout-tip { --callout-color: var(--foreground2, #838383); }
18 .callout-important { --callout-color: var(--purple, var(--accent, #9a76ce)); }
19 .callout-warning { --callout-color: var(--orange, #ee8f24); }
20 .callout-error { --callout-color: var(--red, #e05560); }
21 .callout-success { --callout-color: var(--green, #1da811); }
22 .callout-inline {
23 display: flex; align-items: baseline; gap: 0;
24 flex-wrap: nowrap; white-space: nowrap; margin-block: 0.25lh;
25 }
26 .callout-inline > summary { display: none; }
27 .callout-inline > :not(summary) { display: inline; margin: 0; color: var(--callout-color); }
28 .callout-inline::before {
29 content: ''; display: inline-block; width: 1em; height: 1em; flex-shrink: 0;
30 margin-inline-end: -0.3em;
31 transform: translateY(0.12em); background-color: var(--callout-color);
32 mask-repeat: no-repeat; mask-position: center; mask-size: contain;
33 -webkit-mask-repeat: no-repeat; -webkit-mask-position: center; -webkit-mask-size: contain;
34 mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z'/%3E%3C/svg%3E");
35 -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M11,9H13V7H11M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M11,17H13V11H11V17Z'/%3E%3C/svg%3E");
36 }
37 .callout-inline[data-callout='tip']::before {
38 mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20,11H23V13H20V11M1,11H4V13H1V11M13,1V4H11V1H13M4.92,3.5L7.05,5.64L5.63,7.05L3.5,4.93L4.92,3.5M16.95,5.63L19.07,3.5L20.5,4.93L18.37,7.05L16.95,5.63M12,6A6,6 0 0,1 18,12C18,14.22 16.79,16.16 15,17.2V19A1,1 0 0,1 14,20H10A1,1 0 0,1 9,19V17.2C7.21,16.16 6,14.22 6,12A6,6 0 0,1 12,6M14,21V22A1,1 0 0,1 13,23H11A1,1 0 0,1 10,22V21H14M11,18H13V15.87C14.73,15.43 16,13.86 16,12A4,4 0 0,0 12,8A4,4 0 0,0 8,12C8,13.86 9.27,15.43 11,15.87V18Z'/%3E%3C/svg%3E");
39 -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M20,11H23V13H20V11M1,11H4V13H1V11M13,1V4H11V1H13M4.92,3.5L7.05,5.64L5.63,7.05L3.5,4.93L4.92,3.5M16.95,5.63L19.07,3.5L20.5,4.93L18.37,7.05L16.95,5.63M12,6A6,6 0 0,1 18,12C18,14.22 16.79,16.16 15,17.2V19A1,1 0 0,1 14,20H10A1,1 0 0,1 9,19V17.2C7.21,16.16 6,14.22 6,12A6,6 0 0,1 12,6M14,21V22A1,1 0 0,1 13,23H11A1,1 0 0,1 10,22V21H14M11,18H13V15.87C14.73,15.43 16,13.86 16,12A4,4 0 0,0 12,8A4,4 0 0,0 8,12C8,13.86 9.27,15.43 11,15.87V18Z'/%3E%3C/svg%3E");
40 }
41 .callout-inline[data-callout='important']::before {
42 mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17.66 11.2C17.43 10.9 17.15 10.64 16.89 10.38C16.22 9.78 15.46 9.35 14.82 8.72C13.33 7.26 13 4.85 13.95 3C13 3.23 12.17 3.75 11.46 4.32C8.87 6.4 7.85 10.07 9.07 13.22C9.11 13.32 9.15 13.42 9.15 13.55C9.15 13.77 9 13.97 8.8 14.05C8.57 14.15 8.33 14.09 8.14 13.93C8.08 13.88 8.04 13.83 8 13.76C6.87 12.33 6.69 10.28 7.45 8.64C5.78 10 4.87 12.3 5 14.47C5.06 14.97 5.12 15.47 5.29 15.97C5.43 16.57 5.7 17.17 6 17.7C7.08 19.43 8.95 20.67 10.96 20.92C13.1 21.19 15.39 20.8 17.03 19.32C18.86 17.66 19.5 15 18.56 12.72L18.43 12.46C18.22 12 17.66 11.2 17.66 11.2M14.5 17.5C14.22 17.74 13.76 18 13.4 18.1C12.28 18.5 11.16 17.94 10.5 17.28C11.69 17 12.4 16.12 12.61 15.23C12.78 14.43 12.46 13.77 12.33 13C12.21 12.26 12.23 11.63 12.5 10.94C12.69 11.32 12.89 11.7 13.13 12C13.9 13 15.11 13.44 15.37 14.8C15.41 14.94 15.43 15.08 15.43 15.23C15.46 16.05 15.1 16.95 14.5 17.5H14.5Z'/%3E%3C/svg%3E");
43 -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M17.66 11.2C17.43 10.9 17.15 10.64 16.89 10.38C16.22 9.78 15.46 9.35 14.82 8.72C13.33 7.26 13 4.85 13.95 3C13 3.23 12.17 3.75 11.46 4.32C8.87 6.4 7.85 10.07 9.07 13.22C9.11 13.32 9.15 13.42 9.15 13.55C9.15 13.77 9 13.97 8.8 14.05C8.57 14.15 8.33 14.09 8.14 13.93C8.08 13.88 8.04 13.83 8 13.76C6.87 12.33 6.69 10.28 7.45 8.64C5.78 10 4.87 12.3 5 14.47C5.06 14.97 5.12 15.47 5.29 15.97C5.43 16.57 5.7 17.17 6 17.7C7.08 19.43 8.95 20.67 10.96 20.92C13.1 21.19 15.39 20.8 17.03 19.32C18.86 17.66 19.5 15 18.56 12.72L18.43 12.46C18.22 12 17.66 11.2 17.66 11.2M14.5 17.5C14.22 17.74 13.76 18 13.4 18.1C12.28 18.5 11.16 17.94 10.5 17.28C11.69 17 12.4 16.12 12.61 15.23C12.78 14.43 12.46 13.77 12.33 13C12.21 12.26 12.23 11.63 12.5 10.94C12.69 11.32 12.89 11.7 13.13 12C13.9 13 15.11 13.44 15.37 14.8C15.41 14.94 15.43 15.08 15.43 15.23C15.46 16.05 15.1 16.95 14.5 17.5H14.5Z'/%3E%3C/svg%3E");
44 }
45 .callout-inline[data-callout='warning']::before {
46 mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12,2L1,21H23M12,6L19.53,19H4.47M11,10V14H13V10M11,16V18H13V16'/%3E%3C/svg%3E");
47 -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12,2L1,21H23M12,6L19.53,19H4.47M11,10V14H13V10M11,16V18H13V16'/%3E%3C/svg%3E");
48 }
49 .callout-inline[data-callout='error']::before {
50 mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23,12L20.56,14.78L20.9,18.46L17.29,19.28L15.4,22.46L12,21L8.6,22.47L6.71,19.29L3.1,18.47L3.44,14.78L1,12L3.44,9.21L3.1,5.53L6.71,4.72L8.6,1.54L12,3L15.4,1.54L17.29,4.72L20.9,5.54L20.56,9.22L23,12M20.33,12L18.5,9.89L18.74,7.1L16,6.5L14.58,4.07L12,5.18L9.42,4.07L8,6.5L5.26,7.09L5.5,9.88L3.67,12L5.5,14.1L5.26,16.9L8,17.5L9.42,19.93L12,18.81L14.58,19.92L16,17.5L18.74,16.89L18.5,14.1L20.33,12M11,15H13V17H11V15M11,7H13V13H11V7'/%3E%3C/svg%3E");
51 -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M23,12L20.56,14.78L20.9,18.46L17.29,19.28L15.4,22.46L12,21L8.6,22.47L6.71,19.29L3.1,18.47L3.44,14.78L1,12L3.44,9.21L3.1,5.53L6.71,4.72L8.6,1.54L12,3L15.4,1.54L17.29,4.72L20.9,5.54L20.56,9.22L23,12M20.33,12L18.5,9.89L18.74,7.1L16,6.5L14.58,4.07L12,5.18L9.42,4.07L8,6.5L5.26,7.09L5.5,9.88L3.67,12L5.5,14.1L5.26,16.9L8,17.5L9.42,19.93L12,18.81L14.58,19.92L16,17.5L18.74,16.89L18.5,14.1L20.33,12M11,15H13V17H11V15M11,7H13V13H11V7'/%3E%3C/svg%3E");
52 }
53 .callout-inline[data-callout='success']::before {
54 mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M12 20C7.59 20 4 16.41 4 12S7.59 4 12 4 20 7.59 20 12 16.41 20 12 20M16.59 7.58L10 14.17L7.41 11.59L6 13L10 17L18 9L16.59 7.58Z'/%3E%3C/svg%3E");
55 -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.5 2 2 6.5 2 12S6.5 22 12 22 22 17.5 22 12 17.5 2 12 2M12 20C7.59 20 4 16.41 4 12S7.59 4 12 4 20 7.59 20 12 16.41 20 12 20M16.59 7.58L10 14.17L7.41 11.59L6 13L10 17L18 9L16.59 7.58Z'/%3E%3C/svg%3E");
56 }
57 </style>
58 <details is-="accordion" class="callout callout-note callout-inline" data-callout="note" open>
59 <summary></summary>
60 <p>A note, on one line.</p>
61 </details>
62 <details is-="accordion" class="callout callout-tip callout-inline" data-callout="tip" open>
63 <summary></summary>
64 <p>A handy tip.</p>
65 </details>
66 <details is-="accordion" class="callout callout-important callout-inline" data-callout="important" open>
67 <summary></summary>
68 <p><a href="#">a repo or link</a></p>
69 </details>
70 <details is-="accordion" class="callout callout-warning callout-inline" data-callout="warning" open>
71 <summary></summary>
72 <p>Heads up about something.</p>
73 </details>
74 <details is-="accordion" class="callout callout-error callout-inline" data-callout="error" open>
75 <summary></summary>
76 <p>Something went wrong.</p>
77 </details>
78 <details is-="accordion" class="callout callout-success callout-inline" data-callout="success" open>
79 <summary></summary>
80 <p>It worked.</p>
81 </details>
82

Installation

Install the theme with your preferred package manager

bun i @webtui/theme-custom
npm i @webtui/theme-custom
yarn add @webtui/theme-custom
pnpm i @webtui/theme-custom

Ensure you import the theme after all the other stylesheets from @webtui/css or the styles will not be applied

@layer base, utils, components;

@import '@webtui/css/base.css';
@import '@webtui/css/components/typography.css';
/* ... */

@import '@webtui/theme-custom';

Set the data-webtui-theme attribute to the <html> tag

<html data-webtui-theme="custom-dark"></html>

To only apply the theme to a specific element, use the same attribute

<html data-webtui-theme="catppuccin">
    <body>
        <div data-webtui-theme="custom-dark">
            <!-- ... -->
        </div>
    </body>
</html>

Variants

Supports light and dark variants.

<html data-webtui-theme="custom-light"></html>
<html data-webtui-theme="custom-dark"></html>

Components

Components affected/modified by the theme

Text

  • Colors headings from h1 to h6
  • inline <a> tags are underlined and colored to be var(--url)
  • inline <code> tags are colored to be var(--red)
<h1>Heading 1</h1>
<!-- ... -->
<h6>Heading 6</h6>

<p><a href="https://example.com">Link</a> <code>Inline Code</code></p>

Badge

Adds variants to badges matching all custom accent colors

<!-- Shared across both variants -->
<span is-="badge" variant-="red">red</span>
<span is-="badge" variant-="green">green</span>
<span is-="badge" variant-="yellow">yellow</span>
<span is-="badge" variant-="blue">blue</span>
<span is-="badge" variant-="purple">purple</span>
<span is-="badge" variant-="aqua">aqua</span>
<span is-="badge" variant-="orange">orange</span>
<span is-="badge" variant-="pink">pink</span>
<span is-="badge" variant-="teal">teal</span>

<!-- Additional colors (custom-dark) -->
<span is-="badge" variant-="rosewater">rosewater</span>
<span is-="badge" variant-="flamingo">flamingo</span>
<span is-="badge" variant-="mauve">mauve</span>
<span is-="badge" variant-="maroon">maroon</span>
<span is-="badge" variant-="peach">peach</span>
<span is-="badge" variant-="sky">sky</span>
<span is-="badge" variant-="sapphire">sapphire</span>
<span is-="badge" variant-="lavender">lavender</span>

Button

Adds variants to buttons matching all custom accent colors, plus dim and bright

<button variant-="red">red</button>
<button variant-="green">green</button>
<button variant-="blue">blue</button>
<!-- ... all color variants ... -->
<button variant-="dim">dim</button>
<button variant-="bright">bright</button>

CSS Variables

Custom Light

[data-webtui-theme='custom-light'] {
    --oklch-scale: 0.85;
    --text: oklch(from #333333 l c h);
    --base: oklch(from #eff1f5 l c h);
    --mantle: oklch(from #e6e9ef l c h);
    --crust: oklch(from #e4e4e4 l c h);

    /* Foreground / Background */
    --foreground0: oklch(from #000000 l c h);
    --foreground1: oklch(from #333333 l c h);
    --foreground2: oklch(from #888888 l c h);
    --foreground3: oklch(from #aaaaaa l c h);
    --background0: oklch(from #ffffff l c h);
    --background1: oklch(from #f8f8f8 l c h);
    --background2: oklch(from #cccccc l c h);
    --background3: oklch(from #999999 l c h);

    /* Accent Colors */
    --red: oklch(from #ff8a80 l c h);
    --green: oklch(from #05a551 l c h);
    --yellow: oklch(from #ff794e l c h);
    --blue: oklch(from #2196f3 l c h);
    --purple: oklch(from #8260cc l c h);
    --aqua: oklch(from #00b8d4 l c h);
    --orange: oklch(from #ff5722 l c h);
    --pink: oklch(from #ff3399 l c h);
    --teal: oklch(from #00838f l c h);
}

Custom Dark

[data-webtui-theme='custom-dark'] {
    --oklch-scale: 1.15;
    --text: #eeeeee;
    --base: oklch(from #1c1c1c l c h);
    --mantle: oklch(from #111111 l c h);
    --crust: oklch(from #101010 l c h);

    /* Foreground / Background */
    --foreground0: oklch(from #eeeeee l c h);
    --foreground1: oklch(from #cccccc l c h);
    --foreground2: oklch(from #888888 l c h);
    --foreground3: #999999;
    --background0: oklch(from #1c1c1c l c h);
    --background1: oklch(from #242424 l c h);
    --background2: oklch(from #333333 l c h);
    --background3: oklch(from #777777 l c h);

    /* Catppuccin Macchiato Accent Colors */
    --rosewater: #f4dbd6;
    --flamingo: #f0c6c6;
    --pink: #f5bde6;
    --mauve: #c6a0f6;
    --red: #ed8796;
    --maroon: #ee99a0;
    --peach: #f5a97f;
    --yellow: #eed49f;
    --green: #a6da95;
    --teal: #8bd5ca;
    --sky: #91d7e3;
    --sapphire: #7dc4e4;
    --blue: #8aadf4;
    --lavender: #b7bdf8;

    /* Additional Colors */
    --orange: #f2ab47;
    --aqua: #84d6eb;
    --purple: #ef7fff;
}

Theme Colors

1
2 <style>
3 .color-grid { display: flex; flex-direction: column; gap: 0.5rem; font-family: monospace; font-size: 0.8rem; }
4 .color-row { display: flex; gap: 0.25rem; align-items: center; }
5 .color-row-label { width: 7rem; opacity: 0.6; flex-shrink: 0; }
6 .swatch { width: 2.5rem; height: 1.5rem; border-radius: 3px; border: 1px solid var(--foreground2); display: inline-flex; align-items: center; justify-content: center; font-size: 0.6rem; color: var(--foreground2); }
7 </style>
8 <div class="color-grid">
9 <div class="color-row">
10 <span class="color-row-label">foreground</span>
11 <span class="swatch" style="background:var(--foreground0)">0</span>
12 <span class="swatch" style="background:var(--foreground1)">1</span>
13 <span class="swatch" style="background:var(--foreground2)">2</span>
14 <span class="swatch" style="background:var(--foreground3)">3</span>
15 </div>
16 <div class="color-row">
17 <span class="color-row-label">background</span>
18 <span class="swatch" style="background:var(--background0)">0</span>
19 <span class="swatch" style="background:var(--background1)">1</span>
20 <span class="swatch" style="background:var(--background2)">2</span>
21 <span class="swatch" style="background:var(--background3)">3</span>
22 </div>
23 <div class="color-row">
24 <span class="color-row-label">accents</span>
25 <span class="swatch" style="background:var(--red)" title="red"></span>
26 <span class="swatch" style="background:var(--orange)" title="orange"></span>
27 <span class="swatch" style="background:var(--yellow)" title="yellow"></span>
28 <span class="swatch" style="background:var(--green)" title="green"></span>
29 <span class="swatch" style="background:var(--teal)" title="teal"></span>
30 <span class="swatch" style="background:var(--blue)" title="blue"></span>
31 <span class="swatch" style="background:var(--purple)" title="purple"></span>
32 <span class="swatch" style="background:var(--pink)" title="pink"></span>
33 <span class="swatch" style="background:var(--aqua)" title="aqua"></span>
34 <span class="swatch" style="background:var(--accent)" title="accent"></span>
35 </div>
36 <div class="color-row">
37 <span class="color-row-label">semantic</span>
38 <span class="swatch" style="background:var(--text)" title="text"></span>
39 <span class="swatch" style="background:var(--url)" title="url"></span>
40 <span class="swatch" style="background:var(--base)" title="base"></span>
41 <span class="swatch" style="background:var(--mantle)" title="mantle"></span>
42 <span class="swatch" style="background:var(--crust)" title="crust"></span>
43 <span class="swatch" style="background:var(--code-bg)" title="code-bg"></span>
44 <span class="swatch" style="background:var(--code-fg)" title="code-fg"></span>
45 </div>
46 </div>
47
 samf.sh / webtui / plugins / theme-custom · Top 1:1