Files
Behavision/server/internal/web/dist/assets/index-CtuyPF09.css
Suriyakumarvijayanayagam 18686cbceb Live view at head office, relayed through the agent's outbound connection
I got this wrong first time. "Head office cannot show live video cheaply"
conflated TRUE VIDEO with SEEING THE CAMERA NOW, and only the first needs
WebRTC and a TURN server.

The shop PC is behind a router with no inbound route, so head office
cannot pull the engine's MJPEG. It can answer the agent's outbound
requests, which is the shape of everything else here: the server holds a
poll open, the agent asks "is anyone watching?", and pushes JPEGs up for
exactly as long as somebody is.

Measured on the office camera: 98 KB full frame, 20.8 KB re-encoded at
640/q60, so one watcher costs ~83 KB/s. 47 frames arrived in 12 seconds -
4 fps, as configured. The UI says "about 4 frames a second" rather than
letting anyone conclude the camera stutters.

Nothing is uploaded when nobody is looking, which is the whole cost
argument: Publish returns false once the last viewer goes, interest lapses
on a timer each viewer refreshes as it reads (so a closed tab stops the
upload within seconds), one push is capped at five minutes, and the UI
streams one camera at a time.

LiveHub is deliberately the opposite of the arrivals Hub. There a doorbell
pushes nothing because nothing may be lost; here a dropped frame is the
correct outcome, so each viewer has a one-slot buffer that is overwritten -
the only frame worth having is the newest, and a queue would show an
ever-growing delay behind the shop instead of dropping back to live.

Ownership is proved once, before anything streams: the relay is keyed on a
camera id, a hub does not know whose camera it holds, and a camera id is
not a secret. Verified: another tenant gets 404, no session gets 401, and
an agent cannot push into another site's camera.

Also fixes a bug I introduced with it - the Live button was gated on
`connected`, which is head office's last report and up to two minutes
stale, so it hid itself during every reconnect. "Is that camera really
down?" is exactly when somebody wants to look, and a hidden control says
"you cannot" where the honest answer is "here is why".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HViLj9gYNRtSr7YVZmW5sn
2026-09-04 16:46:23 +05:30

2 lines
20 KiB
CSS

:root{--ground: #0E1317;--surface: #161D23;--surface-2: #1D262D;--line: #27333B;--line-soft: #1F2A31;--ink: #E7EEF3;--ink-2: #B4C2CC;--muted: #7C8B97;--accent: #45B0C7;--accent-dim:#123039;--ok: #4FB37B;--ok-dim: #12291F;--warn: #E0A33A;--warn-dim: #2C2313;--bad: #E0655A;--bad-dim: #2B1917;--radius: 10px;--mono: "SFMono-Regular", ui-monospace, Menlo, Consolas, monospace}*{box-sizing:border-box;margin:0}html{color-scheme:dark}body{background:var(--ground);color:var(--ink);font:15px/1.55 system-ui,-apple-system,Segoe UI,sans-serif;-webkit-font-smoothing:antialiased}button,input,select,textarea{font:inherit;color:inherit}:focus-visible{outline:2px solid var(--accent);outline-offset:2px}code{font-family:var(--mono);font-size:.9em}h1{font-size:22px;font-weight:620;letter-spacing:-.015em}h2{font-size:16px;font-weight:600}h3{font-size:13px;font-weight:600;text-transform:uppercase;letter-spacing:.08em;color:var(--muted)}.sub{color:var(--muted);font-size:13.5px}.num{font-variant-numeric:tabular-nums}.ok{color:var(--ok)}.warn{color:var(--warn)}.bad{color:var(--bad)}.app{min-height:100vh;display:flex;flex-direction:column}.topbar{position:sticky;top:0;z-index:20;display:flex;align-items:center;gap:28px;padding:0 24px;height:60px;background:var(--surface);border-bottom:1px solid var(--line)}.brand{display:flex;align-items:center;gap:11px}.brand strong{display:block;font-size:15px;font-weight:620;letter-spacing:-.01em}.brand .org{display:block;font-size:12px;color:var(--muted)}.mark{width:18px;height:18px;border-radius:50%;border:2.5px solid var(--accent);box-shadow:inset 0 0 0 3px var(--ground);flex:none}.mark.big{width:30px;height:30px;border-width:3px;margin-bottom:14px}.tabs{display:flex;gap:2px;margin-right:auto}.tabs button{background:none;border:0;border-radius:7px;padding:7px 13px;color:var(--ink-2);cursor:pointer;font-size:14px}.tabs button:hover{background:var(--surface-2);color:var(--ink)}.tabs button[aria-current=page]{background:var(--accent-dim);color:var(--accent);font-weight:550}.who{display:flex;align-items:center;gap:12px}.who .name{font-size:13.5px}.who .role{font-size:11px;color:var(--muted);text-transform:uppercase;letter-spacing:.07em}.page{flex:1;padding:26px 24px 64px;max-width:1280px;width:100%;margin:0 auto;display:flex;flex-direction:column;gap:20px}.head{display:flex;align-items:flex-end;gap:16px;flex-wrap:wrap}.head h1{margin-right:auto}.head .sub{padding-bottom:2px}button.primary{background:var(--accent);color:#04161b;border:0;border-radius:7px;padding:9px 16px;font-weight:600;cursor:pointer}button.primary:disabled{opacity:.5;cursor:default}button.ghost{background:none;border:1px solid var(--line);border-radius:7px;padding:7px 13px;color:var(--ink-2);cursor:pointer}button.ghost:hover{border-color:var(--muted);color:var(--ink)}.segmented{display:flex;border:1px solid var(--line);border-radius:8px;overflow:hidden}.segmented button{background:none;border:0;padding:7px 14px;color:var(--ink-2);cursor:pointer;font-size:13.5px}.segmented button+button{border-left:1px solid var(--line)}.segmented button[aria-current]{background:var(--accent-dim);color:var(--accent)}.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--radius)}.grid{display:grid;gap:14px}.grid.sites{grid-template-columns:repeat(auto-fill,minmax(320px,1fr));gap:16px}.grid.stats{grid-template-columns:repeat(auto-fit,minmax(190px,1fr))}.card.site{overflow:hidden;padding:0;cursor:pointer;border-left:3px solid var(--line);transition:border-color .15s ease,transform .15s ease}.card.site.state-ok{border-left-color:var(--ok)}.card.site.state-warn{border-left-color:var(--warn)}.card.site.state-bad{border-left-color:var(--bad)}.card.site.state-idle{border-left-color:var(--muted)}.card.site:hover{transform:translateY(-1px)}.card.site:focus-visible{outline:2px solid var(--accent);outline-offset:2px}@media (prefers-reduced-motion: reduce){.card.site{transition:none}}.metrics{display:grid;grid-template-columns:repeat(3,1fr);border-top:1px solid var(--line-soft)}.metric{padding:11px 6px;text-align:center}.metric+.metric{border-left:1px solid var(--line-soft)}.metric b{display:block;font-size:15px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.01em}.metric b.ok{color:var(--ink)}.metric b.warn{color:var(--warn)}.metric b.bad{color:var(--bad)}.metric b.idle{color:var(--muted)}.metric span{display:block;margin-top:1px;font-size:11px;color:var(--muted)}.shopmark{width:38px;height:30px;fill:none;stroke:var(--line);stroke-width:2;stroke-linejoin:round}.pill{display:inline-block;padding:3px 9px;border-radius:20px;flex:none;font-size:11.5px;font-weight:550;letter-spacing:.01em;background:var(--surface-2);color:var(--ink-2)}.pill.ok{background:var(--ok-dim);color:var(--ok)}.pill.warn{background:var(--warn-dim);color:var(--warn)}.pill.bad{background:var(--bad-dim);color:var(--bad)}.pill.new{background:var(--accent-dim);color:var(--accent)}.dot{display:inline-block;width:7px;height:7px;border-radius:50%;background:var(--muted);margin-right:7px;vertical-align:1px}.dot.ok{background:var(--ok)}.dot.warn{background:var(--warn)}.card.stat{padding:16px 18px;display:flex;flex-direction:column;gap:3px}.stat .value{font-size:30px;font-weight:620;letter-spacing:-.02em;font-variant-numeric:tabular-nums;line-height:1.15}.stat .label{font-size:13.5px;color:var(--ink-2)}.stat .note{font-size:12.5px;color:var(--muted);margin-top:3px}.banner{padding:12px 16px;border-radius:var(--radius);font-size:14px;display:flex;gap:16px;align-items:flex-start}.banner.warn{background:var(--warn-dim);border:1px solid #4A3A18;color:#f0d9a6}.banner.ok{background:var(--ok-dim);border:1px solid #1E4534;color:#c6e9d6}.banner>div{flex:1}.creds{display:flex;gap:26px;margin-top:10px;flex-wrap:wrap}.creds dt{font-size:11px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted)}.creds dd{font-family:var(--mono);font-size:14px;-webkit-user-select:all;user-select:all}.arrivals{list-style:none;padding:0;display:grid;gap:8px}.card.arrival{display:flex;align-items:center;gap:14px;padding:11px 14px}.face{width:46px;height:46px;border-radius:50%;flex:none;object-fit:cover;background:var(--surface-2)}.face.initials{display:grid;place-items:center;color:var(--muted);font-size:15px;font-weight:600;letter-spacing:.02em}.who-col{display:flex;flex-direction:column;gap:1px;flex:1;min-width:0}.who-col strong{font-weight:570}.attrs{font-size:12.5px;color:var(--muted);text-transform:capitalize}.toolbar{display:flex;gap:10px}.search{flex:1;max-width:380px;background:var(--surface);border:1px solid var(--line);border-radius:8px;padding:9px 13px}.search::placeholder{color:var(--muted)}input::placeholder,textarea::placeholder{color:var(--muted);opacity:1}.tablewrap{overflow-x:auto;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius)}table.rows{border-collapse:collapse;width:100%;min-width:620px}table.rows th,table.rows td{text-align:left;padding:11px 16px;border-bottom:1px solid var(--line-soft)}table.rows tr:last-child td{border-bottom:0}table.rows th{font-size:11.5px;text-transform:uppercase;letter-spacing:.08em;color:var(--muted);font-weight:600;background:var(--surface-2)}table.rows tbody tr{cursor:pointer}table.rows tbody tr:hover{background:var(--surface-2)}table.rows td.num{font-variant-numeric:tabular-nums}.chart-card{padding:18px}.chart-head{margin-bottom:16px}.peak{font-size:12.5px;color:var(--muted);margin-bottom:8px}.peak b{color:var(--ink-2);font-weight:600;font-variant-numeric:tabular-nums}.chart{display:flex;align-items:flex-end;gap:3px;height:190px;overflow-x:auto;padding-bottom:4px}.col{flex:1;min-width:16px;display:flex;flex-direction:column;align-items:center;gap:6px;height:100%}.bars{flex:1;width:100%;display:flex;flex-direction:column;justify-content:flex-end}.bar{display:block;width:100%;border-radius:2px 2px 0 0}.bar.new{background:var(--accent)}.bar.returning{background:var(--accent-dim);border-radius:0}.col:hover .bar.returning{background:#1b4552}.tick{font-size:10.5px;color:var(--muted);white-space:nowrap;font-variant-numeric:tabular-nums}.legend{display:flex;gap:18px;align-items:center;margin-top:14px;padding-top:12px;border-top:1px solid var(--line-soft);font-size:12.5px;color:var(--ink-2)}.legend span{display:flex;align-items:center;gap:7px}.swatch{width:10px;height:10px;border-radius:2px;display:inline-block}.swatch.new{background:var(--accent)}.swatch.returning{background:var(--accent-dim)}.pad{padding:24px 0}.overlay{position:fixed;top:0;right:0;bottom:0;left:0;background:#04080a9e;display:flex;justify-content:flex-end;z-index:50}.drawer{width:min(560px,100%);background:var(--surface);border-left:1px solid var(--line);height:100%;overflow-y:auto;display:flex;flex-direction:column}.drawer.narrow{width:min(440px,100%)}.drawer-head{position:sticky;top:0;z-index:1;display:flex;align-items:flex-start;gap:16px;padding:18px 22px;background:var(--surface);border-bottom:1px solid var(--line)}.drawer-head h2{margin-right:auto}.drawer-head>div{flex:1}.drawer-body{padding:20px 22px;display:flex;flex-direction:column;gap:14px}.drawer-body+.drawer-body{border-top:1px solid var(--line-soft)}fieldset{border:0;padding:0;margin:0;display:flex;flex-direction:column;gap:14px}fieldset:disabled{opacity:.6}label{display:flex;flex-direction:column;gap:6px;font-size:13px;color:var(--ink-2)}label input[type=text],label input[type=email],label input[type=password],label input:not([type]),.drawer input{background:var(--ground);border:1px solid var(--line);border-radius:7px;padding:9px 12px;color:var(--ink);font-size:14.5px}label .hint{font-size:12px;color:var(--muted);line-height:1.45}label.check{flex-direction:row;align-items:center;gap:9px}label.check input{width:auto}.timeline{list-style:none;padding:0;display:grid;gap:8px}.timeline li{display:flex;align-items:center;gap:12px;font-size:13.5px;padding:9px 12px;background:var(--ground);border-radius:7px}.timeline .when{font-variant-numeric:tabular-nums}.timeline .where{color:var(--muted);margin-right:auto}.state{display:flex;flex-direction:column;align-items:center;gap:8px;padding:64px 20px;text-align:center;color:var(--ink-2)}.state .sub{max-width:46ch}.boot{min-height:100vh;display:flex;align-items:center;justify-content:center;gap:10px;color:var(--muted)}.error{color:var(--bad);font-size:13.5px}.spinner{width:14px;height:14px;border-radius:50%;border:2px solid var(--line);border-top-color:var(--accent);animation:spin .7s linear infinite;display:inline-block}@keyframes spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.spinner{animation:none}}.signin{min-height:100vh;display:grid;place-items:center;padding:24px}.signin .card{width:min(380px,100%);padding:30px;display:flex;flex-direction:column;gap:14px}.signin h1{font-size:20px}.signin .sub{margin-top:-8px;margin-bottom:6px}.signin .foot{font-size:12.5px;color:var(--muted);text-align:center;margin-top:4px;line-height:1.5}@media (max-width: 720px){.topbar{height:auto;flex-wrap:wrap;padding:12px 16px;gap:12px}.tabs{order:3;width:100%;overflow-x:auto}.page{padding:18px 16px 48px}.who .name{display:none}}.pair{display:grid;grid-template-columns:1fr 1fr;gap:14px}select{background:var(--ground);border:1px solid var(--line);border-radius:7px;padding:9px 12px;color:var(--ink);font-size:14.5px}button.ghost.danger{border-color:#4a211d;color:var(--bad)}button.ghost.danger:hover{border-color:var(--bad)}.drawer.wizard{width:min(560px,100%)}.steps{list-style:none;display:flex;gap:4px;padding:14px 22px;margin:0;border-bottom:1px solid var(--line-soft);background:var(--surface);position:sticky;top:62px;z-index:1}.steps li{flex:1;display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--muted);min-width:0}.steps li .dot{width:20px;height:20px;border-radius:50%;flex:none;display:grid;place-items:center;font-size:11px;background:var(--surface-2);color:var(--muted)}.steps li.now{color:var(--ink);font-weight:550}.steps li.now .dot{background:var(--accent);color:#04161b}.steps li.done .dot{background:var(--ok-dim);color:var(--ok)}.waiting{display:flex;gap:12px;align-items:center;padding:14px 16px;background:var(--ground);border:1px solid var(--line);border-radius:var(--radius)}.waiting>div{display:flex;flex-direction:column;gap:2px}.outcome{border:1px solid var(--line);border-left-width:3px;border-radius:var(--radius);padding:14px 16px;display:flex;flex-direction:column;gap:12px}.outcome.ok{border-left-color:var(--ok);background:var(--ok-dim)}.outcome.warn{border-left-color:var(--warn);background:var(--warn-dim)}.outcome.bad{border-left-color:var(--bad);background:var(--bad-dim)}.outcome-head{display:flex;align-items:center;gap:10px;flex-wrap:wrap}.outcome-head b{font-size:14.5px}.proof{width:100%;border-radius:6px;display:block;background:#05090b}.advice{margin:0;padding-left:18px;display:grid;gap:6px;font-size:13.5px;color:var(--ink-2);line-height:1.5}.verified{display:flex;align-items:center;gap:8px;margin-top:10px;font-size:13px}.verified .mark{width:17px;height:17px;border-radius:50%;flex:none;display:grid;place-items:center;font-size:10.5px}.verified.ok{color:var(--ok)}.verified.ok .mark{background:var(--ok-dim)}.verified.warn{color:var(--warn)}.verified.warn .mark{background:var(--warn-dim)}.verified.bad{color:var(--bad)}.verified.bad .mark{background:var(--bad-dim)}.verified.idle{color:var(--muted)}.verified.idle .mark{background:var(--surface-2)}.checklist{list-style:none;padding:0;margin:0;display:grid;gap:2px}.checklist li{display:flex;gap:12px;padding:13px 14px;background:var(--ground);border-radius:8px;border-left:3px solid var(--line)}.checklist li>div{display:flex;flex-direction:column;gap:3px;flex:1}.checklist li.pass{border-left-color:var(--ok)}.checklist li.warn{border-left-color:var(--warn)}.checklist li.fail{border-left-color:var(--bad)}.checklist li.unknown{border-left-color:var(--muted)}.checklist .mark{width:20px;height:20px;border-radius:50%;flex:none;display:grid;place-items:center;font-size:11px;background:var(--surface-2);color:var(--muted)}.checklist li.pass .mark{background:var(--ok-dim);color:var(--ok)}.checklist li.warn .mark{background:var(--warn-dim);color:var(--warn)}.checklist li.fail .mark{background:var(--bad-dim);color:var(--bad)}.advice-line{font-size:13px;color:var(--warn);line-height:1.45}.checklist li.pass .advice-line{color:var(--muted)}.grid.cams{grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}.card.cam{overflow:hidden;border-left:0;padding:0;cursor:pointer;transition:border-color .15s ease,transform .15s ease}.card.cam:hover{border-color:var(--muted);transform:translateY(-1px)}.card.cam:focus-visible{outline:2px solid var(--accent);outline-offset:2px}@media (prefers-reduced-motion: reduce){.card.cam{transition:none}}.shot{position:relative;aspect-ratio:16 / 10;background:#05090b;display:grid;place-items:center}.shot img{width:100%;height:100%;object-fit:cover;display:block}.noshot{display:flex;flex-direction:column;align-items:center;gap:10px;color:var(--muted);font-size:12.5px;text-align:center;padding:0 28px;line-height:1.5}.lens{width:34px;height:34px;border-radius:50%;border:2px solid var(--line);position:relative}.lens:after{content:"";position:absolute;top:7px;right:7px;bottom:7px;left:7px;border-radius:50%;border:2px solid var(--line-soft)}.shot-over{position:absolute;inset:auto 0 0 0;display:flex;align-items:flex-end;justify-content:space-between;gap:10px;padding:26px 14px 12px;background:linear-gradient(transparent,#04080ad9)}.shot-name b{display:block;font-size:14.5px;font-weight:600;letter-spacing:-.01em}.shot-name span{display:block;font-size:11.5px;color:#9fb0ba;margin-top:1px}.status{display:flex;align-items:center;gap:6px;flex:none;font-size:11px;font-weight:550;letter-spacing:.01em;padding:4px 9px;border-radius:20px;white-space:nowrap;background:#0e1317b8;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);color:var(--ink-2)}.status i{width:6px;height:6px;border-radius:50%;background:var(--muted)}.status.ok{color:#8fe0b4}.status.ok i{background:var(--ok)}.status.warn{color:#efc77c}.status.warn i{background:var(--warn)}.status.bad{color:#f0a79e}.status.bad i{background:var(--bad)}.status.idle i{background:var(--muted)}.shot-age{position:absolute;top:10px;right:12px;font-size:10.5px;color:#9fb0ba;background:#04080a99;padding:2px 7px;border-radius:20px;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}.verdict{display:flex;align-items:center;gap:10px;padding:12px 14px;font-size:13px;border-top:1px solid var(--line-soft)}.verdict .words{flex:1;min-width:0}.verdict .go{color:var(--muted);font-size:14px}.verdict .mark{width:18px;height:18px;border-radius:50%;flex:none;display:grid;place-items:center;font-size:10.5px}.verdict.ok{color:var(--ok)}.verdict.ok .mark{background:var(--ok-dim)}.verdict.warn{color:var(--warn)}.verdict.warn .mark{background:var(--warn-dim)}.verdict.bad{color:var(--bad)}.verdict.bad .mark{background:var(--bad-dim)}.verdict.idle{color:var(--muted)}.verdict.idle .mark{background:var(--surface-2)}.claim{margin-top:22px;padding-top:18px;border-top:1px solid var(--line-soft)}.claim h3{font-size:14px;font-weight:600;margin-bottom:6px}.claim .field{display:block;margin:12px 0}.claim .field span{display:block;font-size:12.5px;color:var(--muted);margin-bottom:5px}.claim .field input{width:100%;background:var(--ground);border:1px solid var(--line);border-radius:7px;padding:9px 12px}.claim .row{display:flex;gap:8px;margin-top:12px}.claim .code{font-family:var(--mono);font-size:19px;letter-spacing:.08em;background:var(--ground);border:1px solid var(--line);border-radius:8px;padding:14px 12px;text-align:center;margin:12px 0 10px;-webkit-user-select:all;user-select:all;word-break:break-all}.with-assistant{display:flex;flex:1;min-height:0}.with-assistant .page{flex:1;min-width:0}.ask-btn{background:var(--accent-dim);color:var(--accent);border:0;border-radius:7px;padding:7px 13px;cursor:pointer;font-size:13.5px;font-weight:550;display:flex;align-items:center;gap:7px}.ask-btn:hover,.ask-btn.on{background:var(--accent);color:#04161b}.assistant{width:360px;flex:none;border-left:1px solid var(--line);background:var(--surface);display:flex;flex-direction:column;position:sticky;top:60px;height:calc(100vh - 60px)}.assistant-head{display:flex;align-items:flex-start;gap:12px;padding:15px 16px;border-bottom:1px solid var(--line-soft)}.assistant-head>div{flex:1;display:flex;flex-direction:column;gap:2px}.assistant-body{flex:1;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:12px}.assistant-ask{display:flex;gap:8px;padding:12px 14px;border-top:1px solid var(--line-soft)}.assistant-ask input{flex:1;min-width:0;background:var(--ground);border:1px solid var(--line);border-radius:8px;padding:9px 12px}.bubble{padding:11px 13px;border-radius:12px;font-size:14px;line-height:1.55;white-space:pre-wrap;max-width:100%}.bubble.user{background:var(--accent-dim);color:var(--ink);align-self:flex-end;border-bottom-right-radius:4px}.bubble.assistant{background:var(--ground);border:1px solid var(--line-soft);border-bottom-left-radius:4px}.bubble.failed{border-color:#4a211d;color:var(--bad)}.bubble.assistant-thinking{color:var(--muted);display:flex;align-items:center;gap:9px}.used{display:block;margin-top:8px;padding-top:7px;border-top:1px solid var(--line-soft);font-size:11.5px;color:var(--muted)}.suggest{display:flex;flex-direction:column;align-items:flex-start;gap:8px}.chip{background:var(--ground);border:1px solid var(--line);border-radius:20px;padding:7px 13px;color:var(--ink-2);cursor:pointer;font-size:13px;text-align:left}.chip:hover{border-color:var(--accent);color:var(--accent)}@media (max-width: 900px){.with-assistant{flex-direction:column}.assistant{width:100%;height:60vh;position:static;border-left:0;border-top:1px solid var(--line)}}.card.cam .watch{position:absolute;left:10px;top:10px;z-index:2;display:inline-flex;align-items:center;gap:6px;padding:4px 9px;border-radius:999px;border:0;cursor:pointer;font:inherit;font-size:11.5px;font-weight:600;letter-spacing:.02em;color:#fff;background:#0c1014b8;-webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px)}.card.cam .watch:hover{background:#0c1014e6}.card.cam .watch i{width:7px;height:7px;border-radius:50%;background:#e5484d;box-shadow:0 0 #e5484db3;animation:livepulse 2s infinite}@keyframes livepulse{70%{box-shadow:0 0 0 6px #e5484d00}to{box-shadow:0 0 #e5484d00}}@media (prefers-reduced-motion: reduce){.card.cam .watch i{animation:none}}.drawer.live{max-width:760px}.liveshot{position:relative;background:#000;border-radius:10px;overflow:hidden;aspect-ratio:16 / 9}.liveshot img{width:100%;height:100%;object-fit:contain;display:block}.livewait{position:absolute;top:0;right:0;bottom:0;left:0;display:grid;place-items:center;font-size:13px;color:#ffffffc7;background:#00000059}