Live-review iteration on the browser SPA, driven by crit feedback. Sidebar / session tree - Compact single-line leaf rows; status shown as a faint "alive" row wash instead of per-row dots (exited rows dim + keep the "exited" badge). - Host is now the first level of nesting (host → label path → session); the inline @daemon is dropped from rows. - Flush, borderless search input spanning the sidebar; drag-to-resize grip on the sidebar edge (width persisted to localStorage); narrower default. - Per-row clone action (opens the spawn modal prefilled); right-pointing chevron when collapsed. Chrome / layout - Buttons swapped to a bracket terminal style ([ + Spawn ]); ghost/icon drop the brackets. Old filled styles removed. - Squared corners globally (radius tokens) and tighter, denser spacing. - Session tally + daemon chips moved into the centered app header. - Shorter control height; shared --bar-h aligns the search and attach bars. Attach / terminal - Useful attach title (name · command @ host) over a bare UUID. - Robust fit: compute columns from the viewport's scrollbar-excluded clientWidth (fixes mobile under-fit and desktop overflow); ResizeObserver + font-load refit; full-bleed terminal on mobile. Spawn / empty states - Spawn modal accepts a prefill (clone); real "+ Spawn" buttons in welcome and no-sessions empty states. Dev - New ?kit design-kit page (kit.ts/kit.css, DEV-only) showcasing components. - Richer ?mock fixture with deeper label nesting. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+286
-120
@@ -31,16 +31,22 @@
|
||||
--sp-6: 24px;
|
||||
--sp-8: 32px;
|
||||
|
||||
/* ---- radii ---- */
|
||||
--r-1: 6px;
|
||||
--r-2: 9px;
|
||||
--r-3: 14px;
|
||||
--r-pill: 999px;
|
||||
/* ---- radii ----
|
||||
Terminal-native: crisp, near-square corners. Round dots (status, brand)
|
||||
use border-radius:50% directly and are unaffected; these tokens govern
|
||||
rectangles (buttons, inputs, cards, tags) and stay sharp on purpose. */
|
||||
--r-1: 2px;
|
||||
--r-2: 3px;
|
||||
--r-3: 4px;
|
||||
--r-pill: 3px;
|
||||
|
||||
/* ---- sizing ---- */
|
||||
--row-h: 46px;
|
||||
--control-h: 38px;
|
||||
--control-h: 30px;
|
||||
--tap: 40px;
|
||||
/* Height of the two top-of-pane bars (sidebar search + attach header) — shared
|
||||
so they line up across the split. */
|
||||
--bar-h: 34px;
|
||||
|
||||
/* ---- motion ---- */
|
||||
--ease-out: cubic-bezier(0.22, 1, 0.36, 1);
|
||||
@@ -248,18 +254,18 @@ textarea {
|
||||
border-radius: var(--r-1);
|
||||
}
|
||||
|
||||
/* ---------- buttons ---------- */
|
||||
/* ---------- buttons ----------
|
||||
Terminal-native: the brackets are the chrome. Default + primary wear
|
||||
[ brackets ]; ghost/icon drop them for quieter nav and single glyphs. */
|
||||
|
||||
.btn {
|
||||
--_bg: var(--surface-2);
|
||||
appearance: none;
|
||||
border: 1px solid var(--border);
|
||||
background: var(--_bg);
|
||||
border: 1px solid transparent;
|
||||
background: transparent;
|
||||
color: var(--ink);
|
||||
padding: 0 var(--sp-4);
|
||||
padding: 0 var(--sp-1);
|
||||
height: var(--control-h);
|
||||
min-height: var(--control-h);
|
||||
border-radius: var(--r-2);
|
||||
cursor: pointer;
|
||||
font-family: var(--font-mono);
|
||||
font-size: var(--fs-13);
|
||||
@@ -268,17 +274,31 @@ textarea {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: var(--sp-2);
|
||||
gap: 4px;
|
||||
white-space: nowrap;
|
||||
transition:
|
||||
color var(--dur-fast) var(--ease-out),
|
||||
background var(--dur-fast) var(--ease-out),
|
||||
border-color var(--dur-fast) var(--ease-out),
|
||||
transform var(--dur-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
.btn::before {
|
||||
content: "[";
|
||||
color: var(--faint);
|
||||
}
|
||||
|
||||
.btn::after {
|
||||
content: "]";
|
||||
color: var(--faint);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background: var(--surface-3);
|
||||
border-color: var(--border-strong);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.btn:hover::before,
|
||||
.btn:hover::after {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.btn:active {
|
||||
@@ -292,25 +312,32 @@ textarea {
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
--_bg: var(--accent);
|
||||
border-color: transparent;
|
||||
color: var(--accent-ink);
|
||||
color: var(--accent);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--accent-strong);
|
||||
border-color: transparent;
|
||||
.btn-primary::before,
|
||||
.btn-primary::after {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background: var(--accent-tint);
|
||||
}
|
||||
|
||||
/* Ghost: no brackets — quiet nav (back, disconnect, theme, kit) and icons. */
|
||||
.btn-ghost {
|
||||
--_bg: transparent;
|
||||
border-color: transparent;
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.btn-ghost::before,
|
||||
.btn-ghost::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.btn-ghost:hover {
|
||||
color: var(--ink);
|
||||
background: var(--surface-2);
|
||||
border-color: var(--border);
|
||||
}
|
||||
|
||||
.btn-icon {
|
||||
@@ -319,6 +346,15 @@ textarea {
|
||||
font-size: var(--fs-15);
|
||||
}
|
||||
|
||||
.btn-icon::before,
|
||||
.btn-icon::after {
|
||||
content: none;
|
||||
}
|
||||
|
||||
.btn-icon:hover {
|
||||
background: var(--surface-2);
|
||||
}
|
||||
|
||||
/* ---------- app shell: sidebar + content ---------- */
|
||||
|
||||
/* Global app header: brand + app-level actions (spawn, theme toggle), spanning
|
||||
@@ -328,17 +364,45 @@ textarea {
|
||||
align-items: center;
|
||||
gap: var(--sp-3);
|
||||
flex: 0 0 auto;
|
||||
padding: var(--sp-3) var(--sp-4);
|
||||
padding: var(--sp-1) var(--sp-3);
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: color-mix(in oklab, var(--surface) 82%, transparent);
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
/* Three-part header: brand (left), status (centered), actions (right). Equal
|
||||
flex on the outer two keeps the status group truly centered. */
|
||||
.app-header .brand {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.app-status {
|
||||
flex: 0 1 auto;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.app-status .statusbar {
|
||||
border-bottom: 0;
|
||||
background: transparent;
|
||||
padding: 0;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
|
||||
.app-status .statusbar .spacer {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.app-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-2);
|
||||
margin-left: auto;
|
||||
flex: 1 1 0;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.app-shell {
|
||||
@@ -351,7 +415,8 @@ textarea {
|
||||
@media (min-width: 860px) {
|
||||
.app-shell {
|
||||
display: grid;
|
||||
grid-template-columns: clamp(280px, 26vw, 360px) minmax(0, 1fr);
|
||||
grid-template-columns:
|
||||
var(--sidebar-w, clamp(220px, 22vw, 320px)) minmax(0, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,21 +426,64 @@ textarea {
|
||||
min-height: 0;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
background: color-mix(in oklab, var(--surface) 26%, var(--bg));
|
||||
border-right: 1px solid var(--border);
|
||||
}
|
||||
|
||||
/* Drag-to-resize grip on the sidebar's right edge (desktop split only). */
|
||||
.sidebar-resize {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -3px;
|
||||
width: 6px;
|
||||
height: 100%;
|
||||
cursor: col-resize;
|
||||
z-index: var(--z-sticky);
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.sidebar-resize:hover,
|
||||
.sidebar-resize:active {
|
||||
background: var(--accent-ring);
|
||||
}
|
||||
|
||||
@media (max-width: 859px) {
|
||||
.sidebar-resize {
|
||||
display: none;
|
||||
}
|
||||
.app-status {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Sidebar's own slim header: just the session search (app-level actions live
|
||||
in the global top bar). */
|
||||
/* The search input IS the header — it spans edge to edge, flush, with just a
|
||||
bottom rule for separation. No wrapper padding, no boxed border/radius. */
|
||||
.sidebar-search {
|
||||
flex: 0 0 auto;
|
||||
padding: var(--sp-3) var(--sp-4);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.sidebar-search .search {
|
||||
width: 100%;
|
||||
max-width: none;
|
||||
height: var(--bar-h);
|
||||
border: 0;
|
||||
border-bottom: 1px solid var(--border);
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.sidebar-search .search:hover {
|
||||
background: var(--surface-2);
|
||||
border-bottom-color: var(--border-strong);
|
||||
}
|
||||
|
||||
.sidebar-search .search:focus {
|
||||
background: var(--surface-2);
|
||||
border-bottom-color: var(--accent);
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.content {
|
||||
@@ -419,7 +527,7 @@ textarea {
|
||||
flex-wrap: wrap;
|
||||
align-items: center;
|
||||
gap: var(--sp-3);
|
||||
padding: var(--sp-3) var(--sp-4);
|
||||
padding: var(--sp-2) var(--sp-3);
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: color-mix(in oklab, var(--surface) 82%, transparent);
|
||||
backdrop-filter: blur(8px);
|
||||
@@ -497,7 +605,7 @@ textarea {
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--sp-2) var(--sp-3);
|
||||
padding: var(--sp-2) var(--sp-4);
|
||||
padding: var(--sp-2) var(--sp-3);
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
font-size: var(--fs-12);
|
||||
@@ -588,7 +696,7 @@ textarea {
|
||||
.tree {
|
||||
flex: 1 1 auto;
|
||||
overflow: auto;
|
||||
padding: var(--sp-2) 0 var(--sp-8);
|
||||
padding: var(--sp-1) 0 var(--sp-4);
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--border-strong) transparent;
|
||||
}
|
||||
@@ -659,112 +767,85 @@ textarea {
|
||||
.tree-leaf {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-3);
|
||||
min-height: var(--row-h);
|
||||
padding: var(--sp-2) var(--sp-4) var(--sp-2) var(--sp-3);
|
||||
border-left: 2px solid transparent;
|
||||
gap: var(--sp-2);
|
||||
min-height: 30px;
|
||||
margin: 1px var(--sp-2);
|
||||
padding: 4px var(--sp-3);
|
||||
border-radius: var(--r-1);
|
||||
color: var(--ink);
|
||||
position: relative;
|
||||
transition: background var(--dur-fast) var(--ease-out);
|
||||
transition:
|
||||
background var(--dur-fast) var(--ease-out),
|
||||
box-shadow var(--dur-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
.tree-leaf::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: var(--sp-4);
|
||||
right: var(--sp-4);
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
background: var(--border);
|
||||
opacity: 0.5;
|
||||
/* "Alive" reads as a faint wash on the row itself — no per-row status icon. */
|
||||
.tree-leaf[data-status="running"] {
|
||||
background: color-mix(in oklab, var(--accent) 6%, transparent);
|
||||
}
|
||||
|
||||
.tree-leaf:hover {
|
||||
background: var(--surface);
|
||||
background: var(--surface-2);
|
||||
}
|
||||
|
||||
.tree-leaf[data-status="running"]:hover {
|
||||
background: color-mix(in oklab, var(--accent) 13%, var(--surface-2));
|
||||
}
|
||||
|
||||
.tree-leaf:focus-visible {
|
||||
outline: none;
|
||||
background: var(--surface);
|
||||
border-left-color: var(--accent);
|
||||
box-shadow: inset 0 0 0 1px var(--accent-ring);
|
||||
}
|
||||
|
||||
/* The session currently mounted in the content pane. */
|
||||
.tree-leaf.is-active {
|
||||
.tree-leaf.is-active,
|
||||
.tree-leaf.is-active[data-status="running"] {
|
||||
background: var(--accent-tint);
|
||||
border-left-color: var(--accent);
|
||||
box-shadow: inset 0 0 0 1px var(--accent-ring);
|
||||
}
|
||||
|
||||
.tree-leaf.is-active .leaf-name {
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.tree-leaf.is-active::after {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* Exited sessions recede: dimmed name + an "exited" badge carry status, so it's
|
||||
never the running tint's absence alone doing the work. */
|
||||
.tree-leaf[data-status="dead"] {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.leaf-status {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
flex: 0 0 10px;
|
||||
border-radius: 50%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
[data-status="running"] .leaf-status {
|
||||
background: var(--live);
|
||||
box-shadow: 0 0 0 3px var(--live-glow);
|
||||
}
|
||||
|
||||
[data-status="running"] .leaf-status::before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: -3px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid var(--live);
|
||||
opacity: 0.6;
|
||||
animation: ripple 2.4s var(--ease-out) infinite;
|
||||
}
|
||||
|
||||
[data-status="dead"] .leaf-status {
|
||||
background: transparent;
|
||||
border: 1.5px solid var(--faint);
|
||||
}
|
||||
|
||||
.leaf-main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
gap: 1px;
|
||||
.tree-leaf[data-status="dead"] .leaf-name {
|
||||
color: var(--muted);
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
.leaf-name {
|
||||
font-weight: 500;
|
||||
font-size: var(--fs-14);
|
||||
font-size: var(--fs-13);
|
||||
flex: 0 1 auto;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.leaf-meta {
|
||||
font-size: var(--fs-12);
|
||||
font-size: var(--fs-11);
|
||||
color: var(--muted);
|
||||
margin-left: auto;
|
||||
padding-left: var(--sp-2);
|
||||
min-width: 0;
|
||||
flex: 0 1 auto;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
display: inline-flex;
|
||||
align-items: baseline;
|
||||
gap: var(--sp-2);
|
||||
}
|
||||
|
||||
.leaf-daemon {
|
||||
color: var(--faint);
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.leaf-daemon::before {
|
||||
@@ -774,6 +855,9 @@ textarea {
|
||||
|
||||
.leaf-cmd {
|
||||
color: var(--muted);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.leaf-badge {
|
||||
@@ -787,36 +871,50 @@ textarea {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
.leaf-kill {
|
||||
background: transparent;
|
||||
.leaf-actions {
|
||||
position: absolute;
|
||||
right: var(--sp-1);
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: inline-flex;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.leaf-act {
|
||||
background: var(--surface-3);
|
||||
color: var(--faint);
|
||||
border: 1px solid transparent;
|
||||
border-radius: var(--r-2);
|
||||
width: var(--tap);
|
||||
height: var(--tap);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--r-1);
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
cursor: pointer;
|
||||
flex: 0 0 var(--tap);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: var(--fs-14);
|
||||
font-size: var(--fs-12);
|
||||
transition:
|
||||
color var(--dur-fast) var(--ease-out),
|
||||
background var(--dur-fast) var(--ease-out),
|
||||
border-color var(--dur-fast) var(--ease-out),
|
||||
opacity var(--dur-fast) var(--ease-out);
|
||||
border-color var(--dur-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
@media (hover: hover) {
|
||||
.leaf-kill {
|
||||
.leaf-actions {
|
||||
opacity: 0;
|
||||
transition: opacity var(--dur-fast) var(--ease-out);
|
||||
}
|
||||
.tree-leaf:hover .leaf-kill,
|
||||
.tree-leaf:focus-within .leaf-kill {
|
||||
.tree-leaf:hover .leaf-actions,
|
||||
.tree-leaf:focus-within .leaf-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.leaf-clone:hover {
|
||||
color: var(--accent);
|
||||
background: var(--accent-tint);
|
||||
border-color: color-mix(in oklab, var(--accent) 40%, transparent);
|
||||
}
|
||||
|
||||
.leaf-kill:hover {
|
||||
color: var(--danger);
|
||||
background: var(--danger-tint);
|
||||
@@ -826,7 +924,7 @@ textarea {
|
||||
/* ---------- empty / loading ---------- */
|
||||
|
||||
.empty {
|
||||
padding: var(--sp-8) var(--sp-4);
|
||||
padding: var(--sp-5) var(--sp-4);
|
||||
color: var(--muted);
|
||||
text-align: center;
|
||||
display: flex;
|
||||
@@ -871,6 +969,12 @@ textarea {
|
||||
color: var(--ink);
|
||||
}
|
||||
|
||||
.empty-actions {
|
||||
display: flex;
|
||||
gap: var(--sp-2);
|
||||
margin-top: var(--sp-2);
|
||||
}
|
||||
|
||||
.empty.connecting .empty-glyph {
|
||||
color: var(--warn);
|
||||
animation: pulse 1.6s var(--ease-out) infinite;
|
||||
@@ -888,16 +992,27 @@ textarea {
|
||||
.attach-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-3);
|
||||
padding: var(--sp-2) var(--sp-3);
|
||||
gap: var(--sp-2);
|
||||
height: var(--bar-h);
|
||||
padding: 0 var(--sp-2);
|
||||
border-bottom: 1px solid var(--border);
|
||||
background: var(--surface);
|
||||
}
|
||||
|
||||
/* Compact controls so the bar hugs the title — no tall buttons. */
|
||||
.attach-header .btn {
|
||||
height: 26px;
|
||||
min-height: 26px;
|
||||
}
|
||||
|
||||
.attach-header .btn-icon {
|
||||
width: 26px;
|
||||
}
|
||||
|
||||
.attach-header .back {
|
||||
font-size: var(--fs-17);
|
||||
width: var(--tap);
|
||||
height: var(--control-h);
|
||||
font-size: var(--fs-15);
|
||||
width: 28px;
|
||||
height: 26px;
|
||||
}
|
||||
|
||||
/* Desktop keeps the session list permanently in view, so the in-header "back"
|
||||
@@ -932,12 +1047,37 @@ textarea {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.attach-title .at-name {
|
||||
color: var(--ink);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.attach-title .at-cmd {
|
||||
color: var(--muted);
|
||||
}
|
||||
|
||||
.attach-title .at-cmd::before {
|
||||
content: "·";
|
||||
margin: 0 6px;
|
||||
color: var(--faint);
|
||||
}
|
||||
|
||||
.attach-title .at-host {
|
||||
color: var(--faint);
|
||||
margin-left: 6px;
|
||||
}
|
||||
|
||||
.attach-title .at-host::before {
|
||||
content: "@";
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.attach-state {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
font-size: var(--fs-12);
|
||||
padding: 4px 10px;
|
||||
padding: 2px var(--sp-2);
|
||||
border-radius: var(--r-pill);
|
||||
background: var(--surface-2);
|
||||
color: var(--muted);
|
||||
@@ -979,6 +1119,7 @@ textarea {
|
||||
min-height: 0;
|
||||
padding: var(--sp-2);
|
||||
display: flex;
|
||||
overflow: hidden;
|
||||
background: var(--term-bg);
|
||||
}
|
||||
|
||||
@@ -987,9 +1128,34 @@ textarea {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
/* xterm hard-codes overflow-y: scroll on its viewport — an always-on bar that
|
||||
(a) shows even with no scrollback and (b) makes FitAddon subtract its width,
|
||||
costing a column. Hide it entirely: scroll still works via wheel/touch/keys,
|
||||
and fit reclaims the full width. */
|
||||
/* Higher specificity than xterm's own `.xterm .xterm-viewport` (which loads
|
||||
after this and would otherwise win the tie) so the always-on scrollbar
|
||||
reservation actually goes away. */
|
||||
.attach-body .xterm .xterm-viewport {
|
||||
overflow-y: auto;
|
||||
scrollbar-width: none;
|
||||
}
|
||||
|
||||
.attach-body .xterm .xterm-viewport::-webkit-scrollbar {
|
||||
width: 0;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Mobile: full-bleed terminal — the desktop frame padding wastes space and the
|
||||
sub-cell remainder it left was triggering a stray scrollbar. */
|
||||
@media (max-width: 859px) {
|
||||
.attach-body {
|
||||
padding: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.attach-status {
|
||||
margin: var(--sp-4);
|
||||
padding: var(--sp-3) var(--sp-4);
|
||||
padding: var(--sp-2) var(--sp-3);
|
||||
border-radius: var(--r-2);
|
||||
background: var(--surface);
|
||||
border: 1px solid var(--border);
|
||||
@@ -1048,7 +1214,7 @@ textarea {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: var(--sp-4);
|
||||
padding: var(--sp-3);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
@@ -1068,11 +1234,11 @@ textarea {
|
||||
}
|
||||
|
||||
.modal-body {
|
||||
padding: var(--sp-4);
|
||||
padding: var(--sp-3);
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-3);
|
||||
gap: var(--sp-2);
|
||||
scrollbar-width: thin;
|
||||
scrollbar-color: var(--border-strong) transparent;
|
||||
}
|
||||
@@ -1220,7 +1386,7 @@ textarea {
|
||||
|
||||
.not-found {
|
||||
margin: auto;
|
||||
padding: var(--sp-8) var(--sp-4);
|
||||
padding: var(--sp-5) var(--sp-4);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-3);
|
||||
@@ -1366,7 +1532,7 @@ textarea {
|
||||
flex: 1 1 100%;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.tree-leaf .leaf-kill {
|
||||
.tree-leaf .leaf-actions {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user