260 lines
7.7 KiB
PHP
260 lines
7.7 KiB
PHP
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<title>OPHI-118 / control panel</title>
|
|
<link rel="icon" type="image/x-icon" href="{{ asset('favicon.ico') }}">
|
|
<link rel="stylesheet" href="{{ asset('css/hud.css') }}">
|
|
<style>
|
|
html, body {
|
|
color: var(--term-fg);
|
|
font-family: var(--mono);
|
|
}
|
|
body.page-shell {
|
|
display: flex;
|
|
flex-direction: column;
|
|
overflow: hidden;
|
|
}
|
|
.banner { margin-bottom: 28px; }
|
|
|
|
/* ---------- Banner / lede ---------- */
|
|
.banner h1 {
|
|
color: var(--term-fg-bright);
|
|
text-shadow: 0 0 12px var(--term-glow);
|
|
font-size: 28px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.22em;
|
|
margin-bottom: 6px;
|
|
}
|
|
.banner .lede {
|
|
color: var(--term-fg-dim);
|
|
font-size: 13px;
|
|
letter-spacing: 0.04em;
|
|
}
|
|
.banner .lede .caret { color: var(--term-fg-bright); margin-right: 8px; }
|
|
|
|
/* ---------- Tile grid ---------- */
|
|
.tiles {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
grid-template-rows: repeat(2, 1fr);
|
|
gap: 22px;
|
|
flex: 1 1 auto;
|
|
min-height: 0;
|
|
}
|
|
|
|
.tile {
|
|
--tile-fg: var(--term-fg);
|
|
--tile-fg-hi: var(--term-fg-bright);
|
|
--tile-dim: var(--term-fg-dim);
|
|
--tile-edge: var(--term-edge);
|
|
--tile-glow: var(--term-glow);
|
|
|
|
position: relative;
|
|
background:
|
|
linear-gradient(180deg, rgba(80,220,100,0.04) 0%, rgba(0,0,0,0) 60%),
|
|
var(--term-bg);
|
|
border: 2px solid var(--tile-edge);
|
|
border-radius: 6px;
|
|
padding: 26px 30px 22px;
|
|
color: var(--tile-fg);
|
|
text-decoration: none;
|
|
display: grid;
|
|
grid-template-rows: auto 1fr auto;
|
|
gap: 14px;
|
|
overflow: hidden;
|
|
transition: border-color 140ms ease, transform 140ms ease, box-shadow 140ms ease;
|
|
box-shadow:
|
|
0 0 30px rgba(80, 220, 100, 0.04),
|
|
inset 0 0 60px rgba(0, 30, 0, 0.55);
|
|
}
|
|
.tile:hover {
|
|
border-color: var(--tile-fg-hi);
|
|
box-shadow:
|
|
0 0 40px var(--tile-glow),
|
|
inset 0 0 60px rgba(0, 30, 0, 0.55);
|
|
transform: translateY(-2px);
|
|
}
|
|
.tile:hover .tile-title { text-shadow: 0 0 14px var(--tile-glow); }
|
|
.tile::after {
|
|
content: '';
|
|
position: absolute; inset: 0;
|
|
pointer-events: none;
|
|
background: repeating-linear-gradient(
|
|
to bottom,
|
|
rgba(0,0,0,0) 0px,
|
|
rgba(0,0,0,0) 2px,
|
|
rgba(0,0,0,0.22) 3px,
|
|
rgba(0,0,0,0.22) 4px
|
|
);
|
|
opacity: 0.45;
|
|
mix-blend-mode: multiply;
|
|
}
|
|
|
|
/* HUD-cyan variant for the scenes tile */
|
|
.tile.cyan {
|
|
--tile-fg: var(--hud);
|
|
--tile-fg-hi: #c4ecff;
|
|
--tile-dim: var(--hud-dim);
|
|
--tile-edge: rgba(79, 210, 255, 0.45);
|
|
--tile-glow: rgba(79, 210, 255, 0.55);
|
|
background:
|
|
linear-gradient(180deg, rgba(79,210,255,0.05) 0%, rgba(0,0,0,0) 60%),
|
|
var(--term-bg);
|
|
color: var(--tile-fg);
|
|
}
|
|
/* Warn-yellow variant for external links */
|
|
.tile.warn {
|
|
--tile-fg: var(--warn);
|
|
--tile-fg-hi: #ffe580;
|
|
--tile-dim: rgba(255, 208, 0, 0.55);
|
|
--tile-edge: rgba(255, 208, 0, 0.45);
|
|
--tile-glow: rgba(255, 208, 0, 0.55);
|
|
background:
|
|
linear-gradient(180deg, rgba(255,208,0,0.04) 0%, rgba(0,0,0,0) 60%),
|
|
var(--term-bg);
|
|
color: var(--tile-fg);
|
|
}
|
|
|
|
.tile-head {
|
|
display: flex; align-items: baseline; justify-content: space-between;
|
|
gap: 12px;
|
|
color: var(--tile-dim);
|
|
font-size: 11px; letter-spacing: 0.20em;
|
|
}
|
|
.tile-slug { color: var(--tile-fg-hi); }
|
|
.tile-badge {
|
|
border: 1px solid var(--tile-edge);
|
|
padding: 2px 8px;
|
|
border-radius: 3px;
|
|
color: var(--tile-fg);
|
|
background: rgba(0, 0, 0, 0.35);
|
|
}
|
|
|
|
.tile-title {
|
|
color: var(--tile-fg-hi);
|
|
font-size: 38px;
|
|
font-weight: 700;
|
|
letter-spacing: 0.04em;
|
|
line-height: 1.05;
|
|
text-shadow: 0 0 8px var(--tile-glow);
|
|
transition: text-shadow 140ms ease;
|
|
}
|
|
.tile-desc {
|
|
color: var(--tile-fg);
|
|
opacity: 0.85;
|
|
font-size: 13px;
|
|
line-height: 1.55;
|
|
max-width: 90%;
|
|
}
|
|
|
|
.tile-foot {
|
|
display: flex; align-items: center; justify-content: space-between;
|
|
color: var(--tile-dim);
|
|
font-size: 12px; letter-spacing: 0.08em;
|
|
}
|
|
.tile-target {
|
|
color: var(--tile-fg-hi);
|
|
font-weight: 700;
|
|
}
|
|
.tile-target .caret { color: var(--tile-fg); margin-right: 6px; }
|
|
.tile-foot .arrow { font-size: 18px; color: var(--tile-fg-hi); }
|
|
|
|
/* ---------- CRT overlays (full-viewport) ---------- */
|
|
.scanlines, .vignette, .flicker { position: fixed; z-index: 999; }
|
|
|
|
@media (max-width: 1100px) {
|
|
body.page-shell { padding: 20px 28px; }
|
|
.tiles { grid-template-columns: 1fr; grid-template-rows: auto; }
|
|
.tile-title { font-size: 30px; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="page-shell">
|
|
@include('partials.topbar', ['crumb' => 'CONTROL PANEL'])
|
|
|
|
<section class="banner">
|
|
<h1>STREAMING CONTROL</h1>
|
|
<div class="lede"><span class="caret">▶</span>select an operation</div>
|
|
</section>
|
|
|
|
<main class="tiles">
|
|
<a class="tile" href="/onboard">
|
|
<div class="tile-head">
|
|
<span><span class="tile-slug">[01]</span> PRE-FLIGHT</span>
|
|
<span class="tile-badge">INTERNAL</span>
|
|
</div>
|
|
<div>
|
|
<div class="tile-title">ONBOARD</div>
|
|
<div class="tile-desc">Compile a Project Loading manifest — game, subtitle, countdown, camera/mic state. Pushes the channel title + category to Twitch.</div>
|
|
</div>
|
|
<div class="tile-foot">
|
|
<span class="tile-target"><span class="caret">▶</span>/onboard</span>
|
|
<span class="arrow">→</span>
|
|
</div>
|
|
</a>
|
|
|
|
<a class="tile cyan" href="/scenes">
|
|
<div class="tile-head">
|
|
<span><span class="tile-slug">[02]</span> ROUTES</span>
|
|
<span class="tile-badge">INTERNAL</span>
|
|
</div>
|
|
<div>
|
|
<div class="tile-title">SCENES</div>
|
|
<div class="tile-desc">Every overlay URL OBS browser-sources point at, plus the data endpoints (playlist, cover, audio stream).</div>
|
|
</div>
|
|
<div class="tile-foot">
|
|
<span class="tile-target"><span class="caret">▶</span>/scenes</span>
|
|
<span class="arrow">→</span>
|
|
</div>
|
|
</a>
|
|
|
|
<a class="tile warn" href="https://ophi118.com" target="_blank" rel="noopener">
|
|
<div class="tile-head">
|
|
<span><span class="tile-slug">[03]</span> LANDING</span>
|
|
<span class="tile-badge">EXTERNAL ↗</span>
|
|
</div>
|
|
<div>
|
|
<div class="tile-title">OPHI118.COM</div>
|
|
<div class="tile-desc">Public landing page for the OPHI-118 broadcast. Bio, schedule, social links.</div>
|
|
</div>
|
|
<div class="tile-foot">
|
|
<span class="tile-target"><span class="caret">▶</span>ophi118.com</span>
|
|
<span class="arrow">↗</span>
|
|
</div>
|
|
</a>
|
|
|
|
<a class="tile warn" href="https://gamez.ciemnosc.com" target="_blank" rel="noopener">
|
|
<div class="tile-head">
|
|
<span><span class="tile-slug">[04]</span> SERVERS</span>
|
|
<span class="tile-badge">EXTERNAL ↗</span>
|
|
</div>
|
|
<div>
|
|
<div class="tile-title">GAMEZ.CIEMNOSC.COM</div>
|
|
<div class="tile-desc">Roster of the self-hosted game servers currently live — connect strings, mod lists, player counts.</div>
|
|
</div>
|
|
<div class="tile-foot">
|
|
<span class="tile-target"><span class="caret">▶</span>gamez.ciemnosc.com</span>
|
|
<span class="arrow">↗</span>
|
|
</div>
|
|
</a>
|
|
</main>
|
|
|
|
<div class="scanlines"></div>
|
|
<div class="vignette"></div>
|
|
<div class="flicker"></div>
|
|
|
|
<script>
|
|
// UTC clock — same look as the in-scene HUD strip.
|
|
const clock = document.getElementById('clock');
|
|
function tick() {
|
|
const d = new Date();
|
|
const pad = n => String(n).padStart(2, '0');
|
|
clock.textContent = `${pad(d.getUTCHours())}:${pad(d.getUTCMinutes())}:${pad(d.getUTCSeconds())}`;
|
|
}
|
|
tick();
|
|
setInterval(tick, 1000);
|
|
</script>
|
|
</body>
|
|
</html>
|