refactor : UI styles across intranet and public pages for consistency

This commit is contained in:
Thibault Pouch
2026-02-18 11:16:42 +01:00
parent b79c8e2460
commit 0021787af7
17 changed files with 152 additions and 139 deletions

View File

@@ -4,8 +4,8 @@
"description": "Community hub for Headless Hazard, a retro-futuristic puzzle game by CrowMate Studio.",
"start_url": "/",
"display": "standalone",
"background_color": "#0a0d0a",
"theme_color": "#0a0d0a",
"background_color": "#ffffff",
"theme_color": "#ffffff",
"icons": [
{
"src": "/icon-192.png",

View File

@@ -65,7 +65,7 @@ export function IntranetLayout() {
fontFamily: 'var(--font-mono)',
fontSize: '0.78rem',
color: isActive ? 'var(--color-yellow)' : 'var(--color-text-muted)',
background: isActive ? 'rgba(255,255,0,0.06)' : 'transparent',
background: isActive ? 'rgba(37,99,235,0.08)' : 'transparent',
borderLeft: isActive ? '3px solid var(--color-yellow)' : '3px solid transparent',
textDecoration: 'none',
transition: 'color 0.1s, background 0.1s',

View File

@@ -27,14 +27,16 @@ function DevRoleSwitcherInner() {
position: 'fixed',
bottom: '1rem',
right: '1rem',
background: '#0a1a0a',
border: '1px solid var(--color-amber)',
background: 'var(--color-surface)',
border: '2px solid var(--color-yellow)',
padding: '0.75rem',
zIndex: 9999,
fontSize: '0.7rem',
fontFamily: 'var(--font-mono)',
color: 'var(--color-amber)',
color: 'var(--color-text)',
maxWidth: '220px',
borderRadius: '8px',
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -2px rgba(0, 0, 0, 0.1)',
}}
>
<div style={{ marginBottom: '0.5rem', fontWeight: 'bold', letterSpacing: '0.1em' }}>

View File

@@ -6,7 +6,7 @@ export function Footer() {
return (
<footer
style={{
background: 'rgba(8,11,8,0.95)',
background: 'var(--color-surface-alt)',
borderTop: '1px solid var(--color-border)',
padding: '2.5rem 1.5rem 2rem',
marginTop: 'auto',

View File

@@ -1,40 +1,40 @@
@import url('https://fonts.googleapis.com/css2?family=VT323&family=Press+Start+2P&family=Courier+Prime:wght@400;700&family=Share+Tech+Mono&display=swap');
@import "tailwindcss";
/* ── Design Tokens — Minitel Aesthetic ─────────────────── */
/* ── Design Tokens — White Theme ─────────────────── */
:root {
--color-bg: #00001a;
--color-bg-alt: #000033;
--color-surface: #00003d;
--color-surface-alt: #000055;
--color-border: #0000cc;
--color-border-dim: #000088;
--color-bg: #ffffff;
--color-bg-alt: #f8f9fa;
--color-surface: #ffffff;
--color-surface-alt: #f1f3f5;
--color-border: #dee2e6;
--color-border-dim: #e9ecef;
/* Primary accent: yellow */
--color-yellow: #ffff00;
--color-yellow-dim: #cccc00;
/* Primary accent: blue */
--color-yellow: #2563eb;
--color-yellow-dim: #1d4ed8;
/* Secondary accent: cyan */
--color-cyan: #00ffff;
--color-cyan-dim: #00cccc;
/* Secondary accent: dark gray */
--color-cyan: #374151;
--color-cyan-dim: #4b5563;
/* Tertiary: magenta */
--color-magenta: #ff00ff;
--color-magenta-dim: #cc00cc;
/* Tertiary: purple */
--color-magenta: #7c3aed;
--color-magenta-dim: #6d28d9;
/* Red for errors/danger */
--color-red: #ff4444;
--color-red: #dc2626;
/* Text */
--color-text: #e0e0ff;
--color-text-dim: #a0a0cc;
--color-text-muted: #6060aa;
--color-text: #1f2937;
--color-text-dim: #4b5563;
--color-text-muted: #9ca3af;
/* Legacy aliases kept so existing pages compile without changes */
--color-green: #00ffff;
--color-green-dim: #00cccc;
--color-amber: #ffff00;
--color-amber-dim: #cccc00;
--color-green: #059669;
--color-green-dim: #047857;
--color-amber: #d97706;
--color-amber-dim: #b45309;
--font-mono: 'Share Tech Mono', 'Courier Prime', monospace;
--font-heading: 'VT323', 'Press Start 2P', monospace;
@@ -66,8 +66,8 @@ body {
/* ── Scrollbar ─────────────────────────────────────────── */
::-webkit-scrollbar { width: 8px; }
::-webkit-scrollbar-track { background: var(--color-bg); }
::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 0; }
::-webkit-scrollbar-track { background: var(--color-bg-alt); }
::-webkit-scrollbar-thumb { background: var(--color-border); border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: var(--color-cyan); }
/* ── Typography ────────────────────────────────────────── */
@@ -79,18 +79,20 @@ h1, h2, h3, h4, h5 {
}
a {
color: var(--color-cyan);
color: var(--color-yellow);
text-decoration: underline;
transition: color 0.1s;
}
a:hover { color: var(--color-yellow); }
a:hover { color: var(--color-yellow-dim); }
/* ── Minitel box (replaces crt-box) ────────────────────── */
/* ── Content box ─────────────────────────────────────── */
.crt-box {
border: 2px solid var(--color-border);
border: 1px solid var(--color-border);
background: var(--color-surface);
position: relative;
overflow: hidden;
border-radius: 8px;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px -1px rgba(0, 0, 0, 0.1);
}
/* ── Scanlines — kept as no-op class (Minitel: no effect) */
@@ -106,17 +108,17 @@ a:hover { color: var(--color-yellow); }
.glitch-text::before,
.glitch-text::after { display: none; }
/* ── Redacted — Minitel style: yellow block characters ─── */
/* ── Redacted — blocked text ─── */
.redacted {
display: inline-block;
color: var(--color-yellow);
background: var(--color-yellow);
color: #6b7280;
background: #6b7280;
font-family: var(--font-mono);
padding: 0 2px;
user-select: none;
cursor: default;
letter-spacing: 0;
border: 1px solid var(--color-yellow);
border: 1px solid #6b7280;
transition: background 0.1s, color 0.1s;
}
.redacted:hover {
@@ -125,42 +127,42 @@ a:hover { color: var(--color-yellow); }
color: var(--color-red);
}
/* ── No glow classes — kept as no-ops for compatibility ── */
.glow-green { color: var(--color-cyan); }
.glow-amber { color: var(--color-yellow); }
/* ── Color classes ── */
.glow-green { color: var(--color-green); }
.glow-amber { color: var(--color-amber); }
.flicker {}
/* ── Buttons — blocky flat Minitel style ───────────────── */
/* ── Buttons — clean white theme style ───────────────── */
.btn-terminal {
font-family: var(--font-mono);
background: var(--color-bg);
border: 2px solid var(--color-cyan);
color: var(--color-cyan);
border: 2px solid var(--color-yellow);
color: var(--color-yellow);
padding: 0.4rem 1.1rem;
text-transform: uppercase;
letter-spacing: 0.08em;
cursor: pointer;
transition: background 0.1s, color 0.1s;
transition: background 0.15s, color 0.15s;
display: inline-flex;
align-items: center;
gap: 0.4rem;
font-size: 0.85rem;
border-radius: 0;
border-radius: 6px;
text-decoration: none;
}
.btn-terminal::before { display: none; }
.btn-terminal:hover {
background: var(--color-cyan);
color: var(--color-bg);
background: var(--color-yellow);
color: #ffffff;
}
.btn-amber {
border-color: var(--color-yellow);
color: var(--color-yellow);
border-color: var(--color-amber);
color: var(--color-amber);
}
.btn-amber:hover {
background: var(--color-yellow);
color: var(--color-bg);
background: var(--color-amber);
color: #ffffff;
}
.btn-danger {
@@ -172,17 +174,17 @@ a:hover { color: var(--color-yellow); }
color: #fff;
}
/* ── Form inputs — blocky flat style ──────────────────── */
/* ── Form inputs — clean style ──────────────────── */
.input-terminal {
background: var(--color-bg);
border: 2px solid var(--color-border);
border-radius: 0;
border-radius: 6px;
color: var(--color-text);
font-family: var(--font-mono);
font-size: 0.9rem;
padding: 0.4rem 0.7rem;
width: 100%;
transition: border-color 0.1s;
transition: border-color 0.15s, box-shadow 0.15s;
outline: none;
-webkit-appearance: none;
appearance: none;
@@ -191,7 +193,8 @@ a:hover { color: var(--color-yellow); }
color: var(--color-text-muted);
}
.input-terminal:focus {
border-color: var(--color-cyan);
border-color: var(--color-yellow);
box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1);
}
.input-terminal.error {
border-color: var(--color-red);
@@ -201,7 +204,7 @@ a:hover { color: var(--color-yellow); }
.section-label {
font-family: var(--font-mono);
font-size: 0.72rem;
color: var(--color-cyan);
color: var(--color-text-dim);
text-transform: uppercase;
letter-spacing: 0.2em;
margin-bottom: 0.5rem;
@@ -216,43 +219,43 @@ a:hover { color: var(--color-yellow); }
animation: page-enter 0.2s ease forwards;
}
/* ── Status badges — flat, blocky ──────────────────────── */
/* ── Status badges — clean style ──────────────────────── */
.badge {
font-family: var(--font-mono);
font-size: 0.65rem;
padding: 0.1rem 0.45rem;
text-transform: uppercase;
letter-spacing: 0.08em;
border-radius: 0;
border-radius: 4px;
display: inline-block;
white-space: nowrap;
border: 1px solid;
}
.badge-open { background: #002200; color: #00ff88; border-color: #00ff88; }
.badge-progress { background: #221100; color: var(--color-yellow); border-color: var(--color-yellow); }
.badge-resolved { background: #002211; color: #00ffaa; border-color: #00ffaa; }
.badge-closed { background: #111133; color: var(--color-text-muted); border-color: var(--color-text-muted); }
.badge-critical { background: #330000; color: var(--color-red); border-color: var(--color-red); }
.badge-high { background: #221100; color: #ff8800; border-color: #ff8800; }
.badge-medium { background: #221100; color: var(--color-yellow); border-color: var(--color-yellow); }
.badge-low { background: #001122; color: var(--color-cyan-dim); border-color: var(--color-cyan-dim); }
.badge-open { background: #d1fae5; color: #065f46; border-color: #059669; }
.badge-progress { background: #fef3c7; color: #92400e; border-color: #d97706; }
.badge-resolved { background: #dbeafe; color: #1e40af; border-color: #2563eb; }
.badge-closed { background: #f3f4f6; color: #6b7280; border-color: #9ca3af; }
.badge-critical { background: #fee2e2; color: #991b1b; border-color: #dc2626; }
.badge-high { background: #fed7aa; color: #9a3412; border-color: #ea580c; }
.badge-medium { background: #fef3c7; color: #92400e; border-color: #d97706; }
.badge-low { background: #e0e7ff; color: #3730a3; border-color: #6366f1; }
/* ── Blink cursor ──────────────────────────────────────── */
@keyframes blink { 0%, 100% { opacity: 1; } 50% { opacity: 0; } }
.cursor-blink::after {
content: '_';
animation: blink 1s step-end infinite;
color: var(--color-cyan);
color: var(--color-text-dim);
}
/* ── Minitel horizontal rule ───────────────────────────── */
/* ── Horizontal rule ───────────────────────────── */
.minitel-rule {
border: none;
border-top: 2px solid var(--color-border);
border-top: 1px solid var(--color-border);
margin: 2rem 0;
}
/* ── Minitel block decoration ──────────────────────────── */
/* ── Block decoration ──────────────────────────── */
.block-deco {
color: var(--color-border);
font-family: var(--font-mono);

View File

@@ -90,7 +90,7 @@ export default function IntranetBugs() {
{ label: 'Critical', value: criticalCount, color: 'var(--color-red)' },
{ label: 'Mine', value: myCount, color: 'var(--color-amber)' },
].map(({ label, value, color }) => (
<div key={label} style={{ background: '#0a0d0a', border: '1px solid #1a2a1a', padding: '0.75rem', textAlign: 'center' }}>
<div key={label} style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)', padding: '0.75rem', textAlign: 'center' }}>
<div style={{ fontFamily: 'var(--font-heading)', color, fontSize: '1.8rem' }}>{value}</div>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.65rem', letterSpacing: '0.1em' }}>{label}</div>
</div>
@@ -118,7 +118,7 @@ export default function IntranetBugs() {
{/* Bug list */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.4rem' }}>
{filtered.length === 0 ? (
<div style={{ background: '#0a0d0a', border: '1px solid #1a2a1a', padding: '2rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)', fontSize: '0.8rem' }}>
<div style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)', padding: '2rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)', fontSize: '0.8rem' }}>
No reports match filters.
</div>
) : (
@@ -127,8 +127,8 @@ export default function IntranetBugs() {
key={bug.id}
onClick={() => setSelected(bug === selected ? null : bug)}
style={{
background: selected?.id === bug.id ? 'rgba(255,176,0,0.05)' : '#0a0d0a',
border: `1px solid ${selected?.id === bug.id ? 'rgba(255,176,0,0.3)' : '#1a2a1a'}`,
background: selected?.id === bug.id ? 'rgba(37,99,235,0.08)' : 'var(--color-surface)',
border: `1px solid ${selected?.id === bug.id ? 'var(--color-yellow)' : 'var(--color-border)'}`,
padding: '0.85rem 1.1rem',
cursor: 'pointer',
transition: 'all 0.15s',
@@ -162,7 +162,7 @@ export default function IntranetBugs() {
{/* Right panel — detail */}
{selected && (
<div style={{ background: '#0a0d0a', border: '1px solid #1a2a1a', padding: '1.5rem', position: 'sticky', top: '1rem' }}>
<div style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)', padding: '1.5rem', position: 'sticky', top: '1rem' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '1rem' }}>
<div>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.68rem', marginBottom: '0.25rem' }}>{selected.uniqueCode}</div>
@@ -201,14 +201,14 @@ export default function IntranetBugs() {
{/* Description */}
<div style={{ marginBottom: '1rem' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.65rem', letterSpacing: '0.1em', marginBottom: '0.4rem' }}>DESCRIPTION</div>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-dim)', fontSize: '0.78rem', lineHeight: 1.7, whiteSpace: 'pre-wrap', background: 'rgba(0,0,0,0.3)', padding: '0.75rem' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-dim)', fontSize: '0.78rem', lineHeight: 1.7, whiteSpace: 'pre-wrap', background: 'var(--color-bg-alt)', padding: '0.75rem', borderRadius: '4px' }}>
{selected.description}
</div>
</div>
<div style={{ marginBottom: '1rem' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.65rem', letterSpacing: '0.1em', marginBottom: '0.4rem' }}>STEPS TO REPRODUCE</div>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-dim)', fontSize: '0.78rem', lineHeight: 1.7, whiteSpace: 'pre-wrap', background: 'rgba(0,0,0,0.3)', padding: '0.75rem' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-dim)', fontSize: '0.78rem', lineHeight: 1.7, whiteSpace: 'pre-wrap', background: 'var(--color-bg-alt)', padding: '0.75rem', borderRadius: '4px' }}>
{selected.stepsToReproduce}
</div>
</div>
@@ -221,7 +221,7 @@ export default function IntranetBugs() {
) : (
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem', marginBottom: '0.75rem' }}>
{(selected.notes ?? []).map((note) => (
<div key={note.id} style={{ background: 'rgba(255,176,0,0.05)', border: '1px solid rgba(255,176,0,0.15)', padding: '0.6rem' }}>
<div key={note.id} style={{ background: 'rgba(217,119,6,0.08)', border: '1px solid rgba(217,119,6,0.2)', padding: '0.6rem', borderRadius: '4px' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-amber)', fontSize: '0.65rem', marginBottom: '0.2rem' }}>
{note.authorName} &mdash; {formatDateTime(note.createdAt)}
</div>

View File

@@ -17,8 +17,8 @@ function StatCard({ label, value, accent = 'green' }: StatCardProps) {
return (
<div
style={{
background: '#0a0d0a',
border: '1px solid #1a2a1a',
background: 'var(--color-surface)',
border: '1px solid var(--color-border)',
padding: '1.25rem',
display: 'flex',
flexDirection: 'column',
@@ -47,8 +47,8 @@ function NavTile({ to, label, description, icon }: NavTileProps) {
<Link
to={to}
style={{
background: '#0a0d0a',
border: '1px solid #1a2a1a',
background: 'var(--color-surface)',
border: '1px solid var(--color-border)',
padding: '1.5rem',
display: 'flex',
flexDirection: 'column',
@@ -57,12 +57,12 @@ function NavTile({ to, label, description, icon }: NavTileProps) {
transition: 'border-color 0.2s, background 0.2s',
}}
onMouseEnter={(e) => {
(e.currentTarget as HTMLAnchorElement).style.borderColor = 'rgba(255,176,0,0.4)';
(e.currentTarget as HTMLAnchorElement).style.background = 'rgba(255,176,0,0.03)';
(e.currentTarget as HTMLAnchorElement).style.borderColor = 'var(--color-yellow)';
(e.currentTarget as HTMLAnchorElement).style.background = 'rgba(37,99,235,0.05)';
}}
onMouseLeave={(e) => {
(e.currentTarget as HTMLAnchorElement).style.borderColor = '#1a2a1a';
(e.currentTarget as HTMLAnchorElement).style.background = '#0a0d0a';
(e.currentTarget as HTMLAnchorElement).style.borderColor = 'var(--color-border)';
(e.currentTarget as HTMLAnchorElement).style.background = 'var(--color-surface)';
}}
>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-amber)', fontSize: '0.75rem', letterSpacing: '0.1em' }}>
@@ -134,13 +134,13 @@ export default function IntranetDashboard() {
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.7rem', letterSpacing: '0.15em', marginBottom: '1rem' }}>
RECENT TEAM ACTIVITY
</div>
<div style={{ background: '#0a0d0a', border: '1px solid #1a2a1a' }}>
<div style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)' }}>
{MOCK_STAFF_POSTS.slice(0, 4).map((post, idx) => (
<div
key={post.id}
style={{
padding: '0.85rem 1.25rem',
borderBottom: idx < 3 ? '1px solid #1a2a1a' : 'none',
borderBottom: idx < 3 ? '1px solid var(--color-border)' : 'none',
}}
>
<div style={{ display: 'flex', justifyContent: 'space-between', gap: '1rem', marginBottom: '0.3rem', flexWrap: 'wrap' }}>

View File

@@ -12,15 +12,15 @@ const ROLE_COLORS: Record<UserRole, string> = {
function FeedPost({ post }: { post: StaffPost }) {
return (
<div style={{ background: '#0a0d0a', border: '1px solid #1a2a1a', padding: '1.1rem 1.25rem' }}>
<div style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)', padding: '1.1rem 1.25rem' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: '1rem', marginBottom: '0.5rem', flexWrap: 'wrap' }}>
<div style={{ display: 'flex', alignItems: 'center', gap: '0.6rem' }}>
<div
style={{
width: '30px',
height: '30px',
background: 'rgba(255,176,0,0.08)',
border: '1px solid rgba(255,176,0,0.2)',
background: 'rgba(217,119,6,0.1)',
border: '1px solid rgba(217,119,6,0.25)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
@@ -28,6 +28,7 @@ function FeedPost({ post }: { post: StaffPost }) {
color: 'var(--color-amber)',
fontSize: '0.85rem',
flexShrink: 0,
borderRadius: '4px',
}}
>
{post.authorName[0].toUpperCase()}
@@ -39,14 +40,15 @@ function FeedPost({ post }: { post: StaffPost }) {
<span
style={{
fontFamily: 'var(--font-mono)',
background: 'rgba(255,176,0,0.08)',
border: '1px solid rgba(255,176,0,0.2)',
background: 'rgba(217,119,6,0.1)',
border: '1px solid rgba(217,119,6,0.25)',
color: 'var(--color-amber)',
fontSize: '0.6rem',
padding: '0.05rem 0.35rem',
marginLeft: '0.5rem',
letterSpacing: '0.08em',
textTransform: 'uppercase',
borderRadius: '3px',
}}
>
{post.authorRole}
@@ -106,7 +108,7 @@ export default function IntranetFeed() {
</div>
{/* Compose */}
<div style={{ background: '#0a0d0a', border: '1px solid #1a2a1a', padding: '1.25rem', marginBottom: '1.5rem' }}>
<div style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)', padding: '1.25rem', marginBottom: '1.5rem' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-amber)', fontSize: '0.7rem', letterSpacing: '0.1em', marginBottom: '0.75rem' }}>
[{user?.username} {user?.role}] Post an update
</div>

View File

@@ -56,7 +56,7 @@ export default function IntranetModeration() {
</div>
{/* Tabs */}
<div style={{ display: 'flex', borderBottom: '1px solid #1a2a1a', marginBottom: '1.5rem', gap: 0 }}>
<div style={{ display: 'flex', borderBottom: '1px solid var(--color-border)', marginBottom: '1.5rem', gap: 0 }}>
{(['threads', 'replies'] as const).map((tab) => (
<button
key={tab}
@@ -96,8 +96,8 @@ export default function IntranetModeration() {
<div
key={thread.id}
style={{
background: selectedThreadId === thread.id ? 'rgba(255,176,0,0.04)' : '#0a0d0a',
border: `1px solid ${selectedThreadId === thread.id ? 'rgba(255,176,0,0.25)' : '#1a2a1a'}`,
background: selectedThreadId === thread.id ? 'rgba(37,99,235,0.08)' : 'var(--color-surface)',
border: `1px solid ${selectedThreadId === thread.id ? 'var(--color-yellow)' : 'var(--color-border)'}`,
padding: '0.85rem 1.1rem',
}}
>
@@ -147,7 +147,7 @@ export default function IntranetModeration() {
</div>
))}
{filteredThreads.length === 0 && (
<div style={{ padding: '2rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)', fontSize: '0.8rem', background: '#0a0d0a', border: '1px solid #1a2a1a' }}>
<div style={{ padding: '2rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)', fontSize: '0.8rem', background: 'var(--color-surface)', border: '1px solid var(--color-border)' }}>
No threads found.
</div>
)}
@@ -156,7 +156,7 @@ export default function IntranetModeration() {
{/* Thread replies panel */}
{selectedThreadId && (
<div style={{ background: '#0a0d0a', border: '1px solid #1a2a1a', padding: '1.25rem', position: 'sticky', top: '1rem' }}>
<div style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)', padding: '1.25rem', position: 'sticky', top: '1rem' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '1rem' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-amber)', fontSize: '0.7rem', letterSpacing: '0.1em' }}>
REPLIES ({selectedThreadReplies.length})
@@ -168,7 +168,7 @@ export default function IntranetModeration() {
) : (
<div style={{ display: 'flex', flexDirection: 'column', gap: '0.5rem' }}>
{selectedThreadReplies.map((reply) => (
<div key={reply.id} style={{ background: '#0d110d', border: '1px solid #1a2a1a', padding: '0.75rem' }}>
<div key={reply.id} style={{ background: 'var(--color-surface-alt)', border: '1px solid var(--color-border)', padding: '0.75rem' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '0.35rem' }}>
<span style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-dim)', fontSize: '0.72rem' }}>{reply.authorName}</span>
<button
@@ -196,7 +196,7 @@ export default function IntranetModeration() {
{recentReplies.map((reply) => {
const thread = threads.find((t) => t.id === reply.threadId);
return (
<div key={reply.id} style={{ background: '#0a0d0a', border: '1px solid #1a2a1a', padding: '0.85rem 1.1rem' }}>
<div key={reply.id} style={{ background: 'var(--color-surface)', border: '1px solid var(--color-border)', padding: '0.85rem 1.1rem' }}>
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: '0.75rem', flexWrap: 'wrap' }}>
<div style={{ flex: 1, minWidth: 0 }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.68rem', marginBottom: '0.2rem' }}>
@@ -220,7 +220,7 @@ export default function IntranetModeration() {
);
})}
{recentReplies.length === 0 && (
<div style={{ padding: '2rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)', fontSize: '0.8rem', background: '#0a0d0a', border: '1px solid #1a2a1a' }}>
<div style={{ padding: '2rem', textAlign: 'center', color: 'var(--color-text-muted)', fontFamily: 'var(--font-mono)', fontSize: '0.8rem', background: 'var(--color-surface)', border: '1px solid var(--color-border)' }}>
No replies found.
</div>
)}

View File

@@ -70,9 +70,9 @@ export default function IntranetUsers() {
{/* Confirm dialog */}
{confirmAction && (
<div style={{ background: 'rgba(0,0,0,0.8)', position: 'fixed', inset: 0, zIndex: 200, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
<div style={{ background: 'rgba(0,0,0,0.3)', position: 'fixed', inset: 0, zIndex: 200, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
onClick={() => setConfirmAction(null)}>
<div style={{ background: '#0a0d0a', border: '1px solid var(--color-amber)', padding: '2rem', maxWidth: '380px', width: '90%' }}
<div style={{ background: 'var(--color-surface)', border: '2px solid var(--color-yellow)', padding: '2rem', maxWidth: '380px', width: '90%', borderRadius: '8px' }}
onClick={(e) => e.stopPropagation()}>
<h3 style={{ fontFamily: 'var(--font-heading)', color: 'var(--color-text)', marginBottom: '1rem' }}>CONFIRM ACTION</h3>
<p style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.82rem', marginBottom: '1.5rem', lineHeight: 1.7 }}>
@@ -103,7 +103,7 @@ export default function IntranetUsers() {
<div style={{ overflowX: 'auto' }}>
<table style={{ width: '100%', borderCollapse: 'collapse', fontFamily: 'var(--font-mono)', fontSize: '0.78rem' }}>
<thead>
<tr style={{ borderBottom: '1px solid #1a2a1a' }}>
<tr style={{ borderBottom: '1px solid var(--color-border)' }}>
{['Username', 'Email', 'Role', 'Joined', 'Threads', 'Bugs', 'Status', 'Actions'].map((h) => (
<th key={h} style={{ padding: '0.6rem 0.75rem', textAlign: 'left', color: 'var(--color-text-muted)', fontWeight: 'normal', letterSpacing: '0.1em', fontSize: '0.68rem', textTransform: 'uppercase', whiteSpace: 'nowrap' }}>
{h}
@@ -117,7 +117,7 @@ export default function IntranetUsers() {
return (
<tr
key={u.id}
style={{ borderBottom: '1px solid #111811', background: u.isBanned ? 'rgba(255,34,68,0.03)' : 'transparent' }}
style={{ borderBottom: '1px solid var(--color-border)', background: u.isBanned ? 'rgba(220,38,38,0.05)' : 'transparent' }}
>
<td style={{ padding: '0.7rem 0.75rem', color: 'var(--color-text)', fontWeight: isSelf ? 'bold' : 'normal' }}>
{u.username} {isSelf && <span style={{ color: 'var(--color-amber)', fontSize: '0.65rem' }}>(you)</span>}

View File

@@ -161,8 +161,8 @@ export default function BugDetailPage() {
<div
key={label}
style={{
background: 'rgba(0,0,0,0.4)',
border: '1px solid var(--color-border-dim)',
background: 'var(--color-surface-alt)',
border: '1px solid var(--color-border)',
padding: '0.55rem 0.7rem',
}}
>
@@ -179,14 +179,15 @@ export default function BugDetailPage() {
<div className="section-label" style={{ marginBottom: '0.4rem' }}>Description</div>
<div
style={{
background: 'rgba(0,0,0,0.4)',
border: '1px solid var(--color-border-dim)',
background: 'var(--color-surface-alt)',
border: '1px solid var(--color-border)',
padding: '0.9rem 1rem',
fontFamily: 'var(--font-mono)',
color: 'var(--color-text-dim)',
fontSize: '0.83rem',
lineHeight: 1.8,
whiteSpace: 'pre-wrap',
borderRadius: '6px',
}}
>
{bug.description}
@@ -198,14 +199,15 @@ export default function BugDetailPage() {
<div className="section-label" style={{ marginBottom: '0.4rem' }}>Steps to Reproduce</div>
<div
style={{
background: 'rgba(0,0,0,0.4)',
border: '1px solid var(--color-border-dim)',
background: 'var(--color-surface-alt)',
border: '1px solid var(--color-border)',
padding: '0.9rem 1rem',
fontFamily: 'var(--font-mono)',
color: 'var(--color-text-dim)',
fontSize: '0.83rem',
lineHeight: 1.8,
whiteSpace: 'pre-wrap',
borderRadius: '6px',
}}
>
{bug.stepsToReproduce}
@@ -220,12 +222,13 @@ export default function BugDetailPage() {
gap: '1rem',
flexWrap: 'wrap',
padding: '0.9rem 1rem',
background: 'rgba(0,255,255,0.04)',
border: '1px solid var(--color-border)',
background: 'rgba(5,150,105,0.05)',
border: '1px solid rgba(5,150,105,0.2)',
borderRadius: '6px',
}}
>
{/* Count */}
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-cyan)', fontSize: '0.82rem' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-green)', fontSize: '0.82rem' }}>
<span style={{ fontSize: '1.1rem' }}>{metooCount}</span>{' '}
{metooCount === 1 ? 'user has' : 'users have'} this issue
</div>
@@ -244,11 +247,12 @@ export default function BugDetailPage() {
style={{
fontFamily: 'var(--font-mono)',
fontSize: '0.78rem',
color: '#00ffaa',
border: '1px solid #00ffaa',
color: 'var(--color-green)',
border: '1px solid var(--color-green)',
padding: '0.25rem 0.75rem',
background: 'rgba(0,255,170,0.07)',
background: 'rgba(5,150,105,0.08)',
cursor: 'default',
borderRadius: '4px',
}}
>
&#10003; You reported this too

View File

@@ -71,11 +71,12 @@ function BugCard({ bug, highlight }: BugCardProps) {
style={{
fontFamily: 'var(--font-mono)',
fontSize: '0.65rem',
color: 'var(--color-cyan)',
border: '1px solid var(--color-cyan)',
color: 'var(--color-green)',
border: '1px solid var(--color-green)',
padding: '0.05rem 0.4rem',
background: 'rgba(0,255,255,0.06)',
background: 'rgba(5,150,105,0.08)',
whiteSpace: 'nowrap',
borderRadius: '3px',
}}
>
&#9654; {bug.meTooBugs.length} {bug.meTooBugs.length === 1 ? 'user' : 'users'} have this
@@ -316,7 +317,7 @@ export default function BugReportPage() {
<p style={{ color: 'var(--color-text-muted)', fontSize: '0.78rem', marginTop: '0.5rem', fontFamily: 'var(--font-mono)' }}>
<span style={{ color: 'var(--color-cyan)' }}>{openCount}</span> open &nbsp;&mdash;&nbsp;
<span style={{ color: 'var(--color-yellow)' }}>{inProgressCount}</span> in progress &nbsp;&mdash;&nbsp;
<span style={{ color: '#00ffaa' }}>{resolvedCount}</span> resolved
<span style={{ color: 'var(--color-green)' }}>{resolvedCount}</span> resolved
</p>
</div>

View File

@@ -82,7 +82,7 @@ function CategoryCard({ category, threads }: { category: ForumCategory; threads:
justifyContent: 'space-between',
gap: '1rem',
flexWrap: 'wrap',
background: thread.isPinned ? 'rgba(255,176,0,0.03)' : 'transparent',
background: thread.isPinned ? 'rgba(217,119,6,0.05)' : 'transparent',
}}
>
<div style={{ flex: 1, minWidth: '0' }}>

View File

@@ -45,27 +45,27 @@ function HeroSection() {
padding: '4rem 1.5rem',
}}
>
{/* Minitel background — deep navy with subtle cyan tint */}
{/* Subtle gradient background */}
<div
style={{
position: 'absolute',
inset: 0,
background: `
radial-gradient(ellipse 70% 50% at 50% 40%, rgba(0,0,80,0.7) 0%, transparent 70%),
radial-gradient(ellipse 70% 50% at 50% 40%, rgba(37,99,235,0.05) 0%, transparent 70%),
var(--color-bg)
`,
zIndex: 0,
}}
/>
{/* Grid lines — Minitel character grid feel */}
{/* Grid lines — subtle pattern */}
<div
style={{
position: 'absolute',
inset: 0,
backgroundImage: `
linear-gradient(rgba(0,0,204,0.15) 1px, transparent 1px),
linear-gradient(90deg, rgba(0,0,204,0.15) 1px, transparent 1px)
linear-gradient(rgba(200,200,200,0.3) 1px, transparent 1px),
linear-gradient(90deg, rgba(200,200,200,0.3) 1px, transparent 1px)
`,
backgroundSize: '40px 40px',
zIndex: 0,
@@ -280,7 +280,7 @@ function GameplaySection() {
id="gameplay"
style={{
padding: '6rem 1.5rem',
background: 'rgba(0,0,0,0.2)',
background: 'var(--color-bg-alt)',
borderTop: '1px solid var(--color-border)',
borderBottom: '1px solid var(--color-border)',
}}
@@ -424,12 +424,13 @@ function VisualStyleSection() {
style={{
marginTop: '2rem',
padding: '1.25rem',
background: 'rgba(0,255,65,0.03)',
border: '1px solid rgba(0,255,65,0.1)',
background: 'rgba(5,150,105,0.05)',
border: '1px solid rgba(5,150,105,0.15)',
fontFamily: 'var(--font-mono)',
color: 'var(--color-text-muted)',
fontSize: '0.8rem',
lineHeight: 1.8,
borderRadius: '6px',
}}
>
<span style={{ color: 'var(--color-green)' }}>&gt; </span>

View File

@@ -60,7 +60,7 @@ export default function LoginPage() {
<form onSubmit={handleSubmit} noValidate className="crt-box" style={{ padding: '2rem' }}>
{/* Demo hint */}
<div style={{ background: 'rgba(255,176,0,0.06)', border: '1px solid rgba(255,176,0,0.2)', padding: '0.75rem', marginBottom: '1.5rem' }}>
<div style={{ background: 'rgba(217,119,6,0.08)', border: '1px solid rgba(217,119,6,0.2)', padding: '0.75rem', marginBottom: '1.5rem', borderRadius: '6px' }}>
<div style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-amber)', fontSize: '0.7rem', letterSpacing: '0.05em', marginBottom: '0.4rem' }}>
[DEMO] Quick login emails:
</div>
@@ -92,7 +92,7 @@ export default function LoginPage() {
</div>
{errors.form && (
<div style={{ background: 'rgba(255,34,68,0.08)', border: '1px solid rgba(255,34,68,0.3)', color: 'var(--color-red)', fontFamily: 'var(--font-mono)', fontSize: '0.78rem', padding: '0.75rem', marginBottom: '1.25rem' }}>
<div style={{ background: 'rgba(220,38,38,0.1)', border: '1px solid rgba(220,38,38,0.3)', color: 'var(--color-red)', fontFamily: 'var(--font-mono)', fontSize: '0.78rem', padding: '0.75rem', marginBottom: '1.25rem', borderRadius: '6px' }}>
[ERROR] {errors.form}
</div>
)}

View File

@@ -30,7 +30,7 @@ export default function NotFoundPage() {
</div>
<p style={{ fontFamily: 'var(--font-mono)', color: 'var(--color-text-muted)', fontSize: '0.85rem', maxWidth: '400px', margin: '0 auto 2rem', lineHeight: 1.8 }}>
The page you're looking for doesn't exist, has been moved, or was redacted by{' '}
<span style={{ background: '#111', padding: '0 4px', color: 'transparent', border: '1px solid rgba(255,34,68,0.3)' }}>
<span style={{ background: '#6b7280', padding: '0 4px', color: 'transparent', border: '1px solid var(--color-red)' }}>
AMALGAM CORP
</span>.
</p>

View File

@@ -72,7 +72,7 @@ export default function RegisterPage() {
<form onSubmit={handleSubmit} noValidate className="crt-box" style={{ padding: '2rem' }}>
{errors.form && (
<div style={{ background: 'rgba(255,34,68,0.08)', border: '1px solid rgba(255,34,68,0.3)', color: 'var(--color-red)', fontFamily: 'var(--font-mono)', fontSize: '0.78rem', padding: '0.75rem', marginBottom: '1.25rem' }}>
<div style={{ background: 'rgba(220,38,38,0.1)', border: '1px solid rgba(220,38,38,0.3)', color: 'var(--color-red)', fontFamily: 'var(--font-mono)', fontSize: '0.78rem', padding: '0.75rem', marginBottom: '1.25rem', borderRadius: '6px' }}>
[ERROR] {errors.form}
</div>
)}