Files
xtremflow/Theme/admin_panel_xtremflow_redesign/code.html
T
MichaelandClaude Fable 5 60d3f42901 feat: security hardening, streaming overhaul, design polish, tests
Security:
- Replace unsalted SHA-256 password hashing with bcrypt (lazy rehash on login)
- Add authenticated /api/xtream-api gateway: Xtream credentials are injected
  server-side and never sent to the frontend; /api/playlists no longer
  returns passwords
- Redact credentials from all logs (login body, proxy/FFmpeg/scheduler URLs)
- Add auth to recordings, EPG, season-passes and streaming routes
  (HttpOnly session cookie for hls.js; loopback bypass for local FFmpeg)
- Lock player postMessage to same-origin in both directions
- Vendor and pin hls.js 1.6.7 / mpegts.js 1.7.3 (drop CDN @latest)
- Fix rate limiter (client IP was never resolved), add login rate limit,
  restrict CORS, add CSP Report-Only, block private-IP SSRF targets,
  fix path traversal in recording log retrieval, chmod 777 -> 770
- Remove dead HiveService (seeded admin/admin into IndexedDB with SHA-256)
- Fix authMiddleware not populating 'user' context (getPlaylist ignored the
  logged-in user; admin purge always returned 403)

Streaming:
- New FfmpegSessionManager: process registry, idle reaper (4 min live /
  15 min VOD), orphan cleanup at startup, clean SIGTERM shutdown,
  fast-fail with stderr instead of 30 s timeout
- Quality selection (source/high/medium/low) for live and VOD; source mode
  streams with -c:v copy (zero transcoding); selector wired into the player
- Concurrent recordings (MAX_CONCURRENT_RECORDINGS, default 2); conflicts
  retry on the next tick instead of silently failing
- Lower live latency (HLS window 20 -> 10 segments, liveSync 10 -> 3)
- Fix recording log lookup (.mp4 vs .mkv mismatch)

Design:
- Replace hardcoded colors with AppColors tokens (12 files)
- web/theme.css syncs HTML players with the Flutter palette
- DPAD/keyboard navigation (arrow-key focus, player shortcuts)
- Tooltips on player icon buttons, Semantics on content cards
- Remove 7 dead widgets broken since the Stitch merge

Quality:
- bin/test/: 21 unit tests (bcrypt, redaction, traversal, SSRF, recording
  conflicts) plus a quality-selector widget test
- GitHub Actions CI (analyze + test + build web)
- Archive stale status docs into docs/archive/

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-10 10:07:18 +02:00

442 lines
26 KiB
HTML

<!DOCTYPE html>
<html class="dark" lang="en"><head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1.0" name="viewport"/>
<title>XtremFlow - Admin Settings</title>
<script src="https://cdn.tailwindcss.com?plugins=forms,container-queries"></script>
<link href="https://fonts.googleapis.com" rel="preconnect"/>
<link crossorigin="" href="https://fonts.gstatic.com" rel="preconnect"/>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&amp;family=Space+Grotesk:wght@500;600;700;900&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght,FILL@100..700,0..1&amp;display=swap" rel="stylesheet"/>
<script id="tailwind-config">
tailwind.config = {
darkMode: "class",
theme: {
extend: {
"colors": {
"surface-variant": "#343439",
"primary-fixed": "#d8e2ff",
"surface-bright": "#38393d",
"on-tertiary-container": "#282a2a",
"error-container": "#93000a",
"on-secondary": "#2f3037",
"on-primary-fixed-variant": "#004493",
"tertiary-container": "#909191",
"surface-container-lowest": "#0d0e12",
"inverse-on-surface": "#2f3035",
"surface-container-highest": "#343439",
"surface": "#121317",
"secondary-fixed-dim": "#c6c5cf",
"on-tertiary": "#2f3131",
"surface-dim": "#121317",
"on-secondary-fixed": "#1a1b22",
"on-primary": "#002e69",
"primary": "#adc6ff",
"primary-fixed-dim": "#adc6ff",
"outline": "#8b90a0",
"secondary": "#c6c5cf",
"surface-tint": "#adc6ff",
"surface-container-high": "#292a2e",
"on-tertiary-fixed-variant": "#454747",
"error": "#ffb4ab",
"on-surface": "#e3e2e7",
"secondary-container": "#4a4b53",
"on-primary-fixed": "#001a41",
"tertiary-fixed": "#e2e2e2",
"on-secondary-container": "#bcbbc4",
"on-secondary-fixed-variant": "#46464e",
"inverse-primary": "#005bc1",
"primary-container": "#4b8eff",
"tertiary": "#c6c6c7",
"inverse-surface": "#e3e2e7",
"on-error-container": "#ffdad6",
"surface-container": "#1f1f24",
"on-tertiary-fixed": "#1a1c1c",
"surface-container-low": "#1a1b20",
"on-error": "#690005",
"tertiary-fixed-dim": "#c6c6c7",
"secondary-fixed": "#e3e1eb",
"on-surface-variant": "#c1c6d7",
"on-background": "#e3e2e7",
"outline-variant": "#414755",
"background": "#121317",
"on-primary-container": "#00285c"
},
"borderRadius": {
"DEFAULT": "0.25rem",
"lg": "0.5rem",
"xl": "0.75rem",
"full": "9999px"
},
"spacing": {
"base": "8px",
"xl": "80px",
"lg": "48px",
"md": "24px",
"sm": "12px",
"xs": "4px",
"margin": "32px",
"gutter": "24px"
},
"fontFamily": {
"body-md": ["Inter"],
"headline-lg": ["Space Grotesk"],
"label-lg": ["Inter"],
"headline-xl": ["Space Grotesk"],
"label-sm": ["Inter"],
"body-lg": ["Inter"],
"headline-md": ["Space Grotesk"]
},
"fontSize": {
"body-md": ["16px", {"lineHeight": "1.5", "fontWeight": "400"}],
"headline-lg": ["32px", {"lineHeight": "1.2", "letterSpacing": "-0.01em", "fontWeight": "600"}],
"label-lg": ["14px", {"lineHeight": "1.2", "letterSpacing": "0.05em", "fontWeight": "600"}],
"headline-xl": ["48px", {"lineHeight": "1.1", "letterSpacing": "-0.02em", "fontWeight": "700"}],
"label-sm": ["12px", {"lineHeight": "1.2", "letterSpacing": "0.02em", "fontWeight": "500"}],
"body-lg": ["18px", {"lineHeight": "1.6", "fontWeight": "400"}],
"headline-md": ["24px", {"lineHeight": "1.3", "fontWeight": "500"}]
}
}
}
}
</script>
<style>
/* Custom Glassmorphism and Utility Styles not easily covered by Tailwind config alone */
.glass-panel {
background-color: rgba(31, 31, 36, 0.6); /* surface-container with opacity */
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
border: 1px solid rgba(255, 255, 255, 0.1);
}
.glass-panel:hover {
border-color: rgba(255, 255, 255, 0.2);
}
.glow-text {
text-shadow: 0 0 10px rgba(173, 198, 255, 0.5); /* primary color glow */
}
.progress-glow {
box-shadow: 0 0 12px rgba(75, 142, 255, 0.6); /* primary-container glow */
}
/* Custom Scrollbar for sleek look */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: #414755; border-radius: 4px; }
::-webkit-scrollbar-thumb:hover { background: #8b90a0; }
</style>
</head>
<body class="bg-background text-on-background font-body-md text-body-md antialiased overflow-x-hidden selection:bg-primary-container selection:text-white">
<div class="flex min-h-screen w-full relative">
<!-- SideNavBar -->
<nav class="fixed left-0 top-0 h-full w-64 border-r border-white/10 shadow-2xl bg-slate-950/80 backdrop-blur-2xl flex flex-col py-6 z-50">
<div class="px-6 mb-10 flex items-center gap-sm">
<div class="w-10 h-10 rounded-lg bg-gradient-to-br from-primary-container to-[#005bc1] flex items-center justify-center shadow-[0_0_15px_rgba(75,142,255,0.4)]">
<span class="material-symbols-outlined text-white text-[24px]">stream</span>
</div>
<div>
<h1 class="text-xl font-black text-white font-headline-md tracking-tight leading-none">XtremFlow</h1>
<span class="text-xs text-slate-400 font-label-sm uppercase tracking-widest mt-1 block">Media Control</span>
</div>
</div>
<div class="flex-1 overflow-y-auto px-2 space-y-1">
<a class="flex items-center gap-3 px-4 py-3 text-slate-400 hover:bg-white/5 hover:text-slate-100 transition-colors active:translate-x-1 duration-150 font-['Space_Grotesk'] font-medium rounded-lg mx-2" href="#">
<span class="material-symbols-outlined text-[20px]">dashboard</span>
Dashboard
</a>
<a class="flex items-center gap-3 px-4 py-3 text-slate-400 hover:bg-white/5 hover:text-slate-100 transition-colors active:translate-x-1 duration-150 font-['Space_Grotesk'] font-medium rounded-lg mx-2" href="#">
<span class="material-symbols-outlined text-[20px]">video_library</span>
Library
</a>
<a class="flex items-center gap-3 px-4 py-3 text-slate-400 hover:bg-white/5 hover:text-slate-100 transition-colors active:translate-x-1 duration-150 font-['Space_Grotesk'] font-medium rounded-lg mx-2" href="#">
<span class="material-symbols-outlined text-[20px]">insights</span>
Analytics
</a>
<a class="flex items-center gap-3 px-4 py-3 text-slate-400 hover:bg-white/5 hover:text-slate-100 transition-colors active:translate-x-1 duration-150 font-['Space_Grotesk'] font-medium rounded-lg mx-2" href="#">
<span class="material-symbols-outlined text-[20px]">cloud_upload</span>
Media Manager
</a>
<!-- Active Item -->
<a class="flex items-center gap-3 px-4 py-3 text-blue-400 border-l-4 border-blue-500 bg-blue-500/10 active:translate-x-1 duration-150 font-['Space_Grotesk'] font-medium rounded-r-lg ml-2 mr-2" href="#">
<span class="material-symbols-outlined text-[20px]" style="font-variation-settings: 'FILL' 1;">admin_panel_settings</span>
Admin Settings
</a>
</div>
<div class="px-4 mt-auto space-y-1">
<a class="flex items-center gap-3 px-4 py-3 text-slate-400 hover:bg-white/5 hover:text-slate-100 transition-colors active:translate-x-1 duration-150 font-['Space_Grotesk'] font-medium rounded-lg mx-2" href="#">
<span class="material-symbols-outlined text-[20px]">help</span>
Support
</a>
<a class="flex items-center gap-3 px-4 py-3 text-error hover:bg-error/10 transition-colors active:translate-x-1 duration-150 font-['Space_Grotesk'] font-medium rounded-lg mx-2 mt-2" href="#">
<span class="material-symbols-outlined text-[20px]">logout</span>
Logout
</a>
</div>
</nav>
<!-- Main Content Area -->
<main class="ml-64 flex-1 flex flex-col min-h-screen relative w-[calc(100%-16rem)]">
<!-- TopNavBar -->
<header class="docked full-width top-0 sticky z-40 border-b border-white/10 shadow-[0_0_20px_rgba(0,0,0,0.5)] bg-slate-950/50 backdrop-blur-xl flex justify-between items-center w-full px-6 py-3 font-['Space_Grotesk'] text-sm tracking-tight text-blue-500">
<div class="flex items-center gap-6 flex-1">
<div class="relative w-full max-w-md group">
<span class="material-symbols-outlined absolute left-3 top-1/2 -translate-y-1/2 text-slate-400 text-[18px] group-focus-within:text-blue-400 transition-colors">search</span>
<input class="w-full bg-[#181920] border border-outline-variant/50 rounded-full pl-10 pr-4 py-2 text-on-surface focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 focus:bg-[#1f2029] transition-all placeholder:text-slate-500 font-body-md text-sm" placeholder="Search system resources, users, or settings..." type="text"/>
</div>
</div>
<div class="flex items-center gap-sm ml-auto">
<button class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-white/5 hover:text-white transition-all active:scale-95 duration-200 relative text-slate-400">
<span class="material-symbols-outlined">notifications</span>
<span class="absolute top-2 right-2 w-2 h-2 bg-blue-500 rounded-full shadow-[0_0_8px_rgba(59,130,246,0.8)]"></span>
</button>
<button class="w-10 h-10 flex items-center justify-center rounded-full hover:bg-white/5 hover:text-white transition-all active:scale-95 duration-200 text-slate-400">
<span class="material-symbols-outlined">settings</span>
</button>
<div class="w-px h-6 bg-white/10 mx-2"></div>
<button class="flex items-center gap-2 hover:bg-white/5 p-1 pr-3 rounded-full transition-all border border-transparent hover:border-white/10">
<img alt="User profile avatar" class="w-8 h-8 rounded-full border border-white/20 object-cover" data-alt="Portrait of a male user with glasses and short dark hair against a light background" src="https://lh3.googleusercontent.com/aida-public/AB6AXuDba2WTdK70Rwv4MbN3nX7oK51wv0COSzCNRPk7ZjzoVkwQHRY1f9Bj-SHsmp8AEdOfovgsacwFO_lDg9MyaqRQyUm_VRuVACWugh---Z_lhHUjs0rO-OUvz72Evds-I7XmIVszJsYbdvBUmUx41xf4TgBcIULjOdM8o8Gqd9sErK33Mqb7FS55FC-Xw-ryt18A7UH4iH215IRWQVYUQ3hFZRm1QGb0oKKoXTRBk5_LnAKgeh4LkTTmKnUjywfNDzFh05E42-Jv8HY"/>
<span class="text-slate-200 font-medium text-sm hidden lg:block">Admin</span>
<span class="material-symbols-outlined text-[16px] text-slate-400">expand_more</span>
</button>
</div>
</header>
<!-- Page Content -->
<div class="p-margin flex-1 flex flex-col gap-lg max-w-[1600px] w-full mx-auto">
<!-- Page Header -->
<div class="flex flex-col md:flex-row md:items-end justify-between gap-md">
<div>
<h2 class="font-headline-xl text-headline-xl text-white tracking-tight mb-xs">System Administration</h2>
<p class="font-body-md text-body-md text-on-surface-variant max-w-2xl">Monitor server performance, manage user access levels, and configure global environment variables for the XtremFlow network.</p>
</div>
<div class="flex gap-sm">
<button class="px-md py-sm rounded-lg font-label-lg text-label-lg border border-outline-variant bg-surface-container/30 text-on-surface hover:bg-surface-container/50 hover:border-outline transition-all flex items-center gap-2">
<span class="material-symbols-outlined text-[18px]">download</span> Export Logs
</button>
<button class="bg-gradient-to-r from-[#007AFF] to-[#00c6ff] text-white px-md py-sm rounded-lg font-label-lg text-label-lg shadow-[0_4px_15px_rgba(0,122,255,0.3)] hover:shadow-[0_6px_20px_rgba(0,122,255,0.5)] hover:scale-[1.02] transition-all flex items-center gap-2 border border-blue-400/30">
<span class="material-symbols-outlined text-[18px]">person_add</span> Add User
</button>
</div>
</div>
<!-- Server Performance Bento Grid -->
<section class="grid grid-cols-1 lg:grid-cols-12 gap-gutter">
<!-- CPU Node -->
<div class="col-span-1 lg:col-span-4 glass-panel rounded-xl p-md flex flex-col relative overflow-hidden group">
<div class="absolute top-0 right-0 w-32 h-32 bg-blue-500/10 rounded-full blur-[40px] -mr-10 -mt-10 pointer-events-none"></div>
<div class="flex justify-between items-start mb-lg relative z-10">
<div>
<h3 class="font-headline-md text-sm text-on-surface-variant uppercase tracking-wider mb-1">Core Processing</h3>
<div class="font-headline-xl text-3xl text-white glow-text">78%</div>
</div>
<div class="w-10 h-10 rounded bg-blue-500/20 border border-blue-500/30 flex items-center justify-center text-blue-400">
<span class="material-symbols-outlined text-[20px]">memory</span>
</div>
</div>
<div class="mt-auto relative z-10">
<div class="flex justify-between text-xs text-on-surface-variant mb-2">
<span>Load Average: 2.14, 2.05, 1.98</span>
<span class="text-blue-400">Stable</span>
</div>
<div class="h-2 w-full bg-surface-container-highest/80 rounded-full overflow-hidden">
<div class="h-full bg-gradient-to-r from-blue-600 to-[#00A3FF] w-[78%] rounded-full progress-glow relative">
<div class="absolute top-0 right-0 bottom-0 w-4 bg-white/20 blur-[2px]"></div>
</div>
</div>
</div>
</div>
<!-- Memory Node -->
<div class="col-span-1 lg:col-span-4 glass-panel rounded-xl p-md flex flex-col relative overflow-hidden">
<div class="absolute top-0 right-0 w-32 h-32 bg-purple-500/10 rounded-full blur-[40px] -mr-10 -mt-10 pointer-events-none"></div>
<div class="flex justify-between items-start mb-lg relative z-10">
<div>
<h3 class="font-headline-md text-sm text-on-surface-variant uppercase tracking-wider mb-1">Active Memory</h3>
<div class="font-headline-xl text-3xl text-white">42<span class="text-lg text-slate-400 ml-1">GB</span></div>
</div>
<div class="w-10 h-10 rounded bg-purple-500/20 border border-purple-500/30 flex items-center justify-center text-purple-400">
<span class="material-symbols-outlined text-[20px]">dns</span>
</div>
</div>
<div class="mt-auto relative z-10">
<div class="flex justify-between text-xs text-on-surface-variant mb-2">
<span>64 GB Total Capacity</span>
<span class="text-purple-400">65% Utilized</span>
</div>
<div class="h-2 w-full bg-surface-container-highest/80 rounded-full overflow-hidden">
<div class="h-full bg-gradient-to-r from-purple-600 to-purple-400 w-[65%] rounded-full shadow-[0_0_10px_rgba(168,85,247,0.5)]"></div>
</div>
</div>
</div>
<!-- Network Stats (List) -->
<div class="col-span-1 lg:col-span-4 glass-panel rounded-xl p-md flex flex-col">
<div class="flex items-center gap-2 mb-md">
<span class="material-symbols-outlined text-tertiary-container text-[20px]">swap_vert</span>
<h3 class="font-headline-md text-sm text-white uppercase tracking-wider">Network I/O</h3>
</div>
<div class="space-y-4 flex-1 flex flex-col justify-center">
<div class="flex justify-between items-center bg-surface-container-low/50 p-3 rounded-lg border border-white/5">
<div class="flex items-center gap-3">
<span class="material-symbols-outlined text-green-400 text-[18px]">south_west</span>
<span class="text-sm text-slate-300">Inbound Traffic</span>
</div>
<span class="font-mono text-white text-sm">2.4 GB/s</span>
</div>
<div class="flex justify-between items-center bg-surface-container-low/50 p-3 rounded-lg border border-white/5">
<div class="flex items-center gap-3">
<span class="material-symbols-outlined text-blue-400 text-[18px]">north_east</span>
<span class="text-sm text-slate-300">Outbound Traffic</span>
</div>
<span class="font-mono text-white text-sm">8.1 GB/s</span>
</div>
</div>
</div>
</section>
<!-- Two Column Layout: Users & Settings -->
<div class="grid grid-cols-1 xl:grid-cols-3 gap-gutter items-start">
<!-- User Management Table (Spans 2 columns) -->
<div class="xl:col-span-2 glass-panel rounded-xl flex flex-col overflow-hidden">
<div class="p-md border-b border-white/10 flex justify-between items-center bg-surface-container/40">
<div>
<h3 class="font-headline-md text-lg text-white">Active Personnel</h3>
<p class="text-xs text-on-surface-variant mt-1">Manage admin and moderator access levels.</p>
</div>
<div class="flex items-center gap-2">
<span class="w-2 h-2 rounded-full bg-green-500 shadow-[0_0_8px_rgba(34,197,94,0.6)]"></span>
<span class="text-xs text-slate-300 font-medium">12 Online</span>
</div>
</div>
<div class="overflow-x-auto">
<table class="w-full text-left border-collapse">
<thead>
<tr class="border-b border-white/5 bg-surface-container-lowest/50 text-xs text-on-surface-variant uppercase tracking-wider font-label-sm">
<th class="py-4 px-md font-medium">User Profile</th>
<th class="py-4 px-md font-medium">Role Level</th>
<th class="py-4 px-md font-medium">Last Access</th>
<th class="py-4 px-md font-medium text-right">Actions</th>
</tr>
</thead>
<tbody class="text-sm font-body-md divide-y divide-white/5">
<tr class="hover:bg-white/[0.02] transition-colors group">
<td class="py-3 px-md">
<div class="flex items-center gap-3">
<img alt="Sarah Connor" class="w-8 h-8 rounded-full border border-white/10 object-cover" data-alt="Portrait of a young woman with dark hair smiling gently, studio lighting" src="https://lh3.googleusercontent.com/aida-public/AB6AXuDOSTUzzDMCE_BuwwZxnh8dIkjg2kUSd10fIxwI1A24MEqroG8fpglAh7e9CVVvvGdgXiWDiCdBqAzBJB6xhGGboZZr0eyj6j2VEUuqXKJxmXAqJeIkKEuGSRhx3nM4ONT9pPRIo8GuVT7YHKKFksXBNiHsjcfpSz1YWLX5P7dTpwBe1XoeNOQG9JpK7Xv1oGs5P3VL3Tkjn8pIlSjywUkfSQntepl2FggphhNkfv1Xp2yVrZts4mnnWlT5kvtlO93VWy7I0e-N_DA"/>
<div>
<div class="text-slate-200 font-medium">Sarah Connor</div>
<div class="text-xs text-slate-500 font-mono">s.connor@xtremflow.io</div>
</div>
</div>
</td>
<td class="py-3 px-md">
<span class="inline-flex items-center px-2 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider bg-blue-500/10 text-blue-400 border border-blue-500/20">Super Admin</span>
</td>
<td class="py-3 px-md text-slate-400 font-mono text-xs">
2 mins ago<br/><span class="text-[10px] text-slate-500">192.168.1.104</span>
</td>
<td class="py-3 px-md text-right">
<div class="flex items-center justify-end gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
<button class="p-1.5 rounded bg-surface-container hover:bg-surface-bright text-slate-300 hover:text-white transition-colors border border-white/5" title="Edit User">
<span class="material-symbols-outlined text-[16px]">edit</span>
</button>
<button class="p-1.5 rounded bg-error-container/20 hover:bg-error-container/40 text-error hover:text-red-400 transition-colors border border-error/20" title="Revoke Access">
<span class="material-symbols-outlined text-[16px]">block</span>
</button>
</div>
</td>
</tr>
<tr class="hover:bg-white/[0.02] transition-colors group">
<td class="py-3 px-md">
<div class="flex items-center gap-3">
<div class="w-8 h-8 rounded-full bg-purple-500/20 border border-purple-500/30 flex items-center justify-center text-purple-400 text-xs font-bold">JD</div>
<div>
<div class="text-slate-200 font-medium">John Doe</div>
<div class="text-xs text-slate-500 font-mono">j.doe@xtremflow.io</div>
</div>
</div>
</td>
<td class="py-3 px-md">
<span class="inline-flex items-center px-2 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider bg-emerald-500/10 text-emerald-400 border border-emerald-500/20">Moderator</span>
</td>
<td class="py-3 px-md text-slate-400 font-mono text-xs">
1 hour ago<br/><span class="text-[10px] text-slate-500">10.0.0.42</span>
</td>
<td class="py-3 px-md text-right">
<div class="flex items-center justify-end gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
<button class="p-1.5 rounded bg-surface-container hover:bg-surface-bright text-slate-300 hover:text-white transition-colors border border-white/5">
<span class="material-symbols-outlined text-[16px]">edit</span>
</button>
<button class="p-1.5 rounded bg-error-container/20 hover:bg-error-container/40 text-error hover:text-red-400 transition-colors border border-error/20">
<span class="material-symbols-outlined text-[16px]">block</span>
</button>
</div>
</td>
</tr>
<tr class="hover:bg-white/[0.02] transition-colors group">
<td class="py-3 px-md">
<div class="flex items-center gap-3">
<img alt="Michael Chen" class="w-8 h-8 rounded-full border border-white/10 object-cover" data-alt="Portrait of a mature man looking off-camera with a serious expression, dark cinematic lighting" src="https://lh3.googleusercontent.com/aida-public/AB6AXuBXZoQNsetCsvQtmZGvMHjWgkp5jAXgOVpRJalasyuj5OwOB97vYPjvGVFVCKHTXnOaLbGh92sRbKIevyGpcYwTXorOfXPC7oXVNWLulLBRaNDX8CIMU53geIOehL1nZu6d8TmrdmdTcGaVLNu9Mj7jwsLtkXQhnT_-B83c9aW8CdLANPTxCfWzETp1uBvWIGt-7m1NsZCj5wz0Noc2BAAaTZgieX_HFKXVOSEVw43h962mbE4AfMtzeV-Ea78aGuFD1u5KRLq3a60"/>
<div>
<div class="text-slate-200 font-medium">Michael Chen</div>
<div class="text-xs text-slate-500 font-mono">m.chen@xtremflow.io</div>
</div>
</div>
</td>
<td class="py-3 px-md">
<span class="inline-flex items-center px-2 py-1 rounded-full text-[10px] font-bold uppercase tracking-wider bg-slate-500/10 text-slate-400 border border-slate-500/20">Viewer</span>
</td>
<td class="py-3 px-md text-slate-400 font-mono text-xs">
Yesterday<br/><span class="text-[10px] text-slate-500">172.16.0.5</span>
</td>
<td class="py-3 px-md text-right">
<div class="flex items-center justify-end gap-2 opacity-0 group-hover:opacity-100 transition-opacity">
<button class="p-1.5 rounded bg-surface-container hover:bg-surface-bright text-slate-300 hover:text-white transition-colors border border-white/5">
<span class="material-symbols-outlined text-[16px]">edit</span>
</button>
<button class="p-1.5 rounded bg-error-container/20 hover:bg-error-container/40 text-error hover:text-red-400 transition-colors border border-error/20">
<span class="material-symbols-outlined text-[16px]">block</span>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="p-3 border-t border-white/5 bg-surface-container-lowest/30 flex justify-center">
<button class="text-xs text-blue-400 hover:text-blue-300 font-medium transition-colors flex items-center gap-1">View All Users <span class="material-symbols-outlined text-[14px]">arrow_forward</span></button>
</div>
</div>
<!-- System Settings Form -->
<div class="glass-panel rounded-xl p-md flex flex-col h-full">
<div class="flex items-center gap-3 mb-6">
<span class="material-symbols-outlined text-slate-300">tune</span>
<h3 class="font-headline-md text-lg text-white">Environment Config</h3>
</div>
<form class="space-y-5 flex-1 flex flex-col">
<div>
<label class="block text-xs font-label-sm text-slate-400 mb-1.5 uppercase tracking-wider">Streaming Endpoint</label>
<input class="w-full bg-[#121317] border border-outline-variant/60 rounded-lg px-3 py-2 text-sm text-slate-200 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 font-mono transition-all" type="text" value="rtmp://ingest.xtremflow.io/live"/>
</div>
<div>
<label class="block text-xs font-label-sm text-slate-400 mb-1.5 uppercase tracking-wider">Max Concurrent Streams</label>
<div class="relative">
<input class="w-full bg-[#121317] border border-outline-variant/60 rounded-lg px-3 py-2 text-sm text-slate-200 focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500 transition-all font-mono" type="number" value="1000"/>
<span class="absolute right-3 top-1/2 -translate-y-1/2 text-xs text-slate-500">connections</span>
</div>
</div>
<div class="flex items-center justify-between p-3 rounded-lg bg-surface-container-low/50 border border-white/5 mt-2">
<div>
<div class="text-sm text-slate-200 font-medium">Auto-Scaling</div>
<div class="text-xs text-slate-500">Deploy additional nodes on high load</div>
</div>
<label class="relative inline-flex items-center cursor-pointer">
<input checked="" class="sr-only peer" type="checkbox" value=""/>
<div class="w-9 h-5 bg-surface-container-highest rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-white after:border-gray-300 after:border after:rounded-full after:h-4 after:w-4 after:transition-all peer-checked:bg-blue-500 border border-white/10 shadow-[inset_0_2px_4px_rgba(0,0,0,0.4)]"></div>
</label>
</div>
<div class="mt-auto pt-6 flex gap-3">
<button class="flex-1 py-2 rounded-lg text-sm font-medium text-slate-300 bg-surface-container hover:bg-surface-bright border border-white/10 transition-colors" type="button">Discard</button>
<button class="flex-1 py-2 rounded-lg text-sm font-medium text-on-primary-container bg-primary-container hover:bg-blue-400 transition-colors shadow-[0_0_10px_rgba(75,142,255,0.2)]" type="button">Apply Config</button>
</div>
</form>
</div>
</div>
</div>
</main>
</div>
</body></html>