Compare commits

...

48 commits

Author SHA1 Message Date
dvorakmortonxd
7418089bb3 re-add public assets 2026-05-18 13:02:39 +02:00
dvorakmortonxd
88f6e7857e fixed apos build error 2026-05-18 11:49:44 +02:00
dvorakmortonxd
a30eb447b7 added an IOS link to quipee 2026-05-18 10:52:08 +02:00
dvorakmortonxd
22f687980a added a legitimate android link and a placeholder for now for ios for quipee 2026-05-18 10:01:55 +02:00
dvorakmortonxd
4bcac14c47 added a dash in the friends section 2026-05-18 09:59:21 +02:00
dvorakmortonxd
1eb69a2e21 added quipee to the friends project section 2026-05-18 09:56:48 +02:00
dvorakmortonxd
9c4aed434a made the background of the friends section green so it matches the icons 2026-05-18 09:46:18 +02:00
dvorakmortonxd
2a23136154 made the friends svg icons green 2026-05-18 09:44:46 +02:00
dvorakmortonxd
420931040e added a title to the friends website section 2026-05-18 09:38:38 +02:00
dvorakmortonxd
700093c39d added a title to the project.docx too, ps. dont be scared of pink :) 2026-05-18 09:37:06 +02:00
dvorakmortonxd
a3598d7786 added a title to the tech_list.json section 2026-05-18 09:35:08 +02:00
dvorakmortonxd
3933184b8c gitdxd branding :3 2026-05-18 09:29:07 +02:00
dvorakmortonxd
fd79539983 moved the forgejo heatmap below gitdxd, made more sense 2026-05-18 09:28:30 +02:00
dvorakmortonxd
0e8d790530 added an image to gitdxd section 2026-05-18 09:27:18 +02:00
dvorakmortonxd
1694c7ef50 minor change in gitdxd section 2026-05-18 09:24:01 +02:00
dvorakmortonxd
affcae6e26 added a gitdxd section 2026-05-18 09:23:17 +02:00
dvorakmortonxd
e3b6857b55 moved rustywolf section below the services section because it makes more sense for me no idea why I didnt do that the first time 2026-05-18 09:18:58 +02:00
dvorakmortonxd
c0ca6e8813 Added a complete RustyWolf Section, with RustyWolfPreview.webp in public and a section in page.tsx 2026-05-18 09:15:32 +02:00
dvorakmortonxd
a458c9ced2 gitdxd description change 2026-05-18 08:41:55 +02:00
dvorakmortonxd
908c65362a slightly changed up the softcraft section 2026-05-18 08:08:02 +02:00
dvorakmortonxd
c180b57af9 really needed to list my bodyweight somewhere :3 2026-05-16 00:53:57 +02:00
dvorakmortonxd
cddea3efb4 purple is nicer 2026-05-16 00:52:13 +02:00
dvorakmortonxd
ec996a46ff new actuality in about_me section 2026-05-16 00:49:18 +02:00
dvorakmortonxd
91137778a1 GPL3.0 Disclaimer at the bottom to keep the project open source :) 2026-05-16 00:46:44 +02:00
dvorakmortonxd
c07afb3d8e more vagons :3 2026-05-16 00:45:27 +02:00
dvorakmortonxd
01cefbdf79 changed description of my hardware after a recent upgrade 2026-05-16 00:27:30 +02:00
dvorakmortonxd
86e1da2596 added a new color and changed up the colors of the text in the forgejo heatmap section 2026-05-16 00:12:09 +02:00
dvorakmortonxd
dee8d23a3d changed the cells of the heatmap to purple, I like it better this way :3 2026-05-16 00:03:09 +02:00
dvorakmortonxd
d7ea83d031 fixed the heatmap cells being too sensitive compared to the original forgejo heatmap 2026-05-15 23:58:50 +02:00
dvorakmortonxd
19b8bc0dd2 added a feature for the git heatmap which shows the amount of commits done on the cell youre hovering over 2026-05-15 23:54:18 +02:00
dvorakmortonxd
ffb96d1c02 added dates for each PR in sbd 2026-05-15 23:50:16 +02:00
dvorakmortonxd
fe5fc4c0e5 added a glow to the SBD section 2026-05-15 23:44:30 +02:00
dvorakmortonxd
b915612456 added a slightly white blur as a background to the friends website section 2026-05-15 23:10:27 +02:00
dvorakmortonxd
559971f8a8 fixed build error caused by a mistake in route.ts and ContributionHeatmap.tsx 2026-05-15 13:20:43 +02:00
dvorakmortonxd
ab18ff319e added recent contributions to the contribution section 2026-05-15 13:13:06 +02:00
dvorakmortonxd
75192d53f1 slight change of the name of the contribution heatmap section 2026-05-15 13:00:39 +02:00
dvorakmortonxd
a7357c5764 perfected the forgejo heatmap, made it prettier and fully visible on all devices 2026-05-15 12:59:10 +02:00
dvorakmortonxd
c745cfc304 added a git heatmap from my forgejo instance to the website 2026-05-15 11:37:46 +02:00
dvorakmortonxd
6f3333b6be Fixed the SBD section for mobile devices 2026-05-15 10:52:30 +02:00
dvorakmortonxd
162c86a3d6 Changed the search bar text so its more accurate 2026-05-15 10:43:40 +02:00
dvorakmortonxd
94c8874b54 added a gym section to the website 2026-05-15 10:40:44 +02:00
dvorakmortonxd
cbbebbacc5 added a search bar for my searxng instance 2026-05-15 10:21:34 +02:00
dvorakmortonxd
9439ffcc84 updated README.md to my liking 2026-05-14 12:25:45 +02:00
dvorakmortonxd
f0856509ea fixed the website background (forgot to change png to webp after optimizing) and removed the uneccessary DS_Store file 2026-05-14 12:10:23 +02:00
dvorakmortonxd
d2a436a1c7 removed personal gf stuff (listed as "personal" in commit history), fixed a typo in .gitignore, and removed the accidentally comitted "removelater/" file 2026-05-14 11:58:03 +02:00
88fbd8d174 personal 2026-05-14 11:54:37 +02:00
24fc4c1e3a personal 2026-05-14 11:54:31 +02:00
dvorakmortonxd
21c10942bb Switched all the .png's to .webp and downsized them to allow for faster loading of the website+smaller repository size 2026-05-14 10:53:38 +02:00
77 changed files with 22682 additions and 1219 deletions

BIN
.DS_Store vendored

Binary file not shown.

5
.gitignore vendored
View file

@ -10,6 +10,10 @@
# testing
/coverage
# private gf site
/src/app/darecek/
/public/darecek/
# next.js
/.next/
/out/
@ -19,6 +23,7 @@
# misc
.DS_Store
/public/DS_Store
*.pem
# debug

View file

@ -1,46 +1,19 @@
# dvorakmortonxd.dev
# 👾 dvorakmortonxd.dev
> My personal website — socials, projects, services, and hardware all in one place. Welcome to the goblin cave. >:)
![Next.js](https://img.shields.io/badge/Next.js-black?logo=next.js) ![TypeScript](https://img.shields.io/badge/TypeScript-3178C6?logo=typescript&logoColor=white) ![Gentoo](https://img.shields.io/badge/Gentoo-54487A?logo=gentoo&logoColor=white)
---
## $ whoami
Hey, I'm **Martin Dvořák** — a 17-year-old IT student based in the Czech Republic, specializing in network management and administration at [sssvt.cz](https://sssvt.cz). I'm a passionate homelabber and developer heavily focused on self-hosting literally everything, writing code, and tinkering with Linux systems and retro hardware.
---
## 🌐 Live Site
**[dvorakmortonxd.dev](https://dvorakmortonxd.dev)**
---
> The source code for my own website.
This repository contains the Next.js frontend for my personal portfolio and link tree, **[dvorakmortonxd.dev](https://dvorakmortonxd.dev)**.
It's designed with a custom terminal/TUI aesthetic (using the Monocraft font and a Gruvbox-inspired theme) to list out my socials, hardware collections, self-hosted homelab services, and various scattered coding projects.
## 🛠️ Tech Stack
- **Framework:** Next.js (TypeScript)
- **Styling:** PostCSS / Tailwind
- **Deployed at:** [dvorakmortonxd.dev](https://dvorakmortonxd.dev)
---
## 📁 Project Structure
```
dvorakmortonxd.dev/
├── public/ # Static assets (icons, SVGs)
├── src/ # App source code
├── next.config.ts
├── tsconfig.json
└── postcss.config.mjs
```
---
- **Framework:** Next.js (App Router)
- **Language:** TypeScript
- **Styling:** Custom CSS for that retro TUI vibe
## 🚀 Running Locally
Want to spin it up and check the code out yourself?
```bash
git clone https://git.dvorakmortonxd.dev/dvorakmortonxd/dvorakmortonxd.dev
cd dvorakmortonxd.dev
@ -48,51 +21,14 @@ npm install
npm run dev
```
Open [http://localhost:3000](http://localhost:3000) in your browser.
Then open [http://localhost:3000](http://localhost:3000) in your browser.
---
## 🌍 Deploying?
## 🖥️ Self-Hosted Services
| Service | Description | Link |
|---|---|---|
| Proxmox | Server Management | [proxmox.dvorakmortonxd.dev](https://proxmox.dvorakmortonxd.dev) |
| Ollama | Local AI Server | [ai.dvorakmortonxd.dev](https://ai.dvorakmortonxd.dev) |
| Jellyfin | Local Media Server | [jelly.dvorakmortonxd.dev](https://jelly.dvorakmortonxd.dev) |
| MCSManager | Game Server Panel | [fake-pterodactyl.dvorakmortonxd.dev](https://fake-pterodactyl.dvorakmortonxd.dev) |
| Navidrome | Music Streaming | [navidrome.dvorakmortonxd.dev](https://navidrome.dvorakmortonxd.dev) |
| Mailcow | Email Server | [mailcow.dvorakmortonxd.dev](https://mailcow.dvorakmortonxd.dev) |
| SearxNG | Private Search | [search.dvorakmortonxd.dev](https://search.dvorakmortonxd.dev) |
| ConvertX | File Converter | [convert.dvorakmortonxd.dev](https://convert.dvorakmortonxd.dev) |
| GitDXD | Self-hosted Git | [git.dvorakmortonxd.dev](https://git.dvorakmortonxd.dev) |
---
## 🧪 Projects
- **[Hospital Execution](https://martin-dv.itch.io/hospital-execution-demo)** — First real game, made in Pygame
- **[Underbaranoia](https://martin-dv.itch.io/underbaranoia)** — Undertale-like infinite fight simulator in Pygame
- **[RustyWolf](https://git.dvorakmortonxd.dev/dvorakmortonxd/RustyWolf)** — Lightweight browser written in Rust with WebKitGTK
- **[dxdwm](https://git.dvorakmortonxd.dev/dvorakmortonxd/dxdwm)** — Small X11 window manager written in Rust
- **[Venturesome](https://git.dvorakmortonxd.dev/dvorakmortonxd/Venturesome)** — Browser written in Python with PyQtWebEngine
- **[Mandelbrot Set in Pygame](https://git.dvorakmortonxd.dev/dvorakmortonxd/mandelbrot)** — Pygame Mandelbrot set renderer
- **[Underpygametale](https://git.dvorakmortonxd.dev/dvorakmortonxd/underpygametale)** — Undertale remake in Pygame
- **[Batch MSDOS Simulator](https://git.dvorakmortonxd.dev/dvorakmortonxd/DvorakMSDOS)** — Batch OS simulator with games, browser, and surprises
- **[Offline Memer](https://martin-dv.itch.io/offline-memer)** — Dank Memer parody made in Batch
- **[Softcraft](https://dvorakmortonxd.dev/softcraft)** — My Minecraft server with a [live BlueMap](https://bluemap.dvorakmortonxd.dev)
---
In order to deploy the website youd want to set up a reverse proxy and something that runs it as a service, me personally, I use cloudflared and pm2.
you could also use something like vercel but I prefer selfhosting, also please if you want to deploy it,
you gotta change it enough so that you dont directly copy my website, and also follow the GPL3.0-only license,
meaning you gotta make your code opensource too
## 📬 Contact
- **Email:** [martin@dvorakmortonxd.dev](mailto:martin@dvorakmortonxd.dev)
- **Instagram:** [@dvorakmortonxd](https://www.instagram.com/dvorakmortonxd/)
- **LinkedIn:** [Martin Dvořák](https://www.linkedin.com/in/martin-dvorak-32012a394/)
- **Discord:** [dvorakmortonxd](https://discord.com/users/555745543763001364)
- **Itch.io:** [martin-dv.itch.io](https://martin-dv.itch.io)
---
## 📄 License
© 2025–2026 Martin Dvořák. All rights reserved (not really, I don't care).
To see my projects or get in touch, visit the live site or email me at [martin@dvorakmortonxd.dev](mailto:martin@dvorakmortonxd.dev).

BIN
public/Monocraft-Bold.ttf Normal file

Binary file not shown.

BIN
public/Monocraft-Italic.ttf Normal file

Binary file not shown.

BIN
public/Monocraft.ttf Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

BIN
public/asuslaptop.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

8
public/bench.svg Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<g id="bench-press-6" transform="translate(-2 -2)">
<path id="primary" d="M6,21V15H18v6" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path id="primary-2" data-name="primary" d="M4,3V9M3,4V8M20,3V9m1-5V8M4,6H20M16,4V15M8,15V4m9,17h2M5,21H7" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 625 B

4626
public/bukovina.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 285 KiB

BIN
public/coding-1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

BIN
public/coding-1.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
public/coding-10.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

BIN
public/coding-11.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

BIN
public/coding-12.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
public/coding-13.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/coding-14.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/coding-15.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

BIN
public/coding-16.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
public/coding-17.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

BIN
public/coding-2.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/coding-3.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 442 B

BIN
public/coding-4.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 954 B

BIN
public/coding-5.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
public/coding-6.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

BIN
public/coding-7.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
public/coding-8.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

BIN
public/coding-9.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

9
public/deadlift.svg Normal file
View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
<g id="deadlift" transform="translate(-2 -2)">
<circle id="secondary" fill="#2ca9bc" cx="2" cy="2" r="2" transform="translate(10 3)"/>
<path id="primary" d="M8,15V10a2,2,0,0,1,2-2h4a2,2,0,0,1,2,2v5" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
<path id="primary-2" data-name="primary" d="M14,5a2,2,0,1,1-2-2A2,2,0,0,1,14,5Zm0,9v7m-4,0V14M3,14H20m0-2v4m1-3v2M4,12v4M3,13v2" fill="none" stroke="#000000" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 762 B

BIN
public/dirt.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

12
public/discord.svg Normal file
View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0.5 24 24" id="meteor-icon-kit__regular-discord" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_525_68)">
<path d="M20.317 4.54101C18.7873 3.82774 17.147 3.30224 15.4319 3.00126C15.4007 2.99545 15.3695 3.00997 15.3534 3.039C15.1424 3.4203 14.9087 3.91774 14.7451 4.30873C12.9004 4.02808 11.0652 4.02808 9.25832 4.30873C9.09465 3.90905 8.85248 3.4203 8.64057 3.039C8.62448 3.01094 8.59328 2.99642 8.56205 3.00126C6.84791 3.30128 5.20756 3.82678 3.67693 4.54101C3.66368 4.54681 3.65233 4.5565 3.64479 4.56907C0.533392 9.29283 -0.31895 13.9005 0.0991801 18.451C0.101072 18.4733 0.11337 18.4946 0.130398 18.5081C2.18321 20.0401 4.17171 20.9701 6.12328 21.5866C6.15451 21.5963 6.18761 21.5847 6.20748 21.5585C6.66913 20.9179 7.08064 20.2424 7.43348 19.532C7.4543 19.4904 7.43442 19.441 7.39186 19.4246C6.73913 19.173 6.1176 18.8662 5.51973 18.5178C5.47244 18.4897 5.46865 18.421 5.51216 18.3881C5.63797 18.2923 5.76382 18.1926 5.88396 18.0919C5.90569 18.0736 5.93598 18.0697 5.96153 18.0813C9.88928 19.9036 14.1415 19.9036 18.023 18.0813C18.0485 18.0687 18.0788 18.0726 18.1015 18.091C18.2216 18.1916 18.3475 18.2923 18.4742 18.3881C18.5177 18.421 18.5149 18.4897 18.4676 18.5178C17.8697 18.8729 17.2482 19.173 16.5945 19.4236C16.552 19.4401 16.533 19.4904 16.5538 19.532C16.9143 20.2414 17.3258 20.9169 17.7789 21.5576C17.7978 21.5847 17.8319 21.5963 17.8631 21.5866C19.8241 20.9701 21.8126 20.0401 23.8654 18.5081C23.8834 18.4946 23.8948 18.4742 23.8967 18.452C24.3971 13.1911 23.0585 8.6212 20.3482 4.57004C20.3416 4.5565 20.3303 4.54681 20.317 4.54101ZM8.02002 15.6802C6.8375 15.6802 5.86313 14.577 5.86313 13.222C5.86313 11.8671 6.8186 10.7639 8.02002 10.7639C9.23087 10.7639 10.1958 11.8768 10.1769 13.222C10.1769 14.577 9.22141 15.6802 8.02002 15.6802ZM15.9947 15.6802C14.8123 15.6802 13.8379 14.577 13.8379 13.222C13.8379 11.8671 14.7933 10.7639 15.9947 10.7639C17.2056 10.7639 18.1705 11.8768 18.1516 13.222C18.1516 14.577 17.2056 15.6802 15.9947 15.6802Z" fill="#758CA3"/>
</g>
<defs>
<clipPath id="clip0_525_68">
<rect width="24" height="24" fill="white"/>
</clipPath>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

BIN
public/gentoo-setup.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

BIN
public/gitdxd.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 77 KiB

34
public/github.svg Normal file
View file

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="-1.65 0 259.3 259.3" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
<g>
<path fill="#9EDCF2" d="M200.9,199.8c0,13.9-32.2,25.1-71.9,25.1c-39.7,0-71.9-11.3-71.9-25.1c0-13.9,32.2-25.1,71.9-25.1C168.7,174.7,200.9,185.9,200.9,199.8L200.9,199.8z M200.9,199.8" />
<g>
<defs>
<path id="SVGID_1_" d="M98.1,244.8c1.6,7.5,5.5,11.9,9.4,14.5l41.1,0c5-3.4,10.1-9.8,10.1-21.8v-31c0,0,0.6-7.7,7.7-10.2c0,0,4.1-2.9-0.3-4.5c0,0-19.5-1.6-19.5,14.4v23.6c0,0,0.8,8.7-3.8,12.3v-29.2c0,0,0.3-9.3,5.1-12.8c0,0,3.2-5.7-3.8-4.2c0,0-13.4,1.9-14,17.6l-0.3,30h-3.2l-0.3-30c-0.6-15.6-14-17.6-14-17.6c-7-1.6-3.8,4.2-3.8,4.2c4.8,3.5,5.1,12.8,5.1,12.8v29.5c-4.6-3.3-3.8-12.6-3.8-12.6v-23.6c0-16-19.5-14.4-19.5-14.4c-4.5,1.6-0.3,4.5-0.3,4.5c7,2.6,7.7,10.2,7.7,10.2v21.7L98.1,244.8z" />
</defs>
<clipPath id="SVGID_2_">
<use xlink:href="#SVGID_1_" overflow="visible" />
</clipPath>
<path clip-path="url(#SVGID_2_)" fill="#7DBCE7" d="M200.9,199.8c0,13.9-32.2,25.1-71.9,25.1c-39.7,0-71.9-11.3-71.9-25.1c0-13.9,32.2-25.1,71.9-25.1C168.7,174.7,200.9,185.9,200.9,199.8L200.9,199.8z M200.9,199.8" />
</g>
<path fill="#9EDCF2" d="M46.9,125.9l-2.1,7.2c0,0-0.5,2.6,1.9,3.1c2.6-0.1,2.4-2.5,2.2-3.2L46.9,125.9L46.9,125.9z M46.9,125.9" />
<path fill="#010101" d="M255.8,95.6l0.2-0.9c-21.1-4.2-42.7-4.3-55.8-3.7c2.1-7.7,2.8-16.7,2.8-26.6c0-14.3-5.4-25.7-14-34.3c1.5-4.9,3.5-15.8-2-29.7c0,0-9.8-3.1-32.1,11.8c-8.7-2.2-18-3.3-27.3-3.3c-10.2,0-20.5,1.3-30.2,3.9C74.4-2.9,64.3,0.3,64.3,0.3c-6.6,16.5-2.5,28.8-1.3,31.8c-7.8,8.4-12.5,19.1-12.5,32.2c0,9.9,1.1,18.8,3.9,26.5c-13.2-0.5-34-0.3-54.4,3.8l0.2,0.9c20.4-4.1,41.4-4.2,54.5-3.7c0.6,1.6,1.3,3.2,2,4.7c-13,0.4-35.1,2.1-56.3,8.1l0.3,0.9c21.4-6,43.7-7.6,56.6-8c7.8,14.4,23,23.8,50.2,26.7c-3.9,2.6-7.8,7-9.4,14.5c-5.3,2.5-21.9,8.7-31.9-8.5c0,0-5.6-10.2-16.3-11c0,0-10.4-0.2-0.7,6.5c0,0,6.9,3.3,11.7,15.6c0,0,6.3,21,36.4,14.2V177c0,0-0.6,7.7-7.7,10.2c0,0-4.2,2.9,0.3,4.5c0,0,19.5,1.6,19.5-14.4v-23.6c0,0-0.8-9.4,3.8-12.6v38.8c0,0-0.3,9.3-5.1,12.8c0,0-3.2,5.7,3.8,4.2c0,0,13.4-1.9,14-17.6l0.3-39.3h3.2l0.3,39.3c0.6,15.6,14,17.6,14,17.6c7,1.6,3.8-4.2,3.8-4.2c-4.8-3.5-5.1-12.8-5.1-12.8v-38.5c4.6,3.6,3.8,12.3,3.8,12.3v23.6c0,16,19.5,14.4,19.5,14.4c4.5-1.6,0.3-4.5,0.3-4.5c-7-2.6-7.7-10.2-7.7-10.2v-31c0-12.1-5.1-18.5-10.1-21.8c29-2.9,42.9-12.2,49.3-26.8c12.7,0.3,35.6,1.9,57.4,8.1l0.3-0.9c-21.7-6.1-44.4-7.7-57.3-8.1c0.6-1.5,1.1-3,1.6-4.6C212.9,91.4,234.6,91.4,255.8,95.6L255.8,95.6z M255.8,95.6" />
<path fill="#F5CCB3" d="M174.6,63.7c6.2,5.7,9.9,12.5,9.9,19.8c0,34.4-25.6,35.3-57.2,35.3c-31.6,0-57.2-4.8-57.2-35.3c0-7.3,3.6-14.1,9.8-19.7c10.3-9.4,27.7-4.4,47.4-4.4C147,59.4,164.3,54.3,174.6,63.7L174.6,63.7z M174.6,63.7" />
<path fill="#FFFFFF" d="M108.3,85.3c0,9.5-5.3,17.1-11.9,17.1c-6.6,0-11.9-7.7-11.9-17.1c0-9.5,5.3-17.1,11.9-17.1C103,68.1,108.3,75.8,108.3,85.3L108.3,85.3z M108.3,85.3" />
<path fill="#AF5C51" d="M104.5,85.5c0,6.3-3.6,11.4-7.9,11.4c-4.4,0-7.9-5.1-7.9-11.4c0-6.3,3.6-11.4,7.9-11.4C100.9,74.1,104.5,79.2,104.5,85.5L104.5,85.5z M104.5,85.5" />
<path fill="#FFFFFF" d="M172.2,85.3c0,9.5-5.3,17.1-11.9,17.1c-6.6,0-11.9-7.7-11.9-17.1c0-9.5,5.3-17.1,11.9-17.1C166.8,68.1,172.2,75.8,172.2,85.3L172.2,85.3z M172.2,85.3" />
<path fill="#AF5C51" d="M168.3,85.5c0,6.3-3.6,11.4-7.9,11.4c-4.4,0-7.9-5.1-7.9-11.4c0-6.3,3.6-11.4,7.9-11.4C164.8,74.1,168.3,79.2,168.3,85.5L168.3,85.5z M168.3,85.5" />
<path fill="#AF5C51" d="M130.5,100.5c0,1.6-1.3,3-3,3c-1.6,0-3-1.3-3-3s1.3-3,3-3C129.1,97.5,130.5,98.8,130.5,100.5L130.5,100.5z M130.5,100.5" />
<path fill="#AF5C51" d="M120.6,108c-0.2-0.5,0.1-1,0.6-1.2c0.5-0.2,1,0.1,1.2,0.6c0.8,2.2,2.8,3.6,5.1,3.6c2.3,0,4.3-1.5,5.1-3.6c0.2-0.5,0.7-0.8,1.2-0.6c0.5,0.2,0.8,0.7,0.6,1.2c-1,2.9-3.8,4.9-6.9,4.9C124.4,112.9,121.6,110.9,120.6,108L120.6,108z M120.6,108" />
<path fill="#C4E5D9" d="M54.5,121.6c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C53.6,120.2,54.5,120.8,54.5,121.6L54.5,121.6z M54.5,121.6" />
<path fill="#C4E5D9" d="M60.3,124.8c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C59.4,123.4,60.3,124,60.3,124.8L60.3,124.8z M60.3,124.8" />
<path fill="#C4E5D9" d="M63.8,129c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C62.9,127.5,63.8,128.2,63.8,129L63.8,129z M63.8,129" />
<path fill="#C4E5D9" d="M67,133.8c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C66.1,132.3,67,133,67,133.8L67,133.8z M67,133.8" />
<path fill="#C4E5D9" d="M70.5,138.2c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C69.6,136.8,70.5,137.4,70.5,138.2L70.5,138.2z M70.5,138.2" />
<path fill="#C4E5D9" d="M75.3,142.1c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C74.4,140.6,75.3,141.3,75.3,142.1L75.3,142.1z M75.3,142.1" />
<path fill="#C4E5D9" d="M82,144.6c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C81.1,143.2,82,143.8,82,144.6L82,144.6z M82,144.6" />
<path fill="#C4E5D9" d="M88.7,144.6c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C87.8,143.2,88.7,143.8,88.7,144.6L88.7,144.6z M88.7,144.6" />
<path fill="#C4E5D9" d="M95.5,143.5c0,0.8-0.9,1.4-2.1,1.4c-1.1,0-2.1-0.6-2.1-1.4c0-0.8,0.9-1.4,2.1-1.4C94.5,142.1,95.5,142.7,95.5,143.5L95.5,143.5z M95.5,143.5" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 5.5 KiB

BIN
public/gruvbox.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

24
public/instagram.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 656 KiB

BIN
public/iphone-7.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
public/iphone11.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

BIN
public/iphone16pro.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

5
public/itchio.svg Normal file
View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="24" cy="24" r="20" fill="#FF2449"/>
<path d="M15.129 13.1335C14.0821 13.7551 12.0195 16.1245 12 16.746V17.7745C12 19.0783 13.2188 20.2243 14.3253 20.2243C15.6539 20.2243 16.761 19.1231 16.761 17.8162C16.761 19.1231 17.8301 20.2243 19.1589 20.2243C20.4877 20.2243 21.5225 19.1231 21.5225 17.8162C21.5225 19.1231 22.6592 20.2243 23.9879 20.2243H24.0121C25.3409 20.2243 26.4776 19.1231 26.4776 17.8162C26.4776 19.1231 27.5124 20.2243 28.8411 20.2243C30.1699 20.2243 31.239 19.1231 31.239 17.8162C31.239 19.1231 32.3462 20.2243 33.6747 20.2243C34.7812 20.2243 36 19.0785 36 17.7745V16.746C35.9805 16.1244 33.9179 13.7549 32.8713 13.1335C29.6175 13.0193 27.3618 12.9995 23.9999 13C20.6381 13.0003 16.055 13.0528 15.1287 13.1335H15.129ZM21.5057 19.6102C21.3786 19.8317 21.2212 20.0343 21.0381 20.2122C20.5365 20.7026 19.849 21.0067 19.0911 21.0067C18.362 21.0074 17.6611 20.7218 17.1399 20.2119C16.9582 20.0339 16.8201 19.8435 16.6936 19.6219L16.6931 19.6223C16.5666 19.8443 16.3906 20.0345 16.2085 20.2127C15.6873 20.7223 14.9863 21.0076 14.2573 21.007C14.166 21.007 14.0709 20.9818 13.9941 20.9554C13.8872 22.0677 13.8422 23.1306 13.8263 23.9057L13.8261 23.9101C13.8241 24.3037 13.8221 24.6273 13.8202 25.077C13.8407 27.4107 13.589 32.6411 14.8491 33.9262C16.8019 34.3815 20.395 34.5888 23.9998 34.5901H24.0004C27.6051 34.5888 31.1982 34.3815 33.1509 33.9262C34.4111 32.641 34.1594 27.4106 34.18 25.0769C34.1778 24.6273 34.176 24.3037 34.1741 23.91L34.1737 23.9056C34.158 23.1303 34.1129 22.0674 34.006 20.9551C33.9292 20.9815 33.8342 21.0068 33.7428 21.0068C33.0138 21.0074 32.3128 20.7221 31.7916 20.2125C31.6095 20.0343 31.4334 19.8442 31.307 19.6221L31.3064 19.6217C31.1798 19.8433 31.0418 20.0337 30.8601 20.2117C30.339 20.7215 29.6381 21.0071 28.909 21.0063C28.1512 21.0063 27.4636 20.7022 26.962 20.2119C26.7789 20.034 26.6215 19.8313 26.4945 19.6099C26.3688 19.8311 26.2129 20.0337 26.0312 20.2119C25.51 20.7217 24.809 21.0072 24.0799 21.0064C24.0535 21.0064 24.0271 21.0053 24.0007 21.0045H24C23.9736 21.0053 23.9472 21.0064 23.9205 21.0064C23.1914 21.0072 22.4903 20.7218 21.9691 20.212C21.7876 20.0338 21.6316 19.8311 21.506 19.61L21.5057 19.6102ZM19.5019 22.2013L19.5017 22.2022H19.5032C20.2967 22.2038 21.0016 22.2022 21.875 23.1555C22.5625 23.0834 23.2808 23.0474 23.9997 23.0485H24.0003C24.7192 23.0475 25.4375 23.0834 26.1251 23.1555C26.9985 22.2021 27.7034 22.2037 28.4969 22.2022H28.4983L28.4981 22.2013C28.8731 22.2013 30.3728 22.2013 31.4178 25.1362L32.5402 29.1626C33.372 32.158 32.2739 32.2313 30.9042 32.2338C28.8729 32.1583 27.7481 30.6831 27.7481 29.2081C26.6237 29.3924 25.312 29.4846 24.0002 29.4846H23.9996C22.6878 29.4846 21.376 29.3924 20.2517 29.2081C20.2517 30.6831 19.1269 32.1583 17.0957 32.2338C15.7259 32.2313 14.6279 32.1581 15.4597 29.1626L16.5824 25.1363C17.6274 22.2014 19.1271 22.2014 19.5021 22.2014L19.5019 22.2013ZM23.9997 24.5078V24.5084C23.9978 24.5103 21.8613 26.4725 21.4772 27.1703L22.8763 27.1143V28.3344C22.8763 28.3915 23.4377 28.3682 23.9997 28.3422H24.0003C24.5622 28.3682 25.1236 28.3915 25.1236 28.3344V27.1143L26.5227 27.1703C26.1385 26.4725 24.0002 24.5084 24.0002 24.5084V24.5078L23.9999 24.508L23.9997 24.5078Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 3.3 KiB

BIN
public/joker.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

2
public/linkedin.svg Normal file
View file

@ -0,0 +1,2 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" width="800px" height="800px" viewBox="0 0 24 24" id="linkedin" data-name="Flat Line" xmlns="http://www.w3.org/2000/svg" class="icon flat-line"><rect id="secondary" x="3" y="3" width="18" height="18" rx="1" style="fill: rgb(44, 169, 188); stroke-width: 2;"></rect><path id="primary" d="M16,17V14a2,2,0,0,0-2-2h0a2,2,0,0,0-2,2v3" style="fill: none; stroke: rgb(0, 0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"></path><line id="primary-upstroke" x1="7.95" y1="7.5" x2="8.05" y2="7.5" style="fill: none; stroke: rgb(0, 0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2.5;"></line><path id="primary-2" data-name="primary" d="M8,12v5m4-3V12m9,8V4a1,1,0,0,0-1-1H4A1,1,0,0,0,3,4V20a1,1,0,0,0,1,1H20A1,1,0,0,0,21,20Z" style="fill: none; stroke: rgb(0, 0, 0); stroke-linecap: round; stroke-linejoin: round; stroke-width: 2;"></path></svg>

After

Width:  |  Height:  |  Size: 1,013 B

117
public/llms.txt Normal file
View file

@ -0,0 +1,117 @@
# dvorakmortonxd.dev
> Personal website of Martin Dvořák (dvorakmortonxd), a Czech developer, homelab enthusiast, and self-hoster based in the Czech Republic. The site serves as a hub for his social media, self-hosted services, hardware collection, coding projects, and friends.
## Author
- Name: Martin Dvořák
- Alias: dvorakmortonxd
- Role: Developer, homelab enthusiast, self-hoster, IT Student at sssvt.cz
- Location: Czech Republic
- Contact: dvorak@dvorakmortonxd.dev, or see social links below
- Free time: Spending time with girlfriend, playing Terraria and Minecraft modpacks with Mekanism
## Socials
- Instagram (main): https://www.instagram.com/dvorakmortonxd/
- Instagram (gym): https://www.instagram.com/dvorakmortonxd2/
- SoundCloud: https://soundcloud.com/martin-dvorak-185636305
- TikTok: https://www.tiktok.com/@dvorakmortonxd
- Snapchat: https://www.snapchat.com/add/dvorakmortonxd
- GitHub: https://github.com/dvorakmortonxd
- LinkedIn: https://www.linkedin.com/in/martin-dvorak-32012a394/
- Itch.io: https://martin-dv.itch.io
- Discord: https://discord.com/users/555745543763001364
- Reddit: https://www.reddit.com/user/M4RT1NYT/
- Twitter/X: https://x.com/pepicskopcecek
- Quipee: https://quipee.me/dvorakmortonxd
## Self-Hosted Services
Martin runs a personal Proxmox homelab server and self-hosts the following services:
- Proxmox (server management): https://proxmox.dvorakmortonxd.dev/
- Ollama (local AI inference with RTX 3070 GPU passthrough): https://ai.dvorakmortonxd.dev/
- Jellyfin (local media server): https://jelly.dvorakmortonxd.dev/
- MCSManager (game server panel): https://fake-pterodactyl.dvorakmortonxd.dev/
- Navidrome (music streaming): https://navidrome.dvorakmortonxd.dev/
- Mailcow (email server): https://mailcow.dvorakmortonxd.dev/
- SearxNG (private search): https://search.dvorakmortonxd.dev/
- ConvertX (file converter): https://convert.dvorakmortonxd.dev/
## Hardware
### Main Desktop — Gentoo Linux
- CPU: AMD Ryzen 5 3600 (6c/12t)
- GPU: NVIDIA GTX 1050 Ti
- RAM: 16GB
- Storage: 240GB SSD
- OS: Gentoo Linux
### Proxmox Homelab Server
- CPU: Intel Xeon E5 2680 v4 (14c/28t)
- GPU: NVIDIA RTX 3070 (used for local AI via Ollama)
- RAM: 68GB DDR4 RDIMM (2×16GB + 1×32GB + 1×4GB)
- Storage: 256GB SATA M.2 + 1TB HDD + 750GB HDD
- Note: Available for VPS/hosting (DM on Instagram)
### Laptops
- MacBook Air M4 13" — Apple M4 (10c CPU / 8c GPU), 16GB unified RAM (LPDDR5X), 256GB storage. Main daily driver for everything except gaming.
- MacBook Air 2013 11" — Intel Core i5 (2c/4t), 8GB DDR3, 250GB SSD. Runs Arch Linux with i3-gaps (given to Josef).
- MacBook Unibody 2010 — Non-functional (purchased faulty for €15 on bazos).
- ThinkPad T400s 14" (2009) — Intel Core 2 Duo (2c/2t), 8GB DDR3, 800GB HDD. Runs Void Linux + i3wm. Intel AMT disabled.
- Asus N56JR 15.6" — Intel Core i7 4700HQ (4c/8t), 8GB DDR3, 240GB SSD. Runs Ubuntu 24.04 LTS (mom uses it for movies).
### Phones
- iPhone 16 Pro 128GB — Apple A18 Pro (6c/6t), 8GB RAM. Current main phone.
- iPhone 11 128GB — Apple A13 (6c/6t), 4GB RAM. Now used by father.
- iPhone 7 128GB — Apple A10 (4c/4t), 2GB RAM. Purchased for ~€4 on refurbed.cz.
### Gaming
- Xbox 360 S — Trinity motherboard, modified with badupdate exploit for custom software. XCGPU (3c/6t), 0.5GB GDDR3, 500GB HDD.
- Xbox One S 2TB — Owned since ~2018 or 2019, used sometimes for Minecraft console edition gliding minigame.
## Coding Projects
### Games
- Hospital Execution — First real game, made in Pygame. https://martin-dv.itch.io/hospital-execution-demo
- Underbaranoia — Undertale-like infinite fight simulator, made in Pygame. https://martin-dv.itch.io/underbaranoia
- Swords and Sandals 2 Pygame Remake — Unfinished remake of the classic flash game (will finish it one day). https://github.com/dvorakmortonxd/sas2py
- Underpygametale — Remake of Undertale written in Pygame. https://github.com/dvorakmortonxd/underpygametale
### Tools & Utilities
- Offline Memer — Parody of the Discord bot "Dank Memer", made in Batch (first published game). https://martin-dv.itch.io/offline-memer
- 4y — Rebranded fork of Ly (Linux login manager), no extra features. Outdated. https://github.com/dvorakmortonxd/4y
- 4rch Linux — Rebranded fork of Arch Linux with the Calamares installer. Outdated. https://github.com/dvorakmortonxd/4rch-linux
- You_Are_An_Idiot_Virus.py — Python script spamming blinking windows as a prank. https://github.com/dvorakmortonxd/You_Are_An_Idiot_Virus
- Batch MSDOS Simulator — School project, OS simulator with browser, games, and photos in Batch. https://github.com/dvorakmortonxd/DvorakMSDOS
### Browsers
- Venturesome — Browser built in Python using PyQtWebEngine with PyQt5. Superseded by RustyWolf. https://github.com/dvorakmortonxd/Venturesome
- RustyWolf — Lightweight browser built in Rust with WebKitGTK. Successor to Venturesome. https://github.com/dvorakmortonxd/RustyWolf
### Window Manager
- dxdwm — Minimal X11 window manager written in Rust. https://github.com/dvorakmortonxd/DvorakMSDOS
### Minecraft
- MMO Minecraft Plugin — Basic MMO plugin with custom bosses and items done manually. https://www.youtube.com/watch?v=cSAX5Ds61ac
- Various Minecraft servers — Creative Games, Softcraft, Frostville, EuSMP, EurthSMP, SoftSMP, etc. https://discord.gg/KtHRm9kRmy
### Other
- PYGETEX — Discord bots collection. (Including a self-bot that auto-advertised a minecraft server). https://github.com/dvorakmortonxd/PYGETEX
- Ollama Server — Local AI server VM running on Proxmox with RTX 3070 GPU passthrough. https://ai.dvorakmortonxd.dev/
- Mandelbrot Set in Pygame — Python script rendering the Mandelbrot set. https://github.com/dvorakmortonxd/mandelbrot
- Proxmox Setup — Proxmox setup with over 8 VMs running all local services. https://proxmox.dvorakmortonxd.dev/
## Friends
- Josef Skopec: https://skopec.dev/
- Filip Bukovina: https://bukovinafilip.com/
- Tomáš Vlk: https://vlcak.me
## Content Policy
- Personal website, not a commercial entity.
- Content may be referenced with attribution.
- Self-hosted services are personal and not intended for public use unless stated.
- The Proxmox server is available for VPS/hosting on request (contact via Instagram).

BIN
public/macbook-air-11.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

BIN
public/macbook-air.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.8 KiB

BIN
public/macbook2010.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

BIN
public/minecrafttest2.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 682 KiB

BIN
public/proxmox-server.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
public/proxmox.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

295
public/quip.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 292 KiB

BIN
public/quipee.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

17
public/reddit.svg Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 -4 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Reddit-color</title>
<desc>Created with Sketch.</desc>
<defs>
</defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Color-" transform="translate(-800.000000, -566.000000)" fill="#FF5700">
<path d="M831.14,592.325803 C829.346,592.325803 827.8385,590.884067 827.8385,589.106421 C827.8385,587.328775 829.346,585.839477 831.14,585.839477 C832.934,585.839477 834.389,587.328775 834.389,589.106421 C834.389,590.884067 832.934,592.325803 831.14,592.325803 M831.902,598.574316 C830.231,600.228597 827.654,601.032699 824.024,601.032699 C824.0165,601.032699 824.0075,601.031213 823.9985,601.031213 C823.991,601.031213 823.982,601.032699 823.973,601.032699 C820.343,601.032699 817.7675,600.228597 816.098,598.574316 C815.585,598.065993 815.585,597.244055 816.098,596.737218 C816.6095,596.23038 817.439,596.23038 817.952,596.737218 C819.104,597.878716 821.0735,598.434602 823.973,598.434602 C823.982,598.434602 823.991,598.436088 823.9985,598.436088 C824.0075,598.436088 824.0165,598.434602 824.024,598.434602 C826.9235,598.434602 828.8945,597.878716 830.048,596.737218 C830.561,596.228894 831.3905,596.23038 831.902,596.737218 C832.4135,597.245541 832.4135,598.067479 831.902,598.574316 M813.611,589.106421 C813.611,587.330262 815.1155,585.839477 816.908,585.839477 C818.702,585.839477 820.157,587.330262 820.157,589.106421 C820.157,590.884067 818.702,592.325803 816.908,592.325803 C815.1155,592.325803 813.611,590.884067 813.611,589.106421 M839.996,568.598098 C841.211,568.598098 842.1995,569.577586 842.1995,570.780024 C842.1995,571.983948 841.211,572.963436 839.996,572.963436 C838.781,572.963436 837.7925,571.983948 837.7925,570.780024 C837.7925,569.577586 838.781,568.598098 839.996,568.598098 M848,585.570452 C848,582.417955 845.4125,579.854043 842.231,579.854043 C840.854,579.854043 839.5895,580.335612 838.5965,581.136742 C835.079,578.945898 830.615,577.62604 825.83,577.346611 L828.326,569.527051 L835.1855,571.127824 C835.3655,573.602556 837.4535,575.561534 839.996,575.561534 C842.6555,575.561534 844.82,573.416766 844.82,570.780024 C844.82,568.144768 842.6555,566 839.996,566 C838.136,566 836.519,567.049346 835.7135,568.581748 L827.7425,566.722354 C827.075,566.56629 826.4,566.94679 826.193,567.594828 L823.094,577.300535 C817.9385,577.425386 813.092,578.749703 809.3165,581.068371 C808.337,580.308859 807.1055,579.854043 805.769,579.854043 C802.5875,579.854043 800,582.417955 800,585.570452 C800,587.519025 800.99,589.241677 802.4975,590.273187 C802.4345,590.726516 802.4015,591.182818 802.4015,591.645065 C802.4015,595.585315 804.713,599.250595 808.91,601.964625 C812.933,604.567182 818.258,606 823.9025,606 C829.547,606 834.872,604.567182 838.895,601.964625 C843.092,599.250595 845.4035,595.585315 845.4035,591.645065 C845.4035,591.224435 845.375,590.806778 845.3225,590.392093 C846.9305,589.376932 848,587.594828 848,585.570452" id="Reddit">
</path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

57
public/robots.txt Normal file
View file

@ -0,0 +1,57 @@
# robots.txt for dvorakmortonxd.dev
# https://dvorakmortonxd.dev
# General crawlers — allow main site, block self-hosted services
User-agent: *
Allow: /
Allow: /llms.txt
Allow: /llms-full.txt
Disallow: /api/
Disallow: /_next/
Disallow: /admin/
Disallow: /darecek/
# AI training crawlers
User-agent: GPTBot
Allow: /
User-agent: anthropic-ai
Allow: /
User-agent: Claude-Web
Allow: /
# Meta bots — not welcome
User-agent: FacebookBot
Disallow: /
User-agent: meta-externalagent
Disallow: /
User-agent: meta-externalfetcher
Disallow: /
# Search engine crawlers — welcome
User-agent: Googlebot
Allow: /
User-agent: Bingbot
Allow: /
User-agent: DuckDuckBot
Allow: /
User-agent: Slurp
Allow: /
User-agent: Baiduspider
Allow: /
# Sitemap and Llms
Sitemap: https://dvorakmortonxd.dev/sitemap.xml
LLMs: https://dvorakmortonxd.dev/llms.txt
# ===========================================
# 🎮 Have a great day, crawler!
# Check out my projects at dvorakmortonxd.dev
# ===========================================

70
public/sitemap.xml Normal file
View file

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<!-- Main page -->
<url>
<loc>https://dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>monthly</changefreq>
<priority>1.0</priority>
</url>
<!-- LLM / AI files -->
<url>
<loc>https://dvorakmortonxd.dev/llms.txt</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>monthly</changefreq>
<priority>0.5</priority>
</url>
<!-- Self-hosted services -->
<url>
<loc>https://proxmox.dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>yearly</changefreq>
<priority>0.4</priority>
</url>
<url>
<loc>https://ai.dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>yearly</changefreq>
<priority>0.4</priority>
</url>
<url>
<loc>https://jelly.dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>yearly</changefreq>
<priority>0.4</priority>
</url>
<url>
<loc>https://fake-pterodactyl.dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
<url>
<loc>https://navidrome.dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>yearly</changefreq>
<priority>0.4</priority>
</url>
<url>
<loc>https://mailcow.dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
<url>
<loc>https://search.dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
<url>
<loc>https://convert.dvorakmortonxd.dev/</loc>
<lastmod>2026-04-14</lastmod>
<changefreq>yearly</changefreq>
<priority>0.3</priority>
</url>
</urlset>

727
public/skopec-fr.html Normal file
View file

@ -0,0 +1,727 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Friends' Websites | Josef</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='20' fill='%23111622'/><rect x='18' y='20' width='64' height='44' rx='7' fill='none' stroke='%23f38020' stroke-width='6'/><rect x='24' y='26' width='52' height='32' rx='4' fill='%23111622'/><text x='50' y='50' text-anchor='middle' font-family='Segoe UI,Arial,sans-serif' font-size='24' font-weight='700' fill='%23f38020'>J</text><rect x='42' y='68' width='16' height='6' rx='2' fill='%23d1d5db'/><rect x='34' y='75' width='32' height='6' rx='3' fill='%239ca3af'/></svg>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
height: 100%;
scroll-behavior: smooth;
}
body {
min-height: 100vh;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background:
radial-gradient(circle at top left, rgba(243, 128, 32, 0.22), transparent 35%),
radial-gradient(circle at bottom right, rgba(255, 183, 77, 0.14), transparent 32%),
linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
color: #e8e8e8;
line-height: 1.6;
overflow-x: hidden;
display: flex;
flex-direction: column;
}
a {
color: inherit;
}
.container {
max-width: 1200px;
width: 100%;
margin: 0 auto;
padding: 0 clamp(14px, 2.4vw, 24px);
}
header {
position: sticky;
top: 0;
z-index: 100;
background: rgba(10, 10, 20, 0.45);
border-bottom: 1px solid rgba(243, 128, 32, 0.25);
-webkit-backdrop-filter: blur(14px) saturate(130%);
backdrop-filter: blur(14px) saturate(130%);
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
padding: 1rem 0;
flex-wrap: wrap;
}
.brand {
display: flex;
align-items: center;
gap: 0.8rem;
color: #ffd7a8;
text-decoration: none;
}
.brand-mark {
width: 42px;
height: 42px;
border-radius: 12px;
background: linear-gradient(135deg, #ffefcf 0%, #f38020 55%, #ff6b35 100%);
color: #111;
display: grid;
place-items: center;
font-weight: 800;
box-shadow: 0 10px 24px rgba(243, 128, 32, 0.3);
}
.brand-text {
font-size: 1.05rem;
font-weight: 700;
letter-spacing: 0.02em;
color: #ffd7a8;
background: linear-gradient(120deg, #fff0dd 0%, #ffbf6f 25%, #ff8a00 50%, #ff5e00 75%, #ffd18c 100%);
background-size: 240% 240%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: orangeGradientFlow 6s ease-in-out infinite;
filter: drop-shadow(0 0 8px rgba(255, 122, 0, 0.28));
}
.section-title,
#contact h2 {
color: #ffd7a8;
background: linear-gradient(120deg, #fff0dd 0%, #ffbf6f 25%, #ff8a00 50%, #ff5e00 75%, #ffd18c 100%);
background-size: 240% 240%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: orangeGradientFlow 6s ease-in-out infinite;
filter: drop-shadow(0 0 8px rgba(255, 122, 0, 0.28));
}
@keyframes orangeGradientFlow {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
@media (prefers-reduced-motion: reduce) {
.brand-text,
.section-title,
#contact h2 {
animation: none;
}
}
nav {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
gap: 1.2rem;
}
nav a {
display: inline-flex;
align-items: center;
text-decoration: none;
color: #e0e0e0;
border: 1px solid rgba(243, 128, 32, 0.28);
background: rgba(243, 128, 32, 0.08);
padding: 0.38rem 0.82rem;
border-radius: 999px;
transition: color 0.25s ease, border-color 0.25s ease, background 0.25s ease;
}
nav a:hover {
color: #f38020;
border-color: rgba(243, 128, 32, 0.52);
background: rgba(243, 128, 32, 0.14);
}
.hero {
padding: clamp(2rem, 4vw, 4rem) 0 1.25rem;
}
.hero-grid {
display: grid;
grid-template-columns: 1.2fr 0.8fr;
gap: clamp(1rem, 2.2vw, 2.2rem);
align-items: stretch;
}
.eyebrow {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.45rem 0.8rem;
border-radius: 999px;
background: rgba(243, 128, 32, 0.12);
border: 1px solid rgba(243, 128, 32, 0.35);
color: #ffd7a8;
font-size: 0.92rem;
margin-bottom: 1rem;
}
h1 {
font-size: clamp(2rem, 5vw, 4rem);
line-height: 1.02;
margin-bottom: 0.85rem;
color: #fff;
}
.hero-copy {
background: rgba(255, 255, 255, 0.04);
border-left: 3px solid #f38020;
border-top: 1px solid rgba(243, 128, 32, 0.2);
border-right: 1px solid rgba(243, 128, 32, 0.2);
border-bottom: 1px solid rgba(243, 128, 32, 0.2);
border-radius: 24px;
padding: clamp(1rem, 2.3vw, 2rem);
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.22);
}
.hero-copy p {
font-size: 1.05rem;
color: #c7c7c7;
max-width: 52ch;
}
.hero-meta {
display: flex;
gap: 0.6rem;
flex-wrap: wrap;
margin-top: 1rem;
}
.hero-meta span {
background: rgba(243, 128, 32, 0.12);
border: 1px solid rgba(243, 128, 32, 0.3);
color: #ffdbb0;
border-radius: 999px;
padding: 0.32rem 0.65rem;
font-size: 0.84rem;
font-weight: 700;
}
.hero-note {
margin-top: 1.2rem;
color: #ffce9b;
}
.hero-panel {
background: rgba(255, 255, 255, 0.05);
border: 1px solid rgba(243, 128, 32, 0.25);
border-radius: 24px;
padding: clamp(1rem, 2vw, 1.4rem);
box-shadow: 0 20px 44px rgba(0, 0, 0, 0.25);
display: flex;
}
.preview-rack {
display: grid;
grid-template-rows: repeat(2, minmax(0, 1fr));
gap: 0.85rem;
width: 100%;
}
.preview-pill {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
gap: 0.2rem;
background: linear-gradient(135deg, rgba(46, 58, 88, 0.88), rgba(34, 46, 73, 0.84));
border-left: 3px solid #f38020;
border-top: 1px solid rgba(243, 128, 32, 0.2);
border-right: 1px solid rgba(243, 128, 32, 0.2);
border-bottom: 1px solid rgba(243, 128, 32, 0.2);
border-radius: 18px;
padding: 0.9rem 1rem;
width: 100%;
min-height: 0;
box-shadow: inset 0 0 0 1px rgba(255, 214, 165, 0.12);
transition: border-color 0.2s ease, transform 0.2s ease;
}
.preview-pill:hover {
border-color: rgba(243, 128, 32, 0.4);
transform: translateY(-1px);
}
.preview-pill strong {
color: #fff;
font-size: 1rem;
line-height: 1.2;
}
.preview-pill span {
color: #e7e7e7;
font-size: 0.92rem;
line-height: 1.2;
}
main {
flex: 1;
padding: 1rem 0 4rem;
}
.section-title {
font-size: 2rem;
margin-bottom: 1rem;
text-align: center;
}
.section-lead {
text-align: center;
color: #bdbdbd;
max-width: 70ch;
margin: 0 auto 2.2rem;
}
.sites-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
gap: clamp(1rem, 2vw, 1.8rem);
}
.site-card {
background: rgba(255, 255, 255, 0.05);
border-top: 1px solid rgba(243, 128, 32, 0.2);
border-right: 1px solid rgba(243, 128, 32, 0.2);
border-bottom: 1px solid rgba(243, 128, 32, 0.2);
border-radius: 16px;
overflow: hidden;
box-shadow: 0 18px 40px rgba(0, 0, 0, 0.22);
transition: transform 0.3s ease, box-shadow 0.3s ease, border-color 0.3s ease;
display: flex;
flex-direction: column;
}
.site-card:hover {
transform: translateY(-6px);
box-shadow: 0 24px 56px rgba(243, 128, 32, 0.18);
border-color: rgba(243, 128, 32, 0.5);
}
.site-preview {
aspect-ratio: 16 / 9;
background: #111622;
position: relative;
overflow: hidden;
border-bottom: 1px solid rgba(243, 128, 32, 0.15);
}
.browser-preview {
aspect-ratio: 16 / 11;
background: #0f0f0f;
}
.browser-toolbar {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 0.9rem;
background: rgba(34, 34, 34, 0.96);
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
}
.browser-dots {
display: flex;
gap: 0.35rem;
flex-shrink: 0;
}
.browser-dots span {
width: 10px;
height: 10px;
border-radius: 50%;
background: #4b4b4b;
}
.browser-url {
flex: 1;
min-width: 0;
padding: 0.48rem 0.7rem;
border-radius: 10px;
background: #1b1b1b;
border: 1px solid rgba(243, 128, 32, 0.24);
color: #f1f1f1;
font-size: 0.82rem;
letter-spacing: 0.03em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.browser-view {
position: relative;
height: calc(100% - 3rem);
overflow: hidden;
background: #0f0f0f;
display: flex;
align-items: center;
justify-content: center;
padding: 0.35rem;
}
.site-preview img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.site-preview iframe {
width: 100%;
height: 100%;
border: 0;
display: block;
background: #0f0f0f;
}
.browser-view img {
width: 100%;
height: 100%;
object-fit: contain;
object-position: top center;
}
.site-overlay {
position: absolute;
left: 0;
right: 0;
bottom: 0;
padding: 1rem;
background: linear-gradient(180deg, transparent, rgba(0, 0, 0, 0.88));
display: flex;
justify-content: space-between;
align-items: end;
gap: 1rem;
}
.site-overlay span {
display: inline-flex;
align-items: center;
gap: 0.45rem;
padding: 0.35rem 0.7rem;
border-radius: 999px;
background: rgba(243, 128, 32, 0.9);
color: #111;
font-size: 0.82rem;
font-weight: 800;
}
.site-content {
padding: 1.2rem 1.2rem 1.35rem;
display: flex;
flex-direction: column;
gap: 0.75rem;
border-left: 3px solid #f38020;
border-top: 1px solid rgba(243, 128, 32, 0.2);
}
.site-content h2 {
font-size: 1.45rem;
color: #f38020;
}
.site-content p {
color: #c8c8c8;
margin-bottom: 1rem;
}
.site-actions {
display: flex;
gap: 0.75rem;
flex-wrap: wrap;
}
.primary-btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
padding: 0.82rem 1rem;
border-radius: 999px;
text-decoration: none;
font-weight: 700;
transition: transform 0.25s ease, filter 0.25s ease, background 0.25s ease;
}
.primary-btn {
color: #e0e0e0;
border: 1px solid rgba(243, 128, 32, 0.45);
background: rgba(243, 128, 32, 0.14);
flex: 1 1 170px;
}
.primary-btn:hover {
transform: translateY(-2px);
color: #ffffff;
background: rgba(243, 128, 32, 0.26);
border-color: rgba(243, 128, 32, 0.65);
filter: brightness(1.05);
}
#contact {
padding: 3rem 0;
border-bottom: 1px solid rgba(243, 128, 32, 0.2);
}
#contact h2 {
font-size: 2.5rem;
margin-bottom: 2rem;
text-align: center;
}
.social-links {
display: flex;
justify-content: center;
gap: 2rem;
flex-wrap: wrap;
padding: 2rem 0;
}
.social-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
background: rgba(243, 128, 32, 0.12);
border: 1px solid rgba(243, 128, 32, 0.55);
border-radius: 50%;
color: #f38020;
text-decoration: none;
font-size: 1.5rem;
transition: all 0.3s;
}
.social-btn:hover {
background: #f38020;
color: white;
transform: scale(1.1);
}
footer {
padding: 1.5rem 0 2rem;
text-align: center;
color: #a9a9a9;
border-top: 1px solid rgba(243, 128, 32, 0.16);
background: rgba(0, 0, 0, 0.28);
}
@media (max-width: 900px) {
.hero-grid {
grid-template-columns: 1fr;
}
.header-content {
justify-content: center;
}
nav {
width: 100%;
justify-content: center;
}
}
@media (max-width: 640px) {
.container {
padding: 0 14px;
}
nav {
width: 100%;
justify-content: center;
gap: 0.6rem;
overflow-x: auto;
white-space: nowrap;
padding-bottom: 0.25rem;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
nav::-webkit-scrollbar {
display: none;
}
nav a {
font-size: 0.9rem;
border: 1px solid rgba(243, 128, 32, 0.55);
padding: 0.35rem 0.75rem;
background: rgba(243, 128, 32, 0.1);
}
.hero {
padding-top: 2.6rem;
}
.sites-grid {
grid-template-columns: 1fr;
}
.site-preview {
aspect-ratio: 16 / 10;
}
.site-content {
padding: 1rem;
}
.section-title {
font-size: 1.7rem;
}
#contact h2 {
font-size: 1.8rem;
margin-bottom: 1.2rem;
}
.social-links {
gap: 0.75rem;
padding: 1rem 0;
}
.social-btn {
width: 46px;
height: 46px;
font-size: 1.2rem;
}
}
</style>
</head>
<body>
<header>
<div class="container">
<div class="header-content">
<a class="brand" href="index.html">
<div class="brand-mark">J</div>
<div class="brand-text">Josef</div>
</a>
<nav>
<a href="skopec.html">About</a>
<a href="skopec.html">Projects</a>
<a href="skopec.html">Hardware</a>
<a href="skopec-fr.html">Friends' Websites</a>
<a href="skopec.html">Contact</a>
</nav>
</div>
</div>
</header>
<section class="hero">
<div class="container">
<div class="hero-grid">
<div class="hero-copy">
<div class="eyebrow"><i class="fas fa-globe"></i> Friends' Websites</div>
<h1>Friends' Websites</h1>
<p>Clean live previews of sites I want to keep nearby, with quick one-click access to each full page.</p>
<div class="hero-meta">
<span>2 sites</span>
<span>Live preview</span>
<span>Fast access</span>
</div>
</div>
<div class="hero-panel">
<div class="preview-rack">
<div class="preview-pill">
<strong>Martin Dvořák</strong>
<span>dvorakmortonxd.dev</span>
</div>
<div class="preview-pill">
<strong>Filip Bukovina</strong>
<span>bukovinafilip.com</span>
</div>
</div>
</div>
</div>
</div>
</section>
<main>
<div class="container">
<h2 class="section-title">Web previews</h2>
<p class="section-lead">The previews below help you quickly see what each site looks like without leaving this page.</p>
<div class="sites-grid">
<article class="site-card">
<div class="site-preview">
<iframe src="https://dvorakmortonxd.dev" title="Live preview of dvorakmortonxd.dev" loading="lazy" referrerpolicy="no-referrer"></iframe>
<div class="site-overlay">
<span><i class="fas fa-camera"></i> Preview</span>
<span>Martin Dvořák</span>
</div>
</div>
<div class="site-content">
<h2>Martin Dvořák</h2>
<div class="site-actions">
<a class="primary-btn" href="https://dvorakmortonxd.dev" target="_blank" rel="noopener noreferrer">
Open website <i class="fas fa-arrow-up-right-from-square"></i>
</a>
</div>
</div>
</article>
<article class="site-card">
<div class="site-preview">
<iframe src="https://bukovinafilip.com" title="Live preview of bukovinafilip.com" loading="lazy" referrerpolicy="no-referrer"></iframe>
<div class="site-overlay">
<span><i class="fas fa-camera"></i> Preview</span>
<span>Filip Bukovina</span>
</div>
</div>
<div class="site-content">
<h2>Filip Bukovina</h2>
<div class="site-actions">
<a class="primary-btn" href="https://bukovinafilip.com" target="_blank" rel="noopener noreferrer">
Open website <i class="fas fa-arrow-up-right-from-square"></i>
</a>
</div>
</div>
</article>
</div>
<!-- Contact Section -->
<section id="contact">
<h2>Connect With Me</h2>
<p style="text-align: center; margin-bottom: 2rem; color: #aaa;">Follow me on social media or get in touch</p>
<div class="social-links">
<a href="https://github.com/pepaskopec-blip" class="social-btn" title="GitHub" target="_blank" rel="noopener noreferrer"><i class="fab fa-github"></i></a>
<a href="https://www.linkedin.com/in/josef-skopec-69380234b/" class="social-btn" title="LinkedIn" target="_blank" rel="noopener noreferrer"><i class="fab fa-linkedin"></i></a>
<a href="https://x.com/ishoot4fun11" class="social-btn" title="X" target="_blank" rel="noopener noreferrer"><i class="fa-brands fa-x-twitter"></i></a>
<a href="https://www.instagram.com/skopcaak1/" class="social-btn" title="Instagram" target="_blank" rel="noopener noreferrer"><i class="fab fa-instagram"></i></a>
<a href="https://www.tiktok.com/@skopcaak_1" class="social-btn" title="TikTok" target="_blank" rel="noopener noreferrer"><i class="fab fa-tiktok"></i></a>
<a href="https://www.snapchat.com/add/skopcaak?share_id=xwTiIsZlpos&locale=en-US" class="social-btn" title="Snapchat" target="_blank" rel="noopener noreferrer"><i class="fab fa-snapchat"></i></a>
<a href="https://www.threads.com/@skopcaak1" class="social-btn" title="Threads" target="_blank" rel="noopener noreferrer">@</a>
<a href="https://quipee.me/u/skopcaak_1" class="social-btn" title="Quip" target="_blank" rel="noopener noreferrer">Q</a>
<a href="https://itch.io/profile/skopcaak" class="social-btn" title="itch.io" target="_blank" rel="noopener noreferrer"><i class="fab fa-itch-io"></i></a>
<a href="https://discord.com/app" class="social-btn" title="Discord: ishootn4fun" aria-label="Discord: ishootn4fun" target="_blank" rel="noopener noreferrer"><i class="fab fa-discord"></i></a>
<a href="/cdn-cgi/l/email-protection#cfa5a0bcaaa98fbca4a0bfaaace1abaab9" class="social-btn" title="Email"><i class="fas fa-envelope"></i></a>
</div>
</section>
</div>
</main>
<footer>
<p>&copy; 2026 Josef Skopec.</p>
</footer>
<script data-cfasync="false" src="/cdn-cgi/scripts/5c5dd728/cloudflare-static/email-decode.min.js"></script><script>(function(){function c(){var b=a.contentDocument||a.contentWindow.document;if(b){var d=b.createElement('script');d.innerHTML="window.__CF$cv$params={r:'9e902874fc45f988',t:'MTc3NTYzOTYyNw=='};var a=document.createElement('script');a.src='/cdn-cgi/challenge-platform/scripts/jsd/main.js';document.getElementsByTagName('head')[0].appendChild(a);";b.getElementsByTagName('head')[0].appendChild(d)}}if(document.body){var a=document.createElement('iframe');a.height=1;a.width=1;a.style.position='absolute';a.style.top=0;a.style.left=0;a.style.border='none';a.style.visibility='hidden';document.body.appendChild(a);if('loading'!==document.readyState)c();else if(window.addEventListener)document.addEventListener('DOMContentLoaded',c);else{var e=document.onreadystatechange||function(){};document.onreadystatechange=function(b){e(b);'loading'!==document.readyState&&(document.onreadystatechange=e,c())}}}})();</script></body>
</html>

830
public/skopec.html Normal file
View file

@ -0,0 +1,830 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Josef - IT STUDENT & DEVELOPER</title>
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><rect width='100' height='100' rx='20' fill='%23111622'/><rect x='18' y='20' width='64' height='44' rx='7' fill='none' stroke='%23f38020' stroke-width='6'/><rect x='24' y='26' width='52' height='32' rx='4' fill='%23111622'/><text x='50' y='50' text-anchor='middle' font-family='Segoe UI,Arial,sans-serif' font-size='24' font-weight='700' fill='%23f38020'>J</text><rect x='42' y='68' width='16' height='6' rx='2' fill='%23d1d5db'/><rect x='34' y='75' width='32' height='6' rx='3' fill='%239ca3af'/></svg>">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background:
radial-gradient(circle at top left, rgba(243, 128, 32, 0.22), transparent 35%),
radial-gradient(circle at bottom right, rgba(255, 183, 77, 0.14), transparent 32%),
linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
color: #e0e0e0;
line-height: 1.6;
overflow-x: hidden;
}
header {
background: rgba(10, 10, 20, 0.38);
padding: 2rem 0;
border-bottom: 1px solid rgba(243, 128, 32, 0.25);
position: sticky;
top: 0;
z-index: 100;
-webkit-backdrop-filter: blur(14px) saturate(130%);
backdrop-filter: blur(14px) saturate(130%);
transition: padding 0.25s ease, background 0.25s ease, backdrop-filter 0.25s ease;
}
header.scrolled {
padding: 0.8rem 0;
background: rgba(10, 10, 20, 0.55);
-webkit-backdrop-filter: blur(18px) saturate(130%);
backdrop-filter: blur(18px) saturate(130%);
}
.container {
max-width: 1200px;
width: 100%;
margin: 0 auto;
padding: 0 clamp(14px, 2.4vw, 24px);
}
.header-content {
display: flex;
justify-content: space-between;
align-items: center;
gap: 1rem;
flex-wrap: wrap;
}
.brand {
display: inline-flex;
align-items: center;
gap: 0.75rem;
white-space: nowrap;
overflow: hidden;
max-width: 220px;
transition: opacity 0.25s ease, transform 0.25s ease, max-width 0.25s ease;
}
.brand-mark {
width: 38px;
height: 38px;
border-radius: 11px;
background: linear-gradient(135deg, #ffefcf 0%, #f38020 55%, #ff6b35 100%);
color: #111;
display: grid;
place-items: center;
font-weight: 800;
box-shadow: 0 8px 20px rgba(243, 128, 32, 0.3);
flex-shrink: 0;
}
.brand-text,
section h2,
.hardware-group-title,
.project-content h3 {
color: #ffd7a8;
background: linear-gradient(120deg, #fff0dd 0%, #ffbf6f 25%, #ff8a00 50%, #ff5e00 75%, #ffd18c 100%);
background-size: 240% 240%;
-webkit-background-clip: text;
background-clip: text;
-webkit-text-fill-color: transparent;
animation: orangeGradientFlow 6s ease-in-out infinite;
filter: drop-shadow(0 0 8px rgba(255, 122, 0, 0.28));
}
@keyframes orangeGradientFlow {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
@media (prefers-reduced-motion: reduce) {
.brand-text,
section h2,
.hardware-group-title,
.project-content h3 {
animation: none;
}
}
.brand-text {
font-size: 1.45rem;
font-weight: 700;
letter-spacing: 0.01em;
}
header.scrolled .brand-text {
font-size: 1.2rem;
}
header.hide-logo .brand {
opacity: 0;
transform: translateY(-6px);
max-width: 0;
pointer-events: none;
}
nav {
display: flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
gap: 1.2rem;
}
nav a {
color: #e0e0e0;
text-decoration: none;
margin-left: 0;
transition: color 0.3s, font-size 0.25s ease, border-color 0.25s ease, background 0.25s ease;
border: 1px solid rgba(243, 128, 32, 0.28);
border-radius: 999px;
background: rgba(243, 128, 32, 0.08);
padding: 0.38rem 0.82rem;
}
header.scrolled nav a {
font-size: 0.92rem;
}
nav a:hover {
color: #f38020;
border-color: rgba(243, 128, 32, 0.52);
background: rgba(243, 128, 32, 0.14);
}
.hero {
padding: 4rem 0;
text-align: center;
}
.hero-badges {
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 0.4rem;
}
.hero h1 {
font-size: 3.5rem;
margin-bottom: 1rem;
color: #ffffff;
}
.hero p {
font-size: 1.2rem;
color: #c9c9c9;
margin-bottom: 2rem;
}
.badge {
display: inline-block;
background: rgba(243, 128, 32, 0.16);
color: #ffd7a8;
border: 1px solid rgba(243, 128, 32, 0.36);
padding: 0.5rem 1rem;
border-radius: 20px;
margin: 0.5rem;
font-size: 0.9rem;
font-weight: bold;
}
section {
padding: 3rem 0;
border-bottom: 1px solid rgba(243, 128, 32, 0.2);
}
section h2 {
font-size: 2.5rem;
margin-bottom: 2rem;
text-align: center;
}
.about-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3rem;
align-items: center;
}
.about-text h3 {
font-size: 1.5rem;
margin-bottom: 1rem;
color: #ffffff;
}
.about-text p {
margin-bottom: 1rem;
color: #ccc;
}
.interests {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 1rem;
margin-top: 1.5rem;
}
.interest-item {
background: rgba(255, 255, 255, 0.05);
padding: 1rem;
border-left: 3px solid #f38020;
border-radius: 12px;
border-top: 1px solid rgba(243, 128, 32, 0.2);
border-right: 1px solid rgba(243, 128, 32, 0.2);
border-bottom: 1px solid rgba(243, 128, 32, 0.2);
}
.interest-item strong {
color: #f38020;
font-weight: 700;
}
.hardware-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 1rem;
}
.hardware-group-title {
margin: 1.5rem 0 0.9rem;
font-size: 1.2rem;
letter-spacing: 0.02em;
}
.hardware-item {
background: rgba(255, 255, 255, 0.05);
padding: 1rem;
border-left: 3px solid #f38020;
border-radius: 12px;
border-top: 1px solid rgba(243, 128, 32, 0.2);
border-right: 1px solid rgba(243, 128, 32, 0.2);
border-bottom: 1px solid rgba(243, 128, 32, 0.2);
}
.hardware-item h3 {
color: #f38020;
font-size: 1rem;
margin-bottom: 0.35rem;
}
.hardware-item p {
color: #d8d8d8;
font-size: 0.95rem;
}
.hardware-item-featured {
grid-column: 1 / -1;
border-left-width: 5px;
background: rgba(243, 128, 32, 0.18);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.2);
}
.hardware-item-featured h3 {
font-size: 0.9rem;
text-transform: uppercase;
letter-spacing: 0.08em;
color: #ffd5b3;
}
.hardware-item-featured p {
font-size: 1.15rem;
font-weight: 700;
color: #ffffff;
margin-top: 0.2rem;
}
.projects-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
gap: 2rem;
}
.project-card {
background: rgba(255, 255, 255, 0.05);
border-radius: 16px;
overflow: hidden;
transition: transform 0.3s, box-shadow 0.3s;
border: 1px solid rgba(243, 128, 32, 0.3);
}
.project-card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 30px rgba(243, 128, 32, 0.2);
}
.project-image {
width: 100%;
height: 200px;
background: linear-gradient(135deg, #f38020, #ff6b35);
display: flex;
align-items: center;
justify-content: center;
font-size: 3rem;
}
.project-content {
padding: 1.5rem;
}
.project-content h3 {
margin-bottom: 0.5rem;
}
.project-content p {
color: #aaa;
font-size: 0.9rem;
margin-bottom: 1rem;
}
.project-tags {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
.tag {
background: rgba(243, 128, 32, 0.2);
color: #f38020;
padding: 0.3rem 0.7rem;
border-radius: 15px;
font-size: 0.8rem;
}
.social-links {
display: flex;
justify-content: center;
gap: 2rem;
flex-wrap: wrap;
padding: 2rem 0;
}
.social-btn {
display: inline-flex;
align-items: center;
justify-content: center;
width: 50px;
height: 50px;
background: rgba(243, 128, 32, 0.12);
border: 1px solid rgba(243, 128, 32, 0.55);
border-radius: 50%;
color: #f38020;
text-decoration: none;
font-size: 1.5rem;
transition: all 0.3s;
}
.social-btn:hover {
background: #f38020;
color: white;
transform: scale(1.1);
}
footer {
background: rgba(0, 0, 0, 0.35);
text-align: center;
padding: 2rem;
color: #aaa;
border-top: 1px solid rgba(243, 128, 32, 0.2);
}
#projects {
display: block;
}
@media (max-width: 1024px) {
.container {
padding: 0 16px;
}
.hero h1 {
font-size: 2.6rem;
}
section {
padding: 2.4rem 0;
}
.projects-grid {
grid-template-columns: 1fr;
gap: 1.3rem;
}
.social-links {
gap: 1rem;
}
}
@media (max-width: 768px) {
header {
padding: 1rem 0;
}
.header-content {
justify-content: center;
}
.about-grid {
grid-template-columns: 1fr;
gap: 1.6rem;
}
.hero h1 {
font-size: 2.1rem;
}
.hero {
padding: 2.4rem 0 2rem;
}
.hero p {
font-size: 1rem;
margin-bottom: 1.2rem;
}
nav {
width: 100%;
justify-content: center;
gap: 0.6rem;
overflow-x: auto;
white-space: nowrap;
padding-bottom: 0.25rem;
-webkit-overflow-scrolling: touch;
scrollbar-width: none;
}
nav::-webkit-scrollbar {
display: none;
}
nav a {
font-size: 0.9rem;
border: 1px solid rgba(243, 128, 32, 0.55);
border-radius: 999px;
padding: 0.35rem 0.75rem;
background: rgba(243, 128, 32, 0.1);
}
.interests {
grid-template-columns: 1fr;
}
.hardware-grid {
grid-template-columns: 1fr;
}
.project-image {
height: 160px;
}
.project-content {
padding: 1.1rem;
}
.social-links {
gap: 0.75rem;
padding: 1rem 0;
}
.social-btn {
width: 46px;
height: 46px;
font-size: 1.2rem;
}
.badge {
margin: 0.3rem;
padding: 0.4rem 0.75rem;
font-size: 0.82rem;
}
section h2 {
font-size: 1.8rem;
margin-bottom: 1.2rem;
}
}
@media (max-width: 480px) {
.container {
padding: 0 12px;
}
.hero h1 {
font-size: 1.8rem;
line-height: 1.2;
}
.hero p {
font-size: 0.95rem;
}
.hardware-item-featured p {
font-size: 1rem;
}
.project-image {
height: 140px;
font-size: 2.4rem;
}
footer {
padding: 1.4rem 1rem;
}
}
</style>
</head>
<body>
<!-- Navigation Header -->
<header>
<div class="container">
<div class="header-content">
<div class="brand" aria-label="Josef brand">
<div class="brand-mark">J</div>
<div class="brand-text">Josef</div>
</div>
<nav>
<a href="javascript:void(0)">About</a>
<a href="javascript:void(0)">Projects</a>
<a href="javascript:void(0)">Hardware</a>
<a href="skopec-fr.html">Friends' Websites</a>
<a href="javascript:void(0)">Contact</a>
</nav>
</div>
</div>
</header>
<div class="container">
<!-- Hero Section -->
<section class="hero">
<h1>Hi, I'm Josef</h1>
<p>Tech Enthusiast | Student | Developer | Linux Lover</p>
<p style="color: #f38020; font-weight: bold; margin: 1rem 0; font-size: 0.95rem;">⚙️ This website is under construction - not final results yet, that's why it maybe looks weird</p>
<div class="hero-badges">
<span class="badge">AI</span>
<span class="badge">Retro Computing</span>
<span class="badge">Simple Tech Projects</span>
<span class="badge">Fitness</span>
</div>
</section>
<!-- About Section -->
<section id="about">
<h2>About Me</h2>
<div class="about-grid">
<div class="about-text">
<h3>Welcome! 👋</h3>
<p>Hey, I'm Josef. I study IT at a Private Secondary School of Information Technology, and most of the time I'm messing around with tech.</p>
<p>I'm really into AI, old PCs, Linux, and building random projects just to see how things work.</p>
</div>
<div>
<div class="interests">
<div class="interest-item">
<strong>🤖 AI</strong>
<p>Exploring artificial intelligence and AI applications</p>
</div>
<div class="interest-item">
<strong>💻 Retro Tech</strong>
<p>Fascinated by vintage computers and their engineering</p>
</div>
<div class="interest-item">
<strong>🐧 Linux</strong>
<p>I use Arch btw 🥹</p>
</div>
<div class="interest-item">
<strong>⚙️ Building</strong>
<p>Creating projects and learning through hands-on development</p>
</div>
<div class="interest-item">
<strong>💪 Fitness</strong>
<p>Regular gym enthusiast balancing tech life with hitting the gym</p>
</div>
<div class="interest-item">
<strong>🔫 Airsoft</strong>
<p>Playing airsoft since 2023</p>
</div>
</div>
</div>
</div>
</section>
<!-- Projects Section -->
<section id="projects">
<h2>My Projects</h2>
<div class="projects-grid">
<div class="project-card">
<div class="project-image">🐍</div>
<div class="project-content">
<h3>Complex Snake (Pygame)</h3>
<p>Advanced Snake game built in Python with Pygame, featuring dynamic difficulty, obstacles, power-ups, score multipliers, and smooth grid-based movement.</p>
<div class="project-tags">
<span class="tag">Python</span>
<span class="tag">Pygame</span>
<span class="tag">Game Dev</span>
<span class="tag">OOP</span>
</div>
</div>
</div>
</div>
</section>
<!-- Hardware Section -->
<section id="hardware">
<h2>Hardware</h2>
<h3 class="hardware-group-title">Main Desktop PC</h3>
<div class="hardware-grid">
<div class="hardware-item hardware-item-featured">
<h3>Build / System</h3>
<p>Custom PC (2022) - Arch Linux with modified Zen kernel</p>
</div>
<div class="hardware-item">
<h3>CPU</h3>
<p>AMD Ryzen 5 5600</p>
</div>
<div class="hardware-item">
<h3>GPU</h3>
<p>AMD Radeon RX 6700</p>
</div>
<div class="hardware-item">
<h3>RAM</h3>
<p>KINGSTON FURY BEAST 16 GB DDR4 3200MHZ (RGB)</p>
</div>
<div class="hardware-item">
<h3>Storage</h3>
<p>1TB M.2 NVMe SSD (WD)</p>
</div>
<div class="hardware-item">
<h3>Motherboard</h3>
<p>ASUS TUF B550-Plus</p>
</div>
<div class="hardware-item">
<h3>PSU</h3>
<p>600W SilentiumPC</p>
</div>
<div class="hardware-item">
<h3>CPU Cooler</h3>
<p>SilentiumPC Fera 5</p>
</div>
<div class="hardware-item">
<h3>Case</h3>
<p>SilentiumPC PC Case</p>
</div>
</div>
<h3 class="hardware-group-title">Laptop</h3>
<div class="hardware-grid">
<div class="hardware-item hardware-item-featured">
<h3>Model / Year</h3>
<p>MacBook Air 11" (Mid 2013) - Arch Linux with LTS kernel and SWAY/KDE plasma desktop</p>
</div>
<div class="hardware-item">
<h3>CPU</h3>
<p>Intel Core i5-4250U (1.3 GHz, Turbo up to 2.6 GHz)</p>
</div>
<div class="hardware-item">
<h3>GPU</h3>
<p>Intel HD Graphics 5000</p>
</div>
<div class="hardware-item">
<h3>RAM</h3>
<p>8 GB LPDDR3 1600 MHz</p>
</div>
<div class="hardware-item">
<h3>Storage</h3>
<p>256 GB PCIe SSD</p>
</div>
<div class="hardware-item">
<h3>Display</h3>
<p>11.6", 1366x768</p>
</div>
<div class="hardware-item">
<h3>Wireless</h3>
<p>Wi-Fi 802.11ac, Bluetooth 4.0</p>
</div>
</div>
<h3 class="hardware-group-title">Phone</h3>
<div class="hardware-grid">
<div class="hardware-item hardware-item-featured">
<h3>Model / System</h3>
<p>Xiaomi Redmi Note 11 Pro 5G - Android (HyperOS) - I am planning to root it</p>
</div>
<div class="hardware-item">
<h3>Display</h3>
<p>6.67" AMOLED, 120 Hz, FHD+ (2400x1080)</p>
</div>
<div class="hardware-item">
<h3>Chipset</h3>
<p>Qualcomm Snapdragon 695 5G (6 nm)</p>
</div>
<div class="hardware-item">
<h3>RAM</h3>
<p>6 GB LPDDR4X</p>
</div>
<div class="hardware-item">
<h3>Storage</h3>
<p>128 GB UFS 2.2 + microSD slot</p>
</div>
<div class="hardware-item">
<h3>Battery</h3>
<p>5000 mAh, 67 W turbo charging</p>
</div>
<div class="hardware-item">
<h3>Main Camera</h3>
<p>108 MP + 8 MP ultrawide + 2 MP macro</p>
</div>
<div class="hardware-item">
<h3>Connectivity</h3>
<p>5G, NFC, Wi-Fi 5, Bluetooth 5.1, USB-C</p>
</div>
</div>
</section>
<!-- Contact Section -->
<section id="contact">
<h2>Connect With Me</h2>
<p style="text-align: center; margin-bottom: 2rem; color: #aaa;">Follow me on social media or get in touch</p>
<div class="social-links">
<a href="https://github.com/pepaskopec-blip" class="social-btn" title="GitHub" target="_blank" rel="noopener noreferrer"><i class="fab fa-github"></i></a>
<a href="https://www.linkedin.com/in/josef-skopec-69380234b/" class="social-btn" title="LinkedIn" target="_blank" rel="noopener noreferrer"><i class="fab fa-linkedin"></i></a>
<a href="https://x.com/ishoot4fun11" class="social-btn" title="X" target="_blank" rel="noopener noreferrer"><i class="fa-brands fa-x-twitter"></i></a>
<a href="https://www.instagram.com/skopcaak1/" class="social-btn" title="Instagram" target="_blank" rel="noopener noreferrer"><i class="fab fa-instagram"></i></a>
<a href="https://www.tiktok.com/@skopcaak_1" class="social-btn" title="TikTok" target="_blank" rel="noopener noreferrer"><i class="fab fa-tiktok"></i></a>
<a href="https://www.snapchat.com/add/skopcaak?share_id=xwTiIsZlpos&locale=en-US" class="social-btn" title="Snapchat" target="_blank" rel="noopener noreferrer"><i class="fab fa-snapchat"></i></a>
<a href="https://www.threads.com/@skopcaak1" class="social-btn" title="Threads" target="_blank" rel="noopener noreferrer">@</a>
<a href="https://quipee.me/u/skopcaak_1" class="social-btn" title="Quip" target="_blank" rel="noopener noreferrer">Q</a>
<a href="https://itch.io/profile/skopcaak" class="social-btn" title="itch.io" target="_blank" rel="noopener noreferrer"><i class="fab fa-itch-io"></i></a>
<a href="https://discord.com/app" class="social-btn" title="Discord: ishootn4fun" aria-label="Discord: ishootn4fun" target="_blank" rel="noopener noreferrer"><i class="fab fa-discord"></i></a>
<a href="/cdn-cgi/l/email-protection#ddb7b2aeb8bb9daeb6b2adb8bef3b9b8ab" class="social-btn" title="Email"><i class="fas fa-envelope"></i></a>
</div>
</section>
</div>
<!-- Footer -->
<footer>
<p>&copy; 2026 Josef Skopec.</p>
</footer>
<script>
const header = document.querySelector('header');
const heroHeading = document.querySelector('.hero h1');
const SCROLL_ADD_THRESHOLD = 64;
const SCROLL_REMOVE_THRESHOLD = 20;
let isHeaderScrolled = window.scrollY > SCROLL_ADD_THRESHOLD;
function updateHeaderOnScroll() {
if (!header) return;
if (!isHeaderScrolled && window.scrollY >= SCROLL_ADD_THRESHOLD) {
isHeaderScrolled = true;
} else if (isHeaderScrolled && window.scrollY <= SCROLL_REMOVE_THRESHOLD) {
isHeaderScrolled = false;
}
header.classList.toggle('scrolled', isHeaderScrolled);
}
function initLogoVisibility() {
if (!header || !heroHeading) return;
if ('IntersectionObserver' in window) {
const observer = new IntersectionObserver((entries) => {
const [entry] = entries;
header.classList.toggle('hide-logo', entry.isIntersecting);
}, { threshold: 0.2 });
observer.observe(heroHeading);
return;
}
const fallback = () => {
const rect = heroHeading.getBoundingClientRect();
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
const isVisible = rect.bottom > 0 && rect.top < viewportHeight;
header.classList.toggle('hide-logo', isVisible);
};
fallback();
window.addEventListener('scroll', fallback, { passive: true });
window.addEventListener('resize', fallback);
}
updateHeaderOnScroll();
initLogoVisibility();
window.addEventListener('scroll', updateHeaderOnScroll, { passive: true });
</script>
</body>
</html>

9125
public/skopec.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 566 KiB

83
public/snapchat.svg Normal file
View file

@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg version="1.1" id="Icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 32 32" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#3A559F;}
.st2{fill:#F4F4F4;}
.st3{fill:#FF0084;}
.st4{fill:#0063DB;}
.st5{fill:#00ACED;}
.st6{fill:#FFEC06;}
.st7{fill:#FF0000;}
.st8{fill:#25D366;}
.st9{fill:#0088FF;}
.st10{fill:#314358;}
.st11{fill:#EE6996;}
.st12{fill:#01AEF3;}
.st13{fill:#FFFEFF;}
.st14{fill:#F06A35;}
.st15{fill:#00ADEF;}
.st16{fill:#1769FF;}
.st17{fill:#1AB7EA;}
.st18{fill:#6001D1;}
.st19{fill:#E41214;}
.st20{fill:#05CE78;}
.st21{fill:#7B519C;}
.st22{fill:#FF4500;}
.st23{fill:#00F076;}
.st24{fill:#FFC900;}
.st25{fill:#00D6FF;}
.st26{fill:#FF3A44;}
.st27{fill:#FF6A36;}
.st28{fill:#0061FE;}
.st29{fill:#F7981C;}
.st30{fill:#EE1B22;}
.st31{fill:#EF3561;}
.st32{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-miterlimit:10;}
.st33{fill:#0097D3;}
.st34{fill:#01308A;}
.st35{fill:#019CDE;}
.st36{fill:#FFD049;}
.st37{fill:#16A05D;}
.st38{fill:#4486F4;}
.st39{fill:none;}
.st40{fill:#34A853;}
.st41{fill:#4285F4;}
.st42{fill:#FBBC05;}
.st43{fill:#EA4335;}
</style>
<path class="st6" d="M23,0H9C4,0,0,4,0,9v14c0,5,4,9,9,9h14c5,0,9-4,9-9V9C32,4,28,0,23,0z"/>
<g>
<path class="st0" d="M16.1,28.5c-0.7,0-1.4-0.1-2.1-0.3c-0.8-0.3-1.6-0.7-2.2-1.1c-0.7-0.4-1.5-0.6-2.4-0.6l-0.1,0
c-0.2,0-0.4,0-0.7-0.1l-0.2,0c-0.7-0.1-1.6-0.4-1.8-1.6c-0.1,0-0.2-0.1-0.3-0.1l-0.5-0.2c-0.4-0.2-0.8-0.3-1.2-0.5
c-1-0.5-1.1-1.3-1.1-1.6c0-0.3,0.1-1.1,1.1-1.7c1.2-0.6,2-1.3,2.6-2c0.5-0.5,0.8-1.1,1-1.7c-0.2-0.1-0.3-0.2-0.4-0.3
c-0.3-0.2-0.5-0.4-0.8-0.5c-0.3-0.2-0.5-0.4-0.8-0.7c-0.7-0.7-0.8-1.6-0.4-2.5c0.4-0.8,1.1-1.3,2-1.3c0.1,0,0.2,0,0.3,0
c0.2,0,0.4,0.1,0.6,0.1c0-0.7,0-1.4,0.1-2.1c0.2-2.5,1.6-4.4,3.9-5.5C14,3.6,14.7,3.5,16,3.5c2.3,0,4.2,0.8,5.7,2.4
c1,1,1.5,2.3,1.7,3.7c0.1,0.7,0.1,1.4,0.1,2.2c0.2,0,0.5-0.1,0.7-0.1c0,0,0,0,0,0c1,0,1.8,0.6,2.1,1.4c0.3,0.9,0.1,1.9-0.6,2.5
c-0.4,0.3-0.7,0.6-1.1,0.9l-0.3,0.2c-0.1,0.1-0.3,0.2-0.4,0.3c0,0-0.1,0-0.1,0.1c0.4,1,1,1.9,2,2.6c0.3,0.2,0.7,0.5,1.1,0.7
c0.2,0.1,0.5,0.3,0.7,0.4c1,0.6,1,1.4,0.9,1.8c-0.1,0.6-0.6,1.2-1.2,1.5c-0.6,0.2-1.2,0.5-1.8,0.7c-0.2,0.9-0.9,1.6-1.9,1.6l-0.1,0
c-0.2,0-0.4,0.1-0.7,0.1l-0.2,0c-1,0-1.9,0.3-2.7,0.9C18.7,28.1,17.4,28.5,16.1,28.5z"/>
<path d="M16,4C16,4,16,4,16,4c2.2,0,3.9,0.8,5.3,2.2c0.9,1,1.4,2.1,1.6,3.5c0.1,0.9,0.1,1.8,0.1,2.8c0.1,0,0.1,0,0.2-0.1
c0.4-0.1,0.7-0.2,1.1-0.2c0,0,0,0,0.1,0c0.7,0,1.3,0.4,1.5,1.1c0.3,0.7,0.1,1.5-0.5,1.9c-0.4,0.3-0.7,0.6-1.1,0.8L24,16.3
c-0.1,0.1-0.2,0.2-0.4,0.3c-0.1,0.1-0.2,0.1-0.3,0.2c0,0-0.1,0.1-0.1,0.1c0,0,0,0.1,0,0.1c0.4,1.2,1.1,2.2,2.2,3
c0.3,0.3,0.7,0.5,1.1,0.7c0.2,0.1,0.5,0.3,0.7,0.4c0.7,0.4,0.8,0.9,0.7,1.3c-0.1,0.5-0.4,0.9-0.9,1.1c-0.7,0.3-1.4,0.6-2.1,0.8
c-0.1,0.9-0.7,1.5-1.5,1.5c-0.1,0-0.1,0-0.2,0c-0.2,0-0.4,0.1-0.6,0.1c0,0,0,0,0,0c0,0-0.1,0-0.1,0c-1.1,0-2.1,0.3-3,0.9
c-1.1,0.7-2.3,1.1-3.5,1.1c-0.6,0-1.3-0.1-2-0.3c-0.8-0.2-1.5-0.7-2.1-1c-0.8-0.5-1.6-0.7-2.6-0.7c0,0-0.1,0-0.1,0
c-0.2,0-0.4,0-0.6,0l-0.2,0c-0.8-0.1-1.3-0.4-1.5-1.5c-0.1,0-0.1,0-0.2-0.1c-0.1,0-0.3-0.1-0.4-0.1L6,24c-0.4-0.1-0.8-0.3-1.1-0.5
C4.1,23.2,4,22.6,4,22.3c0-0.3,0.1-0.8,0.8-1.2c1.2-0.7,2.1-1.3,2.8-2.1c0.6-0.7,1-1.4,1.2-2.1c0,0,0,0,0,0
c-0.3-0.2-0.5-0.4-0.8-0.5c-0.3-0.2-0.5-0.3-0.7-0.5c-0.2-0.2-0.5-0.4-0.7-0.7c-0.5-0.5-0.6-1.3-0.3-1.9c0.3-0.6,0.9-1,1.5-1
c0.1,0,0.2,0,0.2,0c0.4,0.1,0.8,0.2,1.1,0.3c0,0,0,0,0,0c0-0.9,0-1.8,0-2.7c0.2-2.3,1.5-4.1,3.6-5.1C14.1,4.1,14.7,4,16,4
C16,4,16,4,16,4 M16,3L16,3l-0.1,0c-1.3,0-2.1,0.1-3.5,0.8C9.9,5,8.4,7.1,8.2,9.7c0,0.5-0.1,1-0.1,1.5c-0.1,0-0.2,0-0.4,0
c-1,0-1.9,0.6-2.4,1.6c-0.5,1-0.3,2.2,0.5,3.1c0.3,0.3,0.6,0.6,0.9,0.8C7,16.8,7.2,17,7.5,17.2c0,0,0.1,0.1,0.1,0.1
c-0.2,0.4-0.5,0.8-0.8,1.2c-0.6,0.7-1.4,1.3-2.5,1.9C3.1,20.9,3,21.9,3,22.4c0,0.9,0.5,1.6,1.4,2c0.4,0.2,0.9,0.4,1.2,0.5l0.5,0.2
c0,0,0.1,0,0.1,0c0.5,1.4,1.7,1.7,2.2,1.7l0.2,0C8.8,26.9,9,27,9.3,27l0.1,0c0.8,0,1.5,0.2,2.1,0.6c0.6,0.4,1.4,0.9,2.3,1.1
c0.8,0.2,1.5,0.3,2.3,0.3c1.4,0,2.8-0.4,4.1-1.3c0.8-0.5,1.6-0.8,2.5-0.8l0.1,0l0,0l0,0c0.3,0,0.5,0,0.7-0.1c0.1,0,0.1,0,0.1,0
c1.1-0.1,1.9-0.8,2.3-1.7c0.6-0.2,1.1-0.4,1.6-0.6c0.8-0.3,1.4-1.1,1.5-1.9c0.1-0.4,0.1-1.5-1.2-2.3c-0.2-0.2-0.5-0.3-0.7-0.4
c-0.4-0.2-0.7-0.4-1-0.7c-0.8-0.6-1.3-1.3-1.7-2c0.1,0,0.1-0.1,0.2-0.1l0.3-0.2c0.4-0.3,0.8-0.6,1.1-0.9c0.9-0.7,1.2-1.9,0.8-3
c-0.4-1.1-1.4-1.8-2.5-1.8l-0.1,0c-0.1,0-0.1,0-0.2,0c0-0.6-0.1-1.1-0.1-1.7c-0.2-1.5-0.8-2.9-1.8-4C20.5,3.9,18.5,3,16,3L16,3
L16,3z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 4.6 KiB

BIN
public/softcraft.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

17
public/soundcloud.svg Normal file
View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 -10.5 48 48" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Soundcloud-color</title>
<desc>Created with Sketch.</desc>
<defs>
</defs>
<g id="Icons" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Color-" transform="translate(-301.000000, -469.000000)" fill="#FF4300">
<path d="M301,491.152608 C301,491.756664 301.215945,492.213396 301.647743,492.52299 C302.079587,492.832537 302.541182,492.941985 303.032573,492.851428 C303.494168,492.760824 303.81804,492.594702 304.004234,492.353108 C304.190336,492.111513 304.283433,491.711316 304.283433,491.152608 L304.283433,484.583839 C304.283433,484.115689 304.123374,483.719298 303.80321,483.394665 C303.483092,483.069986 303.092212,482.90767 302.630572,482.90767 C302.183852,482.90767 301.800433,483.069986 301.480269,483.394665 C301.160105,483.719298 301,484.115689 301,484.583839 L301,491.152608 L301,491.152608 Z M306.137273,493.961324 C306.137273,494.399303 306.289918,494.727695 306.595161,494.946685 C306.900449,495.165675 307.291329,495.275124 307.767799,495.275124 C308.25919,495.275124 308.657485,495.165629 308.962773,494.946685 C309.268016,494.727742 309.420661,494.399303 309.420661,493.961324 L309.420661,478.649296 C309.420661,478.196277 309.260556,477.807405 308.940437,477.482773 C308.620273,477.15814 308.229394,476.995778 307.767799,476.995778 C307.32108,476.995778 306.937615,477.15814 306.617497,477.482773 C306.297332,477.807452 306.137273,478.196277 306.137273,478.649296 L306.137273,493.961324 L306.137273,493.961324 Z M311.25221,494.686153 C311.25221,495.124087 311.408562,495.452525 311.721266,495.671515 C312.033969,495.890459 312.436017,495.999954 312.927454,495.999954 C313.403924,495.999954 313.794804,495.890459 314.100047,495.671515 C314.405335,495.452525 314.55798,495.124087 314.55798,494.686153 L314.55798,480.71053 C314.55798,480.242426 314.397875,479.842229 314.077756,479.510031 C313.757592,479.177833 313.374173,479.011757 312.927454,479.011757 C312.465813,479.011757 312.071226,479.177833 311.743647,479.510031 C311.416068,479.842229 311.252256,480.242426 311.252256,480.71053 L311.252256,494.686153 L311.25221,494.686153 Z M316.389483,494.754106 C316.389483,495.584671 316.940422,495.999954 318.042345,495.999954 C319.144223,495.999954 319.695161,495.584671 319.695161,494.754106 L319.695161,472.103177 C319.695161,470.834725 319.31545,470.117461 318.556027,469.951339 C318.064635,469.830519 317.580659,469.97399 317.104189,470.381707 C316.627673,470.789423 316.389438,471.363216 316.389438,472.103177 L316.389438,494.754106 L316.389483,494.754106 Z M321.616146,495.410983 L321.616146,470.766772 C321.616146,469.981556 321.846921,469.513452 322.308561,469.362415 C323.306219,469.12082 324.296463,469 325.279245,469 C327.557469,469 329.679432,469.543622 331.644951,470.630867 C333.610517,471.718111 335.200124,473.201747 336.413681,475.081774 C337.627284,476.961848 338.330867,479.034361 338.52443,481.299501 C339.432744,480.906869 340.400606,480.710577 341.42806,480.710577 C343.512766,480.710577 345.295936,481.458057 346.777525,482.953019 C348.25916,484.448026 349,486.244969 349,488.343986 C349,490.458088 348.25916,492.262597 346.777525,493.757558 C345.295936,495.252519 343.520227,496 341.450396,496 L322.018102,495.977349 C321.884041,495.932047 321.783529,495.848963 321.716521,495.728189 C321.649513,495.607415 321.616146,495.501587 321.616146,495.410983 L321.616146,495.410983 L321.616146,495.410983 Z" id="Soundcloud">
</path>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.7 KiB

15
public/squat.svg Normal file
View file

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg fill="#000000" height="800px" width="800px" version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 256 256" xml:space="preserve">
<g>
<circle cx="127" cy="28.4" r="26.6"/>
<path d="M213.4,171.2h-49.8V97.3c0-1.8,1.5-3.3,3.3-3.3c0.6,0,1.2,0.2,1.7,0.5l30.1,17.3l-20.8,36c-3.2,5.6-1.3,12.7,4.3,15.9
c5.6,3.2,12.7,1.3,15.9-4.3l26.6-46c3.2-5.6,1.3-12.7-4.3-15.9l-51.6-29.8c-4.7-3.3-10-5.4-15.5-6L127,61.6h0h0l-26.3,0.1
c-5.5,0.6-10.8,2.7-15.5,6L33.6,97.5c-5.6,3.2-7.5,10.3-4.3,15.9l26.6,46c3.2,5.6,10.3,7.5,15.9,4.3c5.6-3.2,7.5-10.3,4.3-15.9
l-20.8-36l30.1-17.3c0.5-0.3,1.1-0.5,1.7-0.5c1.8,0,3.3,1.5,3.3,3.3v24.1v49.8H40.6c-9.2,0-16.6,7.4-16.6,16.6
c0,4.6,1.8,8.7,4.8,11.7l49.7,49.7c6.5,6.5,17,6.5,23.5,0c6.5-6.5,6.5-17,0-23.5l-21.3-21.3l46.2,0l0-13.3c0,0,0,0,0,0s0,0,0,0
l0,13.3l46.2,0l-21.3,21.3c-6.5,6.5-6.5,17,0,23.5c6.5,6.5,17,6.5,23.5,0l49.7-49.7c3-3,4.8-7.1,4.8-11.7
C230,178.7,222.6,171.2,213.4,171.2z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
public/thinkpadt400s.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

8
public/tiktok.svg Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.45095 19.7926C8.60723 18.4987 9.1379 17.7743 10.1379 17.0317C11.5688 16.0259 13.3561 16.5948 13.3561 16.5948V13.2197C13.7907 13.2085 14.2254 13.2343 14.6551 13.2966V17.6401C14.6551 17.6401 12.8683 17.0712 11.4375 18.0775C10.438 18.8196 9.90623 19.5446 9.7505 20.8385C9.74562 21.5411 9.87747 22.4595 10.4847 23.2536C10.3345 23.1766 10.1815 23.0889 10.0256 22.9905C8.68807 22.0923 8.44444 20.7449 8.45095 19.7926ZM22.0352 6.97898C21.0509 5.90039 20.6786 4.81139 20.5441 4.04639H21.7823C21.7823 4.04639 21.5354 6.05224 23.3347 8.02482L23.3597 8.05134C22.8747 7.7463 22.43 7.38624 22.0352 6.97898ZM28 10.0369V14.293C28 14.293 26.42 14.2312 25.2507 13.9337C23.6179 13.5176 22.5685 12.8795 22.5685 12.8795C22.5685 12.8795 21.8436 12.4245 21.785 12.3928V21.1817C21.785 21.6711 21.651 22.8932 21.2424 23.9125C20.709 25.246 19.8859 26.1212 19.7345 26.3001C19.7345 26.3001 18.7334 27.4832 16.9672 28.28C15.3752 28.9987 13.9774 28.9805 13.5596 28.9987C13.5596 28.9987 11.1434 29.0944 8.96915 27.6814C8.49898 27.3699 8.06011 27.0172 7.6582 26.6277L7.66906 26.6355C9.84383 28.0485 12.2595 27.9528 12.2595 27.9528C12.6779 27.9346 14.0756 27.9528 15.6671 27.2341C17.4317 26.4374 18.4344 25.2543 18.4344 25.2543C18.5842 25.0754 19.4111 24.2001 19.9423 22.8662C20.3498 21.8474 20.4849 20.6247 20.4849 20.1354V11.3475C20.5435 11.3797 21.2679 11.8347 21.2679 11.8347C21.2679 11.8347 22.3179 12.4734 23.9506 12.8889C25.1204 13.1864 26.7 13.2483 26.7 13.2483V9.91314C27.2404 10.0343 27.7011 10.0671 28 10.0369Z" fill="#EE1D52"/>
<path d="M26.7009 9.91314V13.2472C26.7009 13.2472 25.1213 13.1853 23.9515 12.8879C22.3188 12.4718 21.2688 11.8337 21.2688 11.8337C21.2688 11.8337 20.5444 11.3787 20.4858 11.3464V20.1364C20.4858 20.6258 20.3518 21.8484 19.9432 22.8672C19.4098 24.2012 18.5867 25.0764 18.4353 25.2553C18.4353 25.2553 17.4337 26.4384 15.668 27.2352C14.0765 27.9539 12.6788 27.9357 12.2604 27.9539C12.2604 27.9539 9.84473 28.0496 7.66995 26.6366L7.6591 26.6288C7.42949 26.4064 7.21336 26.1717 7.01177 25.9257C6.31777 25.0795 5.89237 24.0789 5.78547 23.7934C5.78529 23.7922 5.78529 23.791 5.78547 23.7898C5.61347 23.2937 5.25209 22.1022 5.30147 20.9482C5.38883 18.9122 6.10507 17.6625 6.29444 17.3494C6.79597 16.4957 7.44828 15.7318 8.22233 15.0919C8.90538 14.5396 9.6796 14.1002 10.5132 13.7917C11.4144 13.4295 12.3794 13.2353 13.3565 13.2197V16.5948C13.3565 16.5948 11.5691 16.028 10.1388 17.0317C9.13879 17.7743 8.60812 18.4987 8.45185 19.7926C8.44534 20.7449 8.68897 22.0923 10.0254 22.991C10.1813 23.0898 10.3343 23.1775 10.4845 23.2541C10.7179 23.5576 11.0021 23.8221 11.3255 24.0368C12.631 24.8632 13.7249 24.9209 15.1238 24.3842C16.0565 24.0254 16.7586 23.2167 17.0842 22.3206C17.2888 21.7611 17.2861 21.1978 17.2861 20.6154V4.04639H20.5417C20.6763 4.81139 21.0485 5.90039 22.0328 6.97898C22.4276 7.38624 22.8724 7.7463 23.3573 8.05134C23.5006 8.19955 24.2331 8.93231 25.1734 9.38216C25.6596 9.61469 26.1722 9.79285 26.7009 9.91314Z" fill="#000000"/>
<path d="M4.48926 22.7568V22.7594L4.57004 22.9784C4.56076 22.9529 4.53074 22.8754 4.48926 22.7568Z" fill="#69C9D0"/>
<path d="M10.5128 13.7916C9.67919 14.1002 8.90498 14.5396 8.22192 15.0918C7.44763 15.7332 6.79548 16.4987 6.29458 17.354C6.10521 17.6661 5.38897 18.9168 5.30161 20.9528C5.25223 22.1068 5.61361 23.2983 5.78561 23.7944C5.78543 23.7956 5.78543 23.7968 5.78561 23.798C5.89413 24.081 6.31791 25.0815 7.01191 25.9303C7.2135 26.1763 7.42963 26.4111 7.65924 26.6334C6.92357 26.1457 6.26746 25.5562 5.71236 24.8839C5.02433 24.0451 4.60001 23.0549 4.48932 22.7626C4.48919 22.7605 4.48919 22.7584 4.48932 22.7564V22.7527C4.31677 22.2571 3.95431 21.0651 4.00477 19.9096C4.09213 17.8736 4.80838 16.6239 4.99775 16.3108C5.4985 15.4553 6.15067 14.6898 6.92509 14.0486C7.608 13.4961 8.38225 13.0567 9.21598 12.7484C9.73602 12.5416 10.2778 12.3891 10.8319 12.2934C11.6669 12.1537 12.5198 12.1415 13.3588 12.2575V13.2196C12.3808 13.2349 11.4148 13.4291 10.5128 13.7916Z" fill="#69C9D0"/>
<path d="M20.5438 4.04635H17.2881V20.6159C17.2881 21.1983 17.2881 21.76 17.0863 22.3211C16.7575 23.2167 16.058 24.0253 15.1258 24.3842C13.7265 24.923 12.6326 24.8632 11.3276 24.0368C11.0036 23.823 10.7187 23.5594 10.4844 23.2567C11.5962 23.8251 12.5913 23.8152 13.8241 23.341C14.7558 22.9821 15.4563 22.1734 15.784 21.2774C15.9891 20.7178 15.9864 20.1546 15.9864 19.5726V3H20.4819C20.4819 3 20.4315 3.41188 20.5438 4.04635ZM26.7002 8.99104V9.9131C26.1725 9.79263 25.6609 9.61447 25.1755 9.38213C24.2352 8.93228 23.5026 8.19952 23.3594 8.0513C23.5256 8.1559 23.6981 8.25106 23.8759 8.33629C25.0192 8.88339 26.1451 9.04669 26.7002 8.99104Z" fill="#69C9D0"/>
</svg>

After

Width:  |  Height:  |  Size: 4.7 KiB

3
public/twitter.svg Normal file
View file

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="800px" height="800px" viewBox="0 0 1024 1024" class="icon" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M362.41 879.648c-95.417 0-192.465-27.316-288.485-81.263-8.064-4.527-11.83-14.15-8.98-22.977 2.855-8.788 11.185-14.191 20.773-13.355 72.17 8.408 148.407-8.75 205.511-42.302-66.043-15.525-119.417-58.397-147.571-120.676a19.454 19.454 0 0 1 3.119-20.884c4.983-5.746 13.011-8.03 20.317-5.781a142.417 142.417 0 0 0 25.033 5.364c-50.106-29.903-103.784-87.197-103.784-172.987 0-7.531 4.335-14.379 11.11-17.573a19.353 19.353 0 0 1 20.654 2.47c6.241 5.099 12.938 9.362 19.821 12.708-14.339-19.44-26.781-43.562-33.857-70.8-12.972-49.989-5.478-100.585 21.683-146.351 3.233-5.516 9.018-9.054 15.372-9.514 6.238-0.681 12.552 2.249 16.584 7.27 57.332 71.633 159.212 158.183 323.066 174.01-3.003-51.854 12.556-136.841 84.154-178.653 87.462-51.13 173.248-44.434 245.606 18.983 32.263-7.187 83.202-29.291 93.741-36.673a19.516 19.516 0 0 1 22.33-0.04c6.696 4.683 9.779 13.052 7.686 20.963-4.87 18.375-15.864 38.765-29.6 57.027 10.881-3.233 20.012-6.505 24.882-9.014 7.837-3.997 17.308-2.322 23.318 4.146 5.937 6.505 6.775 16.131 2.097 23.587-22.942 36.218-59.959 69.963-84.727 88.222 9.931 121.587-39.26 255.425-132.998 360.459-99.976 111.966-233.776 173.634-376.781 173.634h-0.074z" fill="#2577FF" /><path d="M773.705 209.378c11.484-2.559 25.333-7.039 38.885-12.041-50.557-43.083-107.542-58.134-158.074-50.884 36.738 5.548 86.781 34.522 119.189 62.925zM484.047 365.248c-0.152-2.646-0.222-5.432-0.275-8.24-133.027-2.397-266.805-97.597-324.061-174.009-3.863-5.155-10.347-7.952-16.584-7.271-6.354 0.46-12.138 3.998-15.371 9.514-2.83 4.767-5.318 9.616-7.72 14.483 86.352 148.04 212.727 150.909 364.011 165.523zM954.896 233.745c-6.012-6.466-15.483-8.141-23.32-4.144-4.87 2.509-14.002 5.781-24.882 9.014 13.736-18.262 24.73-38.652 29.6-57.027a19.502 19.502 0 0 0-7.686-20.963 19.52 19.52 0 0 0-22.33 0.039c-3.711 2.6-12.577 7.061-23.723 12.014 0.607 2.903 0.772 5.914-0.021 8.911-4.87 18.375-15.864 38.765-29.599 57.027 10.881-3.233 20.012-6.505 24.882-9.014 7.837-3.997 17.308-2.322 23.32 4.144 5.936 6.507 6.774 16.133 2.095 23.59-22.942 36.216-59.959 69.961-84.726 88.22 9.929 121.587-39.261 255.425-132.997 360.461C592.268 810.433 469.603 871.055 337.5 878.76c8.309 0.411 16.624 0.888 24.91 0.888h0.073c143.006 0 276.806-61.669 376.784-173.633 93.736-105.035 142.927-238.874 132.997-360.461 24.767-18.259 61.784-52.004 84.726-88.22 4.68-7.457 3.842-17.083-2.094-23.589z" fill="" /></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

5992
public/vlcak.svg Normal file

File diff suppressed because it is too large Load diff

After

Width:  |  Height:  |  Size: 351 KiB

BIN
public/xbox360.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

BIN
public/xboxones.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View file

@ -0,0 +1,9 @@
export async function GET() {
try {
const res = await fetch("https://git.dvorakmortonxd.dev/api/v1/users/dvorakmortonxd/activities/feeds?limit=20");
const data = await res.json();
return Response.json(data);
} catch {
return Response.json({ error: "failed to load" }, { status: 500 });
}
}

View file

@ -0,0 +1,5 @@
export async function GET() {
const res = await fetch("https://git.dvorakmortonxd.dev/api/v1/users/dvorakmortonxd/heatmap");
const data = await res.json();
return Response.json(data);
}

View file

@ -0,0 +1,207 @@
"use client";
import React, { useEffect, useState } from "react";
interface HeatmapData {
timestamp: number;
contributions: number;
}
interface Activity {
op_type: string;
content?: string | null;
created: string;
repo?: {
full_name?: string;
};
}
interface ActivityPayload {
Commits?: Array<{
Message?: string;
}>;
HeadCommit?: {
Message?: string;
};
}
export default function ContributionHeatmap() {
const [weeks, setWeeks] = useState<{ date: string; contribs: number; level: number }[][]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(false);
const [totalContribs, setTotalContribs] = useState(0);
const [activities, setActivities] = useState<Activity[]>([]);
const [hoveredCell, setHoveredCell] = useState<{ date: string; contribs: number } | null>(null);
useEffect(() => {
async function fetchHeatmap() {
try {
const res = await fetch("/api/heatmap");
if (!res.ok) {
throw new Error("Failed to fetch");
}
const data: HeatmapData[] = await res.json();
const map = new Map<string, number>();
let total = 0;
let maxContribs = 0;
data.forEach((item) => {
const d = new Date(item.timestamp * 1000);
const dateStr = d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
const currentDayTotal = (map.get(dateStr) || 0) + item.contributions;
map.set(dateStr, currentDayTotal);
if (currentDayTotal > maxContribs) maxContribs = currentDayTotal;
total += item.contributions;
});
const endDate = new Date();
endDate.setHours(0, 0, 0, 0);
const startDate = new Date(endDate);
startDate.setFullYear(startDate.getFullYear() - 1);
startDate.setDate(startDate.getDate() - startDate.getDay());
const newWeeks = [];
let currentWeek = [];
for (let d = new Date(startDate); d <= endDate; d.setDate(d.getDate() + 1)) {
const dateStr = d.getFullYear() + "-" + String(d.getMonth() + 1).padStart(2, "0") + "-" + String(d.getDate()).padStart(2, "0");
const contribs = map.get(dateStr) || 0;
let level = 0;
if (contribs > 0) {
level = 1;
if (contribs > maxContribs * 0.25) level = 2;
if (contribs > maxContribs * 0.5) level = 3;
if (contribs > maxContribs * 0.75) level = 4;
}
currentWeek.push({ date: dateStr, contribs, level });
if (currentWeek.length === 7) {
newWeeks.push(currentWeek);
currentWeek = [];
}
}
if (currentWeek.length > 0) {
while (currentWeek.length < 7) {
currentWeek.push({ date: "", contribs: -1, level: -1 });
}
newWeeks.push(currentWeek);
}
setWeeks(newWeeks);
setTotalContribs(total);
setLoading(false);
} catch (err) {
console.error("Failed to load heatmap:", err);
setError(true);
setLoading(false);
}
}
async function fetchActivities() {
try {
const res = await fetch("/api/activities");
if (res.ok) {
const data: Activity[] = await res.json();
// Filter to just standard push/commit events
const valid = data.filter((d) => d.op_type === "commit_repo" || d.op_type === "push_repo").slice(0, 3);
setActivities(valid);
}
} catch (err) {
console.error("Failed to load activities:", err);
}
}
fetchHeatmap();
fetchActivities();
}, []);
if (loading) {
return <div style={{ color: "var(--gray)", fontSize: "0.85rem" }}>Loading contributions...</div>;
}
if (error) {
return <div style={{ color: "var(--gray)", fontSize: "0.85rem" }}>Failed to load contributions.</div>;
}
return (
<div style={{ display: "flex", flexDirection: "column", gap: "10px", width: "100%" }}>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<div style={{ fontSize: "0.85rem", color: "var(--fg)" }}>
<span style={{ color: "var(--green)" }}>martin@git.dvorakmortonxd.dev</span>:<span style={{ color: "var(--gray)" }}>~</span>$ echo &#34;<span style={{ color: "var(--prettypurple)" }}>{totalContribs}</span> contributions in the last year&#34;
</div>
</div>
<div className="heatmap-container">
{weeks.map((week, wIdx) => (
<div key={wIdx} className="heatmap-week">
{week.map((day, dIdx) => (
<div
key={dIdx}
className="heatmap-cell"
data-level={day.level >= 0 ? day.level : undefined}
style={{ visibility: day.level === -1 ? "hidden" : "visible" }}
title={day.level >= 0 ? `${day.contribs} contributions on ${day.date}` : undefined}
onMouseEnter={() => day.level >= 0 && setHoveredCell({ date: day.date, contribs: day.contribs })}
onMouseLeave={() => setHoveredCell(null)}
>
</div>
))}
</div>
))}
</div>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", fontSize: "0.75rem", color: "var(--gray)", marginTop: "4px" }}>
<div>
{hoveredCell ? (
<span><strong style={{ color: "var(--prettypurple)" }}>{hoveredCell.contribs}</strong> contributions on {hoveredCell.date}</span>
) : (
<span>Hover over a day to see contributions</span>
)}
</div>
<div style={{ display: "flex", alignItems: "center", gap: "4px" }}>
<span>Less</span>
<div className="heatmap-legend-cell" data-level="0"></div>
<div className="heatmap-legend-cell" data-level="1"></div>
<div className="heatmap-legend-cell" data-level="2"></div>
<div className="heatmap-legend-cell" data-level="3"></div>
<div className="heatmap-legend-cell" data-level="4"></div>
<span>More</span>
</div>
</div>
{activities.length > 0 && (
<div>
<div style={{ fontSize: "0.85rem", color: "var(--fg)", marginBottom: "4px" }}>
<span style={{ color: "var(--green)" }}>martin@git.dvorakmortonxd.dev</span>:<span style={{ color: "var(--gray)" }}>~</span>$ git log -n 3 <span style={{ color: "var(--gray)" }}>#displays my 3 latest contributions</span>
</div>
{activities.map((act, idx) => {
let msg = "No message";
try {
if (act.content) {
const parsed = JSON.parse(act.content) as ActivityPayload;
if (parsed.Commits && parsed.Commits.length > 0) {
msg = parsed.Commits[0].Message?.split("\n")[0] ?? msg;
} else if (parsed.HeadCommit?.Message) {
msg = parsed.HeadCommit.Message.split("\n")[0];
}
}
} catch {}
return (
<div key={idx} style={{ display: "flex", flexDirection: "column", fontSize: "0.8rem", color: "var(--fg)" }}>
<div style={{ display: "flex", justifyContent: "space-between", color: "var(--white)" }}>
<span>repo: {act.repo?.full_name || "unknown"}</span>
<span style={{ color: "var(--green)", fontSize: "0.67rem" }}>
{new Date(act.created).toLocaleDateString()}-{new Date(act.created).toLocaleTimeString()}
</span>
</div>
<div style={{ color: "var(--gray)", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis" }}>
{msg}
</div>
</div>
);
})}
</div>
)}
</div>
);
}

View file

@ -27,7 +27,7 @@ export default function JokerLogo() {
/>
{jokerActive && (
<div className="joker-flash-overlay">
<Image src="/joker.png" alt="Joker" className="joker-img" width={500} height={500} unoptimized />
<Image src="/joker.webp" alt="Joker" className="joker-img" width={500} height={500} unoptimized />
</div>
)}
</>

View file

@ -4,14 +4,14 @@ import { useEffect, useState } from "react";
const TRAIN_ASCII = ` ==== ________ ___________
_D _| |_______/ \\__I_I_____===__|_________|
|(_)--- | H\\________/ | | =|___ ___| _________________ _________________ _________________
/ | | H | | | | ||_| |_|| _| \\_____| \\_____| \\_____A
| | | H |__--------------------| [___] | =| | | |
| ________|___H__/__|_____/[][]~\\_______| | -| | | |
|/ | |-----------I_____I [][] [] D |=======|____|________________________|_______________________|_______________________|_
__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__|__________________________|_______________________|_______________________|
|/-=|___|= || || || |_____/~\\___/ |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_|
\\_/ \\O=====O=====O=====O_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/`;
|(_)--- | H\\________/ | | =|___ ___| _________________ _________________ _________________ _________________ _________________ _________________
/ | | H | | | | ||_| |_|| _| \\_____| \\_____| \\_____| \\_____| \\_____| \\_____A
| | | H |__--------------------| [___] | =| | | | | | |
| ________|___H__/__|_____/[][]~\\_______| | -| | | | | | |
|/ | |-----------I_____I [][] [] D |=======|____|________________________|_______________________|_______________________|_______________________|_______________________|_______________________|_
__/ =| o |=-~~\\ /~~\\ /~~\\ /~~\\ ____Y___________|__|__________________________|_______________________|_______________________|_______________________|_______________________|_______________________|
|/-=|___|= || || || |_____/~\\___/ |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_| |_D__D__D_|
\\_/ \\O=====O=====O=====O_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/ \\_/`;
export default function SlBackground() {
const [pos, setPos] = useState(150);
@ -25,7 +25,7 @@ export default function SlBackground() {
const delta = timestamp - lastTime;
// Update position every ~30ms to create a retro sliding terminal refresh feel
if (delta > 30) {
if (delta > 45) {
setPos((prev) => {
if (prev <= -150) return 150;
return prev - 1.5;
@ -65,7 +65,7 @@ export default function SlBackground() {
paddingBottom: "5vh",
justifyContent: "center",
userSelect: "none",
backgroundImage: "linear-gradient(rgba(29, 32, 33, 0.94), rgba(29, 32, 33, 0.94)), url('/gruvbox.png')",
backgroundImage: "linear-gradient(rgba(29, 32, 33, 0.94), rgba(29, 32, 33, 0.94)), url('/gruvbox.webp')",
backgroundSize: "cover",
backgroundPosition: "center",
}}

View file

@ -1,710 +0,0 @@
/* Valentine's Page for Kiki */
.kiki-container {
min-height: 100vh;
width: 100%;
background: linear-gradient(
135deg,
#1a1a2e 0%,
#16213e 25%,
#1a1a2e 50%,
#2d132c 75%,
#1a1a2e 100%
);
background-size: 400% 400%;
animation: gradientBG 15s ease infinite;
position: relative;
overflow: hidden;
font-family: "Inter", "Segoe UI", system-ui, sans-serif;
}
@keyframes gradientBG {
0% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
100% { background-position: 0% 50%; }
}
/* Floating Hearts */
.hearts-container {
position: fixed;
inset: 0;
pointer-events: none;
overflow: hidden;
z-index: 1;
}
.floating-heart {
position: absolute;
bottom: -50px;
animation: floatUp linear infinite;
opacity: 0.7;
filter: drop-shadow(0 0 10px rgba(255, 105, 180, 0.5));
}
@keyframes floatUp {
0% {
transform: translateY(0) rotate(0deg) scale(1);
opacity: 0;
}
10% {
opacity: 0.7;
}
90% {
opacity: 0.7;
}
100% {
transform: translateY(-110vh) rotate(720deg) scale(0.5);
opacity: 0;
}
}
/* Sparkles */
.sparkles {
position: fixed;
inset: 0;
pointer-events: none;
z-index: 2;
}
.sparkle {
position: absolute;
width: 6px;
height: 6px;
background: white;
border-radius: 50%;
animation: sparkle 3s ease-in-out infinite;
}
@keyframes sparkle {
0%, 100% {
opacity: 0;
transform: scale(0);
}
50% {
opacity: 1;
transform: scale(1);
box-shadow:
0 0 10px #fff,
0 0 20px #ff69b4,
0 0 30px #ff69b4;
}
}
/* Rose Petals */
.petals-container {
position: fixed;
inset: 0;
pointer-events: none;
overflow: hidden;
z-index: 3;
}
.petal {
position: absolute;
top: -50px;
font-size: 24px;
animation: fallPetal linear infinite;
filter: drop-shadow(0 0 5px rgba(255, 182, 193, 0.5));
}
@keyframes fallPetal {
0% {
transform: translateY(0) rotate(0deg) translateX(0);
opacity: 0;
}
10% {
opacity: 0.8;
}
90% {
opacity: 0.8;
}
100% {
transform: translateY(110vh) rotate(360deg) translateX(100px);
opacity: 0;
}
}
/* Main Content */
.kiki-main {
position: relative;
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
padding: 60px 20px;
min-height: 100vh;
}
/* Title */
.kiki-title {
font-size: clamp(2.5rem, 8vw, 5rem);
font-weight: 900;
text-align: center;
background: linear-gradient(
135deg,
#ff6b9d 0%,
#ff8fab 20%,
#ffc3d8 40%,
#ff8fab 60%,
#ff6b9d 80%,
#e84a8a 100%
);
background-size: 300% 300%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: titleGradient 5s ease-in-out infinite;
margin-bottom: 0.5rem;
opacity: 0;
transform: translateY(30px);
transition: all 1s cubic-bezier(0.34, 1.56, 0.64, 1);
filter: drop-shadow(0 0 30px rgba(255, 107, 157, 0.5));
}
.kiki-title.show {
opacity: 1;
transform: translateY(0);
}
@keyframes titleGradient {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
.kiki-subtitle {
font-size: clamp(2rem, 6vw, 4rem);
font-weight: 800;
color: #ffc3d8;
text-align: center;
margin-bottom: 3rem;
opacity: 0;
transform: translateY(30px);
transition: all 1s cubic-bezier(0.34, 1.56, 0.64, 1) 0.2s;
text-shadow:
0 0 20px rgba(255, 195, 216, 0.6),
0 0 40px rgba(255, 107, 157, 0.4),
0 0 60px rgba(255, 107, 157, 0.2);
animation: subtitlePulse 2s ease-in-out infinite;
}
.kiki-subtitle.show {
opacity: 1;
transform: translateY(0);
}
@keyframes subtitlePulse {
0%, 100% {
text-shadow:
0 0 20px rgba(255, 195, 216, 0.6),
0 0 40px rgba(255, 107, 157, 0.4),
0 0 60px rgba(255, 107, 157, 0.2);
}
50% {
text-shadow:
0 0 30px rgba(255, 195, 216, 0.8),
0 0 60px rgba(255, 107, 157, 0.6),
0 0 90px rgba(255, 107, 157, 0.4);
}
}
/* Photo Frame */
.photo-frame {
width: 100%;
max-width: 400px;
margin: 0 auto 3rem;
opacity: 0;
transform: scale(0.8) rotateY(-10deg);
transition: all 1.2s cubic-bezier(0.34, 1.56, 0.64, 1) 0.4s;
perspective: 1000px;
}
.photo-frame.show {
opacity: 1;
transform: scale(1) rotateY(0deg);
}
.photo-inner {
background: linear-gradient(145deg, #ff6b9d, #ff8fab, #ffc3d8);
padding: 12px;
border-radius: 24px;
box-shadow:
0 25px 80px rgba(255, 107, 157, 0.4),
0 10px 30px rgba(0, 0, 0, 0.3),
inset 0 2px 0 rgba(255, 255, 255, 0.3);
overflow: hidden;
position: relative;
}
.photo-inner::before {
content: "";
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.2) 0%,
transparent 50%
);
pointer-events: none;
border-radius: 24px;
}
.photo-slider {
display: flex;
transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
}
.photo-slide {
min-width: 100%;
}
.photo {
width: 100%;
height: 350px;
object-fit: cover;
border-radius: 16px;
display: block;
}
.photo-dots {
display: flex;
justify-content: center;
gap: 10px;
margin-top: 16px;
}
.photo-dot {
width: 12px;
height: 12px;
border-radius: 50%;
border: none;
background: rgba(255, 107, 157, 0.3);
cursor: pointer;
transition: all 0.3s ease;
}
.photo-dot:hover {
background: rgba(255, 107, 157, 0.6);
transform: scale(1.2);
}
.photo-dot.active {
background: #ff6b9d;
box-shadow: 0 0 15px rgba(255, 107, 157, 0.8);
transform: scale(1.3);
}
/* Love Letter */
.love-letter {
width: 100%;
max-width: 600px;
margin: 0 auto 3rem;
opacity: 0;
transform: translateY(50px) rotateX(-10deg);
transition: all 1.2s cubic-bezier(0.34, 1.56, 0.64, 1) 0.6s;
}
.love-letter.show {
opacity: 1;
transform: translateY(0) rotateX(0deg);
}
.letter-content {
background: linear-gradient(
145deg,
rgba(255, 255, 255, 0.08),
rgba(255, 255, 255, 0.03)
);
backdrop-filter: blur(20px);
border: 1px solid rgba(255, 107, 157, 0.3);
border-radius: 24px;
padding: 2.5rem;
box-shadow:
0 20px 60px rgba(0, 0, 0, 0.3),
0 0 40px rgba(255, 107, 157, 0.15),
inset 0 1px 0 rgba(255, 255, 255, 0.1);
position: relative;
overflow: hidden;
}
.letter-content::before {
content: "💌";
position: absolute;
top: -10px;
right: -10px;
font-size: 80px;
opacity: 0.1;
transform: rotate(15deg);
}
.letter-greeting {
font-size: 1.5rem;
font-weight: 700;
color: #ff8fab;
margin-bottom: 1.5rem;
font-style: italic;
}
.letter-text {
color: #fff;
font-size: 1.1rem;
line-height: 1.8;
margin-bottom: 1.2rem;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
.letter-signature {
color: #ffc3d8;
font-size: 1.2rem;
text-align: right;
margin-top: 2rem;
font-style: italic;
line-height: 1.6;
}
.signature-name {
font-weight: 700;
font-size: 1.4rem;
background: linear-gradient(135deg, #ff6b9d, #ffc3d8);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
/* Big Heart */
.big-heart {
margin: 2rem 0;
opacity: 0;
transform: scale(0);
transition: all 1s cubic-bezier(0.34, 1.56, 0.64, 1) 0.8s;
}
.big-heart.show {
opacity: 1;
transform: scale(1);
}
.heart-pulse {
font-size: 100px;
animation: heartBeat 1.5s ease-in-out infinite;
filter: drop-shadow(0 0 30px rgba(255, 107, 157, 0.6));
}
@keyframes heartBeat {
0%, 100% {
transform: scale(1);
}
10% {
transform: scale(1.15);
}
20% {
transform: scale(1);
}
30% {
transform: scale(1.15);
}
40% {
transform: scale(1);
}
}
/* Cute Messages */
.cute-messages {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 1rem;
margin-top: 2rem;
opacity: 0;
transform: translateY(30px);
transition: all 1s ease 1s;
}
.cute-messages.show {
opacity: 1;
transform: translateY(0);
}
.cute-msg {
background: linear-gradient(135deg, rgba(255, 107, 157, 0.3), rgba(255, 143, 171, 0.2));
backdrop-filter: blur(10px);
padding: 12px 24px;
border-radius: 999px;
color: #ffc3d8;
font-weight: 600;
font-size: 0.95rem;
border: 1px solid rgba(255, 107, 157, 0.3);
animation: floatMsg 3s ease-in-out infinite;
box-shadow: 0 5px 20px rgba(255, 107, 157, 0.2);
}
.cute-msg:nth-child(1) { animation-delay: 0s; }
.cute-msg:nth-child(2) { animation-delay: 0.5s; }
.cute-msg:nth-child(3) { animation-delay: 1s; }
@keyframes floatMsg {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-10px); }
}
/* Responsive */
@media (max-width: 600px) {
.kiki-main {
padding: 40px 16px;
}
.photo {
height: 280px;
}
.letter-content {
padding: 1.5rem;
}
.letter-text {
font-size: 1rem;
}
.heart-pulse {
font-size: 70px;
}
.cute-messages {
flex-direction: column;
align-items: center;
}
}
/* Extra glow effect overlay */
.kiki-container::before {
content: "";
position: fixed;
top: 30%;
left: 50%;
transform: translateX(-50%);
width: 600px;
height: 600px;
background: radial-gradient(circle, rgba(255, 107, 157, 0.15) 0%, transparent 70%);
pointer-events: none;
z-index: 0;
animation: glowPulse 4s ease-in-out infinite;
}
@keyframes glowPulse {
0%, 100% { opacity: 0.5; transform: translateX(-50%) scale(1); }
50% { opacity: 1; transform: translateX(-50%) scale(1.2); }
}
/* Question Screen */
.question-screen {
position: relative;
z-index: 10;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 40px 20px;
text-align: center;
}
.question-heart {
font-size: 75px;
animation: heartBounce 2s ease infinite;
filter: drop-shadow(0 0 40px rgba(255, 107, 157, 0.6));
margin-bottom: 1rem;
}
@keyframes heartBounce {
0%, 100% { transform: scale(1) rotate(-5deg); }
25% { transform: scale(1.1) rotate(5deg); }
50% { transform: scale(1) rotate(-5deg); }
75% { transform: scale(1.15) rotate(5deg); }
}
.question-title {
font-size: clamp(2rem, 6vw, 3.5rem);
font-weight: 800;
color: #ffc3d8;
margin-bottom: 1rem;
text-shadow:
0 0 20px rgba(255, 195, 216, 0.6),
0 0 40px rgba(255, 107, 157, 0.4);
animation: fadeInDown 1s ease;
}
@keyframes fadeInDown {
from {
opacity: 0;
transform: translateY(-30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.question-text {
font-size: clamp(1.8rem, 5vw, 3rem);
font-weight: 900;
background: linear-gradient(
135deg,
#ff6b9d 0%,
#ff8fab 25%,
#ffc3d8 50%,
#ff8fab 75%,
#ff6b9d 100%
);
background-size: 300% 300%;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: titleGradient 4s ease-in-out infinite, fadeInUp 1s ease 0.3s both;
margin-bottom: 3rem;
filter: drop-shadow(0 0 30px rgba(255, 107, 157, 0.5));
}
.question-buttons {
display: flex;
gap: 2rem;
align-items: center;
justify-content: center;
flex-wrap: wrap;
position: relative;
min-height: 80px;
width: 100%;
max-width: 500px;
}
.yes-button {
padding: 20px 50px;
font-size: 1.5rem;
font-weight: 700;
color: white;
background: linear-gradient(135deg, #ff6b9d, #ff8fab, #ff6b9d);
background-size: 200% 200%;
border: none;
border-radius: 999px;
cursor: pointer;
transition: all 0.4s cubic-bezier(0.175, 0.885, 0.32, 1.275);
box-shadow:
0 10px 40px rgba(255, 107, 157, 0.5),
0 5px 15px rgba(0, 0, 0, 0.2),
inset 0 2px 0 rgba(255, 255, 255, 0.3);
animation: yesButtonPulse 2s ease-in-out infinite, fadeInUp 1s ease 0.5s both;
z-index: 10;
}
@keyframes yesButtonPulse {
0%, 100% {
transform: scale(1);
box-shadow:
0 10px 40px rgba(255, 107, 157, 0.5),
0 5px 15px rgba(0, 0, 0, 0.2),
inset 0 2px 0 rgba(255, 255, 255, 0.3);
}
50% {
transform: scale(1.05);
box-shadow:
0 15px 50px rgba(255, 107, 157, 0.7),
0 8px 25px rgba(0, 0, 0, 0.3),
inset 0 2px 0 rgba(255, 255, 255, 0.3);
}
}
.yes-button:hover {
transform: scale(1.15) !important;
background-position: 100% 0;
box-shadow:
0 20px 60px rgba(255, 107, 157, 0.7),
0 10px 30px rgba(0, 0, 0, 0.3),
inset 0 2px 0 rgba(255, 255, 255, 0.4);
}
.no-button {
padding: 15px 35px;
font-size: 1.1rem;
font-weight: 600;
color: #ff8fab;
background: rgba(30, 20, 40, 0.95);
border: 2px solid rgba(255, 107, 157, 0.5);
border-radius: 999px;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
backdrop-filter: blur(10px);
animation: fadeInUp 1s ease 0.6s both;
z-index: 5;
white-space: nowrap;
}
.no-button:hover {
background: rgba(50, 30, 60, 0.95);
border-color: rgba(255, 107, 157, 0.7);
}
.no-button.runaway {
z-index: 99999 !important;
animation: popIn 0.25s cubic-bezier(0.175, 0.885, 0.32, 1.275);
box-shadow:
0 10px 40px rgba(255, 107, 157, 0.5),
0 0 20px rgba(255, 107, 157, 0.3),
0 0 60px rgba(255, 107, 157, 0.2);
background: rgba(30, 20, 40, 0.98);
border: 2px solid rgba(255, 107, 157, 0.8);
pointer-events: auto;
}
@keyframes popIn {
0% {
transform: scale(0.3) rotate(-10deg);
opacity: 0;
}
60% {
transform: scale(1.15) rotate(3deg);
}
100% {
transform: scale(1) rotate(0deg);
opacity: 1;
}
}
.hint-text {
margin-top: 2rem;
color: #ffc3d8;
font-size: 1.1rem;
font-style: italic;
animation: fadeIn 0.5s ease;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
/* Make the Yes button grow bigger over time as No keeps running away */
.yes-button:active {
transform: scale(0.95) !important;
}
/* Responsive adjustments for question screen */
@media (max-width: 600px) {
.question-heart {
font-size: 70px;
}
.question-buttons {
flex-direction: column;
gap: 1.5rem;
}
.yes-button {
padding: 18px 45px;
font-size: 1.3rem;
}
.no-button {
padding: 12px 30px;
font-size: 1rem;
}
}

View file

@ -1,370 +0,0 @@
"use client";
import { useEffect, useState } from "react";
import Image from "next/image";
import "./darecek.css";
export default function KikiPage() {
const [hasAnswered, setHasAnswered] = useState(false);
const [showMessage, setShowMessage] = useState(false);
const [currentPhotoIndex, setCurrentPhotoIndex] = useState(0);
const [hearts, setHearts] = useState<{ id: number; left: number; delay: number; duration: number; size: number }[]>([]);
const [noButtonStyle, setNoButtonStyle] = useState<React.CSSProperties>({});
const [noButtonText, setNoButtonText] = useState("ne 😢");
const [noHoverCount, setNoHoverCount] = useState(0);
const [isRunning, setIsRunning] = useState(false);
const noButtonTexts = [
"ne 😢",
"fakt? 🥺",
"pjosim? 🥺",
"hej 😡",
"stop 👿",
"nech toooo 😭",
"😭😭😭",
"budu urazeny 🥺",
"grrrrr 👿👿👿",
"stejnak nemas na vyber 😝😝😝",
];
// Add your photos here - just put images in /public/darecek/ folder
// named photo1.jpg, photo2.jpg, etc.
const photos = [
"/darecek/photo1.jpg",
"/darecek/photo2.jpg",
"/darecek/photo3.jpg",
"/darecek/photo4.jpg",
"/darecek/photo5.jpg",
];
const moveNoButton = (e: React.MouseEvent | React.TouchEvent) => {
// Get current mouse/touch position
let currentX = 0;
let currentY = 0;
if ('touches' in e) {
currentX = e.touches[0].clientX;
currentY = e.touches[0].clientY;
} else {
currentX = e.clientX;
currentY = e.clientY;
}
const viewportWidth = window.innerWidth;
const viewportHeight = window.innerHeight;
const buttonWidth = 200;
const buttonHeight = 60;
const padding = 20;
const minDistanceFromMouse = 200; // Minimum distance from mouse
// Calculate safe bounds
const minX = padding;
const maxX = viewportWidth - buttonWidth - padding;
const minY = padding;
const maxY = viewportHeight - buttonHeight - padding;
let newX: number;
let newY: number;
let attempts = 0;
const maxAttempts = 50;
// Keep trying until we find a position far enough from mouse
do {
newX = minX + Math.random() * (maxX - minX);
newY = minY + Math.random() * (maxY - minY);
attempts++;
// Calculate distance from mouse
const distance = Math.sqrt(
Math.pow(newX + buttonWidth / 2 - currentX, 2) +
Math.pow(newY + buttonHeight / 2 - currentY, 2)
);
// If far enough from mouse, use this position
if (distance > minDistanceFromMouse) break;
} while (attempts < maxAttempts);
// If still too close after max attempts, move to opposite side of screen
const buttonCenterX = newX + buttonWidth / 2;
const buttonCenterY = newY + buttonHeight / 2;
const distanceFromMouse = Math.sqrt(
Math.pow(buttonCenterX - currentX, 2) +
Math.pow(buttonCenterY - currentY, 2)
);
if (distanceFromMouse < minDistanceFromMouse) {
// Move to opposite quadrant of the screen
if (currentX < viewportWidth / 2) {
newX = maxX - Math.random() * (maxX / 3);
} else {
newX = minX + Math.random() * (maxX / 3);
}
if (currentY < viewportHeight / 2) {
newY = maxY - Math.random() * (maxY / 3);
} else {
newY = minY + Math.random() * (maxY / 3);
}
}
// Ensure bounds
newX = Math.max(minX, Math.min(maxX, newX));
newY = Math.max(minY, Math.min(maxY, newY));
setNoButtonStyle({
position: 'fixed',
left: `${newX}px`,
top: `${newY}px`,
});
setIsRunning(true);
setNoHoverCount(prev => prev + 1);
setNoButtonText(noButtonTexts[Math.min(noHoverCount + 1, noButtonTexts.length - 1)]);
};
const handleYesClick = () => {
setHasAnswered(true);
// Show message after transition
setTimeout(() => setShowMessage(true), 500);
};
useEffect(() => {
// Generate floating hearts
const newHearts = Array.from({ length: 30 }, (_, i) => ({
id: i,
left: Math.random() * 100,
delay: Math.random() * 5,
duration: 5 + Math.random() * 10,
size: 15 + Math.random() * 25,
}));
setHearts(newHearts);
}, []);
useEffect(() => {
if (!hasAnswered) return;
// Auto-rotate photos
const interval = setInterval(() => {
setCurrentPhotoIndex((prev) => (prev + 1) % photos.length);
}, 4000);
return () => clearInterval(interval);
}, [hasAnswered, photos.length]);
// Question screen
if (!hasAnswered) {
return (
<div className="kiki-container">
{/* Floating Hearts Background */}
<div className="hearts-container">
{hearts.map((heart) => (
<div
key={heart.id}
className="floating-heart"
style={{
left: `${heart.left}%`,
animationDelay: `${heart.delay}s`,
animationDuration: `${heart.duration}s`,
fontSize: `${heart.size}px`,
}}
>
💖
</div>
))}
</div>
{/* Sparkles */}
<div className="sparkles">
{Array.from({ length: 50 }).map((_, i) => (
<div
key={i}
className="sparkle"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 3}s`,
}}
/>
))}
</div>
{/* Question Content */}
<div className="question-screen">
<div className="question-heart">😝</div>
<h1 className="question-title">kikiiiii</h1>
<h2 className="question-text">budes muj valentyn? ❤️</h2>
<div className="question-buttons">
<button className="yes-button" onClick={handleYesClick}>
jo 😘
</button>
{!isRunning && (
<button
className="no-button"
onMouseEnter={moveNoButton}
onTouchStart={moveNoButton}
onClick={moveNoButton}
>
{noButtonText}
</button>
)}
</div>
{noHoverCount > 3 && (
<p className="hint-text">
{noHoverCount > 6 ? "dej ano tele 😛" : "to tlacitko ti zdrha 😝😝😝"}
</p>
)}
</div>
{/* Runaway No Button - rendered outside the question-buttons container */}
{isRunning && (
<button
className="no-button runaway"
style={noButtonStyle}
onMouseEnter={moveNoButton}
onTouchStart={moveNoButton}
onClick={moveNoButton}
>
{noButtonText}
</button>
)}
</div>
);
}
return (
<div className="kiki-container">
{/* Floating Hearts Background */}
<div className="hearts-container">
{hearts.map((heart) => (
<div
key={heart.id}
className="floating-heart"
style={{
left: `${heart.left}%`,
animationDelay: `${heart.delay}s`,
animationDuration: `${heart.duration}s`,
fontSize: `${heart.size}px`,
}}
>
💘
</div>
))}
</div>
{/* Sparkles */}
<div className="sparkles">
{Array.from({ length: 50 }).map((_, i) => (
<div
key={i}
className="sparkle"
style={{
left: `${Math.random() * 100}%`,
top: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 3}s`,
}}
/>
))}
</div>
{/* Main Content */}
<main className="kiki-main">
{/* Title */}
<h1 className={`kiki-title ${showMessage ? "show" : ""}`}>
stastnej valentynnnn
</h1>
<h2 className={`kiki-subtitle ${showMessage ? "show" : ""}`}>
laskoooo 😘😘😝
</h2>
{/* Photo Gallery */}
<div className={`photo-frame ${showMessage ? "show" : ""}`}>
<div className="photo-inner">
<div
className="photo-slider"
style={{ transform: `translateX(-${currentPhotoIndex * 100}%)` }}
>
{photos.map((photo, index) => (
<div key={index} className="photo-slide">
<Image
src={photo}
alt={`Memory ${index + 1}`}
className="photo"
width={500}
height={500}
onError={(e) => {
// Fallback if image doesn't exist
(e.target as HTMLImageElement).src = "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='300' height='300' viewBox='0 0 300 300'%3E%3Crect fill='%23ff6b9d' width='300' height='300'/%3E%3Ctext x='150' y='150' text-anchor='middle' dy='.3em' fill='white' font-size='60'%3E💕%3C/text%3E%3C/svg%3E";
}}
/>
</div>
))}
</div>
</div>
<div className="photo-dots">
{photos.map((_, index) => (
<button
key={index}
className={`photo-dot ${index === currentPhotoIndex ? "active" : ""}`}
onClick={() => setCurrentPhotoIndex(index)}
/>
))}
</div>
</div>
{/* Love Letter */}
<div className={`love-letter ${showMessage ? "show" : ""}`}>
<div className="letter-content">
<p className="letter-greeting">pro moji princeznu,</p>
<p className="letter-text">
tohle je nas druhej valentyn a jsem moc moc stastnej, ze ho muzu stravit s tebou 😘
</p>
<p className="letter-text">
si ta nejlepsi, nejkrasnejsi a nejroztomilejsi holka na svete, kterou bych si kdy mohl prat, a jsem vdecnej, ze si to semnou vydrzela, i pres ty moje nalady 🥺😝❤️
</p>
<p className="letter-text">
tak strasne moc te milujuuuu a chci byt s tebou pro zbytek svyho zivota, lasko moje ❤️🥹
</p>
<p className="letter-signature">
tvoje laska,<br />
<span className="signature-name">Martin ❤️</span>
</p>
</div>
</div>
{/* Animated Heart */}
<div className={`big-heart ${showMessage ? "show" : ""}`}>
<div className="heart-pulse">❤️</div>
</div>
{/* Cute Messages */}
<div className={`cute-messages ${showMessage ? "show" : ""}`}>
<span className="cute-msg">jsi moje 👸🏽</span>
<span className="cute-msg">miluju te nejvic ve vesmiru 😝</span>
<span className="cute-msg">chci jenom tebee 😍</span>
</div>
</main>
{/* Rose petals falling */}
<div className="petals-container">
{Array.from({ length: 20 }).map((_, i) => (
<div
key={i}
className="petal"
style={{
left: `${Math.random() * 100}%`,
animationDelay: `${Math.random() * 8}s`,
animationDuration: `${8 + Math.random() * 7}s`,
}}
>
💝
</div>
))}
</div>
</div>
);
}

View file

@ -26,6 +26,7 @@
--bg-hard: #32302f;
--fg: #ebdbb2;
--gray: #a89984;
--prettypurple: #733999;
--accent: #fabd2f; /* Gruvbox Yellow */
--accent2: #fe8019; /* Gruvbox Orange */
--accent3: #d79921; /* Gruvbox Dark Yellow */
@ -506,6 +507,12 @@ body {
color: var(--purple);
}
.subsection-panel.friends-panel {
background: rgba(255, 255, 255, 0.08); /* slightly light */
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
}
.subsection-panel.friends-panel .subsection-panel-label {
color: var(--aqua);
}
@ -644,7 +651,7 @@ body {
overflow: hidden;
border: 1px solid var(--card-border);
border-top: none;
aspect-ratio: 2 / 1;
aspect-ratio: 16 / 9;
transform: translateZ(0);
will-change: transform;
}
@ -792,6 +799,20 @@ body {
.friend-iframe-container {
aspect-ratio: 16 / 9;
}
.gym-grid {
gap: 12px;
padding: 16px;
}
.gym-item {
padding: 12px;
gap: 8px;
}
.gym-weight {
font-size: 1.4rem;
}
}
@media (max-width: 520px) {
@ -807,12 +828,38 @@ body {
grid-template-columns: 1fr;
}
.gym-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 4px;
padding: 12px 4px;
}
.gym-item {
padding: 8px 2px;
gap: 4px;
min-width: 0;
}
.gym-icon {
max-width: 32px !important;
}
.gym-label {
font-size: 0.55rem;
letter-spacing: 0.02em;
}
.gym-weight {
font-size: 0.95rem;
}
.project-grid {
grid-template-columns: 1fr;
}
.video-grid {
grid-template-columns: 1fr;
gap: 10px;
}
.project-image {
@ -833,6 +880,41 @@ body {
}
}
/* ============================================
SEARCH BAR
============================================ */
.search-section {
margin-top: 16px;
}
.search-form {
display: flex;
padding: 20px 24px;
}
.search-bar {
width: 100%;
padding: 12px 16px;
background: rgba(255, 255, 255, 0.05); /* very transparent */
backdrop-filter: blur(10px) saturate(120%);
-webkit-backdrop-filter: blur(10px) saturate(120%);
border: 1px solid var(--tui-border);
color: var(--fg);
font-family: var(--font-custom-mono), monospace;
font-size: 1rem;
outline: none;
transition: all 0.3s ease;
}
.search-bar:focus {
border-color: var(--red);
box-shadow: 0 0 10px rgba(74, 233, 52, 0.3);
}
.search-bar::placeholder {
color: var(--gray);
}
/* Joker Animation */
.joker-flash-overlay {
position: fixed;
@ -873,3 +955,115 @@ body {
transform: scale(0) rotate(-20deg);
}
}
/* ============================================
GYM PANEL
============================================ */
.gym-section {
margin-top: 16px;
}
.gym-grid {
display: grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap: 16px;
padding: 24px;
text-align: center;
}
.gym-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 16px;
background: rgba(255, 255, 255, 0.02);
border: 1px solid rgba(168, 153, 132, 0.1);
transition: all 0.3s ease;
}
.gym-item:hover {
background: rgba(250, 189, 47, 0.05);
border-color: rgba(250, 189, 47, 0.3);
transform: translateY(-4px);
}
.gym-icon {
opacity: 0.9;
transition: opacity 0.3s ease, filter 0.3s ease;
width: 100%;
max-width: 48px;
height: auto;
}
.gym-item:hover .gym-icon {
opacity: 1;
filter: drop-shadow(0 0 8px rgba(250, 189, 47, 0.8));
}
.gym-label {
font-size: 0.85rem;
font-weight: 700;
color: var(--gray);
letter-spacing: 0.08em;
text-transform: uppercase;
}
.gym-weight {
font-size: 1.6rem;
font-weight: 800;
color: var(--fg);
font-family: var(--font-custom-mono), monospace;
}
/* ============================================
HEATMAP
============================================ */
.heatmap-container {
display: flex;
width: 100%;
overflow-x: auto;
gap: 2px;
scrollbar-width: none;
scrollbar-color: var(--gray) transparent;
}
.heatmap-week {
display: flex;
flex-direction: column;
flex: 1;
gap: 2px;
}
.heatmap-cell {
width: 100%;
aspect-ratio: 1;
border-radius: 2px;
background-color: var(--bg-hard);
transition: transform 0.1s ease;
}
.heatmap-cell:hover {
transform: scale(1.2);
z-index: 10;
box-shadow: 0 0 6px rgba(142, 68, 173, 0.6);
}
.heatmap-cell[data-level="1"] { background-color: rgba(142, 68, 173, 0.4); }
.heatmap-cell[data-level="2"] { background-color: rgba(142, 68, 173, 0.6); }
.heatmap-cell[data-level="3"] { background-color: rgba(142, 68, 173, 0.8); }
.heatmap-cell[data-level="4"] { background-color: rgba(142, 68, 173, 1); }
.heatmap-legend-cell {
width: 11px;
height: 11px;
border-radius: 2px;
background-color: var(--bg-hard);
flex-shrink: 0;
}
.heatmap-legend-cell[data-level="1"] { background-color: rgba(142, 68, 173, 0.4); }
.heatmap-legend-cell[data-level="2"] { background-color: rgba(142, 68, 173, 0.6); }
.heatmap-legend-cell[data-level="3"] { background-color: rgba(142, 68, 173, 0.8); }
.heatmap-legend-cell[data-level="4"] { background-color: rgba(142, 68, 173, 1); }

View file

@ -4,6 +4,7 @@ import { Metadata } from 'next';
import JokerLogo from "./components/JokerLogo";
import ServiceButton from "./components/ServiceButton";
import SlBackground from "./components/SlBackground";
import ContributionHeatmap from "./components/ContributionHeatmap";
export const metadata: Metadata = {
title: 'dvorakmortonxd.dev',
@ -23,109 +24,109 @@ const codingProjects = [
{
title: "Hospital Execution",
desc: "the first ever real game I made, in pygame.",
img: "/coding-1.png",
img: "/coding-1.webp",
url: "https://martin-dv.itch.io/hospital-execution-demo",
},
{
title: "Underbaranoia",
desc: "basically a undertale like infinite fight simulator that gets progressively harder, made in pygame.",
img: "/coding-2.png",
img: "/coding-2.webp",
url: "https://martin-dv.itch.io/underbaranoia",
},
{
title: "Offline memer",
desc: "parody of the discord bot \"Dank Memer\" made in batch. (this was technically my first ever game I published).",
img: "/coding-3.png",
img: "/coding-3.webp",
url: "https://martin-dv.itch.io/offline-memer",
},
{
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.",
img: "/coding-4.png",
img: "/coding-4.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/4y",
},
{
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.",
img: "/coding-5.png",
img: "/coding-5.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/4rch-linux",
},
{
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.",
img: "/coding-6.png",
img: "/coding-6.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/uranidiot",
},
{
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.",
img: "/coding-7.png",
img: "/coding-7.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/Venturesome",
},
{
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.",
img: "/coding-8.png",
img: "/coding-8.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/mandelbrot",
},
{
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.",
img: "/coding-9.png",
img: "/coding-9.webp",
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.",
img: "/coding-10.png",
img: "/coding-10.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/PYGETEX",
},
{
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.",
img: "/coding-11.png",
img: "/coding-11.webp",
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.",
img: "/coding-12.png",
img: "/coding-12.webp",
url: "https://discord.gg/KtHRm9kRmy",
},
{
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.",
img: "/coding-13.png",
img: "/coding-13.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/sas2py",
},
{
title: "Ollama server",
desc: "my ollama vm running on my proxmox with a gpu passthroughed RTX 3070, dm me if u wanna test it lol.",
img: "/coding-14.png",
img: "/coding-14.webp",
url: "https://ai.dvorakmortonxd.dev/",
},
{
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).",
img: "/coding-15.png",
img: "/coding-15.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/DvorakMSDOS",
},
{
title: "RustyWolf",
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 :)",
img: "/coding-16.png",
img: "/coding-16.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/RustyWolf",
},
{
title: "dxdwm",
desc: "a small x11 window manager written in rust.",
img: "/coding-17.png",
img: "/coding-17.webp",
url: "https://git.dvorakmortonxd.dev/dvorakmortonxd/dxdwm",
},
{
title: "proxmox setup",
desc: "my proxmox setup with more than 8 vms for my services, this is running literally everything at my house.",
img: "/proxmox.png",
img: "/proxmox.webp",
url: "https://proxmox.dvorakmortonxd.dev/",
},
];
@ -149,63 +150,63 @@ export default function Home() {
const techProjects = [
{
title: "Gentoo Setup",
desc: "my main computer with gentoo. specs: Ryzen 5 3600 (6c/12t), GTX 1050 Ti (yes im aware I could use the rtx 3070 from the proxmox server but I dont need it and its much better off being in there cuz of local ai), 16gb of ram and a 240gb ssd.",
image: "/gentoo-setup.png",
desc: "my main computer with gentoo. specs: Ryzen 5 3600 (6c/12t), RX 580 8GB ASUS ROG, 16gb of ram and a 240gb sata ssd.",
image: "/gentoo-setup.webp",
},
{
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 (for local ai), 68gb ddr4 rdimm ram (2*16gb, 1*32gb, 1*4gb), 256gb of sata m2 space + 1tb hdd + 750gb hdd.",
image: "/proxmox-server.png",
desc: "my personal proxmox server (dm me on ig if u need a VPS/hosting), specs: Xeon E5 2680 v4 (14c/28t), RTX 3070 (for local ai) and GTX 1050 Ti (for jellyfin), 68gb ddr4 rdimm ram (2*16gb, 1*32gb, 1*4gb), 256gb of sata m2 space + 1tb hdd + 750gb hdd.",
image: "/proxmox-server.webp",
},
{
title: "Xbox 360 S with 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.",
image: "/xbox360.png",
image: "/xbox360.webp",
},
{
title: "Macbook Air M4 13\"",
desc: "my main device for basically everything except gaming. specs are Apple M4 (cpu:10c,gpu:8c), 16gb of unified ram (lpddr5x), 256gb Storage.",
image: "/macbook-air.png",
image: "/macbook-air.webp",
},
{
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 i3-gaps (this is my laptop not josef's I gave it to him lol).",
image: "/macbook-air-11.png",
image: "/macbook-air-11.webp",
},
{
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",
image: "/iphone-7.png",
image: "/iphone-7.webp",
},
{
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 :(",
image: "/macbook2010.png",
image: "/macbook2010.webp",
},
{
title: "ThinkPad T400s 14\"",
desc: "got it from a random guy for 20 bucks, its an old laptop from 2009 and I disabled intel AMT and slapped void linux on it and i3wm on it, specs are intel core 2 duo (2c/2t), 8gb ddr3 ram and 800gb hdd.",
image: "/thinkpadt400s.png",
desc: "got it from a random guy for 20 bucks, its an old laptop from 2009 and I slapped void linux on it and i3wm on it, specs are intel core 2 duo (2c/2t), 8gb ddr3 ram and 800gb hdd.",
image: "/thinkpadt400s.webp",
},
{
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.",
image: "/asuslaptop.png",
image: "/asuslaptop.webp",
},
{
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)",
image: "/iphone11.png",
image: "/iphone11.webp",
},
{
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.",
image: "/iphone16pro.png",
image: "/iphone16pro.webp",
},
{
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.",
image: "/xboxones.png",
image: "/xboxones.webp",
},
];
@ -258,6 +259,16 @@ export default function Home() {
</p>
</div>
{/* Search Panel */}
<div className="search-section">
<div className="tui-panel">
<span className="tui-panel-label" style={{ color: 'var(--red)' }}>├─ SEARXNG.C</span>
<form action="https://search.dvorakmortonxd.dev/search" method="GET" target="_blank" rel="noopener noreferrer" className="search-form">
<input type="text" name="q" placeholder="Search... (only works if I granted you access)" className="search-bar" />
</form>
</div>
</div>
{/* Social Links Panel */}
<div className="social-section">
<div className="tui-panel">
@ -282,6 +293,33 @@ export default function Home() {
</div>
</div>
{/* Gym SBD Panel */}
<div className="gym-section">
<div className="tui-panel">
<span className="tui-panel-label" style={{ color: 'var(--accent2)' }}>├─ GYM_SBD_AT_73KG_BW.DB</span>
<div className="gym-grid">
<div className="gym-item">
<Image src="/squat.svg" alt="Squat" width={48} height={48} className="gym-icon" />
<div className="gym-label">SQUAT</div>
<div className="gym-weight">125kg</div>
<div className="gym-date" style={{ fontSize: '0.65rem', color: 'var(--gray)' }}>5.1.2025</div>
</div>
<div className="gym-item">
<Image src="/bench.svg" alt="Bench" width={48} height={48} className="gym-icon" />
<div className="gym-label">BENCH</div>
<div className="gym-weight">108kg</div>
<div className="gym-date" style={{ fontSize: '0.65rem', color: 'var(--gray)' }}>25.4.2026</div>
</div>
<div className="gym-item">
<Image src="/deadlift.svg" alt="Deadlift" width={48} height={48} className="gym-icon" />
<div className="gym-label">DEADLIFT</div>
<div className="gym-weight">165kg</div>
<div className="gym-date" style={{ fontSize: '0.65rem', color: 'var(--gray)' }}>17.12.2024</div>
</div>
</div>
</div>
</div>
{/* About Me Panel */}
<div className="about-section">
<div className="tui-panel">
@ -292,13 +330,13 @@ export default function Home() {
</p>
<div style={{ color: '#a3a3a3' }}>
<p>
Hey, I&#39;m Martin Dvořák — a 17-year-old IT student based in the Czech Republic, specializing in network management and administration at <span className="text-pink-700"><a href="https://sssvt.cz">sssvt.cz</a></span>. I&#39;m a freshman and I have wanted to go to this school since 7th grade (2022) so I&#39;m happy I got in in 2025, the school is pretty cool so if you are in middle school and interested in IT, check it.
Hey, I&#39;m Martin Dvořák — a 17-year-old IT student based in the Czech Republic, specializing in network management and administration at <span className="text-purple-500"><a href="https://sssvt.cz">sssvt.cz</a></span>. I&#39;m a freshman and I have wanted to go to this school since 7th grade (2022) so I&#39;m happy I got in in 2025, the school is pretty cool so if you are in middle school and interested in IT, check it.
</p>
<p>
I&#39;m a passionate homelabber and developer heavily focused on self-hosting <i>literally everything</i>, writing code, and tinkering with Linux systems and retro hardware. Whether it&#39;s configuring Proxmox, reviving an old Thinkpad with Void Linux, or compiling Gentoo on my main rig, I&#39;m always looking at bazos to get more retro hardware.
</p>
<p>
In my free time I mostly spend time with my girl {'<'}3, also constructing some of my self hosted stuff, and also when I&#39;m in my gaming mood (which is kinda rare nowadays) I play terraria (around 1300hr playtime btw) and minecraft modpacks with mekanism. I also go to the gym around 3-5 times a week, running a PPL split focused on strength/powerlifting, my SBD total is 398kg (Squat:125kg, Bench:108kg, Deadlift:165kg) with a bodyweight of 73kg.<span className="cursor-blink"></span>
In my free time I mostly spend time with my girl {'<'}3, I also spend a lot of time constructing some of my self hosted stuff, and also when I&#39;m in my gaming mood (which is kinda rare nowadays) I play terraria (around 1300hr playtime btw) and minecraft modpacks with mekanism. I also go to the gym around 3-5 times a week, running a PPL split focused on strength/powerlifting and especially SBD, lately I&#39;ve also taken interest in Jiu-Jitsu lessons for self-defense.<span className="cursor-blink"></span>
</p>
</div>
</div>
@ -371,7 +409,7 @@ export default function Home() {
className="gitdxd"
icon="🐙"
name="GitDXD"
desc="Better Github"
desc="Best Git Hosting OAT"
/>
</div>
</div>
@ -388,25 +426,81 @@ export default function Home() {
className="softcraft"
icon="⛏️"
name="Softcraft"
desc="Play on my Minecraft Server!"
desc="Try my minecraft server"
/>
<ServiceButton
url="https://bluemap.dvorakmortonxd.dev"
className="bluemap"
icon="🗺️"
name="BlueMap"
desc="Live SoftCraft Map"
desc="SoftCraft Map"
/>
<ServiceButton
url="https://discord-sc.dvorakmortonxd.dev"
className="discord-sc"
icon={<Image src="/discord.svg" alt="Discord" width={28} height={28} />}
name="Discord"
desc="Join our community"
desc="Join SoftCraft Discord"
/>
</div>
</div>
</div>
{/* GitDXD Panel */}
<div className="gitdxd-section" style={{ marginTop: '20px' }}>
<div className="tui-panel">
<span className="tui-panel-label" style={{ color: '#0ea5e9' }}>├─ GITDXD.GIT</span>
<div style={{ padding: '24px 16px 16px' }}>
<h2 style={{ fontSize: '2.4rem', fontWeight: 'bold', color: '#0ea5e9', marginBottom: '16px', textAlign: 'center' }}>GitDXD</h2>
<p style={{ fontSize: '1.8rem', color: '#0ea5e9', fontWeight: '500', textAlign: 'center' }}>Self-hosted Git Instance</p>
<div style={{ marginTop: '16px', marginBottom: '16px', borderRadius: '8px', overflow: 'hidden', border: '1px solid rgba(14, 165, 233, 0.4)', boxShadow: '0 0 30px rgba(14, 165, 233, 0.15)' }}>
<Image
src="/gitdxd.webp"
alt="GitDXD Preview"
width={1280}
height={720}
style={{ width: '100%', height: 'auto', display: 'block' }}
/>
</div>
<div style={{ color: '#a3a3a3', marginTop: '12px', lineHeight: '1.6', textAlign: 'center' }}>
<p>My very own forgejo git instance, feel free to contact me if you wanna join but as of now I&#39;ve made it exclusively private for me and my friends. Visit it at <span className="text-purple-500"><a href="https://git.dvorakmortonxd.dev">git.dvorakmortonxd.dev</a></span>.<span className="cursor-blink"></span></p>
</div>
</div>
</div>
</div>
{/* Commits Panel */}
<div className="commits-section" style={{ marginTop: '16px' }}>
<div className="tui-panel">
<span className="tui-panel-label" style={{ color: 'var(--green)' }}>├─ CONTRIBUTIONS@GITDXD.GIT</span>
<div className="commits-content" style={{ padding: '24px 16px 16px' }}>
<ContributionHeatmap />
</div>
</div>
</div>
{/* RustyWolf Panel */}
<div className="rustywolf-section" style={{ marginTop: '20px' }}>
<div className="tui-panel">
<span className="tui-panel-label" style={{ color: '#f74c00' }}>├─ RUSTYWOLF.RS</span>
<div style={{ padding: '24px 16px 16px' }}>
<h2 style={{ fontSize: '2.4rem', fontWeight: 'bold', color: '#f74c00', marginBottom: '32px', textAlign: 'center' }}>Introducing RustyWolf</h2>
<div style={{ marginTop: '12px', marginBottom: '12px', borderRadius: '8px', overflow: 'hidden', border: '1px solid rgba(255, 255, 255, 0.4)', boxShadow: '0 0 30px rgba(255, 255, 255, 0.15)' }}>
<Image
src="/RustyWolfPreview.webp"
alt="RustyWolf Browser Preview"
width={1280}
height={720}
style={{ width: '100%', height: 'auto', display: 'block' }}
/>
</div>
<p style={{ fontSize: '1.8rem', color: '#f74c00', fontWeight: '500', textAlign: 'center' }}>What makes it so cool???</p>
<div style={{ color: '#a3a3a3', marginTop: '12px', lineHeight: '1.6' }}>
<p>A lightweight browser made in Rust with WebKitGTK. It&#39;s the successor to my previous project Venturesome, aiming to provide a fast and minimalist browsing experience. It&#39;s a perfect browser for old machines that struggle with modern browsers. Check it out at <span className="text-purple-500"><a href="https://git.dvorakmortonxd.dev/dvorakmortonxd/RustyWolf">GitDXD</a></span>.<span className="cursor-blink"></span></p>
</div>
</div>
</div>
</div>
</main>
{/* Projects */}
@ -415,6 +509,7 @@ export default function Home() {
<div className="subsection-wrapper">
<div className="subsection-panel">
<span className="subsection-panel-label">├─ TECH_LIST.JSON</span>
<h2 style={{ fontSize: '2rem', fontWeight: 'bold', textAlign: 'center', margin: '4px 0 20px', color: 'darkorange' }}>All my hardware equipment :)</h2>
<div className="project-grid">
{techProjects.map((project) => (
<div key={project.title} className="project-card">
@ -434,6 +529,7 @@ export default function Home() {
<div className="subsection-wrapper">
<div className="subsection-panel coding-panel">
<span className="subsection-panel-label">├─ PROJECTS.DOCX</span>
<h2 style={{ fontSize: '2rem', fontWeight: 'bold', textAlign: 'center', margin: '4px 0 20px', color: 'pink' }}>All the stuff I&#39;ve worked on :))</h2>
<div className="project-grid">
{codingProjects.map((project, idx) => (
<a
@ -457,27 +553,42 @@ export default function Home() {
{/* Friends Section */}
<div className="subsection-wrapper">
<div className="subsection-panel friends-panel">
<div className="subsection-panel friends-panel" style={{ backgroundColor: 'rgba(50, 205, 50, 0.05)', borderColor: 'rgba(50, 205, 50, 0.2)' }}>
<span className="subsection-panel-label">└─ FRIENDS.TSX</span>
<h2 style={{ fontSize: '2rem', fontWeight: 'bold', textAlign: 'center', margin: '4px 0 20px', color: 'limegreen' }}>Friend&#39;s websites and projects</h2>
<div className="services-buttons" style={{ gap: '1rem' }}>
{friends.map((friend, idx) => (
<ServiceButton
key={idx}
url={friend.realUrl || friend.url}
className="friend"
icon={<Image src={friend.img} alt={friend.name} width={68} height={68} className="friend-icon" style={{ borderRadius: '50%' }} />}
icon={<Image src={friend.img} alt={friend.name} width={68} height={68} className="friend-icon" style={{ borderRadius: '50%', filter: 'brightness(0) invert(75%) sepia(100%) hue-rotate(70deg) saturate(300%)' }} />}
name={friend.name}
desc={friend.desc}
/>
))}
</div>
<div style={{ width: '160px', height: '4px', backgroundColor: 'limegreen', margin: '16px auto 0', borderRadius: '2px', opacity: 0.8 }} />
<div style={{ marginTop: '32px', display: 'flex', flexDirection: 'column', alignItems: 'center', gap: '16px' }}>
<h3 style={{ fontSize: '1.5rem', color: 'limegreen', fontWeight: '600' }}>Quipee by Bukovina Filip & Vlk Tomáš</h3>
<div style={{ width: '100%', borderRadius: '8px', overflow: 'hidden', border: '1px solid rgba(50, 205, 50, 0.3)', boxShadow: '0 0 20px rgba(50, 205, 50, 0.1)' }}>
<Image src="/quipee.webp" alt="Quipee Thumbnail" width={1280} height={720} style={{ width: '100%', height: 'auto', display: 'block' }} />
</div>
<div style={{ display: 'flex', gap: '12px', flexWrap: 'wrap', justifyContent: 'center' }}>
<a href="https://quipee.me" target="_blank" rel="noopener noreferrer" style={{ backgroundColor: 'rgba(50, 205, 50, 0.1)', color: 'limegreen', padding: '6px 16px', borderRadius: '6px', fontSize: '1rem', fontWeight: '500', textDecoration: 'none', border: '1px solid rgba(50, 205, 50, 0.3)' }}>Web</a>
<a href="https://drive.google.com/drive/folders/1oi76JyWs6J84MUmCGV7GvtLUexXI8Jel?usp=share_link" target="_blank" rel="noopener noreferrer" style={{ backgroundColor: 'rgba(50, 205, 50, 0.1)', color: 'limegreen', padding: '6px 16px', borderRadius: '6px', fontSize: '1rem', fontWeight: '500', textDecoration: 'none', border: '1px solid rgba(50, 205, 50, 0.3)' }}>Android</a>
<a href="https://testflight.apple.com/join/hP2a1E5x" target="_blank" rel="noopener noreferrer" style={{ backgroundColor: 'rgba(50, 205, 50, 0.1)', color: 'limegreen', padding: '6px 16px', borderRadius: '6px', fontSize: '1rem', fontWeight: '500', textDecoration: 'none', border: '1px solid rgba(50, 205, 50, 0.3)' }}>IOS</a>
</div>
</div>
</div>
</div>
</section>
<footer className="footer">
<span className="footer-label">v1.6.7</span>
© 2025-2026 Martin Dvořák. All rights reserved (not really I dont care)
© 2025-2026 Martin Dvořák. All rights reserved (not really I dont care, just follow the GPL3.0 License)
</footer>
</div>
</>

View file

@ -24,7 +24,7 @@ export default function Softcraft() {
}
.header, .hero-panel, .tui-panel, .footer, .service-button, .social-button, .video-container, .hero-panel-label, .tui-panel-label, .footer-label {
background-image: linear-gradient(rgba(10, 10, 10, 0.85), rgba(10, 10, 10, 0.85)), url(/dirt.png) !important;
background-image: linear-gradient(rgba(10, 10, 10, 0.85), rgba(10, 10, 10, 0.85)), url(/dirt.webp) !important;
background-repeat: repeat !important;
background-size: 64px !important;
image-rendering: pixelated !important;
@ -32,7 +32,7 @@ export default function Softcraft() {
}
.terminal-box {
background-image: linear-gradient(rgba(0, 0, 0, 0.95), rgba(0, 0, 0, 0.95)), url(/dirt.png) !important;
background-image: linear-gradient(rgba(0, 0, 0, 0.95), rgba(0, 0, 0, 0.95)), url(/dirt.webp) !important;
background-repeat: repeat !important;
background-size: 64px !important;
image-rendering: pixelated !important;
@ -45,7 +45,7 @@ export default function Softcraft() {
width: '100vw',
height: '100vh',
zIndex: -1,
backgroundImage: 'url(/minecrafttest2.png)',
backgroundImage: 'url(/minecrafttest2.webp)',
backgroundSize: 'cover',
animation: 'mc-panorama-pan 120s linear infinite alternate',
filter: 'brightness(0.6)'
@ -82,7 +82,7 @@ export default function Softcraft() {
<div style={{ flexShrink: 0 }}>
<Image
src="/softcraft.png"
src="/softcraft.webp"
alt="Softcraft Logo"
width={128}
height={128}