init: initial commit
- ticker / QR ad overlay / break slide graphics (1920×1080) with all geometry derived from one shared module (src/shared/obs-geometry.mjs) - OBS scene-collection generator (scripts/generate-obs-scenes.mjs) and a read-only in-dashboard setup verifier, both driven by the same module - en/sr dashboard i18n selected via bundle config; configschema.json with neutral first-run defaults seeded from optional branding config - install.sh / systemd user service / update.sh for venue deployment - reference OBS scene collection + profile from a real venue as fixtures
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
/* @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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user