feat: GutscheinNest als Name mit neuem App-Icon, Favicon und Designphilosophie

This commit is contained in:
opencode committed 2026-10-18 19:13:37 +02:00
1 parent 36c54cfa1c
commit ef8662130c
9 files changed
+19 -6

No files matched your search

+1 -1
View File
@@ -1,4 +1,4 @@
# Gutscheintracker
# GutscheinNest
Private Gutscheinverwaltung für einen Haushalt (Next.js + SQLite + Prisma). Gemeinsamer Bestand, Anmeldung per Passwort oder SSO (OIDC), Erinnerungen per Mail/Telegram.
Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

+2 -2
View File
@@ -35,7 +35,7 @@ export default function Shell({ children }: { children: ReactNode }) {
>
G
</span>
Gutscheintracker
GutscheinNest
</p>
<nav aria-label="Hauptmenü" className="mt-7 flex flex-col gap-1">
{NAV.map((item) => (
@@ -71,7 +71,7 @@ export default function Shell({ children }: { children: ReactNode }) {
>
G
</span>
Gutscheintracker
GutscheinNest
</p>
<button
type="button"
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

+1 -1
View File
@@ -5,7 +5,7 @@ import "./globals.css";
const geist = Geist({ subsets: ["latin"], display: "swap" });
export const metadata = {
title: "Gutscheintracker",
title: "GutscheinNest",
description: "Gutscheine verwalten und rechtzeitig an das Ablaufdatum erinnern.",
};
+1 -1
View File
@@ -63,7 +63,7 @@ export default function LoginPage() {
>
G
</span>
Gutscheintracker
GutscheinNest
</p>
<section
aria-labelledby="login-title"
Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

+13
View File
@@ -0,0 +1,13 @@
# Hearth Geometry
A design philosophy for the GutscheinNest identity.
Space speaks before words do. The composition rests on a single, calm field: a deep green plane with softly rounded corners, generous and unhurried. Within it, one pale form carries the entire meaning — a ticket whose top edge rises into a shallow gable, a roofline folded out of paper. The roof is never drawn as a separate house; it emerges from the ticket itself, the way shelter emerges from what a family shares. Negative space is the mortar: wide margins on every side let the mark breathe, and nothing touches the edges.
Color is material, not decoration. A pine green field holds the warmth of a forest clearing at dusk, steady and trustworthy. Against it sits a single warm-white shape, the color of paper kept in a drawer for a special occasion. No gradients, no shadows, no glow — flatness is honesty here. The palette stays at two tones so the mark survives a favicon, a monochrome print, a glance from across the room. Every pixel earns its place through restraint, the product of painstaking reduction until nothing can be removed without losing meaning.
Scale follows a quiet hierarchy. The ticket occupies roughly two thirds of the field, large enough to read as an object held in the hand, small enough to feel kept and protected. Two circular notches bite into its flanks — the classic ticket punch — giving rhythm to the silhouette and anchoring the eye left and right. A fine dashed line runs vertically through the form, suggesting the perforation between keeping and redeeming. These details are drawn with master-level precision: crisp arcs, consistent stroke rhythm, geometry a craftsman would measure twice.
Typography, where it appears alongside the mark, whispers. A single humanist sans in sentence case carries the name; the icon itself needs no letters. The letterforms are never squeezed, stretched, or outlined — they stand apart from the symbol with the confidence of something that does not need to explain itself.
The whole is the result of countless refinements: corner radii tuned until the square feels held rather than drawn, the gable pitched until it reads as both roof and ticket, the notch radius matched to the field's own curve. It looks effortless because every decision was labored over — the unmistakable signature of work done at the very top of the craft.
+1 -1
View File
@@ -13,4 +13,4 @@ export async function middleware(req: NextRequest) {
if (token && (await verifySession(token))) return NextResponse.next();
return NextResponse.redirect(new URL("/login", req.url));
}
export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"] };
export const config = { matcher: ["/((?!_next/static|_next/image|favicon.ico|icon.png|apple-icon.png|manifest.webmanifest|robots.txt).*)"] };