/* @import url('https://fonts.googleapis.com/css2?family=Margarine&family=Schoolbell&display=swap'); */ @import "tailwindcss"; @font-face { font-family: "Margarine"; src: url("./fonts/Margarine-Regular.ttf") format("truetype"); font-weight: 100 900; font-display: block; } /* ── FONT LAB ──────────────────────────────────────────────────────────── Two roles, applied everywhere via the `font-ticker` / `font-display` utility classes. Swap candidates by editing the two variables below, save (watch rebuild), refresh the graphic. - ticker → the scrolling marquee text - display → big statements: ad row/column text, break slide Candidates to try (must be installed on the OBS machine, or bundled below; the stack falls through to the next name if one is missing): grotesque: "Inter", "Archivo", "Manrope", "Roboto" condensed: "Oswald", "Archivo Narrow", "Roboto Condensed" poster: "Anton", "Archivo Black", "Bebas Neue", Impact To bundle a font file (works offline, recommended for the venue): drop the .woff2/.ttf into src/graphics/fonts/ and uncomment: @font-face { font-family: "MojFont"; src: url("./fonts/MojFont.woff2") format("woff2"); font-weight: 100 900; font-display: block; } Google Fonts also works if the OBS machine has internet — add e.g. @import url("https://fonts.googleapis.com/css2?family=Anton&display=block"); directly under the tailwindcss import above (keep all @import lines at the very top of this file). Latin-extended fonts cover č ć đ š ž. ──────────────────────────────────────────────────────────────────────── */ /* ── THEME LAB ─────────────────────────────────────────────────────────── Every brand color the graphics use, in one place. Edit, save (watch rebuild), refresh the graphic — nothing else references raw colors. - ticker-* the scrolling marquee: bottom→top gradient, top border, and the accent used for the recurring blurb text - ad-bg-* fallback gradient behind ad backgrounds while the image loads (or when none is uploaded) - break-bg-* break-slide backdrop gradient (a/b = edges/center) - break-accent the "where they're from" line on the break slide - break-blob-* the three drifting ambient blobs shown when no background image is uploaded (keep them translucent) ──────────────────────────────────────────────────────────────────────── */ @theme { --font-ticker: "Margarine", system-ui, sans-serif; --font-display: "Margarine", system-ui, sans-serif; --color-ticker-start: var(--color-cyan-800); --color-ticker-end: var(--color-teal-500); --color-ticker-border: var(--color-blue-400); --color-ticker-accent: var(--color-amber-200); --color-ad-bg-start: #0b1020; --color-ad-bg-end: #1a2140; --color-break-bg-a: #0a0e1a; --color-break-bg-b: #171030; --color-break-accent: color-mix(in srgb, var(--color-amber-300) 90%, transparent); --color-break-blob-1: rgba(99, 102, 241, 0.35); --color-break-blob-2: rgba(168, 85, 247, 0.3); --color-break-blob-3: rgba(245, 158, 11, 0.18); } html, body { margin: 0; background: transparent; overflow: hidden; } /* Break slide ambient motion */ @keyframes drift-a { from { transform: translate(-120px, -80px) scale(1); } to { transform: translate(180px, 140px) scale(1.2); } } @keyframes drift-b { from { transform: translate(120px, 60px) scale(1.1); } to { transform: translate(-160px, -110px) scale(0.9); } } @keyframes drift-c { from { transform: translate(0, 120px) scale(1); } to { transform: translate(100px, -140px) scale(1.3); } } /* Ad background: slow pan; the 1.15 scale gives the ±3% translate room to move without ever exposing an edge (7.5% margin > 3% × 1.15 travel) */ @keyframes ad-pan { from { transform: scale(1.15) translate(-3%, -2%); } to { transform: scale(1.15) translate(3%, 2%); } } /* Break background: full edge-to-edge sweep that visibly reverses. At 1.15 scale the hidden margin is 7.5% of the screen per side, i.e. ~6.5% of the element's own size — ±6%/±4% stays just inside that, so each bounce lands right at the image edge without exposing it */ @keyframes break-bounce { from { transform: scale(1.15) translate(-6%, -4%); } to { transform: scale(1.15) translate(6%, 4%); } } @keyframes breathe { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.045); } }