/* ========================================================================== tui-pages website — custom layer on top of Tailwind + DaisyUI Loaded AFTER Tailwind Play CDN compiles and DaisyUI prebuilt. Keep this small. Tailwind utility classes do the heavy lifting. ========================================================================== */ /* ---------- Smooth scroll, native feel ----------------------------------- */ html { scroll-behavior: smooth; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-rendering: optimizeLegibility; } @media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } *, *::before, *::after { animation-duration: 0.001ms !important; animation-iteration-count: 1 !important; transition-duration: 0.001ms !important; } } /* ---------- 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; /* 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"] { /* 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) ------------------ */ @supports (view-transition-name: foo) { ::view-transition-old(root), ::view-transition-new(root) { animation-duration: 220ms; } } /* ---------- Hero --------------------------------------------------------- */ .tp-hero { background: transparent; /* let the mountain ASCII show through */ position: relative; isolation: isolate; } .tp-hero > .max-w-7xl { position: relative; z-index: 1; } .tp-hero h1, .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 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: ""; position: absolute; inset: 0; background-image: linear-gradient(var(--tp-grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--tp-grid-line) 1px, transparent 1px); background-size: 56px 56px; background-position: -1px -1px; -webkit-mask-image: radial-gradient(ellipse 60% 50% at 50% 0%, #000 30%, transparent 80%); mask-image: radial-gradient(ellipse 60% 50% at 50% 0%, #000 30%, transparent 80%); pointer-events: none; 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 glow in the hero, behind the content */ .tp-hero-glow { position: absolute; inset: 0; pointer-events: none; z-index: -1; opacity: 0.6; background: 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: var(--tp-bg-nav); backdrop-filter: saturate(160%) blur(12px); -webkit-backdrop-filter: saturate(160%) blur(12px); border-bottom: 1px solid var(--tp-border); transition: background 200ms ease, border-color 200ms ease; } /* ---------- Feature cards ------------------------------------------------ */ .tp-card { position: relative; background: var(--tp-bg-card); border: 1px solid var(--tp-border); border-radius: 1rem; padding: 1.5rem; 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: var(--tp-bg-card-hover); transform: translateY(-2px); box-shadow: var(--tp-card-shadow-hover); } :root[data-theme="winter"] .tp-card:hover { border-color: rgba(154, 58, 14, 0.4); } .tp-card-icon { display: inline-flex; align-items: center; justify-content: center; width: 2.5rem; height: 2.5rem; border-radius: 0.75rem; background: var(--tp-accent-soft); color: var(--tp-accent); 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 { font-family: 'JetBrains Mono', ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.85rem; line-height: 1.6; tab-size: 4; } .tp-code pre { 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; } /* ---------- Inline kbd --------------------------------------------------- */ .tp-kbd { display: inline-flex; align-items: center; padding: 0.15rem 0.5rem; font-family: 'JetBrains Mono', ui-monospace, monospace; font-size: 0.75rem; font-weight: 500; border: 1px solid var(--tp-border-strong); border-bottom-width: 2px; border-radius: 0.375rem; background: rgba(39, 39, 42, 0.6); color: var(--tp-fg-code); line-height: 1; } :root[data-theme="winter"] .tp-kbd { background: #ffffff; color: #1c1917; border-color: #d6d3d1; box-shadow: 0 1px 0 rgba(28, 25, 23, 0.04); } /* ---------- Terminal window wrapper -------------------------------------- */ .tp-terminal { position: relative; border-radius: 0.875rem; background: transparent; /* let the body ASCII art show through */ box-shadow: 0 0 0 1px rgba(244, 162, 107, 0.18), /* rust-orange hairline, brand */ 0 30px 60px -20px rgba(0, 0, 0, 0.55), 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; inset: 0; pointer-events: none; border-radius: inherit; background: linear-gradient( to bottom, rgba(11, 11, 15, 0.55) 0%, rgba(11, 11, 15, 0) 18%, rgba(11, 11, 15, 0) 82%, rgba(11, 11, 15, 0.45) 100% ); /* 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 { background: var(--tp-accent); color: var(--tp-accent-fg); } /* ---------- Focus ring -------------------------------------------------- */ :focus-visible { outline: 2px solid var(--tp-accent); outline-offset: 2px; border-radius: 0.25rem; } /* ---------- Scrollbar (subtle) ----------------------------------------- */ ::-webkit-scrollbar { width: 10px; height: 10px; } ::-webkit-scrollbar-track { background: transparent; } ::-webkit-scrollbar-thumb { background: var(--tp-border-strong); border-radius: 999px; border: 2px solid transparent; 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; } /* ---------- Alpine x-cloak (prevents flash of un-initialised content) --- */ [x-cloak] { display: none !important; } /* ========================================================================== 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; }