Files
muxplex/muxplex/frontend/style.css
T

2529 lines
51 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/* Design tokens, dark base theme, typography */
:root {
/* Background palette */
--bg: #0D1117; /* --color-bg-base */
--bg-secondary: #10131C; /* --color-bg-elevated */
--bg-tile: #10131C; /* --color-bg-elevated */
--bg-header: #0D1117; /* --color-bg-base (header matches page) */
--bg-overlay: rgba(13, 17, 23, 0.85); /* brand base with opacity */
--bg-tile-hover: #1A1F2B; /* --color-bg-surface */
--bg-surface: #1A1F2B;
/* Text palette */
--text: #F0F6FF; /* --color-text-primary */
--text-dim: #4A5060; /* --color-text-disabled */
--text-muted: #8E95A3; /* --color-text-secondary */
/* Borders */
--border: #2A3040; /* --color-border-default */
--border-subtle: #1E2430; /* --color-border-subtle */
/* Accent */
--accent: #00D9F5; /* brand cyan */
--accent-hover: #00b8d1; /* slightly darker cyan for hover */
--accent-dim: rgba(0, 217, 245, 0.15);
/* Bell / notification */
--bell: #F1A640;
--bell-color: #F1A640; /* brand amber */
--activity-color: #F1A640;
--bell-glow: rgba(241, 166, 64, 0.25);
--bell-border: rgba(241, 166, 64, 0.6);
/* Status */
--ok: #3fb950;
--warn: #d29922;
--err: #f85149;
/* Layout */
--tile-height: 300px;
--tile-min-width: 360px;
--grid-gap: 8px;
--grid-padding: 16px;
--header-height: 44px;
/* Transitions */
--t-zoom: 250ms ease-in-out;
--t-fast: 150ms ease;
--t-fade: 200ms ease;
/* Typography */
--font-ui: system-ui, -apple-system, 'Segoe UI', sans-serif;
--font-mono: 'SF Mono', 'Fira Code', 'Consolas', 'Menlo', monospace;
}
/* Box-sizing reset */
*,
*::before,
*::after {
box-sizing: border-box;
}
/* ============================================================
Custom scrollbar — thin, dark, matches theme
============================================================ */
/* Firefox */
* {
scrollbar-width: thin;
scrollbar-color: rgba(48, 54, 61, 0.6) transparent;
}
/* WebKit (Chrome, Edge, Safari) */
*::-webkit-scrollbar {
width: 6px;
height: 6px;
}
*::-webkit-scrollbar-track {
background: transparent;
}
*::-webkit-scrollbar-thumb {
background: rgba(48, 54, 61, 0.6);
border-radius: 3px;
}
*::-webkit-scrollbar-thumb:hover {
background: rgba(0, 200, 200, 0.35); /* --accent at 35% */
}
*::-webkit-scrollbar-thumb:active {
background: rgba(0, 200, 200, 0.55); /* --accent at 55% */
}
*::-webkit-scrollbar-corner {
background: transparent;
}
/* Base */
html,
body {
height: 100%;
background: var(--bg);
color: var(--text);
font-family: var(--font-ui);
font-size: 14px;
overflow: hidden;
margin: 0;
padding: 0;
}
/* Utility */
.hidden {
display: none !important;
}
/* ============================================================
App layout
============================================================ */
.view {
height: 100vh; /* fallback for browsers without dvh support */
height: 100dvh; /* dynamic viewport height — adjusts for mobile browser chrome */
overflow: hidden;
}
.view--active {
display: flex;
flex-direction: column;
}
.view.hidden {
display: none;
}
/* ============================================================
App header
============================================================ */
.app-header {
height: var(--header-height);
padding: 0 var(--grid-padding);
background: var(--bg-header);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
}
/* ============================================================
Session grid
============================================================ */
.session-grid {
flex: 1;
overflow-y: auto;
padding: var(--grid-padding);
display: grid;
grid-template-columns: repeat(auto-fill, minmax(var(--tile-min-width), 1fr));
gap: var(--grid-gap);
align-content: start;
}
/* ============================================================
Session tile
============================================================ */
.session-tile {
height: var(--tile-height);
background: var(--bg-tile);
border: 1px solid var(--border);
border-left: 3px solid var(--border); /* edge bar — always present, matches other 3 borders */
border-radius: 4px;
display: flex;
flex-direction: column;
cursor: pointer;
overflow: hidden;
position: relative;
transition: border-color var(--t-fast), border-left-color var(--t-fast), box-shadow var(--t-fast);
}
.session-tile:hover,
.session-tile:focus-visible {
border-color: var(--accent);
}
/* Bell / notification tile */
.session-tile--bell {
border-color: var(--bell-border);
box-shadow: 0 0 0 1px var(--bell-border), inset 0 0 12px var(--bell-glow);
}
/* Edge-bar only (dot mode): amber left border, no glow */
.session-tile--edge-bell {
border-left-color: var(--bell);
}
/* ============================================================
Tile header
============================================================ */
.tile-header {
height: 32px;
padding: 0 10px;
background: var(--bg-header);
border-bottom: 1px solid var(--border-subtle);
display: flex;
align-items: center;
}
.tile-name {
font-size: 13px;
font-weight: 500;
color: var(--text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
}
.tile-meta {
font-size: 11px;
color: var(--text-muted);
white-space: nowrap;
margin-left: 8px;
transition: opacity 150ms ease; /* × crossfade with badge + timestamp on hover */
}
.tile-meta-sep {
margin: 0 2px;
}
.session-tile:hover .tile-meta,
.session-tile:focus-within .tile-meta {
opacity: 0;
}
/* Bell notification badge */
.tile-bell {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 16px;
height: 16px;
padding: 0 3px;
border-radius: 8px;
background: var(--bell);
color: #0D1117;
font-size: 9px;
font-weight: 700;
line-height: 1;
flex-shrink: 0;
margin-right: 6px;
animation: bell-pulse 1.4s ease-in-out infinite;
}
/* Bell count number inside the badge */
.tile-bell-count {
font-size: 9px;
font-weight: 700;
line-height: 1;
color: inherit;
}
@keyframes bell-pulse {
0%, 100% {
opacity: 1;
transform: scale(1);
}
50% {
opacity: 0.5;
transform: scale(0.8);
}
}
/* ============================================================
Tile body
============================================================ */
.tile-body {
flex: 1;
overflow: hidden;
position: relative;
background: #000000;
}
.tile-body pre {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 6px 8px;
font-family: 'SF Mono', 'Fira Code', Consolas, monospace;
font-size: 11px;
line-height: 1.0;
color: #c9d1d9; /* match xterm.js foreground */
white-space: pre;
overflow: hidden;
margin: 0;
}
/* Loading placeholder tile — shown while a new session is being created */
.tile--loading {
opacity: 0.6;
pointer-events: none;
}
.tile--loading .tile-body pre {
background: repeating-linear-gradient(
90deg,
var(--border) 0px,
var(--bg-surface) 30px,
var(--border) 60px
);
background-size: 200% 100%;
animation: shimmer 1.5s ease-in-out infinite;
min-height: 60px;
border-radius: 2px;
}
@keyframes shimmer {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.tile-pre {
position: absolute;
inset: 0;
padding: 6px 8px;
font-family: var(--font-mono);
font-size: 11px;
color: var(--text-dim);
white-space: pre;
overflow: hidden;
margin: 0;
}
/* ============================================================
Empty state
============================================================ */
.empty-state {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-dim);
}
/* ============================================================
Responsive breakpoints
============================================================ */
@media (max-width:1199px) and (min-width:900px) {
:root {
--tile-min-width:420px;
}
}
@media (max-width:899px) and (min-width:600px) {
.session-grid {
grid-template-columns:1fr;
padding:8px;
}
.session-tile {
height:200px;
}
}
@media (max-width:599px) {
.session-grid {
display:flex;
flex-direction:column;
gap:1px;
padding:0;
}
.session-tile {
height:auto;
border-radius:0;
border-left:none;
border-right:none;
}
}
@media (max-width:599px) and (orientation:landscape) {
.session-grid {
padding:0;
}
}
/* ============================================================
Expanded view
============================================================ */
#view-expanded {
position: relative;
}
.expanded-header {
height: var(--header-height);
padding: 0 12px;
background: var(--bg-header);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
gap: 12px;
flex-shrink: 0;
}
.back-btn {
background: none;
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text-muted);
font-size: 18px;
width: 36px;
height: 36px;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
}
.back-btn:hover {
border-color: var(--accent);
color: var(--text);
}
.expanded-session-name {
flex: 1;
font-size: 14px;
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.view-body {
display: flex;
flex-direction: row;
flex: 1;
min-height: 0;
overflow: hidden;
}
/* ============================================================
Session sidebar
============================================================ */
.session-sidebar {
width: 200px;
min-width: 200px;
background: var(--bg-secondary);
border-right: 1px solid var(--border-subtle);
display: flex;
flex-direction: column;
overflow: hidden;
flex-shrink: 0;
transition: width 0.25s ease, min-width 0.25s ease;
}
.session-sidebar.sidebar--collapsed {
width: 0;
min-width: 0;
}
.sidebar-header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
border-bottom: 1px solid var(--border-subtle);
flex-shrink: 0;
}
.sidebar-title {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
}
/* Sidebar view switcher dropdown */
.sidebar-view-dropdown {
position: relative;
flex: 1;
min-width: 0;
}
.sidebar-view-trigger {
display: flex;
align-items: center;
gap: 4px;
background: transparent;
border: none;
color: var(--text-muted);
font-size: 13px;
font-family: var(--font-ui);
cursor: pointer;
padding: 2px 4px;
border-radius: 4px;
max-width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.sidebar-view-trigger:hover {
color: var(--accent);
}
#sidebar-view-dropdown-menu {
position: fixed;
min-width: 180px;
}
.sidebar-list {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding: 8px;
display: flex;
flex-direction: column;
gap: 6px;
touch-action: pan-y; /* tell browser vertical panning is allowed on mobile */
overscroll-behavior: contain; /* prevent scroll chaining to non-scrollable parent */
}
.sidebar-collapse-btn {
background: none;
border: none;
color: var(--text-muted);
cursor: pointer;
font-size: 18px;
padding: 2px 6px;
border-radius: 4px;
}
.sidebar-collapse-btn:hover {
color: var(--text);
}
.sidebar-toggle-btn {
background: none;
border: 1px solid var(--border);
border-radius: 4px;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
margin-right: 8px;
cursor: pointer;
color: var(--text-muted);
}
.sidebar-toggle-btn:hover {
border-color: var(--accent);
}
/* ============================================================
Sidebar session card styles
============================================================ */
.sidebar-item {
height: 120px;
flex-shrink: 0; /* prevent flex from compressing cards to fit */
background: var(--bg-secondary);
cursor: pointer;
overflow: hidden;
display: flex;
flex-direction: column;
position: relative;
border: 1px solid var(--border);
border-left: 3px solid var(--border); /* edge bar — always present, matches other 3 borders */
border-radius: 4px;
transition: border-color var(--t-fast), border-left-color var(--t-fast), box-shadow var(--t-fast);
}
.sidebar-item:hover,
.sidebar-item:focus-visible {
border-color: var(--accent);
}
.sidebar-item--active {
background: var(--bg-surface);
border-color: var(--accent);
border-left: 3px solid var(--accent);
}
/* Bell / activity glow — matches .session-tile--bell */
.sidebar-item--bell {
border-color: var(--bell-border);
box-shadow: 0 0 0 1px var(--bell-border), inset 0 0 12px var(--bell-glow);
}
/* Edge-bar only (dot mode): amber left border, no glow */
.sidebar-item--edge-bell {
border-left-color: var(--bell);
}
.sidebar-item-header {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 8px 8px 4px;
height: 32px;
gap: 4px;
align-items: center;
flex-shrink: 0;
}
.sidebar-item-name {
font-size: 12px;
font-weight: 600;
color: var(--text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
flex: 1;
min-width: 0;
}
.sidebar-item-body {
flex: 1;
position: relative;
overflow: hidden;
background: #000000;
}
.sidebar-item-body pre {
position: absolute;
bottom: 0;
left: 0;
right: 0;
font-family: 'SF Mono', 'Fira Code', Consolas, monospace;
font-size: 10px;
line-height: 1.0;
color: #c9d1d9; /* match xterm.js foreground */
white-space: pre;
padding: 0 8px 6px;
margin: 0;
}
.sidebar-item-header .device-badge {
margin-left: auto;
margin-right: 4px;
flex-shrink: 0;
}
.sidebar-empty {
padding: 16px 12px;
color: var(--text-muted);
font-size: 12px;
text-align: center;
}
.terminal-wrapper {
flex: 1;
min-width: 0;
overflow: hidden;
display: flex;
flex-direction: column;
}
.terminal-container {
flex: 1;
min-width: 0;
overflow: hidden;
background: #000;
padding: 0 4px; /* keep text off the side edges */
}
/* Terminal search bar */
.terminal-search-bar {
display: flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
background: var(--bg-surface);
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.terminal-search-bar.hidden {
display: none;
}
.terminal-search-input {
flex: 1;
background: var(--bg);
color: var(--text);
border: 1px solid var(--border);
border-radius: 4px;
padding: 4px 8px;
font-family: var(--font-ui);
font-size: 13px;
outline: none;
}
.terminal-search-input:focus {
border-color: var(--accent);
}
.terminal-search-count {
color: var(--text-muted);
font-size: 12px;
min-width: 40px;
text-align: center;
}
.terminal-search-btn {
background: none;
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text-muted);
cursor: pointer;
padding: 2px 8px;
font-size: 12px;
}
.terminal-search-btn:hover {
color: var(--text);
border-color: var(--accent);
}
/* xterm.js injects overflow-y: scroll on .xterm-viewport — override it */
.xterm .xterm-viewport {
overflow-y: hidden !important;
}
.reconnect-overlay {
position: absolute;
inset: var(--header-height) 0 0;
background: var(--bg-overlay);
display: flex;
align-items: center;
justify-content: center;
z-index: 10;
}
/* ============================================================
Zoom-in-place expand/collapse transition
============================================================ */
.session-tile--expanding {
position: fixed;
z-index: 50;
border-radius: 4px;
transition:
top var(--t-zoom),
left var(--t-zoom),
width var(--t-zoom),
height var(--t-zoom),
border-radius var(--t-zoom);
}
.session-tile--expanded {
top: 0 !important;
left: 0 !important;
width: 100vw !important;
height: 100vh !important; /* fallback for browsers without dvh support */
height: 100dvh !important; /* dynamic viewport height — adjusts for mobile browser chrome */
border-radius: 0;
}
.session-grid--dimming .session-tile:not(.session-tile--expanding) {
opacity: 0;
transition: opacity var(--t-fade);
}
/* Activity dot removed — edge bar (border-left-color) is now the state indicator.
.tile-bell-dot and .sidebar-bell-dot have been replaced by:
.session-tile--edge-bell { border-left-color: var(--bell); }
.sidebar-item--edge-bell { border-left-color: var(--bell); }
*/
/* ============================================================
Connection status indicator states
============================================================ */
.connection-status--ok {
color: var(--ok);
}
.connection-status--warn {
color: var(--warn);
}
.connection-status--err {
color: var(--err);
}
/* ============================================================
Toast notification
============================================================ */
.toast {
position: fixed;
bottom: 80px;
left: 50%;
transform: translateX(-50%);
background: var(--bg-header);
border: 1px solid var(--border);
border-radius: 4px;
padding: 8px 16px;
font-size: 13px;
color: var(--text-muted);
z-index: 100;
pointer-events: none;
animation: toast-in var(--t-fast) ease;
}
@keyframes toast-in {
from {
opacity: 0;
transform: translateX(-50%) translateY(8px);
}
to {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
}
/* ============================================================
Mobile three-tier priority list (bell / active / idle)
============================================================ */
@media (max-width:599px) {
/* Tier 1 — bell: expanded preview (~126px total) */
.session-tile--tier-bell .tile-body {
height: 90px;
}
.session-tile--tier-bell {
min-height: 126px;
}
/* Tier 2 — active: single-line preview (~60px total) */
.session-tile--tier-active .tile-body {
height: 24px;
}
.session-tile--tier-active {
min-height: 60px;
}
.session-tile--tier-active .tile-body pre {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
/* Tier 3 — idle: compact preview (36px body) */
.session-tile--tier-idle .tile-body {
height: 36px;
}
.session-tile--tier-idle {
min-height: 44px;
}
.session-tile--tier-idle .tile-header {
height: 44px;
}
.session-tile--tier-idle .tile-name {
color: var(--text-dim);
}
}
/* ─── Mobile Bottom Sheet ─────────────────────────────────────── */
.bottom-sheet {
position: fixed;
inset: 0;
z-index: 200;
display: flex;
align-items: flex-end;
}
.bottom-sheet__backdrop {
position: absolute;
inset: 0;
background: var(--bg-overlay);
}
.bottom-sheet__panel {
position: relative;
width: 100%;
background: var(--bg-header);
border-top: 1px solid var(--border);
border-radius: 12px 12px 0 0;
max-height: 70vh;
overflow-y: auto;
animation: sheet-up var(--t-zoom) ease;
}
@keyframes sheet-up {
from { transform: translateY(100%); }
to { transform: translateY(0); }
}
.bottom-sheet__handle {
width: 36px;
height: 4px;
background: var(--border);
border-radius: 2px;
margin: 10px auto 6px;
}
.bottom-sheet__list {
list-style: none;
padding-bottom: 8px;
}
.sheet-item {
display: flex;
align-items: center;
gap: 10px;
padding: 0 16px;
height: 56px;
cursor: pointer;
font-size: 14px;
color: var(--text);
border-bottom: 1px solid var(--border-subtle);
transition: background var(--t-fast);
}
.sheet-item:hover {
background: var(--accent-dim);
}
.sheet-item__name {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.sheet-item__bell {
color: var(--bell);
}
.sheet-item__time {
font-size: 12px;
color: var(--text-dim);
}
/* ─── Floating Session Pill ───────────────────────────────────── */
.session-pill {
position: fixed;
bottom: 24px;
right: 16px;
z-index: 50;
background: var(--bg-header);
border: 1px solid var(--border);
border-radius: 20px;
padding: 8px 14px;
display: flex;
align-items: center;
gap: 6px;
font-size: 13px;
color: var(--text-muted);
cursor: pointer;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
opacity: 0.75;
}
.session-pill:hover {
opacity: 1;
border-color: var(--accent);
color: var(--text);
}
.session-pill__label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 140px;
}
.session-pill__bell {
color: var(--bell);
}
/* ============================================================
Source tile states — offline and auth-required (Phase 3)
============================================================ */
.source-tile {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 12px;
padding: 24px;
height: var(--tile-height);
background: var(--bg-tile);
border: 1px solid var(--border);
border-radius: 4px;
}
.source-tile--offline {
opacity: 0.45;
border-style: dashed;
}
.source-tile--offline .source-tile__name {
color: var(--text-dim);
}
.source-tile--offline .source-tile__badge {
background: var(--err);
color: #ffffff;
font-size: 10px;
font-weight: bold;
padding: 2px 8px;
border-radius: 10px;
text-transform: uppercase;
}
.source-tile--offline .source-tile__last-seen {
font-size: 11px;
color: var(--text-dim);
}
.source-tile--auth {
border-color: var(--warn);
border-style: dashed;
}
.source-tile--empty {
opacity: 0.6;
border-style: dashed;
}
.source-tile__name {
font-size: 15px;
font-weight: 600;
color: var(--text);
}
.source-tile__login-btn {
background: var(--accent);
color: var(--bg);
border: none;
border-radius: 4px;
padding: 8px 20px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
opacity: 1;
transition: opacity var(--t-fast);
}
.source-tile__login-btn:hover {
opacity: 0.85;
}
.source-tile__login-btn:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.source-tile__hint {
font-size: 11px;
color: var(--text-muted);
}
/* ─── Reduced Motion ──────────────────────────────────────────── */
@media (prefers-reduced-motion: reduce) {
.tile-bell {
animation: none;
}
.session-tile--expanding {
transition: none;
}
.session-grid--dimming .session-tile:not(.session-tile--expanding) {
transition: none;
}
.bottom-sheet__panel {
animation: none;
}
.toast {
animation: none;
}
.session-sidebar {
transition: none;
}
.new-session-fab:active {
transform: none;
}
}
/* ============================================================
App wordmark
============================================================ */
.app-wordmark {
margin: 0;
line-height: 1;
display: flex;
align-items: center;
}
.app-wordmark img {
height: 24px;
width: auto;
display: block;
}
/* ============================================================
Hover preview popover (desktop dashboard)
============================================================ */
.preview-popover {
position: fixed;
z-index: 500;
background: #000000;
border: 2px solid var(--accent);
border-radius: 8px;
padding: 16px 20px;
/* Cover most of the viewport — centered with margin */
top: 5vh;
left: 5vw;
right: 5vw;
bottom: 5vh;
overflow-y: auto;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.6);
pointer-events: none; /* mouse events pass through to tiles below */
}
.preview-popover pre {
margin: 0;
font-family: 'SF Mono', 'Fira Code', Consolas, monospace;
font-size: 14px;
line-height: 1.0;
color: #c9d1d9; /* match xterm.js foreground exactly */
white-space: pre-wrap; /* WRAP text instead of horizontal overflow */
word-break: break-all; /* break long lines at viewport edge */
overflow-x: hidden;
}
/* ============================================================
Delete (kill) session buttons — appear on hover
============================================================ */
.tile-delete {
position: absolute;
top: 8px;
right: 8px;
background: none;
border: none;
color: var(--text-dim);
font-size: 14px;
cursor: pointer;
padding: 2px 6px;
border-radius: 4px;
opacity: 0;
transition: opacity 150ms ease;
pointer-events: none;
z-index: 2;
line-height: 1;
}
.session-tile:hover .tile-delete,
.session-tile:focus-within .tile-delete {
opacity: 1;
pointer-events: auto;
}
.tile-delete:hover {
color: #ef4444;
background: rgba(239, 68, 68, 0.1);
opacity: 1;
}
.sidebar-delete {
background: none;
border: none;
color: var(--text-dim);
font-size: 13px;
cursor: pointer;
padding: 1px 5px;
border-radius: 3px;
opacity: 0;
transition: opacity 150ms ease;
pointer-events: none;
flex-shrink: 0;
line-height: 1;
}
.sidebar-item:hover .sidebar-delete,
.sidebar-item:focus-within .sidebar-delete {
opacity: 1;
pointer-events: auto;
}
.sidebar-delete:hover {
color: #ef4444;
background: rgba(239, 68, 68, 0.1);
opacity: 1;
}
/* ============================================================
Header actions + settings buttons
============================================================ */
.header-actions {
display: flex;
align-items: center;
gap: 8px;
}
.header-btn {
width: 32px;
height: 32px;
background: none;
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 16px;
padding: 0;
flex-shrink: 0;
}
.header-btn:hover {
border-color: var(--accent);
color: var(--accent);
}
/* ============================================================
Settings dialog
============================================================ */
.settings-backdrop {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(2px);
z-index: 299;
}
.settings-dialog {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 600px;
height: 480px;
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 8px;
z-index: 300;
padding: 0;
overflow: hidden;
margin: 0;
}
/* <dialog> is display:none by default (UA stylesheet). When opened via
showModal(), the browser adds the [open] attribute. We apply flex layout
only when open — otherwise our display:flex would override the UA
display:none and make the dialog always visible. */
.settings-dialog[open] {
display: flex;
flex-direction: column;
}
.settings-dialog::backdrop {
background: transparent;
pointer-events: none; /* let clicks fall through to #settings-backdrop */
}
.settings-dialog-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 16px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.settings-dialog-title {
margin: 0;
font-size: 14px;
font-weight: 600;
color: var(--text);
}
.settings-close-btn {
background: none;
border: none;
color: var(--text-muted);
font-size: 20px;
cursor: pointer;
padding: 2px 6px;
border-radius: 4px;
line-height: 1;
}
.settings-close-btn:hover {
color: var(--text);
background: var(--bg-surface);
}
.settings-layout {
display: flex;
flex: 1;
min-height: 0;
}
.settings-tabs {
width: 140px;
flex-shrink: 0;
display: flex;
flex-direction: column;
border-right: 1px solid var(--border);
padding: 8px 0;
background: var(--bg-secondary);
}
.settings-tab {
background: none;
border: none;
border-left: 3px solid transparent;
color: var(--text-muted);
cursor: pointer;
text-align: left;
padding: 10px 16px;
font-size: 13px;
}
.settings-tab:hover {
color: var(--text);
background: rgba(255, 255, 255, 0.05);
}
.settings-tab--active {
color: var(--accent);
border-left-color: var(--accent);
}
.settings-content {
flex: 1;
overflow-y: auto;
padding: 16px;
}
.settings-panel-title {
font-size: 14px;
font-weight: 600;
color: var(--text);
margin: 0 0 16px;
}
.settings-field {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px solid var(--border-subtle);
}
.settings-label {
font-size: 13px;
color: var(--text);
}
.settings-select {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text);
font-size: 13px;
padding: 4px 8px;
cursor: pointer;
}
.settings-select:focus {
outline: none;
border-color: var(--accent);
}
/* ============================================================
Settings dialog — mobile (bottom sheet at ≤599px)
============================================================ */
@media (max-width: 599px) {
.settings-dialog {
position: fixed;
bottom: 0;
left: 0;
right: 0;
top: auto;
transform: none;
width: 100%;
height: 85vh;
border-radius: 12px 12px 0 0;
margin: 0;
}
.settings-layout {
flex-direction: column;
}
.settings-tabs {
width: auto;
flex-direction: row;
overflow-x: auto;
border-right: none;
border-bottom: 1px solid var(--border);
padding: 0;
height: auto;
}
.settings-tab {
border-left: none;
border-bottom: 3px solid transparent;
white-space: nowrap;
padding: 10px 16px;
}
.settings-tab--active {
border-bottom-color: var(--accent);
border-left-color: transparent;
}
}
/* ============================================================
Sessions tab controls
============================================================ */
.settings-field--column {
flex-direction: column;
align-items: flex-start;
gap: 8px;
}
.settings-checkbox-list {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
}
.settings-checkbox-item {
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
color: var(--text);
}
.settings-checkbox {
accent-color: var(--accent);
width: 16px;
height: 16px;
cursor: pointer;
}
/* ============================================================
New Session tab controls
============================================================ */
.settings-textarea {
width: 100%;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text);
font-family: var(--font-mono);
font-size: 13px;
padding: 10px;
resize: vertical;
min-height: 60px;
outline: none;
}
.settings-textarea:focus {
border-color: var(--accent);
}
.settings-helper {
font-size: 12px;
color: var(--text-muted);
font-style: italic;
}
/* ============================================================
Notifications tab controls
============================================================ */
.settings-notification-status {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 4px;
}
.settings-status-text {
font-size: 12px;
color: var(--text-muted);
}
.settings-action-btn {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text);
font-size: 12px;
padding: 4px 10px;
cursor: pointer;
}
.settings-action-btn:hover {
border-color: var(--accent);
}
.settings-action-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
/* ============================================================
Header + button inline name input (new-session-btn)
============================================================ */
.new-session-input {
background: var(--bg);
border: 1px solid var(--accent);
border-radius: 4px;
font-size: 13px;
font-family: var(--font-ui);
padding: 4px 10px;
width: 180px;
outline: none;
color: var(--text);
}
.new-session-input::placeholder {
color: var(--text-dim);
}
.new-session-device-select {
background: var(--bg);
border: 1px solid var(--border);
border-radius: 4px;
font-size: 12px;
font-family: var(--font-ui);
padding: 4px 6px;
color: var(--text);
outline: none;
margin-right: 6px;
vertical-align: middle;
}
.fab-input-overlay .new-session-device-select {
display: block;
width: 100%;
margin-bottom: 6px;
margin-right: 0;
}
/* ============================================================
Sidebar sticky footer (+ New button)
============================================================ */
.sidebar-footer {
padding: 8px;
border-top: 1px solid var(--border-subtle);
flex-shrink: 0;
}
.sidebar-new-btn {
width: 100%;
background: none;
border: 1px dashed var(--border);
border-radius: 4px;
color: var(--text-dim);
font-size: 12px;
font-family: var(--font-ui);
padding: 8px;
cursor: pointer;
}
.sidebar-new-btn:hover {
color: var(--text-muted);
border-color: var(--text-muted);
}
/* ============================================================
Mobile FAB — new session floating action button
============================================================ */
.new-session-fab {
display: none;
position: fixed;
bottom: 16px;
right: 16px;
width: 56px;
height: 56px;
border-radius: 50%;
background: var(--accent);
color: var(--bg);
border: none;
font-size: 28px;
font-weight: 300;
line-height: 1;
cursor: pointer;
z-index: 100;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
transition: transform 150ms ease;
}
.new-session-fab:active {
transform: scale(0.95);
}
.new-session-fab:focus-visible {
outline: 2px solid var(--bg);
outline-offset: 2px;
}
/* Fixed-position input overlay triggered by mobile FAB —
appended to body so position:fixed escapes overflow:hidden on views */
.fab-input-overlay {
position: fixed;
bottom: 80px;
right: 16px;
z-index: 200;
}
/* ============================================================
View dropdown — header view selector
============================================================ */
.view-dropdown {
position: relative;
display: flex;
align-items: center;
margin-left: 12px;
}
.view-dropdown__trigger {
display: flex;
align-items: center;
gap: 6px;
background: transparent;
border: 1px solid transparent;
border-radius: 6px;
font-size: 13px;
font-family: var(--font-ui);
color: var(--text);
cursor: pointer;
padding: 4px 10px;
transition: border-color 0.15s, background 0.15s;
}
.view-dropdown__trigger:hover,
.view-dropdown__trigger[aria-expanded="true"] {
border-color: var(--border);
background: var(--bg-surface);
}
.view-dropdown__caret {
font-size: 10px;
color: var(--text-muted);
}
.view-dropdown__menu {
position: absolute;
top: calc(100% + 4px);
left: 0;
min-width: 200px;
max-width: 280px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 8px;
z-index: 100;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
overflow: hidden;
}
.view-dropdown__item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
background: transparent;
border: none;
width: 100%;
font-size: 13px;
font-family: var(--font-ui);
color: var(--text);
cursor: pointer;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.view-dropdown__item:hover,
.view-dropdown__item:focus-visible {
background: var(--bg-surface);
outline: none;
}
.view-dropdown__item--active {
color: var(--accent);
}
.view-dropdown__item--active::before {
content: "\2713";
flex-shrink: 0;
}
.view-dropdown__shortcut {
margin-left: auto;
font-size: 11px;
color: var(--text-dim);
font-family: var(--font-mono);
}
.view-dropdown__separator {
height: 1px;
margin: 4px 0;
background: var(--border-subtle);
}
.view-dropdown__action {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 12px;
color: var(--text-muted);
font-size: 13px;
font-family: var(--font-ui);
background: transparent;
border: none;
width: 100%;
cursor: pointer;
text-align: left;
}
.view-dropdown__action:hover {
background: var(--bg-surface);
color: var(--text);
}
.view-dropdown__new-input {
width: calc(100% - 24px);
margin: 12px;
border: 1px solid var(--accent);
border-radius: 4px;
background: var(--bg);
color: var(--text);
font-size: 13px;
font-family: var(--font-ui);
padding: 4px 8px;
outline: none;
box-sizing: border-box;
}
.view-dropdown__count {
font-size: 11px;
color: var(--text-dim);
}
/* ============================================================
Device badge, group header, filter bar, sidebar device header
============================================================ */
.device-badge {
display: inline-block;
font-size: 9px;
color: var(--accent);
background: var(--accent-dim);
border: 1px solid var(--accent);
border-radius: 4px;
padding: 1px 4px;
line-height: 1.4;
vertical-align: middle;
}
.device-group-header {
font-size: 13px;
font-weight: 600;
color: var(--text-muted);
grid-column: 1 / -1;
padding: 8px 0 6px;
border-bottom: 1px solid var(--border);
margin-bottom: 4px;
}
.filter-bar {
display: flex;
flex-wrap: wrap;
gap: 6px;
padding: 6px 0;
}
.filter-pill {
font-size: 12px;
border-radius: 14px;
border: 1px solid var(--border);
background: transparent;
color: var(--text-muted);
padding: 3px 10px;
cursor: pointer;
transition: border-color 150ms ease, color 150ms ease;
line-height: 1.4;
}
.filter-pill:hover {
border-color: var(--accent);
color: var(--accent);
}
.filter-pill--active {
border-color: var(--accent);
background: var(--accent-dim);
color: var(--accent);
font-weight: 700;
}
.sidebar-device-header {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text-dim);
padding: 8px 12px 4px;
}
/* ============================================================
Dashboard view modes — Fit
============================================================ */
/* Fit view — tiles fill viewport, no scroll */
.session-grid--fit {
overflow: hidden;
align-content: stretch; /* let 1fr rows fill container height */
}
/* In fit mode, tiles must use height:auto so the CSS grid 1fr rows control sizing.
The base .session-tile uses var(--tile-height) which is a fixed pixel value —
overriding with height:auto lets the grid cell (from grid-template-rows: repeat(n,1fr))
determine the tile height instead. JS sets only grid-template-columns/rows, not inline heights. */
.session-grid--fit .session-tile {
height: auto;
}
/* In fit mode, tile body and pre use the base CSS:
.tile-body { position: relative; overflow: hidden; }
.tile-body pre { position: absolute; bottom: 0; left: 0; right: 0; }
The pre's natural height from 80 lines of content exceeds the tile height, so it
overflows from bottom:0 upward, and tile-body clips excess at the top — showing
the bottom-most content (the prompt area) just like a real terminal. */
/* —— Add Sessions Panel —————————————————————————————————————————————————————————————————————————— */
.add-sessions-panel {
position: fixed;
inset: 0;
z-index: 250;
display: flex;
align-items: center;
justify-content: center;
}
.add-sessions-panel__backdrop {
position: absolute;
inset: 0;
background: var(--bg-overlay);
}
.add-sessions-panel__content {
position: relative;
width: 90%;
max-width: 440px;
max-height: 70vh;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 12px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.add-sessions-panel__header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 12px 16px;
border-bottom: 1px solid var(--border-subtle);
}
.add-sessions-panel__title {
font-size: 15px;
font-weight: 600;
color: var(--text);
margin: 0;
}
.add-sessions-panel__close {
width: 28px;
height: 28px;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
color: var(--text-muted);
font-size: 18px;
cursor: pointer;
border-radius: 4px;
}
.add-sessions-panel__close:hover {
background: var(--bg-surface);
color: var(--text);
}
.add-sessions-panel__list {
overflow-y: auto;
padding: 8px 0;
flex: 1;
}
.add-sessions-panel__empty {
padding: 24px 16px;
text-align: center;
color: var(--text-muted);
font-size: 13px;
}
.add-sessions-item {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 16px;
cursor: pointer;
}
.add-sessions-item:hover {
background: var(--bg-surface);
}
.add-sessions-item--hidden {
opacity: 0.5;
}
.add-sessions-item__checkbox {
flex-shrink: 0;
accent-color: var(--accent);
}
.add-sessions-item__name {
font-size: 13px;
color: var(--text);
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.add-sessions-item__device {
font-size: 11px;
color: var(--text-dim);
white-space: nowrap;
}
.add-sessions-item__badge {
font-size: 10px;
color: var(--text-dim);
background: var(--bg);
border: 1px solid var(--border-subtle);
border-radius: 3px;
padding: 1px 5px;
}
.add-sessions-item__disclosure {
width: 100%;
padding: 2px 16px 6px 42px;
font-size: 11px;
color: var(--text-dim);
font-style: italic;
display: none;
}
/* Mobile: full-screen sheet for Add Sessions */
@media (max-width: 599px) {
.add-sessions-panel__content {
width: 100%;
max-width: 100%;
max-height: 100%;
height: 100%;
border-radius: 0;
}
}
/* ============================================================
Responsive overlay sidebar at <960px
============================================================ */
@media (max-width: 959px) {
.session-sidebar {
position: fixed;
left: 0;
top: 0;
height: 100%;
z-index: 200;
width: 240px;
min-width: 240px;
transition: transform 0.25s ease;
transform: translateX(0);
box-shadow: 2px 0 16px rgba(0,0,0,0.5);
}
.session-sidebar.sidebar--collapsed {
width: 240px;
min-width: 240px;
transform: translateX(-100%);
}
.sidebar-collapse-btn {
display: none;
}
/* Mobile FAB: show on mobile, hide header + button */
.new-session-fab {
display: flex;
align-items: center;
justify-content: center;
}
#new-session-btn {
display: none;
}
}
/* ============================================================
Remote Instances UI (task-15)
============================================================ */
.settings-input {
flex: 1;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text);
font-size: 13px;
padding: 5px 8px;
outline: none;
transition: border-color 0.15s;
}
.settings-input:focus {
border-color: var(--accent);
}
.settings-remote-list {
display: flex;
flex-direction: column;
gap: 6px;
width: 100%;
}
.settings-remote-row {
display: flex;
gap: 6px;
align-items: center;
}
.settings-remote-url,
.settings-remote-name {
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text);
font-size: 13px;
padding: 5px 8px;
outline: none;
transition: border-color 0.15s;
}
.settings-remote-url {
flex: 2;
}
.settings-remote-name {
flex: 1;
}
.settings-remote-url:focus,
.settings-remote-name:focus {
border-color: var(--accent);
}
.settings-remote-remove {
flex-shrink: 0;
background: transparent;
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text-muted);
cursor: pointer;
font-size: 16px;
line-height: 1;
padding: 4px 8px;
transition: color 0.15s, border-color 0.15s;
}
.settings-remote-remove:hover {
border-color: #ef4444;
color: #ef4444;
background: rgba(239, 68, 68, 0.1);
}
/* Multi-Device tab — smooth enable/disable opacity transition */
#multi-device-fields {
transition: opacity 0.2s ease;
}
/* Constrain device name input width so it doesn't stretch the full settings panel */
#setting-device-name {
max-width: 200px;
}
/* Federation key display */
.settings-federation-key {
display: flex;
align-items: center;
gap: 8px;
}
.settings-key-display {
font-family: var(--font-mono);
font-size: 13px;
color: var(--text-muted);
user-select: all;
}
.settings-key-display--visible {
color: var(--accent);
background: var(--accent-dim);
padding: 4px 8px;
border-radius: 4px;
}
/* Remote instance federation key input */
.settings-remote-key {
flex: 1;
min-width: 100px;
font-size: 12px;
padding: 4px 6px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text);
}
/* ─── Manage Views settings tab (task-9) ─────────────────────────────────── */
.views-settings-list {
display: flex;
flex-direction: column;
gap: 4px;
width: 100%;
}
.views-settings-row {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 4px;
}
.views-settings-name {
flex: 1;
font-size: 13px;
color: var(--text);
cursor: pointer;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.views-settings-name:hover {
color: var(--accent);
text-decoration: underline;
}
.views-settings-count {
font-size: 11px;
color: var(--text-muted);
white-space: nowrap;
flex-shrink: 0;
}
.views-settings-actions {
display: flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
.views-settings-btn {
background: transparent;
border: 1px solid var(--border);
border-radius: 4px;
color: var(--text-muted);
cursor: pointer;
font-size: 12px;
line-height: 1;
padding: 3px 7px;
transition: color 0.15s, border-color 0.15s, background 0.15s;
}
.views-settings-btn:hover:not(:disabled) {
border-color: var(--accent);
color: var(--accent);
background: var(--accent-dim);
}
.views-settings-btn:disabled {
opacity: 0.35;
cursor: not-allowed;
}
.views-settings-btn--danger:hover:not(:disabled) {
border-color: #ef4444;
color: #ef4444;
background: rgba(239, 68, 68, 0.1);
}
.views-settings-confirm {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 12px;
color: var(--text-muted);
}
.views-settings-rename-input {
flex: 1;
background: var(--bg);
border: 1px solid var(--accent);
border-radius: 4px;
color: var(--text);
font-size: 13px;
padding: 3px 6px;
outline: none;
}
/* —— Tile Flyout Menu ————————————————————————————————————————————————————— */
.tile-options-btn {
position: absolute;
top: 6px;
right: 6px;
width: 24px;
height: 24px;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-tile);
border: 1px solid var(--border-subtle);
border-radius: 4px;
color: var(--text-muted);
font-size: 14px;
line-height: 1;
cursor: pointer;
z-index: 2;
transition: border-color var(--t-fast), color var(--t-fast), background var(--t-fast);
}
.tile-options-btn:hover,
.tile-options-btn:focus-visible {
border-color: var(--border);
color: var(--text);
background: var(--bg-surface);
}
.flyout-menu {
position: fixed;
min-width: 200px;
max-width: 280px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 8px;
padding: 4px 0;
z-index: 300;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
}
.flyout-menu__item {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 7px 12px;
background: transparent;
border: none;
color: var(--text);
font-size: 13px;
cursor: pointer;
text-align: left;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
position: relative;
}
.flyout-menu__item:hover,
.flyout-menu__item:focus-visible {
background: var(--bg-surface);
}
.flyout-menu__item--danger {
color: var(--err);
}
.flyout-menu__item--danger:hover {
background: rgba(248, 81, 73, 0.1);
}
.flyout-menu__item--has-submenu::after {
content: "\25B8";
margin-left: auto;
font-size: 10px;
color: var(--text-dim);
}
.flyout-menu__separator {
height: 1px;
margin: 4px 0;
background: var(--border-subtle);
}
.flyout-menu__confirm {
display: flex;
align-items: center;
gap: 6px;
padding: 7px 12px;
font-size: 13px;
color: var(--text-muted);
}
.flyout-menu__confirm-btn {
padding: 2px 8px;
border-radius: 4px;
border: 1px solid var(--border);
background: transparent;
color: var(--text);
font-size: 12px;
cursor: pointer;
}
.flyout-menu__confirm-btn:hover {
background: var(--bg-surface);
}
.flyout-menu__confirm-btn--yes {
border-color: var(--err);
color: var(--err);
}
.flyout-menu__confirm-btn--yes:hover {
background: rgba(248, 81, 73, 0.15);
}
/* —— Flyout Submenu (Add to View) ———————————————————————————————————————— */
.flyout-submenu {
position: fixed;
min-width: 180px;
max-width: 240px;
background: var(--bg-secondary);
border: 1px solid var(--border);
border-radius: 8px;
padding: 4px 0;
z-index: 310;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.5);
}
.flyout-submenu__item {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 6px 12px;
background: transparent;
border: none;
color: var(--text);
font-size: 13px;
cursor: pointer;
text-align: left;
}
.flyout-submenu__item:hover {
background: var(--bg-surface);
}
.flyout-submenu__check {
width: 14px;
flex-shrink: 0;
color: var(--accent);
font-size: 12px;
}
/* —— Mobile: Flyout as bottom action sheet ——————————————————————————————— */
.flyout-sheet {
position: fixed;
inset: 0;
z-index: 300;
display: flex;
align-items: flex-end;
}
.flyout-sheet__backdrop {
position: absolute;
inset: 0;
background: var(--bg-overlay);
}
.flyout-sheet__panel {
position: relative;
width: 100%;
background: var(--bg-header);
border-top: 1px solid var(--border);
border-radius: 12px 12px 0 0;
max-height: 70vh;
overflow-y: auto;
animation: sheet-up var(--t-zoom) ease;
padding-bottom: env(safe-area-inset-bottom, 8px);
}
.flyout-sheet__handle {
width: 36px;
height: 4px;
background: var(--border);
border-radius: 2px;
margin: 10px auto 6px;
}
.flyout-sheet__item {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
padding: 14px 20px;
background: transparent;
border: none;
color: var(--text);
font-size: 15px;
cursor: pointer;
text-align: left;
}
.flyout-sheet__item:active {
background: var(--bg-surface);
}
.flyout-sheet__item--danger {
color: var(--err);
}
.flyout-sheet__separator {
height: 1px;
margin: 4px 0;
background: var(--border-subtle);
}
/* —— Add Sessions affordance tile ————————————————————————————————————————— */
.add-sessions-tile {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 8px;
min-height: 120px;
background: transparent;
border: 2px dashed var(--border-subtle);
border-radius: 8px;
color: var(--text-dim);
font-size: 13px;
cursor: pointer;
transition: border-color var(--t-fast), color var(--t-fast);
}
.add-sessions-tile:hover {
border-color: var(--accent);
color: var(--accent);
}
.add-sessions-tile__icon {
font-size: 24px;
line-height: 1;
}
.add-sessions-tile__label {
font-size: 12px;
}