move RustyWolf tabs into the window title bar

This commit is contained in:
dvorakmortonxd 2026-10-05 12:41:08 +02:00
commit a110744127
7 changed files with 44 additions and 24 deletions

View file

@ -34,7 +34,8 @@ more.
hero / quick-tile / section cards. hero / quick-tile / section cards.
- **Asset-free feature windows** — the two feature panels (Revival Inc. / RustyWolf) are - **Asset-free feature windows** — the two feature panels (Revival Inc. / RustyWolf) are
hand-built CSS mock windows instead of screenshots: a little necromancy game scene with a hand-built CSS mock windows instead of screenshots: a little necromancy game scene with a
blinking "PRESS START", and a little browser window with a tab strip, toolbar and start page. blinking "PRESS START", and a little browser window with tabs in the title bar, a toolbar
and a start page.
- **Draggable desktop icons** — free placement that snaps to a measured grid, one icon per - **Draggable desktop icons** — free placement that snaps to a measured grid, one icon per
cell, with a follow-the-cursor drag ghost. Icons shrink on cramped viewports so they never cell, with a follow-the-cursor drag ghost. Icons shrink on cramped viewports so they never
collide. collide.
@ -76,7 +77,7 @@ more.
- **Fonts:** the web theme uses the system sans stack; Monocraft (self-hosted in `public/`) is - **Fonts:** the web theme uses the system sans stack; Monocraft (self-hosted in `public/`) is
used by the desktop theme's SMP menu and the in-desktop terminal. used by the desktop theme's SMP menu and the in-desktop terminal.
- **Images:** `next/image` - **Images:** `next/image`
- **Version:** `2.2.10` (see `package.json`) - **Version:** `2.2.11` (see `package.json`)
- **Dependencies:** `npm audit` reports **0 vulnerabilities**. `next` is kept at a patched - **Dependencies:** `npm audit` reports **0 vulnerabilities**. `next` is kept at a patched
release (`>=16.3.6`) for the `next/og` RCE, and `brace-expansion` is force-upgraded via release (`>=16.3.6`) for the `next/og` RCE, and `brace-expansion` is force-upgraded via
`overrides`. `braces` (a transitive ESLint/`fast-glob` dependency) has **no upstream fix**, `overrides`. `braces` (a transitive ESLint/`fast-glob` dependency) has **no upstream fix**,

View file

@ -34,7 +34,7 @@ When in doubt, prefer updating. A stale README **or** agents.md is treated as a
## Bump the version on EVERY prompt — also do this every time ## Bump the version on EVERY prompt — also do this every time
Another standing requirement: increment the **patch** version (`x.x.+1`, so Another standing requirement: increment the **patch** version (`x.x.+1`, so
`2.2.9` → `2.2.10` → …) as part of every task, even the small ones. Keep all of `2.2.10` → `2.2.11` → …) as part of every task, even the small ones. Keep all of
these in sync: these in sync:
- `package.json` → `"version"` - `package.json` → `"version"`
@ -56,7 +56,7 @@ frosted-glass **web** site, and an alternate KDE/Plasma **desktop simulation**
utilities in the components (Tailwind is present via PostCSS but the look is utilities in the components (Tailwind is present via PostCSS but the look is
hand-written CSS). hand-written CSS).
- Path alias: `@/*` → `src/*`. - Path alias: `@/*` → `src/*`.
- Version: `2.2.10` (see `package.json`). - Version: `2.2.11` (see `package.json`).
### Scripts ### Scripts
```bash ```bash
@ -162,8 +162,8 @@ Themes: `web` = default frosted-glass website (sidebar + content, light/dark),
to equal height and share a fixed `16 / 10` `.fw` window (the `FeatureWindow` to equal height and share a fixed `16 / 10` `.fw` window (the `FeatureWindow`
component) — a decorative, **asset-free CSS mock-up** rather than a screenshot: component) — a decorative, **asset-free CSS mock-up** rather than a screenshot:
Revival Inc. is a little necromancy game scene (night sky, moon, tombstones, Revival Inc. is a little necromancy game scene (night sky, moon, tombstones,
blinking "PRESS START") and RustyWolf is a little browser window (tab strip, blinking "PRESS START") and RustyWolf is a little browser window (tabs in the
toolbar, address bar, start page). Both are `aria-hidden` and purely title bar, toolbar, address bar, start page). Both are `aria-hidden` and purely
presentational; the real copy stays in the `.web-feature-text` paragraph below. presentational; the real copy stays in the `.web-feature-text` paragraph below.
The old raster feature shots (`.web-shot` + `next/image`) were removed from the The old raster feature shots (`.web-shot` + `next/image`) were removed from the
web theme only — `revivalinc.webp` / `RustyWolfPreview.webp` are still used by web theme only — `revivalinc.webp` / `RustyWolfPreview.webp` are still used by

4
package-lock.json generated
View file

@ -1,12 +1,12 @@
{ {
"name": "dvorakmortonxd", "name": "dvorakmortonxd",
"version": "2.2.10", "version": "2.2.11",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "dvorakmortonxd", "name": "dvorakmortonxd",
"version": "2.2.10", "version": "2.2.11",
"dependencies": { "dependencies": {
"next": "^16.3.8", "next": "^16.3.8",
"react": "^19.3.0", "react": "^19.3.0",

View file

@ -1,6 +1,6 @@
{ {
"name": "dvorakmortonxd", "name": "dvorakmortonxd",
"version": "2.2.10", "version": "2.2.11",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "node scripts/dev-server.mjs", "dev": "node scripts/dev-server.mjs",

View file

@ -9,16 +9,24 @@ import type { ReactNode } from "react";
* copy lives in the `.web-feature-text` paragraph below each window. * copy lives in the `.web-feature-text` paragraph below each window.
*/ */
function Chrome({ title, children }: { title: string; children: ReactNode }) { function Chrome({
title,
tabs,
children,
}: {
title?: string;
tabs?: ReactNode;
children: ReactNode;
}) {
return ( return (
<div className="fw" aria-hidden="true"> <div className="fw" aria-hidden="true">
<div className="fw-bar"> <div className={"fw-bar" + (tabs ? " fw-bar-browser" : "")}>
<span className="fw-dots"> <span className="fw-dots">
<span className="fw-dot" /> <span className="fw-dot" />
<span className="fw-dot" /> <span className="fw-dot" />
<span className="fw-dot" /> <span className="fw-dot" />
</span> </span>
<span className="fw-title">{title}</span> {tabs ?? <span className="fw-title">{title}</span>}
</div> </div>
<div className="fw-body">{children}</div> <div className="fw-body">{children}</div>
</div> </div>
@ -51,13 +59,6 @@ function BrowserBody() {
const tiles = ["G", "Y", "R", "D", "X"]; const tiles = ["G", "Y", "R", "D", "X"];
return ( return (
<div className="fw-browser"> <div className="fw-browser">
<div className="fw-tabs">
<span className="fw-tab">
<span className="fw-tab-dot" />
New Tab
</span>
<span className="fw-tab-plus">+</span>
</div>
<div className="fw-toolbar"> <div className="fw-toolbar">
<span className="fw-nav">‹</span> <span className="fw-nav">‹</span>
<span className="fw-nav">›</span> <span className="fw-nav">›</span>
@ -96,7 +97,17 @@ export default function FeatureWindow({ variant }: { variant: "game" | "browser"
); );
} }
return ( return (
<Chrome title="RustyWolf — new tab"> <Chrome
tabs={
<div className="fw-tabs">
<span className="fw-tab">
<span className="fw-tab-dot" />
New Tab
</span>
<span className="fw-tab-plus">+</span>
</div>
}
>
<BrowserBody /> <BrowserBody />
</Chrome> </Chrome>
); );

View file

@ -318,7 +318,7 @@ export default function WebLayout() {
</Section> </Section>
<footer className="web-footer glass"> <footer className="web-footer glass">
<span className="web-footer-label">v2.2.10</span> <span className="web-footer-label">v2.2.11</span>
© 2025-2026 Martin Dvořák. All rights reserved (not really I dont care, just © 2025-2026 Martin Dvořák. All rights reserved (not really I dont care, just
follow the GPL3.0 License) follow the GPL3.0 License)
</footer> </footer>

View file

@ -457,6 +457,12 @@ html[data-theme="web"] body {
background: var(--fw-chrome); background: var(--fw-chrome);
border-bottom: 1px solid var(--glass-border); border-bottom: 1px solid var(--glass-border);
} }
/* Browser variant: the tab strip lives in the title bar (Chrome/Firefox style). */
.fw-bar-browser {
gap: 8px;
padding: 0 8px 0 12px;
border-bottom: none;
}
.fw-dots { .fw-dots {
display: flex; display: flex;
gap: 6px; gap: 6px;
@ -649,9 +655,10 @@ html[data-theme="web"] body {
.fw-tabs { .fw-tabs {
display: flex; display: flex;
align-items: flex-end; align-items: flex-end;
align-self: stretch;
gap: 5px; gap: 5px;
height: 26px; min-width: 0;
padding: 5px 10px 0; flex: 1;
} }
.fw-tab { .fw-tab {
display: inline-flex; display: inline-flex;
@ -661,7 +668,8 @@ html[data-theme="web"] body {
overflow: hidden; overflow: hidden;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
padding: 3px 11px; padding: 7px 12px 6px;
margin-bottom: -1px;
border-radius: 8px 8px 0 0; border-radius: 8px 8px 0 0;
border: 1px solid var(--btn-border, var(--glass-border)); border: 1px solid var(--btn-border, var(--glass-border));
border-bottom: none; border-bottom: none;