default to dark mode, refresh Right now text, CSS barbell gym icons

This commit is contained in:
Martin Dvořák 2026-09-30 21:37:56 +00:00
commit 4a8cac689b
10 changed files with 101 additions and 66 deletions

View file

@ -7,8 +7,9 @@ import { useServerInsertedHTML } from "next/navigation";
// are applied without a flash. It is injected with useServerInsertedHTML so the
// <script> lives in the SSR HTML stream instead of inside the React tree —
// React 19 logs an error for script tags rendered by components on the client.
// Anything unrecognised falls back to the defaults: web + light.
const INIT_SCRIPT = `(function(){try{var t=localStorage.getItem('theme');document.documentElement.setAttribute('data-theme',t==='skeuo'?'skeuo':'web');var s=localStorage.getItem('scheme');document.documentElement.setAttribute('data-scheme',s==='dark'?'dark':'light');}catch(e){}})();`;
// Anything unrecognised falls back to the defaults: web + dark. Dark is the
// default scheme; only an explicit stored "light" switches it off.
const INIT_SCRIPT = `(function(){try{var t=localStorage.getItem('theme');document.documentElement.setAttribute('data-theme',t==='skeuo'?'skeuo':'web');var s=localStorage.getItem('scheme');document.documentElement.setAttribute('data-scheme',s==='light'?'light':'dark');}catch(e){}})();`;
export default function ThemeScript() {
// useServerInsertedHTML can fire several times during a single render pass;

View file

@ -121,15 +121,15 @@ function Services() {
function Gym() {
const lifts = [
{ icon: "/squat.svg", label: "SQUAT", weight: "125kg", date: "5.1.2025" },
{ icon: "/bench.svg", label: "BENCH", weight: "111kg", date: "29.5.2026" },
{ icon: "/deadlift.svg", label: "DEADLIFT", weight: "165kg", date: "17.12.2024" },
{ icon: "squat", label: "SQUAT", weight: "125kg", date: "5.1.2025" },
{ icon: "bench", label: "BENCH", weight: "111kg", date: "29.5.2026" },
{ icon: "deadlift", label: "DEADLIFT", weight: "165kg", date: "17.12.2024" },
];
return (
<div className="gym-grid">
{lifts.map((l) => (
<div key={l.label} className="gym-item">
<Image src={l.icon} alt={l.label} width={48} height={48} className="gym-icon" />
<span className={`gym-icon gym-icon--${l.icon}`} aria-hidden="true" />
<div className="gym-label">{l.label}</div>
<div className="gym-weight">{l.weight}</div>
<div className="gym-date">{l.date}</div>
@ -238,11 +238,9 @@ export default function WebLayout() {
<article id="now" className="web-tile glass">
<h3 className="web-tile-title">Right now</h3>
<p className="web-tile-text">
I&#39;m currently hosting an SMP (dm me on discord). Also I&#39;m pretty much
cooking daily, because im bulking through out the non-summer seasons. And me
and my pal <a href="https://skopec.dev">Pepa</a> are working on an education
app so we can study more efficiently, It&#39;s called{" "}
<a href="https://git.dvorakmortonxd.dev/edu/maturita.c">maturita.c</a>!
I left the maturita.c project to focus on my proxmox server (just popped in
another 1.7TB hdd upgrade, 3 small hdds from ewaste laptops and I just
ziplocked it into place and connected it lmao)
</p>
</article>

View file

@ -301,25 +301,19 @@ function GymApp() {
<div className="app-pad">
<div className="gym-grid">
<div className="gym-item">
<Image src="/squat.svg" alt="Squat" width={48} height={48} className="gym-icon" />
<span className="gym-icon gym-icon--squat" aria-hidden="true" />
<div className="gym-label">SQUAT</div>
<div className="gym-weight">125kg</div>
<div className="gym-date">5.1.2025</div>
</div>
<div className="gym-item">
<Image src="/bench.svg" alt="Bench" width={48} height={48} className="gym-icon" />
<span className="gym-icon gym-icon--bench" aria-hidden="true" />
<div className="gym-label">BENCH</div>
<div className="gym-weight">111kg</div>
<div className="gym-date">29.5.2026</div>
</div>
<div className="gym-item">
<Image
src="/deadlift.svg"
alt="Deadlift"
width={48}
height={48}
className="gym-icon"
/>
<span className="gym-icon gym-icon--deadlift" aria-hidden="true" />
<div className="gym-label">DEADLIFT</div>
<div className="gym-weight">165kg</div>
<div className="gym-date">17.12.2024</div>

View file

@ -4,13 +4,13 @@ import { useSyncExternalStore } from "react";
/**
* Light/dark appearance for the web theme. Persisted in `localStorage.scheme`
* and applied pre-paint as `<html data-scheme>` so there is no flash. Light is
* the default.
* and applied pre-paint as `<html data-scheme>` so there is no flash. Dark is
* the default; the user's choice is remembered once they toggle.
*/
export type ColorScheme = "light" | "dark";
const EVENT = "scheme-change";
export const DEFAULT_SCHEME: ColorScheme = "light";
export const DEFAULT_SCHEME: ColorScheme = "dark";
function subscribe(callback: () => void) {
window.addEventListener(EVENT, callback);
@ -22,9 +22,9 @@ function subscribe(callback: () => void) {
}
function getSnapshot(): ColorScheme {
return document.documentElement.getAttribute("data-scheme") === "dark"
? "dark"
: "light";
return document.documentElement.getAttribute("data-scheme") === "light"
? "light"
: "dark";
}
function getServerSnapshot(): ColorScheme {

View file

@ -357,7 +357,9 @@ html[data-theme="web"] body {
display: grid;
grid-template-columns: 1.5fr 1fr;
gap: 20px;
align-items: stretch;
/* Don't stretch the shorter "Right now" tile to the taller Gym tile's
height — that left a big empty gap under its text. */
align-items: start;
}
.web-tile {
display: flex;
@ -373,7 +375,8 @@ html[data-theme="web"] body {
color: var(--accent);
}
.web-tile-text {
font-size: 0.9rem;
font-size: 1.12rem;
line-height: 1.7;
color: var(--web-muted);
}
.web-tile-note {
@ -728,10 +731,72 @@ html[data-theme="web"][data-scheme="dark"] .social-icon {
border-color: var(--accent-line);
transform: translateY(-2px);
}
/* Custom CSS barbell icons (the squat/bench/deadlift SVGs are gone). Same
barbell, drawn from currentColor so it adapts to the theme; more plates per
side = heavier lift (bench 1, squat 2, deadlift 3). */
.gym-icon {
width: 100%;
max-width: 42px;
height: auto;
position: relative;
display: block;
width: 54px;
height: 30px;
}
.gym-icon::before {
/* the bar */
content: "";
position: absolute;
left: 0;
right: 0;
top: 50%;
height: 3px;
border-radius: 2px;
background: currentColor;
opacity: 0.55;
transform: translateY(-50%);
}
.gym-icon::after {
/* the weight plates */
content: "";
position: absolute;
inset: 0;
background-repeat: no-repeat;
opacity: 0.85;
}
.gym-icon--bench::after {
background-image:
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor);
background-size: 7px 24px, 7px 24px;
background-position: 9px center, calc(100% - 16px) center;
}
.gym-icon--squat::after {
background-image:
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor);
background-size: 6px 18px, 7px 26px, 6px 18px, 7px 26px;
background-position:
5px center,
12px center,
calc(100% - 11px) center,
calc(100% - 19px) center;
}
.gym-icon--deadlift::after {
background-image:
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor),
linear-gradient(currentColor, currentColor);
background-size: 6px 16px, 6px 22px, 7px 28px, 6px 16px, 6px 22px, 7px 28px;
background-position:
3px center,
9px center,
16px center,
calc(100% - 9px) center,
calc(100% - 15px) center,
calc(100% - 23px) center;
}
.gym-label {
font-size: 0.66rem;