Files
Behavision/server/internal/web/dist/assets/index-Bgt5SnW3.css
Suriyakumarvijayanayagam 3f9fb33b24 Accounts people can create, and photos on a server with no bucket
A tenant had exactly the users somebody had created with a command on the
server. That is not a missing screen: a shop with an owner and four staff
either shared one password or raised a ticket per person, and a phone app
for the shop floor could not exist while there was one account to sign in
as.

Registration is by invitation, never open signup - the same line already
drawn around creating a company. The code carries the address and the role
and the request carries only a password, so a code that gets forwarded
cannot become somebody else's account, and a staff invitation cannot be
redeemed as an owner. Single use lives in the UPDATE and the account is
created in the same transaction.

Deactivating a member revokes their sessions in that transaction too. An
access token lives twelve hours, so without it "remove their access"
removed it sometime tomorrow. The session list and revoke that go with it
are the benefit of opaque tokens the product had been paying for and never
collecting: nothing could say what was signed in, let alone stop one.

Face images now work on a deployment with no object storage, which was
every local install and every self-hosted site - the arrivals feed said
"not storing customer photos" for every customer forever, on the screen
whose whole job is to show a face. Bounded to one row per visitor, so it
grows with the customer base and not with footfall; the bucket stays
primary wherever one exists.

Image.auth says whether a URL needs the session, because a browser img
cannot load one that does, a mobile image view can, and a webview can do
neither - the desktop client resolves those to a data URI in Go.

Found by running it, not by tests:

  * UPDATE ... RETURNING gives the value AFTER the update, so the prune
    read back empty keys, deleted nothing, and the table grew with
    footfall exactly as if it were not there. The fake agreed with either
    version; only the live Postgres test caught it.
  * Trusting only the auth flag broke every shop card, because Sites.jsx
    rebuilt a partial snapshot object and dropped it. A relative URL is
    now sufficient on its own.
  * ago() renders a future time as "just now", so a code valid for a week
    read "expires just now".

Verified live against real Postgres: invite, preview, escalation refused,
register into a session, replay 404, staff forbidden, device revoked and
401 at once, last owner refused, and a 92,405-byte camera JPEG stored,
served to its owner, 401 with no session, 404 to another tenant, and
rendered in a browser.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HViLj9gYNRtSr7YVZmW5sn
2026-09-05 11:45:42 +05:30

2 lines
21 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;overflow:hidden;object-fit:cover;background:var(--surface-2)}.face>img{width:100%;height:100%;object-fit:cover;display:block}.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}.rows tr.inactive td{opacity:.55}.rows .role{text-transform:capitalize}.rows td.right{text-align:right}.pill.muted{margin-left:8px;font-size:11px;padding:1px 7px;border-radius:999px;background:var(--surface-2);color:var(--muted);vertical-align:middle}.pending{margin-top:26px}.pending h2{font-size:14px;font-weight:600;color:var(--muted);margin:0 0 10px}.invites{list-style:none;padding:0;display:grid;gap:8px}.card.invite{display:flex;align-items:center;justify-content:space-between;gap:14px;padding:11px 14px}.card.invite .sub{display:block}.creds code.big{font-size:16px;letter-spacing:.06em}.linkish{background:none;border:0;padding:0;font:inherit;color:var(--accent);cursor:pointer;text-decoration:underline;text-underline-offset:2px}.linkish:hover{opacity:.8}.codefield{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;letter-spacing:.04em;text-transform:uppercase}