@tailwind base; @tailwind components; @tailwind utilities; /* ---------------------------------------------------------------------------- Day/night palette. JS sets data-phase={dawn|day|dusk|night} on . Each phase drives a small set of CSS vars; the page transitions smoothly thanks to the `transition-colors duration-1000` on . ---------------------------------------------------------------------------- */ :root, html[data-phase="day"] { --bg: #fff7e4; /* warm cream */ --bg-grad: #ffeec2; /* soft sun wash */ --card: #ffffff; --ink: #3a2e1f; --accent: #f2a541; /* sunshine yellow */ } html[data-phase="dawn"] { --bg: #ffe7d6; --bg-grad: #ffc9c9; --card: #fff4ea; --ink: #4a2e2a; --accent: #ff8a65; } html[data-phase="dusk"] { --bg: #ffd6a8; --bg-grad: #f7a07e; --card: #fff1de; --ink: #3d2417; --accent: #e6553a; } html[data-phase="night"] { --bg: #1a1f3a; --bg-grad: #2a3358; --card: #2d365a; --ink: #f1ecd8; /* moonlight */ --accent: #f9d976; /* lantern */ } @layer base { body { font-family: "Nunito", system-ui, sans-serif; } html { scroll-behavior: smooth; } /* Belt-and-braces: never let stray wide content push horizontal scroll on the whole page (the channel nav scrolls inside itself instead). */ html, body { overflow-x: hidden; } } @layer components { /* Channel pill row may exceed viewport on mobile once enough channels are configured. Let it scroll inside its own rounded container and hide the scrollbar chrome so it still reads as a clean pill. */ .pete-channel-nav { scrollbar-width: none; -ms-overflow-style: none; } .pete-channel-nav::-webkit-scrollbar { display: none; } } @layer utilities { .font-display { font-family: "Fredoka", "Nunito", system-ui, sans-serif; letter-spacing: -0.01em; } /* Soft signage shadow — Animal Crossing wooden plank vibe. */ .shadow-pete { box-shadow: 0 4px 0 rgba(60,40,20,0.10), 0 8px 24px rgba(60,40,20,0.08); } .shadow-pete-lg { box-shadow: 0 6px 0 rgba(60,40,20,0.12), 0 16px 32px rgba(60,40,20,0.12); } /* Per-channel theme colors. Kept as plain utilities so Tailwind doesn't need to know to safelist them. */ .bg-theme-gaming { background-color: #4caf7d; } .bg-theme-tech { background-color: #5aa9e6; } .bg-theme-politics { background-color: #e07a5f; } .bg-theme-eu { background-color: #003399; } .bg-theme-music { background-color: #b079d6; } .bg-theme-anime { background-color: #ec5e8a; } .bg-theme-foss { background-color: #d97706; } .text-theme-gaming { color: #2d8a5a; } .text-theme-tech { color: #2f7fb8; } .text-theme-politics { color: #b8523a; } .text-theme-eu { color: #003399; } .text-theme-music { color: #8a4fb8; } .text-theme-anime { color: #c33a6a; } .text-theme-foss { color: #b8530a; } .decoration-theme-gaming { text-decoration-color: #4caf7d; } .decoration-theme-tech { text-decoration-color: #5aa9e6; } .decoration-theme-politics { text-decoration-color: #e07a5f; } .decoration-theme-eu { text-decoration-color: #003399; } .decoration-theme-music { text-decoration-color: #b079d6; } .decoration-theme-anime { text-decoration-color: #ec5e8a; } .decoration-theme-foss { text-decoration-color: #d97706; } .border-theme-gaming { border-color: #4caf7d; } .border-theme-tech { border-color: #5aa9e6; } .border-theme-politics { border-color: #e07a5f; } .border-theme-eu { border-color: #003399; } .border-theme-music { border-color: #b079d6; } .border-theme-anime { border-color: #ec5e8a; } .border-theme-foss { border-color: #d97706; } /* "Posted to Matrix" glow — soft pulsing aura in the channel's theme color. */ .glow-theme-gaming { box-shadow: 0 0 0 2px rgba(76,175,125,0.35), 0 0 24px 4px rgba(76,175,125,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; } .glow-theme-tech { box-shadow: 0 0 0 2px rgba(90,169,230,0.35), 0 0 24px 4px rgba(90,169,230,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; } .glow-theme-politics { box-shadow: 0 0 0 2px rgba(224,122,95,0.35), 0 0 24px 4px rgba(224,122,95,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; } .glow-theme-eu { box-shadow: 0 0 0 2px rgba(0,51,153,0.35), 0 0 24px 4px rgba(0,51,153,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; } .glow-theme-music { box-shadow: 0 0 0 2px rgba(176,121,214,0.35), 0 0 24px 4px rgba(176,121,214,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; } .glow-theme-anime { box-shadow: 0 0 0 2px rgba(236,94,138,0.35), 0 0 24px 4px rgba(236,94,138,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; } .glow-theme-foss { box-shadow: 0 0 0 2px rgba(217,119,6,0.35), 0 0 24px 4px rgba(217,119,6,0.45); animation: pete-glow-pulse 2.4s ease-in-out infinite; } @keyframes pete-glow-pulse { 0%, 100% { filter: brightness(1); } 50% { filter: brightness(1.08); } } .line-clamp-3 { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; } /* "PAYWALLED" diagonal rubber stamp overlay — slapped across the whole card when the source is gated and no archive snapshot worked. The card stays clickable (link still goes to the original); the stamp is just visual warning. pointer-events:none keeps it from eating clicks. */ .paywall-stamp { position: absolute; inset: 0; pointer-events: none; display: flex; align-items: center; justify-content: center; z-index: 5; background: rgba(255, 250, 240, 0.18); } .paywall-stamp::before { content: "PAYWALLED"; font-family: var(--font-display, ui-sans-serif), system-ui, sans-serif; font-weight: 900; font-size: clamp(1rem, 3.2vw, 1.75rem); letter-spacing: 0.12em; color: rgba(180, 30, 30, 0.85); border: 0.28rem double rgba(180, 30, 30, 0.85); padding: 0.3rem 0.9rem; transform: rotate(-15deg); text-shadow: 0 1px 0 rgba(255,255,255,0.4); box-shadow: inset 0 0 0 2px rgba(255,255,255,0.15); background: rgba(255, 240, 230, 0.55); border-radius: 0.25rem; /* slight roughness to mimic a real ink stamp */ filter: contrast(1.05); } }