diff --git a/README.md b/README.md index be88457..5a26a22 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ more. - **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. - **Images:** `next/image` -- **Version:** `2.2.0` (see `package.json`) +- **Version:** `2.2.1` (see `package.json`) ## 🚀 Running Locally diff --git a/agents.md b/agents.md index fd8fa1d..1cd247b 100644 --- a/agents.md +++ b/agents.md @@ -43,7 +43,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 hand-written CSS). - Path alias: `@/*` → `src/*`. -- Version: `2.2.0` (see `package.json`). +- Version: `2.2.1` (see `package.json`). ### Scripts ```bash @@ -123,30 +123,44 @@ Themes: `web` = default frosted-glass website (sidebar + content, light/dark), `skeuo` = KDE Plasma desktop simulation (desktop-only; the web sidebar's "Desktop" control switches to it, and it has a "Web" control in its tray). -### Web theme + light/dark (v2.2.0 rework) +### Web theme + light/dark (v2.2 rework) - `WebLayout.tsx` is the default shell. Layout is a **sticky sidebar** (brand, section nav, light/dark switch, desktop switch, contact/clock) beside a single content column of `.glass` panels: hero (with a compact "Find me" socials row), - a `.web-quick` 2-up (`now.txt` + `gym_sbd.db`), then services, activity, + a `.web-quick` 2-up ("Right now" + "Gym PRs"), then services, activity, projects, hardware, features (Revival/RustyWolf) and friends. Projects/hardware use a CSS multi-column **masonry** gallery (`.project-grid`) so short cards don't leave half-empty grid slots. The old stacked TUI panel layout and the `SlBackground` ASCII train were removed with it. +- **Not a terminal.** The web theme deliberately has no TUI chrome: the hero is + a name + blurb (no `$ whoami` prompt, no blinking cursor), section eyebrows are + plain words (not `README.MD` / `TECH_LIST.JSON` filenames), and the activity + panel renders without the `martin@git…:~$ echo …` / `git log -n 3` command + lines. `ContributionHeatmap` takes `variant?: "terminal" | "web"` (default + `terminal`); `WebLayout` passes `variant="web"`, the desktop app keeps the + terminal look. Don't reintroduce command prompts in the web variant. - **Grid gotcha:** the mobile column is `minmax(0, 1fr)`, never bare `1fr`. A `1fr` track has an automatic `min-content` floor, and with a wide child that blew the single column out to ~2x the viewport (horizontal scroll + clipped content on phones). Keep the `minmax(0, …)`. - Glassmorphism lives in one utility class, `.glass`, in `web.css`: a subtle `linear-gradient` over `--glass-hi`/`--glass-lo` with - `backdrop-filter: blur(20px) saturate(165%)`. The page blobs behind the panels + `backdrop-filter: blur(28px) saturate(180%)`. The page blobs behind the panels are `.web-bg` (a fixed radial-gradient layer at `z-index: 0`; `.web-root` sits at `z-index: 1`). +- Interactive surfaces (`.web-ctl`, pills, `.service-button`, `.social-button`, + `.project-card`, `.gym-item`, `.contribution-entry`, `.heatmap-container`) read + the `--btn-bg` / `--btn-bg-hi` / `--btn-border` / `--btn-shadow` tokens with + the glass tokens as **fallbacks** (`var(--btn-bg, var(--glass-lo))`). The + tokens are only defined under `html[data-theme="web"]`, so the desktop theme + falls back to the old values and is unaffected. Light-mode buttons need the + extra opacity + a visible (dark, low-alpha) outline or they melt into the pale + background. - Colours are tokenised in `web.css` under `:root` (light) and `html[data-theme="web"][data-scheme="dark"]` (dark). The shared token names - (`--fg`, `--gray`, `--accent`, `--green`, …) are reused so `ServiceButton` and - `ContributionHeatmap` need no changes. `skeuo.css` overrides the same names - while the desktop theme is active, so the two themes don't bleed into each - other. + (`--fg`, `--gray`, `--accent`, `--green`, …) are reused by `ServiceButton` and + `ContributionHeatmap`. `skeuo.css` overrides the same names while the desktop + theme is active, so the two themes don't bleed into each other. - The desktop switch (`.web-ctl-desktop`) is hidden on phones: under the `max-width: 960px` breakpoint and under `(hover: none) and (pointer: coarse)`. There is no device sniff anymore — phones just get the responsive web shell. diff --git a/package-lock.json b/package-lock.json index 13c50b7..0aa829f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "dvorakmortonxd", - "version": "2.2.0", + "version": "2.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "dvorakmortonxd", - "version": "2.2.0", + "version": "2.2.1", "dependencies": { "next": "^16.3.5", "react": "^19.3.0", diff --git a/package.json b/package.json index ba678da..4785219 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "dvorakmortonxd", - "version": "2.2.0", + "version": "2.2.1", "private": true, "scripts": { "dev": "node scripts/dev-server.mjs", diff --git a/public/gruvbox.webp b/public/gruvbox.webp deleted file mode 100644 index f4fe2d8..0000000 Binary files a/public/gruvbox.webp and /dev/null differ diff --git a/public/phonewallpaper.jpg b/public/phonewallpaper.jpg deleted file mode 100644 index 6ef7252..0000000 Binary files a/public/phonewallpaper.jpg and /dev/null differ diff --git a/src/app/components/ContributionHeatmap.tsx b/src/app/components/ContributionHeatmap.tsx index ba9eb50..6143b78 100644 --- a/src/app/components/ContributionHeatmap.tsx +++ b/src/app/components/ContributionHeatmap.tsx @@ -25,7 +25,8 @@ interface ActivityPayload { }; } -export default function ContributionHeatmap() { +export default function ContributionHeatmap({ variant = "terminal" }: { variant?: "terminal" | "web" }) { + const isWeb = variant === "web"; const [weeks, setWeeks] = useState<{ date: string; contribs: number; level: number }[][]>([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(false); @@ -123,11 +124,13 @@ export default function ContributionHeatmap() { return (
-
-
- martin@git.dvorakmortonxd.dev:~$ echo "{totalContribs} contributions in the last year" + {!isWeb && ( +
+
+ martin@git.dvorakmortonxd.dev:~$ echo "{totalContribs} contributions in the last year" +
-
+ )}
{totalContribs} contributions in the last year
@@ -169,9 +172,13 @@ export default function ContributionHeatmap() { {activities.length > 0 && (
-
- martin@git.dvorakmortonxd.dev:~$ git log -n 3 #displays my 3 latest contributions -
+ {isWeb ? ( +
Latest commits
+ ) : ( +
+ martin@git.dvorakmortonxd.dev:~$ git log -n 3 #displays my 3 latest contributions +
+ )} {activities.map((act, idx) => { let msg = "No message"; try { @@ -190,7 +197,7 @@ export default function ContributionHeatmap() { return (
- repo: {act.repo?.full_name || "unknown"} + {isWeb ? "" : "repo: "}{act.repo?.full_name || "unknown"} {created.toLocaleDateString()}-{created.toLocaleTimeString()} diff --git a/src/app/components/WebLayout.tsx b/src/app/components/WebLayout.tsx index 7d113e4..3ce087b 100644 --- a/src/app/components/WebLayout.tsx +++ b/src/app/components/WebLayout.tsx @@ -228,12 +228,11 @@ export default function WebLayout() {
- README.MD -

$ whoami

+ About me +

Martin Dvořák

Welcome to my personal website! Here I show off my projects and the hardware I own, as well as my self-hosted services. -

@@ -252,7 +251,7 @@ export default function WebLayout() { -
+
{friends.map((friend, idx) => ( diff --git a/src/app/globals.css b/src/app/globals.css index 89ff29a..f161ce1 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -1,5 +1,27 @@ @import "tailwindcss"; +/* Monocraft is the desktop theme's pixel font (SMP menu + in-desktop terminal). + It is declared globally because the desktop shell is mounting/unmounting + alongside the web shell. */ +@font-face { + font-family: "Monocraft"; + src: url("/Monocraft.ttf") format("truetype"); + font-weight: normal; + font-style: normal; +} +@font-face { + font-family: "Monocraft"; + src: url("/Monocraft-Bold.ttf") format("truetype"); + font-weight: bold; + font-style: normal; +} +@font-face { + font-family: "Monocraft"; + src: url("/Monocraft-Italic.ttf") format("truetype"); + font-weight: normal; + font-style: italic; +} + :root { --background: #1d2021; --foreground: #ebdbb2; diff --git a/src/app/web.css b/src/app/web.css index d701661..820ce21 100644 --- a/src/app/web.css +++ b/src/app/web.css @@ -1,29 +1,3 @@ -/* ============================================================ - FONT FACES - ------------------------------------------------------------ - Monocraft is no longer the web theme's font, but it is still - used by the desktop theme's Minecraft-style SMP menu and the - in-desktop terminal, so the faces stay registered here. - ============================================================ */ -@font-face { - font-family: "Monocraft"; - src: url("/Monocraft.ttf") format("truetype"); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: "Monocraft"; - src: url("/Monocraft-Bold.ttf") format("truetype"); - font-weight: bold; - font-style: normal; -} -@font-face { - font-family: "Monocraft"; - src: url("/Monocraft-Italic.ttf") format("truetype"); - font-weight: normal; - font-style: italic; -} - /* ============================================================ WEB THEME — light frosted-glass website shell. ------------------------------------------------------------ @@ -95,6 +69,11 @@ html[data-theme="web"][data-scheme="dark"] { --blob-c: rgba(236, 72, 153, 0.18); --blob-d: rgba(45, 212, 191, 0.16); + --btn-bg: rgba(255, 255, 255, 0.06); + --btn-bg-hi: rgba(255, 255, 255, 0.12); + --btn-border: rgba(255, 255, 255, 0.16); + --btn-shadow: 0 10px 24px -14px rgba(0, 0, 0, 0.9); + --bg-hard: rgba(255, 255, 255, 0.08); --green: #34d399; --aqua: #2dd4bf; @@ -106,6 +85,15 @@ html[data-theme="web"][data-scheme="dark"] { html[data-theme="web"] { scroll-behavior: smooth; + + /* Interactive surfaces (buttons, cards, chips). Kept a step more opaque and + more clearly outlined than the glass panels, so they don't melt into the + light background. The base rules read these with the old glass tokens as + fallbacks, which keeps the desktop theme untouched. */ + --btn-bg: rgba(255, 255, 255, 0.62); + --btn-bg-hi: rgba(255, 255, 255, 0.92); + --btn-border: rgba(20, 28, 52, 0.14); + --btn-shadow: 0 8px 20px -12px rgba(23, 32, 60, 0.45); } html[data-theme="web"] body { @@ -261,8 +249,9 @@ html[data-theme="web"] body { gap: 10px; padding: 9px 12px; border-radius: 12px; - border: 1px solid var(--glass-border); - background: var(--glass-lo); + border: 1px solid var(--btn-border, var(--glass-border)); + background: var(--btn-bg, var(--glass-lo)); + box-shadow: var(--btn-shadow, none); color: var(--fg); font: inherit; font-size: 0.82rem; @@ -272,7 +261,7 @@ html[data-theme="web"] body { } .web-ctl:hover { border-color: var(--accent-line); - background: var(--glass-hi); + background: var(--btn-bg-hi, var(--glass-hi)); box-shadow: 0 0 0 1px var(--accent-soft); } .web-ctl-icon { @@ -290,7 +279,7 @@ html[data-theme="web"] body { height: 20px; border-radius: 999px; background: var(--bg-hard); - border: 1px solid var(--glass-border); + border: 1px solid var(--btn-border, var(--glass-border)); transition: background-color 0.2s ease, border-color 0.2s ease; flex-shrink: 0; } @@ -385,13 +374,13 @@ html[data-theme="web"] body { box-shadow: 0 16px 30px -12px var(--accent); } .web-pill.ghost { - background: var(--glass-lo); + background: var(--btn-bg, var(--glass-lo)); color: var(--fg); - border: 1px solid var(--glass-border); - box-shadow: none; + border: 1px solid var(--btn-border, var(--glass-border)); + box-shadow: var(--btn-shadow, none); } .web-pill.ghost:hover { - background: var(--glass-hi); + background: var(--btn-bg-hi, var(--glass-hi)); border-color: var(--accent-line); } @@ -514,8 +503,9 @@ html[data-theme="web"] body { gap: 12px; padding: 14px 16px; border-radius: 16px; - border: 1px solid var(--glass-border); - background: var(--glass-lo); + border: 1px solid var(--btn-border, var(--glass-border)); + background: var(--btn-bg, var(--glass-lo)); + box-shadow: var(--btn-shadow, none); color: var(--fg); text-decoration: none; min-width: 0; @@ -525,7 +515,7 @@ html[data-theme="web"] body { .service-button:hover { transform: translateY(-3px); border-color: var(--accent-line); - background: var(--glass-hi); + background: var(--btn-bg-hi, var(--glass-hi)); box-shadow: 0 18px 34px -18px rgba(23, 32, 60, 0.5), 0 0 0 1px var(--accent-soft); } .service-button.disabled { @@ -533,9 +523,9 @@ html[data-theme="web"] body { } .service-button.disabled:hover { transform: none; - border-color: var(--glass-border); - background: var(--glass-lo); - box-shadow: none; + border-color: var(--btn-border, var(--glass-border)); + background: var(--btn-bg, var(--glass-lo)); + box-shadow: var(--btn-shadow, none); } .service-button.disabled:hover .service-icon { transform: none; @@ -651,8 +641,9 @@ html[data-theme="web"][data-scheme="dark"] .friend-icon { margin-bottom: 14px; padding: 12px; border-radius: 16px; - border: 1px solid var(--glass-border); - background: var(--glass-lo); + border: 1px solid var(--btn-border, var(--glass-border)); + background: var(--btn-bg, var(--glass-lo)); + box-shadow: var(--btn-shadow, none); color: inherit; text-decoration: none; transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease, @@ -661,7 +652,7 @@ html[data-theme="web"][data-scheme="dark"] .friend-icon { .project-card:hover { transform: translateY(-4px); border-color: var(--accent-line); - background: var(--glass-hi); + background: var(--btn-bg-hi, var(--glass-hi)); box-shadow: 0 20px 38px -20px rgba(23, 32, 60, 0.55); } .project-image { @@ -701,8 +692,9 @@ html[data-theme="web"][data-scheme="dark"] .friend-icon { gap: 9px; padding: 9px 12px; border-radius: 12px; - border: 1px solid transparent; - background: var(--glass-lo); + border: 1px solid var(--btn-border, transparent); + background: var(--btn-bg, var(--glass-lo)); + box-shadow: var(--btn-shadow, none); color: var(--fg); font-size: 0.82rem; font-weight: 550; @@ -711,8 +703,8 @@ html[data-theme="web"][data-scheme="dark"] .friend-icon { } .social-button:hover { transform: translateY(-2px); - background: var(--glass-hi); - border-color: var(--glass-border); + background: var(--btn-bg-hi, var(--glass-hi)); + border-color: var(--btn-border, var(--glass-border)); color: var(--accent); } .social-icon { @@ -750,8 +742,9 @@ html[data-theme="web"][data-scheme="dark"] .social-icon { gap: 6px; padding: 12px 8px; border-radius: 14px; - border: 1px solid var(--glass-border); - background: var(--glass-lo); + border: 1px solid var(--btn-border, var(--glass-border)); + background: var(--btn-bg, var(--glass-lo)); + box-shadow: var(--btn-shadow, none); text-align: center; transition: border-color 0.18s ease, transform 0.18s ease; } @@ -806,9 +799,9 @@ html[data-theme="web"][data-scheme="dark"] .social-icon { display: flex; gap: 3px; padding: 6px; - border: 1px solid var(--glass-border); + border: 1px solid var(--btn-border, var(--glass-border)); border-radius: 14px; - background: var(--glass-lo); + background: var(--btn-bg, var(--glass-lo)); overflow-x: auto; scrollbar-width: none; } @@ -912,6 +905,13 @@ html[data-theme="web"][data-scheme="dark"] .heatmap-legend-cell[data-level="4"] min-width: 0; margin-top: 4px; } +.contribution-log-title { + font-size: 0.68rem; + font-weight: 700; + letter-spacing: 0.14em; + text-transform: uppercase; + color: var(--web-muted); +} .contribution-entry { display: flex; flex-direction: column; @@ -919,8 +919,9 @@ html[data-theme="web"][data-scheme="dark"] .heatmap-legend-cell[data-level="4"] min-width: 0; padding: 10px 12px; border-radius: 12px; - border: 1px solid var(--glass-border); - background: var(--glass-lo); + border: 1px solid var(--btn-border, var(--glass-border)); + background: var(--btn-bg, var(--glass-lo)); + box-shadow: var(--btn-shadow, none); font-size: 0.78rem; } .contribution-entry-header { @@ -982,25 +983,6 @@ html[data-theme="web"][data-scheme="dark"] .heatmap-legend-cell[data-level="4"] /* ============================================================ SHARED BITS ============================================================ */ -.cursor-blink { - display: inline-block; - width: 7px; - height: 1.05em; - margin-left: 4px; - vertical-align: text-bottom; - background: var(--accent); - animation: cursorBlink 1s step-end infinite; -} -@keyframes cursorBlink { - 0%, - 100% { - opacity: 1; - } - 50% { - opacity: 0; - } -} - .joker-flash-overlay { position: fixed; inset: 0;