:root { font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; color-scheme: dark; --bg:#101722; --panel:#17212f; --line:#2a3545; --text:#f1f5fa; --muted:#98a6b9; --accent:#fa7454; --healthy:#26c786; --infected:#ff666d; --recovered:#a8ebcf; --dead:#8d97a7; }
* { box-sizing:border-box; } [hidden] { display:none!important; } body { margin:0; font-size:1rem; line-height:1.5; } button,input,select { font:inherit; } button,a,input,select { -webkit-tap-highlight-color:transparent; } button { cursor:pointer; } button:disabled { opacity:.45; cursor:not-allowed; } button:focus-visible,a:focus-visible,input:focus-visible,select:focus-visible { outline:3px solid #faad92; outline-offset:3px; } a { color:inherit; } h1,h2,h3,p { margin:0; } input,select { min-width:0; } .wordmark { display:inline-flex; align-items:center; font-size:1.5rem; font-weight:750; letter-spacing:-.06em; text-decoration:none; } .brand-mark { color:var(--accent); margin-left:4px; font-weight:900; } .eyebrow { display:block; font-size:.75rem; font-weight:700; letter-spacing:.16em; color:var(--muted); } .text-button { color:inherit; padding:4px 0; background:none; border:0; font-size:.875rem; } .muted { color:var(--muted); font-size:.875rem; } .button { display:inline-flex; align-items:center; justify-content:center; min-height:42px; padding:10px 16px; border:1px solid #3a4657; border-radius:7px; background:#202c3d; color:var(--text); font-size:.875rem; font-weight:600; transition:background .15s; } .button:hover { background:#2a384a; } .button.primary { background:var(--accent); color:#231713; border-color:var(--accent); } .button.primary:hover { background:#ff8c6e; } .button.danger-quiet { background:transparent; color:#d99fa3; border-color:#61414b; } .button.danger { background:#d94151; color:white; border-color:#d94151; } .full-width { width:100%; } .error { color:#ff989e; font-size:.875rem; min-height:1.5em; }
/* A participant's entire screen is its state. */
.phone { color:#063b2a; background:#25c17d; color-scheme:light; transition:background .45s,color .45s; } .phone.healthy { background:#25c17d; color:#053b27; } .phone.infected { background:#f25a61; color:#4e1017; } .phone.recovered { background:#b0efd1; color:#174b36; } .phone.dead { background:#9da6b2; color:#233142; } .phone .brand-mark { color:currentColor; opacity:.6; } .phone-shell { max-width:680px; margin:0 auto; padding:0 26px; min-height:100svh; display:flex; flex-direction:column; } .phone-header { padding:22px 0; display:flex; align-items:center; justify-content:space-between; gap:12px; } .phone-connection { font-size:.8125rem; border:1px solid currentColor; border-radius:20px; padding:4px 10px; } .phone-main { flex:1; display:flex; align-items:center; justify-content:center; padding:30px 0; } .join-panel { width:100%; max-width:430px; } .phone .eyebrow { color:inherit; opacity:.75; } .join-panel h1 { font-size:clamp(2.8rem,10vw,4rem); letter-spacing:-.06em; line-height:1.05; margin:20px 0; } .join-panel p { max-width:370px; } .join-panel form { margin-top:32px; } .join-panel label { display:block; font-size:.875rem; margin-bottom:8px; font-weight:600; } .optional { font-weight:400; } .join-panel input { width:100%; background:#ffffff30; border:1px solid #063b2a70; color:inherit; border-radius:8px; padding:14px; } .join-panel input::placeholder { color:#174b36b0; } .phone-button { width:100%; margin-top:12px; background:#073d2b; color:#d0ffdf; border:0; border-radius:8px; padding:15px; font-weight:700; } .status-panel { text-align:center; width:100%; } .status-symbol { width:112px; height:112px; margin:36px auto 24px; border-radius:50%; border:2px solid currentColor; display:flex; align-items:center; justify-content:center; font-size:3.5rem; line-height:1; } .status-panel h1 { font-size:clamp(3rem,13vw,5rem); font-weight:750; letter-spacing:-.06em; line-height:1.1; } .status-panel>p { max-width:340px; margin:16px auto; } .phone-badge { display:inline-flex; border:1px solid currentColor; border-radius:25px; padding:7px 16px; margin-top:12px; font-size:.875rem; } .timer-label { font-size:.875rem; min-height:1.5em; opacity:.8; } .phone-footer { padding:16px 0 max(20px,env(safe-area-inset-bottom)); } .proximity-control { border-top:1px solid #00000024; padding-top:18px; } .proximity-control>label { display:block; font-size:.875rem; font-weight:650; margin-bottom:8px; } .proximity-control select { width:100%; border:1px solid currentColor; color:inherit; background:#ffffff40; padding:12px; border-radius:8px; } .proximity-control p { font-size:.875rem; opacity:.8; margin-top:8px; } .proximity-row { display:flex; justify-content:space-between; align-items:center; gap:10px; } .phone-small-button { background:#ffffff40; border:1px solid currentColor; color:inherit; border-radius:7px; padding:9px 12px; font-size:.875rem; } .phone-footer-row { display:flex; justify-content:space-between; align-items:center; margin-top:18px; font-size:.875rem; gap:16px; } .simulation-note { margin-top:14px; font-size:.75rem; opacity:.65; } .phone-error { font-size:.875rem; font-weight:600; margin-top:10px; }
/* The console is a compact laboratory work surface. */
.console { background:var(--bg); color:var(--text); } .console-header { min-height:76px; display:flex; align-items:center; padding:16px 36px; gap:22px; border-bottom:1px solid var(--line); } .header-divider { height:22px; width:1px; background:var(--line); } .console-title { font-size:.875rem; color:#c5cfde; } .header-right { margin-left:auto; display:flex; gap:24px; align-items:center; } .connection-chip { font-size:.75rem; color:#c1c9d6; padding:4px 10px; border:1px solid var(--line); border-radius:5px; } .connection-chip.connected { color:var(--healthy); border-color:#295243; background:#1a3029; } .dashboard-wrap { max-width:1600px; margin:0 auto; padding:30px 36px 0; } .scenario-heading { display:flex; justify-content:space-between; align-items:center; margin-bottom:24px; gap:16px; } .scenario-heading h1 { font-size:1.875rem; letter-spacing:-.045em; font-weight:650; margin-top:4px; } .scenario-meta { display:flex; align-items:center; gap:20px; color:var(--muted); font-size:.875rem; } .clock { color:var(--text); font-variant-numeric:tabular-nums; font-size:1.25rem; } .run-badge { border:1px solid #6c5940; background:#352b1f; color:#e7bf7e; border-radius:5px; padding:4px 10px; font-size:.75rem; } .run-badge.running { border-color:#285b49; background:#163a2c; color:#91e9bc; } .stat-grid { display:grid; grid-template-columns:repeat(4,minmax(0,1fr)); gap:16px; margin-bottom:22px; } .stat-card { padding:18px 22px; border:1px solid var(--line); background:var(--panel); border-radius:9px; border-top:2px solid; display:grid; grid-template-columns:1fr auto; align-items:center; row-gap:8px; } .healthy-stat { border-top-color:var(--healthy); } .infected-stat { border-top-color:var(--infected); } .recovered-stat { border-top-color:var(--recovered); } .dead-stat { border-top-color:var(--dead); } .stat-label { font-size:.875rem; color:#dce3ed; display:flex; align-items:center; gap:8px; } .stat-card strong { grid-column:1; grid-row:2; font-size:2.125rem; font-weight:550; letter-spacing:-.05em; line-height:1; font-variant-numeric:tabular-nums; } .stat-foot { color:var(--muted); font-size:.75rem; grid-column:2; grid-row:2; text-align:right; } .state-dot { width:7px; height:7px; border-radius:50%; display:inline-block; flex-shrink:0; } .healthy-dot { background:var(--healthy); } .infected-dot { background:var(--infected); } .recovered-dot { background:var(--recovered); } .dead-dot { background:var(--dead); } .workspace-grid { display:grid; grid-template-columns:290px minmax(0,1fr); gap:22px; align-items:start; } .control-column,.visual-column { display:flex; flex-direction:column; gap:20px; min-width:0; } .panel { background:var(--panel); border:1px solid var(--line); border-radius:9px; overflow:hidden; } .panel-title { display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:16px; } h2 { font-size:1rem; font-weight:650; letter-spacing:-.02em; } .section-number { font:400 .75rem ui-monospace,SFMono-Regular,monospace; color:#708197; } .scenario-control,.settings-panel { padding:20px; } .scenario-control .button+.button { margin-top:9px; } .control-hint { font-size:.75rem; color:var(--muted); margin-top:14px; line-height:1.6; } .settings-panel input:not([type=range]),.settings-panel select,.login-card input,.join-link-row input { width:100%; border:1px solid #364154; background:#101a27; color:#e8eef6; border-radius:6px; padding:10px; font-size:.875rem; } .field-label { display:block; font-size:.875rem; margin:16px 0 7px; } .settings-panel form>.field-label:first-child { margin-top:0; } .field-hint { font-size:.75rem; color:var(--muted); line-height:1.6; margin-top:7px; } .field-row { display:flex; gap:12px; margin-top:18px; } .field-row>div { flex:1; min-width:0; } .field-row label { display:block; font-size:.875rem; margin-bottom:7px; } label span { color:var(--muted); font-size:.75rem; } .slider-heading { display:flex; align-items:center; justify-content:space-between; margin-top:22px; font-size:.875rem; } .slider-heading output { color:#fba88f; font-variant-numeric:tabular-nums; } input[type=range] { width:100%; margin:12px 0 2px; accent-color:var(--accent); cursor:pointer; height:16px; } .settings-panel button[type=submit] { margin-top:20px; } .panel-subtitle { font-size:.75rem; color:var(--muted); margin-top:4px; } .network-panel>.panel-title,.chart-panel>.panel-title { padding:20px 22px 0; } .online-badge { font-size:.75rem; color:#b8c9dd; background:#202e41; border:1px solid #344359; border-radius:5px; padding:5px 10px; white-space:nowrap; } .network-wrap { height:355px; position:relative; background-image:radial-gradient(#304055 1px,transparent 1px); background-size:22px 22px; margin:0 10px; } canvas { display:block; width:100%; height:100%; } .network-empty { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; text-align:center; padding:24px; pointer-events:none; } .empty-symbol { font-size:2.5rem; font-weight:200; color:#627790; line-height:1; margin-bottom:16px; } .network-empty h3 { font-size:1rem; font-weight:500; margin-bottom:8px; color:#d3deec; } .network-empty p { font-size:.875rem; color:var(--muted); max-width:290px; } .network-footer { display:flex; justify-content:space-between; gap:12px; color:var(--muted); font-size:.75rem; padding:13px 22px; border-top:1px solid var(--line); } .network-tooltip { position:absolute; background:#0b111bed; border:1px solid #43536a; border-radius:6px; padding:8px 12px; font-size:.8125rem; pointer-events:none; max-width:250px; z-index:2; } .chart-wrap { height:178px; padding:0 18px 0 4px; } .chart-legend { padding:12px 22px 17px; display:flex; align-items:center; gap:22px; font-size:.75rem; color:#b7c4d6; flex-wrap:wrap; } .chart-legend span { display:flex; align-items:center; gap:7px; } .bottom-grid { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:20px; } .join-card { padding:20px 22px; } .join-card .eyebrow { color:#e59b83; } .join-card h2 { margin-top:8px; } .join-card>p { color:var(--muted); font-size:.875rem; margin-top:8px; } .join-link-row { display:flex; gap:8px; margin-top:16px; } .join-link-row input { width:100%; min-width:0; } .join-link-row button { padding:8px 12px; } .activity-panel { padding:20px 22px; } .activity-list { list-style:none; padding:0; margin:0; height:150px; overflow-y:auto; } .activity-list li { display:flex; gap:12px; font-size:.75rem; padding:8px 0; border-bottom:1px solid #273447; color:#c6d2e3; } .activity-time { color:#7e90a8; font-variant-numeric:tabular-nums; flex-shrink:0; } .activity-list li.infection { color:#ff9aa0; } .activity-list li.recovery { color:#abe7ce; } .activity-list li.death { color:#a5acb9; } .roster-panel { margin-top:22px; } .roster-panel .panel-title { margin:0; padding:20px 22px; } .roster-panel h2 .muted { margin-left:8px; } .table-scroll { overflow-x:auto; max-height:420px; } table { width:100%; border-collapse:collapse; text-align:left; font-size:.875rem; } th { font-size:.75rem; color:#8ea2ba; font-weight:500; background:#14202e; position:sticky; top:0; } th,td { padding:13px 22px; border-top:1px solid var(--line); white-space:nowrap; } .participant-name { color:#99a8bc; margin-left:9px; } .status-pill { display:inline-flex; align-items:center; gap:7px; font-size:.75rem; color:#bdc9da; text-transform:capitalize; } .status-pill.healthy { color:#71dfb0; } .status-pill.infected { color:#ff9298; } .status-pill.recovered { color:#b7eed8; } .right-align { text-align:right; } .infect-button { padding:5px 10px; min-height:30px; font-size:.75rem; } .table-empty { text-align:center; padding:35px 20px; color:var(--muted); } .console-footer { display:flex; justify-content:space-between; gap:12px; padding:22px 0; color:#71839a; font-size:.75rem; letter-spacing:.05em; } .login-screen { min-height:100svh; display:grid; place-items:center; padding:24px; background:radial-gradient(ellipse at 50% 15%,#1f2e43,var(--bg) 60%); } .login-card { width:100%; max-width:420px; padding:32px; border:1px solid var(--line); background:var(--panel); border-radius:12px; } .login-card .wordmark { margin-bottom:36px; } .login-card .eyebrow { color:var(--accent); } .login-card h1 { font-size:1.875rem; letter-spacing:-.04em; margin:9px 0; } .login-card>p { color:var(--muted); font-size:.875rem; } .login-card form { margin-top:28px; } .login-card label { display:block; font-size:.875rem; margin-bottom:8px; } .login-card .button { width:100%; margin-top:12px; } .login-card .error { color:#ff989e; margin-top:12px; } .subtle-link { display:block; font-size:.8125rem; color:var(--muted); margin-top:16px; text-decoration:none; } .toast { position:fixed; bottom:24px; left:50%; transform:translateX(-50%); background:#253a4d; border:1px solid #53708a; color:#f3f7fc; border-radius:8px; padding:12px 20px; font-size:.875rem; max-width:calc(100vw - 32px); box-shadow:0 10px 40px #0006; z-index:50; } .toast.error-toast { background:#452632; border-color:#a06071; } dialog { max-width:450px; width:calc(100vw - 40px); background:var(--panel); color:var(--text); border:1px solid #425066; border-radius:12px; padding:28px; } dialog::backdrop { background:#050a13b0; backdrop-filter:blur(3px); } dialog h2 { margin:10px 0; font-size:1.4rem; } dialog p { font-size:.875rem; color:var(--muted); } .dialog-actions { display:flex; justify-content:flex-end; gap:10px; margin-top:24px; }
.zone-buttons { display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:10px; }
.zone-button { padding:14px 10px; min-height:52px; border:1px solid currentColor; border-radius:8px; color:inherit; background:#ffffff30; font-weight:650; }
.zone-button { overflow-wrap:anywhere; }
.zone-button[aria-pressed=true]:disabled { opacity:1; }
.current-room { display:flex; align-items:center; justify-content:space-between; flex-wrap:wrap; gap:8px 18px; padding:14px 16px; margin-bottom:18px; border:1px solid #00000030; border-radius:8px; background:#ffffff30; }
.current-room span { font-size:.875rem; }
.current-room strong { font-size:1.375rem; overflow-wrap:anywhere; }
.room-heading { font-size:1rem; margin-bottom:10px; }
.settings-panel textarea { font:inherit; width:100%; min-height:100px; resize:vertical; border:1px solid #364154; background:#101a27; color:#e8eef6; border-radius:6px; padding:10px; font-size:.875rem; }
.settings-panel textarea:focus-visible { outline:3px solid #faad92; outline-offset:3px; }
.zone-button[aria-pressed=true] { background:#063b2ae6; border-color:#063b2a; color:#e0ffee; }
.phone.infected .zone-button[aria-pressed=true] { background:#4e1017; color:#ffe6e8; border-color:#4e1017; }
.phone.dead .zone-button[aria-pressed=true] { background:#233142; color:#edf2f8; border-color:#233142; }
.proximity-method { color:#d5deeb; font-size:.875rem; background:#223248; padding:9px 12px; border-radius:6px; }
@media(min-width:1400px) { .network-wrap { height:390px; } .workspace-grid { grid-template-columns:310px minmax(0,1fr); } }
@media(max-width:1100px) { .stat-foot { grid-column:1; grid-row:3; text-align:left; } .stat-card { padding:16px 18px; } .bottom-grid { grid-template-columns:1fr; } .activity-list { height:125px; } .network-wrap { height:315px; } }
@media(max-width:800px) { .console-header { padding:16px 20px; gap:14px; } .header-right { gap:14px; } .console-title,.header-divider { display:none; } .dashboard-wrap { padding:24px 18px 0; } .scenario-heading { align-items:flex-start; } .scenario-heading h1 { font-size:1.5rem; } .scenario-meta { gap:8px; flex-wrap:wrap; justify-content:flex-end; max-width:140px; } .scenario-meta>span:first-child { width:100%; text-align:right; font-size:.75rem; } .clock { font-size:1rem; } .stat-grid { gap:10px; } .stat-card { padding:13px 12px; } .stat-label { font-size:.75rem; gap:5px; } .stat-foot { display:none; } .workspace-grid { grid-template-columns:1fr; } .control-column { display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); align-items:start; } .visual-column { grid-row:1; } .bottom-grid { grid-template-columns:1fr 1fr; } .network-wrap { height:320px; } .roster-panel .panel-title { align-items:flex-start; flex-direction:column; gap:6px; } .console-footer { font-size:.6875rem; } }
@media(max-width:520px) { .control-column,.bottom-grid { grid-template-columns:1fr; } .stat-grid { grid-template-columns:repeat(2,1fr); } .stat-card { padding:14px 16px; } .stat-card strong { font-size:1.875rem; } .stat-label { font-size:.875rem; } .network-wrap { height:280px; } .network-footer { flex-direction:column; gap:4px; padding:12px 18px; } .panel-title .muted { font-size:.75rem; } .chart-legend { gap:12px; } .phone-shell { padding:0 22px; } .phone-main { padding:20px 0; } .status-symbol { width:88px; height:88px; margin:22px auto; font-size:2.75rem; } .phone-header .wordmark { font-size:1.375rem; } .phone-connection { font-size:.75rem; } .console-footer { flex-direction:column; } }
@media(prefers-reduced-motion:reduce) { * { transition:none!important; scroll-behavior:auto!important; } }
