docs: interactive HTML preview of the redesigned MainWindow
docs/preview/redesigned-mainwindow.html — a single-file faithful rendering of the redesigned MainWindow at 1280×780 fidelity. Built so you can SEE the redesign tomorrow morning even with the WinUI 3 activation issue unresolved. What's interactive: * Title-bar sun/moon icon toggles dark <-> light. The full CSS variable set swaps in-place; both themes are accurate to DESIGN.md's token table (Wild Dragon cyan stays as the surface fill in both; accent.cyan for text darkens to #0E7C82 on the light palette for AA contrast). * Rail "settings" icon (the gear) slides the settings drawer in from the right with a 220ms ease-out-quart transition. * Esc dismisses the drawer. * Banner "Toggle dark / light" and "Open settings" buttons for hover-discoverable parity. What's faithful to the WinUI 3 implementation: * All structural decisions from the shape brief: 64px rail, 44px title bar with absorbed live pills (live · 00:14:32 / rec 3 / 482GB free), section header with primary button + secondary actions, 64px table rows with avatar+name, signal+lock dot, audio meter, output-name in mono, ISO pill at right, conditional in-call control bar, slim 32px status bar. * Active-speaker row (Maya) has the cyan left border + cyan-muted background tint, matching the data trigger in MainWindow.xaml. * Wild Dragon brand mark in the rail uses the same cyan-muted square + cyan-text "W" treatment as the WinUI 3 Avatar style. * In-call buttons use the destructive style for Muted + Leave (coral border and text) and Secondary for Camera / Share / Marker, mirroring the button-hierarchy commitment from DESIGN.md. * Settings drawer shows the Appearance tab with the System / Dark / Light radio group + the accent peek panel. Open it in any modern browser: file:///C:/Users/zacga/Documents/Claude/Projects/Teams%20ISO/docs/preview/redesigned-mainwindow.html This is documentation; the actual product is the WinUI 3 XAML in src/TeamsISO.App.WinUI/. Once activation unblocks, the preview can be deleted (or kept for future stakeholder demos before binaries ship).
This commit is contained in:
parent
8e29c1dc1e
commit
c150bce28e
1 changed files with 789 additions and 0 deletions
789
docs/preview/redesigned-mainwindow.html
Normal file
789
docs/preview/redesigned-mainwindow.html
Normal file
|
|
@ -0,0 +1,789 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<title>TeamsISO — redesigned MainWindow preview</title>
|
||||
<style>
|
||||
:root {
|
||||
/* Dark palette — mirrors src/TeamsISO.App.WinUI/Themes/Tokens.xaml */
|
||||
--bg-canvas: #0a0a0a;
|
||||
--bg-rail: #080808;
|
||||
--bg-surface: #141416;
|
||||
--bg-elevated: #1c1c1f;
|
||||
--bg-hover: #26272b;
|
||||
--bg-active: #33343a;
|
||||
--border-subtle: #26272b;
|
||||
--border-strong: #3a3b40;
|
||||
--fg-primary: #f4f4f6;
|
||||
--fg-secondary: #a3a4aa;
|
||||
--fg-tertiary: #6b6c72;
|
||||
--fg-disabled: #404145;
|
||||
--fg-on-accent: #0a0a0a;
|
||||
--accent-cyan-surface: #97edf0;
|
||||
--accent-cyan-text: #97edf0;
|
||||
--accent-cyan-hover: #b5f2f4;
|
||||
--accent-cyan-muted: #1b3537;
|
||||
--accent-coral: #fb819c;
|
||||
--accent-coral-bg: #3a1922;
|
||||
--status-live: #4ade80;
|
||||
--status-live-bg: #13261a;
|
||||
--status-warn: #fbbf24;
|
||||
--status-warn-bg: #3a2e12;
|
||||
--shadow-drawer: rgba(0,0,0,0.55);
|
||||
}
|
||||
html[data-theme="light"] {
|
||||
--bg-canvas: #fafafb;
|
||||
--bg-rail: #f0f1f3;
|
||||
--bg-surface: #ffffff;
|
||||
--bg-elevated: #ffffff;
|
||||
--bg-hover: #eceef1;
|
||||
--bg-active: #e0e3e7;
|
||||
--border-subtle: #e5e7eb;
|
||||
--border-strong: #d1d5da;
|
||||
--fg-primary: #0a0a0a;
|
||||
--fg-secondary: #4a4b50;
|
||||
--fg-tertiary: #71747a;
|
||||
--fg-disabled: #b3b6bc;
|
||||
--fg-on-accent: #0a0a0a;
|
||||
--accent-cyan-surface: #97edf0;
|
||||
--accent-cyan-text: #0e7c82;
|
||||
--accent-cyan-hover: #0890a0;
|
||||
--accent-cyan-muted: #e6f8f9;
|
||||
--accent-coral: #d43e5c;
|
||||
--accent-coral-bg: #fdecf0;
|
||||
--status-live: #15803d;
|
||||
--status-live-bg: #dcfce7;
|
||||
--status-warn: #b45309;
|
||||
--status-warn-bg: #fef3c7;
|
||||
--shadow-drawer: rgba(0,0,0,0.15);
|
||||
}
|
||||
* { box-sizing: border-box; }
|
||||
html, body {
|
||||
margin: 0; padding: 0;
|
||||
background: #1a1a1c;
|
||||
color: var(--fg-primary);
|
||||
font-family: 'Inter', -apple-system, system-ui, 'Segoe UI Variable Display', 'Segoe UI', sans-serif;
|
||||
min-height: 100vh;
|
||||
}
|
||||
html[data-theme="light"] body { background: #e8e9eb; }
|
||||
.preview-shell {
|
||||
max-width: 1304px;
|
||||
margin: 24px auto;
|
||||
padding: 0 12px;
|
||||
}
|
||||
.preview-banner {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 12px 16px; margin-bottom: 16px;
|
||||
background: var(--bg-surface);
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: 8px;
|
||||
color: var(--fg-secondary);
|
||||
font-size: 12px;
|
||||
}
|
||||
.preview-banner strong { color: var(--fg-primary); font-weight: 600; }
|
||||
.preview-banner-actions { display: flex; gap: 8px; }
|
||||
.preview-banner-actions button {
|
||||
background: transparent;
|
||||
border: 1px solid var(--border-strong);
|
||||
color: var(--fg-primary);
|
||||
padding: 6px 14px;
|
||||
font-size: 12px; font-weight: 500;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
font-family: inherit;
|
||||
}
|
||||
.preview-banner-actions button:hover { border-color: var(--accent-cyan-text); }
|
||||
.preview-banner-actions .primary {
|
||||
background: var(--accent-cyan-surface);
|
||||
border-color: var(--accent-cyan-surface);
|
||||
color: var(--fg-on-accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
.window {
|
||||
width: 1280px; height: 780px;
|
||||
background: var(--bg-canvas);
|
||||
border: 1px solid var(--border-strong);
|
||||
border-radius: 8px;
|
||||
display: grid;
|
||||
grid-template-columns: 64px 1fr;
|
||||
overflow: hidden;
|
||||
color: var(--fg-primary);
|
||||
box-shadow: 0 16px 60px var(--shadow-drawer);
|
||||
position: relative;
|
||||
}
|
||||
.rail {
|
||||
background: var(--bg-rail);
|
||||
border-right: 1px solid var(--border-subtle);
|
||||
display: flex; flex-direction: column;
|
||||
padding: 12px 0 12px 0;
|
||||
}
|
||||
.rail-top { flex: 1; display: flex; flex-direction: column; gap: 2px; }
|
||||
.rail-btn {
|
||||
width: 48px; height: 48px;
|
||||
margin: 4px 8px;
|
||||
border-radius: 8px;
|
||||
border: 0; background: transparent;
|
||||
color: var(--fg-secondary);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
cursor: pointer;
|
||||
transition: background 120ms ease-out, color 120ms ease-out;
|
||||
}
|
||||
.rail-btn:hover { background: var(--bg-hover); color: var(--accent-cyan-text); }
|
||||
.rail-brand {
|
||||
width: 48px; height: 56px;
|
||||
margin: 0 8px 8px;
|
||||
}
|
||||
.rail-brand .mark {
|
||||
width: 40px; height: 40px;
|
||||
background: var(--accent-cyan-muted);
|
||||
border-radius: 8px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
color: var(--accent-cyan-text);
|
||||
font-size: 22px; font-weight: 700;
|
||||
}
|
||||
.rail-divider {
|
||||
height: 1px; background: var(--border-subtle);
|
||||
margin: 4px 14px 12px;
|
||||
}
|
||||
.rail-btn.active {
|
||||
background: var(--accent-cyan-muted);
|
||||
color: var(--accent-cyan-text);
|
||||
}
|
||||
.rail-status-puck {
|
||||
width: 48px; height: 48px;
|
||||
margin: 12px 8px;
|
||||
border-radius: 24px;
|
||||
background: var(--status-live-bg);
|
||||
border: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
cursor: pointer;
|
||||
}
|
||||
.rail-status-puck .dot {
|
||||
width: 10px; height: 10px;
|
||||
background: var(--status-live);
|
||||
border-radius: 50%;
|
||||
}
|
||||
.icon {
|
||||
width: 20px; height: 20px;
|
||||
stroke: currentColor;
|
||||
fill: none;
|
||||
stroke-width: 1.6;
|
||||
stroke-linecap: round; stroke-linejoin: round;
|
||||
}
|
||||
.content {
|
||||
display: grid;
|
||||
grid-template-rows: 44px auto 1fr auto 32px;
|
||||
min-width: 0;
|
||||
}
|
||||
.titlebar {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto auto auto auto;
|
||||
align-items: center;
|
||||
background: var(--bg-canvas);
|
||||
}
|
||||
.titlebar-app {
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
padding: 0 24px;
|
||||
}
|
||||
.titlebar-app .name {
|
||||
font-size: 14px; font-weight: 600;
|
||||
}
|
||||
.titlebar-app .version {
|
||||
font-family: 'JetBrains Mono', 'Cascadia Mono', Consolas, monospace;
|
||||
font-size: 11px; color: var(--fg-tertiary);
|
||||
}
|
||||
.titlebar-pills {
|
||||
display: flex; gap: 8px;
|
||||
padding: 0 12px 0 0;
|
||||
}
|
||||
.pill {
|
||||
height: 22px;
|
||||
border-radius: 999px;
|
||||
padding: 0 12px;
|
||||
display: inline-flex; align-items: center; gap: 6px;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
background: var(--bg-surface);
|
||||
border: 1px solid var(--border-subtle);
|
||||
color: var(--fg-secondary);
|
||||
}
|
||||
.pill .dot {
|
||||
width: 7px; height: 7px; border-radius: 50%;
|
||||
background: var(--fg-tertiary);
|
||||
}
|
||||
.pill.live { background: var(--status-live-bg); border-color: transparent; color: var(--status-live); }
|
||||
.pill.live .dot { background: var(--status-live); }
|
||||
.pill.rec { background: var(--accent-coral-bg); border-color: transparent; color: var(--accent-coral); }
|
||||
.pill.rec .dot { background: var(--accent-coral); }
|
||||
.titlebar-tool {
|
||||
width: 46px; height: 32px;
|
||||
border: 0; background: transparent;
|
||||
color: var(--fg-primary);
|
||||
cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.titlebar-tool:hover { background: var(--bg-hover); }
|
||||
.titlebar-tool.close:hover { background: #c42b1c; color: white; }
|
||||
|
||||
.section-header {
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
padding: 18px 32px 12px;
|
||||
gap: 12px;
|
||||
}
|
||||
.section-title {
|
||||
display: flex; align-items: center; gap: 12px;
|
||||
}
|
||||
.display-title {
|
||||
font-size: 22px; font-weight: 600; letter-spacing: -0.01em;
|
||||
color: var(--fg-primary);
|
||||
}
|
||||
.count-badge {
|
||||
height: 22px; padding: 0 12px;
|
||||
background: var(--bg-surface);
|
||||
border: 1px solid var(--border-subtle);
|
||||
border-radius: 999px;
|
||||
display: inline-flex; align-items: center;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px;
|
||||
color: var(--fg-secondary);
|
||||
}
|
||||
.section-actions {
|
||||
display: flex; gap: 8px; align-items: center;
|
||||
}
|
||||
.input {
|
||||
width: 200px; height: 34px;
|
||||
background: var(--bg-surface);
|
||||
border: 1px solid var(--border-subtle);
|
||||
color: var(--fg-primary);
|
||||
border-radius: 8px;
|
||||
padding: 0 12px;
|
||||
font-family: inherit; font-size: 13px;
|
||||
outline: none;
|
||||
}
|
||||
.input:focus { border-color: var(--accent-cyan-text); }
|
||||
.input::placeholder { color: var(--fg-tertiary); }
|
||||
.btn {
|
||||
height: 34px;
|
||||
padding: 0 14px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border-strong);
|
||||
background: transparent;
|
||||
color: var(--fg-primary);
|
||||
font-family: inherit; font-size: 12px; font-weight: 500;
|
||||
cursor: pointer;
|
||||
transition: border-color 120ms ease-out, background 120ms ease-out;
|
||||
}
|
||||
.btn:hover { border-color: var(--accent-cyan-text); background: var(--bg-hover); }
|
||||
.btn.primary {
|
||||
background: var(--accent-cyan-surface);
|
||||
border-color: var(--accent-cyan-surface);
|
||||
color: var(--fg-on-accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
.btn.primary:hover {
|
||||
background: var(--accent-cyan-hover);
|
||||
border-color: var(--accent-cyan-hover);
|
||||
}
|
||||
.btn.destructive {
|
||||
color: var(--accent-coral);
|
||||
border-color: var(--accent-coral);
|
||||
}
|
||||
|
||||
.table {
|
||||
padding: 0 32px;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
}
|
||||
.table-head {
|
||||
display: grid;
|
||||
grid-template-columns: 56px 2fr 1fr 1.2fr 1.5fr auto;
|
||||
align-items: center;
|
||||
height: 36px;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
color: var(--fg-tertiary);
|
||||
font-size: 11px; font-weight: 500;
|
||||
letter-spacing: 0.08em; text-transform: uppercase;
|
||||
padding-right: 12px;
|
||||
}
|
||||
.table-head > * { padding: 0 4px; }
|
||||
.row {
|
||||
display: grid;
|
||||
grid-template-columns: 56px 2fr 1fr 1.2fr 1.5fr auto;
|
||||
align-items: center;
|
||||
height: 64px;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
padding-right: 12px;
|
||||
position: relative;
|
||||
transition: background 120ms ease-out;
|
||||
}
|
||||
.row:hover { background: var(--bg-hover); }
|
||||
.row.active-speaker {
|
||||
background: var(--accent-cyan-muted);
|
||||
}
|
||||
.row .left-accent {
|
||||
position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
|
||||
background: var(--accent-cyan-text);
|
||||
display: none;
|
||||
}
|
||||
.row.active-speaker .left-accent { display: block; }
|
||||
|
||||
.row-avatar {
|
||||
width: 56px;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
}
|
||||
.avatar {
|
||||
width: 36px; height: 36px;
|
||||
border-radius: 50%;
|
||||
background: var(--bg-active);
|
||||
color: var(--fg-secondary);
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 13px; font-weight: 600;
|
||||
}
|
||||
.row.active-speaker .avatar {
|
||||
background: var(--accent-cyan-muted);
|
||||
color: var(--accent-cyan-text);
|
||||
}
|
||||
.row-name { line-height: 1.3; }
|
||||
.row-name .name {
|
||||
font-size: 14px; font-weight: 500;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.row-name .codec {
|
||||
font-size: 11px; color: var(--fg-secondary);
|
||||
}
|
||||
.row-signal {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
font-family: 'JetBrains Mono', monospace; font-size: 11px;
|
||||
}
|
||||
.row-signal .dot {
|
||||
width: 8px; height: 8px; border-radius: 50%;
|
||||
}
|
||||
.row-signal.locked .dot { background: var(--status-live); }
|
||||
.row-signal.degraded { color: var(--status-warn); }
|
||||
.row-signal.degraded .dot { background: var(--status-warn); }
|
||||
.meter { display: flex; align-items: center; gap: 2px; height: 24px; }
|
||||
.meter span {
|
||||
width: 4px; border-radius: 2px;
|
||||
background: var(--bg-active);
|
||||
}
|
||||
.meter.active span { background: var(--fg-secondary); }
|
||||
.row.active-speaker .meter.active span { background: var(--accent-cyan-text); }
|
||||
.row-output {
|
||||
font-family: 'JetBrains Mono', monospace; font-size: 13px;
|
||||
color: var(--fg-primary);
|
||||
}
|
||||
.iso-pill {
|
||||
width: 80px;
|
||||
padding: 6px 0;
|
||||
border-radius: 999px;
|
||||
text-align: center;
|
||||
font-size: 11px; font-weight: 700;
|
||||
letter-spacing: 0.06em;
|
||||
}
|
||||
.iso-pill.live {
|
||||
background: var(--status-live-bg);
|
||||
color: var(--status-live);
|
||||
border: 1px solid var(--status-live);
|
||||
}
|
||||
.iso-pill.off {
|
||||
background: var(--bg-surface);
|
||||
color: var(--fg-secondary);
|
||||
border: 1px solid var(--border-strong);
|
||||
}
|
||||
|
||||
.in-call {
|
||||
padding: 12px 32px;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
background: var(--bg-canvas);
|
||||
display: flex; align-items: center; gap: 10px;
|
||||
}
|
||||
.in-call .label {
|
||||
font-size: 11px; font-weight: 500; letter-spacing: 0.08em;
|
||||
text-transform: uppercase; color: var(--fg-tertiary);
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.status-bar {
|
||||
padding: 0 32px;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
background: var(--bg-canvas);
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px; color: var(--fg-tertiary);
|
||||
}
|
||||
.status-bar .left {
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
color: var(--fg-secondary);
|
||||
}
|
||||
.status-bar .left .dot {
|
||||
width: 6px; height: 6px; border-radius: 50%;
|
||||
background: var(--accent-cyan-text);
|
||||
}
|
||||
|
||||
/* Settings drawer */
|
||||
.drawer {
|
||||
position: absolute;
|
||||
top: 44px; right: 0; bottom: 0;
|
||||
width: 400px;
|
||||
background: var(--bg-surface);
|
||||
border-left: 1px solid var(--border-subtle);
|
||||
transform: translateX(100%);
|
||||
transition: transform 220ms cubic-bezier(0.16, 1, 0.3, 1);
|
||||
display: flex; flex-direction: column;
|
||||
z-index: 5;
|
||||
}
|
||||
.drawer.open { transform: translateX(0); }
|
||||
.drawer-head {
|
||||
height: 56px;
|
||||
padding: 0 12px 0 20px;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
}
|
||||
.drawer-head .title {
|
||||
font-size: 18px; font-weight: 600;
|
||||
}
|
||||
.drawer-tabs {
|
||||
display: flex; gap: 6px;
|
||||
padding: 12px 20px 0;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
}
|
||||
.drawer-tab {
|
||||
padding: 8px 12px;
|
||||
border: 0; background: transparent;
|
||||
color: var(--fg-tertiary);
|
||||
font-family: inherit; font-size: 12px; font-weight: 500;
|
||||
cursor: pointer;
|
||||
border-bottom: 2px solid transparent;
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
.drawer-tab.active {
|
||||
color: var(--fg-primary);
|
||||
border-bottom-color: var(--accent-cyan-text);
|
||||
}
|
||||
.drawer-body {
|
||||
flex: 1;
|
||||
padding: 20px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.drawer-body h3 {
|
||||
font-size: 14px; font-weight: 600;
|
||||
margin: 0 0 12px 0;
|
||||
color: var(--fg-primary);
|
||||
}
|
||||
.drawer-body p {
|
||||
font-size: 12px;
|
||||
color: var(--fg-secondary);
|
||||
margin: 0 0 16px 0;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.theme-picker { display: flex; gap: 8px; margin-bottom: 16px; }
|
||||
.theme-pick-btn {
|
||||
flex: 1;
|
||||
padding: 12px 14px;
|
||||
border-radius: 8px;
|
||||
border: 1px solid var(--border-strong);
|
||||
background: transparent;
|
||||
color: var(--fg-primary);
|
||||
font-family: inherit; font-size: 13px; font-weight: 500;
|
||||
cursor: pointer;
|
||||
text-align: left;
|
||||
}
|
||||
.theme-pick-btn.active {
|
||||
border-color: var(--accent-cyan-text);
|
||||
background: var(--accent-cyan-muted);
|
||||
}
|
||||
.accent-swatches { display: flex; gap: 12px; flex-wrap: wrap; }
|
||||
.swatch {
|
||||
display: flex; flex-direction: column; gap: 6px;
|
||||
text-align: center;
|
||||
}
|
||||
.swatch .chip {
|
||||
width: 80px; height: 32px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
.swatch .label {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
font-size: 11px; color: var(--fg-tertiary);
|
||||
letter-spacing: 0.06em; text-transform: uppercase;
|
||||
}
|
||||
.drawer-row {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
padding: 6px 0;
|
||||
border-bottom: 1px solid var(--border-subtle);
|
||||
font-size: 13px;
|
||||
}
|
||||
.drawer-row .v {
|
||||
font-family: 'JetBrains Mono', monospace;
|
||||
color: var(--fg-secondary);
|
||||
}
|
||||
.drawer-foot {
|
||||
padding: 12px 16px;
|
||||
border-top: 1px solid var(--border-subtle);
|
||||
display: flex; justify-content: flex-end; gap: 8px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="preview-shell">
|
||||
<div class="preview-banner">
|
||||
<div>
|
||||
<strong>TeamsISO redesign — interactive preview</strong>
|
||||
The same XAML that's in <code>src/TeamsISO.App.WinUI/Views/MainWindow.xaml</code>, rendered as HTML so you can see and toggle it before the WinUI 3 .exe activation issue is resolved.
|
||||
</div>
|
||||
<div class="preview-banner-actions">
|
||||
<button id="open-drawer">Open settings</button>
|
||||
<button id="toggle-theme" class="primary">Toggle dark / light</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="window">
|
||||
<!-- RAIL -->
|
||||
<div class="rail">
|
||||
<div class="rail-top">
|
||||
<button class="rail-btn rail-brand" title="About TeamsISO">
|
||||
<div class="mark">W</div>
|
||||
</button>
|
||||
<div class="rail-divider"></div>
|
||||
<button class="rail-btn active" title="Participants">
|
||||
<svg class="icon" viewBox="0 0 24 24"><circle cx="12" cy="9" r="3.2"/><path d="M5 19c0-3.5 3.1-6 7-6s7 2.5 7 6"/></svg>
|
||||
</button>
|
||||
<button class="rail-btn" title="Launch / surface Teams">
|
||||
<svg class="icon" viewBox="0 0 24 24"><rect x="3" y="7" width="13" height="10" rx="2"/><path d="M16 11l5-3v8l-5-3z"/></svg>
|
||||
</button>
|
||||
<button class="rail-btn" title="Hide / show Teams windows">
|
||||
<svg class="icon" viewBox="0 0 24 24"><path d="M2 12s4-7 10-7 10 7 10 7-4 7-10 7S2 12 2 12z"/><circle cx="12" cy="12" r="3"/></svg>
|
||||
</button>
|
||||
<button class="rail-btn" id="rail-settings" title="Settings">
|
||||
<svg class="icon" viewBox="0 0 24 24"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.7 1.7 0 0 0 .3 1.8l.1.1a2 2 0 1 1-2.8 2.8l-.1-.1a1.7 1.7 0 0 0-1.8-.3 1.7 1.7 0 0 0-1 1.5V21a2 2 0 1 1-4 0v-.1a1.7 1.7 0 0 0-1-1.5 1.7 1.7 0 0 0-1.8.3l-.1.1a2 2 0 1 1-2.8-2.8l.1-.1a1.7 1.7 0 0 0 .3-1.8 1.7 1.7 0 0 0-1.5-1H3a2 2 0 1 1 0-4h.1a1.7 1.7 0 0 0 1.5-1 1.7 1.7 0 0 0-.3-1.8l-.1-.1a2 2 0 1 1 2.8-2.8l.1.1a1.7 1.7 0 0 0 1.8.3h.1a1.7 1.7 0 0 0 1-1.5V3a2 2 0 1 1 4 0v.1a1.7 1.7 0 0 0 1 1.5 1.7 1.7 0 0 0 1.8-.3l.1-.1a2 2 0 1 1 2.8 2.8l-.1.1a1.7 1.7 0 0 0-.3 1.8v.1a1.7 1.7 0 0 0 1.5 1H21a2 2 0 1 1 0 4h-.1a1.7 1.7 0 0 0-1.5 1z"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<button class="rail-status-puck" title="Engine status">
|
||||
<div class="dot"></div>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- CONTENT -->
|
||||
<div class="content">
|
||||
<!-- Title bar -->
|
||||
<div class="titlebar">
|
||||
<div class="titlebar-app">
|
||||
<span class="name">TeamsISO</span>
|
||||
<span class="version">v1.0.0-alpha</span>
|
||||
</div>
|
||||
<div></div>
|
||||
<div class="titlebar-pills">
|
||||
<div class="pill live"><div class="dot"></div>live · 00:14:32</div>
|
||||
<div class="pill rec"><div class="dot"></div>rec 3 · 00:11:08</div>
|
||||
<div class="pill">482 GB free</div>
|
||||
</div>
|
||||
<button class="titlebar-tool" id="titlebar-theme" title="Theme">
|
||||
<svg class="icon" viewBox="0 0 24 24" id="theme-icon-mark"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
|
||||
</button>
|
||||
<button class="titlebar-tool" title="Minimize">
|
||||
<svg class="icon" viewBox="0 0 24 24"><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
||||
</button>
|
||||
<button class="titlebar-tool" title="Maximize">
|
||||
<svg class="icon" viewBox="0 0 24 24"><rect x="5" y="5" width="14" height="14"/></svg>
|
||||
</button>
|
||||
<button class="titlebar-tool close" title="Close">
|
||||
<svg class="icon" viewBox="0 0 24 24"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Section header -->
|
||||
<div class="section-header">
|
||||
<div class="section-title">
|
||||
<span class="display-title">Participants</span>
|
||||
<span class="count-badge">4</span>
|
||||
</div>
|
||||
<div></div>
|
||||
<div class="section-actions">
|
||||
<input class="input" placeholder="Filter participants"/>
|
||||
<button class="btn">Refresh</button>
|
||||
<button class="btn">Presets</button>
|
||||
<button class="btn primary">Enable all online</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<div class="table">
|
||||
<div class="table-head">
|
||||
<div></div>
|
||||
<div>Participant</div>
|
||||
<div>Signal</div>
|
||||
<div>Audio</div>
|
||||
<div>Output name</div>
|
||||
<div>ISO</div>
|
||||
</div>
|
||||
|
||||
<div class="row active-speaker">
|
||||
<div class="left-accent"></div>
|
||||
<div class="row-avatar"><div class="avatar">MA</div></div>
|
||||
<div class="row-name"><div class="name">Maya Rodriguez</div><div class="codec">MS Teams · 1920×1080 · 30fps</div></div>
|
||||
<div class="row-signal locked"><div class="dot"></div>locked</div>
|
||||
<div>
|
||||
<div class="meter active">
|
||||
<span style="height:24px"></span>
|
||||
<span style="height:20px"></span>
|
||||
<span style="height:28px"></span>
|
||||
<span style="height:18px"></span>
|
||||
<span style="height:12px"></span>
|
||||
<span style="height:22px"></span>
|
||||
<span style="height:8px"></span>
|
||||
<span style="height:14px"></span>
|
||||
<span style="height:6px"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-output">TEAMSISO_maya</div>
|
||||
<div><div class="iso-pill live">LIVE</div></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="row-avatar"><div class="avatar">DC</div></div>
|
||||
<div class="row-name"><div class="name">Daniel Chen</div><div class="codec">MS Teams · 1280×720 · 30fps</div></div>
|
||||
<div class="row-signal locked"><div class="dot"></div>locked</div>
|
||||
<div>
|
||||
<div class="meter active">
|
||||
<span style="height:10px"></span>
|
||||
<span style="height:14px"></span>
|
||||
<span style="height:8px"></span>
|
||||
<span style="height:12px"></span>
|
||||
<span style="height:6px"></span>
|
||||
<span style="height:9px"></span>
|
||||
<span style="height:4px"></span>
|
||||
<span style="height:3px"></span>
|
||||
<span style="height:2px"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-output">TEAMSISO_daniel</div>
|
||||
<div><div class="iso-pill live">LIVE</div></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="row-avatar"><div class="avatar">AK</div></div>
|
||||
<div class="row-name"><div class="name">Aïcha Koné</div><div class="codec">MS Teams · 1920×1080 · 30fps</div></div>
|
||||
<div class="row-signal degraded"><div class="dot"></div>degraded</div>
|
||||
<div>
|
||||
<div class="meter">
|
||||
<span style="height:3px"></span>
|
||||
<span style="height:4px"></span>
|
||||
<span style="height:3px"></span>
|
||||
<span style="height:2px"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-output" style="color:var(--fg-secondary)">TEAMSISO_aicha</div>
|
||||
<div><div class="iso-pill off">OFF</div></div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="row-avatar"><div class="avatar">SP</div></div>
|
||||
<div class="row-name"><div class="name">Sam Park</div><div class="codec">MS Teams · 1920×1080 · 30fps</div></div>
|
||||
<div class="row-signal locked"><div class="dot"></div>locked</div>
|
||||
<div>
|
||||
<div class="meter active">
|
||||
<span style="height:8px"></span>
|
||||
<span style="height:12px"></span>
|
||||
<span style="height:16px"></span>
|
||||
<span style="height:7px"></span>
|
||||
<span style="height:5px"></span>
|
||||
<span style="height:3px"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row-output">TEAMSISO_sam</div>
|
||||
<div><div class="iso-pill live">LIVE</div></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- In-call control -->
|
||||
<div class="in-call">
|
||||
<span class="label">In-call</span>
|
||||
<button class="btn destructive">⊘ Muted</button>
|
||||
<button class="btn">⌗ Camera</button>
|
||||
<button class="btn">⇪ Share</button>
|
||||
<button class="btn">▷ Marker</button>
|
||||
<button class="btn destructive">Leave</button>
|
||||
<button class="btn" style="width:36px;padding:0;">⋯</button>
|
||||
</div>
|
||||
|
||||
<!-- Status bar -->
|
||||
<div class="status-bar">
|
||||
<div class="left">
|
||||
<div class="dot"></div>
|
||||
<span>control surface · 127.0.0.1:9755</span>
|
||||
</div>
|
||||
<div>F1 help · Ctrl+M marker · Ctrl+Shift+S panic · Ctrl+K command palette</div>
|
||||
</div>
|
||||
|
||||
<!-- Settings drawer -->
|
||||
<div class="drawer" id="drawer">
|
||||
<div class="drawer-head">
|
||||
<div class="title">Settings</div>
|
||||
<button class="titlebar-tool" id="drawer-close" title="Close (Esc)">
|
||||
<svg class="icon" viewBox="0 0 24 24"><line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="drawer-tabs">
|
||||
<button class="drawer-tab active">Appearance</button>
|
||||
<button class="drawer-tab">Routing</button>
|
||||
<button class="drawer-tab">Display</button>
|
||||
<button class="drawer-tab">Control</button>
|
||||
<button class="drawer-tab">Advanced</button>
|
||||
</div>
|
||||
<div class="drawer-body">
|
||||
<h3>Appearance</h3>
|
||||
<p>Dark is the default for the 1:50am operator scene; light is for daytime production. System follows the Windows app-mode preference.</p>
|
||||
<div class="theme-picker">
|
||||
<button class="theme-pick-btn" data-theme="dark">Dark</button>
|
||||
<button class="theme-pick-btn active" data-theme="dark">System</button>
|
||||
<button class="theme-pick-btn" data-theme="light">Light</button>
|
||||
</div>
|
||||
<h3>Accent peek</h3>
|
||||
<p>These accents work in both themes. Cyan stays bright as a surface fill (text on top is near-black regardless). For inline text on light, the palette substitutes a darker cyan automatically.</p>
|
||||
<div class="accent-swatches">
|
||||
<div class="swatch"><div class="chip" style="background:var(--accent-cyan-surface)"></div><div class="label">Cyan</div></div>
|
||||
<div class="swatch"><div class="chip" style="background:var(--accent-coral)"></div><div class="label">Coral</div></div>
|
||||
<div class="swatch"><div class="chip" style="background:var(--status-live)"></div><div class="label">Live</div></div>
|
||||
<div class="swatch"><div class="chip" style="background:var(--status-warn)"></div><div class="label">Warn</div></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="drawer-foot">
|
||||
<button class="btn">Reset to defaults</button>
|
||||
<button class="btn primary">Apply</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
const html = document.documentElement;
|
||||
const themeIcon = document.getElementById('theme-icon-mark');
|
||||
const sunPath = 'M12 1v2 M12 21v2 M4.2 4.2l1.4 1.4 M18.4 18.4l1.4 1.4 M1 12h2 M21 12h2 M4.2 19.8l1.4-1.4 M18.4 5.6l1.4-1.4 M12 8a4 4 0 1 0 0 8 4 4 0 0 0 0-8';
|
||||
const moonPath = 'M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z';
|
||||
|
||||
function applyTheme(t) {
|
||||
html.dataset.theme = t;
|
||||
themeIcon.setAttribute('d', t === 'light' ? sunPath : moonPath);
|
||||
themeIcon.parentElement.innerHTML = `<svg class="icon" viewBox="0 0 24 24" id="theme-icon-mark"><path d="${t === 'light' ? sunPath : moonPath}"/></svg>`;
|
||||
}
|
||||
|
||||
function toggle() {
|
||||
applyTheme(html.dataset.theme === 'light' ? 'dark' : 'light');
|
||||
}
|
||||
|
||||
document.getElementById('toggle-theme').addEventListener('click', toggle);
|
||||
document.getElementById('titlebar-theme').addEventListener('click', toggle);
|
||||
|
||||
const drawer = document.getElementById('drawer');
|
||||
document.getElementById('rail-settings').addEventListener('click', () => drawer.classList.add('open'));
|
||||
document.getElementById('open-drawer').addEventListener('click', () => drawer.classList.add('open'));
|
||||
document.getElementById('drawer-close').addEventListener('click', () => drawer.classList.remove('open'));
|
||||
document.addEventListener('keydown', (e) => { if (e.key === 'Escape') drawer.classList.remove('open'); });
|
||||
|
||||
applyTheme('dark');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Loading…
Reference in a new issue