cat / goq
clone

turns a linux box into a private steam streaming appliance: plug in, tap your key, play from another computer

fix/architecture-review-findings
goq / portal / style.css
style.css 19.2K
1/* ─────────────────────────────────────────────────────────────2 portal webview — goq.sh visual language, dark ramp.3 The app frames a video stream, so it commits to the landing4 page's dark palette as a single theme.5 ───────────────────────────────────────────────────────────── */67:root {8 /* paper + ink (goq.sh dark ramp) */9 --paper: #201913;10 --paper-2: #271f17;11 --stage: #16110c;12 --ink: #ece0cd;13 --ink-muted: #a3927a;14 --hair: rgba(236, 224, 205, 0.12);15 --hair-strong: rgba(236, 224, 205, 0.24);16 --panel-shadow: rgba(0, 0, 0, 0.45);1718 /* earth-tone splashes */19 --terracotta: #cf7048;20 --ochre: #d99a47;21 --moss: #8a9155;22 --clay: #bd6c52;23 --sand: #cbb488;2425 /* semantic aliases (state colors ride the palette) */26 --background: var(--paper);27 --foreground: var(--ink);28 --muted: var(--paper-2);29 --muted-fg: var(--ink-muted);30 --accent: var(--terracotta);31 --border: var(--hair);32 --border-strong: var(--hair-strong);33 --destructive: var(--clay);34 --green: var(--moss);35 --yellow: var(--ochre);3637 --mono: "SFMono-Regular", "Cascadia Mono", "Liberation Mono", ui-monospace, monospace;38 --sans: -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;39}40* { margin: 0; padding: 0; box-sizing: border-box; -webkit-user-select: none; user-select: none; }41input, textarea { -webkit-user-select: text; user-select: text; }42button { font: inherit; }43.info-value,44.overlay-status,45.host-info .value,46.config-row-value,47.node-id { -webkit-user-select: text; user-select: text; }48html, body { height: 100%; }49body {50 background: var(--background);51 color: var(--foreground);52 font-family: var(--sans);53 font-size: 13px;54 display: flex;55 flex-direction: column;56 overflow: hidden;57 -webkit-font-smoothing: antialiased;58}5960::selection { background: var(--ochre); color: var(--paper); }6162/* ─── Top bar ─────────────────────────────────────────────────────── */63.topbar {64 display: flex;65 align-items: center;66 gap: 12px;67 padding: 8px 16px;68 border-bottom: 1px solid var(--border);69 flex-shrink: 0;70}71.brand {72 font-family: var(--mono);73 font-size: 13px;74 font-weight: 600;75 letter-spacing: 0.02em;76 text-transform: lowercase;77 color: var(--terracotta);78}79.dev-badge {80 border: 1px solid color-mix(in srgb, var(--ochre) 65%, transparent);81 color: var(--yellow);82 font-family: var(--mono);83 font-size: 10px;84 font-weight: 600;85 letter-spacing: 0.04em;86 padding: 2px 5px;87 text-transform: uppercase;88}89.dev-badge.hidden { display: none; }90.dev-warning {91 margin: -10px 0 20px;92 border: 1px solid var(--yellow);93 color: var(--yellow);94 background: color-mix(in srgb, var(--ochre) 8%, transparent);95 padding: 10px;96 font-family: var(--mono);97 font-size: 11px;98 font-weight: 600;99 line-height: 1.5;100}101.dev-warning.hidden { display: none; }102.sep { color: var(--muted-fg); }103.status-line {104 font-family: var(--mono);105 font-size: 12px;106 color: var(--muted-fg);107 display: flex;108 align-items: center;109 gap: 7px;110}111/* pixel-square state dot, matching the site's pixel bullets */112.status-line .dot {113 width: 7px; height: 7px;114 background: var(--muted-fg);115}116.status-line .dot.ok { background: var(--green); }117.status-line .dot.err { background: var(--destructive); }118.status-line .dot.pending { background: var(--yellow); }119.status-line.ok { color: var(--green); }120.status-line.err { color: var(--destructive); }121.status-line.pending { color: var(--yellow); }122.topbar-right {123 margin-left: auto;124 display: flex;125 align-items: center;126 gap: 12px;127}128.node-id {129 font-family: var(--mono);130 font-size: 11px;131 color: var(--muted-fg);132 max-width: 180px;133 overflow: hidden;134 text-overflow: ellipsis;135 white-space: nowrap;136}137.controller-status {138 font-family: var(--mono);139 font-size: 10px;140 color: var(--muted-fg);141}142.controller-status.connected { color: var(--green); }143.controller-status.warning { color: var(--yellow); }144.link-btn {145 font-family: var(--mono);146 font-size: 12px;147 text-transform: lowercase;148 color: var(--muted-fg);149 cursor: pointer;150 text-decoration: underline;151 text-decoration-color: transparent;152 background: none;153 border: none;154 padding: 0;155 transition: color 0.1s, text-decoration-color 0.1s;156}157.link-btn:hover {158 color: var(--foreground);159 text-decoration-color: currentColor;160}161.link-btn:focus-visible,162.link-btn.controller-focus {163 color: var(--foreground);164 outline: 2px solid var(--moss);165 outline-offset: 4px;166}167168/* ─── Main area ───────────────────────────────────────────────────── */169.main {170 flex: 1;171 display: flex;172 align-items: center;173 justify-content: center;174 position: relative;175 min-height: 0;176 background: var(--stage);177}178#frame-canvas {179 max-width: 100%;180 max-height: 100%;181 object-fit: contain;182 display: none;183}184#frame-canvas.relative-control { cursor: none; }185body.native-pointer-control,186body.native-pointer-control * { cursor: none !important; }187.remote-pointer {188 position: absolute;189 display: none;190 width: 24px;191 height: 32px;192 z-index: 3;193 pointer-events: none;194 overflow: visible;195 transform: translate(-2px, -2px);196 filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.9));197}198.remote-pointer.visible { display: block; }199.remote-pointer path {200 fill: #fff;201 stroke: #000;202 stroke-width: 1.5;203 stroke-linejoin: round;204}205.placeholder {206 text-align: center;207 color: var(--muted-fg);208 font-family: var(--mono);209 font-size: 13px;210 padding: 40px;211}212.placeholder::before {213 content: "";214 display: inline-block;215 width: 8px; height: 8px;216 margin-right: 9px;217 background: var(--ochre);218 vertical-align: baseline;219}220.placeholder.hidden { display: none; }221222/* Session controls */223.control-bar {224 display: none;225 align-items: center;226 min-width: 0;227 gap: 4px;228}229.control-bar.visible { display: flex; }230.control-toggle {231 font-family: var(--mono);232 font-size: 12px;233 color: var(--muted-fg);234 cursor: pointer;235 padding: 4px 10px;236 text-decoration: underline;237 text-decoration-color: transparent;238 transition: color 0.1s, text-decoration-color 0.1s;239 background: none;240 border: none;241 min-width: 0;242}243#control-toggle {244 max-width: min(62vw, 760px);245 overflow: hidden;246 text-overflow: ellipsis;247 white-space: nowrap;248}249.control-toggle:hover {250 color: var(--foreground);251 text-decoration-color: currentColor;252}253.control-toggle.active {254 color: var(--green);255 text-decoration-color: currentColor;256}257.control-toggle:focus-visible,258.control-toggle.controller-focus {259 outline: 2px solid var(--moss);260 outline-offset: 1px;261}262.control-toggle.disabled {263 color: var(--yellow);264 cursor: not-allowed;265 text-decoration: none;266}267.control-toggle.disabled:hover {268 color: var(--yellow);269 text-decoration: none;270}271#audio-toggle {272 display: inline-flex;273 align-items: center;274 justify-content: center;275 min-width: 80px;276 min-height: 36px;277 padding: 8px 12px;278 font-family: var(--mono);279 font-size: 12px;280 line-height: 1;281 white-space: nowrap;282 touch-action: manipulation;283}284285/* ─── Bottom bar ──────────────────────────────────────────────────── */286.bottombar {287 display: grid;288 grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);289 align-items: center;290 gap: 8px;291 padding: 6px 16px;292 border-top: 1px solid var(--border);293 background: var(--background);294 flex-shrink: 0;295 font-family: var(--mono);296 font-size: 12px;297}298.bottombar-start,299.bottombar-end {300 display: flex;301 align-items: center;302 min-width: 0;303 gap: 8px;304}305.bottombar-start { justify-self: start; }306.bottombar-end { justify-self: end; }307.control-bar.visible + .bottombar-end .sep { display: none; }308.bottombar .prompt { color: var(--foreground); }309.bottombar .sep { color: var(--muted-fg); }310.bottombar .action {311 font-family: var(--mono);312 text-transform: lowercase;313 color: var(--muted-fg);314 cursor: pointer;315 text-decoration: underline;316 text-decoration-color: transparent;317 transition: color 0.1s, text-decoration-color 0.1s, background 0.1s;318 background: none;319 border: none;320}321.bottombar .action:hover {322 color: var(--foreground);323 text-decoration-color: currentColor;324}325.bottombar .action.primary {326 color: var(--foreground);327 border: 1px solid var(--border-strong);328 padding: 4px 12px;329 letter-spacing: 0.04em;330 text-decoration: none;331 box-shadow: 2px 2px 0 var(--hair);332}333.bottombar .action.primary:hover {334 background: var(--ink);335 color: var(--paper);336}337.bottombar .action.danger { color: var(--destructive); opacity: 0.8; }338.bottombar .action.danger:hover { opacity: 1; }339.bottombar .action:focus-visible,340.bottombar .action.controller-focus {341 color: var(--foreground);342 outline: 2px solid var(--moss);343 outline-offset: 3px;344}345.bottombar .hidden { display: none; }346.pin-group {347 display: flex;348 align-items: center;349 gap: 6px;350}351.pin-input {352 width: 80px;353 background: transparent;354 border: none;355 border-bottom: 1px solid var(--border-strong);356 color: var(--foreground);357 padding: 2px 4px;358 font-family: var(--mono);359 font-size: 12px;360 text-align: center;361}362.pin-input:focus {363 outline: none;364 border-bottom-color: var(--sand);365}366.pin-input.controller-focus { outline: 2px solid var(--moss); outline-offset: 3px; }367.pin-input.hidden { display: none; }368.pin-label {369 font-size: 11px;370 color: var(--muted-fg);371}372.pin-label.hidden { display: none; }373374@media (max-width: 720px) {375 .bottombar {376 grid-template-columns: auto minmax(0, 1fr) auto;377 padding-inline: 10px;378 }379 #control-toggle { max-width: 46vw; }380 .bottombar-end { gap: 5px; }381}382383@media (max-width: 480px) {384 .bottombar { padding-inline: 8px; }385 .pin-input { width: 60px; }386 #control-toggle { max-width: 40vw; }387}388389/* ─── Intro / overlay screens ─────────────────────────────────────── */390.overlay-screen {391 position: fixed;392 inset: 0;393 z-index: 100;394 display: flex;395 align-items: center;396 justify-content: center;397 background: var(--background);398}399.overlay-screen.hidden { display: none; }400.overlay-content {401 position: relative;402 text-align: center;403 width: 360px;404 max-width: calc(100vw - 48px);405 padding: 36px 32px 32px;406 border: 1px solid var(--border-strong);407 background: var(--muted);408 box-shadow: 12px 12px 0 var(--panel-shadow);409}410/* dithered strip along the panel's top edge */411.overlay-content::before {412 content: "";413 position: absolute;414 top: 0; left: 0; right: 0;415 height: 6px;416 background-image:417 repeating-linear-gradient(90deg,418 var(--terracotta) 0 6px, transparent 6px 18px),419 repeating-linear-gradient(90deg,420 var(--moss) 9px 12px, transparent 12px 30px),421 repeating-linear-gradient(90deg,422 var(--ochre) 21px 24px, transparent 24px 42px);423 opacity: 0.7;424 pointer-events: none;425}426.overlay-content h1 {427 font-family: var(--mono);428 font-size: 16px;429 font-weight: 700;430 text-transform: lowercase;431 letter-spacing: -0.01em;432 color: var(--foreground);433 margin-bottom: 12px;434}435#intro .overlay-content h1 {436 font-size: 26px;437 letter-spacing: -0.5px;438 margin-bottom: 8px;439 color: var(--terracotta);440}441.overlay-content p {442 font-size: 12px;443 color: var(--muted-fg);444 line-height: 1.6;445 margin-bottom: 24px;446 font-family: var(--mono);447 letter-spacing: 0.02em;448}449/* pixel security-key mark (tap overlay) */450.pixel-key {451 display: block;452 margin: 0 auto 16px;453 image-rendering: pixelated;454 image-rendering: crisp-edges;455}456/* three-step flow eyebrow: 01 pin · 02 tap · 03 play */457.flow-steps {458 display: flex;459 justify-content: center;460 gap: 16px;461 margin-bottom: 20px;462 font-family: var(--mono);463 font-size: 10px;464 font-weight: 500;465 letter-spacing: 0.12em;466 text-transform: uppercase;467 color: var(--muted-fg);468}469.flow-step { opacity: 0.55; }470.flow-step.active {471 opacity: 1;472 font-weight: 700;473 padding-bottom: 3px;474 border-bottom: 2px solid currentColor;475}476#intro .flow-step.active { color: var(--terracotta); }477#tap-overlay .flow-step.active { color: var(--ochre); }478.enrollment-content,479.invitation-content { width: 460px; }480.enrollment-peer {481 margin: 20px 0 4px;482 padding: 12px;483 border: 1px solid var(--border-strong);484 background: var(--background);485 font-family: var(--mono);486 text-align: left;487}488.enrollment-peer.hidden { display: none; }489.enrollment-peer span {490 display: block;491 margin-bottom: 7px;492 color: var(--muted-fg);493 font-size: 10px;494 text-transform: uppercase;495 letter-spacing: 0.08em;496}497.enrollment-peer output {498 display: block;499 overflow-wrap: anywhere;500 color: var(--sand);501 font-size: 11px;502 user-select: text;503 -webkit-user-select: text;504}505.invitation-summary {506 margin: 18px 0;507 border-block: 1px solid var(--border);508 font-family: var(--mono);509 font-size: 12px;510 text-align: left;511}512.invitation-summary > div {513 display: grid;514 grid-template-columns: 86px minmax(0, 1fr);515 gap: 12px;516 padding: 9px 4px;517 border-bottom: 1px solid var(--border);518}519.invitation-summary > div:last-child { border-bottom: 0; }520.invitation-summary dt { color: var(--muted-fg); }521.invitation-summary dd { color: var(--foreground); overflow-wrap: anywhere; }522.overlay-actions {523 display: flex;524 gap: 16px;525 justify-content: center;526 align-items: center;527 margin-top: 14px;528}529.overlay-btn.danger {530 color: var(--destructive);531 border-color: color-mix(in srgb, var(--destructive) 55%, var(--border));532}533.shortcut-key {534 color: var(--foreground);535}536.overlay-form {537 display: flex;538 gap: 8px;539 justify-content: center;540 align-items: center;541}542.overlay-input {543 width: 120px;544 text-align: center;545 background: transparent;546 border: none;547 border-bottom: 1px solid var(--border-strong);548 color: var(--foreground);549 padding: 6px 8px;550 font-family: var(--mono);551 font-size: 14px;552}553.overlay-input:focus {554 outline: none;555 border-bottom-color: var(--sand);556}557.overlay-input.controller-focus {558 outline: 2px solid var(--moss);559 outline-offset: 4px;560}561.overlay-btn {562 font-family: var(--mono);563 font-size: 13px;564 text-transform: lowercase;565 color: var(--muted-fg);566 cursor: pointer;567 background: none;568 border: none;569 padding: 6px 12px;570 text-decoration: underline;571 text-decoration-color: transparent;572 transition: color 0.1s, text-decoration-color 0.1s, background 0.1s;573}574.overlay-btn:hover {575 color: var(--foreground);576 text-decoration-color: currentColor;577}578.overlay-btn.primary {579 color: var(--foreground);580 border: 1px solid var(--border-strong);581 padding: 7px 20px;582 letter-spacing: 0.06em;583 text-decoration: none;584 box-shadow: 3px 3px 0 var(--hair);585}586.overlay-btn.primary:hover {587 background: var(--ink);588 color: var(--paper);589}590.overlay-btn:focus-visible,591.overlay-btn.controller-focus {592 color: var(--foreground);593 outline: 2px solid var(--moss);594 outline-offset: 2px;595 text-decoration-color: currentColor;596}597.overlay-btn.primary:focus-visible,598.overlay-btn.primary.controller-focus {599 text-decoration: none;600}601.overlay-btn:disabled {602 opacity: 0.4;603 cursor: not-allowed;604}605.overlay-status {606 font-family: var(--mono);607 font-size: 12px;608 color: var(--muted-fg);609 margin-top: 16px;610 min-height: 16px;611}612.overlay-status.pending { color: var(--yellow); }613.overlay-status.err { color: var(--destructive); }614.overlay-status.ok { color: var(--green); }615.controller-hint {616 margin: 18px 0 0 !important;617 font-size: 10px !important;618 color: var(--muted-fg) !important;619}620.controller-pin-btn { white-space: nowrap; }621622/* ─── Controller PIN pad ─────────────────────────────────────────── */623#pin-pad-overlay { z-index: 160; }624.pin-pad-content { width: 380px; }625.pin-pad-display {626 min-height: 36px;627 margin: 8px 0 4px;628 color: var(--foreground);629 font-family: var(--mono);630 font-size: 24px;631 letter-spacing: 0.3em;632}633.pin-pad-grid {634 display: grid;635 grid-template-columns: repeat(3, 72px);636 justify-content: center;637 gap: 10px;638 margin-top: 20px;639}640.pin-pad-key {641 height: 56px;642 border: 1px solid var(--border-strong);643 color: var(--foreground);644 background: var(--background);645 font-family: var(--mono);646 font-size: 18px;647 cursor: pointer;648 box-shadow: 3px 3px 0 var(--hair);649 transition: background 0.1s, color 0.1s;650}651.pin-pad-key:hover { border-color: var(--sand); }652.pin-pad-key:active {653 transform: translate(2px, 2px);654 box-shadow: 1px 1px 0 var(--hair);655}656.pin-pad-key:focus-visible,657.pin-pad-key.controller-focus {658 outline: 3px solid var(--moss);659 outline-offset: 2px;660 border-color: var(--moss);661}662.pin-pad-key.pin-pad-action { font-size: 12px; color: var(--muted-fg); text-transform: lowercase; }663.pin-pad-clear { display: block; margin: 12px auto 0; }664.panel-action { margin-top: 10px; }665666/* ─── Side panel ──────────────────────────────────────────────────── */667.panel-overlay {668 position: fixed;669 inset: 0;670 background: rgba(0, 0, 0, 0.5);671 z-index: 90;672 display: none;673}674.panel-overlay.visible { display: block; }675.panel {676 position: fixed;677 top: 0; right: 0; bottom: 0;678 width: 300px;679 background: var(--background);680 border-left: 1px solid var(--border-strong);681 transform: translateX(100%);682 transition: transform 0.15s;683 z-index: 91;684 display: flex;685 flex-direction: column;686}687.panel.visible { transform: translateX(0); }688.panel-header {689 display: flex;690 align-items: center;691 justify-content: space-between;692 padding: 10px 16px;693 border-bottom: 1px solid var(--border);694}695.panel-header h2 {696 font-family: var(--mono);697 font-size: 13px;698 font-weight: 600;699 text-transform: lowercase;700}701.panel-body {702 flex: 1;703 overflow-y: auto;704 padding: 12px 16px;705}706.panel-section {707 margin-bottom: 24px;708}709.panel-section h3 {710 font-family: var(--mono);711 font-size: 11px;712 font-weight: 700;713 text-transform: lowercase;714 color: var(--foreground);715 margin-bottom: 8px;716}717.panel-section h3 .hash { color: var(--ochre); font-weight: 500; }718.info-row {719 display: flex;720 justify-content: space-between;721 align-items: center;722 padding: 4px 0;723 border-bottom: 1px solid var(--border);724}725.info-row:last-child { border-bottom: none; }726.info-row.metric-stack {727 align-items: stretch;728 flex-direction: column;729 gap: 3px;730}731.info-row.metric-stack .info-value {732 overflow-wrap: anywhere;733 text-align: left;734}735.info-label {736 font-size: 12px;737 color: var(--muted-fg);738}739.info-value {740 font-family: var(--mono);741 font-size: 11px;742 font-variant-numeric: tabular-nums;743 color: var(--foreground);744}745.config-select {746 font-family: var(--mono);747 font-size: 11px;748 color: var(--foreground);749 background: var(--background);750 border: 1px solid var(--border);751 padding: 2px 4px;752 cursor: pointer;753}754.config-input {755 font-family: var(--mono);756 font-size: 11px;757 color: var(--foreground);758 background: var(--background);759 border: 1px solid var(--border);760 padding: 2px 4px;761 width: 80px;762}763.config-input:focus {764 outline: none;765 border-color: var(--sand);766}767768@media (prefers-reduced-motion: reduce) {769 .panel { transition: none; }770 .pin-pad-key:active { transform: none; }771}