From 95dd0128b81f07c1ee043fca6aac0086426277a9 Mon Sep 17 00:00:00 2001 From: dvorakmortonxd Date: Sun, 11 Oct 2026 23:22:30 +0200 Subject: [PATCH] revamp projects/hardware as grouped index lists, drop emoji tiles, add Freezmo feature section --- README.md | 15 +- agents.md | 39 ++-- package-lock.json | 243 ++++++++++++------------- public/freezmo-app.webp | Bin 0 -> 39472 bytes src/app/components/ProjectIndex.tsx | 140 +++++++++++++++ src/app/components/WebLayout.tsx | 52 +++--- src/app/components/apps.tsx | 54 ++---- src/app/data.ts | 266 ++++++++++++++++++++++------ src/app/skeuo.css | 82 +++------ src/app/web.css | 243 +++++++++++++++++-------- 10 files changed, 733 insertions(+), 401 deletions(-) create mode 100644 public/freezmo-app.webp create mode 100644 src/app/components/ProjectIndex.tsx diff --git a/README.md b/README.md index 1a96764..fbeb7a7 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,9 @@ from the saved theme, all from the same content: - **`web`** (default) — a light, frosted-glass **website**: a sticky full-height sidebar (section nav, light/dark switch, desktop switch) beside a column of glass cards — hero with - a socials row, quick tiles, the Revival Inc. / RustyWolf feature panels (drawn as little - CSS windows, not screenshots), live services, - activity heatmap, projects and hardware (a masonry gallery), and friends. Dark by default + a socials row, quick tiles, the Freezmo feature panel (a real app screenshot) above the + Revival Inc. / RustyWolf CSS mock windows, live services, + activity heatmap, projects and hardware (grouped index lists), and friends. Dark by default with a persisted light mode, and fully responsive, so phones and desktops get the same shell. - **`skeuo`** — an alternate KDE Plasma / Windows-style **desktop simulation** (desktop only): draggable snap-to-grid icons, resizable/floating windows, a Start menu, taskbar and @@ -36,11 +36,12 @@ more. hand-built CSS mock windows instead of screenshots: a little necromancy game scene whose blinking "PRESS START" launches the game, and a little browser window with tabs in the title bar, a toolbar and a start page. -- **Asset-free cards & wallpaper** — every project/hardware card is a CSS gradient tile with - an emoji glyph (no screenshots), the desktop shell's app previews are the same CSS mock +- **Asset-free index & wallpaper** — Projects and Hardware are grouped repo-style index lists + (category headers, status/language chips, language-tinted dots on project rows, years — no emoji, no + screenshots), the desktop shell's app previews are the same CSS mock windows (a git-forge page for GitDXD), and its wallpaper is a layered CSS gradient. The - only real images left are the logo, the social SVGs, the Joker easter egg and the Gentoo - mark. + only real images left are the logo, the social SVGs, the Freezmo screenshot, the Joker + easter egg and the Gentoo mark. - **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 collide. diff --git a/agents.md b/agents.md index 7b057ce..dc408d5 100644 --- a/agents.md +++ b/agents.md @@ -157,15 +157,25 @@ Themes: `web` = default frosted-glass website (sidebar + content, light/dark), rectangle/square and never ends in an orphan "L" row (a 4th friend made the old 3-column grid do that). The same `friend.emoji` drives the desktop friend icon (Josef is 🧌 goblin, the rest 🧙 — the old per-friend SVGs are gone). - Projects/hardware use a CSS multi-column - **masonry** gallery (`.project-grid`) so short cards don't leave half-empty - grid slots; on phones it drops to 2 columns with a shorter tile. Cards are - **asset-free**: each renders a `.project-thumb` — a `.thumb-N` gradient - (N = index % 6) with the item's `emoji` glyph centred — instead of a - screenshot. `codingProjects` / `techProjects` in `data.ts` carry `emoji` - (no `img`/`image`). The two feature panels (`.web-split`) stretch + Projects/hardware render as a grouped repo-listing-style + **index** (`ProjectIndex.tsx`, `.index-*` classes): group headers + (Games & game jams / Linux & desktop / Bots, servers & plugins / Apps & + experiments; Desktops & servers / Laptops / Phones / Consoles & handhelds), + then rows: coding rows lead with a language-coloured dot, title and a + status pill over the description, with the language/host tag right-aligned; + hardware rows are plain (no dot) with the year right-aligned. Coding rows are + external links with a hover highlight + arrow; hardware rows are static. The + rows are **asset-free** (no emoji, no screenshots). `codingProjects` in + `data.ts` carries `slug` / `group` / `status?` / `tag` / `accent`; + `techProjects` carries `slug` / `group` / `year?` + (no `img`/`image`/`emoji`/`accent`). Status pill colors come from the `--status-*` + tokens in `web.css`, overridden for the dark desktop windows in `skeuo.css` + along with the row hairlines (`--index-line`). Above the split, the full-width + **Freezmo** feature panel (`.web-feature` + `.web-feature-shot`) is the one + place a **real screenshot** is used (`public/freezmo-app.webp`, the live + study app). The two remaining feature panels (`.web-split`) stretch 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) — decorative, **asset-free CSS mock-ups** rather than screenshots: Revival Inc. is a little necromancy game scene (night sky, moon, tombstones, blinking "PRESS START") and RustyWolf is a little browser window (tabs in the title bar, toolbar, address bar, start page). The browser window is `aria-hidden` @@ -178,11 +188,13 @@ Themes: `web` = default frosted-glass website (sidebar + content, light/dark), Revival Inc. → game, RustyWolf → browser), so there are no app-preview screenshots. The old stacked TUI panel layout and the `SlBackground` ASCII train were removed earlier. -- **No raster UI assets.** Every card, feature panel, app preview and the desktop - wallpaper is drawn in CSS: project/hardware cards are `.project-thumb` gradient - tiles with an `emoji`, the feature/app previews are `FeatureWindow` mock windows, +- **No raster UI assets.** Every list, feature panel mock, app preview and the + desktop wallpaper is drawn in CSS: project/hardware entries are `.index-row` + list rows (accent dot, status pill, tag/year, hairline separators), the + feature/app previews are `FeatureWindow` mock windows, and `.win-desktop` carries a layered gradient "wallpaper" (there is no - `wallpaper.jpg`). Only the social SVGs, the site logo (`src/app/icon.png`), the + `wallpaper.jpg`). Only the social SVGs, the site logo (`src/app/icon.png`), + the Freezmo screenshot (`public/freezmo-app.webp`), the Joker easter egg (`joker.webp`) and the Gentoo mark (`gentoo.svg`) remain as real image files. - **Not a terminal.** The web theme deliberately has no TUI chrome: the hero is @@ -207,7 +219,8 @@ Themes: `web` = default frosted-glass website (sidebar + content, light/dark), alphas makes dark look far more gradient-heavy. Tune the two schemes separately, not by eye against each other. - Interactive surfaces (`.web-ctl`, `.service-button`, `.social-button`, - `.project-card`, `.gym-item`, `.contribution-entry`, `.heatmap-container`) read + `.index-list`, `a.index-row:hover`, `.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 diff --git a/package-lock.json b/package-lock.json index e30b5ad..1de9256 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1901,9 +1901,9 @@ } }, "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", - "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.5.tgz", + "integrity": "sha512-QRUlFQ0WxvdWyqqG/WtI3iupfD5rBzmCHXSdPsY91sAtVtTo7Q4cb6zOccZ3gqEqkr0f1As1ehLqmEpDsRf+lg==", "cpu": [ "arm64" ], @@ -1919,13 +1919,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.3" + "@img/sharp-libvips-darwin-arm64": "1.3.4" } }, "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", - "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.5.tgz", + "integrity": "sha512-+BR255RhDlpygUpOc/Jdt1nT6DQ3XG/ERo5wbcdOf5Q320dKtPCKPLR1LJs9VGXRaMa8l1uUa0tkCNOXiAxZUw==", "cpu": [ "x64" ], @@ -1941,20 +1941,20 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.3" + "@img/sharp-libvips-darwin-x64": "1.3.4" } }, "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", - "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.5.tgz", + "integrity": "sha512-Y/z91nEZ4uIBX5X3nfTovjU9lHNKFYbL2lpHCLVNmXQK03VIZvXBBt0KxbPGp2SdGSF+2mQU4e+hQaWOt86iAw==", "license": "Apache-2.0", "optional": true, "os": [ "freebsd" ], "dependencies": { - "@img/sharp-wasm32": "0.35.4" + "@img/sharp-wasm32": "0.35.5" }, "engines": { "node": ">=20.9.0" @@ -1964,9 +1964,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", - "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.4.tgz", + "integrity": "sha512-5R89nBYiRdUlSWJxPhO+GVtaXzXSxKnRu/xqMn3KTA3L9EB9Oy/P+Nn2f2vlhPuUdy/Zusb2DarbyTpGCfEDuw==", "cpu": [ "arm64" ], @@ -1980,9 +1980,9 @@ } }, "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", - "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.4.tgz", + "integrity": "sha512-iR2OKH80yi0U+dUplyh3/xdpFvps6YkCwsXenIJxqxR1v9o+xtKTGbS9H7cps+2Vxjc8B1j96p75NmTGjIhtpQ==", "cpu": [ "x64" ], @@ -1996,9 +1996,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", - "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.4.tgz", + "integrity": "sha512-LmRtTsOHuvM2+wlO2Db37dx5MiZhB0FvSunciw48YjdOkZz9KAiRbm8ujeMOA1INqmei5NapFxYEK1D1ZSidmw==", "cpu": [ "arm" ], @@ -2015,9 +2015,9 @@ } }, "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", - "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.4.tgz", + "integrity": "sha512-Y3dgX/6lE2QhQb+Gxy0WZxfg9MEm/JBjamZpS2IklP7xIQoKN4hzAm7KcMVGtaVDt3neE9OKBC7vAfonA/Lr1A==", "cpu": [ "arm64" ], @@ -2034,9 +2034,9 @@ } }, "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", - "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.4.tgz", + "integrity": "sha512-Le6boB8Tai0Nis+gIxIpKx68UDVVIqdR8Tin5Yf1z2LJJQLDJvCDRqRu+jC2qCoD+eIomonmOwB4smBRxfVpYQ==", "cpu": [ "ppc64" ], @@ -2053,9 +2053,9 @@ } }, "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", - "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.4.tgz", + "integrity": "sha512-aHkkIEHPRdQEegJN20MLmGtxYD9R2wQr3Cwpddnu5+YKMt6Uzax7S9h5gpZTo8wyrGuZSlfQ63OevL5mTyOC7Q==", "cpu": [ "riscv64" ], @@ -2072,9 +2072,9 @@ } }, "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", - "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.4.tgz", + "integrity": "sha512-ra/mB6MikESDUO7Yg+Mi95bFBb9GsObURuhnOv3OqknjGe9sZrG8tCe9q0xSIGrtLgvgw0gKnFWcK4blSgQOuQ==", "cpu": [ "s390x" ], @@ -2091,9 +2091,9 @@ } }, "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", - "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.4.tgz", + "integrity": "sha512-GJ//SSXbnwSDes02umB3nDJLFcQzw8a18V8fyhqr6tV515tOEMdImjjxj1AoafMRz56F3PHgftnj1QEKSU1zkw==", "cpu": [ "x64" ], @@ -2110,9 +2110,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", - "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.4.tgz", + "integrity": "sha512-hvulFwtjUcagsis6BBxHwGFwWoNZjgYmULGVrZcyfNbjA8hKILbRxGg15/7w5HDyXHXUos/j6baAWqnCyQ2DWA==", "cpu": [ "arm64" ], @@ -2129,9 +2129,9 @@ } }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", - "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.4.tgz", + "integrity": "sha512-6zXKeE/p39I1AmA3cJG35eyBGNqNddLnUXjhwBnsGjFPWqf5VKkDBEqaEkPDoTEtkxwi2vv8Tcr2mDyP4So7Fg==", "cpu": [ "x64" ], @@ -2148,9 +2148,9 @@ } }, "node_modules/@img/sharp-linux-arm": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", - "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.5.tgz", + "integrity": "sha512-LEaXK2WdXVK5ykcw0buWyPMsmLLL2vpHLD6yrNSW+JGEL3BZPA4tpKN6iaMc4AxTTAoaX/sU1rOL51lcIz48ZQ==", "cpu": [ "arm" ], @@ -2169,13 +2169,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.3" + "@img/sharp-libvips-linux-arm": "1.3.4" } }, "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", - "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.5.tgz", + "integrity": "sha512-LYVx5JTsOM2CBzmxreh+nl64/3H6Xb09iSLknqH47z2T2DFFxDeFLP5y4dJwe6H7uGQlHPyEEtIqyo3DYsRwdQ==", "cpu": [ "arm64" ], @@ -2194,13 +2194,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.3" + "@img/sharp-libvips-linux-arm64": "1.3.4" } }, "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", - "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.5.tgz", + "integrity": "sha512-QVxAAq8evVRI9ia2vqgwrmWucn5Dfv+JdWzj75pD8omHLPSP7f8p20O8jxzjCcuCEQEOtYOZUmX1hkiZ0kdevA==", "cpu": [ "ppc64" ], @@ -2219,13 +2219,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.3" + "@img/sharp-libvips-linux-ppc64": "1.3.4" } }, "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", - "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.5.tgz", + "integrity": "sha512-LtdreXguaavKODPIfzJ4kffx7UNt1omwtK0rch4EBbbSTXPnxWmYSayXdLJw0fJzQ97kHt1gL/yh4tvU+nCyRQ==", "cpu": [ "riscv64" ], @@ -2244,13 +2244,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.3" + "@img/sharp-libvips-linux-riscv64": "1.3.4" } }, "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", - "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.5.tgz", + "integrity": "sha512-UZasTOFiYzotTsGOCu42BfUzP6Tu6Do/947iRm1RsLKvlllxwGcn4RN27LibGWceix4Y+Pmw3jsnTcCQIgWjqA==", "cpu": [ "s390x" ], @@ -2269,13 +2269,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.3" + "@img/sharp-libvips-linux-s390x": "1.3.4" } }, "node_modules/@img/sharp-linux-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", - "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.5.tgz", + "integrity": "sha512-SxFtLTeJInhAA9Q836kux2vZNeOBQEx658qvbboZScr0wIARym3IcGmW7KpVD5sbVg0Ojy+udFQdayYIZyoNog==", "cpu": [ "x64" ], @@ -2294,13 +2294,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.3" + "@img/sharp-libvips-linux-x64": "1.3.4" } }, "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", - "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.5.tgz", + "integrity": "sha512-9HbMclmI1zlNkFRs3z9/eBtDjfD0sGlrX1z6b1qwmiFY5ElDLh4BC0LPBdVp7z1DXFiKlIcznf+ZlsuZzLxQqg==", "cpu": [ "arm64" ], @@ -2319,13 +2319,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4" } }, "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", - "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.5.tgz", + "integrity": "sha512-4KOphqB035HrVdqLZfCgMzzERrQkkzOwRhl4OAkRO1YCldbaFjySXMaK534Mo0V+LndnlJk+sbUyLeU0ULyD1A==", "cpu": [ "x64" ], @@ -2344,13 +2344,13 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.3" + "@img/sharp-libvips-linuxmusl-x64": "1.3.4" } }, "node_modules/@img/sharp-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", - "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.5.tgz", + "integrity": "sha512-Ptsga1su4tQx+LLF1ECS9U6nz5kmrXKo6XVbtR48Ke3ZRxxgaWBu7IDtEe1quo8hiupwm6WFqxVlXaSf7IINGQ==", "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", "optional": true, "dependencies": { @@ -2364,16 +2364,16 @@ } }, "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", - "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.5.tgz", + "integrity": "sha512-hfhF/FmoQyTUkA0bIKFOtw536BQSeBMe6BF6QyWlrPxT754+TFLaZ7sKKTfvvM0yJgKgaYTwnFCIZ/GuDw5SUA==", "cpu": [ "wasm32" ], "license": "Apache-2.0", "optional": true, "dependencies": { - "@img/sharp-wasm32": "0.35.4" + "@img/sharp-wasm32": "0.35.5" }, "engines": { "node": ">=20.9.0" @@ -2383,9 +2383,9 @@ } }, "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", - "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.5.tgz", + "integrity": "sha512-X4t7g+7ZA5DKblCBEXGjUqqemj4vczING/5viFwAL8h4N3qYeyjwdCvRLHi4EdOUI+2Z7UFlp1VM+p/AuEtm6Q==", "cpu": [ "arm64" ], @@ -2402,9 +2402,9 @@ } }, "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", - "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.5.tgz", + "integrity": "sha512-5Zm82LoBc43nhwNybZlG7Y1KO//Zhsn306fQl29ZOuStHLGTo3BWL83q3cznX0poxSAMuYL1On/BHBxkBeKr6A==", "cpu": [ "ia32" ], @@ -2421,9 +2421,9 @@ } }, "node_modules/@img/sharp-win32-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", - "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.5.tgz", + "integrity": "sha512-x76eH0vEiHlcMQu8Y8IenntaACtddpT6W0wmXtWrnKcnKI7ME5DdgqhAD6SEWOEl1v2zDvkZDhFA9KnURwpfqg==", "cpu": [ "x64" ], @@ -8052,9 +8052,9 @@ } }, "node_modules/sharp": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", - "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", + "version": "0.35.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.5.tgz", + "integrity": "sha512-Ywn4OnzGukp7CDMrp08RQ50YKmuwG47brZgIVPTvBaaAfQlRlygrRqSrxdCiL9M+LlzLBiJ68IR1QqvzHyjC7g==", "license": "Apache-2.0", "optional": true, "dependencies": { @@ -8069,31 +8069,31 @@ "url": "https://opencollective.com/libvips" }, "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.4", - "@img/sharp-darwin-x64": "0.35.4", - "@img/sharp-freebsd-wasm32": "0.35.4", - "@img/sharp-libvips-darwin-arm64": "1.3.3", - "@img/sharp-libvips-darwin-x64": "1.3.3", - "@img/sharp-libvips-linux-arm": "1.3.3", - "@img/sharp-libvips-linux-arm64": "1.3.3", - "@img/sharp-libvips-linux-ppc64": "1.3.3", - "@img/sharp-libvips-linux-riscv64": "1.3.3", - "@img/sharp-libvips-linux-s390x": "1.3.3", - "@img/sharp-libvips-linux-x64": "1.3.3", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", - "@img/sharp-libvips-linuxmusl-x64": "1.3.3", - "@img/sharp-linux-arm": "0.35.4", - "@img/sharp-linux-arm64": "0.35.4", - "@img/sharp-linux-ppc64": "0.35.4", - "@img/sharp-linux-riscv64": "0.35.4", - "@img/sharp-linux-s390x": "0.35.4", - "@img/sharp-linux-x64": "0.35.4", - "@img/sharp-linuxmusl-arm64": "0.35.4", - "@img/sharp-linuxmusl-x64": "0.35.4", - "@img/sharp-webcontainers-wasm32": "0.35.4", - "@img/sharp-win32-arm64": "0.35.4", - "@img/sharp-win32-ia32": "0.35.4", - "@img/sharp-win32-x64": "0.35.4" + "@img/sharp-darwin-arm64": "0.35.5", + "@img/sharp-darwin-x64": "0.35.5", + "@img/sharp-freebsd-wasm32": "0.35.5", + "@img/sharp-libvips-darwin-arm64": "1.3.4", + "@img/sharp-libvips-darwin-x64": "1.3.4", + "@img/sharp-libvips-linux-arm": "1.3.4", + "@img/sharp-libvips-linux-arm64": "1.3.4", + "@img/sharp-libvips-linux-ppc64": "1.3.4", + "@img/sharp-libvips-linux-riscv64": "1.3.4", + "@img/sharp-libvips-linux-s390x": "1.3.4", + "@img/sharp-libvips-linux-x64": "1.3.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.4", + "@img/sharp-libvips-linuxmusl-x64": "1.3.4", + "@img/sharp-linux-arm": "0.35.5", + "@img/sharp-linux-arm64": "0.35.5", + "@img/sharp-linux-ppc64": "0.35.5", + "@img/sharp-linux-riscv64": "0.35.5", + "@img/sharp-linux-s390x": "0.35.5", + "@img/sharp-linux-x64": "0.35.5", + "@img/sharp-linuxmusl-arm64": "0.35.5", + "@img/sharp-linuxmusl-x64": "0.35.5", + "@img/sharp-webcontainers-wasm32": "0.35.5", + "@img/sharp-win32-arm64": "0.35.5", + "@img/sharp-win32-ia32": "0.35.5", + "@img/sharp-win32-x64": "0.35.5" }, "peerDependenciesMeta": { "@types/node": { @@ -8220,9 +8220,10 @@ } }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } diff --git a/public/freezmo-app.webp b/public/freezmo-app.webp new file mode 100644 index 0000000000000000000000000000000000000000..6d6206708c1e376432196f216cd1d63622f4d343 GIT binary patch literal 39472 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 Ydf7!qPX!&qv0)n6WsFs8==Mke02|XNiU0rr literal 0 HcmV?d00001 diff --git a/src/app/components/ProjectIndex.tsx b/src/app/components/ProjectIndex.tsx new file mode 100644 index 0000000..2b78bad --- /dev/null +++ b/src/app/components/ProjectIndex.tsx @@ -0,0 +1,140 @@ +import type { CSSProperties, ReactNode } from "react"; +import { + codingProjects, + techProjects, + type CodingProject, + type CodingProjectGroup, + type ProjectStatus, + type TechProject, + type TechProjectGroup, +} from "../data"; + +const STATUS_LABEL: Record = { + finished: "Finished", + live: "Live", + wip: "WIP", + unfinished: "Unfinished", + discontinued: "Discontinued", + forgotten: "Forgotten", +}; + +const PROJECT_GROUPS: { id: CodingProjectGroup; title: string }[] = [ + { id: "games", title: "Games & game jams" }, + { id: "linux", title: "Linux & desktop" }, + { id: "bots", title: "Bots, servers & plugins" }, + { id: "apps", title: "Apps & experiments" }, +]; + +const HARDWARE_GROUPS: { id: TechProjectGroup; title: string }[] = [ + { id: "desktops", title: "Desktops & servers" }, + { id: "laptops", title: "Laptops" }, + { id: "phones", title: "Phones" }, + { id: "consoles", title: "Consoles & handhelds" }, +]; + +/** + * Grouped, repo-listing-style index that replaced the old card gallery. + * Coding rows: language-coloured dot — title (+ status pill) over the + * description — host/language tag. Hardware rows: plain rows with the year + * on the right. Coding rows are links; hardware rows are static. + */ +function Group({ + title, + count, + children, +}: { + title: string; + count: number; + children: ReactNode; +}) { + return ( +
+

+ {title} + {count} +

+
{children}
+
+ ); +} + +function CodingRow({ project }: { project: CodingProject }) { + return ( + + + ); +} + +function HardwareRow({ project }: { project: TechProject }) { + return ( +
+ + + {project.title} + + {project.desc} + + {project.year ?? ""} +
+ ); +} + +export function CodingProjectIndex() { + return ( +
+ {PROJECT_GROUPS.map((group) => { + const items = codingProjects.filter((p) => p.group === group.id); + if (!items.length) return null; + return ( + + {items.map((project) => ( + + ))} + + ); + })} +
+ ); +} + +export function HardwareProjectIndex() { + return ( +
+ {HARDWARE_GROUPS.map((group) => { + const items = techProjects.filter((p) => p.group === group.id); + if (!items.length) return null; + return ( + + {items.map((project) => ( + + ))} + + ); + })} +
+ ); +} diff --git a/src/app/components/WebLayout.tsx b/src/app/components/WebLayout.tsx index 7fc9e4c..b2ab559 100644 --- a/src/app/components/WebLayout.tsx +++ b/src/app/components/WebLayout.tsx @@ -6,10 +6,11 @@ import JokerLogo from "./JokerLogo"; import ServiceButton from "./ServiceButton"; import ContributionHeatmap from "./ContributionHeatmap"; import FeatureWindow from "./FeatureWindow"; +import { CodingProjectIndex, HardwareProjectIndex } from "./ProjectIndex"; import Clock from "./Clock"; import { useTheme } from "./useTheme"; import { useColorScheme } from "./useColorScheme"; -import { socials, codingProjects, techProjects, friends } from "../data"; +import { socials, friends } from "../data"; const NAV = [ { id: "overview", label: "Overview" }, @@ -234,6 +235,23 @@ export default function WebLayout() { +
+ Freezmo quiz screen — a history question about the Schuman plan with AI grading feedback +

+ Started working on a new project Freezmo — basically a free version of the + famous Gizmo app, but instead of paying for AI you use your ollama free cloud + API key. Notes in, flashcards and quizzes out. Try it at{" "} + freezmo.dvorakmortonxd.dev. +

+
+
@@ -246,7 +264,7 @@ export default function WebLayout() {

-
+

A lightweight browser made in Rust with WebKitGTK. It's the successor to my @@ -267,37 +285,11 @@ export default function WebLayout() {

-
- {codingProjects.map((project, idx) => ( - - -

{project.title}

-

{project.desc}

-
- ))} -
+
-
- {techProjects.map((project, idx) => ( -
- -

{project.title}

-

{project.desc}

-
- ))} -
+
diff --git a/src/app/components/apps.tsx b/src/app/components/apps.tsx index 7df7a3a..0643cb0 100644 --- a/src/app/components/apps.tsx +++ b/src/app/components/apps.tsx @@ -2,15 +2,11 @@ import Image from "next/image"; import { useEffect, useRef, useState, type KeyboardEvent as ReactKeyboardEvent, type ReactNode } from "react"; -import { - socials, - codingProjects, - techProjects, - friends, -} from "../data"; +import { socials, friends } from "../data"; import ServiceButton from "./ServiceButton"; import ContributionHeatmap from "./ContributionHeatmap"; import FeatureWindow from "./FeatureWindow"; +import { CodingProjectIndex, HardwareProjectIndex } from "./ProjectIndex"; import JokerLogo from "./JokerLogo"; import { setTheme } from "./useTheme"; @@ -107,10 +103,14 @@ function NowApp() {

I'm currently hosting an SMP (dm me on discord). Also I'm pretty much - cooking daily, because im bulking through out the non-summer seasons. And me and - my pal Pepa are working on an education app so we - can study more efficiently, It's called{" "} - maturita.c! + cooking daily, because im bulking through out the non-summer seasons. I started + working on a new project{" "} + Freezmo, basically a free + version of the famous Gizmo app but instead of paying for AI you use your ollama + free cloud api key. The education app I started with my pal{" "} + Pepa, maturita.c, now lives on as{" "} + Graduately under his + wing.

@@ -204,23 +204,7 @@ function ServicesApp() { function ProjectsApp() { return (
-
- {codingProjects.map((project, idx) => ( - - -

{project.title}

-

{project.desc}

-
- ))} -
+
); } @@ -228,17 +212,7 @@ function ProjectsApp() { function HardwareApp() { return (
-
- {techProjects.map((project, idx) => ( -
- -

{project.title}

-

{project.desc}

-
- ))} -
+
); } @@ -480,7 +454,7 @@ function RevivalApp() { function RustyWolfApp() { return (
-

Introducing RustyWolf

+

RustyWolf

What makes it so cool???

@@ -513,7 +487,7 @@ const TERMINAL_FILES: Record = { "about_me.md": "Hey, I'm Martin Dvorak, a 17 year old IT student from the Czech Republic.\nI self-host way too many things and tinker with GNU/Linux.", "now.txt": - "Currently hosting an SMP and building an education app with Pepa.", + "Currently hosting an SMP. Started working on a new project Freezmo, basically a free version of the famous Gizmo app but instead of paying for AI you use your ollama free cloud api key.", "resume.txt": "sssvt.cz - network management & administration (2025-)\nGentoo, SwayFX, RustyWolf, dxdwm, Revival Inc.", }; diff --git a/src/app/data.ts b/src/app/data.ts index 804d6b3..47b2032 100644 --- a/src/app/data.ts +++ b/src/app/data.ts @@ -4,19 +4,46 @@ export interface Social { url: string; } +/** Lifecycle state of a coding project, shown as a chip on its index row. */ +export type ProjectStatus = + | "finished" + | "live" + | "wip" + | "unfinished" + | "discontinued" + | "forgotten"; + +/** Section a coding project is filed under in the Projects index. */ +export type CodingProjectGroup = "games" | "linux" | "bots" | "apps"; + export interface CodingProject { title: string; desc: string; - /** Emoji glyph shown on the card's CSS gradient tile (no image assets). */ - emoji: string; + /** Stable key for the index row (also the React key), e.g. `rustywolf`. */ + slug: string; + /** Index group the project is listed under. */ + group: CodingProjectGroup; + /** Status chip on the row; omitted for grab-bag entries. */ + status?: ProjectStatus; + /** Language or host badge on the row. */ + tag: string; + /** Hex accent for the row dot + hover tint. */ + accent: string; url: string; } +/** Section a device is filed under in the Hardware index. */ +export type TechProjectGroup = "desktops" | "laptops" | "phones" | "consoles"; + export interface TechProject { title: string; desc: string; - /** Emoji glyph shown on the card's CSS gradient tile (no image assets). */ - emoji: string; + /** Stable key for the index row (also the React key), e.g. `macbook-air-m4`. */ + slug: string; + /** Index group the device is listed under. */ + group: TechProjectGroup; + /** Model / build year, shown on the right when known. */ + year?: string; } export interface Friend { @@ -54,190 +81,317 @@ export const socials: Social[] = [ export const codingProjects: CodingProject[] = [ { - title: "Hospital Execution (Unfinished)", + title: "Hospital Execution", desc: "the first ever real game I made, in pygame. I've abandoned it.", - emoji: "🏥", + slug: "hospital-execution", + group: "games", + status: "unfinished", + tag: "itch.io", + accent: "#fa5c5c", url: "https://martin-dv.itch.io/hospital-execution-demo", }, { - title: "Underbaranoia (Finished)", + title: "Underbaranoia", desc: "basically a undertale like infinite fight simulator that gets progressively harder, made in pygame.", - emoji: "⚔️", + slug: "underbaranoia", + group: "games", + status: "finished", + tag: "itch.io", + accent: "#fa5c5c", url: "https://martin-dv.itch.io/underbaranoia", }, { - title: "Offline memer (Finished)", + title: "Offline memer", desc: "parody of the discord bot \"Dank Memer\" made in batch. (this was technically my first ever game I published).", - emoji: "🤖", + slug: "offline-memer", + group: "games", + status: "finished", + tag: "itch.io", + accent: "#fa5c5c", url: "https://martin-dv.itch.io/offline-memer", }, { - title: "4y (Forgotten)", + title: "The Larvae", + desc: "my entry for Mini Jam 212 (theme: Control), made in pygame. you spawn in a well developed city and parasite on people with your manipulative powers until you get so rich you destroy it.", + slug: "the-larvae", + group: "games", + status: "unfinished", + tag: "Python", + accent: "#cf6bd6", + url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/the-larvae", + }, + { + title: "4y", desc: "just a renamed fork of the ly login manager (based login manager btw I love it), no extra features, just a rename, its actually outdated so dont use it.", - emoji: "🔐", + slug: "4y", + group: "linux", + status: "forgotten", + tag: "C", + accent: "#7d8590", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/4y", }, { - title: "4rch linux (Forgotten)", + title: "4rch linux", desc: "same as above, basically just a renamed fork of arch linux with calamares installer, also outdated and not maintained at all so no use please.", - emoji: "🐧", + slug: "4rch-linux", + group: "linux", + status: "forgotten", + tag: "Shell", + accent: "#89e051", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/4rch-linux", }, { - title: "You_Are_An_Idiot_Virus.py (Finished)", + title: "You_Are_An_Idiot_Virus.py", desc: "this is just a python script that just spams blinking \"you are an idiot\" windows, made it as a prank I think, not really sure rn.", - emoji: "🪟", + slug: "uranidiot", + group: "apps", + status: "finished", + tag: "Python", + accent: "#3572A5", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/uranidiot", }, { - title: "Venturesome (Discontinued)", + title: "Venturesome", desc: "a browser I wrote in python using PyQtWebEngine with PyQt5, actually pretty cool and modular but I couldnt get past the stage of adding a tab system, basically surpassed by my other project: RustyWolf.", - emoji: "🌐", + slug: "venturesome", + group: "linux", + status: "discontinued", + tag: "Python", + accent: "#3572A5", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/Venturesome", }, { - title: "Mandelbrot set in Pygame (Finished)", + title: "Mandelbrot set in Pygame", desc: "a python pygame script that renders the mandelbrot set, made it when I was fascinated by how it looks and ngl it still looks cool af.", - emoji: "🌀", + slug: "mandelbrot", + group: "apps", + status: "finished", + tag: "Python", + accent: "#8b5cf6", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/mandelbrot", }, { - title: "Underpygametale (Unfinished)", + title: "Underpygametale", desc: "a remake of undertale written in pygame, got it to about the flowey part (at the beginning) and didnt touch it in a long time.", - emoji: "💀", + slug: "underpygametale", + group: "games", + status: "unfinished", + tag: "Python", + accent: "#ef476f", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/underpygametale", }, { title: "Many discord bots...", - desc: "so many of them, once I (allegedly, pls discord dont ban me) even wrote a \"self-bot\" which auto-advertised a minecraft server on minecraft discord server in lfg-hosting every two hours, around 800 people joined in total.", - emoji: "💬", - url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/PYGETEX", + desc: "so many of them, once I (allegedly, pls discord dont ban me) even wrote a \"self-bot\" (lfg-bot) which auto-advertised a minecraft server on minecraft discord server in lfg-hosting every two hours, around 800 people joined in total.", + slug: "lfg-bot", + group: "bots", + tag: "Python", + accent: "#5865F2", + url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/lfg-bot", }, { - title: "MMO minecraft plugin (Unfinished)", + title: "MMO minecraft plugin", desc: "a minceraft plugin with custom bosses, items, and functions. pretty barebones and basic but I did it all manually before vibecoding was even a thing so what.", - emoji: "⛏️", + slug: "mmo-plugin", + group: "bots", + status: "unfinished", + tag: "YouTube", + accent: "#ff3d3d", url: "https://www.youtube.com/watch?v=cSAX5Ds61ac", }, { title: "Many many failed minecraft servers..", desc: "creative games, softcraft, frostville, eusmp, eurthsmp, softsmp and many other SMPs that died later on. I cant even count how many mc servers I had in total.", - emoji: "🧱", + slug: "smp-graveyard", + group: "bots", + tag: "Discord", + accent: "#62b47a", url: "https://discord.gg/KtHRm9kRmy", }, { - title: "Swords and Sandals 2 pygame remake (Unfinished)", + title: "Swords and Sandals 2 pygame remake", desc: "an unfinished remake of swords and sandals 2 in pygame, I got bored of it and never finished it but ill finish it one day for sure lol.", - emoji: "🗡️", + slug: "sas2py", + group: "games", + status: "unfinished", + tag: "Python", + accent: "#d97706", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/sas2py", }, { title: "Llama.cpp server", desc: "my llama.cpp vm running on my proxmox with a gpu passthroughed RTX 3070, dm me if u wanna test it lol.", - emoji: "🦾", + slug: "llama-cpp", + group: "bots", + status: "live", + tag: "self-hosted", + accent: "#76b900", url: "https://ai.dvorakmortonxd.dev/", }, { - title: "Batch MSDOS Simulator (Finished)", + title: "Batch MSDOS Simulator", desc: "a freshman school project on making games in batch, it was like an OS simulator with a web browser, games, photos, even a video suprise (youll have to try it to figure that one out lol).", - emoji: "💾", + slug: "dvorakmsdos", + group: "linux", + status: "finished", + tag: "Batchfile", + accent: "#b6d94c", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/DvorakMSDOS", }, { - title: "RustyWolf (WIP, Available now!)", - desc: "a browser I made in rust with webkitgtk, I made it to be lightweight and to be able to be ran on macbook unibody 2010 before I realised I got scammed.. It's the successor to my previous project Venturesome :)", - emoji: "🐺", + title: "RustyWolf", + desc: "my privacy focused browser made in rust with webkitgtk, made lightweight so it can run on a macbook unibody 2010 before I realised I got scammed.. It's the successor to my previous project Venturesome :)", + slug: "rustywolf", + group: "linux", + status: "wip", + tag: "Rust", + accent: "#dea584", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/RustyWolf", }, { - title: "dxdwm (Discontinued)", - desc: "a small x11 window manager written in rust.", - emoji: "🪟", + title: "dxdwm", + desc: "a small x11 window manager. originally written in rust (dxdwm-rs), now continued in C.", + slug: "dxdwm", + group: "linux", + status: "discontinued", + tag: "C", + accent: "#94a3b8", url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/dxdwm", }, { - title: "Revival Inc. (Finished)", + title: "Revival Inc.", desc: "My game written in pygame and packaged with pygbag made for the Mini Jame Gam #55! tho I only made it in 6 hours lmao", - emoji: "🧟", + slug: "revival-inc", + group: "games", + status: "finished", + tag: "Python", + accent: "#10b981", url: "https://dvorakmortonxd.dev/revival-inc", }, + { + title: "freezmo", + desc: "a free version of the famous Gizmo app: notes in, flashcards and quizzes out — instead of paying for AI you use your own ollama free cloud api key.", + slug: "freezmo", + group: "apps", + status: "wip", + tag: "TypeScript", + accent: "#3178c6", + url: "https://freezmo.dvorakmortonxd.dev", + }, + { + title: "qol-tweaks", + desc: "my quality of life plugin for the dvorakmortonxd SMP.", + slug: "qol-tweaks", + group: "bots", + status: "live", + tag: "Java", + accent: "#b07219", + url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/qol-tweaks", + }, ]; export const techProjects: TechProject[] = [ { title: "Gentoo Setup", desc: "my main computer with gentoo and SwayFX. specs: Ryzen 5 3600 (6c/12t), RX 580 8GB ASUS ROG, 16gb of ram and a 240gb sata ssd.", - emoji: "🐧", + slug: "gentoo-swayfx", + group: "desktops", }, { title: "Proxmox Server", desc: "my personal proxmox server (dm me on ig if u need a VPS/hosting), specs: Xeon E5 2680 v4 (14c/28t), RTX 3070 (llama.cpp), 68gb ddr4 rdimm ram (2*16gb, 1*32gb, 1*4gb), 256gb of sata m2 space + 1tb hdd + 750gb hdd.", - emoji: "🖥️", + slug: "proxmox-server", + group: "desktops", }, { title: "Xbox 360 S (badupdate)", desc: "xbox 360 slim (trinity) with badupdate exploit, allowing to boot custom software. (not my photo), the specs are XCGPU (3c/6t), 0.5GB of gddr3 ram and a 500gb hdd.", - emoji: "🎮", + slug: "xbox-360-s", + group: "consoles", + year: "2010", }, { title: "Lenovo Legion Go S", desc: "my gaming handheld which I sometimes use as a computer, it has 32gb of unified lpddr5x memory and 1tb of nvme storage, I dualboot artix linux (openrc) with SwayFX and stock SteamOS on it.", - emoji: "🕹️", + slug: "legion-go-s", + group: "consoles", + year: "2025", }, { title: "Macbook Air M4 13\"", desc: "my main device for basically everything on the go except gaming. specs are Apple M4 (cpu:10c,gpu:8c), 16gb of unified ram (lpddr5x), 256gb Storage.", - emoji: "💻", + slug: "macbook-air-m4", + group: "laptops", + year: "2025", }, { title: "Macbook Air 2013 11\"", desc: "bought this for tinkering lol, specs are intel core i5 (2c/4t), 8gb of ddr3 ram and 250gb ssd, installed arch linux on it with i3wm.", - emoji: "💻", + slug: "macbook-air-2013", + group: "laptops", + year: "2013", }, { title: "iPhone 7 128gb", desc: "somehow found a listing for 4 bucks (refurbed.cz) for it so I got it lol, it has a little dent I marked it on the photo (which isnt mine btw), except cosmetic damage its pretty much fully functional, specs are Apple A10 (4c/4t), 2gb of ram and 128gb of storage", - emoji: "📱", + slug: "iphone-7", + group: "phones", + year: "2016", }, { title: "Macbook Unibody 2010", desc: "found random listing on bazos for 15 bucks but after I bought a power adapter it turned out to be non functioning so I got scammed :(", - emoji: "💻", + slug: "macbook-unibody-2010", + group: "laptops", + year: "2010", }, { title: "ThinkPad T400s 14\"", desc: "got it from a random guy for 20 bucks, its an old laptop from 2009. I put void linux on it and i3wm on it, specs are intel core 2 duo (2c/2t), 8gb ddr3 ram and 800gb hdd.", - emoji: "💻", + slug: "thinkpad-t400s", + group: "laptops", + year: "2009", }, { title: "Asus N56JR 15.6\"", desc: "one of my first laptops my dad got for me when I was like 12, still works but the battery is KO, specs are intel core i7 4700HQ (4c/8t), 8gb ddr3 ram and 240gb ssd, it currently runs ubuntu linux 24.04LTS and my mom uses it for movies and shows.", - emoji: "💻", + slug: "asus-n56jr", + group: "laptops", + year: "2013", }, { title: "Small Unknown XP Acer Laptop", desc: "found that one in ewaste, I think it has like 2gb of ram and an intel atom, not sure what to do with it yet", - emoji: "📟", + slug: "unknown-acer-xp", + group: "laptops", }, { title: "Dell Latitude E6320", desc: "also from ewaste, put mint on it but didnt do anything yet, lowk kinda capable for its time in 2011 so I might put it to use later but the battery is KO.", - emoji: "💻", + slug: "latitude-e6320", + group: "laptops", + year: "2011", }, { title: "iPhone 11 128gb", desc: "my first iphone I got from my parents at 13, rn my dad has it because I switched over to the iphone 16 pro in 2025, specs are Apple A13 (6c/6t), 4gb of ram and 128gb of storage. (NOT MY IMAGE)", - emoji: "📱", + slug: "iphone-11", + group: "phones", + year: "2019", }, { title: "iPhone 16 Pro 128gb", desc: "originally wanted iphone 13 mini (because of the size) but I somehow decided to get 16 pro, which is a bit smaller than my older iphone 11, specs are Apple A18 pro (6c/6t), (btw this chip is the same chip used in the macbook neo so thats cool) and 8gb of ram and 128gb of storage, my main phone.", - emoji: "📱", + slug: "iphone-16-pro", + group: "phones", + year: "2025", }, { title: "Xbox one S 2TB", desc: "my dad bought it for me also in like 2018 or 2019 and I sometimes play the console edition of minecraft because I like to play the gliding minigame on it when someone comes over.", - emoji: "🎮", + slug: "xbox-one-s", + group: "consoles", + year: "2016", }, ]; diff --git a/src/app/skeuo.css b/src/app/skeuo.css index 7f1db1e..74e7b56 100644 --- a/src/app/skeuo.css +++ b/src/app/skeuo.css @@ -852,41 +852,6 @@ a.win-icon { color: #9a9a9a; } -.app-surface .project-grid { - display: grid; - grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); - gap: 12px; -} -.app-surface .project-card { - padding: 10px; - border: 1px solid rgba(0, 0, 0, 0.15); - border-radius: 6px; - background: linear-gradient(to bottom, #ffffff, #f0f4fa); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.14); -} -.app-surface .project-card:hover { - border-color: #7db9e8; - background: #ffffff; - box-shadow: 0 0 0 1px #7db9e8, 0 0 14px rgba(110, 185, 255, 0.5), - 0 8px 18px rgba(0, 25, 55, 0.2); -} -.app-surface .project-thumb { - height: 150px; - border-radius: 4px; - border: 1px solid rgba(0, 0, 0, 0.12); -} -.app-surface .project-title { - color: #0e3355; -} -.app-surface .project-card:hover .project-title { - color: #0d5aa7; -} -.app-surface .project-desc { - color: #43607c; -} -.app-surface .project-card:hover .project-desc { - color: #1d3e5c; -} .app-surface .gym-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); @@ -1151,29 +1116,29 @@ a.win-icon { .win-body .service-button:hover .service-desc { color: #d3dae3; } -.win-body .project-card { - border-color: #1b1e20; - background: linear-gradient(to bottom, #31363b, #2a2e32); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4); +/* Project/Hardware index inside the dark KDE windows. */ +.win-body { + --index-line: rgba(255, 255, 255, 0.07); + --status-finished: #4ade80; + --status-live: #60a5fa; + --status-wip: #fbbf24; + --status-unfinished: #fb923c; + --status-discontinued: #f87171; + --status-forgotten: #94a3b8; } -.win-body .project-card:hover { - border-color: #3daee9; - background: #353b40; - box-shadow: 0 0 0 1px #3daee9, 0 0 14px rgba(61, 174, 233, 0.45); +.win-body .index-list { + background: rgba(255, 255, 255, 0.03); } -.win-body .project-thumb { - border-color: #1b1e20; -} -.win-body .project-title { +.win-body .index-title { color: #eff0f1; } -.win-body .project-card:hover .project-title { - color: #3daee9; -} -.win-body .project-desc { +.win-body .index-desc { color: #b0b6bc; } -.win-body .project-card:hover .project-desc { +.win-body a.index-row:hover { + background: rgba(255, 255, 255, 0.06); +} +.win-body a.index-row:hover .index-desc { color: #d3dae3; } @@ -1600,9 +1565,6 @@ html[data-theme="skeuo"] .fw { .app-pad { padding: 14px; } - .app-surface .project-grid { - grid-template-columns: 1fr; - } .app-surface .social-buttons { grid-template-columns: 1fr 1fr; } @@ -1613,8 +1575,14 @@ html[data-theme="skeuo"] .fw { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 6px; } - .app-surface .project-thumb { - height: 140px; + .app-surface .index-group-head { + font-size: 0.6rem; + } + .app-surface .index-row { + padding: 10px 11px; + } + .app-surface .index-desc { + font-size: 0.75rem; } } diff --git a/src/app/web.css b/src/app/web.css index 45338cd..6c18d28 100644 --- a/src/app/web.css +++ b/src/app/web.css @@ -44,6 +44,15 @@ --red: #e11d48; --darkpink: #db2777; + /* Project/Hardware index tokens */ + --index-line: rgba(16, 24, 43, 0.1); + --status-finished: #15803d; + --status-live: #1d4ed8; + --status-wip: #b45309; + --status-unfinished: #c2410c; + --status-discontinued: #b91c1c; + --status-forgotten: #64748b; + --web-font: "Inter", ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; --font-custom-mono: ui-monospace, "JetBrains Mono", "SFMono-Regular", Menlo, Consolas, @@ -84,6 +93,15 @@ html[data-theme="web"][data-scheme="dark"] { --purple: #c084fc; --red: #fb7185; --darkpink: #f472b6; + + /* Project/Hardware index tokens */ + --index-line: rgba(255, 255, 255, 0.09); + --status-finished: #4ade80; + --status-live: #60a5fa; + --status-wip: #fbbf24; + --status-unfinished: #fb923c; + --status-discontinued: #f87171; + --status-forgotten: #94a3b8; } html[data-theme="web"] { @@ -430,6 +448,17 @@ html[data-theme="web"] body { display: flex; flex-direction: column; } +/* Real app screenshot inside a feature panel (Freezmo) — framed like the CSS + mock windows so it sits in the same visual language. */ +.web-feature-shot { + display: block; + width: 100%; + height: auto; + margin-bottom: 14px; + border-radius: 16px; + border: 1px solid var(--glass-border); + box-shadow: 0 18px 36px -22px rgba(23, 32, 60, 0.5); +} /* ============================================================ FEATURE WINDOWS Asset-free decorative mock windows that replace the old @@ -1161,78 +1190,145 @@ html[data-theme="web"] body { } /* ============================================================ - PROJECTS / HARDWARE - ============================================================ */ -.project-grid { - /* Masonry-ish gallery: multi-column packs the cards tightly, so a short card - never leaves a half-empty slot under a tall neighbour. */ - columns: 3 250px; - column-gap: 14px; + PROJECTS / HARDWARE INDEX + ------------------------------------------------------------ + Grouped repo-listing layout: per-section group headers, then + rows of accent dot – title (+ status) over description – tag / + year. Replaced the old card gallery. */ +.index-groups { + display: flex; + flex-direction: column; + gap: 22px; } -.project-card { - display: block; - break-inside: avoid; - -webkit-column-break-inside: avoid; - margin-bottom: 14px; - padding: 12px; - border-radius: 16px; - border: 1px solid var(--btn-border, var(--glass-border)); +.index-group-head { + display: flex; + align-items: center; + gap: 10px; + margin: 0 0 8px; + font-family: var(--font-custom-mono); + font-size: 0.66rem; + font-weight: 700; + letter-spacing: 0.16em; + text-transform: uppercase; + color: var(--gray); +} +.index-group-count { + font-weight: 600; + color: color-mix(in srgb, var(--gray) 55%, transparent); +} +.index-group-head::after { + content: ""; + flex: 1; + height: 1px; + background: var(--index-line); +} +.index-list { + border: 1px solid var(--index-line); + border-radius: 12px; + overflow: hidden; background: var(--btn-bg, var(--glass-lo)); - box-shadow: var(--btn-shadow, none); +} +.index-list > * + * { + border-top: 1px solid var(--index-line); +} +.index-row { + display: grid; + grid-template-columns: 10px minmax(0, 1fr) auto; + gap: 14px; + align-items: start; + padding: 11px 14px; color: inherit; text-decoration: none; - transition: transform 0.22s ease, border-color 0.22s ease, box-shadow 0.22s ease, - background-color 0.22s ease; } -.project-card:hover { - transform: translateY(-4px); - border-color: var(--accent-line); +/* Hardware rows: no accent dot (it carried no meaning there), so the body + takes the full first track. */ +.index-row-plain { + grid-template-columns: minmax(0, 1fr) auto; +} +a.index-row { + transition: background-color 0.16s ease; +} +a.index-row:hover { background: var(--btn-bg-hi, var(--glass-hi)); - box-shadow: 0 20px 38px -20px rgba(23, 32, 60, 0.55); } -.project-thumb { - display: grid; - place-items: center; - height: 150px; - width: 100%; - margin-bottom: 12px; - border-radius: 12px; - border: 1px solid var(--glass-border); - font-size: 2.6rem; - line-height: 1; - user-select: none; - text-shadow: 0 3px 10px rgba(0, 0, 0, 0.35); +.index-dot { + width: 9px; + height: 9px; + margin-top: 6px; + border-radius: 50%; + background: var(--index-accent, var(--accent)); + box-shadow: 0 0 9px color-mix(in srgb, var(--index-accent, var(--accent)) 55%, transparent); } -/* Shared gradient palette for the card tiles (no image assets). */ -.thumb-0 { - background: linear-gradient(150deg, #6d5efc, #2f8bff); +.index-line1 { + display: flex; + align-items: baseline; + flex-wrap: wrap; + gap: 8px; } -.thumb-1 { - background: linear-gradient(150deg, #ec4899, #db2777); -} -.thumb-2 { - background: linear-gradient(150deg, #f59e0b, #d97757); -} -.thumb-3 { - background: linear-gradient(150deg, #10b981, #0d9488); -} -.thumb-4 { - background: linear-gradient(150deg, #8b5cf6, #6366f1); -} -.thumb-5 { - background: linear-gradient(150deg, #06b6d4, #3b82f6); -} -.project-title { - font-size: 0.95rem; +.index-title { + font-size: 0.92rem; font-weight: 700; + color: var(--fg); } -.project-card:hover .project-title { - color: var(--accent); +a.index-row:hover .index-title { + color: color-mix(in srgb, var(--index-accent, var(--accent)) 72%, var(--fg)); } -.project-desc { - margin-top: 4px; - font-size: 0.8rem; - color: var(--web-muted); +.index-status { + padding: 1px 7px 2px; + border-radius: 999px; + border: 1px solid color-mix(in srgb, currentColor 32%, transparent); + background: color-mix(in srgb, currentColor 10%, transparent); + font-family: var(--font-custom-mono); + font-size: 0.56rem; + font-weight: 700; + letter-spacing: 0.1em; + text-transform: uppercase; + color: var(--status-forgotten); +} +.index-status-finished { + color: var(--status-finished); +} +.index-status-live { + color: var(--status-live); +} +.index-status-wip { + color: var(--status-wip); +} +.index-status-unfinished { + color: var(--status-unfinished); +} +.index-status-discontinued { + color: var(--status-discontinued); +} +.index-status-forgotten { + color: var(--status-forgotten); +} +.index-desc { + display: block; + margin-top: 3px; + font-size: 0.78rem; + line-height: 1.5; + color: var(--gray); +} +.index-meta { + display: inline-flex; + align-items: center; + gap: 10px; + padding-top: 3px; + font-family: var(--font-custom-mono); + font-size: 0.62rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--gray); + white-space: nowrap; +} +.index-arrow { + transition: transform 0.16s ease, color 0.16s ease; +} +a.index-row:hover .index-arrow { + transform: translate(2px, -2px); + color: color-mix(in srgb, var(--index-accent, var(--accent)) 72%, var(--fg)); } /* ============================================================ @@ -1750,27 +1846,20 @@ html[data-theme="web"][data-scheme="dark"] .heatmap-legend-cell[data-level="4"] font-size: 0.82rem; font-weight: 600; } - /* Projects/hardware gallery: 2-up on phones instead of one full-width card - per row, with a shorter image + tighter card so a row is compact. */ - .project-grid { - columns: 2; - column-gap: 10px; + /* Projects/hardware index: tighter rows on phones. */ + .index-groups { + gap: 18px; } - .project-card { - margin-bottom: 10px; - padding: 10px; + .index-row { + gap: 10px; + padding: 10px 11px; } - .project-thumb { - height: 90px; - margin-bottom: 8px; - font-size: 1.8rem; - } - .project-title { - font-size: 0.88rem; - } - .project-desc { + .index-desc { font-size: 0.75rem; } + .index-meta { + font-size: 0.58rem; + } .services-buttons, .services-buttons.services-main { grid-template-columns: 1fr;