Files
wadamesh/web/shell/app.css
T
Kaj SchittecatandClaude Opus 5.5 b372b91a54 web: Emscripten build of the real UI in a page (web/build.sh web, serve)
pthreads for the UI's background tasks, LVGL + the UI loop on the browser main
thread (emscripten_set_main_loop), IDBFS at /data loaded before main() and
persisted after writes settle and on hide/pagehide; Reboot persists and
reloads. Page shell in the site's Night palette: Demo badge, Connect
placeholder, Reset demo data, Fullscreen; canvas scaled with aspect kept,
crisp at whole device pixels; pointer = finger, keyboard = CardKB codes.
serve.py and nginx-snippet.conf send COOP/COEP; without isolation the page
says so. Release -O2 (wasm brotli 1.14 MB), web-debug variant with -g.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 12:56:00 +02:00

118 lines
5.9 KiB
CSS

/* wadamesh in the browser: the page around the device canvas.
Tokens are the site's Night palette (deploy/site/theme.css), dark only. */
:root{
color-scheme:dark;
--bg:#000400;
--card:rgba(11,14,16,.74);
--solid:#0B0E10;
--ink:#E6EBED; --ink2:#D2D9DD; --mut:#B0BAC0; --dim:#8C979D;
--line:#1C2428;
--control:#161D21; --control-hi:#222C31;
--teal:#15B6A6; --cyan:#19D6C2;
--accent-fill:#15B6A6; --on-accent:#00120F;
--accent-soft:rgba(25,214,194,.13);
--bar:rgba(0,0,0,.5);
--frame:#16191D; --frame-edge:#2A3036;
--warn:#F2A33A; --warn-bg:rgba(242,163,58,.13); --warn-line:rgba(242,163,58,.38);
--bad:#F06A6E;
--shadow:0 22px 50px -26px rgba(0,0,0,.85);
--bar-h:56px;
--gutter:16px;
}
*{box-sizing:border-box}
html,body{margin:0; height:100%}
html{background:var(--bg)}
body{
min-height:100%; display:flex; flex-direction:column;
color:var(--ink); background:
radial-gradient(1200px 600px at 20% -10%, rgba(25,214,194,.10), transparent 60%),
radial-gradient(900px 500px at 90% 110%, rgba(90,169,255,.07), transparent 60%),
var(--bg);
font-family:'Montserrat',-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif; font-weight:500;
-webkit-font-smoothing:antialiased;
}
::selection{background:rgba(25,214,194,.32)}
/* ---- the bar ---- */
.bar{
display:flex; align-items:center; gap:10px; flex-wrap:wrap;
min-height:var(--bar-h); padding:8px var(--gutter);
padding-left:max(var(--gutter), env(safe-area-inset-left));
padding-right:max(var(--gutter), env(safe-area-inset-right));
background:var(--bar); border-bottom:1px solid var(--line);
-webkit-backdrop-filter:blur(10px); backdrop-filter:blur(10px);
}
.brand{display:inline-flex; align-items:center; gap:8px; color:var(--ink); text-decoration:none;
font-weight:700; letter-spacing:.02em; font-size:17px}
.brand img{display:block}
.badge{display:inline-flex; align-items:center; height:24px; padding:0 10px; border-radius:12px;
background:var(--warn-bg); color:var(--warn); box-shadow:inset 0 0 0 1px var(--warn-line);
font-size:12px; font-weight:700; letter-spacing:.06em; text-transform:uppercase}
.spacer{flex:1}
.btn{
height:36px; padding:0 14px; border:0; border-radius:18px; cursor:pointer;
background:var(--control); color:var(--ink2); box-shadow:inset 0 0 0 1px var(--line);
font:inherit; font-size:14px; font-weight:600; white-space:nowrap;
transition:background .15s, box-shadow .15s, color .15s;
}
.btn:hover{background:var(--control-hi)}
.btn:focus-visible{outline:none; box-shadow:inset 0 0 0 1px var(--teal), 0 0 0 3px var(--accent-soft)}
.btn.primary{background:var(--accent-fill); color:var(--on-accent); box-shadow:none}
.btn.primary:hover{background:var(--cyan)}
.btn.icon{width:36px; padding:0; display:inline-grid; place-items:center}
.btn.icon svg{width:18px; height:18px; fill:none; stroke:currentColor; stroke-width:2; stroke-linecap:round; stroke-linejoin:round}
.btn[hidden]{display:none}
/* ---- the stage: the canvas, scaled by app.js (aspect kept, integer device pixels when it can) ---- */
#stage{
flex:1; min-height:0; display:flex; align-items:center; justify-content:center;
padding:var(--gutter);
padding-left:max(var(--gutter), env(safe-area-inset-left));
padding-right:max(var(--gutter), env(safe-area-inset-right));
}
#frame{position:relative; line-height:0; border-radius:10px; background:#000;
box-shadow:0 0 0 1px var(--frame-edge), 0 0 0 7px var(--frame), 0 0 0 8px var(--frame-edge), var(--shadow)}
#screen{display:block; width:800px; height:480px; border-radius:2px; touch-action:none; outline:none;
-webkit-user-select:none; user-select:none; -webkit-tap-highlight-color:transparent; cursor:default}
#screen.crisp{image-rendering:crisp-edges; image-rendering:pixelated} /* integer device-pixel scale: nearest */
#overlay{position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center;
gap:6px; padding:24px; text-align:center; line-height:1.45; background:var(--solid); border-radius:2px}
#overlay[hidden]{display:none}
#overlay img{opacity:.95; margin-bottom:8px}
#status{margin:0; font-size:16px; font-weight:600; color:var(--ink)}
#overlay .detail{margin:0; max-width:520px; font-size:13px; color:var(--mut)}
#overlay .detail code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:12px; color:var(--ink2)}
#overlay.busy #status::after{content:""; display:inline-block; width:1.2em; text-align:left;
animation:dots 1.2s steps(4,end) infinite}
@keyframes dots{0%{content:""}25%{content:"."}50%{content:".."}75%{content:"..."}}
#overlay.fatal #status{color:var(--bad)}
#overlay .btn{margin-top:10px; line-height:normal}
.hint{margin:0 auto; padding:0 var(--gutter) 18px; max-width:820px; text-align:center;
color:var(--dim); font-size:13px; line-height:1.5}
#toast{position:fixed; left:50%; top:calc(var(--bar-h) + 12px); transform:translateX(-50%);
max-width:min(460px, calc(100vw - 32px)); padding:12px 16px; border-radius:12px;
background:var(--solid); color:var(--ink2); box-shadow:inset 0 0 0 1px var(--line), var(--shadow);
font-size:14px; line-height:1.45; z-index:10}
/* fullscreen: only the device, on black */
#stage:fullscreen{padding:0; background:#000; align-items:center}
#stage:-webkit-full-screen{padding:0; background:#000; align-items:center}
#stage:fullscreen #frame, #stage:-webkit-full-screen #frame{box-shadow:none; border-radius:0}
.rotate-hint{display:none}
@media (max-width:560px){
:root{--bar-h:auto}
.wide{display:none}
#stage{align-items:flex-start; flex:0 0 auto}
.rotate-hint{display:block; margin:0 auto 10px; padding:0 var(--gutter); text-align:center; color:var(--mut); font-size:13px}
.bar{gap:8px}
.brand span{display:none}
.btn{height:34px; padding:0 12px; font-size:13px}
.btn.icon{width:34px}
#frame{border-radius:6px; box-shadow:0 0 0 1px var(--frame-edge), 0 0 0 4px var(--frame), 0 0 0 5px var(--frame-edge)}
}
@media (prefers-reduced-motion:reduce){ #overlay.busy #status::after{animation:none; content:"..."} }