Compare commits
10 Commits
b5a35ab198
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51beca2776 | ||
|
|
0b9df4549e | ||
|
|
78407ae9e8 | ||
|
|
bc670d11dc | ||
|
|
d22dca0a27 | ||
|
|
3266c944ba | ||
|
|
93769b3129 | ||
|
|
83a80b6e31 | ||
|
|
7c85022686 | ||
|
|
5f354bda1c |
23
Caddyfile
Normal file
@@ -0,0 +1,23 @@
|
||||
tui-pages.farmeris.sk {
|
||||
encode gzip
|
||||
|
||||
# mdbook served under /book (book.toml has site-url = "/book/")
|
||||
redir /book /book/
|
||||
handle /book/* {
|
||||
root * /app/tui-pages-docs
|
||||
file_server
|
||||
}
|
||||
|
||||
# website at the root (catch-all — must come last)
|
||||
handle {
|
||||
root * /app/tui-pages-web
|
||||
file_server
|
||||
}
|
||||
|
||||
# custom 404 page for the website
|
||||
handle_errors {
|
||||
root * /app/tui-pages-web
|
||||
rewrite * /404.html
|
||||
file_server
|
||||
}
|
||||
}
|
||||
10
LICENSE
Normal file
@@ -0,0 +1,10 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2026 Filip Priečinský
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
15
README.md
@@ -37,9 +37,20 @@ the page plays back.
|
||||
- `SCALE` — source pixel width fed to chafa; scale it up with `SIZE`.
|
||||
|
||||
After changing `SIZE`, set a matching `font-size` in `static/css/ascii.css`
|
||||
(it halves each time you double the grid) so the ASCII fills the screen.
|
||||
(lines 32–33, the two `font-size: max(...)` declarations) so the ASCII fills
|
||||
the screen. The font-size scales **inversely** with the grid: halve the grid →
|
||||
double the font-size. The two `max()` multipliers are:
|
||||
|
||||
Current setup: `480x144`, font-size `max(0.35vw, 0.695vh)`.
|
||||
- vw multiplier ≈ `1 / (cols × 0.6)` (0.6 ≈ JetBrains Mono char aspect ratio)
|
||||
- vh multiplier ≈ `1 / rows`
|
||||
|
||||
| `SIZE` | `font-size` in `ascii.css` |
|
||||
| --------- | ------------------------------ |
|
||||
| `480x144` | `max(0.35vw, 0.695vh)` |
|
||||
| `360x108` | `max(0.463vw, 0.926vh)` |
|
||||
| `240x72` | `max(0.7vw, 1.39vh)` |
|
||||
|
||||
Current setup: `240x72`, font-size `max(0.7vw, 1.39vh)`.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<title>Examples — tui-pages</title>
|
||||
<meta name="description" content="Three runnable TUI apps built with tui-pages: a default multi-page app, a canvas login form, and a keybindings modal. Clone, cargo run, learn.">
|
||||
<link rel="icon" href="/static/img/favicon.svg" type="image/svg+xml">
|
||||
<link rel="canonical" href="https://tui-pages.dev/examples.html">
|
||||
<link rel="canonical" href="https://tui-pages.farmeris.sk/examples.html">
|
||||
|
||||
<meta property="og:title" content="Examples — tui-pages">
|
||||
<meta property="og:description" content="Three runnable TUI apps built with tui-pages. Clone, cargo run, learn.">
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
<ul class="hidden md:flex items-center gap-1 ml-4 text-sm">
|
||||
<li><a href="/examples.html" class="px-3 py-1.5 text-white rounded-md bg-zinc-800/60" aria-current="page">Examples</a></li>
|
||||
<li><a href="https://tui-pages.farmeris.sk" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">Book</a></li>
|
||||
<li><a href="https://tui-pages.farmeris.sk/book" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">Book</a></li>
|
||||
<li><a href="https://docs.rs/tui-pages" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">API</a></li>
|
||||
<li><a href="https://gitlab.com/filipriec/tui-pages" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">GitLab</a></li>
|
||||
</ul>
|
||||
@@ -114,7 +114,7 @@
|
||||
</nav>
|
||||
<p class="text-sm font-medium text-accent uppercase tracking-widest">Examples</p>
|
||||
<h1 class="mt-3 text-4xl sm:text-5xl font-bold tracking-tight text-zinc-50">
|
||||
Three apps in the box.
|
||||
Rich examples out of the box.
|
||||
</h1>
|
||||
<p class="mt-4 text-lg text-zinc-300 max-w-2xl">
|
||||
Each example is a standalone <code class="font-mono text-zinc-200">cargo</code> project under <code class="font-mono text-zinc-200">examples/</code> in the repo. Clone, run, read, fork.
|
||||
@@ -129,7 +129,12 @@
|
||||
<div class="lg:col-span-3">
|
||||
<div class="tp-card !p-2">
|
||||
<div class="tp-terminal">
|
||||
<img src="/static/img/terminal-default.svg" alt="examples/default TUI screenshot" class="block w-full h-auto" loading="lazy" width="640" height="400">
|
||||
<img
|
||||
src="/static/img/terminal-default.svg"
|
||||
:src="theme === 'night' ? '/static/img/terminal-default.svg' : '/static/img/terminal-default-light.svg'"
|
||||
alt="examples/default TUI screenshot"
|
||||
class="block w-full h-auto"
|
||||
loading="lazy" width="640" height="400">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -144,21 +149,7 @@
|
||||
A multi-page app with a focusable list, page navigation, and quit. The minimal end-to-end example — the one to read first to understand the architecture.
|
||||
</p>
|
||||
|
||||
<h3 class="mt-6 text-sm font-semibold uppercase tracking-widest text-zinc-400">Run it</h3>
|
||||
<div
|
||||
x-data="{ copied: false }"
|
||||
class="mt-2 inline-flex items-stretch w-full max-w-md rounded-lg border border-zinc-800 bg-zinc-950/80 overflow-hidden font-mono text-sm"
|
||||
>
|
||||
<code class="px-3 py-2.5 text-zinc-100 whitespace-nowrap">cargo run --example default</code>
|
||||
<button type="button"
|
||||
@click="navigator.clipboard.writeText('cargo run --example default').then(() => { copied = true; setTimeout(() => copied = false, 1400) })"
|
||||
class="ml-auto px-3 border-l border-zinc-800 text-zinc-400 hover:text-white hover:bg-zinc-900 transition-colors flex items-center gap-1.5"
|
||||
>
|
||||
<svg x-show="!copied" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
<svg x-show="copied" x-cloak width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
<span x-text="copied ? 'Copied' : 'Copy'" class="text-xs"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
|
||||
<h3 class="mt-6 text-sm font-semibold uppercase tracking-widest text-zinc-400">What it shows</h3>
|
||||
<ul class="mt-2 space-y-1.5 text-sm text-zinc-300">
|
||||
@@ -184,7 +175,12 @@
|
||||
<div class="lg:col-span-3 lg:order-2">
|
||||
<div class="tp-card !p-2">
|
||||
<div class="tp-terminal">
|
||||
<img src="/static/img/terminal-canvas.svg" alt="examples/canvas TUI screenshot" class="block w-full h-auto" loading="lazy" width="640" height="400">
|
||||
<img
|
||||
src="/static/img/terminal-canvas.svg"
|
||||
:src="theme === 'night' ? '/static/img/terminal-canvas.svg' : '/static/img/terminal-canvas-light.svg'"
|
||||
alt="examples/canvas TUI screenshot"
|
||||
class="block w-full h-auto"
|
||||
loading="lazy" width="640" height="400">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -199,22 +195,6 @@
|
||||
A login form with validated inputs, a submit button, and a canvas-owned keymap. Demonstrates the <code class="font-mono text-zinc-200">canvas</code> feature flag: GUI renderers, suggestions, cursor style, validation, computed fields, textareas, and text inputs.
|
||||
</p>
|
||||
|
||||
<h3 class="mt-6 text-sm font-semibold uppercase tracking-widest text-zinc-400">Run it</h3>
|
||||
<div
|
||||
x-data="{ copied: false }"
|
||||
class="mt-2 inline-flex items-stretch w-full max-w-md rounded-lg border border-zinc-800 bg-zinc-950/80 overflow-hidden font-mono text-sm"
|
||||
>
|
||||
<code class="px-3 py-2.5 text-zinc-100 whitespace-nowrap">cargo run --example canvas --features canvas</code>
|
||||
<button type="button"
|
||||
@click="navigator.clipboard.writeText('cargo run --example canvas --features canvas').then(() => { copied = true; setTimeout(() => copied = false, 1400) })"
|
||||
class="ml-auto px-3 border-l border-zinc-800 text-zinc-400 hover:text-white hover:bg-zinc-900 transition-colors flex items-center gap-1.5"
|
||||
>
|
||||
<svg x-show="!copied" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
<svg x-show="copied" x-cloak width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
<span x-text="copied ? 'Copied' : 'Copy'" class="text-xs"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-6 text-sm font-semibold uppercase tracking-widest text-zinc-400">What it shows</h3>
|
||||
<ul class="mt-2 space-y-1.5 text-sm text-zinc-300">
|
||||
<li class="flex gap-2"><span class="text-accent">▸</span> Field-level focus with <span class="tp-kbd">tab</span> / <span class="tp-kbd">shift+tab</span></li>
|
||||
@@ -239,7 +219,12 @@
|
||||
<div class="lg:col-span-3">
|
||||
<div class="tp-card !p-2">
|
||||
<div class="tp-terminal">
|
||||
<img src="/static/img/terminal-keybindings.svg" alt="examples/keybindings TUI screenshot" class="block w-full h-auto" loading="lazy" width="640" height="400">
|
||||
<img
|
||||
src="/static/img/terminal-keybindings.svg"
|
||||
:src="theme === 'night' ? '/static/img/terminal-keybindings.svg' : '/static/img/terminal-keybindings-light.svg'"
|
||||
alt="examples/keybindings TUI screenshot"
|
||||
class="block w-full h-auto"
|
||||
loading="lazy" width="640" height="400">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -254,21 +239,6 @@
|
||||
A modal showing all keybindings, opened with <span class="tp-kbd">?</span>. Demonstrates the built-in <code class="font-mono text-zinc-200">dialog</code> feature: content and result types, plus a ratatui renderer.
|
||||
</p>
|
||||
|
||||
<h3 class="mt-6 text-sm font-semibold uppercase tracking-widest text-zinc-400">Run it</h3>
|
||||
<div
|
||||
x-data="{ copied: false }"
|
||||
class="mt-2 inline-flex items-stretch w-full max-w-md rounded-lg border border-zinc-800 bg-zinc-950/80 overflow-hidden font-mono text-sm"
|
||||
>
|
||||
<code class="px-3 py-2.5 text-zinc-100 whitespace-nowrap">cargo run --example keybindings --features dialog</code>
|
||||
<button type="button"
|
||||
@click="navigator.clipboard.writeText('cargo run --example keybindings --features dialog').then(() => { copied = true; setTimeout(() => copied = false, 1400) })"
|
||||
class="ml-auto px-3 border-l border-zinc-800 text-zinc-400 hover:text-white hover:bg-zinc-900 transition-colors flex items-center gap-1.5"
|
||||
>
|
||||
<svg x-show="!copied" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>
|
||||
<svg x-show="copied" x-cloak width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="20 6 9 17 4 12"/></svg>
|
||||
<span x-text="copied ? 'Copied' : 'Copy'" class="text-xs"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<h3 class="mt-6 text-sm font-semibold uppercase tracking-widest text-zinc-400">What it shows</h3>
|
||||
<ul class="mt-2 space-y-1.5 text-sm text-zinc-300">
|
||||
@@ -295,7 +265,7 @@
|
||||
The book walks you from <code class="font-mono text-zinc-300">cargo new</code> to a working multi-page app. Or read the API reference and dive in.
|
||||
</p>
|
||||
<div class="mt-8 flex flex-wrap items-center justify-center gap-3">
|
||||
<a href="https://tui-pages.farmeris.sk" class="inline-flex items-center gap-2 h-11 px-5 rounded-lg bg-accent text-accent-fg font-medium hover:bg-accent/90 transition-colors">
|
||||
<a href="https://tui-pages.farmeris.sk/book" class="inline-flex items-center gap-2 h-11 px-5 rounded-lg bg-accent text-accent-fg font-medium hover:bg-accent/90 transition-colors">
|
||||
Start the tutorial
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
|
||||
</a>
|
||||
|
||||
54
index.html
@@ -8,25 +8,27 @@
|
||||
<meta name="theme-color" content="#fafafa" media="(prefers-color-scheme: light)">
|
||||
|
||||
<title>tui-pages — a framework for building TUIs in Rust</title>
|
||||
<meta name="description" content="A complete framework for building TUIs in Rust on top of ratatui. Pre-programmed focus manager, input pipeline, keymaps, and page navigation. Stop rewriting the same architecture for every project.">
|
||||
<meta name="description" content="A complete UX framework for building TUIs in Rust. Stop rewriting the same architecture for every project.">
|
||||
|
||||
<meta name="keywords" content="rust, tui, ratatui, terminal, framework, ui, cargo, crate">
|
||||
<meta name="author" content="Filip Riečický">
|
||||
|
||||
<link rel="icon" href="/static/img/favicon.svg" type="image/svg+xml">
|
||||
<link rel="canonical" href="https://tui-pages.dev/">
|
||||
<link rel="canonical" href="https://tui-pages.farmeris.sk/">
|
||||
|
||||
<!-- Open Graph -->
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="tui-pages — a framework for building TUIs in Rust">
|
||||
<meta property="og:description" content="A complete framework for building TUIs in Rust on top of ratatui. Pre-programmed focus manager, input pipeline, keymaps, and page navigation.">
|
||||
<meta property="og:url" content="https://tui-pages.dev/">
|
||||
<meta property="og:url" content="https://tui-pages.farmeris.sk/">
|
||||
<meta property="og:image" content="/static/img/og-image.svg">
|
||||
<meta property="og:site_name" content="tui-pages">
|
||||
|
||||
<!-- Twitter -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="tui-pages — a framework for building TUIs in Rust">
|
||||
<meta name="twitter:description" content="Pre-programmed focus, keymaps, and page navigation. Stop rewriting the same architecture for every TUI project.">
|
||||
<meta name="twitter:description" content="UX for TUIs in Rust. Stop rewriting the same architecture for every project.">
|
||||
|
||||
<meta name="twitter:image" content="/static/img/og-image.svg">
|
||||
|
||||
<!-- Preconnect -->
|
||||
@@ -127,7 +129,7 @@
|
||||
|
||||
<ul class="hidden md:flex items-center gap-1 ml-4 text-sm">
|
||||
<li><a href="/examples.html" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">Examples</a></li>
|
||||
<li><a href="https://tui-pages.farmeris.sk" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">Book</a></li>
|
||||
<li><a href="https://tui-pages.farmeris.sk/book" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">Book</a></li>
|
||||
<li><a href="https://docs.rs/tui-pages" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">API</a></li>
|
||||
<li><a href="https://gitlab.com/filipriec/tui-pages" class="px-3 py-1.5 text-zinc-300 hover:text-white rounded-md hover:bg-zinc-800/50 transition-colors">GitLab</a></li>
|
||||
</ul>
|
||||
@@ -177,7 +179,7 @@
|
||||
>
|
||||
<ul class="px-4 py-3 space-y-1 text-sm">
|
||||
<li><a href="/examples.html" class="block px-3 py-2 rounded-md text-zinc-300 hover:bg-zinc-800/60">Examples</a></li>
|
||||
<li><a href="https://tui-pages.farmeris.sk" class="block px-3 py-2 rounded-md text-zinc-300 hover:bg-zinc-800/60">Book</a></li>
|
||||
<li><a href="https://tui-pages.farmeris.sk/book" class="block px-3 py-2 rounded-md text-zinc-300 hover:bg-zinc-800/60">Book</a></li>
|
||||
<li><a href="https://docs.rs/tui-pages" class="block px-3 py-2 rounded-md text-zinc-300 hover:bg-zinc-800/60">API</a></li>
|
||||
<li><a href="https://gitlab.com/filipriec/tui-pages" class="block px-3 py-2 rounded-md text-zinc-300 hover:bg-zinc-800/60">GitLab</a></li>
|
||||
</ul>
|
||||
@@ -208,7 +210,7 @@
|
||||
</h1>
|
||||
|
||||
<p class="mt-6 text-lg text-zinc-300 max-w-xl leading-relaxed">
|
||||
<code class="font-mono text-accent">tui-pages</code> gives you a pre-programmed focus manager, input pipeline, keymaps, and page navigation on top of <a href="https://ratatui.rs" class="text-zinc-100 underline decoration-zinc-700 underline-offset-4 hover:decoration-accent">ratatui</a>. Stop rewriting the same architecture for every project.
|
||||
<code class="font-mono text-accent">tui-pages</code> gives you full UX you would ever need. Stop rewriting the same architecture for every project.
|
||||
</p>
|
||||
|
||||
<div class="mt-8 flex flex-wrap items-center gap-3">
|
||||
@@ -216,7 +218,7 @@
|
||||
Get started
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
|
||||
</a>
|
||||
<a href="https://tui-pages.farmeris.sk" class="inline-flex items-center gap-2 h-11 px-5 rounded-lg border border-zinc-700 bg-zinc-900/40 text-zinc-100 font-medium hover:border-zinc-500 hover:bg-zinc-900 transition-colors">
|
||||
<a href="https://tui-pages.farmeris.sk/book" class="inline-flex items-center gap-2 h-11 px-5 rounded-lg border border-zinc-700 bg-zinc-900/40 text-zinc-100 font-medium hover:border-zinc-500 hover:bg-zinc-900 transition-colors">
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2zM22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg>
|
||||
Read the book
|
||||
</a>
|
||||
@@ -250,7 +252,12 @@
|
||||
<div class="absolute -inset-4 -z-10 bg-gradient-to-br from-accent/15 via-transparent to-emerald-500/5 rounded-3xl blur-2xl"></div>
|
||||
<div class="tp-float">
|
||||
<div class="tp-terminal">
|
||||
<img src="/static/img/terminal-default.svg" alt="Screenshot of the examples/default TUI app built with tui-pages" class="block w-full h-auto" loading="eager" width="640" height="400">
|
||||
<img
|
||||
src="/static/img/terminal-default.svg"
|
||||
:src="theme === 'night' ? '/static/img/terminal-default.svg' : '/static/img/terminal-default-light.svg'"
|
||||
alt="Screenshot of the examples/default TUI app built with tui-pages"
|
||||
class="block w-full h-auto"
|
||||
loading="eager" width="640" height="400">
|
||||
</div>
|
||||
<p class="mt-3 text-center text-xs text-zinc-500 font-mono">examples/default · cargo run</p>
|
||||
</div>
|
||||
@@ -563,8 +570,8 @@ pub fn keymaps() -> KeyMap {
|
||||
<div class="flex flex-wrap items-end justify-between gap-4">
|
||||
<div class="max-w-2xl">
|
||||
<p class="text-sm font-medium text-accent uppercase tracking-widest">Examples</p>
|
||||
<h2 class="mt-3 text-3xl sm:text-4xl font-bold tracking-tight text-zinc-50">Three apps in the box.</h2>
|
||||
<p class="mt-4 text-lg text-zinc-400 leading-relaxed">Each one is a full <code class="font-mono text-zinc-300">cargo run</code> away. Read the source, run it, fork it.</p>
|
||||
<h2 class="mt-3 text-3xl sm:text-4xl font-bold tracking-tight text-zinc-50">Rich examples.</h2>
|
||||
<p class="mt-4 text-lg text-zinc-400 leading-relaxed">Each one is a simple <code class="font-mono text-zinc-300">cargo run</code> away. Read the source, run it, copy it.</p>
|
||||
</div>
|
||||
<a href="/examples.html" class="inline-flex items-center gap-1.5 text-sm text-zinc-300 hover:text-white">
|
||||
All examples
|
||||
@@ -575,7 +582,12 @@ pub fn keymaps() -> KeyMap {
|
||||
<div class="mt-12 grid md:grid-cols-3 gap-6">
|
||||
<a href="/examples.html#default" class="group block rounded-2xl border border-zinc-800 bg-zinc-950/50 overflow-hidden hover:border-accent/60 transition-colors">
|
||||
<div class="tp-terminal m-3">
|
||||
<img src="/static/img/terminal-default.svg" alt="default example screenshot" class="block w-full h-auto" loading="lazy" width="640" height="400">
|
||||
<img
|
||||
src="/static/img/terminal-default.svg"
|
||||
:src="theme === 'night' ? '/static/img/terminal-default.svg' : '/static/img/terminal-default-light.svg'"
|
||||
alt="default example screenshot"
|
||||
class="block w-full h-auto"
|
||||
loading="lazy" width="640" height="400">
|
||||
</div>
|
||||
<div class="p-5 pt-2">
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -588,7 +600,12 @@ pub fn keymaps() -> KeyMap {
|
||||
|
||||
<a href="/examples.html#canvas" class="group block rounded-2xl border border-zinc-800 bg-zinc-950/50 overflow-hidden hover:border-accent/60 transition-colors">
|
||||
<div class="tp-terminal m-3">
|
||||
<img src="/static/img/terminal-canvas.svg" alt="canvas example screenshot" class="block w-full h-auto" loading="lazy" width="640" height="400">
|
||||
<img
|
||||
src="/static/img/terminal-canvas.svg"
|
||||
:src="theme === 'night' ? '/static/img/terminal-canvas.svg' : '/static/img/terminal-canvas-light.svg'"
|
||||
alt="canvas example screenshot"
|
||||
class="block w-full h-auto"
|
||||
loading="lazy" width="640" height="400">
|
||||
</div>
|
||||
<div class="p-5 pt-2">
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -601,7 +618,12 @@ pub fn keymaps() -> KeyMap {
|
||||
|
||||
<a href="/examples.html#keybindings" class="group block rounded-2xl border border-zinc-800 bg-zinc-950/50 overflow-hidden hover:border-accent/60 transition-colors">
|
||||
<div class="tp-terminal m-3">
|
||||
<img src="/static/img/terminal-keybindings.svg" alt="keybindings example screenshot" class="block w-full h-auto" loading="lazy" width="640" height="400">
|
||||
<img
|
||||
src="/static/img/terminal-keybindings.svg"
|
||||
:src="theme === 'night' ? '/static/img/terminal-keybindings.svg' : '/static/img/terminal-keybindings-light.svg'"
|
||||
alt="keybindings example screenshot"
|
||||
class="block w-full h-auto"
|
||||
loading="lazy" width="640" height="400">
|
||||
</div>
|
||||
<div class="p-5 pt-2">
|
||||
<div class="flex items-center gap-2">
|
||||
@@ -660,7 +682,7 @@ rt.run() // framework handles the rest</code></pre>
|
||||
The book walks you from <code class="font-mono text-zinc-300">cargo new</code> to a working multi-page app. Or read the API reference and dive in.
|
||||
</p>
|
||||
<div class="mt-10 flex flex-wrap items-center justify-center gap-3">
|
||||
<a href="https://tui-pages.farmeris.sk" class="inline-flex items-center gap-2 h-12 px-6 rounded-lg bg-accent text-accent-fg font-medium hover:bg-accent/90 transition-colors">
|
||||
<a href="https://tui-pages.farmeris.sk/book" class="inline-flex items-center gap-2 h-12 px-6 rounded-lg bg-accent text-accent-fg font-medium hover:bg-accent/90 transition-colors">
|
||||
Start the tutorial
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round"><path d="M5 12h14M13 5l7 7-7 7"/></svg>
|
||||
</a>
|
||||
@@ -691,7 +713,7 @@ rt.run() // framework handles the rest</code></pre>
|
||||
<h4 class="text-xs font-semibold uppercase tracking-widest text-zinc-400">Resources</h4>
|
||||
<ul class="mt-3 space-y-2 text-sm">
|
||||
<li><a href="https://docs.rs/tui-pages" class="text-zinc-300 hover:text-white">API reference</a></li>
|
||||
<li><a href="https://tui-pages.farmeris.sk" class="text-zinc-300 hover:text-white">The Book</a></li>
|
||||
<li><a href="https://tui-pages.farmeris.sk/book" class="text-zinc-300 hover:text-white">The Book</a></li>
|
||||
<li><a href="/examples.html" class="text-zinc-300 hover:text-white">Examples</a></li>
|
||||
<li><a href="https://crates.io/crates/tui-pages" class="text-zinc-300 hover:text-white">crates.io</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://tui-pages.dev/sitemap.xml
|
||||
Sitemap: https://tui-pages.farmeris.sk/sitemap.xml
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
|
||||
<url>
|
||||
<loc>https://tui-pages.dev/</loc>
|
||||
<loc>https://tui-pages.farmeris.sk/</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>1.0</priority>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://tui-pages.dev/examples.html</loc>
|
||||
<loc>https://tui-pages.farmeris.sk/examples.html</loc>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
</url>
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
- tints the dense characters rust-orange with text-shadow + glow
|
||||
- adds a CRT scanline overlay
|
||||
- disables the animation under prefers-reduced-motion
|
||||
- swaps the tint for a soft sepia wash in light mode (paper & ink feel)
|
||||
========================================================================== */
|
||||
|
||||
/* Full-screen ASCII mountain top layer ----------------------------------- */
|
||||
@@ -28,17 +29,18 @@
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace;
|
||||
font-size: max(0.35vw, 0.695vh);
|
||||
font-size: max(0.35vw, 0.695svh);
|
||||
/* font-size: max(0.7vw, 1.39vh); */ /* 240p */
|
||||
font-size: max(0.463vw, 0.926vh); /* 360p */
|
||||
line-height: 1.0;
|
||||
letter-spacing: 0;
|
||||
color: #f4a26b;
|
||||
text-shadow: 0 0 8px rgba(183, 65, 14, 0.35);
|
||||
opacity: 0.45;
|
||||
color: var(--tp-mountain-color, #f4a26b);
|
||||
text-shadow: 0 0 8px var(--tp-mountain-glow, rgba(183, 65, 14, 0.35));
|
||||
opacity: var(--tp-mountain-opacity, 0.45);
|
||||
white-space: pre;
|
||||
background: transparent;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
transition: color 250ms ease, opacity 250ms ease, text-shadow 250ms ease;
|
||||
}
|
||||
|
||||
/* CRT scanlines overlay - a thin moving line every 2px. Faint so it doesn't
|
||||
@@ -64,10 +66,13 @@
|
||||
100% { background-position: 0 6px; }
|
||||
}
|
||||
|
||||
/* Light theme: dim the background, drop the glow, switch to dark text. */
|
||||
/* ---------- Light theme: faded ink wash on paper ------------------------
|
||||
In winter mode the ASCII becomes a soft sepia watermark — a hint of
|
||||
"topography" rather than a glowing graphic. The scanlines swap to
|
||||
light-on-dark so they still add texture without darkening the page. */
|
||||
:root[data-theme="winter"] .tp-mountain-bg {
|
||||
opacity: 0.20;
|
||||
color: #2a1810;
|
||||
opacity: 0.12; /* much fainter than the dark mode rust */
|
||||
color: #6b5236; /* warm sepia, harmonizes with cream bg */
|
||||
text-shadow: none;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
@@ -77,10 +82,10 @@
|
||||
to bottom,
|
||||
transparent 0,
|
||||
transparent 2px,
|
||||
rgba(255, 255, 255, 0.12) 2px,
|
||||
rgba(255, 255, 255, 0.12) 3px
|
||||
rgba(28, 25, 23, 0.05) 2px,
|
||||
rgba(28, 25, 23, 0.05) 3px
|
||||
);
|
||||
mix-blend-mode: screen;
|
||||
mix-blend-mode: multiply;
|
||||
}
|
||||
|
||||
/* Reduced motion: keep the first frame static, no scanline drift. */
|
||||
|
||||
@@ -21,30 +21,128 @@ html {
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------- Theme (default to dark) -------------------------------------- */
|
||||
/* ---------- Theme tokens -------------------------------------------------
|
||||
Dark (night) is the default. The `[data-theme="winter"]` block redefines
|
||||
the same tokens for the light theme. Everything below reads from these. */
|
||||
:root {
|
||||
color-scheme: dark light;
|
||||
--tp-accent: #b7410e;
|
||||
--tp-accent-fg: #fff5f0;
|
||||
--tp-grid-line: rgba(63, 63, 70, 0.35);
|
||||
--tp-hero-from: #0b0b0f;
|
||||
--tp-hero-to: #18181b;
|
||||
--tp-text-outline: rgba(0, 0, 0, 0.9);
|
||||
|
||||
/* Brand (rust) */
|
||||
--tp-accent: #b7410e; /* primary accent */
|
||||
--tp-accent-strong: #d24e15; /* hover/active */
|
||||
--tp-accent-fg: #fff5f0; /* text-on-accent */
|
||||
--tp-accent-soft: rgba(183, 65, 14, 0.12);
|
||||
--tp-accent-glow: rgba(183, 65, 14, 0.35);
|
||||
|
||||
/* Surfaces (dark) */
|
||||
--tp-bg: #09090b; /* page bg */
|
||||
--tp-bg-elev: #18181b; /* raised surface */
|
||||
--tp-bg-soft: rgba(24, 24, 27, 0.5);
|
||||
--tp-bg-card: rgba(24, 24, 27, 0.5);
|
||||
--tp-bg-card-hover: rgba(24, 24, 27, 0.78);
|
||||
--tp-bg-nav: rgba(9, 9, 11, 0.65);
|
||||
--tp-bg-mobile: rgba(9, 9, 11, 0.95);
|
||||
--tp-bg-section: rgba(24, 24, 27, 0.3); /* alt section tint */
|
||||
--tp-bg-code: #0b0b0f;
|
||||
|
||||
/* Text (dark) */
|
||||
--tp-fg: #fafafa; /* primary text */
|
||||
--tp-fg-strong: #ffffff;
|
||||
--tp-fg-secondary: #d4d4d8; /* body */
|
||||
--tp-fg-muted: #a1a1aa;
|
||||
--tp-fg-subtle: #71717a;
|
||||
--tp-fg-code: #f4f4f5;
|
||||
|
||||
/* Borders (dark) */
|
||||
--tp-border: rgba(63, 63, 70, 0.5);
|
||||
--tp-border-strong: rgba(63, 63, 70, 0.7);
|
||||
--tp-border-section:rgba(63, 63, 70, 0.4);
|
||||
|
||||
/* Hero / grid (dark) */
|
||||
--tp-grid-line: rgba(63, 63, 70, 0.35);
|
||||
--tp-hero-from: #0b0b0f;
|
||||
--tp-hero-to: #18181b;
|
||||
--tp-text-outline: rgba(0, 0, 0, 0.9);
|
||||
--tp-hero-glow-a: rgba(183, 65, 14, 0.10);
|
||||
--tp-hero-glow-b: rgba(126, 231, 135, 0.05);
|
||||
|
||||
/* Mountain background (dark — rust on black) */
|
||||
--tp-mountain-color: #f4a26b;
|
||||
--tp-mountain-glow: rgba(183, 65, 14, 0.35);
|
||||
--tp-mountain-opacity:0.45;
|
||||
|
||||
/* Shadows (dark — soft + deep) */
|
||||
--tp-card-shadow: 0 1px 0 rgba(255, 255, 255, 0.02) inset,
|
||||
0 12px 24px -16px rgba(0, 0, 0, 0.6);
|
||||
--tp-card-shadow-hover:
|
||||
0 1px 0 rgba(255, 255, 255, 0.04) inset,
|
||||
0 18px 36px -18px rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
|
||||
/* Light theme — warm paper. We swap to a stone (warm-gray) palette so the
|
||||
text and surfaces harmonize with the rust accent instead of fighting it. */
|
||||
:root[data-theme="winter"] {
|
||||
--tp-accent: #93330c;
|
||||
--tp-accent-fg: #fff5f0;
|
||||
--tp-grid-line: rgba(228, 228, 231, 0.7);
|
||||
--tp-hero-from: #fafafa;
|
||||
--tp-hero-to: #f4f4f5;
|
||||
--tp-text-outline: rgba(255, 255, 255, 0.95);
|
||||
/* Brand — slightly darker rust so it has bite on a light bg */
|
||||
--tp-accent: #9a3a0e;
|
||||
--tp-accent-strong: #7f2f08;
|
||||
--tp-accent-fg: #fff7ed;
|
||||
--tp-accent-soft: rgba(154, 58, 14, 0.08);
|
||||
--tp-accent-glow: rgba(154, 58, 14, 0.0);
|
||||
|
||||
/* Surfaces (warm off-white, not stark) */
|
||||
--tp-bg: #fbfaf7; /* page bg, slight cream */
|
||||
--tp-bg-elev: #ffffff; /* cards */
|
||||
--tp-bg-soft: rgba(255, 255, 255, 0.7);
|
||||
--tp-bg-card: #ffffff;
|
||||
--tp-bg-card-hover: #ffffff;
|
||||
--tp-bg-nav: rgba(255, 255, 255, 0.78);
|
||||
--tp-bg-mobile: rgba(255, 255, 255, 0.97);
|
||||
--tp-bg-section: #f3f1ec; /* warm section alt */
|
||||
--tp-bg-code: #0b0b0f; /* keep code blocks dark in both themes */
|
||||
|
||||
/* Text (warm dark — stone, not zinc, so it doesn't look like a science lab) */
|
||||
--tp-fg: #1c1917; /* primary (stone-900) */
|
||||
--tp-fg-strong: #0c0a09; /* stone-950 */
|
||||
--tp-fg-secondary: #44403c; /* stone-700 */
|
||||
--tp-fg-muted: #57534e; /* stone-600 */
|
||||
--tp-fg-subtle: #78716c; /* stone-500 */
|
||||
--tp-fg-code: #f4f4f5;
|
||||
|
||||
/* Borders (warm taupe) */
|
||||
--tp-border: rgba(214, 211, 209, 0.9); /* stone-300 */
|
||||
--tp-border-strong: rgba(168, 162, 158, 0.8); /* stone-400 */
|
||||
--tp-border-section:rgba(214, 211, 209, 0.65);
|
||||
|
||||
/* Hero / grid (warm, very subtle) */
|
||||
--tp-grid-line: rgba(180, 130, 80, 0.14);
|
||||
--tp-hero-from: #fbfaf7;
|
||||
--tp-hero-to: #f5f3ee;
|
||||
--tp-text-outline: rgba(255, 255, 255, 0.95);
|
||||
--tp-hero-glow-a: rgba(154, 58, 14, 0.07);
|
||||
--tp-hero-glow-b: rgba(120, 140, 90, 0.05);
|
||||
|
||||
/* Mountain — very subtle, like a faded ink wash on paper */
|
||||
--tp-mountain-color: #8a6a44; /* warm sepia */
|
||||
--tp-mountain-glow: rgba(138, 106, 68, 0);
|
||||
--tp-mountain-opacity:0.10;
|
||||
|
||||
/* Shadows (soft, warm-tinted, like a printed page) */
|
||||
--tp-card-shadow: 0 1px 0 rgba(255, 255, 255, 1) inset,
|
||||
0 1px 2px rgba(28, 25, 23, 0.04),
|
||||
0 8px 24px -12px rgba(28, 25, 23, 0.10);
|
||||
--tp-card-shadow-hover:
|
||||
0 1px 0 rgba(255, 255, 255, 1) inset,
|
||||
0 1px 2px rgba(28, 25, 23, 0.05),
|
||||
0 14px 32px -14px rgba(154, 58, 14, 0.18);
|
||||
}
|
||||
|
||||
/* ---------- Body --------------------------------------------------------- */
|
||||
body {
|
||||
font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif;
|
||||
font-feature-settings: 'cv11', 'ss01', 'ss03';
|
||||
background-color: var(--tp-bg);
|
||||
color: var(--tp-fg);
|
||||
transition: background-color 200ms ease, color 200ms ease;
|
||||
}
|
||||
|
||||
/* ---------- View Transitions (progressive enhancement) ------------------ */
|
||||
@@ -80,6 +178,19 @@ body {
|
||||
1px 1px 0 var(--tp-text-outline),
|
||||
0 2px 16px rgba(0, 0, 0, 0.9);
|
||||
}
|
||||
:root[data-theme="winter"] .tp-hero h1,
|
||||
:root[data-theme="winter"] .tp-hero p {
|
||||
text-shadow:
|
||||
0 -1px 0 var(--tp-text-outline),
|
||||
1px 0 0 var(--tp-text-outline),
|
||||
0 1px 0 var(--tp-text-outline),
|
||||
-1px 0 0 var(--tp-text-outline),
|
||||
-1px -1px 0 var(--tp-text-outline),
|
||||
1px -1px 0 var(--tp-text-outline),
|
||||
-1px 1px 0 var(--tp-text-outline),
|
||||
1px 1px 0 var(--tp-text-outline),
|
||||
0 2px 12px rgba(154, 58, 14, 0.10);
|
||||
}
|
||||
|
||||
.tp-hero::before {
|
||||
content: "";
|
||||
@@ -96,8 +207,11 @@ body {
|
||||
z-index: -1;
|
||||
opacity: 0.5; /* subtle grid, not a wall */
|
||||
}
|
||||
:root[data-theme="winter"] .tp-hero::before {
|
||||
opacity: 0.7; /* show a touch more on paper */
|
||||
}
|
||||
|
||||
/* Subtle floating code lines in the hero, behind the content */
|
||||
/* Subtle floating glow in the hero, behind the content */
|
||||
.tp-hero-glow {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
@@ -105,43 +219,37 @@ body {
|
||||
z-index: -1;
|
||||
opacity: 0.6;
|
||||
background:
|
||||
radial-gradient(circle at 15% 30%, rgba(183, 65, 14, 0.08), transparent 35%),
|
||||
radial-gradient(circle at 85% 70%, rgba(126, 231, 135, 0.05), transparent 35%);
|
||||
radial-gradient(circle at 15% 30%, var(--tp-hero-glow-a), transparent 35%),
|
||||
radial-gradient(circle at 85% 70%, var(--tp-hero-glow-b), transparent 35%);
|
||||
}
|
||||
|
||||
/* ---------- Glass nav ---------------------------------------------------- */
|
||||
.tp-nav {
|
||||
background: rgba(9, 9, 11, 0.65);
|
||||
background: var(--tp-bg-nav);
|
||||
backdrop-filter: saturate(160%) blur(12px);
|
||||
-webkit-backdrop-filter: saturate(160%) blur(12px);
|
||||
border-bottom: 1px solid rgba(63, 63, 70, 0.4);
|
||||
}
|
||||
:root[data-theme="winter"] .tp-nav {
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
border-bottom-color: rgba(228, 228, 231, 0.7);
|
||||
border-bottom: 1px solid var(--tp-border);
|
||||
transition: background 200ms ease, border-color 200ms ease;
|
||||
}
|
||||
|
||||
/* ---------- Feature cards ------------------------------------------------ */
|
||||
.tp-card {
|
||||
position: relative;
|
||||
background: rgba(24, 24, 27, 0.5);
|
||||
border: 1px solid rgba(63, 63, 70, 0.5);
|
||||
background: var(--tp-bg-card);
|
||||
border: 1px solid var(--tp-border);
|
||||
border-radius: 1rem;
|
||||
padding: 1.5rem;
|
||||
transition: border-color 200ms ease, transform 200ms ease, background 200ms ease;
|
||||
box-shadow: var(--tp-card-shadow);
|
||||
transition: border-color 200ms ease, transform 200ms ease,
|
||||
background 200ms ease, box-shadow 200ms ease;
|
||||
}
|
||||
.tp-card:hover {
|
||||
border-color: rgba(183, 65, 14, 0.6);
|
||||
background: rgba(24, 24, 27, 0.75);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
:root[data-theme="winter"] .tp-card {
|
||||
background: rgba(255, 255, 255, 0.6);
|
||||
border-color: rgba(228, 228, 231, 0.8);
|
||||
background: var(--tp-bg-card-hover);
|
||||
box-shadow: var(--tp-card-shadow-hover);
|
||||
}
|
||||
:root[data-theme="winter"] .tp-card:hover {
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-color: rgba(183, 65, 14, 0.4);
|
||||
border-color: rgba(154, 58, 14, 0.4);
|
||||
}
|
||||
|
||||
.tp-card-icon {
|
||||
@@ -151,11 +259,14 @@ body {
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
border-radius: 0.75rem;
|
||||
background: rgba(183, 65, 14, 0.12);
|
||||
background: var(--tp-accent-soft);
|
||||
color: var(--tp-accent);
|
||||
border: 1px solid rgba(183, 65, 14, 0.25);
|
||||
border: 1px solid var(--tp-accent-glow);
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
:root[data-theme="winter"] .tp-card-icon {
|
||||
border-color: rgba(154, 58, 14, 0.18);
|
||||
}
|
||||
|
||||
/* ---------- Code blocks (kitchen sink — hljs + custom) ------------------ */
|
||||
.tp-code {
|
||||
@@ -165,13 +276,19 @@ body {
|
||||
tab-size: 4;
|
||||
}
|
||||
.tp-code pre {
|
||||
background: #0b0b0f;
|
||||
border: 1px solid rgba(63, 63, 70, 0.5);
|
||||
background: var(--tp-bg-code);
|
||||
border: 1px solid var(--tp-border);
|
||||
border-radius: 0.75rem;
|
||||
padding: 1.25rem 1.5rem;
|
||||
overflow-x: auto;
|
||||
margin: 0;
|
||||
}
|
||||
:root[data-theme="winter"] .tp-code pre {
|
||||
/* keep the code panel a little warmer on light pages, like a printed
|
||||
code listing on cream paper */
|
||||
border-color: rgba(0, 0, 0, 0.12);
|
||||
box-shadow: 0 12px 28px -16px rgba(28, 25, 23, 0.35);
|
||||
}
|
||||
.tp-code pre code.hljs {
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
@@ -185,17 +302,18 @@ body {
|
||||
font-family: 'JetBrains Mono', ui-monospace, monospace;
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
border: 1px solid rgba(63, 63, 70, 0.7);
|
||||
border: 1px solid var(--tp-border-strong);
|
||||
border-bottom-width: 2px;
|
||||
border-radius: 0.375rem;
|
||||
background: rgba(39, 39, 42, 0.6);
|
||||
color: #f4f4f5;
|
||||
color: var(--tp-fg-code);
|
||||
line-height: 1;
|
||||
}
|
||||
:root[data-theme="winter"] .tp-kbd {
|
||||
background: #fff;
|
||||
color: #18181b;
|
||||
border-color: #d4d4d8;
|
||||
background: #ffffff;
|
||||
color: #1c1917;
|
||||
border-color: #d6d3d1;
|
||||
box-shadow: 0 1px 0 rgba(28, 25, 23, 0.04);
|
||||
}
|
||||
|
||||
/* ---------- Terminal window wrapper -------------------------------------- */
|
||||
@@ -209,6 +327,12 @@ body {
|
||||
0 18px 36px -18px rgba(0, 0, 0, 0.45);
|
||||
overflow: hidden;
|
||||
}
|
||||
:root[data-theme="winter"] .tp-terminal {
|
||||
box-shadow:
|
||||
0 0 0 1px rgba(154, 58, 14, 0.18),
|
||||
0 24px 48px -20px rgba(154, 58, 14, 0.22),
|
||||
0 12px 24px -16px rgba(28, 25, 23, 0.10);
|
||||
}
|
||||
.tp-terminal::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
@@ -224,6 +348,15 @@ body {
|
||||
); /* darken only the top + bottom strips, leave the middle transparent
|
||||
so the body ASCII art shows through the terminal content */
|
||||
}
|
||||
:root[data-theme="winter"] .tp-terminal::after {
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
rgba(255, 255, 255, 0.10) 0%,
|
||||
rgba(255, 255, 255, 0) 18%,
|
||||
rgba(255, 255, 255, 0) 82%,
|
||||
rgba(255, 255, 255, 0.10) 100%
|
||||
);
|
||||
}
|
||||
|
||||
/* ---------- Selection --------------------------------------------------- */
|
||||
::selection {
|
||||
@@ -242,27 +375,153 @@ body {
|
||||
::-webkit-scrollbar { width: 10px; height: 10px; }
|
||||
::-webkit-scrollbar-track { background: transparent; }
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: rgba(63, 63, 70, 0.6);
|
||||
background: var(--tp-border-strong);
|
||||
border-radius: 999px;
|
||||
border: 2px solid transparent;
|
||||
background-clip: padding-box;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover { background-color: rgba(82, 82, 91, 0.8); background-clip: padding-box; }
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--tp-fg-subtle);
|
||||
background-clip: padding-box;
|
||||
}
|
||||
|
||||
/* ---------- No-FOUC theme flash ----------------------------------------- */
|
||||
html:not([data-theme]) body { background: #09090b; }
|
||||
:root[data-theme="winter"] body { background: #fafafa; }
|
||||
|
||||
/* ---------- Alpine x-cloak (prevents flash of un-initialised content) --- */
|
||||
[x-cloak] { display: none !important; }
|
||||
|
||||
/* ---------- DaisyUI overrides for our theme ----------------------------- */
|
||||
/* Bring DaisyUI's primary to our accent so .btn-primary etc. look on-brand. */
|
||||
[data-theme="night"] {
|
||||
--p: 28 70% 36%;
|
||||
--pc: 0 0% 100%;
|
||||
--b1: 240 5% 8%;
|
||||
--b2: 240 4% 12%;
|
||||
--b3: 240 4% 16%;
|
||||
--bc: 0 0% 96%;
|
||||
/* ==========================================================================
|
||||
THEME-AWARE TAILWIND OVERRIDES
|
||||
--------------------------------------------------------------------------
|
||||
The HTML uses hardcoded `text-zinc-*`, `bg-zinc-*`, `border-zinc-*` etc.
|
||||
(so the source reads like a normal dark-mode-first site). In light mode
|
||||
we transparently remap those zinc slots to our warm stone palette.
|
||||
This block has higher selector specificity (`:root[data-theme=...] .foo`)
|
||||
than the Tailwind utility class on its own, so it wins without `!important`.
|
||||
========================================================================== */
|
||||
:root[data-theme="winter"] {
|
||||
|
||||
/* ---- DaisyUI body tokens ----------------------------------------------
|
||||
daisyUI 4 uses OKLCH under the hood (`oklch(var(--b1) / .N)`); our custom
|
||||
HSL-flavoured values don't parse, so `bg-base-100` would resolve to
|
||||
transparent. We override the class directly with our token-driven colour. */
|
||||
.bg-base-100 { background-color: var(--tp-bg); }
|
||||
.text-base-content { color: var(--tp-fg); }
|
||||
|
||||
/* ---- text ---- */
|
||||
.text-zinc-50 { color: #0c0a09; }
|
||||
.text-zinc-100 { color: #1c1917; }
|
||||
.text-zinc-200 { color: #292524; }
|
||||
.text-zinc-300 { color: #44403c; }
|
||||
.text-zinc-400 { color: #57534e; }
|
||||
.text-zinc-500 { color: #78716c; }
|
||||
.text-zinc-600 { color: #57534e; }
|
||||
.text-zinc-700 { color: #d6d3d1; } /* dividers + rare text */
|
||||
.text-zinc-800 { color: #e7e5e4; }
|
||||
.text-zinc-900 { color: #ffffff; }
|
||||
.text-zinc-950 { color: #ffffff; }
|
||||
.text-white { color: #1c1917; }
|
||||
|
||||
/* ---- backgrounds ---- */
|
||||
.bg-zinc-50 { background-color: #fafaf9; }
|
||||
.bg-zinc-100 { background-color: #f5f5f4; }
|
||||
.bg-zinc-200 { background-color: #e7e5e4; }
|
||||
.bg-zinc-300 { background-color: #d6d3d1; }
|
||||
.bg-zinc-400 { background-color: #a8a29e; }
|
||||
.bg-zinc-500 { background-color: #78716c; }
|
||||
.bg-zinc-600 { background-color: #57534e; }
|
||||
.bg-zinc-700 { background-color: #d6d3d1; }
|
||||
.bg-zinc-800 { background-color: #e7e5e4; }
|
||||
.bg-zinc-900 { background-color: #ffffff; }
|
||||
.bg-zinc-900\/40 { background-color: rgba(255, 255, 255, 0.65); }
|
||||
.bg-zinc-900\/50 { background-color: rgba(255, 255, 255, 0.75); }
|
||||
.bg-zinc-900\/60 { background-color: rgba(255, 255, 255, 0.85); }
|
||||
.bg-zinc-950 { background-color: #ffffff; }
|
||||
.bg-zinc-950\/30 { background-color: #f3f1ec; } /* section alt */
|
||||
.bg-zinc-950\/40 { background-color: #f5f3ee; } /* trust strip */
|
||||
.bg-zinc-950\/50 { background-color: #ffffff; }
|
||||
.bg-zinc-950\/60 { background-color: #ffffff; }
|
||||
.bg-zinc-950\/80 { background-color: #ffffff; }
|
||||
.bg-zinc-950\/95 { background-color: #ffffff; }
|
||||
|
||||
/* ---- borders ---- */
|
||||
.border-zinc-700 { border-color: #d6d3d1; }
|
||||
.border-zinc-800 { border-color: #e7e5e4; }
|
||||
.border-zinc-800\/40 { border-color: rgba(214, 211, 209, 0.55); }
|
||||
.border-zinc-800\/60 { border-color: rgba(214, 211, 209, 0.75); }
|
||||
.border-zinc-900\/50 { border-color: rgba(214, 211, 209, 0.7); }
|
||||
|
||||
/* The decoration on links (ratatui etc) */
|
||||
.decoration-zinc-700 { text-decoration-color: #d6d3d1; }
|
||||
|
||||
/* ---- hover states (mirror the text/bg map, with a touch more contrast) ---- */
|
||||
.hover\:text-white:hover { color: #0c0a09; }
|
||||
.hover\:text-zinc-100:hover { color: #0c0a09; }
|
||||
.hover\:text-zinc-200:hover { color: #1c1917; }
|
||||
.hover\:text-zinc-300:hover { color: #1c1917; }
|
||||
.hover\:text-zinc-400:hover { color: #1c1917; }
|
||||
.hover\:bg-zinc-800\/50:hover { background-color: rgba(231, 229, 228, 0.7); }
|
||||
.hover\:bg-zinc-800\/60:hover { background-color: rgba(231, 229, 228, 0.85); }
|
||||
.hover\:bg-zinc-900:hover { background-color: #f5f3ee; }
|
||||
.hover\:border-zinc-500:hover { border-color: #a8a29e; }
|
||||
.hover\:border-zinc-700:hover { border-color: #a8a29e; }
|
||||
.hover\:decoration-accent:hover { text-decoration-color: var(--tp-accent); }
|
||||
|
||||
/* ---- accent (rust) — slightly darker on light for legibility ---- */
|
||||
.text-accent { color: #9a3a0e; }
|
||||
.bg-accent { background-color: #9a3a0e; }
|
||||
.bg-accent\/5 { background-color: rgba(154, 58, 14, 0.05); }
|
||||
.bg-accent\/10 { background-color: rgba(154, 58, 14, 0.08); }
|
||||
.bg-accent\/15 { background-color: rgba(154, 58, 14, 0.12); }
|
||||
.border-accent { border-color: #9a3a0e; }
|
||||
.border-accent\/30 { border-color: rgba(154, 58, 14, 0.25); }
|
||||
.border-accent\/40 { border-color: rgba(154, 58, 14, 0.35); }
|
||||
.border-accent\/60 { border-color: rgba(154, 58, 14, 0.55); }
|
||||
.hover\:bg-accent\/90:hover { background-color: #7f2f08; }
|
||||
.hover\:border-accent\/60:hover { border-color: rgba(154, 58, 14, 0.55); }
|
||||
.hover\:text-accent:hover { color: #9a3a0e; }
|
||||
.from-accent\/15 { --tw-gradient-from: rgba(154, 58, 14, 0.18); --tw-gradient-to: rgba(154, 58, 14, 0); --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); }
|
||||
.to-emerald-500\/5 { --tw-gradient-to: rgba(16, 185, 129, 0.06); }
|
||||
|
||||
/* ---- tab pill in code-example tab bar ---- */
|
||||
.bg-zinc-800 { background-color: #e7e5e4; }
|
||||
.bg-zinc-800.text-white { color: #1c1917; }
|
||||
}
|
||||
|
||||
/* ==========================================================================
|
||||
DaisyUI overrides for our theme
|
||||
--------------------------------------------------------------------------
|
||||
DaisyUI 4 ships a built-in `night` theme — we already use it for dark.
|
||||
`winter` is our own theme, so we register its HSL tokens so things like
|
||||
`.bg-base-100` and `.text-base-content` resolve correctly.
|
||||
Format is "H S% L%" (no hsl() wrapper) — DaisyUI concatenates.
|
||||
========================================================================== */
|
||||
[data-theme="night"] {
|
||||
--p: 20 75% 38%; /* primary — rust */
|
||||
--pc: 20 100% 97%;
|
||||
--b1: 240 6% 7%; /* base 100 */
|
||||
--b2: 240 5% 11%;
|
||||
--b3: 240 5% 14%;
|
||||
--bc: 0 0% 96%; /* base content */
|
||||
/* DaisyUI 4 expects OKLCH and ignores HSL on modern browsers. Provide
|
||||
the fallback so the body has a real colour even if OKLCH parsing fails. */
|
||||
--fallback-b1: #09090b;
|
||||
--fallback-bc: #fafafa;
|
||||
/* Make DaisyUI semantic tokens resolve to our rust accent. */
|
||||
.bg-base-100 { background-color: var(--tp-bg); }
|
||||
.text-base-content { color: var(--tp-fg); }
|
||||
}
|
||||
|
||||
[data-theme="winter"] {
|
||||
--p: 19 82% 32%; /* primary — darker rust, sits on cream */
|
||||
--pc: 30 100% 97%;
|
||||
--b1: 36 25% 97%; /* base 100 — warm paper */
|
||||
--b2: 36 18% 94%;
|
||||
--b3: 36 12% 89%;
|
||||
--bc: 24 12% 12%; /* base content — warm near-black */
|
||||
--n: 24 10% 18%; /* neutral */
|
||||
--nc: 36 25% 97%;
|
||||
--fallback-b1: #fbfaf7;
|
||||
--fallback-bc: #1c1917;
|
||||
}
|
||||
|
||||
120
static/img/terminal-canvas-light.svg
Normal file
@@ -0,0 +1,120 @@
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="A text editor built with the tui-pages textarea: relative line numbers and Rust syntax highlighting">
|
||||
<!-- Light-mode twin of terminal-canvas.svg. Same 80x25 grid, light neutral palette. -->
|
||||
<style>
|
||||
.text { fill: #26272b; }
|
||||
.muted { fill: #5a5a62; }
|
||||
.dim { fill: #8a8a90; }
|
||||
.blue { fill: #1f7fb8; }
|
||||
.gold { fill: #a8862a; }
|
||||
.green { fill: #1f9d3f; }
|
||||
.pink { fill: #d6398b; }
|
||||
.greenfg{ fill: #f2fff2; }
|
||||
.curfg { fill: #f4f4f2; }
|
||||
.b { font-weight: 700; }
|
||||
text {
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
||||
font-size: 13px;
|
||||
text-rendering: geometricPrecision;
|
||||
}
|
||||
</style>
|
||||
|
||||
<g xml:space="preserve">
|
||||
<rect x="0.5" y="0.5" width="639" height="399" rx="10" fill="#f4f4f2" stroke="#d8d8d2"/>
|
||||
|
||||
<rect x="0" y="2" width="72" height="20" class="green"/>
|
||||
<text x="8" y="16" class="greenfg b">main.rs</text>
|
||||
<text x="80" y="16" class="muted">lib.rs</text>
|
||||
<text x="144" y="16" class="muted">Cargo.toml</text>
|
||||
|
||||
<rect x="0" y="96" width="640" height="16" fill="#e7e7e3"/>
|
||||
|
||||
<text x="16" y="44" class="dim" text-anchor="end">4</text>
|
||||
<text x="16" y="60" class="dim" text-anchor="end">3</text>
|
||||
<text x="16" y="76" class="dim" text-anchor="end">2</text>
|
||||
<text x="16" y="92" class="dim" text-anchor="end">1</text>
|
||||
<text x="8" y="108" class="gold b">5</text>
|
||||
<text x="16" y="124" class="dim" text-anchor="end">1</text>
|
||||
<text x="16" y="140" class="dim" text-anchor="end">2</text>
|
||||
<text x="16" y="156" class="dim" text-anchor="end">3</text>
|
||||
<text x="16" y="172" class="dim" text-anchor="end">4</text>
|
||||
<text x="16" y="188" class="dim" text-anchor="end">5</text>
|
||||
<text x="16" y="204" class="dim" text-anchor="end">6</text>
|
||||
|
||||
<text x="32" y="44" class="pink">use</text>
|
||||
<text x="64" y="44" class="text">tui_pages</text>
|
||||
<text x="136" y="44" class="muted">::</text>
|
||||
<text x="152" y="44" class="muted">{</text>
|
||||
<text x="160" y="44" class="gold">Page</text>
|
||||
<text x="192" y="44" class="muted">,</text>
|
||||
<text x="208" y="44" class="gold">TextArea</text>
|
||||
<text x="272" y="44" class="muted">}</text>
|
||||
<text x="280" y="44" class="muted">;</text>
|
||||
|
||||
<text x="32" y="76" class="pink">pub</text>
|
||||
<text x="64" y="76" class="pink">fn</text>
|
||||
<text x="88" y="76" class="blue">editor</text>
|
||||
<text x="136" y="76" class="muted">()</text>
|
||||
<text x="160" y="76" class="muted">-></text>
|
||||
<text x="184" y="76" class="gold">Page</text>
|
||||
<text x="224" y="76" class="muted">{</text>
|
||||
|
||||
<text x="64" y="92" class="pink">let</text>
|
||||
<text x="96" y="92" class="text">title</text>
|
||||
<text x="144" y="92" class="muted">=</text>
|
||||
<text x="160" y="92" class="green">"Editor"</text>
|
||||
<text x="224" y="92" class="muted">;</text>
|
||||
|
||||
<text x="64" y="108" class="pink">let</text>
|
||||
<text x="96" y="108" class="pink">mut</text>
|
||||
<rect x="128" y="96" width="8" height="16" fill="#26272b"/>
|
||||
<text x="128" y="108" class="curfg">a</text>
|
||||
<text x="136" y="108" class="text">rea</text>
|
||||
<text x="168" y="108" class="muted">=</text>
|
||||
<text x="184" y="108" class="gold">TextArea</text>
|
||||
<text x="248" y="108" class="muted">::</text>
|
||||
<text x="264" y="108" class="blue">default</text>
|
||||
<text x="320" y="108" class="muted">()</text>
|
||||
<text x="336" y="108" class="muted">;</text>
|
||||
|
||||
<text x="64" y="124" class="text">area</text>
|
||||
<text x="96" y="124" class="muted">.</text>
|
||||
<text x="104" y="124" class="blue">set_placeholder</text>
|
||||
<text x="224" y="124" class="muted">(</text>
|
||||
<text x="232" y="124" class="green">"Type here…"</text>
|
||||
<text x="328" y="124" class="muted">)</text>
|
||||
<text x="336" y="124" class="muted">;</text>
|
||||
|
||||
<text x="64" y="156" class="gold">Page</text>
|
||||
<text x="96" y="156" class="muted">::</text>
|
||||
<text x="112" y="156" class="blue">new</text>
|
||||
<text x="136" y="156" class="muted">(</text>
|
||||
<text x="144" y="156" class="text">title</text>
|
||||
<text x="184" y="156" class="muted">)</text>
|
||||
|
||||
<text x="96" y="172" class="muted">.</text>
|
||||
<text x="104" y="172" class="blue">child</text>
|
||||
<text x="144" y="172" class="muted">(</text>
|
||||
<text x="152" y="172" class="text">area</text>
|
||||
<text x="184" y="172" class="muted">)</text>
|
||||
|
||||
<text x="96" y="188" class="muted">.</text>
|
||||
<text x="104" y="188" class="blue">on_key</text>
|
||||
<text x="152" y="188" class="muted">(</text>
|
||||
<text x="160" y="188" class="green">'q'</text>
|
||||
<text x="184" y="188" class="muted">,</text>
|
||||
<text x="200" y="188" class="muted">|</text>
|
||||
<text x="208" y="188" class="text">app</text>
|
||||
<text x="232" y="188" class="muted">|</text>
|
||||
<text x="248" y="188" class="text">app</text>
|
||||
<text x="272" y="188" class="muted">.</text>
|
||||
<text x="280" y="188" class="blue">quit</text>
|
||||
<text x="312" y="188" class="muted">())</text>
|
||||
|
||||
<text x="32" y="204" class="muted">}</text>
|
||||
|
||||
<text x="32" y="380" class="green b">NOR</text>
|
||||
<text x="120" y="380" class="muted">main.rs</text>
|
||||
<text x="256" y="380" class="muted">Ln 5, Col 18</text>
|
||||
<text x="632" y="380" class="gold" text-anchor="end">tui-pages v0.7.2 │ 60 FPS</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -1,52 +1,138 @@
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="examples/canvas terminal screenshot">
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="A text editor built with the tui-pages textarea: relative line numbers and Rust syntax highlighting">
|
||||
<!--
|
||||
tui-pages textarea showcased as a modal-editor (vim/helix style) on a strict
|
||||
80x25 monospace grid (cell = 8x16 px). Each cell carries at most two colors.
|
||||
Gutter: current line shows its absolute number, others are relative.
|
||||
Syntax: kw=pink, type=gold, fn=blue, string=green, punctuation=muted.
|
||||
-->
|
||||
<style>
|
||||
.bg { fill: #18181b; }
|
||||
.chrome { fill: #27272a; }
|
||||
.dot { fill: #52525b; }
|
||||
.field { fill: #0e0e10; stroke: #3f3f46; stroke-width: 1; }
|
||||
.field-focus { fill: #1c130f; stroke: #b7410e; stroke-width: 2; }
|
||||
.btn { fill: #b7410e; }
|
||||
.sep { stroke: #27272a; stroke-width: 1; }
|
||||
text { font-family: ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace; fill: #f4f4f5; }
|
||||
.t-md { font-size: 14px; }
|
||||
.t-sm { font-size: 12px; }
|
||||
.t-xs { font-size: 11px; }
|
||||
.muted { fill: #a1a1aa; }
|
||||
.dim { fill: #71717a; }
|
||||
.label { fill: #a1a1aa; letter-spacing: 0.08em; }
|
||||
.btn-fg { fill: #fff5f0; }
|
||||
.text { fill: #d7d7db; }
|
||||
.muted { fill: #9a9aa2; }
|
||||
.dim { fill: #6b6b72; }
|
||||
.blue { fill: #3ba7e0; }
|
||||
.gold { fill: #d9b54a; }
|
||||
.green { fill: #46d160; }
|
||||
.pink { fill: #f25fa0; }
|
||||
.greenfg{ fill: #0c130c; }
|
||||
.curfg { fill: #1a1b1e; }
|
||||
.b { font-weight: 700; }
|
||||
text {
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
||||
font-size: 13px;
|
||||
text-rendering: geometricPrecision;
|
||||
}
|
||||
</style>
|
||||
|
||||
<rect class="bg" width="640" height="400" rx="12"/>
|
||||
<rect class="chrome" width="640" height="36" rx="12"/>
|
||||
<rect class="chrome" y="24" width="640" height="12"/>
|
||||
<line class="sep" x1="0" y1="36" x2="640" y2="36"/>
|
||||
<g xml:space="preserve">
|
||||
<rect x="0.5" y="0.5" width="639" height="399" rx="10" fill="#1a1b1e" stroke="#2a2b30"/>
|
||||
|
||||
<circle class="dot" cx="20" cy="18" r="5.5"/>
|
||||
<circle class="dot" cx="40" cy="18" r="5.5"/>
|
||||
<circle class="dot" cx="60" cy="18" r="5.5"/>
|
||||
<!-- buffer tabs (main.rs active) -->
|
||||
<rect x="0" y="2" width="72" height="20" class="green"/>
|
||||
<text x="8" y="16" class="greenfg b">main.rs</text>
|
||||
<text x="80" y="16" class="muted">lib.rs</text>
|
||||
<text x="144" y="16" class="muted">Cargo.toml</text>
|
||||
|
||||
<text x="320" y="22" text-anchor="middle" font-size="11" class="dim">examples/canvas — login page</text>
|
||||
<!-- cursorline -->
|
||||
<rect x="0" y="96" width="640" height="16" fill="#232428"/>
|
||||
|
||||
<text x="40" y="80" font-size="20" font-weight="700">Sign in</text>
|
||||
<text x="40" y="104" font-size="12" class="muted">Use Tab to move between fields. Enter to submit.</text>
|
||||
<!-- gutter: relative numbers, current line absolute -->
|
||||
<text x="16" y="44" class="dim" text-anchor="end">4</text>
|
||||
<text x="16" y="60" class="dim" text-anchor="end">3</text>
|
||||
<text x="16" y="76" class="dim" text-anchor="end">2</text>
|
||||
<text x="16" y="92" class="dim" text-anchor="end">1</text>
|
||||
<text x="8" y="108" class="gold b">5</text>
|
||||
<text x="16" y="124" class="dim" text-anchor="end">1</text>
|
||||
<text x="16" y="140" class="dim" text-anchor="end">2</text>
|
||||
<text x="16" y="156" class="dim" text-anchor="end">3</text>
|
||||
<text x="16" y="172" class="dim" text-anchor="end">4</text>
|
||||
<text x="16" y="188" class="dim" text-anchor="end">5</text>
|
||||
<text x="16" y="204" class="dim" text-anchor="end">6</text>
|
||||
|
||||
<text x="40" y="156" font-size="10" class="label">USERNAME</text>
|
||||
<rect class="field-focus" x="40" y="164" width="560" height="38" rx="6"/>
|
||||
<text x="56" y="189" font-size="14">filip</text>
|
||||
<rect x="92" y="172" width="2" height="22" fill="#b7410e">
|
||||
<animate attributeName="opacity" values="1;0;1" dur="1s" repeatCount="indefinite"/>
|
||||
</rect>
|
||||
<!-- line 1: use tui_pages::{Page, TextArea}; -->
|
||||
<text x="32" y="44" class="pink">use</text>
|
||||
<text x="64" y="44" class="text">tui_pages</text>
|
||||
<text x="136" y="44" class="muted">::</text>
|
||||
<text x="152" y="44" class="muted">{</text>
|
||||
<text x="160" y="44" class="gold">Page</text>
|
||||
<text x="192" y="44" class="muted">,</text>
|
||||
<text x="208" y="44" class="gold">TextArea</text>
|
||||
<text x="272" y="44" class="muted">}</text>
|
||||
<text x="280" y="44" class="muted">;</text>
|
||||
|
||||
<text x="40" y="232" font-size="10" class="label">PASSWORD</text>
|
||||
<rect class="field" x="40" y="240" width="560" height="38" rx="6"/>
|
||||
<text x="56" y="265" font-size="14" class="muted">••••••••••••</text>
|
||||
<!-- line 3: pub fn editor() -> Page { -->
|
||||
<text x="32" y="76" class="pink">pub</text>
|
||||
<text x="64" y="76" class="pink">fn</text>
|
||||
<text x="88" y="76" class="blue">editor</text>
|
||||
<text x="136" y="76" class="muted">()</text>
|
||||
<text x="160" y="76" class="muted">-></text>
|
||||
<text x="184" y="76" class="gold">Page</text>
|
||||
<text x="224" y="76" class="muted">{</text>
|
||||
|
||||
<rect class="btn" x="40" y="300" width="140" height="38" rx="6"/>
|
||||
<text x="110" y="324" text-anchor="middle" font-size="13" class="btn-fg" font-weight="600">Sign in</text>
|
||||
<text x="200" y="324" font-size="11" class="dim">esc · cancel</text>
|
||||
<!-- line 4: let title = "Editor"; -->
|
||||
<text x="64" y="92" class="pink">let</text>
|
||||
<text x="96" y="92" class="text">title</text>
|
||||
<text x="144" y="92" class="muted">=</text>
|
||||
<text x="160" y="92" class="green">"Editor"</text>
|
||||
<text x="224" y="92" class="muted">;</text>
|
||||
|
||||
<line class="sep" x1="0" y1="358" x2="640" y2="358"/>
|
||||
<text x="20" y="380" font-size="11" class="dim">tab next · shift+tab prev · enter submit</text>
|
||||
<text x="620" y="380" text-anchor="end" font-size="11" class="dim">canvas feature enabled</text>
|
||||
<!-- line 5 (current): let mut area = TextArea::default(); -->
|
||||
<text x="64" y="108" class="pink">let</text>
|
||||
<text x="96" y="108" class="pink">mut</text>
|
||||
<rect x="128" y="96" width="8" height="16" fill="#d7d7db"/>
|
||||
<text x="128" y="108" class="curfg">a</text>
|
||||
<text x="136" y="108" class="text">rea</text>
|
||||
<text x="168" y="108" class="muted">=</text>
|
||||
<text x="184" y="108" class="gold">TextArea</text>
|
||||
<text x="248" y="108" class="muted">::</text>
|
||||
<text x="264" y="108" class="blue">default</text>
|
||||
<text x="320" y="108" class="muted">()</text>
|
||||
<text x="336" y="108" class="muted">;</text>
|
||||
|
||||
<!-- line 6: area.set_placeholder("Type here…"); -->
|
||||
<text x="64" y="124" class="text">area</text>
|
||||
<text x="96" y="124" class="muted">.</text>
|
||||
<text x="104" y="124" class="blue">set_placeholder</text>
|
||||
<text x="224" y="124" class="muted">(</text>
|
||||
<text x="232" y="124" class="green">"Type here…"</text>
|
||||
<text x="328" y="124" class="muted">)</text>
|
||||
<text x="336" y="124" class="muted">;</text>
|
||||
|
||||
<!-- line 8: Page::new(title) -->
|
||||
<text x="64" y="156" class="gold">Page</text>
|
||||
<text x="96" y="156" class="muted">::</text>
|
||||
<text x="112" y="156" class="blue">new</text>
|
||||
<text x="136" y="156" class="muted">(</text>
|
||||
<text x="144" y="156" class="text">title</text>
|
||||
<text x="184" y="156" class="muted">)</text>
|
||||
|
||||
<!-- line 9: .child(area) -->
|
||||
<text x="96" y="172" class="muted">.</text>
|
||||
<text x="104" y="172" class="blue">child</text>
|
||||
<text x="144" y="172" class="muted">(</text>
|
||||
<text x="152" y="172" class="text">area</text>
|
||||
<text x="184" y="172" class="muted">)</text>
|
||||
|
||||
<!-- line 10: .on_key('q', |app| app.quit()) -->
|
||||
<text x="96" y="188" class="muted">.</text>
|
||||
<text x="104" y="188" class="blue">on_key</text>
|
||||
<text x="152" y="188" class="muted">(</text>
|
||||
<text x="160" y="188" class="green">'q'</text>
|
||||
<text x="184" y="188" class="muted">,</text>
|
||||
<text x="200" y="188" class="muted">|</text>
|
||||
<text x="208" y="188" class="text">app</text>
|
||||
<text x="232" y="188" class="muted">|</text>
|
||||
<text x="248" y="188" class="text">app</text>
|
||||
<text x="272" y="188" class="muted">.</text>
|
||||
<text x="280" y="188" class="blue">quit</text>
|
||||
<text x="312" y="188" class="muted">())</text>
|
||||
|
||||
<!-- line 11: } -->
|
||||
<text x="32" y="204" class="muted">}</text>
|
||||
|
||||
<!-- status line -->
|
||||
<text x="32" y="380" class="green b">NOR</text>
|
||||
<text x="120" y="380" class="muted">main.rs</text>
|
||||
<text x="256" y="380" class="muted">Ln 5, Col 18</text>
|
||||
<text x="632" y="380" class="gold" text-anchor="end">tui-pages v0.7.2 │ 60 FPS</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 6.0 KiB |
80
static/img/terminal-default-light.svg
Normal file
@@ -0,0 +1,80 @@
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="A register screen built with tui-pages: tab bar, rounded panel, and first-class role autocomplete">
|
||||
<!-- Light-mode twin of terminal-default.svg. Same 80x25 grid, light neutral palette. -->
|
||||
<style>
|
||||
.text { fill: #26272b; }
|
||||
.muted { fill: #5a5a62; }
|
||||
.dim { fill: #8a8a90; }
|
||||
.ghost { fill: #9a9aa2; }
|
||||
.blue { fill: #1f7fb8; }
|
||||
.gold { fill: #a8862a; }
|
||||
.green { fill: #1f9d3f; }
|
||||
.peachfg{ fill: #2a1c08; }
|
||||
.greenfg{ fill: #f2fff2; }
|
||||
.b { font-weight: 700; }
|
||||
text {
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
||||
font-size: 13px;
|
||||
text-rendering: geometricPrecision;
|
||||
}
|
||||
</style>
|
||||
|
||||
<g xml:space="preserve">
|
||||
<rect x="0.5" y="0.5" width="639" height="399" rx="10" fill="#f4f4f2" stroke="#d8d8d2"/>
|
||||
|
||||
<text x="8" y="16" class="muted">Login</text>
|
||||
<rect x="56" y="2" width="80" height="20" class="green"/>
|
||||
<text x="64" y="16" class="greenfg b">Register</text>
|
||||
<text x="144" y="16" class="muted">Admin_Panel</text>
|
||||
<text x="248" y="16" class="muted">Quit</text>
|
||||
|
||||
<text x="168" y="60" class="blue b" textLength="304" lengthAdjust="spacing">╭─ Register ─────────────────────────╮</text>
|
||||
<text x="168" y="76" class="blue">│</text><text x="464" y="76" class="blue">│</text>
|
||||
<text x="168" y="92" class="blue">│</text><text x="464" y="92" class="blue">│</text>
|
||||
<text x="168" y="108" class="blue">│</text><text x="464" y="108" class="blue">│</text>
|
||||
<text x="168" y="124" class="blue">│</text><text x="464" y="124" class="blue">│</text>
|
||||
<text x="168" y="140" class="blue">│</text><text x="464" y="140" class="blue">│</text>
|
||||
<text x="168" y="156" class="blue">│</text><text x="464" y="156" class="blue">│</text>
|
||||
<text x="168" y="172" class="blue">│</text><text x="464" y="172" class="blue">│</text>
|
||||
<text x="168" y="188" class="blue">│</text><text x="464" y="188" class="blue">│</text>
|
||||
<text x="168" y="204" class="blue">│</text><text x="464" y="204" class="blue">│</text>
|
||||
<text x="168" y="220" class="blue">│</text><text x="464" y="220" class="blue">│</text>
|
||||
<text x="168" y="236" class="blue">│</text><text x="464" y="236" class="blue">│</text>
|
||||
<text x="168" y="252" class="blue">│</text><text x="464" y="252" class="blue">│</text>
|
||||
<text x="168" y="268" class="blue">│</text><text x="464" y="268" class="blue">│</text>
|
||||
<text x="168" y="284" class="blue">│</text><text x="464" y="284" class="blue">│</text>
|
||||
<text x="168" y="300" class="blue">│</text><text x="464" y="300" class="blue">│</text>
|
||||
<text x="168" y="316" class="blue">│</text><text x="464" y="316" class="blue">│</text>
|
||||
<text x="168" y="332" class="blue">│</text><text x="464" y="332" class="blue">│</text>
|
||||
<text x="168" y="348" class="blue" textLength="304" lengthAdjust="spacing">╰────────────────────────────────────╯</text>
|
||||
|
||||
<text x="184" y="92" class="muted">Create your account</text>
|
||||
|
||||
<text x="184" y="124" class="muted">Email</text>
|
||||
<text x="280" y="124" class="text">ada@acme.io</text>
|
||||
|
||||
<text x="184" y="156" class="muted">Password</text>
|
||||
<text x="280" y="156" class="muted">••••••••••</text>
|
||||
|
||||
<text x="184" y="188" class="muted">Confirm</text>
|
||||
<text x="280" y="188" class="muted">••••••••••</text>
|
||||
|
||||
<text x="184" y="220" class="muted">Role</text>
|
||||
<text x="280" y="220" class="text">a</text>
|
||||
<rect x="288" y="208" width="2" height="15" fill="#c98a2a"/>
|
||||
<text x="288" y="220" class="ghost">dmin</text>
|
||||
|
||||
<rect x="280" y="224" width="96" height="32" fill="#ffffff"/>
|
||||
<rect x="280" y="224" width="96" height="16" fill="#f0c27a"/>
|
||||
<text x="280" y="236" class="peachfg b">admin</text>
|
||||
<text x="280" y="252" class="text">accountant</text>
|
||||
|
||||
<text x="184" y="300" class="green b" textLength="144" lengthAdjust="spacing">╭────────────────╮</text>
|
||||
<text x="184" y="316" class="green b" textLength="144" lengthAdjust="spacing">│ Create account │</text>
|
||||
<text x="184" y="332" class="green b" textLength="144" lengthAdjust="spacing">╰────────────────╯</text>
|
||||
<text x="360" y="316" class="dim">enter ↵</text>
|
||||
|
||||
<text x="32" y="380" class="green b">INS</text>
|
||||
<text x="72" y="380" class="muted">[+]</text>
|
||||
<text x="632" y="380" class="gold" text-anchor="end">tui-pages v0.7.2 │ 60 FPS</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.7 KiB |
@@ -1,57 +1,93 @@
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="examples/default terminal screenshot">
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="A register screen built with tui-pages: tab bar, rounded panel, and first-class role autocomplete">
|
||||
<!--
|
||||
tui-pages UX showcase on a strict 80x25 monospace grid (cell = 8x16 px).
|
||||
Each cell carries at most two colors (fg + bg), like a real terminal buffer.
|
||||
Frames use rounded box-drawing chars; fills/highlights are grid-snapped rects.
|
||||
-->
|
||||
<style>
|
||||
.bg { fill: transparent; stroke: #3f3f46; stroke-width: 1; }
|
||||
.chrome { fill: transparent; }
|
||||
.dot { fill: #52525b; }
|
||||
.sep { stroke: #3f3f46; stroke-width: 1; }
|
||||
.tab { fill: transparent; }
|
||||
text { font-family: ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace; fill: #f4f4f5; }
|
||||
.t-md { font-size: 15px; }
|
||||
.t-sm { font-size: 13px; }
|
||||
.t-xs { font-size: 11px; }
|
||||
.muted { fill: #a1a1aa; }
|
||||
.dim { fill: #71717a; }
|
||||
.sel-bg { fill: #b7410e; fill-opacity: 0.85; }
|
||||
.sel-fg { fill: #fff5f0; }
|
||||
.text { fill: #d7d7db; }
|
||||
.muted { fill: #9a9aa2; }
|
||||
.dim { fill: #6b6b72; }
|
||||
.ghost { fill: #6b6b72; }
|
||||
.blue { fill: #3ba7e0; }
|
||||
.gold { fill: #d9b54a; }
|
||||
.green { fill: #46d160; }
|
||||
.peachfg{ fill: #1a1206; }
|
||||
.greenfg{ fill: #0c130c; }
|
||||
.b { font-weight: 700; }
|
||||
text {
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
||||
font-size: 13px;
|
||||
text-rendering: geometricPrecision;
|
||||
}
|
||||
</style>
|
||||
|
||||
<rect class="bg" width="640" height="400" rx="12"/>
|
||||
<rect class="chrome" width="640" height="36" rx="12"/>
|
||||
<rect class="chrome" y="24" width="640" height="12"/>
|
||||
<line class="sep" x1="0" y1="36" x2="640" y2="36"/>
|
||||
<g xml:space="preserve">
|
||||
<!-- ===== terminal frame ===== -->
|
||||
<rect x="0.5" y="0.5" width="639" height="399" rx="10" fill="#1a1b1e" stroke="#2a2b30"/>
|
||||
|
||||
<circle class="dot" cx="20" cy="18" r="5.5"/>
|
||||
<circle class="dot" cx="40" cy="18" r="5.5"/>
|
||||
<circle class="dot" cx="60" cy="18" r="5.5"/>
|
||||
<!-- ===== tab bar ===== -->
|
||||
<text x="8" y="16" class="muted">Login</text>
|
||||
<rect x="56" y="2" width="80" height="20" class="green"/>
|
||||
<text x="64" y="16" class="greenfg b">Register</text>
|
||||
<text x="144" y="16" class="muted">Admin_Panel</text>
|
||||
<text x="248" y="16" class="muted">Quit</text>
|
||||
|
||||
<text x="320" y="22" text-anchor="middle" font-size="11" class="dim">examples/default — cargo run</text>
|
||||
<!-- ===== Register panel (cols 21..58, rows 3..21) ===== -->
|
||||
<text x="168" y="60" class="blue b" textLength="304" lengthAdjust="spacing">╭─ Register ─────────────────────────╮</text>
|
||||
<text x="168" y="76" class="blue">│</text><text x="464" y="76" class="blue">│</text>
|
||||
<text x="168" y="92" class="blue">│</text><text x="464" y="92" class="blue">│</text>
|
||||
<text x="168" y="108" class="blue">│</text><text x="464" y="108" class="blue">│</text>
|
||||
<text x="168" y="124" class="blue">│</text><text x="464" y="124" class="blue">│</text>
|
||||
<text x="168" y="140" class="blue">│</text><text x="464" y="140" class="blue">│</text>
|
||||
<text x="168" y="156" class="blue">│</text><text x="464" y="156" class="blue">│</text>
|
||||
<text x="168" y="172" class="blue">│</text><text x="464" y="172" class="blue">│</text>
|
||||
<text x="168" y="188" class="blue">│</text><text x="464" y="188" class="blue">│</text>
|
||||
<text x="168" y="204" class="blue">│</text><text x="464" y="204" class="blue">│</text>
|
||||
<text x="168" y="220" class="blue">│</text><text x="464" y="220" class="blue">│</text>
|
||||
<text x="168" y="236" class="blue">│</text><text x="464" y="236" class="blue">│</text>
|
||||
<text x="168" y="252" class="blue">│</text><text x="464" y="252" class="blue">│</text>
|
||||
<text x="168" y="268" class="blue">│</text><text x="464" y="268" class="blue">│</text>
|
||||
<text x="168" y="284" class="blue">│</text><text x="464" y="284" class="blue">│</text>
|
||||
<text x="168" y="300" class="blue">│</text><text x="464" y="300" class="blue">│</text>
|
||||
<text x="168" y="316" class="blue">│</text><text x="464" y="316" class="blue">│</text>
|
||||
<text x="168" y="332" class="blue">│</text><text x="464" y="332" class="blue">│</text>
|
||||
<text x="168" y="348" class="blue" textLength="304" lengthAdjust="spacing">╰────────────────────────────────────╯</text>
|
||||
|
||||
<text x="20" y="68" font-size="14" class="muted">Pages:</text>
|
||||
<rect class="sel-bg" x="80" y="55" width="60" height="20" rx="3"/>
|
||||
<text x="110" y="69" text-anchor="middle" font-size="12" class="sel-fg" font-weight="600">Home</text>
|
||||
<text x="150" y="69" font-size="12" class="muted">Settings</text>
|
||||
<text x="220" y="69" font-size="12" class="muted">About</text>
|
||||
<text x="270" y="69" font-size="12" class="muted">Quit</text>
|
||||
<!-- subtitle -->
|
||||
<text x="184" y="92" class="muted">Create your account</text>
|
||||
|
||||
<line class="sep" x1="0" y1="92" x2="640" y2="92"/>
|
||||
<!-- fields: label col 23, value col 35 -->
|
||||
<text x="184" y="124" class="muted">Email</text>
|
||||
<text x="280" y="124" class="text">ada@acme.io</text>
|
||||
|
||||
<text x="20" y="120" font-size="18" font-weight="700">Home</text>
|
||||
<text x="20" y="142" font-size="11" class="dim">Choose a section to open.</text>
|
||||
<text x="184" y="156" class="muted">Password</text>
|
||||
<text x="280" y="156" class="muted">••••••••••</text>
|
||||
|
||||
<line class="sep" x1="0" y1="160" x2="640" y2="160"/>
|
||||
<text x="184" y="188" class="muted">Confirm</text>
|
||||
<text x="280" y="188" class="muted">••••••••••</text>
|
||||
|
||||
<g font-size="14">
|
||||
<rect class="sel-bg" x="0" y="170" width="640" height="34"/>
|
||||
<text x="32" y="192" class="sel-fg" font-weight="600">▸ Dashboard</text>
|
||||
<text x="600" y="192" text-anchor="end" class="sel-fg" font-size="11">enter</text>
|
||||
<!-- role: typed prefix white, block cursor, ghost completion gray -->
|
||||
<text x="184" y="220" class="muted">Role</text>
|
||||
<text x="280" y="220" class="text">a</text>
|
||||
<rect x="288" y="208" width="2" height="15" fill="#f3c690"/>
|
||||
<text x="288" y="220" class="ghost">dmin</text>
|
||||
|
||||
<text x="32" y="226" class="muted"> Accounts</text>
|
||||
<text x="32" y="254" class="muted"> Transactions</text>
|
||||
<text x="32" y="282" class="muted"> Reports</text>
|
||||
<text x="32" y="310" class="muted"> Settings</text>
|
||||
<!-- role dropdown: matches typed "a"; no border, no left pad -->
|
||||
<rect x="280" y="224" width="96" height="32" fill="#111217"/>
|
||||
<rect x="280" y="224" width="96" height="16" fill="#f3c690"/>
|
||||
<text x="280" y="236" class="peachfg b">admin</text>
|
||||
<text x="280" y="252" class="text">accountant</text>
|
||||
|
||||
<!-- primary button (bordered, green) -->
|
||||
<text x="184" y="300" class="green b" textLength="144" lengthAdjust="spacing">╭────────────────╮</text>
|
||||
<text x="184" y="316" class="green b" textLength="144" lengthAdjust="spacing">│ Create account │</text>
|
||||
<text x="184" y="332" class="green b" textLength="144" lengthAdjust="spacing">╰────────────────╯</text>
|
||||
<text x="360" y="316" class="dim">enter ↵</text>
|
||||
|
||||
<!-- ===== footer ===== -->
|
||||
<text x="32" y="380" class="green b">INS</text>
|
||||
<text x="72" y="380" class="muted">[+]</text>
|
||||
<text x="632" y="380" class="gold" text-anchor="end">tui-pages v0.7.2 │ 60 FPS</text>
|
||||
</g>
|
||||
|
||||
<line class="sep" x1="0" y1="358" x2="640" y2="358"/>
|
||||
<text x="20" y="380" font-size="11" class="dim">↑↓ move · enter select · q quit</text>
|
||||
<text x="620" y="380" text-anchor="end" font-size="11" class="dim">tui-pages v0.7.2</text>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 5.3 KiB |
73
static/img/terminal-keybindings-light.svg
Normal file
@@ -0,0 +1,73 @@
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="A keybindings help screen built with tui-pages">
|
||||
<!-- Light-mode twin of terminal-keybindings.svg. Same 80x25 grid, light neutral palette. -->
|
||||
<style>
|
||||
.text { fill: #26272b; }
|
||||
.muted { fill: #5a5a62; }
|
||||
.dim { fill: #8a8a90; }
|
||||
.blue { fill: #1f7fb8; }
|
||||
.gold { fill: #a8862a; }
|
||||
.green { fill: #1f9d3f; }
|
||||
.greenfg{ fill: #f2fff2; }
|
||||
.b { font-weight: 700; }
|
||||
text {
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
||||
font-size: 13px;
|
||||
text-rendering: geometricPrecision;
|
||||
}
|
||||
</style>
|
||||
|
||||
<g xml:space="preserve">
|
||||
<rect x="0.5" y="0.5" width="639" height="399" rx="10" fill="#f4f4f2" stroke="#d8d8d2"/>
|
||||
|
||||
<rect x="0" y="2" width="56" height="20" class="green"/>
|
||||
<text x="8" y="16" class="greenfg b">Login</text>
|
||||
<text x="64" y="16" class="muted">Register</text>
|
||||
<text x="144" y="16" class="muted">Admin_Panel</text>
|
||||
<text x="248" y="16" class="muted">Quit</text>
|
||||
|
||||
<text x="168" y="60" class="blue b" textLength="304" lengthAdjust="spacing">╭─ Keybindings ──────────────────────╮</text>
|
||||
<text x="168" y="76" class="blue">│</text><text x="464" y="76" class="blue">│</text>
|
||||
<text x="168" y="92" class="blue">│</text><text x="464" y="92" class="blue">│</text>
|
||||
<text x="168" y="108" class="blue">│</text><text x="464" y="108" class="blue">│</text>
|
||||
<text x="168" y="124" class="blue">│</text><text x="464" y="124" class="blue">│</text>
|
||||
<text x="168" y="140" class="blue">│</text><text x="464" y="140" class="blue">│</text>
|
||||
<text x="168" y="156" class="blue">│</text><text x="464" y="156" class="blue">│</text>
|
||||
<text x="168" y="172" class="blue">│</text><text x="464" y="172" class="blue">│</text>
|
||||
<text x="168" y="188" class="blue">│</text><text x="464" y="188" class="blue">│</text>
|
||||
<text x="168" y="204" class="blue">│</text><text x="464" y="204" class="blue">│</text>
|
||||
<text x="168" y="220" class="blue">│</text><text x="464" y="220" class="blue">│</text>
|
||||
<text x="168" y="236" class="blue">│</text><text x="464" y="236" class="blue">│</text>
|
||||
<text x="168" y="252" class="blue">│</text><text x="464" y="252" class="blue">│</text>
|
||||
<text x="168" y="268" class="blue">│</text><text x="464" y="268" class="blue">│</text>
|
||||
<text x="168" y="284" class="blue">│</text><text x="464" y="284" class="blue">│</text>
|
||||
<text x="168" y="300" class="blue">│</text><text x="464" y="300" class="blue">│</text>
|
||||
<text x="168" y="316" class="blue">│</text><text x="464" y="316" class="blue">│</text>
|
||||
<text x="168" y="332" class="blue">│</text><text x="464" y="332" class="blue">│</text>
|
||||
<text x="168" y="348" class="blue" textLength="304" lengthAdjust="spacing">╰────────────────────────────────────╯</text>
|
||||
|
||||
<text x="184" y="92" class="gold b">MOVEMENT</text>
|
||||
<text x="200" y="108" class="text">j / k</text>
|
||||
<text x="304" y="108" class="muted">move down / up</text>
|
||||
<text x="200" y="124" class="text">gg / G</text>
|
||||
<text x="304" y="124" class="muted">jump to top / bottom</text>
|
||||
|
||||
<text x="184" y="156" class="gold b">ACTIONS</text>
|
||||
<text x="200" y="172" class="text">enter</text>
|
||||
<text x="304" y="172" class="muted">select / open</text>
|
||||
<text x="200" y="188" class="text">/</text>
|
||||
<text x="304" y="188" class="muted">search</text>
|
||||
<text x="200" y="204" class="text">space</text>
|
||||
<text x="304" y="204" class="muted">toggle mark</text>
|
||||
|
||||
<text x="184" y="236" class="gold b">APP</text>
|
||||
<text x="200" y="252" class="text">?</text>
|
||||
<text x="304" y="252" class="muted">toggle this help</text>
|
||||
<text x="200" y="268" class="text">:q</text>
|
||||
<text x="304" y="268" class="muted">quit</text>
|
||||
|
||||
<text x="184" y="316" class="dim">press ? or esc to close</text>
|
||||
|
||||
<text x="32" y="380" class="green b">NOR</text>
|
||||
<text x="632" y="380" class="gold" text-anchor="end">tui-pages v0.7.2 │ 60 FPS</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.2 KiB |
@@ -1,71 +1,82 @@
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="examples/keybindings terminal screenshot">
|
||||
<svg viewBox="0 0 640 400" xmlns="http://www.w3.org/2000/svg" class="w-full h-auto" role="img" aria-label="A keybindings help screen built with tui-pages">
|
||||
<!--
|
||||
tui-pages UX showcase on a strict 80x25 monospace grid (cell = 8x16 px).
|
||||
Each cell carries at most two colors (fg + bg), like a real terminal buffer.
|
||||
-->
|
||||
<style>
|
||||
.bg { fill: #18181b; }
|
||||
.chrome { fill: #27272a; }
|
||||
.dot { fill: #52525b; }
|
||||
.kbd { fill: #27272a; stroke: #3f3f46; stroke-width: 1; }
|
||||
.modal { fill: #1f1f23; stroke: #b7410e; stroke-width: 2; }
|
||||
.sep { stroke: #27272a; stroke-width: 1; }
|
||||
text { font-family: ui-monospace, 'JetBrains Mono', 'SF Mono', Menlo, Consolas, monospace; fill: #f4f4f5; }
|
||||
.t-sm { font-size: 12px; }
|
||||
.t-xs { font-size: 11px; }
|
||||
.muted { fill: #a1a1aa; }
|
||||
.dim { fill: #71717a; }
|
||||
.text { fill: #d7d7db; }
|
||||
.muted { fill: #9a9aa2; }
|
||||
.dim { fill: #6b6b72; }
|
||||
.blue { fill: #3ba7e0; }
|
||||
.gold { fill: #d9b54a; }
|
||||
.green { fill: #46d160; }
|
||||
.greenfg{ fill: #0c130c; }
|
||||
.b { font-weight: 700; }
|
||||
text {
|
||||
font-family: 'JetBrains Mono', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;
|
||||
font-size: 13px;
|
||||
text-rendering: geometricPrecision;
|
||||
}
|
||||
</style>
|
||||
|
||||
<rect class="bg" width="640" height="400" rx="12"/>
|
||||
<rect class="chrome" width="640" height="36" rx="12"/>
|
||||
<rect class="chrome" y="24" width="640" height="12"/>
|
||||
<line class="sep" x1="0" y1="36" x2="640" y2="36"/>
|
||||
<g xml:space="preserve">
|
||||
<rect x="0.5" y="0.5" width="639" height="399" rx="10" fill="#1a1b1e" stroke="#2a2b30"/>
|
||||
|
||||
<circle class="dot" cx="20" cy="18" r="5.5"/>
|
||||
<circle class="dot" cx="40" cy="18" r="5.5"/>
|
||||
<circle class="dot" cx="60" cy="18" r="5.5"/>
|
||||
<!-- tab bar (Login active) -->
|
||||
<rect x="0" y="2" width="56" height="20" class="green"/>
|
||||
<text x="8" y="16" class="greenfg b">Login</text>
|
||||
<text x="64" y="16" class="muted">Register</text>
|
||||
<text x="144" y="16" class="muted">Admin_Panel</text>
|
||||
<text x="248" y="16" class="muted">Quit</text>
|
||||
|
||||
<text x="320" y="22" text-anchor="middle" font-size="11" class="dim">examples/keybindings — modal open</text>
|
||||
<!-- panel -->
|
||||
<text x="168" y="60" class="blue b" textLength="304" lengthAdjust="spacing">╭─ Keybindings ──────────────────────╮</text>
|
||||
<text x="168" y="76" class="blue">│</text><text x="464" y="76" class="blue">│</text>
|
||||
<text x="168" y="92" class="blue">│</text><text x="464" y="92" class="blue">│</text>
|
||||
<text x="168" y="108" class="blue">│</text><text x="464" y="108" class="blue">│</text>
|
||||
<text x="168" y="124" class="blue">│</text><text x="464" y="124" class="blue">│</text>
|
||||
<text x="168" y="140" class="blue">│</text><text x="464" y="140" class="blue">│</text>
|
||||
<text x="168" y="156" class="blue">│</text><text x="464" y="156" class="blue">│</text>
|
||||
<text x="168" y="172" class="blue">│</text><text x="464" y="172" class="blue">│</text>
|
||||
<text x="168" y="188" class="blue">│</text><text x="464" y="188" class="blue">│</text>
|
||||
<text x="168" y="204" class="blue">│</text><text x="464" y="204" class="blue">│</text>
|
||||
<text x="168" y="220" class="blue">│</text><text x="464" y="220" class="blue">│</text>
|
||||
<text x="168" y="236" class="blue">│</text><text x="464" y="236" class="blue">│</text>
|
||||
<text x="168" y="252" class="blue">│</text><text x="464" y="252" class="blue">│</text>
|
||||
<text x="168" y="268" class="blue">│</text><text x="464" y="268" class="blue">│</text>
|
||||
<text x="168" y="284" class="blue">│</text><text x="464" y="284" class="blue">│</text>
|
||||
<text x="168" y="300" class="blue">│</text><text x="464" y="300" class="blue">│</text>
|
||||
<text x="168" y="316" class="blue">│</text><text x="464" y="316" class="blue">│</text>
|
||||
<text x="168" y="332" class="blue">│</text><text x="464" y="332" class="blue">│</text>
|
||||
<text x="168" y="348" class="blue" textLength="304" lengthAdjust="spacing">╰────────────────────────────────────╯</text>
|
||||
|
||||
<!-- dimmed background content -->
|
||||
<text x="40" y="80" font-size="14" class="dim">▸ Accounts</text>
|
||||
<text x="40" y="108" font-size="14" class="dim"> Transactions</text>
|
||||
<text x="40" y="136" font-size="14" class="dim"> Reports</text>
|
||||
<text x="40" y="164" font-size="14" class="dim"> Settings</text>
|
||||
<text x="40" y="320" font-size="11" class="dim">Press ? for help</text>
|
||||
<!-- MOVEMENT -->
|
||||
<text x="184" y="92" class="gold b">MOVEMENT</text>
|
||||
<text x="200" y="108" class="text">j / k</text>
|
||||
<text x="304" y="108" class="muted">move down / up</text>
|
||||
<text x="200" y="124" class="text">gg / G</text>
|
||||
<text x="304" y="124" class="muted">jump to top / bottom</text>
|
||||
|
||||
<!-- modal -->
|
||||
<rect class="modal" x="120" y="60" width="400" height="280" rx="10"/>
|
||||
<text x="140" y="94" font-size="14" font-weight="700">Keybindings</text>
|
||||
<line class="sep" x1="140" y1="104" x2="500" y2="104"/>
|
||||
<!-- ACTIONS -->
|
||||
<text x="184" y="156" class="gold b">ACTIONS</text>
|
||||
<text x="200" y="172" class="text">enter</text>
|
||||
<text x="304" y="172" class="muted">select / open</text>
|
||||
<text x="200" y="188" class="text">/</text>
|
||||
<text x="304" y="188" class="muted">search</text>
|
||||
<text x="200" y="204" class="text">space</text>
|
||||
<text x="304" y="204" class="muted">toggle mark</text>
|
||||
|
||||
<text x="140" y="130" font-size="11" class="muted">MOVEMENT</text>
|
||||
<rect class="kbd" x="140" y="140" width="34" height="24" rx="4"/>
|
||||
<text x="157" y="157" text-anchor="middle" font-size="12">j</text>
|
||||
<text x="184" y="157" font-size="12" class="muted">move down</text>
|
||||
<!-- APP -->
|
||||
<text x="184" y="236" class="gold b">APP</text>
|
||||
<text x="200" y="252" class="text">?</text>
|
||||
<text x="304" y="252" class="muted">toggle this help</text>
|
||||
<text x="200" y="268" class="text">:q</text>
|
||||
<text x="304" y="268" class="muted">quit</text>
|
||||
|
||||
<rect class="kbd" x="140" y="170" width="34" height="24" rx="4"/>
|
||||
<text x="157" y="187" text-anchor="middle" font-size="12">k</text>
|
||||
<text x="184" y="187" font-size="12" class="muted">move up</text>
|
||||
<text x="184" y="316" class="dim">press ? or esc to close</text>
|
||||
|
||||
<rect class="kbd" x="140" y="200" width="34" height="24" rx="4"/>
|
||||
<text x="157" y="217" text-anchor="middle" font-size="12">gg</text>
|
||||
<text x="184" y="217" font-size="12" class="muted">top of list</text>
|
||||
|
||||
<text x="290" y="130" font-size="11" class="muted">ACTIONS</text>
|
||||
<rect class="kbd" x="290" y="140" width="60" height="24" rx="4"/>
|
||||
<text x="320" y="157" text-anchor="middle" font-size="11">enter</text>
|
||||
<text x="360" y="157" font-size="12" class="muted">select</text>
|
||||
|
||||
<rect class="kbd" x="290" y="170" width="34" height="24" rx="4"/>
|
||||
<text x="307" y="187" text-anchor="middle" font-size="11">/</text>
|
||||
<text x="334" y="187" font-size="12" class="muted">search</text>
|
||||
|
||||
<rect class="kbd" x="290" y="200" width="60" height="24" rx="4"/>
|
||||
<text x="320" y="217" text-anchor="middle" font-size="11">ctrl+s</text>
|
||||
<text x="360" y="217" font-size="12" class="muted">save</text>
|
||||
|
||||
<line class="sep" x1="140" y1="300" x2="500" y2="300"/>
|
||||
<text x="320" y="322" text-anchor="middle" font-size="11" class="dim">press esc to close</text>
|
||||
|
||||
<line class="sep" x1="0" y1="358" x2="640" y2="358"/>
|
||||
<text x="20" y="380" font-size="11" class="dim">esc close · ? toggle this dialog</text>
|
||||
<text x="620" y="380" text-anchor="end" font-size="11" class="dim">dialog feature enabled</text>
|
||||
<!-- footer -->
|
||||
<text x="32" y="380" class="green b">NOR</text>
|
||||
<text x="632" y="380" class="gold" text-anchor="end">tui-pages v0.7.2 │ 60 FPS</text>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 4.4 KiB |