From 7c85022686e9203ec9134ab5cfb41bf3b43944cc Mon Sep 17 00:00:00 2001 From: Priec Date: Tue, 2 Jun 2026 19:56:08 +0200 Subject: [PATCH] light mode --- static/css/ascii.css | 23 +-- static/css/site.css | 366 ++++++++++++++++++++++++++++++++++++------- 2 files changed, 327 insertions(+), 62 deletions(-) diff --git a/static/css/ascii.css b/static/css/ascii.css index 876d0b1..cfedb9b 100644 --- a/static/css/ascii.css +++ b/static/css/ascii.css @@ -12,6 +12,7 @@ - tints the dense characters rust-orange with text-shadow + glow - adds a CRT scanline overlay - disables the animation under prefers-reduced-motion + - swaps the tint for a soft sepia wash in light mode (paper & ink feel) ========================================================================== */ /* Full-screen ASCII mountain top layer ----------------------------------- */ @@ -32,13 +33,14 @@ font-size: max(0.35vw, 0.695svh); line-height: 1.0; letter-spacing: 0; - color: #f4a26b; - text-shadow: 0 0 8px rgba(183, 65, 14, 0.35); - opacity: 0.45; + color: var(--tp-mountain-color, #f4a26b); + text-shadow: 0 0 8px var(--tp-mountain-glow, rgba(183, 65, 14, 0.35)); + opacity: var(--tp-mountain-opacity, 0.45); white-space: pre; background: transparent; overflow: hidden; user-select: none; + transition: color 250ms ease, opacity 250ms ease, text-shadow 250ms ease; } /* CRT scanlines overlay - a thin moving line every 2px. Faint so it doesn't @@ -64,10 +66,13 @@ 100% { background-position: 0 6px; } } -/* Light theme: dim the background, drop the glow, switch to dark text. */ +/* ---------- Light theme: faded ink wash on paper ------------------------ + In winter mode the ASCII becomes a soft sepia watermark — a hint of + "topography" rather than a glowing graphic. The scanlines swap to + light-on-dark so they still add texture without darkening the page. */ :root[data-theme="winter"] .tp-mountain-bg { - opacity: 0.20; - color: #2a1810; + opacity: 0.12; /* much fainter than the dark mode rust */ + color: #6b5236; /* warm sepia, harmonizes with cream bg */ text-shadow: none; mix-blend-mode: multiply; } @@ -77,10 +82,10 @@ to bottom, transparent 0, transparent 2px, - rgba(255, 255, 255, 0.12) 2px, - rgba(255, 255, 255, 0.12) 3px + rgba(28, 25, 23, 0.05) 2px, + rgba(28, 25, 23, 0.05) 3px ); - mix-blend-mode: screen; + mix-blend-mode: multiply; } /* Reduced motion: keep the first frame static, no scanline drift. */ diff --git a/static/css/site.css b/static/css/site.css index a5b4d29..69adfe5 100644 --- a/static/css/site.css +++ b/static/css/site.css @@ -21,30 +21,128 @@ html { } } -/* ---------- Theme (default to dark) -------------------------------------- */ +/* ---------- Theme tokens ------------------------------------------------- + Dark (night) is the default. The `[data-theme="winter"]` block redefines + the same tokens for the light theme. Everything below reads from these. */ :root { color-scheme: dark light; - --tp-accent: #b7410e; - --tp-accent-fg: #fff5f0; - --tp-grid-line: rgba(63, 63, 70, 0.35); - --tp-hero-from: #0b0b0f; - --tp-hero-to: #18181b; - --tp-text-outline: rgba(0, 0, 0, 0.9); + + /* Brand (rust) */ + --tp-accent: #b7410e; /* primary accent */ + --tp-accent-strong: #d24e15; /* hover/active */ + --tp-accent-fg: #fff5f0; /* text-on-accent */ + --tp-accent-soft: rgba(183, 65, 14, 0.12); + --tp-accent-glow: rgba(183, 65, 14, 0.35); + + /* Surfaces (dark) */ + --tp-bg: #09090b; /* page bg */ + --tp-bg-elev: #18181b; /* raised surface */ + --tp-bg-soft: rgba(24, 24, 27, 0.5); + --tp-bg-card: rgba(24, 24, 27, 0.5); + --tp-bg-card-hover: rgba(24, 24, 27, 0.78); + --tp-bg-nav: rgba(9, 9, 11, 0.65); + --tp-bg-mobile: rgba(9, 9, 11, 0.95); + --tp-bg-section: rgba(24, 24, 27, 0.3); /* alt section tint */ + --tp-bg-code: #0b0b0f; + + /* Text (dark) */ + --tp-fg: #fafafa; /* primary text */ + --tp-fg-strong: #ffffff; + --tp-fg-secondary: #d4d4d8; /* body */ + --tp-fg-muted: #a1a1aa; + --tp-fg-subtle: #71717a; + --tp-fg-code: #f4f4f5; + + /* Borders (dark) */ + --tp-border: rgba(63, 63, 70, 0.5); + --tp-border-strong: rgba(63, 63, 70, 0.7); + --tp-border-section:rgba(63, 63, 70, 0.4); + + /* Hero / grid (dark) */ + --tp-grid-line: rgba(63, 63, 70, 0.35); + --tp-hero-from: #0b0b0f; + --tp-hero-to: #18181b; + --tp-text-outline: rgba(0, 0, 0, 0.9); + --tp-hero-glow-a: rgba(183, 65, 14, 0.10); + --tp-hero-glow-b: rgba(126, 231, 135, 0.05); + + /* Mountain background (dark — rust on black) */ + --tp-mountain-color: #f4a26b; + --tp-mountain-glow: rgba(183, 65, 14, 0.35); + --tp-mountain-opacity:0.45; + + /* Shadows (dark — soft + deep) */ + --tp-card-shadow: 0 1px 0 rgba(255, 255, 255, 0.02) inset, + 0 12px 24px -16px rgba(0, 0, 0, 0.6); + --tp-card-shadow-hover: + 0 1px 0 rgba(255, 255, 255, 0.04) inset, + 0 18px 36px -18px rgba(0, 0, 0, 0.7); } +/* Light theme — warm paper. We swap to a stone (warm-gray) palette so the + text and surfaces harmonize with the rust accent instead of fighting it. */ :root[data-theme="winter"] { - --tp-accent: #93330c; - --tp-accent-fg: #fff5f0; - --tp-grid-line: rgba(228, 228, 231, 0.7); - --tp-hero-from: #fafafa; - --tp-hero-to: #f4f4f5; - --tp-text-outline: rgba(255, 255, 255, 0.95); + /* Brand — slightly darker rust so it has bite on a light bg */ + --tp-accent: #9a3a0e; + --tp-accent-strong: #7f2f08; + --tp-accent-fg: #fff7ed; + --tp-accent-soft: rgba(154, 58, 14, 0.08); + --tp-accent-glow: rgba(154, 58, 14, 0.0); + + /* Surfaces (warm off-white, not stark) */ + --tp-bg: #fbfaf7; /* page bg, slight cream */ + --tp-bg-elev: #ffffff; /* cards */ + --tp-bg-soft: rgba(255, 255, 255, 0.7); + --tp-bg-card: #ffffff; + --tp-bg-card-hover: #ffffff; + --tp-bg-nav: rgba(255, 255, 255, 0.78); + --tp-bg-mobile: rgba(255, 255, 255, 0.97); + --tp-bg-section: #f3f1ec; /* warm section alt */ + --tp-bg-code: #0b0b0f; /* keep code blocks dark in both themes */ + + /* Text (warm dark — stone, not zinc, so it doesn't look like a science lab) */ + --tp-fg: #1c1917; /* primary (stone-900) */ + --tp-fg-strong: #0c0a09; /* stone-950 */ + --tp-fg-secondary: #44403c; /* stone-700 */ + --tp-fg-muted: #57534e; /* stone-600 */ + --tp-fg-subtle: #78716c; /* stone-500 */ + --tp-fg-code: #f4f4f5; + + /* Borders (warm taupe) */ + --tp-border: rgba(214, 211, 209, 0.9); /* stone-300 */ + --tp-border-strong: rgba(168, 162, 158, 0.8); /* stone-400 */ + --tp-border-section:rgba(214, 211, 209, 0.65); + + /* Hero / grid (warm, very subtle) */ + --tp-grid-line: rgba(180, 130, 80, 0.14); + --tp-hero-from: #fbfaf7; + --tp-hero-to: #f5f3ee; + --tp-text-outline: rgba(255, 255, 255, 0.95); + --tp-hero-glow-a: rgba(154, 58, 14, 0.07); + --tp-hero-glow-b: rgba(120, 140, 90, 0.05); + + /* Mountain — very subtle, like a faded ink wash on paper */ + --tp-mountain-color: #8a6a44; /* warm sepia */ + --tp-mountain-glow: rgba(138, 106, 68, 0); + --tp-mountain-opacity:0.10; + + /* Shadows (soft, warm-tinted, like a printed page) */ + --tp-card-shadow: 0 1px 0 rgba(255, 255, 255, 1) inset, + 0 1px 2px rgba(28, 25, 23, 0.04), + 0 8px 24px -12px rgba(28, 25, 23, 0.10); + --tp-card-shadow-hover: + 0 1px 0 rgba(255, 255, 255, 1) inset, + 0 1px 2px rgba(28, 25, 23, 0.05), + 0 14px 32px -14px rgba(154, 58, 14, 0.18); } /* ---------- Body --------------------------------------------------------- */ body { font-family: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif; font-feature-settings: 'cv11', 'ss01', 'ss03'; + background-color: var(--tp-bg); + color: var(--tp-fg); + transition: background-color 200ms ease, color 200ms ease; } /* ---------- View Transitions (progressive enhancement) ------------------ */ @@ -80,6 +178,19 @@ body { 1px 1px 0 var(--tp-text-outline), 0 2px 16px rgba(0, 0, 0, 0.9); } +:root[data-theme="winter"] .tp-hero h1, +:root[data-theme="winter"] .tp-hero p { + text-shadow: + 0 -1px 0 var(--tp-text-outline), + 1px 0 0 var(--tp-text-outline), + 0 1px 0 var(--tp-text-outline), + -1px 0 0 var(--tp-text-outline), + -1px -1px 0 var(--tp-text-outline), + 1px -1px 0 var(--tp-text-outline), + -1px 1px 0 var(--tp-text-outline), + 1px 1px 0 var(--tp-text-outline), + 0 2px 12px rgba(154, 58, 14, 0.10); +} .tp-hero::before { content: ""; @@ -96,8 +207,11 @@ body { z-index: -1; opacity: 0.5; /* subtle grid, not a wall */ } +:root[data-theme="winter"] .tp-hero::before { + opacity: 0.7; /* show a touch more on paper */ +} -/* Subtle floating code lines in the hero, behind the content */ +/* Subtle floating glow in the hero, behind the content */ .tp-hero-glow { position: absolute; inset: 0; @@ -105,43 +219,38 @@ body { z-index: -1; opacity: 0.6; background: - radial-gradient(circle at 15% 30%, rgba(183, 65, 14, 0.08), transparent 35%), - radial-gradient(circle at 85% 70%, rgba(126, 231, 135, 0.05), transparent 35%); + radial-gradient(circle at 15% 30%, var(--tp-hero-glow-a), transparent 35%), + radial-gradient(circle at 85% 70%, var(--tp-hero-glow-b), transparent 35%); } /* ---------- Glass nav ---------------------------------------------------- */ .tp-nav { - background: rgba(9, 9, 11, 0.65); + background: var(--tp-bg-nav); backdrop-filter: saturate(160%) blur(12px); -webkit-backdrop-filter: saturate(160%) blur(12px); - border-bottom: 1px solid rgba(63, 63, 70, 0.4); -} -:root[data-theme="winter"] .tp-nav { - background: rgba(255, 255, 255, 0.7); - border-bottom-color: rgba(228, 228, 231, 0.7); + border-bottom: 1px solid var(--tp-border); + transition: background 200ms ease, border-color 200ms ease; } /* ---------- Feature cards ------------------------------------------------ */ .tp-card { position: relative; - background: rgba(24, 24, 27, 0.5); - border: 1px solid rgba(63, 63, 70, 0.5); + background: var(--tp-bg-card); + border: 1px solid var(--tp-border); border-radius: 1rem; padding: 1.5rem; - transition: border-color 200ms ease, transform 200ms ease, background 200ms ease; + box-shadow: var(--tp-card-shadow); + transition: border-color 200ms ease, transform 200ms ease, + background 200ms ease, box-shadow 200ms ease; } .tp-card:hover { border-color: rgba(183, 65, 14, 0.6); - background: rgba(24, 24, 27, 0.75); + background: var(--tp-bg-card-hover); transform: translateY(-2px); -} -:root[data-theme="winter"] .tp-card { - background: rgba(255, 255, 255, 0.6); - border-color: rgba(228, 228, 231, 0.8); + box-shadow: var(--tp-card-shadow-hover); } :root[data-theme="winter"] .tp-card:hover { - background: rgba(255, 255, 255, 0.9); - border-color: rgba(183, 65, 14, 0.4); + border-color: rgba(154, 58, 14, 0.4); } .tp-card-icon { @@ -151,11 +260,14 @@ body { width: 2.5rem; height: 2.5rem; border-radius: 0.75rem; - background: rgba(183, 65, 14, 0.12); + background: var(--tp-accent-soft); color: var(--tp-accent); - border: 1px solid rgba(183, 65, 14, 0.25); + border: 1px solid var(--tp-accent-glow); margin-bottom: 1rem; } +:root[data-theme="winter"] .tp-card-icon { + border-color: rgba(154, 58, 14, 0.18); +} /* ---------- Code blocks (kitchen sink — hljs + custom) ------------------ */ .tp-code { @@ -165,13 +277,19 @@ body { tab-size: 4; } .tp-code pre { - background: #0b0b0f; - border: 1px solid rgba(63, 63, 70, 0.5); + background: var(--tp-bg-code); + border: 1px solid var(--tp-border); border-radius: 0.75rem; padding: 1.25rem 1.5rem; overflow-x: auto; margin: 0; } +:root[data-theme="winter"] .tp-code pre { + /* keep the code panel a little warmer on light pages, like a printed + code listing on cream paper */ + border-color: rgba(0, 0, 0, 0.12); + box-shadow: 0 12px 28px -16px rgba(28, 25, 23, 0.35); +} .tp-code pre code.hljs { background: transparent; padding: 0; @@ -185,17 +303,18 @@ body { font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.75rem; font-weight: 500; - border: 1px solid rgba(63, 63, 70, 0.7); + border: 1px solid var(--tp-border-strong); border-bottom-width: 2px; border-radius: 0.375rem; background: rgba(39, 39, 42, 0.6); - color: #f4f4f5; + color: var(--tp-fg-code); line-height: 1; } :root[data-theme="winter"] .tp-kbd { - background: #fff; - color: #18181b; - border-color: #d4d4d8; + background: #ffffff; + color: #1c1917; + border-color: #d6d3d1; + box-shadow: 0 1px 0 rgba(28, 25, 23, 0.04); } /* ---------- Terminal window wrapper -------------------------------------- */ @@ -209,6 +328,12 @@ body { 0 18px 36px -18px rgba(0, 0, 0, 0.45); overflow: hidden; } +:root[data-theme="winter"] .tp-terminal { + box-shadow: + 0 0 0 1px rgba(154, 58, 14, 0.18), + 0 24px 48px -20px rgba(154, 58, 14, 0.22), + 0 12px 24px -16px rgba(28, 25, 23, 0.10); +} .tp-terminal::after { content: ""; position: absolute; @@ -224,6 +349,15 @@ body { ); /* darken only the top + bottom strips, leave the middle transparent so the body ASCII art shows through the terminal content */ } +:root[data-theme="winter"] .tp-terminal::after { + background: linear-gradient( + to bottom, + rgba(255, 255, 255, 0.10) 0%, + rgba(255, 255, 255, 0) 18%, + rgba(255, 255, 255, 0) 82%, + rgba(255, 255, 255, 0.10) 100% + ); +} /* ---------- Selection --------------------------------------------------- */ ::selection { @@ -242,27 +376,153 @@ body { ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { - background: rgba(63, 63, 70, 0.6); + background: var(--tp-border-strong); border-radius: 999px; border: 2px solid transparent; background-clip: padding-box; } -::-webkit-scrollbar-thumb:hover { background-color: rgba(82, 82, 91, 0.8); background-clip: padding-box; } +::-webkit-scrollbar-thumb:hover { + background-color: var(--tp-fg-subtle); + background-clip: padding-box; +} /* ---------- No-FOUC theme flash ----------------------------------------- */ html:not([data-theme]) body { background: #09090b; } -:root[data-theme="winter"] body { background: #fafafa; } /* ---------- Alpine x-cloak (prevents flash of un-initialised content) --- */ [x-cloak] { display: none !important; } -/* ---------- DaisyUI overrides for our theme ----------------------------- */ -/* Bring DaisyUI's primary to our accent so .btn-primary etc. look on-brand. */ -[data-theme="night"] { - --p: 28 70% 36%; - --pc: 0 0% 100%; - --b1: 240 5% 8%; - --b2: 240 4% 12%; - --b3: 240 4% 16%; - --bc: 0 0% 96%; +/* ========================================================================== + THEME-AWARE TAILWIND OVERRIDES + -------------------------------------------------------------------------- + The HTML uses hardcoded `text-zinc-*`, `bg-zinc-*`, `border-zinc-*` etc. + (so the source reads like a normal dark-mode-first site). In light mode + we transparently remap those zinc slots to our warm stone palette. + This block has higher selector specificity (`:root[data-theme=...] .foo`) + than the Tailwind utility class on its own, so it wins without `!important`. + ========================================================================== */ +:root[data-theme="winter"] { + + /* ---- DaisyUI body tokens ---------------------------------------------- + daisyUI 4 uses OKLCH under the hood (`oklch(var(--b1) / .N)`); our custom + HSL-flavoured values don't parse, so `bg-base-100` would resolve to + transparent. We override the class directly with our token-driven colour. */ + .bg-base-100 { background-color: var(--tp-bg); } + .text-base-content { color: var(--tp-fg); } + + /* ---- text ---- */ + .text-zinc-50 { color: #0c0a09; } + .text-zinc-100 { color: #1c1917; } + .text-zinc-200 { color: #292524; } + .text-zinc-300 { color: #44403c; } + .text-zinc-400 { color: #57534e; } + .text-zinc-500 { color: #78716c; } + .text-zinc-600 { color: #57534e; } + .text-zinc-700 { color: #d6d3d1; } /* dividers + rare text */ + .text-zinc-800 { color: #e7e5e4; } + .text-zinc-900 { color: #ffffff; } + .text-zinc-950 { color: #ffffff; } + .text-white { color: #1c1917; } + + /* ---- backgrounds ---- */ + .bg-zinc-50 { background-color: #fafaf9; } + .bg-zinc-100 { background-color: #f5f5f4; } + .bg-zinc-200 { background-color: #e7e5e4; } + .bg-zinc-300 { background-color: #d6d3d1; } + .bg-zinc-400 { background-color: #a8a29e; } + .bg-zinc-500 { background-color: #78716c; } + .bg-zinc-600 { background-color: #57534e; } + .bg-zinc-700 { background-color: #d6d3d1; } + .bg-zinc-800 { background-color: #e7e5e4; } + .bg-zinc-900 { background-color: #ffffff; } + .bg-zinc-900\/40 { background-color: rgba(255, 255, 255, 0.65); } + .bg-zinc-900\/50 { background-color: rgba(255, 255, 255, 0.75); } + .bg-zinc-900\/60 { background-color: rgba(255, 255, 255, 0.85); } + .bg-zinc-950 { background-color: #ffffff; } + .bg-zinc-950\/30 { background-color: #f3f1ec; } /* section alt */ + .bg-zinc-950\/40 { background-color: #f5f3ee; } /* trust strip */ + .bg-zinc-950\/50 { background-color: #ffffff; } + .bg-zinc-950\/60 { background-color: #ffffff; } + .bg-zinc-950\/80 { background-color: #ffffff; } + .bg-zinc-950\/95 { background-color: #ffffff; } + + /* ---- borders ---- */ + .border-zinc-700 { border-color: #d6d3d1; } + .border-zinc-800 { border-color: #e7e5e4; } + .border-zinc-800\/40 { border-color: rgba(214, 211, 209, 0.55); } + .border-zinc-800\/60 { border-color: rgba(214, 211, 209, 0.75); } + .border-zinc-900\/50 { border-color: rgba(214, 211, 209, 0.7); } + + /* The decoration on links (ratatui etc) */ + .decoration-zinc-700 { text-decoration-color: #d6d3d1; } + + /* ---- hover states (mirror the text/bg map, with a touch more contrast) ---- */ + .hover\:text-white:hover { color: #0c0a09; } + .hover\:text-zinc-100:hover { color: #0c0a09; } + .hover\:text-zinc-200:hover { color: #1c1917; } + .hover\:text-zinc-300:hover { color: #1c1917; } + .hover\:text-zinc-400:hover { color: #1c1917; } + .hover\:bg-zinc-800\/50:hover { background-color: rgba(231, 229, 228, 0.7); } + .hover\:bg-zinc-800\/60:hover { background-color: rgba(231, 229, 228, 0.85); } + .hover\:bg-zinc-900:hover { background-color: #f5f3ee; } + .hover\:border-zinc-500:hover { border-color: #a8a29e; } + .hover\:border-zinc-700:hover { border-color: #a8a29e; } + .hover\:decoration-accent:hover { text-decoration-color: var(--tp-accent); } + + /* ---- accent (rust) — slightly darker on light for legibility ---- */ + .text-accent { color: #9a3a0e; } + .bg-accent { background-color: #9a3a0e; } + .bg-accent\/5 { background-color: rgba(154, 58, 14, 0.05); } + .bg-accent\/10 { background-color: rgba(154, 58, 14, 0.08); } + .bg-accent\/15 { background-color: rgba(154, 58, 14, 0.12); } + .border-accent { border-color: #9a3a0e; } + .border-accent\/30 { border-color: rgba(154, 58, 14, 0.25); } + .border-accent\/40 { border-color: rgba(154, 58, 14, 0.35); } + .border-accent\/60 { border-color: rgba(154, 58, 14, 0.55); } + .hover\:bg-accent\/90:hover { background-color: #7f2f08; } + .hover\:border-accent\/60:hover { border-color: rgba(154, 58, 14, 0.55); } + .hover\:text-accent:hover { color: #9a3a0e; } + .from-accent\/15 { --tw-gradient-from: rgba(154, 58, 14, 0.18); --tw-gradient-to: rgba(154, 58, 14, 0); --tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to); } + .to-emerald-500\/5 { --tw-gradient-to: rgba(16, 185, 129, 0.06); } + + /* ---- tab pill in code-example tab bar ---- */ + .bg-zinc-800 { background-color: #e7e5e4; } + .bg-zinc-800.text-white { color: #1c1917; } +} + +/* ========================================================================== + DaisyUI overrides for our theme + -------------------------------------------------------------------------- + DaisyUI 4 ships a built-in `night` theme — we already use it for dark. + `winter` is our own theme, so we register its HSL tokens so things like + `.bg-base-100` and `.text-base-content` resolve correctly. + Format is "H S% L%" (no hsl() wrapper) — DaisyUI concatenates. + ========================================================================== */ +[data-theme="night"] { + --p: 20 75% 38%; /* primary — rust */ + --pc: 20 100% 97%; + --b1: 240 6% 7%; /* base 100 */ + --b2: 240 5% 11%; + --b3: 240 5% 14%; + --bc: 0 0% 96%; /* base content */ + /* DaisyUI 4 expects OKLCH and ignores HSL on modern browsers. Provide + the fallback so the body has a real colour even if OKLCH parsing fails. */ + --fallback-b1: #09090b; + --fallback-bc: #fafafa; + /* Make DaisyUI semantic tokens resolve to our rust accent. */ + .bg-base-100 { background-color: var(--tp-bg); } + .text-base-content { color: var(--tp-fg); } +} + +[data-theme="winter"] { + --p: 19 82% 32%; /* primary — darker rust, sits on cream */ + --pc: 30 100% 97%; + --b1: 36 25% 97%; /* base 100 — warm paper */ + --b2: 36 18% 94%; + --b3: 36 12% 89%; + --bc: 24 12% 12%; /* base content — warm near-black */ + --n: 24 10% 18%; /* neutral */ + --nc: 36 25% 97%; + --fallback-b1: #fbfaf7; + --fallback-bc: #1c1917; }