/* The page is the terminal surface and nothing else. No chrome, no scrollbars of its own: the window, tabs and splits are Avalonia's job, and duplicating any of it here would mean two layout systems disagreeing about the same pixels. */ /* The three colours the page decides for itself, and they are the v2 design's rather than a second opinion about it. The background, #171a26, is `TerminalSurface` in Palette.axaml — the same surface a snippet's command block and the log view are drawn on. The muted grey is `TextDim`. The foreground is the one that is not a palette token: the design sets terminal text to #d8dcea, a step below the #E3E7F4 it uses for interface text, and that difference is deliberate on its part — a wall of monospace at full contrast is harder to read than the labels around it, not easier. The page cannot read an Avalonia resource in any case — it is a WebView served over a loopback socket, not part of the visual tree — so these are repeated here and in the theme object in terminal.js, and both sites say so. */ :root { --dodo-background: #171a26; --dodo-foreground: #d8dcea; --dodo-muted: #8b93b0; } * { box-sizing: border-box; } html, body { margin: 0; padding: 0; height: 100%; overflow: hidden; background: var(--dodo-background); color: var(--dodo-foreground); font-family: ui-monospace, "Cascadia Mono", "SF Mono", Menlo, Consolas, monospace; /* Touch rules, and they only ever matter on the phone — a desktop WebView has no gestures to give away. pan-y keeps the one gesture a terminal wants, dragging the scrollback, and refuses the two it must not have: pinch-zoom, and the double-tap zoom that would otherwise fire on every attempt to place the cursor. text-size-adjust stops Android's own font inflation. It resizes text it judges too small without telling the page, which in a terminal means characters that no longer match the cell grid the fit addon measured — the rows stop lining up and the columns are wrong by a character or two. */ touch-action: pan-y; -webkit-text-size-adjust: 100%; text-size-adjust: 100%; } #root { position: absolute; inset: 0; } /* Every session gets a pane, and all but the active one are hidden rather than destroyed. On a dropped connection the DOM and its scrollback must survive: rebuilding the terminal would discard everything the user was reading, which is the one thing they cannot get back. */ .pane { position: absolute; inset: 0; display: none; /* A little breathing room, and it keeps the WebGL canvas off the window edge. */ padding: 4px 2px 2px 6px; } .pane[data-active="true"] { display: block; } .pane > .xterm { height: 100%; } /* ── THE BLACK STRIP UNDER THE TERMINAL ─────────────────────────────────────────────────────────────── xterm.css paints its scrolling viewport #000 — literally black, and its own comment says why: on macOS the overlay scrollbar is only fully opaque over an opaque backdrop. Everywhere else that black is a surface nobody sees, because the rows cover it — except along the bottom, where they do not. The fit addon floors the row count, so whatever is left of the pane below the last whole row is viewport with nothing drawn on it: a full-width black bar under the terminal, up to one line tall, against this page's own #171a26. On Windows it is also where the classic scrollbar's bottom corner lands, which is the light square at its right-hand end. Repainting it in the page's own background is the whole fix. The remainder is still there — it is the cost of a grid that has to divide evenly — but it now reads as the terminal's own margin rather than as a strip of chrome that belongs to something else. */ .xterm .xterm-viewport { background-color: var(--dodo-background); /* And the scrollbar itself, which WebView2 draws in the classic Windows style: a 15-pixel light-grey channel with arrow buttons, down the right of a near-black terminal. Thin and in this page's own colours instead — kept rather than hidden, because the scrollback is real and a surface that scrolls with no sign that it does is worse than a quiet bar saying where you are. Both spellings. scrollbar-width/-color is the standard one and is what current WebView2 and WebKitGTK honour; ::-webkit-scrollbar is what older Chromium builds and WKWebView answer to. Neither is load-bearing on its own and the two do not conflict — whichever the host understands wins. */ scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--dodo-muted) 45%, transparent) transparent; } .xterm .xterm-viewport::-webkit-scrollbar { width: 9px; } .xterm .xterm-viewport::-webkit-scrollbar-track { background: transparent; } .xterm .xterm-viewport::-webkit-scrollbar-thumb { background: color-mix(in srgb, var(--dodo-muted) 45%, transparent); border-radius: 5px; } #status { position: absolute; left: 0; right: 0; bottom: 0; padding: 6px 10px; font-size: 12px; color: var(--dodo-muted); background: color-mix(in srgb, var(--dodo-background) 88%, white); border-top: 1px solid color-mix(in srgb, var(--dodo-background) 70%, white); } /* Once a session is running the banner is noise, so it only shows when it has something to say. */ #status:empty { display: none; }