๐ŸŽจ docs: full WebTUI redesign โ€” 8-bit terminal palette, custom navbar, nerd font icons, catppuccin/everforest/nord themes, terminal landing

swadhinbiswas committed 2 months ago
ac54424
1 parent ba6e73d
commit ac54424
10 files changed
+459 -273
โ–ผdocs_site/astro.config.mjs
+22-3
26
26
{ icon: 'x.com', label: 'X (Twitter)', href: 'https://x.com/justapidev' },
27
27
],
28
28
customCss: ['./src/styles/custom.css'],
29
+ components: {
30
+ Header: './src/components/Header.astro',
31
+ },
29
32
editLink: {
30
33
baseUrl: 'https://github.com/swadhinbiswas/JustAPI/edit/main/docs_site',
31
34
},
32
35
head: [
36
+ {
37
+ tag: 'link',
38
+ attrs: {
39
+ rel: 'stylesheet',
40
+ href: 'https://cdn.jsdelivr.net/gh/ryanoasis/nerd-fonts@master/css/nerd-fonts-generated.css',
41
+ },
42
+ },
43
+ {
44
+ tag: 'link',
45
+ attrs: {
46
+ rel: 'stylesheet',
47
+ href: 'https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap',
48
+ },
49
+ },
33
50
{
34
51
tag: 'script',
35
52
attrs: { is: 'inline' },
36
- content: `// JustAPI theme switcher (webtui themes)
53
+ content: `// JustAPI theme switcher (terminal themes)
37
54
(function () {
38
- var THEMES = ['dark', 'light', 'catppuccin', 'nord', 'gruvbox'];
55
+ var THEMES = ['dark', 'light', 'catppuccin', 'everforest', 'nord'];
56
+ var ICONS = { dark: '\\uf1db', light: '\\uf185', catppuccin: '\\uf870', everforest: '\\uf1a0', nord: '\\uf0c8' };
39
57
function apply(t) {
40
58
document.documentElement.setAttribute('data-webtui-theme', t);
41
59
document.documentElement.setAttribute('data-theme', t);
52
70
w.className = 'ja-theme-switcher';
53
71
THEMES.forEach(function (t) {
54
72
var b = document.createElement('button');
55
- b.className = 'ja-theme-btn ja-theme-btn--' + (t === 'catppuccin' ? 'catppuccin' : t);
73
+ b.className = 'ja-theme-btn';
56
74
b.dataset.theme = t;
57
75
b.title = t;
58
76
b.setAttribute('aria-label', 'Theme: ' + t);
77
+ b.textContent = ICONS[t];
59
78
b.addEventListener('click', function () { apply(t); });
60
79
w.appendChild(b);
61
80
});
62
81
โ–ผdocs_site/package-lock.json
+21-0
11
11
"@astrojs/sitemap": "^3.7.3",
12
12
"@astrojs/starlight": "^0.41.4",
13
13
"@webtui/css": "^0.1.9",
14
+ "@webtui/plugin-nf": "^0.1.2",
14
15
"@webtui/theme-catppuccin": "^0.0.5",
16
+ "@webtui/theme-everforest": "^0.0.5",
17
+ "@webtui/theme-nord": "^0.0.4",
15
18
"astro": "^7.1.3"
16
19
},
17
20
"engines": {
2283
2286
"integrity": "sha512-frEwcxRihw3VlmUxLzu5gsvp2KaPtETJvKKgCFHq+9KJ/kqZrgGoil9W56SOgW3T6/9CMtRG8fciU4yixGwPOg==",
2284
2287
"license": "MIT"
2285
2288
},
2289
+ "node_modules/@webtui/plugin-nf": {
2290
+ "version": "0.1.2",
2291
+ "resolved": "https://registry.npmmirror.com/@webtui/plugin-nf/-/plugin-nf-0.1.2.tgz",
2292
+ "integrity": "sha512-jLvg6ay1T6oXgaVR2qqBUNFIRxgajY0CruGfYww9d1a7myDnCbkKgUjKlOD7NDnrlQhTvl/ul0J45AUHNC3UDg==",
2293
+ "license": "MIT"
2294
+ },
2286
2295
"node_modules/@webtui/theme-catppuccin": {
2287
2296
"version": "0.0.5",
2288
2297
"resolved": "https://registry.npmmirror.com/@webtui/theme-catppuccin/-/theme-catppuccin-0.0.5.tgz",
2289
2298
"integrity": "sha512-Lpq6vC1pcvaszLynCpoSd96GpyzumdLGeB7eFaxBRbIbgV4YjiICZuwzi4wsT4FlWrpsefaBg5jN3UHs+wLU2Q==",
2290
2299
"license": "MIT"
2291
2300
},
2301
+ "node_modules/@webtui/theme-everforest": {
2302
+ "version": "0.0.5",
2303
+ "resolved": "https://registry.npmmirror.com/@webtui/theme-everforest/-/theme-everforest-0.0.5.tgz",
2304
+ "integrity": "sha512-hRMTMqSc+pLa1l1uYK22hAfkidNBfiTDwcJ7X/nULyArsp/F2CjXjBG0118re5rS8HZTVF9F6TkpHsqVpisw2Q==",
2305
+ "license": "MIT"
2306
+ },
2307
+ "node_modules/@webtui/theme-nord": {
2308
+ "version": "0.0.4",
2309
+ "resolved": "https://registry.npmmirror.com/@webtui/theme-nord/-/theme-nord-0.0.4.tgz",
2310
+ "integrity": "sha512-4nFRz38hsbPGv4A6mPBz4jbbNJhleEXsJS39F6yxBzVHbYHZHQDcB7fI8vbN95lubWbN6k6mya+lf014LmRorQ==",
2311
+ "license": "MIT"
2312
+ },
2292
2313
"node_modules/acorn": {
2293
2314
"version": "8.17.0",
2294
2315
"resolved": "https://registry.npmmirror.com/acorn/-/acorn-8.17.0.tgz",
2295
2316
โ–ผdocs_site/package.json
+3-0
13
13
"@astrojs/sitemap": "^3.7.3",
14
14
"@astrojs/starlight": "^0.41.4",
15
15
"@webtui/css": "^0.1.9",
16
+ "@webtui/plugin-nf": "^0.1.2",
16
17
"@webtui/theme-catppuccin": "^0.0.5",
18
+ "@webtui/theme-everforest": "^0.0.5",
19
+ "@webtui/theme-nord": "^0.0.4",
17
20
"astro": "^7.1.3"
18
21
},
19
22
"engines": {
20
23
โ–ผdocs_site/src/components/Header.astro
+106-0
1
+---
2
+import config from 'virtual:starlight/user-config';
3
+
4
+import LanguageSelect from 'virtual:starlight/components/LanguageSelect';
5
+import Search from 'virtual:starlight/components/Search';
6
+import SiteTitle from 'virtual:starlight/components/SiteTitle';
7
+import SocialIcons from 'virtual:starlight/components/SocialIcons';
8
+import ThemeSelect from 'virtual:starlight/components/ThemeSelect';
9
+
10
+const shouldRenderSearch =
11
+ config.pagefind || config.components.Search !== '@astrojs/starlight/components/Search.astro';
12
+---
13
+
14
+<div class="ja-navbar">
15
+ <div class="ja-navbar-bar">
16
+ <span class="ja-terminal-dot"></span>
17
+ <span class="ja-terminal-dot"></span>
18
+ <span class="ja-terminal-dot"></span>
19
+ <span class="ja-navbar-title">justapi</span>
20
+ </div>
21
+ <div class="ja-navbar-body">
22
+ <div class="title-wrapper sl-flex">
23
+ <SiteTitle />
24
+ </div>
25
+ <div class="sl-flex print:hidden ja-navbar-search">
26
+ {shouldRenderSearch && <Search />}
27
+ </div>
28
+ <div class="sl-hidden md:sl-flex print:hidden right-group">
29
+ <div class="sl-flex social-icons">
30
+ <SocialIcons />
31
+ </div>
32
+ <ThemeSelect />
33
+ <LanguageSelect />
34
+ </div>
35
+ </div>
36
+</div>
37
+
38
+<script>
39
+ import '../scripts/landing.ts';
40
+ initLanding();
41
+</script>
42
+
43
+<style is:global>
44
+ @layer components {
45
+ .ja-navbar {
46
+ border-bottom: var(--box-border-width, 2px) solid var(--foreground0);
47
+ background-color: var(--background1);
48
+ font-family: var(--font-family);
49
+ }
50
+ .ja-navbar-bar {
51
+ display: flex;
52
+ align-items: center;
53
+ gap: 1ch;
54
+ padding: 0.3rem 1ch;
55
+ border-bottom: 1px solid var(--background2);
56
+ background-color: var(--background2);
57
+ font-size: 0.75rem;
58
+ }
59
+ .ja-navbar-title {
60
+ color: var(--foreground0);
61
+ font-weight: var(--font-weight-bold);
62
+ }
63
+ .ja-navbar-body {
64
+ display: flex;
65
+ align-items: center;
66
+ justify-content: space-between;
67
+ gap: 1rem;
68
+ padding: 0 1.5rem;
69
+ min-height: 3.5rem;
70
+ }
71
+ .ja-navbar-body .site-title a {
72
+ font-family: var(--font-family);
73
+ font-weight: var(--font-weight-bold);
74
+ color: var(--foreground0);
75
+ }
76
+ .ja-navbar-body .site-title a::before {
77
+ content: '\f120';
78
+ font-family: 'Symbols Nerd Font';
79
+ margin-right: 0.75ch;
80
+ color: var(--green, var(--foreground0));
81
+ }
82
+ .ja-navbar-body a {
83
+ font-family: var(--font-family);
84
+ color: var(--foreground1);
85
+ text-decoration: none;
86
+ }
87
+ .ja-navbar-body a:hover {
88
+ color: var(--green, var(--foreground0));
89
+ text-decoration: underline;
90
+ }
91
+ .ja-navbar-search .search-input {
92
+ border: 1px solid var(--foreground0) !important;
93
+ border-radius: 0 !important;
94
+ background-color: var(--background0) !important;
95
+ color: var(--foreground0) !important;
96
+ font-family: var(--font-family) !important;
97
+ font-size: 0.85rem !important;
98
+ padding: 0.35rem 1ch !important;
99
+ height: auto !important;
100
+ }
101
+ @media (max-width: 768px) {
102
+ .ja-navbar-body { flex-wrap: wrap; padding: 0.5rem 1rem; }
103
+ .ja-navbar-search { order: 3; width: 100%; }
104
+ }
105
+ }
106
+</style>
0
107
โ–ผdocs_site/src/content/docs/index.mdx
+21-19
5
5
---
6
6
7
7
<div class="ja-hero">
8
- <span is="badge" variant="green">v2.0.9 ยท published on PyPI ยท 8 platforms</span>
8
+ <span is="badge" variant="green">๏ v2.0.9 ยท published on PyPI ยท 8 platforms</span>
9
9
<h1>
10
10
Python writes the logic.<br/>
11
11
<span class="accent">Rust does everything else.</span>
15
15
routing, TLS, validation, serialization and the server itself run in Rust.
16
16
</p>
17
17
<div class="ja-hero-actions">
18
- <a href="/getting-started/overview/" is="button" size="large">Get Started โ†’</a>
19
- <a href="https://github.com/swadhinbiswas/JustAPI" is="button" box="" size="large">GitHub โ†—</a>
18
+ <a href="/getting-started/overview/" is="button" size="large">๏ก Get Started</a>
19
+ <a href="https://github.com/swadhinbiswas/JustAPI" is="button" box="" size="large">๏‚› GitHub</a>
20
20
</div>
21
21
</div>
22
22
53
53
54
54
<div class="ja-tabs">
55
55
<div class="ja-tabs-bar">
56
- <button class="ja-tab-btn" data-tab-btn="pip" data-active="true">pip</button>
57
- <button class="ja-tab-btn" data-tab-btn="uv">uv</button>
58
- <button class="ja-tab-btn" data-tab-btn="scaffold">scaffold</button>
56
+ <button class="ja-tab-btn" data-tab-btn="pip" data-active="true">๏‘ฒ pip</button>
57
+ <button class="ja-tab-btn" data-tab-btn="uv">๏ฎ uv</button>
58
+ <button class="ja-tab-btn" data-tab-btn="scaffold">๏’‚ scaffold</button>
59
59
</div>
60
60
<div class="ja-tab-panel" data-tab-panel="pip">
61
61
```bash
82
82
83
83
<div class="ja-terminal">
84
84
<div class="ja-terminal-bar">
85
- <span>โ—</span><span>โ—</span><span>โ—</span>
86
- <span class="ja-terminal-title">main.py</span>
85
+ <span class="ja-terminal-dot"></span>
86
+ <span class="ja-terminal-dot"></span>
87
+ <span class="ja-terminal-dot"></span>
88
+ <span class="ja-terminal-title">๏…› main.py</span>
87
89
</div>
88
90
<div class="ja-terminal-body">
89
91
<span class="cm">from</span> justapi <span class="cm">import</span> JustAPIApp<br/>
95
97
&nbsp;&nbsp;&nbsp;&nbsp;<span class="cm">return</span> &#123;<span class="ok">"Hello"</span>: <span class="ok">"World"</span>&#125;<br/>
96
98
<br/>
97
99
app.run()<br/>
98
- <span class="ok">โœ“</span> <span class="dim">server started ยท /docs ยท /redoc ยท OpenAPI auto</span>
100
+ <span class="ok">๏€Œ</span> <span class="dim">server started ยท /docs ยท /redoc ยท OpenAPI auto</span>
99
101
</div>
100
102
</div>
101
103
132
134
133
135
<div class="ja-grid">
134
136
<div class="ja-card">
135
- <div class="ja-card-icon">โšก</div>
137
+ <div class="ja-card-icon">๏</div>
136
138
<h3>Rust core</h3>
137
139
<p>Networking, TLS, routing, serialization run in Rust. Python executes only your logic.</p>
138
140
</div>
139
141
<div class="ja-card">
140
- <div class="ja-card-icon">๐Ÿ—„๏ธ</div>
142
+ <div class="ja-card-icon">๏‘ฑ</div>
141
143
<h3>Native async DB</h3>
142
144
<p><code>await app.db.query_async()</code> runs SQL on Rust's tokio runtime โ€” 53ร— faster on slow queries.</p>
143
145
</div>
144
146
<div class="ja-card">
145
- <div class="ja-card-icon">๐Ÿ“ก</div>
147
+ <div class="ja-card-icon">๏Š•</div>
146
148
<h3>Rust-native SSE</h3>
147
149
<p><code>app.sse_native()</code> streams events with zero Python per event.</p>
148
150
</div>
149
151
<div class="ja-card">
150
- <div class="ja-card-icon">๐Ÿš€</div>
152
+ <div class="ja-card-icon">๏‚…</div>
151
153
<h3>Multi-worker</h3>
152
154
<p><code>justapi serve --workers N</code> โ€” 1.88ร— throughput at 4 workers, auto-scale.</p>
153
155
</div>
154
156
<div class="ja-card">
155
- <div class="ja-card-icon">๐Ÿง </div>
157
+ <div class="ja-card-icon">๏ง</div>
156
158
<h3>Free-threaded</h3>
157
159
<p>CPython 3.14t wheels โ€” CPU-bound Python scales with cores, 12.4ร— measured.</p>
158
160
</div>
159
161
<div class="ja-card">
160
- <div class="ja-card-icon">๐Ÿ”</div>
162
+ <div class="ja-card-icon">๏‘ซ</div>
161
163
<h3>Security built-in</h3>
162
164
<p>JWT, rate limiting, CORS, security headers โ€” all in Rust middleware.</p>
163
165
</div>
164
166
<div class="ja-card">
165
- <div class="ja-card-icon">๐Ÿ›ก๏ธ</div>
167
+ <div class="ja-card-icon">๏’œ</div>
166
168
<h3>Production-ready</h3>
167
169
<p>Circuit breakers, OTel tracing, Prometheus metrics, health checks.</p>
168
170
</div>
169
171
<div class="ja-card">
170
- <div class="ja-card-icon">๐Ÿ“‹</div>
172
+ <div class="ja-card-icon">๏’‡</div>
171
173
<h3>Type-checked</h3>
172
174
<p><code>py.typed</code> + complete stubs โ€” mypy-clean on user code.</p>
173
175
</div>
174
176
<div class="ja-card">
175
- <div class="ja-card-icon">๐Ÿ”—</div>
177
+ <div class="ja-card-icon">๏‘</div>
176
178
<h3>FastAPI-compatible</h3>
177
179
<p>Same decorators, Pydantic models, Depends. Migrate with one import.</p>
178
180
</div>
191
193
<div class="ja-cta">
192
194
<h2>Ready to build something fast?</h2>
193
195
<p>One import. Rust underneath. Zero config.</p>
194
- <a href="/getting-started/overview/" is="button" size="large">Get Started โ†’</a>
196
+ <a href="/getting-started/overview/" is="button" size="large">๏ก Get Started</a>
195
197
</div>
196
198
197
199
198
200
โ–ผdocs_site/src/scripts/landing.ts
+1-3
1
-// Landing page: terminal tabs + benchmark bars (no anime.js โ€” WebTUI is pure CSS)
1
+// Landing page: terminal tabs + benchmark bars
2
2
export function initLanding() {
3
- // Terminal tabs
4
3
document.querySelectorAll('.ja-tabs').forEach((tabs) => {
5
4
const btns = tabs.querySelectorAll('[data-tab-btn]');
6
5
const panels = tabs.querySelectorAll('[data-tab-panel]');
14
13
});
15
14
});
16
15
});
17
- // Benchmark bars: animate width on scroll
18
16
const bars = document.querySelectorAll('.ja-bar-fill');
19
17
if (bars.length && 'IntersectionObserver' in window) {
20
18
const io = new IntersectionObserver((entries) => {
21
19
โ–ผdocs_site/src/styles/custom.css
+282-248
1
1
/* โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
2
- JustAPI Docs โ€” WebTUI terminal aesthetic
3
- WebTUI: pure CSS terminal-UIs-in-the-browser (@webtui/css)
4
- Keeps Starlight's dual-sidebar docs layout; restyles content with
5
- WebTUI components and themes.
2
+ JUSTAPI DOCS โ€” TRUE TERMINAL UI (WebTUI)
3
+ 8-bit color palette ยท Nerd Font icons ยท Catppuccin/Everforest/Nord
4
+ Layers: base, utils, components
6
5
โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */
7
6
8
-/* WebTUI layer order: base, utils, components */
9
7
@layer base, utils, components;
10
8
9
+/* โ”€โ”€โ”€ WebTUI core โ”€โ”€โ”€ */
11
10
@import './webtui/base.css';
12
-
13
-/* Components we use */
14
11
@import './webtui/box.css';
15
12
@import './webtui/components/typography.css';
16
13
@import './webtui/components/button.css';
25
22
@import './webtui/components/tooltip.css';
26
23
@import './webtui/components/view.css';
27
24
28
-/* Themes (Catppuccin for the terminal vibe) */
25
+/* โ”€โ”€โ”€ Themes (import after components) โ”€โ”€โ”€ */
29
26
@import './webtui/catppuccin.css';
27
+@import './webtui/everforest.css';
28
+@import './webtui/nord.css';
29
+
30
+/* โ”€โ”€โ”€ Nerd Font icons โ”€โ”€โ”€ */
31
+@import './webtui/nf.css';
30
32
31
-/* โ”€โ”€โ”€ Base: terminal typography โ”€โ”€โ”€ */
33
+/* โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
34
+ BASE โ€” 8-bit terminal palette
35
+ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */
32
36
@layer base {
33
37
:root {
38
+ /* Classic 8-bit / terminal palette (ANSI-inspired) */
34
39
--font-size: 16px;
35
- --line-height: 1.45;
36
- --font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', ui-monospace, monospace;
40
+ --line-height: 1.5;
37
41
--font-weight-normal: 400;
38
42
--font-weight-bold: 700;
43
+ --font-family:
44
+ 'JetBrains Mono', 'Fira Code', 'Cascadia Code', Menlo, Monaco,
45
+ ui-monospace, monospace, 'Symbols Nerd Font';
46
+ }
47
+
48
+ /* Default dark = terminal black/green */
49
+ [data-webtui-theme='dark'],
50
+ [data-webtui-theme='light'] {
51
+ /* 8-bit palette */
52
+ --bit0: #000000; --bit1: #800000; --bit2: #008000; --bit3: #808000;
53
+ --bit4: #000080; --bit5: #800080; --bit6: #008080; --bit7: #c0c0c0;
54
+ --bit8: #808080; --bit9: #ff0000; --bit10: #00ff00; --bit11: #ffff00;
55
+ --bit12: #0000ff; --bit13: #ff00ff; --bit14: #00ffff; --bit15: #ffffff;
56
+ }
57
+
58
+ [data-webtui-theme='dark'] {
59
+ --background0: #0a0a0a;
60
+ --background1: #1a1a1a;
61
+ --background2: #2a2a2a;
62
+ --background3: #3a3a3a;
63
+ --foreground0: var(--bit7);
64
+ --foreground1: var(--bit8);
65
+ --foreground2: var(--bit7);
66
+ --box-border-color: var(--bit7);
67
+ --table-border-color: var(--bit7);
68
+ --separator-color: var(--bit8);
69
+ /* accents */
70
+ --green: var(--bit10);
71
+ --red: var(--bit9);
72
+ --yellow: var(--bit11);
73
+ --blue: var(--bit14);
74
+ --cyan: var(--bit14);
75
+ --magenta: var(--bit13);
76
+ --white: var(--bit15);
77
+ }
78
+
79
+ [data-webtui-theme='light'] {
80
+ --background0: #ffffff;
81
+ --background1: #e0e0e0;
82
+ --background2: #c0c0c0;
83
+ --background3: #a0a0a0;
84
+ --foreground0: #000000;
85
+ --foreground1: #404040;
86
+ --foreground2: #808080;
87
+ --box-border-color: #000000;
88
+ --table-border-color: #000000;
89
+ --separator-color: #808080;
90
+ --green: #008000;
91
+ --red: #800000;
92
+ --yellow: #808000;
93
+ --blue: #000080;
94
+ --cyan: #008080;
95
+ --magenta: #800080;
96
+ --white: #000000;
39
97
}
40
98
}
41
99
42
-/* โ”€โ”€โ”€ Starlight chrome mapped to WebTUI colors โ”€โ”€โ”€ */
100
+/* โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
101
+ CUSTOM โ€” Starlight chrome โ†’ terminal
102
+ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */
43
103
@layer components {
44
- /* Sidebar + nav follow the theme */
45
- .site-header,
46
- .sidebar,
47
- .page-frame {
48
- background-color: var(--background0) !important;
104
+ /* โ”€โ”€โ”€ Header / Navbar (WebTUI terminal bar) โ”€โ”€โ”€ */
105
+ .site-header {
106
+ background-color: var(--background1);
107
+ border-bottom: var(--box-border-width, 2px) solid var(--foreground0);
49
108
}
50
109
110
+ .site-header .site-title a {
111
+ font-family: var(--font-family);
112
+ font-weight: var(--font-weight-bold);
113
+ color: var(--foreground0);
114
+ }
115
+
116
+ .site-header .site-title a::before {
117
+ content: '\f120'; /* nf-fa-terminal */
118
+ font-family: 'Symbols Nerd Font';
119
+ margin-right: 0.75ch;
120
+ color: var(--green, var(--foreground0));
121
+ }
122
+
123
+ .site-header nav a,
124
+ .site-header .right-sidebar a {
125
+ font-family: var(--font-family);
126
+ color: var(--foreground1);
127
+ text-decoration: none;
128
+ }
129
+ .site-header nav a:hover {
130
+ color: var(--green, var(--foreground0));
131
+ text-decoration: underline;
132
+ }
133
+
134
+ .site-header .toggle-theme button {
135
+ font-family: var(--font-family);
136
+ }
137
+
138
+ /* โ”€โ”€โ”€ Sidebars โ”€โ”€โ”€ */
139
+ .sidebar,
51
140
.sidebar-content,
52
141
.sidebar-pane {
53
- background-color: var(--background0) !important;
142
+ background-color: var(--background0);
54
143
}
55
144
56
- /* Links: terminal underline */
57
- .content a {
58
- color: var(--foreground2);
59
- text-decoration: underline;
60
- text-decoration-thickness: 1px;
61
- text-underline-offset: 3px;
145
+ .sidebar nav a {
146
+ font-family: var(--font-family);
147
+ font-size: 0.9rem;
148
+ color: var(--foreground1);
149
+ }
150
+ .sidebar nav a:hover {
151
+ color: var(--green, var(--foreground0));
152
+ background-color: var(--background1);
62
153
}
63
- .content a:hover {
154
+ .sidebar nav a[aria-current='true'] {
64
155
color: var(--foreground0);
65
- text-decoration-thickness: 2px;
156
+ font-weight: var(--font-weight-bold);
157
+ background-color: var(--background1);
158
+ border-left: 3px solid var(--green, var(--foreground0));
66
159
}
67
160
68
- /* Headings: monospace, terminal weight */
69
- .content h1,
70
- .content h2,
71
- .content h3,
72
- .content h4,
73
- .content h5,
74
- .content h6 {
161
+ /* โ”€โ”€โ”€ Typography โ”€โ”€โ”€ */
162
+ .content h1, .content h2, .content h3,
163
+ .content h4, .content h5, .content h6 {
75
164
font-family: var(--font-family);
76
165
color: var(--foreground0);
77
166
}
167
+ .content h1 { font-size: 1.8rem; }
168
+ .content h1::before { content: '# '; color: var(--green, var(--foreground0)); }
169
+ .content h2 { font-size: 1.35rem; border-bottom: 1px solid var(--background2); padding-bottom: 0.35rem; }
170
+ .content h2::before { content: '## '; color: var(--green, var(--foreground0)); }
171
+ .content h3::before { content: '### '; color: var(--green, var(--foreground0)); }
172
+ .content h4::before { content: '#### '; color: var(--green, var(--foreground0)); }
78
173
79
- .content h1 {
80
- font-size: 2rem;
81
- letter-spacing: -0.02em;
174
+ .content p, .content li {
175
+ font-family: var(--font-family);
176
+ font-size: var(--font-size);
177
+ line-height: var(--line-height);
178
+ color: var(--foreground1);
82
179
}
83
- .content h2 {
84
- font-size: 1.4rem;
85
- border-bottom: var(--box-border-width, 2px) solid var(--background2);
86
- padding-bottom: 0.4rem;
180
+
181
+ .content a {
182
+ color: var(--blue, var(--foreground2));
183
+ text-decoration: underline;
184
+ text-underline-offset: 3px;
87
185
}
186
+ .content a:hover { color: var(--cyan, var(--foreground0)); }
88
187
89
- /* Code: terminal inline */
90
188
.content :not(pre) > code {
91
- background-color: var(--background1);
92
- color: var(--foreground0);
93
- padding: 0 1ch;
189
+ font-family: var(--font-family);
190
+ background-color: var(--background2);
191
+ color: var(--red, var(--foreground0));
192
+ padding: 0 0.75ch;
94
193
}
95
194
96
- /* Inline code blocks inside pre keep WebTUI pre style */
195
+ /* โ”€โ”€โ”€ Code blocks โ”€โ”€โ”€ */
97
196
pre {
98
- background-color: var(--background1) !important;
197
+ background-color: var(--background1);
99
198
border: var(--box-border-width, 2px) solid var(--foreground0);
100
199
border-radius: 0;
101
200
color: var(--foreground0);
201
+ font-family: var(--font-family);
202
+ font-size: 0.85rem;
203
+ line-height: 1.6;
102
204
}
103
- pre code {
104
- background: none !important;
105
- color: inherit;
106
- }
205
+ pre code { background: none; color: inherit; }
107
206
108
- /* Tables: terminal grid */
109
- .content table {
110
- border-collapse: collapse;
111
- }
112
- .content th,
113
- .content td {
114
- border: var(--table-border-color, var(--foreground0)) solid var(--box-border-width, 1px);
207
+ /* โ”€โ”€โ”€ Tables โ”€โ”€โ”€ */
208
+ .content table { border-collapse: collapse; }
209
+ .content th, .content td {
210
+ border: 1px solid var(--table-border-color, var(--foreground0));
115
211
padding: 0.4rem 1ch;
212
+ font-family: var(--font-family);
116
213
}
117
- .content th {
118
- color: var(--foreground0);
119
- font-weight: var(--font-weight-bold);
120
- }
121
- .content td {
122
- color: var(--foreground1);
123
- }
214
+ .content th { color: var(--foreground0); font-weight: var(--font-weight-bold); }
215
+ .content td { color: var(--foreground1); }
216
+ .content tbody tr:hover { background-color: var(--background1); }
124
217
125
- /* Callouts โ†’ terminal blocks */
218
+ /* โ”€โ”€โ”€ Callouts โ†’ terminal โ”€โ”€โ”€ */
126
219
.starlight-aside {
127
220
border: var(--box-border-width, 2px) solid var(--foreground0);
128
- border-left: calc(var(--box-border-width, 2px) * 3) solid var(--foreground0);
221
+ border-left-width: 0.75ch;
129
222
border-radius: 0;
130
223
background-color: var(--background1);
131
224
padding: 0.75rem 1.5ch;
225
+ font-family: var(--font-family);
132
226
}
133
- .starlight-aside--note {
134
- border-left-color: var(--blue, var(--foreground2));
135
- }
136
- .starlight-aside--tip {
137
- border-left-color: var(--green, var(--foreground2));
138
- }
139
- .starlight-aside--caution {
140
- border-left-color: var(--yellow, var(--foreground2));
141
- }
142
- .starlight-aside--danger {
143
- border-left-color: var(--red, var(--foreground2));
144
- }
145
-
146
- /* Badges โ†’ terminal badges */
147
- .badge,
148
- [is-~='badge'] {
149
- border: 1px solid var(--foreground0);
150
- }
227
+ .starlight-aside--note { border-left-color: var(--blue, var(--foreground2)); }
228
+ .starlight-aside--tip { border-left-color: var(--green, var(--foreground0)); }
229
+ .starlight-aside--caution { border-left-color: var(--yellow, var(--foreground2)); }
230
+ .starlight-aside--danger { border-left-color: var(--red, var(--foreground2)); }
151
231
152
- /* Search input: terminal */
232
+ /* โ”€โ”€โ”€ Search โ”€โ”€โ”€ */
153
233
.search-input {
154
234
border: 1px solid var(--foreground0) !important;
155
235
border-radius: 0 !important;
157
237
color: var(--foreground0) !important;
158
238
font-family: var(--font-family) !important;
159
239
}
240
+ .search-input::placeholder { color: var(--foreground2); }
241
+
242
+ /* โ”€โ”€โ”€ Footer โ”€โ”€โ”€ */
243
+ .site-footer {
244
+ border-top: var(--box-border-width, 2px) solid var(--foreground0);
245
+ background-color: var(--background1);
246
+ }
247
+ .site-footer p { font-family: var(--font-family); color: var(--foreground1); }
160
248
}
161
249
162
-/* โ”€โ”€โ”€ Landing page: WebTUI components โ”€โ”€โ”€ */
250
+/* โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
251
+ CUSTOM โ€” Landing components
252
+ โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• */
163
253
@layer components {
254
+ /* Hero */
164
255
.ja-hero {
165
256
text-align: center;
166
- padding: 4rem 1rem 2rem;
257
+ padding: 4rem 1rem 2.5rem;
258
+ position: relative;
167
259
}
168
-
169
260
.ja-hero h1 {
170
- font-size: clamp(2.2rem, 5vw, 3.5rem);
261
+ font-size: clamp(2rem, 5vw, 3.25rem);
171
262
margin-bottom: 1rem;
172
- letter-spacing: -0.03em;
173
- }
174
-
175
- .ja-hero h1 .accent {
176
- color: var(--green, var(--foreground0));
177
263
}
178
-
264
+ .ja-hero h1 .accent { color: var(--green, var(--foreground0)); }
265
+ .ja-hero h1::before { content: ''; }
179
266
.ja-hero-sub {
180
- max-width: 40rem;
267
+ max-width: 42rem;
181
268
margin: 0 auto 2rem;
269
+ color: var(--foreground1);
270
+ font-family: var(--font-family);
182
271
}
183
-
184
272
.ja-hero-actions {
185
273
display: flex;
186
274
gap: 1rem;
187
275
justify-content: center;
188
276
flex-wrap: wrap;
189
277
}
190
-
191
- .ja-actions a,
192
- .ja-actions button {
278
+ .ja-hero-actions a {
279
+ font-family: var(--font-family);
193
280
font-size: var(--font-size);
194
281
}
195
282
196
- /* Stats: terminal box grid */
283
+ /* Stats */
197
284
.ja-stats {
198
285
display: grid;
199
286
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
200
287
gap: 0.75rem;
201
288
margin: 2rem 0;
202
289
}
203
-
204
290
.ja-stat {
205
291
border: var(--box-border-width, 2px) solid var(--foreground0);
206
292
background-color: var(--background1);
207
293
padding: 1rem 0.5rem;
208
294
text-align: center;
295
+ position: relative;
296
+ }
297
+ .ja-stat::before {
298
+ content: '\f0ce'; /* grid icon */
299
+ font-family: 'Symbols Nerd Font';
300
+ position: absolute;
301
+ top: 0.4rem;
302
+ left: 0.6rem;
303
+ font-size: 0.7rem;
304
+ color: var(--foreground2);
209
305
}
210
-
211
306
.ja-stat-value {
307
+ font-family: var(--font-family);
212
308
font-size: 1.5rem;
213
309
font-weight: var(--font-weight-bold);
214
310
color: var(--green, var(--foreground0));
215
311
}
216
-
217
312
.ja-stat-label {
313
+ font-family: var(--font-family);
218
314
font-size: 0.8rem;
219
315
color: var(--foreground1);
220
316
}
221
317
222
- /* Cards: terminal boxes */
318
+ /* Cards */
223
319
.ja-grid {
224
320
display: grid;
225
- grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
321
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
226
322
gap: 0.75rem;
227
323
margin: 1.5rem 0;
228
324
}
229
-
230
325
.ja-card {
231
326
border: var(--box-border-width, 2px) solid var(--foreground0);
232
327
background-color: var(--background0);
233
328
padding: 1.25rem;
329
+ position: relative;
330
+ transition: background-color 0.15s ease;
234
331
}
235
-
236
- .ja-card:hover {
237
- background-color: var(--background1);
238
- }
239
-
332
+ .ja-card:hover { background-color: var(--background1); }
240
333
.ja-card-icon {
241
- font-size: 1.25rem;
334
+ font-family: 'Symbols Nerd Font';
335
+ font-size: 1.3rem;
242
336
margin-bottom: 0.5rem;
337
+ color: var(--green, var(--foreground0));
243
338
}
244
-
245
339
.ja-card h3 {
340
+ font-family: var(--font-family);
246
341
font-size: 1rem;
247
342
margin: 0 0 0.5rem;
248
343
}
249
-
250
344
.ja-card p {
345
+ font-family: var(--font-family);
251
346
font-size: 0.85rem;
252
347
color: var(--foreground1);
253
348
margin: 0;
259
354
border: var(--box-border-width, 2px) solid var(--foreground0);
260
355
background-color: var(--background1);
261
356
margin: 1.5rem 0;
357
+ overflow: hidden;
262
358
}
263
-
264
359
.ja-terminal-bar {
265
360
display: flex;
266
- gap: 0.75ch;
267
361
align-items: center;
362
+ gap: 1ch;
268
363
padding: 0.5rem 1ch;
269
364
border-bottom: var(--box-border-width, 2px) solid var(--foreground0);
270
365
background-color: var(--background2);
366
+ font-family: var(--font-family);
271
367
font-size: 0.8rem;
272
368
}
273
-
274
- .ja-terminal-title {
275
- color: var(--foreground0);
276
- margin-left: 1ch;
277
- }
278
-
369
+ .ja-terminal-dot { width: 0.8em; height: 0.8em; border-radius: 50%; display: inline-block; }
370
+ .ja-terminal-dot:nth-child(1) { background: var(--red, #f00); }
371
+ .ja-terminal-dot:nth-child(2) { background: var(--yellow, #ff0); }
372
+ .ja-terminal-dot:nth-child(3) { background: var(--green, #0f0); }
373
+ .ja-terminal-title { color: var(--foreground0); margin-left: 1ch; }
279
374
.ja-terminal-body {
280
375
padding: 1rem 1.5ch;
376
+ font-family: var(--font-family);
281
377
font-size: 0.85rem;
282
378
line-height: 1.7;
283
379
color: var(--green, var(--foreground0));
284
380
overflow-x: auto;
285
381
}
286
-
287
382
.ja-terminal-body .cm { color: var(--foreground2); }
288
383
.ja-terminal-body .ok { color: var(--green, var(--foreground0)); }
289
384
.ja-terminal-body .dim { color: var(--foreground2); }
290
385
291
- /* Benchmark bars: terminal progress */
292
- .ja-bars {
293
- margin: 1.5rem 0;
294
- display: flex;
295
- flex-direction: column;
296
- gap: 0.6rem;
297
- }
298
-
386
+ /* Benchmark bars */
387
+ .ja-bars { margin: 1.5rem 0; display: flex; flex-direction: column; gap: 0.6rem; }
299
388
.ja-bar-row {
300
389
display: grid;
301
- grid-template-columns: 7rem 1fr 4rem;
390
+ grid-template-columns: 8rem 1fr 4.5rem;
302
391
align-items: center;
303
392
gap: 1ch;
393
+ font-family: var(--font-family);
304
394
font-size: 0.85rem;
305
395
}
306
-
307
- .ja-bar-label {
308
- text-align: right;
309
- color: var(--foreground1);
310
- }
311
-
312
- .ja-bar-row--winner .ja-bar-label {
313
- color: var(--green, var(--foreground0));
314
- font-weight: var(--font-weight-bold);
315
- }
316
-
396
+ .ja-bar-label { text-align: right; color: var(--foreground1); }
397
+ .ja-bar-row--winner .ja-bar-label { color: var(--green, var(--foreground0)); font-weight: var(--font-weight-bold); }
317
398
.ja-bar-track {
318
399
height: 1.5rem;
319
400
border: var(--box-border-width, 2px) solid var(--foreground0);
320
401
background-color: var(--background0);
321
402
padding: 2px;
322
403
}
323
-
324
404
.ja-bar-fill {
325
405
height: 100%;
326
406
width: 0%;
327
407
background-color: var(--green, var(--foreground0));
328
408
transition: width 1.2s cubic-bezier(0.16, 1, 0.3, 1);
329
409
}
410
+ .ja-bar-value { color: var(--foreground0); text-align: right; }
330
411
331
- .ja-bar-value {
332
- font-family: var(--font-family);
333
- color: var(--foreground0);
334
- }
335
-
336
- /* CTA */
337
- .ja-cta {
338
- border: var(--box-border-width, 2px) solid var(--foreground0);
339
- background-color: var(--background1);
340
- padding: 2rem 1rem;
341
- text-align: center;
342
- margin: 2rem 0 1rem;
343
- }
344
-
345
- .ja-cta h2 {
346
- margin: 0 0 0.5rem;
347
- border: none;
348
- }
349
-
350
- .ja-cta p {
351
- color: var(--foreground1);
352
- margin: 0 0 1.5rem;
353
- }
354
-
355
- /* Section headings */
356
- .ja-section {
357
- display: flex;
358
- align-items: center;
359
- gap: 1ch;
360
- margin: 2.5rem 0 1rem;
361
- font-size: 1.1rem;
362
- font-weight: var(--font-weight-bold);
363
- color: var(--foreground0);
364
- }
365
-
366
- .ja-section::after {
367
- content: '';
368
- flex: 1;
369
- border-bottom: var(--box-border-width, 2px) solid var(--background2);
370
- }
371
-}
372
-
373
-/* โ”€โ”€โ”€ Tabs (terminal) โ”€โ”€โ”€ */
374
-@layer components {
412
+ /* Tabs */
375
413
.ja-tabs {
376
414
border: var(--box-border-width, 2px) solid var(--foreground0);
377
415
background-color: var(--background0);
378
416
margin: 1.5rem 0;
379
417
}
380
-
381
418
.ja-tabs-bar {
382
419
display: flex;
383
- gap: 0;
384
420
border-bottom: var(--box-border-width, 2px) solid var(--foreground0);
385
421
background-color: var(--background1);
386
422
overflow-x: auto;
387
423
}
388
-
389
424
.ja-tab-btn {
425
+ font-family: var(--font-family);
390
426
padding: 0.5rem 2ch;
391
427
font-size: 0.85rem;
392
- font-weight: var(--font-weight-normal);
393
428
color: var(--foreground1);
394
429
background: none;
395
430
border: none;
396
431
border-right: 1px solid var(--background2);
397
432
cursor: pointer;
398
- font-family: var(--font-family);
399
433
height: auto !important;
400
434
}
401
-
402
- .ja-tab-btn:hover {
403
- background-color: var(--background2);
404
- color: var(--foreground0);
405
- }
406
-
435
+ .ja-tab-btn:hover { background-color: var(--background2); color: var(--foreground0); }
407
436
.ja-tab-btn[data-active='true'] {
408
437
background-color: var(--foreground0);
409
438
color: var(--background0);
410
439
font-weight: var(--font-weight-bold);
411
- text-decoration: none !important;
412
440
}
441
+ .ja-tab-panel { padding: 1rem; background-color: var(--background0); }
442
+ .ja-tab-panel pre { margin: 0; border: none; background: none; }
413
443
414
- .ja-tab-panel {
415
- padding: 1rem;
416
- background-color: var(--background0);
444
+ /* CTA */
445
+ .ja-cta {
446
+ border: var(--box-border-width, 2px) solid var(--foreground0);
447
+ background-color: var(--background1);
448
+ padding: 2.5rem 1rem;
449
+ text-align: center;
450
+ margin: 2rem 0 1rem;
451
+ position: relative;
452
+ }
453
+ .ja-cta::before {
454
+ content: '\f121'; /* nf-fa-terminal-line */
455
+ font-family: 'Symbols Nerd Font';
456
+ position: absolute;
457
+ top: 0.75rem;
458
+ left: 1rem;
459
+ color: var(--green, var(--foreground0));
417
460
}
461
+ .ja-cta h2 { margin: 0 0 0.5rem; border: none; }
462
+ .ja-cta h2::before { content: ''; }
463
+ .ja-cta p { font-family: var(--font-family); color: var(--foreground1); margin: 0 0 1.5rem; }
418
464
419
- .ja-tab-panel pre {
420
- margin: 0;
421
- border: none;
422
- background: none !important;
465
+ /* Section headings */
466
+ .ja-section {
467
+ display: flex;
468
+ align-items: center;
469
+ gap: 1ch;
470
+ margin: 2.5rem 0 1rem;
471
+ font-family: var(--font-family);
472
+ font-size: 1.1rem;
473
+ font-weight: var(--font-weight-bold);
474
+ color: var(--foreground0);
423
475
}
424
-}
476
+ .ja-section::before { content: '\f489'; font-family: 'Symbols Nerd Font'; color: var(--green, var(--foreground0)); }
477
+ .ja-section::after { content: ''; flex: 1; border-bottom: var(--box-border-width, 2px) solid var(--background2); }
425
478
426
-/* โ”€โ”€โ”€ Theme switcher (terminal dots) โ”€โ”€โ”€ */
427
-@layer components {
479
+ /* Theme switcher โ€” terminal buttons */
428
480
.ja-theme-switcher {
429
481
position: fixed;
430
482
bottom: 1rem;
435
487
padding: 0.4rem;
436
488
border: var(--box-border-width, 2px) solid var(--foreground0);
437
489
background-color: var(--background0);
490
+ font-family: 'Symbols Nerd Font';
438
491
}
439
-
440
492
.ja-theme-btn {
441
- width: 1.75rem;
442
- height: 1.75rem;
493
+ font-family: 'Symbols Nerd Font';
494
+ font-size: 1rem;
495
+ line-height: 1;
496
+ width: 2rem;
497
+ height: 2rem;
498
+ padding: 0;
443
499
border: 1px solid var(--foreground2);
500
+ background: none;
501
+ color: var(--foreground0);
444
502
cursor: pointer;
445
- transition: transform 0.2s ease;
446
- padding: 0;
447
- }
448
-
449
- .ja-theme-btn:hover {
450
- transform: scale(1.2);
451
- }
452
-
453
- .ja-theme-btn[data-active='true'] {
454
- border: 2px solid var(--foreground0);
503
+ transition: transform 0.15s ease, background-color 0.15s ease;
455
504
}
456
-
457
- .ja-theme-btn--dark { background: #09090b; color: #22c55e; }
458
- .ja-theme-btn--light { background: #e5e7eb; color: #111; }
459
- .ja-theme-btn--catppuccin { background: #1e1e2e; color: #89b4fa; }
460
- .ja-theme-btn--nord { background: #2e3440; color: #88c0d0; }
461
- .ja-theme-btn--gruvbox { background: #282828; color: #fabd2f; }
505
+ .ja-theme-btn:hover { transform: scale(1.15); background-color: var(--background2); }
506
+ .ja-theme-btn[data-active='true'] { border: 2px solid var(--foreground0); color: var(--green, var(--foreground0)); }
462
507
}
463
508
464
-/* โ”€โ”€โ”€ Print / a11y / misc โ”€โ”€โ”€ */
465
-:focus-visible {
466
- outline: 2px solid var(--foreground0);
467
- outline-offset: 2px;
468
-}
509
+/* โ”€โ”€โ”€ Misc โ”€โ”€โ”€ */
510
+:focus-visible { outline: 2px solid var(--foreground0); outline-offset: 2px; }
511
+
512
+::selection { background: var(--foreground0); color: var(--background0); }
469
513
470
514
@media print {
471
- .sidebar,
472
- .toc-panel,
473
- .edit-link,
474
- .prev-next-nav,
475
- .ja-theme-switcher {
476
- display: none !important;
477
- }
515
+ .sidebar, .toc-panel, .edit-link, .prev-next-nav, .ja-theme-switcher { display: none !important; }
478
516
}
479
517
480
518
@media (max-width: 768px) {
481
- .ja-bar-row {
482
- grid-template-columns: 5.5rem 1fr 3.5rem;
483
- }
484
- .ja-stats {
485
- grid-template-columns: repeat(2, 1fr);
486
- }
519
+ .ja-bar-row { grid-template-columns: 5.5rem 1fr 3.5rem; }
520
+ .ja-stats { grid-template-columns: repeat(2, 1fr); }
487
521
}
488
522
โ–ผdocs_site/src/styles/webtui/everforest.css
+1-0
1
+@layer base{[data-webtui-theme|=everforest-dark]{--red: #e67e80;--orange: #e69875;--yellow: #dbbc7f;--green: #a7c080;--blue: #7fbbb3;--aqua: #83c092;--purple: #d699b6;--fg: #d3c6aa;--statusline1: #a7c080;--statusline2: #d3c6aa;--statusline3: #e67e80;--gray0: #7a8478;--gray1: #859289;--gray2: #9da9a0}[data-webtui-theme=everforest-dark-hard]{--bg-dim: #1e2326;--bg0: #272e33;--bg1: #2e383c;--bg2: #374145;--bg3: #414b50;--bg4: #495156;--bg5: #4f5b58;--bg-red: #4c3743;--bg-visual: #493b40;--bg-yellow: #45443c;--bg-green: #3c4841;--bg-blue: #384b55}[data-webtui-theme=everforest-dark-medium],[data-webtui-theme=everforest-dark],[data-webtui-theme=everforest]{--bg-dim: #232a2e;--bg0: #2d353b;--bg1: #343f44;--bg2: #3d484d;--bg3: #475258;--bg4: #4f585e;--bg5: #56635f;--bg-red: #4c3743;--bg-visual: #493b40;--bg-yellow: #45443c;--bg-green: #3c4841;--bg-blue: #384b55}[data-webtui-theme=everforest-dark-soft]{--bg-dim: #293136;--bg0: #333c43;--bg1: #3a464c;--bg2: #434f55;--bg3: #4d5960;--bg4: #555f66;--bg5: #5d6b66;--bg-red: #5c3f4f;--bg-visual: #59464c;--bg-yellow: #55544a;--bg-green: #48584e;--bg-blue: #3f5865}[data-webtui-theme|=everforest-light]{--red: #f85552;--orange: #f57d26;--yellow: #dfa000;--green: #8da101;--blue: #3a94c5;--aqua: #35a77c;--purple: #df69ba;--fg: #5c6a72;--statusline1: #93b259;--statusline2: #708089;--statusline3: #e66868;--gray0: #a6b0a0;--gray1: #939f91;--gray2: #829181}[data-webtui-theme=everforest-light-hard]{--bg-dim: #f2efdf;--bg0: #fffbef;--bg1: #f8f5e4;--bg2: #f2efdf;--bg3: #edeada;--bg4: #e8e5d5;--bg5: #bec5b2;--bg-visual: #f0f2d4;--bg-red: #ffe7de;--bg-green: #f3f5d9;--bg-blue: #ecf5ed;--bg-yellow: #fef2d5}[data-webtui-theme=everforest-light-medium],[data-webtui-theme=everforest-light]{--bg-dim: #efebd4;--bg0: #fdf6e3;--bg1: #f4f0d9;--bg2: #efebd4;--bg3: #e6e2cc;--bg4: #e0dcc7;--bg5: #bdc3af;--bg-visual: #eaedc8;--bg-red: #fbe3da;--bg-green: #f0f1d2;--bg-blue: #e9f0e9;--bg-yellow: #faedcd}[data-webtui-theme=everforest-light-soft]{--bg-dim: #e5dfc5;--bg0: #f3ead3;--bg1: #eae4ca;--bg2: #e5dfc5;--bg3: #ddd8be;--bg4: #d8d3ba;--bg5: #b9c0ab;--bg-visual: #e1e4bd;--bg-red: #f4dbd0;--bg-green: #e5e6c5;--bg-blue: #e1e7dd;--bg-yellow: #f1e4c5}[data-webtui-theme|=everforest]{--background0: var(--bg0);--background1: var(--bg1);--background2: var(--bg2);--background3: var(--bg3);--foreground0: var(--fg);--foreground1: var(--gray2);--foreground2: var(--gray1)}}@layer components{[data-webtui-theme|=everforest] button[variant-=red]{--button-primary: var(--red);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=green]{--button-primary: var(--green);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=yellow]{--button-primary: var(--yellow);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=blue]{--button-primary: var(--blue);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=purple]{--button-primary: var(--purple);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=aqua]{--button-primary: var(--aqua);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=orange]{--button-primary: var(--orange);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=statusline1]{--button-primary: var(--statusline1);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=statusline2]{--button-primary: var(--statusline2);--button-secondary: var(--background0)}[data-webtui-theme|=everforest] button[variant-=statusline3]{--button-primary: var(--statusline3);--button-secondary: var(--background0)}}@layer components{[data-webtui-theme|=everforest] h1,[data-webtui-theme|=everforest] h2,[data-webtui-theme|=everforest] h3,[data-webtui-theme|=everforest] h4,[data-webtui-theme|=everforest] h5,[data-webtui-theme|=everforest] h6{color:var(--ef-green)}[data-webtui-theme|=everforest] p a,[data-webtui-theme|=everforest] blockquote a,[data-webtui-theme|=everforest] li a,[data-webtui-theme|=everforest] [is-~=typography-block] a{color:var(--ef-blue);text-decoration:underline}[data-webtui-theme|=everforest] p a:hover,[data-webtui-theme|=everforest] blockquote a:hover,[data-webtui-theme|=everforest] li a:hover,[data-webtui-theme|=everforest] [is-~=typography-block] a:hover{color:var(--ef-aqua)}[data-webtui-theme|=everforest] p code,[data-webtui-theme|=everforest] blockquote code,[data-webtui-theme|=everforest] li code,[data-webtui-theme|=everforest] [is-~=typography-block] code{color:var(--ef-orange)}}@layer components{[data-webtui-theme|=everforest] [is-~=badge][variant-=red]{--badge-color: var(--red);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=green]{--badge-color: var(--green);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=yellow]{--badge-color: var(--yellow);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=blue]{--badge-color: var(--blue);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=purple]{--badge-color: var(--purple);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=aqua]{--badge-color: var(--aqua);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=orange]{--badge-color: var(--orange);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=statusline1]{--badge-color: var(--statusline1);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=statusline2]{--badge-color: var(--statusline2);--badge-text: var(--background0)}[data-webtui-theme|=everforest] [is-~=badge][variant-=statusline3]{--badge-color: var(--statusline3);--badge-text: var(--background0)}}@layer components{[data-webtui-theme|=everforest] mark[bg-=red],[data-webtui-theme|=everforest] [is-~=mark][bg-=red]{background-color:var(--red)}[data-webtui-theme|=everforest] mark[bg-=orange],[data-webtui-theme|=everforest] [is-~=mark][bg-=orange]{background-color:var(--orange)}[data-webtui-theme|=everforest] mark[bg-=yellow],[data-webtui-theme|=everforest] [is-~=mark][bg-=yellow]{background-color:var(--yellow)}[data-webtui-theme|=everforest] mark[bg-=green],[data-webtui-theme|=everforest] [is-~=mark][bg-=green]{background-color:var(--green)}[data-webtui-theme|=everforest] mark[bg-=blue],[data-webtui-theme|=everforest] [is-~=mark][bg-=blue]{background-color:var(--blue)}[data-webtui-theme|=everforest] mark[bg-=aqua],[data-webtui-theme|=everforest] [is-~=mark][bg-=aqua]{background-color:var(--aqua)}[data-webtui-theme|=everforest] mark[bg-=purple],[data-webtui-theme|=everforest] [is-~=mark][bg-=purple]{background-color:var(--purple)}[data-webtui-theme|=everforest] mark[bg-=statusline1],[data-webtui-theme|=everforest] [is-~=mark][bg-=statusline1]{background-color:var(--statusline1)}[data-webtui-theme|=everforest] mark[bg-=statusline2],[data-webtui-theme|=everforest] [is-~=mark][bg-=statusline2]{background-color:var(--statusline2)}[data-webtui-theme|=everforest] mark[bg-=statusline3],[data-webtui-theme|=everforest] [is-~=mark][bg-=statusline3]{background-color:var(--statusline3)}[data-webtui-theme|=everforest] mark[fg-=red],[data-webtui-theme|=everforest] [is-~=mark][fg-=red]{color:var(--red)}[data-webtui-theme|=everforest] mark[fg-=orange],[data-webtui-theme|=everforest] [is-~=mark][fg-=orange]{color:var(--orange)}[data-webtui-theme|=everforest] mark[fg-=yellow],[data-webtui-theme|=everforest] [is-~=mark][fg-=yellow]{color:var(--yellow)}[data-webtui-theme|=everforest] mark[fg-=green],[data-webtui-theme|=everforest] [is-~=mark][fg-=green]{color:var(--green)}[data-webtui-theme|=everforest] mark[fg-=blue],[data-webtui-theme|=everforest] [is-~=mark][fg-=blue]{color:var(--blue)}[data-webtui-theme|=everforest] mark[fg-=aqua],[data-webtui-theme|=everforest] [is-~=mark][fg-=aqua]{color:var(--aqua)}[data-webtui-theme|=everforest] mark[fg-=purple],[data-webtui-theme|=everforest] [is-~=mark][fg-=purple]{color:var(--purple)}[data-webtui-theme|=everforest] mark[fg-=statusline1],[data-webtui-theme|=everforest] [is-~=mark][fg-=statusline1]{color:var(--statusline1)}[data-webtui-theme|=everforest] mark[fg-=statusline2],[data-webtui-theme|=everforest] [is-~=mark][fg-=statusline2]{color:var(--statusline2)}[data-webtui-theme|=everforest] mark[fg-=statusline3],[data-webtui-theme|=everforest] [is-~=mark][fg-=statusline3]{color:var(--statusline3)}}
0
2
โ–ผdocs_site/src/styles/webtui/nf.css
+1-0
1
+@font-face{font-family:Symbols Nerd Font;src:local("SymbolsNerdFont-Regular"),url(https://cdn.jsdelivr.net/gh/mshaugh/nerdfont-webfonts@latest/build/fonts/SymbolsNerdFont-Regular.woff2) format("woff2");font-display:swap;font-style:normal;font-weight:400}
0
2
โ–ผdocs_site/src/styles/webtui/nord.css
+1-0
1
+@layer base{[data-webtui-theme=nord]{--nord0: #2e3440;--nord1: #3b4252;--nord2: #434c5e;--nord3: #4c566a;--nord4: #d8dee9;--nord5: #e5e9f0;--nord6: #eceff4;--nord7: #8fbcbb;--nord8: #88c0d0;--nord9: #81a1c1;--nord10: #5e81ac;--nord11: #bf616a;--nord12: #d08770;--nord13: #ebcb8b;--nord14: #a3be8c;--nord15: #b48ead;--background0: var(--nord0);--background1: var(--nord1);--background2: var(--nord2);--background3: var(--nord3);--foreground0: var(--nord6);--foreground1: var(--nord5);--foreground2: var(--nord4)}}@layer components{[data-webtui-theme=nord] button[variant-=nord0]{--button-primary: var(--background0);--button-secondary: var(--foreground0)}[data-webtui-theme=nord] button[variant-=nord1]{--button-primary: var(--background1);--button-secondary: var(--foreground0)}[data-webtui-theme=nord] button[variant-=nord2]{--button-primary: var(--background2);--button-secondary: var(--foreground0)}[data-webtui-theme=nord] button[variant-=nord3]{--button-primary: var(--background3);--button-secondary: var(--foreground0)}[data-webtui-theme=nord] button[variant-=nord6]{--button-primary: var(--foreground0);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord5]{--button-primary: var(--foreground1);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord4]{--button-primary: var(--foreground2);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord7]{--button-primary: var(--nord7);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord8]{--button-primary: var(--nord8);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord9]{--button-primary: var(--nord9);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord10]{--button-primary: var(--nord10);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord11]{--button-primary: var(--nord11);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord12]{--button-primary: var(--nord12);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord13]{--button-primary: var(--nord13);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord14]{--button-primary: var(--nord14);--button-secondary: var(--background0)}[data-webtui-theme=nord] button[variant-=nord15]{--button-primary: var(--nord15);--button-secondary: var(--background0)}}@layer components{[data-webtui-theme=nord] h1,[data-webtui-theme=nord] h2,[data-webtui-theme=nord] h3,[data-webtui-theme=nord] h4,[data-webtui-theme=nord] h5,[data-webtui-theme=nord] h6{color:var(--nord14)}[data-webtui-theme=nord] p a,[data-webtui-theme=nord] blockquote a,[data-webtui-theme=nord] li a,[data-webtui-theme=nord] [is-~=typography-block] a{color:var(--nord7);text-decoration:underline}[data-webtui-theme=nord] p a:hover,[data-webtui-theme=nord] blockquote a:hover,[data-webtui-theme=nord] li a:hover,[data-webtui-theme=nord] [is-~=typography-block] a:hover{color:var(--nord8)}[data-webtui-theme=nord] p code,[data-webtui-theme=nord] blockquote code,[data-webtui-theme=nord] li code,[data-webtui-theme=nord] [is-~=typography-block] code{color:var(--nord12)}}@layer components{[data-webtui-theme=nord] [is-~=badge][variant-=nord0]{--badge-color: var(--background0);--badge-text: var(--foreground0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord1]{--badge-color: var(--background1);--badge-text: var(--foreground0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord2]{--badge-color: var(--background2);--badge-text: var(--foreground0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord3]{--badge-color: var(--background3);--badge-text: var(--foreground0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord6]{--badge-color: var(--foreground0);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord5]{--badge-color: var(--foreground1);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord4]{--badge-color: var(--foreground2);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord7]{--badge-color: var(--nord7);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord8]{--badge-color: var(--nord8);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord9]{--badge-color: var(--nord9);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord10]{--badge-color: var(--nord10);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord11]{--badge-color: var(--nord11);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord12]{--badge-color: var(--nord12);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord13]{--badge-color: var(--nord13);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord14]{--badge-color: var(--nord14);--badge-text: var(--background0)}[data-webtui-theme=nord] [is-~=badge][variant-=nord15]{--badge-color: var(--nord15);--badge-text: var(--background0)}}@layer components{[data-webtui-theme=nord] [is-~=mark][bg-=nord0],[data-webtui-theme=nord] mark[bg-=nord0]{background-color:var(--nord0)}[data-webtui-theme=nord] [is-~=mark][bg-=nord1],[data-webtui-theme=nord] mark[bg-=nord1]{background-color:var(--nord1)}[data-webtui-theme=nord] [is-~=mark][bg-=nord2],[data-webtui-theme=nord] mark[bg-=nord2]{background-color:var(--nord2)}[data-webtui-theme=nord] [is-~=mark][bg-=nord3],[data-webtui-theme=nord] mark[bg-=nord3]{background-color:var(--nord3)}[data-webtui-theme=nord] [is-~=mark][bg-=nord4],[data-webtui-theme=nord] mark[bg-=nord4]{background-color:var(--nord4)}[data-webtui-theme=nord] [is-~=mark][bg-=nord5],[data-webtui-theme=nord] mark[bg-=nord5]{background-color:var(--nord5)}[data-webtui-theme=nord] [is-~=mark][bg-=nord6],[data-webtui-theme=nord] mark[bg-=nord6]{background-color:var(--nord6)}[data-webtui-theme=nord] [is-~=mark][bg-=nord7],[data-webtui-theme=nord] mark[bg-=nord7]{background-color:var(--nord7)}[data-webtui-theme=nord] [is-~=mark][bg-=nord8],[data-webtui-theme=nord] mark[bg-=nord8]{background-color:var(--nord8)}[data-webtui-theme=nord] [is-~=mark][bg-=nord9],[data-webtui-theme=nord] mark[bg-=nord9]{background-color:var(--nord9)}[data-webtui-theme=nord] [is-~=mark][bg-=nord10],[data-webtui-theme=nord] mark[bg-=nord10]{background-color:var(--nord10)}[data-webtui-theme=nord] [is-~=mark][bg-=nord11],[data-webtui-theme=nord] mark[bg-=nord11]{background-color:var(--nord11)}[data-webtui-theme=nord] [is-~=mark][bg-=nord12],[data-webtui-theme=nord] mark[bg-=nord12]{background-color:var(--nord12)}[data-webtui-theme=nord] [is-~=mark][bg-=nord13],[data-webtui-theme=nord] mark[bg-=nord13]{background-color:var(--nord13)}[data-webtui-theme=nord] [is-~=mark][bg-=nord14],[data-webtui-theme=nord] mark[bg-=nord14]{background-color:var(--nord14)}[data-webtui-theme=nord] [is-~=mark][bg-=nord15],[data-webtui-theme=nord] mark[bg-=nord15]{background-color:var(--nord15)}[data-webtui-theme=nord] [is-~=mark][fg-=nord0],[data-webtui-theme=nord] mark[fg-=nord0]{color:var(--nord0)}[data-webtui-theme=nord] [is-~=mark][fg-=nord1],[data-webtui-theme=nord] mark[fg-=nord1]{color:var(--nord1)}[data-webtui-theme=nord] [is-~=mark][fg-=nord2],[data-webtui-theme=nord] mark[fg-=nord2]{color:var(--nord2)}[data-webtui-theme=nord] [is-~=mark][fg-=nord3],[data-webtui-theme=nord] mark[fg-=nord3]{color:var(--nord3)}[data-webtui-theme=nord] [is-~=mark][fg-=nord4],[data-webtui-theme=nord] mark[fg-=nord4]{color:var(--nord4)}[data-webtui-theme=nord] [is-~=mark][fg-=nord5],[data-webtui-theme=nord] mark[fg-=nord5]{color:var(--nord5)}[data-webtui-theme=nord] [is-~=mark][fg-=nord6],[data-webtui-theme=nord] mark[fg-=nord6]{color:var(--nord6)}[data-webtui-theme=nord] [is-~=mark][fg-=nord7],[data-webtui-theme=nord] mark[fg-=nord7]{color:var(--nord7)}[data-webtui-theme=nord] [is-~=mark][fg-=nord8],[data-webtui-theme=nord] mark[fg-=nord8]{color:var(--nord8)}[data-webtui-theme=nord] [is-~=mark][fg-=nord9],[data-webtui-theme=nord] mark[fg-=nord9]{color:var(--nord9)}[data-webtui-theme=nord] [is-~=mark][fg-=nord10],[data-webtui-theme=nord] mark[fg-=nord10]{color:var(--nord10)}[data-webtui-theme=nord] [is-~=mark][fg-=nord11],[data-webtui-theme=nord] mark[fg-=nord11]{color:var(--nord11)}[data-webtui-theme=nord] [is-~=mark][fg-=nord12],[data-webtui-theme=nord] mark[fg-=nord12]{color:var(--nord12)}[data-webtui-theme=nord] [is-~=mark][fg-=nord13],[data-webtui-theme=nord] mark[fg-=nord13]{color:var(--nord13)}[data-webtui-theme=nord] [is-~=mark][fg-=nord14],[data-webtui-theme=nord] mark[fg-=nord14]{color:var(--nord14)}[data-webtui-theme=nord] [is-~=mark][fg-=nord15],[data-webtui-theme=nord] mark[fg-=nord15]{color:var(--nord15)}}
0
2