Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
bc9c740
feat(tui): extend terminal styling across content
saforem2 Nov 12, 2026
7157ccf
docs(post): add fetch to status workflow
saforem2 Nov 12, 2026
2d0b815
docs(post): show submit status fetch sequence
saforem2 Nov 12, 2026
6557c04
style(about): use default table treatment
saforem2 Nov 12, 2026
56f790f
style(tui): remove nested-list rails
saforem2 Nov 12, 2026
be2e73e
feat(webtui): add reading style comparison lab
saforem2 Nov 12, 2026
f806408
style(tui): accent list markers and refine tree tables
saforem2 Nov 12, 2026
486ea85
fix(tables): align header cell padding
saforem2 Nov 12, 2026
2b59f4e
style(tui): use character units for table borders
saforem2 Nov 12, 2026
942a003
style(pagination): remove hover background wash
saforem2 Nov 12, 2026
a40b8fa
fix(sidebar): align tree connector strokes
saforem2 Nov 12, 2026
7644ccb
fix(sidebar): render box drawing tree glyphs
saforem2 Nov 12, 2026
6accd32
Revert "fix(sidebar): render box drawing tree glyphs"
saforem2 Nov 12, 2026
6b6e4e8
Revert "fix(sidebar): align tree connector strokes"
saforem2 Nov 12, 2026
eb9558c
style(sidebar): match main tree presentation
saforem2 Nov 12, 2026
c535580
style(code): enlarge copy badge hit area
saforem2 Nov 12, 2026
6d74b25
style(code): loosen language badge line height
saforem2 Nov 12, 2026
cc666fb
style(code): remove language badge fill
saforem2 Nov 12, 2026
a9b4dc6
fix(lists): align wrapped ordered list text
saforem2 Nov 13, 2026
6556b40
fix(lists): align wrapped unordered list text
saforem2 Nov 13, 2026
ad21b9d
feat(diagrams): render Mermaid with Pele
saforem2 Nov 13, 2026
e1560e2
docs(about): add selected RD3 accomplishments
saforem2 Nov 13, 2026
c892a01
docs(about): fold highlights into existing sections
saforem2 Nov 13, 2026
e783ffd
docs(about): list SC26 workshop organizer roles
saforem2 Nov 13, 2026
c51c158
feat(about): link PyTorch talk recording
saforem2 Nov 13, 2026
ee89b7d
style(mermaid): sharpen default diagram palette
saforem2 Nov 13, 2026
f05015b
style(mermaid): use theme accents for node borders
saforem2 Nov 13, 2026
0b0c53e
fix(content): align list callouts and code frames
saforem2 Nov 13, 2026
1ed2db6
style(code): remove duplicate block fill
saforem2 Nov 13, 2026
90b0780
style(content): simplify blockquotes
saforem2 Nov 13, 2026
9c359af
fix: secure Mermaid SVG rendering and font picker
saforem2 Nov 13, 2026
bcca18d
fix: style sticky table column
saforem2 Nov 14, 2026
ff34bdd
style: format files for CI
saforem2 Nov 14, 2026
28a5c7f
style(mermaid): clarify diagram controls
saforem2 Nov 14, 2026
efdedd1
fix(mermaid): keep controls off diagrams at rest
saforem2 Nov 14, 2026
f16ca02
style(mermaid): match controls to directional pad
saforem2 Nov 14, 2026
7f5ddc6
fix(mermaid): size controls to their own text metrics
saforem2 Nov 14, 2026
717e071
feat(shiki): use Vim and Kitty syntax colors by default
saforem2 Nov 14, 2026
4e84fd9
fix(tables): keep sticky date header visible
saforem2 Nov 14, 2026
0e7cc8c
fix(shiki): match current Vim and Kitty palettes
saforem2 Nov 14, 2026
46b174f
fix(shiki): keep Bash arguments neutral
saforem2 Nov 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .stylelintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"extends": ["stylelint-config-recommended"],
"rules": {
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": [
"apply",
"custom-media",
"custom-variant",
"forward",
"include",
"mixin",
"starting-style",
"theme",
"use"
]
}
],
"block-no-empty": null,
"comment-no-empty": null,
"custom-property-pattern": null,
"custom-property-no-missing-var-function": null,
"declaration-block-no-duplicate-custom-properties": null,
"declaration-block-no-shorthand-property-overrides": null,
"declaration-no-important": null,
"declaration-property-value-keyword-no-deprecated": null,
"declaration-property-value-no-unknown": null,
"no-descending-specificity": null,
"no-duplicate-selectors": null,
"property-no-deprecated": null,
"selector-class-pattern": null,
"selector-id-pattern": null,
"selector-type-no-unknown": null
}
}
530 changes: 45 additions & 485 deletions bun.lock

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@
"dev": "turbo run dev",
"format": "turbo run format",
"format:check": "turbo run format:check",
"lint": "turbo run lint",
"lint": "turbo run lint && bun run lint:css",
"lint:css": "stylelint \"web/src/**/*.css\" \"packages/**/src/**/*.css\" \"web/public/talks/**/tetris/style.css\"",
"clean": "rm -rf node_modules .turbo bun.lockb && turbo run clean"
},
"devDependencies": {
Expand All @@ -21,6 +22,8 @@
"prettier-plugin-astro": "^0.14.1",
"qrcode": "^1.5.4",
"satori": "^0.26.0",
"stylelint": "^18.0.0",
"stylelint-config-recommended": "^19.0.0",
"turbo": "^2.8.4",
"typescript": "5.8.2",
"typescript-eslint": "^8.37.0"
Expand Down Expand Up @@ -48,13 +51,10 @@
],
"dependencies": {
"@astrojs/rss": "^4.0.15",
"astro-mermaid": "^1.3.1",
"katex": "0.16.33",
"mermaid": "^11.13.0",
"node-addon-api": "^8.5.0",
"node-gyp": "^12.2.0",
"playwright": "^1.58.2",
"rehype-mermaid": "^3.0.0",
"sharp": "^0.34.5",
"shiki": "^3.22.0"
}
Expand Down
113 changes: 13 additions & 100 deletions web/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import remarkSlides from './src/utils/remark-slides.mjs'
import rehypeTaskListInteractive from './src/utils/rehype-task-list-interactive.mjs'
import rehypeNotebookCells from './src/utils/rehype-notebook-cells.mjs'
import { rehypeAnsi } from './src/utils/rehype-ansi.mjs'
// import rehypeMermaid from 'rehype-mermaid'
// import Catppuccin from 'tm-themes/themes/catppuccin-mocha'
// import { getSingletonHighlighter } from 'shiki'

Expand Down Expand Up @@ -46,16 +45,11 @@ import { rehypeAnsi } from './src/utils/rehype-ansi.mjs'

import { createHighlighter } from 'shiki'
import { createCssVariablesTheme } from 'shiki'
import { customDarkTheme, customLightTheme } from './src/shiki-themes.mjs'

// Four themes: min-light, one-dark-pro and the two catppuccins.
//
// Six in-house ones were removed — sam-light/sam-dark generated from the
// project palette, and four Neovim mirrors (onelight / cyberdream, each in
// "role" and "hue" palette-swap variants from scripts/gen-nvim-themes.mjs).
// Shiki emits a CSS variable per token PER REGISTERED THEME, so each extra
// theme multiplies across every token on the site: those six accounted for
// 31% of all HTML (101MB -> 69MB across 151 pages, and 933KB -> 600KB on the
// argo post). Anything added back here costs the same way.
// The default light/dark slots use the site's Vim/Kitty palette-matched
// themes. They replace min-light and one-dark-pro in place, so the number of
// registered themes (and per-token CSS variables) stays the same.

const oneLight = createCssVariablesTheme({
name: 'one-light',
Expand Down Expand Up @@ -510,8 +504,8 @@ export default defineConfig({
// theme: 'one-dark-pro',
defaultColor: 'custom-light',
themes: {
'custom-light': 'min-light',
'custom-dark': 'one-dark-pro',
'custom-light': customLightTheme,
'custom-dark': customDarkTheme,
catppuccin: 'catppuccin-mocha',
'catppuccin-latte': 'catppuccin-latte',
},
Expand Down Expand Up @@ -562,7 +556,13 @@ export default defineConfig({
// The dev server is intentionally bound to the LAN/tailnet. Keep
// Vite's DNS-rebinding protection, but permit this machine's two
// names instead of allowing every Host header.
allowedHosts: ['mbph', 'mbph.tail3e7069.ts.net', 'mbpr', 'mbpr.tail3e7069.ts.net', 'localhost'],
allowedHosts: [
'mbph',
'mbph.tail3e7069.ts.net',
'mbpr',
'mbpr.tail3e7069.ts.net',
'localhost',
],
},
ssr: {
noExternal: [
Expand All @@ -572,92 +572,5 @@ export default defineConfig({
'@webtui/plugin-nf',
],
},
plugins: [stubUnusedMermaidDiagrams()],
},
})

/**
* Vite plugin: stub out the mermaid diagram chunks we never render.
*
* Mermaid's core entry contains `import('./chunks/mermaid.core/{X}-{hash}.mjs')`
* for every diagram type it knows about. Rollup follows those dynamic imports
* and builds a chunk per diagram — plus their transitive vendor deps. Two of
* those vendor chunks dominate the bundle:
* - cytoscape (~442 KB) — only needed by c4 / architecture / kanban
* - treemap (~453 KB) — only needed by treemap / mindmap
*
* Our deck uses flowchart, stateDiagram-v2, and gantt (in older posts). Every
* other diagram class is unused. Resolving each unused chunk path to a stub
* module that throws "diagram type not bundled" lets Rollup tree-shake their
* vendor deps out of the build. If someone authors an architecture/treemap/etc
* block later, mermaid will surface a clear runtime error pointing at this
* stub, and the fix is to add the diagram to the keep-list below.
*/
function stubUnusedMermaidDiagrams() {
const KEEP = new Set([
'flowDiagram',
'flowchartElk',
'flowchart-elk',
'stateDiagram',
'stateDiagram-v2',
'ganttDiagram',
// 'diagram-*' is mermaid's per-type registration shim; keep them
// all since they're tiny and removing them breaks registry init.
])
// Match `chunks/mermaid.{core,esm}/{Name}-{HASH}.mjs`. Hash is
// case-insensitive — mermaid's filenames use mixed-case rollup
// hashes (e.g. `flowDiagram-PKNHOUZH.mjs`, `chunk-AGHRB4JF.mjs`),
// so don't require all-uppercase. Also match the bare relative
// form mermaid emits (no `mermaid/dist/` prefix) since the
// importer is already inside mermaid's dist.
const CHUNK_RE =
/chunks[/\\]mermaid\.(?:core|esm)[/\\]([A-Za-z][A-Za-z0-9-]*)-[A-Za-z0-9]+\.mjs$/

return {
name: 'stub-unused-mermaid-diagrams',
enforce: 'pre',
async resolveId(source, importer) {
if (!source.includes('chunks/mermaid.')) return null
const m = source.match(CHUNK_RE)
if (!m) {
if (process.env.STUB_DEBUG) {
console.log('[stub] no match:', source, 'from', importer)
}
return null
}
const name = m[1]
// Always allow the bare `diagram-*` registration shim
// through, and the `chunk-*` shared internal modules
// (those are common mermaid runtime, not per-diagram).
if (name.startsWith('diagram-')) return null
if (name === 'chunk') return null
if (KEEP.has(name)) return null
if (process.env.STUB_DEBUG) {
console.log('[stub] STUBBING:', name, 'from', importer)
}
// Synthetic ID — load() below returns an empty module so
// Rollup tree-shakes the transitive vendor deps out.
return `\0mermaid-stub:${name}`
},
load(id) {
if (!id.startsWith('\0mermaid-stub:')) return null
const name = id.slice('\0mermaid-stub:'.length)
return [
`// Stubbed by astro.config.mjs:stubUnusedMermaidDiagrams.`,
`// '${name}' isn't used anywhere in the site; authoring a diagram of`,
`// this type will throw at runtime — add the chunk name to the KEEP`,
`// set in astro.config.mjs to re-enable.`,
`export default {`,
` id: '${name}',`,
` detector: () => false,`,
` loader: () => {`,
` throw new Error(`,
` "mermaid diagram type '${name}' is not bundled on this site. " +`,
` "Add it to the KEEP set in astro.config.mjs to re-enable."`,
` )`,
` },`,
`}`,
].join('\n')
},
}
}
3 changes: 1 addition & 2 deletions web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,9 @@
"@webtui/theme-vitesse": "workspace:*",
"astro": "^7.3.2",
"katex": "0.16.33",
"mermaid": "^11.12.2",
"pele": "^1.13.0",
"playwright": "^1.58.2",
"rehype-katex": "^7.0.1",
"rehype-mermaid": "^3.0.0",
"remark-math": "^6.0.0",
"sharp": "^0.34.5",
"shiki": "^3.13.0",
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
92 changes: 92 additions & 0 deletions web/public/fonts/iosevka25-condensed/OFL.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
Copyright 2015-2025, Renzhi Li (aka. Belleve Invis, belleve@typeof.net).

This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL

-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------

PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.

The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.

DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.

"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).

"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).

"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.

"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.

PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:

1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.

2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.

3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.

4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.

5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.

TERMINATION
This license becomes null and void if any of the above conditions are
not met.

DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
48 changes: 48 additions & 0 deletions web/public/fonts/iosevka25-condensed/iosevka25-condensed.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/* Optional, self-hosted subset of Iosevka25 Condensed 33.2.6.
* Source files: `/Library/Fonts/Iosevka25-Condensed*.ttf` on mbph.
* Subset to the same codepoint coverage used by mIosevka-Term Web.
* License and copyright: ./OFL.txt.
*/

@font-face {
font-family: 'Iosevka25 Condensed Web';
font-weight: 400;
font-style: normal;
font-display: swap;
src: url('/fonts/iosevka25-condensed/Iosevka25Condensed-Regular.woff2')
format('woff2');
}

@font-face {
font-family: 'Iosevka25 Condensed Web';
font-weight: 400;
font-style: italic;
font-display: swap;
src: url('/fonts/iosevka25-condensed/Iosevka25Condensed-Italic.woff2')
format('woff2');
}

@font-face {
font-family: 'Iosevka25 Condensed Web';
font-weight: 700;
font-style: normal;
font-display: swap;
src: url('/fonts/iosevka25-condensed/Iosevka25Condensed-Bold.woff2')
format('woff2');
}

@font-face {
font-family: 'Iosevka25 Condensed Web';
font-weight: 700;
font-style: italic;
font-display: swap;
src: url('/fonts/iosevka25-condensed/Iosevka25Condensed-BoldItalic.woff2')
format('woff2');
}

/* Keep the condensed family an opt-in code-font choice. */
:root[data-code-font='iosevka25-condensed'] {
--code-font-family:
'Iosevka25 Condensed Web', 'Symbols Nerd Font', ui-monospace,
monospace;
}
5 changes: 3 additions & 2 deletions web/src/components/CiteThis.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
import { createShikiHighlighter } from '@astrojs/markdown-remark/shiki'
import { buildBibtex, type CitationKind } from '@/utils/citation'
import { customDarkTheme, customLightTheme } from '@/shiki-themes.mjs'

interface Props {
title: string
Expand Down Expand Up @@ -29,8 +30,8 @@ const label = kind === 'talk' ? 'talk' : 'post'
const highlighter = await createShikiHighlighter({
langs: ['bibtex'],
themes: {
'custom-light': 'min-light',
'custom-dark': 'one-dark-pro',
'custom-light': customLightTheme,
'custom-dark': customDarkTheme,
catppuccin: 'catppuccin-mocha',
'catppuccin-latte': 'catppuccin-latte',
},
Expand Down
Loading
Loading