This commit is contained in:
Dominik Klarkowski
2026-06-22 15:19:38 +02:00
parent 763321ec68
commit 4b3373869b
34 changed files with 268 additions and 143 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -20,6 +20,7 @@
--color-sand: var(--color-sand);
--font-sans: var(--font-geist-sans);
--font-mono: var(--font-geist-mono);
--font-display: var(--font-space-grotesk);
}
body {
@@ -27,3 +28,87 @@ body {
color: var(--color-fg);
font-family: var(--font-sans), Arial, Helvetica, sans-serif;
}
/* Ambient accent glow behind everything — modern dark-UI depth. */
body::before {
content: "";
position: fixed;
inset: 0;
z-index: -1;
pointer-events: none;
background:
radial-gradient(60rem 40rem at 15% -10%, color-mix(in oklab, var(--color-accent) 14%, transparent), transparent 70%),
radial-gradient(50rem 40rem at 100% 0%, color-mix(in oklab, var(--color-secondary) 45%, transparent), transparent 65%);
}
/* Display font for all headings. */
h1,
h2,
h3 {
font-family: var(--font-display), var(--font-sans), sans-serif;
letter-spacing: -0.015em;
}
/* Tabular figures for stats so numbers line up. */
.tabular-nums {
font-variant-numeric: tabular-nums;
}
/* Confine Leaflet's internal panes (z-index 4001000) to their own stacking
context so the map never overlaps the sticky navbar. */
.leaflet-container {
z-index: 0;
}
/* Unified button system. In @layer components so Tailwind utility overrides
(e.g. px-8, text-xs, w-full) still win over these base styles. */
@layer components {
.btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 0.375rem;
border-radius: 0.75rem;
padding: 0.5rem 1rem;
font-size: 0.875rem;
font-weight: 600;
line-height: 1.25rem;
white-space: nowrap;
cursor: pointer;
transition: transform 0.12s ease, background-color 0.15s ease,
border-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease,
filter 0.15s ease;
}
.btn:disabled {
opacity: 0.5;
cursor: not-allowed;
transform: none;
}
.btn-primary {
background: var(--color-accent);
color: #fff;
box-shadow: 0 6px 18px -6px color-mix(in oklab, var(--color-accent) 70%, transparent);
}
.btn-primary:hover:not(:disabled) {
filter: brightness(1.08);
transform: translateY(-1px);
}
.btn-primary:active:not(:disabled) {
filter: brightness(0.96);
transform: translateY(0);
}
.btn-secondary {
background: color-mix(in oklab, var(--color-surface) 55%, transparent);
border: 1px solid rgba(255, 255, 255, 0.12);
color: color-mix(in oklab, var(--color-fg) 88%, transparent);
-webkit-backdrop-filter: blur(8px);
backdrop-filter: blur(8px);
}
.btn-secondary:hover:not(:disabled) {
border-color: color-mix(in oklab, var(--color-accent) 55%, transparent);
color: var(--color-accent);
transform: translateY(-1px);
}
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 450 B

View File

@@ -1,36 +1,31 @@
import { signIn } from "@/auth";
import { Wordmark } from "@/components/wordmark";
export default function LoginPage() {
return (
<div className="flex min-h-screen flex-col items-center justify-center gap-10">
<div className="flex flex-col items-center gap-4">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img
src="/logo.svg"
alt="KNUR"
width={160}
height={160}
className="rounded-3xl shadow-2xl ring-2 ring-surface"
/>
<h1 className="text-3xl font-bold tracking-tight text-fg">KNUR</h1>
<p className="text-sm text-fg/50">
Książka Notowań Udźwigów i Rezultatów
</p>
</div>
<div className="flex min-h-screen flex-col items-center justify-center px-4">
<div className="flex w-full max-w-sm flex-col items-center gap-7 rounded-2xl border border-white/10 bg-surface/55 p-8 shadow-lg shadow-black/10 backdrop-blur-md">
<div className="flex flex-col items-center gap-4">
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src="/logo-bars.svg" alt="" width={51} height={48} className="h-12 w-auto" />
<Wordmark className="text-3xl" />
<p className="text-center text-sm text-fg/50">
Książka Notowań Udźwigów i Rezultatów
</p>
</div>
<form
action={async () => {
"use server";
await signIn("keycloak", { redirectTo: "/" });
}}
>
<button
type="submit"
className="rounded-lg bg-accent px-8 py-3 text-sm font-semibold text-white transition-opacity hover:opacity-90"
<form
className="w-full"
action={async () => {
"use server";
await signIn("keycloak", { redirectTo: "/" });
}}
>
Zaloguj
</button>
</form>
<button type="submit" className="btn btn-primary w-full px-8 py-3 text-base">
Zaloguj
</button>
</form>
</div>
</div>
);
}

View File

@@ -42,7 +42,7 @@ function buildGrid(maxDistKm: number): number[] {
function RouteMap({ activity }: { activity: RunningActivity }) {
const routePoints = activity.routePoints;
return (
<div className="col-span-2 row-span-3 min-h-[240px] overflow-hidden rounded-lg border border-muted/40">
<div className="col-span-2 row-span-3 min-h-[240px] overflow-hidden rounded-2xl border border-white/10">
{routePoints && routePoints.length > 0 ? (
<RouteMapSection points={routePoints} />
) : (

View File

@@ -34,7 +34,7 @@ export default async function RunningPage() {
<li key={activity._id.toString()}>
<Link
href={`/running/${activity._id.toString()}`}
className="flex items-center justify-between rounded-lg border border-muted/40 bg-surface p-4 transition-colors hover:border-accent/60"
className="flex items-center justify-between rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4 transition-colors hover:border-accent/60"
>
<div>
<div className="font-semibold text-fg">{activity.name}</div>

View File

@@ -22,7 +22,7 @@ export function GarminCredentialsForm({ savedEmail }: { savedEmail: string | nul
defaultValue={savedEmail ?? ""}
placeholder="twoj@email.com"
required
className="rounded-md border border-muted/40 bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg/30 focus:border-accent/60 focus:outline-none"
className="rounded-md border border-white/10 bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg/30 focus:border-accent/60 focus:outline-none"
/>
</div>
<div className="flex flex-col gap-1.5">
@@ -35,7 +35,7 @@ export function GarminCredentialsForm({ savedEmail }: { savedEmail: string | nul
type="password"
placeholder="••••••••"
required
className="rounded-md border border-muted/40 bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg/30 focus:border-accent/60 focus:outline-none"
className="rounded-md border border-white/10 bg-bg px-3 py-2 text-sm text-fg placeholder:text-fg/30 focus:border-accent/60 focus:outline-none"
/>
</div>
@@ -49,7 +49,7 @@ export function GarminCredentialsForm({ savedEmail }: { savedEmail: string | nul
<button
type="submit"
disabled={pending}
className="self-start rounded-md bg-accent px-4 py-2 text-sm font-semibold text-white transition-opacity hover:opacity-90 disabled:opacity-50"
className="btn btn-primary self-start"
>
{pending ? "Zapisywanie…" : "Zapisz"}
</button>

View File

@@ -15,7 +15,7 @@ function StatusRow({ label, ok, okLabel = "Skonfigurowano", failLabel = "Brak ko
failLabel?: string;
}) {
return (
<div className="flex items-center justify-between rounded-lg border border-muted/40 bg-surface p-4">
<div className="flex items-center justify-between rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4">
<span className="text-fg">{label}</span>
{ok ? (
<span className="flex items-center gap-1.5 text-sm text-fg/70">
@@ -67,14 +67,14 @@ export default async function SettingsPage() {
<section className="flex flex-col gap-3">
<h2 className="text-lg font-semibold text-fg">Konto Garmin Connect</h2>
<div className="rounded-lg border border-muted/40 bg-surface p-4">
<div className="rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4">
<GarminCredentialsForm savedEmail={garminCreds?.email ?? null} />
</div>
</section>
<section className="flex flex-col gap-3">
<h2 className="text-lg font-semibold text-fg">Synchronizacja z Garmin</h2>
<div className="flex items-center justify-between rounded-lg border border-muted/40 bg-surface p-4">
<div className="flex items-center justify-between rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4">
<span className="text-sm text-fg/70">
{lastSyncAt
? `Ostatnia synchronizacja: ${formatDate(lastSyncAt)}`

View File

@@ -55,7 +55,7 @@ export default async function StrengthWorkoutPage({
{exercisesWithHistory.map(({ exercise }, index) => {
const e1rm = exerciseE1rm(exercise);
return (
<div key={index} className="flex flex-col gap-2 rounded-lg border border-muted/40 bg-surface px-3 py-2.5">
<div key={index} className="flex flex-col gap-2 rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md px-3 py-2.5">
<p className="text-xs font-semibold text-fg">{exercise.name}</p>
{exercise.notes ? <p className="text-xs text-fg/50 italic">{exercise.notes}</p> : null}
<div className="flex flex-wrap gap-1">

View File

@@ -18,12 +18,12 @@ export function ImportForm() {
rows={16}
required
placeholder={"Trening A\nWednesday, 10 June 2026 at 06:40\n\nDeadlift (Barbell)\nSet 1: 80 kg × 8\n..."}
className="w-full rounded-md border border-muted/40 bg-surface p-3 font-mono text-sm text-fg placeholder:text-fg/30 focus:border-accent focus:outline-none"
className="w-full rounded-md border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-3 font-mono text-sm text-fg placeholder:text-fg/30 focus:border-accent focus:outline-none"
/>
<button
type="submit"
disabled={pending}
className="self-start rounded-md bg-accent px-4 py-2 text-sm font-semibold text-fg transition-opacity hover:opacity-90 disabled:opacity-50"
className="btn btn-primary self-start"
>
{pending ? "Importowanie..." : "Importuj"}
</button>

View File

@@ -31,7 +31,7 @@ export default async function StrengthPage() {
</div>
<Link
href="/strength/import"
className="flex items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-semibold text-fg transition-opacity hover:opacity-90"
className="btn btn-primary"
>
<Plus size={16} />
Importuj
@@ -52,7 +52,7 @@ export default async function StrengthPage() {
<li key={workout._id.toString()}>
<Link
href={`/strength/${workout._id.toString()}`}
className="flex items-center justify-between rounded-lg border border-muted/40 bg-surface p-4 transition-colors hover:border-accent/60"
className="flex items-center justify-between rounded-2xl border border-white/10 bg-surface/55 shadow-lg shadow-black/10 backdrop-blur-md p-4 transition-colors hover:border-accent/60"
>
<div>
<div className="font-semibold text-fg">{workout.name}</div>