/* Системные шрифты — без загрузки из интернета */ :root { --font-ui: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, Roboto, sans-serif; --font-head: 'Segoe UI', system-ui, -apple-system, Roboto, sans-serif; --font-mono: 'SF Mono', 'Fira Code', 'Fira Mono', 'Cascadia Code', Consolas, 'Liberation Mono', Menlo, monospace; color-scheme: dark; /* Surfaces */ --bg: #06110d; --surface: #0b1b14; --surface-2: #10251b; --surface-3: #163224; --border: #214734; --border-strong: #2c5d44; /* Text */ --text: #effff5; --muted: #9fbaaa; --subtle: #6f8c7c; /* Roles */ --success: #6dff9d; --success-dim: rgba(109, 255, 157, 0.14); --warning: #ffd166; --warning-dim: rgba(255, 209, 102, 0.14); --danger: #ff5c5c; --danger-dim: rgba(255, 92, 92, 0.14); --accent: #b7ff63; --accent-dim: rgba(183, 255, 99, 0.14); --info: #8ed4ff; --info-dim: rgba(142, 212, 255, 0.14); /* Radii */ --radius-card: 20px; --radius-input: 12px; --radius-pill: 999px; /* Spacing */ --space-1: 4px; --space-2: 8px; --space-3: 12px; --space-4: 16px; --space-5: 20px; --space-6: 24px; --space-8: 32px; /* Shadow */ --shadow-card: 0 12px 36px rgba(0, 0, 0, 0.32); --shadow-modal: 0 32px 80px rgba(0, 0, 0, 0.6); /* Layout */ --topbar-h: 64px; --sidebar-w: 220px; --status-w: 280px; } * { box-sizing: border-box; } html, body, #root { height: 100%; } body { margin: 0; font-family: var(--font-ui); font-size: 14px; line-height: 1.5; color: var(--text); background: var(--bg); -webkit-font-smoothing: antialiased; } button, input, select, textarea { font: inherit; color: inherit; } a { color: var(--accent); text-decoration: none; } a:hover { text-decoration: underline; } h1, h2, h3, h4 { font-family: var(--font-head); margin: 0; font-weight: 600; letter-spacing: -0.01em; } h1 { font-size: 22px; } h2 { font-size: 18px; } h3 { font-size: 15px; color: var(--text); } h4 { font-size: 13px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.08em; } p { margin: 0; } small { font-size: 12px; color: var(--muted); } code, .mono { font-family: var(--font-mono); font-size: 12px; } /* ============ Layout ============ */ .app { min-height: 100vh; display: grid; grid-template-rows: var(--topbar-h) 1fr; background: radial-gradient(circle at 8% 0%, rgba(109, 255, 157, 0.05), transparent 32rem), radial-gradient(circle at 92% 100%, rgba(142, 212, 255, 0.04), transparent 28rem), var(--bg); } .app-body { display: grid; grid-template-columns: var(--sidebar-w) 1fr var(--status-w); min-height: 0; } .app-body.client-mode { grid-template-columns: 1fr; background: radial-gradient(circle at 10% 0%, rgba(142, 212, 255, 0.08), transparent 28rem), linear-gradient(180deg, #07110f 0%, #070d11 60%, #06090d 100%); } .app-main { padding: var(--space-6); overflow-y: auto; min-width: 0; } @media (max-width: 1100px) { .app-body { grid-template-columns: var(--sidebar-w) 1fr; } .status-pane { display: none; } } @media (max-width: 768px) { .app-body { grid-template-columns: 1fr; } .app-body.client-mode { grid-template-columns: 1fr; } .sidebar { display: none; } .app-main { padding: var(--space-4); } } /* ============ Topbar ============ */ .topbar { display: flex; align-items: center; gap: var(--space-4); padding: 0 var(--space-6); background: var(--surface); border-bottom: 1px solid var(--border); height: var(--topbar-h); } .topbar-brand { font-family: var(--font-head); font-weight: 700; font-size: 16px; letter-spacing: -0.01em; display: flex; align-items: center; gap: var(--space-2); } .topbar-brand .logo-dot { width: 10px; height: 10px; border-radius: 50%; background: var(--accent); box-shadow: 0 0 12px var(--accent); } .topbar-status { display: flex; align-items: center; gap: var(--space-3); flex: 1; min-width: 0; } .topbar-status .status-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; } .topbar-status .status-text strong { font-weight: 600; font-size: 13px; } .topbar-status .status-text small { font-size: 11px; color: var(--subtle); } .topbar-actions { display: flex; align-items: center; gap: var(--space-2); } /* ============ Sidebar ============ */ .sidebar { background: var(--surface); border-right: 1px solid var(--border); padding: var(--space-4) var(--space-3); display: flex; flex-direction: column; gap: var(--space-1); overflow-y: auto; } .sidebar-item { display: flex; align-items: center; gap: var(--space-3); padding: 10px 12px; border-radius: var(--radius-input); color: var(--muted); cursor: pointer; border: 1px solid transparent; background: transparent; text-align: left; font-weight: 500; font-size: 14px; transition: background 0.12s, color 0.12s; } .sidebar-item:hover { background: var(--surface-2); color: var(--text); } .sidebar-item.active { background: var(--surface-2); color: var(--text); border-color: var(--border); } .sidebar-item .ico { width: 18px; opacity: 0.85; flex: 0 0 18px; } .sidebar-item .badge { margin-left: auto; font-size: 11px; padding: 2px 8px; border-radius: var(--radius-pill); background: var(--surface-3); color: var(--muted); } .sidebar-item .badge.warn { background: var(--warning-dim); color: var(--warning); } .sidebar-item .badge.danger { background: var(--danger-dim); color: var(--danger); } /* ============ Status pane ============ */ .status-pane { background: var(--surface); border-left: 1px solid var(--border); padding: var(--space-4); display: flex; flex-direction: column; gap: var(--space-4); overflow-y: auto; } /* ============ Cards & panels ============ */ .card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); padding: var(--space-5); box-shadow: var(--shadow-card); } .card.compact { padding: var(--space-4); } .card.flat { box-shadow: none; background: var(--surface-2); } .card-header { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-4); } .card-header.no-margin { margin-bottom: 0; } .section-stack { display: flex; flex-direction: column; gap: var(--space-4); } .grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-4); } .grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--space-4); } @media (max-width: 900px) { .grid-2, .grid-3 { grid-template-columns: 1fr; } } /* ============ Buttons ============ */ .btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); border: 1px solid transparent; border-radius: var(--radius-input); padding: 8px 14px; font-weight: 600; font-size: 13px; cursor: pointer; background: transparent; color: var(--text); transition: background 0.12s, border-color 0.12s, opacity 0.12s; white-space: nowrap; line-height: 1.2; } .btn:disabled { opacity: 0.4; cursor: not-allowed; } .btn.lg { padding: 12px 18px; font-size: 14px; } .btn.sm { padding: 6px 10px; font-size: 12px; } .btn.block { width: 100%; } .btn-primary { background: var(--accent); color: #061608; border-color: var(--accent); } .btn-primary:hover:not(:disabled) { filter: brightness(1.05); } .btn-secondary { background: var(--surface-2); border-color: var(--border); color: var(--text); } .btn-secondary:hover:not(:disabled) { background: var(--surface-3); border-color: var(--border-strong); } .btn-ghost { background: transparent; border-color: var(--border); color: var(--muted); } .btn-ghost:hover:not(:disabled) { color: var(--text); border-color: var(--border-strong); } .btn-danger { background: transparent; border-color: var(--danger); color: var(--danger); } .btn-danger:hover:not(:disabled) { background: var(--danger-dim); } .btn-link { background: transparent; border: none; color: var(--accent); padding: 4px 6px; } .btn-link:hover:not(:disabled) { text-decoration: underline; } .btn-group { display: inline-flex; gap: var(--space-2); flex-wrap: wrap; } /* ============ Inputs ============ */ .input, .select, .textarea { display: block; width: 100%; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-input); padding: 9px 12px; color: var(--text); outline: none; transition: border-color 0.12s, box-shadow 0.12s; } .input:focus, .select:focus, .textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-dim); } .textarea { min-height: 80px; resize: vertical; font-family: var(--font-mono); font-size: 12px; } .field { display: flex; flex-direction: column; gap: 6px; } .field-label { font-size: 12px; color: var(--muted); font-weight: 500; } .field-error { color: var(--danger); font-size: 11px; } .field-hint { color: var(--subtle); font-size: 11px; } .checkbox { display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; user-select: none; font-size: 13px; color: var(--muted); } .checkbox input { width: 14px; height: 14px; accent-color: var(--accent); } /* ============ Badges & dots ============ */ .badge { display: inline-flex; align-items: center; gap: 6px; padding: 3px 10px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 600; background: var(--surface-3); color: var(--muted); border: 1px solid var(--border); line-height: 1.2; white-space: nowrap; } .badge.success { background: var(--success-dim); color: var(--success); border-color: rgba(109, 255, 157, 0.3); } .badge.warning { background: var(--warning-dim); color: var(--warning); border-color: rgba(255, 209, 102, 0.3); } .badge.danger { background: var(--danger-dim); color: var(--danger); border-color: rgba(255, 92, 92, 0.3); } .badge.info { background: var(--info-dim); color: var(--info); border-color: rgba(142, 212, 255, 0.3); } .badge.neutral { background: var(--surface-3); color: var(--muted); } .dot { width: 8px; height: 8px; border-radius: 50%; background: var(--subtle); flex: 0 0 8px; } .dot.success { background: var(--success); box-shadow: 0 0 8px var(--success); } .dot.warning { background: var(--warning); box-shadow: 0 0 8px var(--warning); } .dot.danger { background: var(--danger); box-shadow: 0 0 8px var(--danger); } .dot.info { background: var(--info); box-shadow: 0 0 8px var(--info); } .pulse { animation: pulse 1.6s ease-in-out infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } /* ============ Lists & tables ============ */ .kv-list { display: flex; flex-direction: column; } .kv-list .row { display: flex; justify-content: space-between; gap: var(--space-3); padding: 8px 0; border-bottom: 1px solid var(--border); font-size: 13px; } .kv-list .row:last-child { border-bottom: 0; } .kv-list .key { color: var(--muted); } .kv-list .val { color: var(--text); font-weight: 500; } .table { width: 100%; border-collapse: collapse; font-size: 13px; } .table th, .table td { text-align: left; padding: 10px 12px; border-bottom: 1px solid var(--border); } .table th { font-size: 11px; text-transform: uppercase; letter-spacing: 0.06em; color: var(--muted); font-weight: 600; } .table tbody tr { transition: background 0.1s; } .table tbody tr:hover { background: var(--surface-2); } .table tbody tr.active { background: var(--accent-dim); } .table .row-actions { display: flex; gap: var(--space-2); justify-content: flex-end; } /* ============ Tag input (chips) ============ */ .chips { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px; background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-input); min-height: 40px; align-items: center; } .chip { display: inline-flex; align-items: center; gap: 6px; padding: 4px 8px; background: var(--surface-3); border: 1px solid var(--border); border-radius: 8px; font-family: var(--font-mono); font-size: 12px; color: var(--text); } .chip.error { border-color: var(--danger); color: var(--danger); } .chip button { background: none; border: none; color: var(--muted); cursor: pointer; padding: 0; font-size: 14px; line-height: 1; } .chip button:hover { color: var(--danger); } .chips .chip-input { flex: 1; min-width: 100px; background: transparent; border: none; outline: none; color: var(--text); font-family: var(--font-mono); font-size: 12px; padding: 4px 6px; } /* ============ Sticky action bar ============ */ .sticky-bar { position: sticky; bottom: 0; margin: var(--space-6) calc(-1 * var(--space-6)) calc(-1 * var(--space-6)); padding: var(--space-3) var(--space-6); background: var(--surface); border-top: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); z-index: 5; box-shadow: 0 -8px 24px rgba(0, 0, 0, 0.3); } /* ============ Drawer & modal ============ */ .modal-backdrop { position: fixed; inset: 0; background: rgba(2, 8, 5, 0.65); backdrop-filter: blur(4px); z-index: 100; display: flex; align-items: center; justify-content: center; padding: var(--space-4); } .modal { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius-card); box-shadow: var(--shadow-modal); width: min(720px, 100%); max-height: 86vh; display: flex; flex-direction: column; } .modal.lg { width: min(960px, 100%); } .modal-head, .modal-foot { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); } .modal-foot { border-top: 1px solid var(--border); border-bottom: 0; } .modal-body { padding: var(--space-5); overflow-y: auto; flex: 1; } .drawer-backdrop { position: fixed; inset: 0; background: rgba(2, 8, 5, 0.55); backdrop-filter: blur(3px); z-index: 90; } .drawer { position: fixed; top: 0; right: 0; bottom: 0; width: min(540px, 100%); background: var(--surface); border-left: 1px solid var(--border); box-shadow: var(--shadow-modal); z-index: 91; display: flex; flex-direction: column; } .drawer-head, .drawer-foot { padding: var(--space-4) var(--space-5); border-bottom: 1px solid var(--border); display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); } .drawer-foot { border-top: 1px solid var(--border); border-bottom: 0; } .drawer-body { padding: var(--space-5); overflow-y: auto; flex: 1; display: flex; flex-direction: column; gap: var(--space-4); } /* ============ Toasts ============ */ .toasts { position: fixed; top: calc(var(--topbar-h) + 12px); right: 16px; display: flex; flex-direction: column; gap: 8px; z-index: 200; max-width: 360px; } .toast { background: var(--surface-3); border: 1px solid var(--border); border-radius: var(--radius-input); padding: 12px 14px; display: flex; gap: 10px; align-items: flex-start; box-shadow: var(--shadow-card); font-size: 13px; } .toast.success { border-color: rgba(109, 255, 157, 0.3); } .toast.danger { border-color: rgba(255, 92, 92, 0.3); } .toast.warning { border-color: rgba(255, 209, 102, 0.3); } .toast .body { flex: 1; } .toast .body small { display: block; color: var(--muted); margin-top: 2px; } .toast button { background: none; border: none; color: var(--muted); cursor: pointer; } /* ============ Logs ============ */ .logs-stream { background: #02080a; border: 1px solid var(--border); border-radius: var(--radius-input); padding: var(--space-3); font-family: var(--font-mono); font-size: 12px; line-height: 1.55; overflow-y: auto; flex: 1; min-height: 320px; } .log-line { display: grid; grid-template-columns: 70px 60px 1fr; gap: 10px; padding: 2px 4px; border-radius: 4px; word-break: break-word; } .log-line:hover { background: var(--surface-2); } .log-line .log-time { color: var(--subtle); } .log-line .log-level { font-size: 10px; text-transform: uppercase; padding-top: 2px; font-weight: 600; } .log-line.info .log-level { color: var(--info); } .log-line.warning .log-level { color: var(--warning); } .log-line.error .log-level { color: var(--danger); } .log-line.debug .log-level { color: var(--subtle); } .log-line .log-text { color: var(--text); } .log-group { display: grid; grid-template-columns: 70px 60px 1fr auto; gap: 10px; padding: 4px; border-radius: 4px; background: var(--surface-2); margin-bottom: 4px; align-items: center; } .log-group .repeat { color: var(--warning); font-size: 11px; } /* ============ Misc ============ */ .empty-state { text-align: center; padding: var(--space-8) var(--space-4); color: var(--muted); } .empty-state h3 { margin-bottom: var(--space-2); color: var(--text); } .flex { display: flex; gap: var(--space-3); align-items: center; } .flex-col { display: flex; flex-direction: column; gap: var(--space-3); } .flex-between { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); } .flex-wrap { flex-wrap: wrap; } .flex-1 { flex: 1; min-width: 0; } .spacer { flex: 1; } .muted { color: var(--muted); } .text-success { color: var(--success); } .text-warning { color: var(--warning); } .text-danger { color: var(--danger); } .text-mono { font-family: var(--font-mono); } .text-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .divider { height: 1px; background: var(--border); margin: var(--space-3) 0; } .config-view { background: #02080a; border: 1px solid var(--border); border-radius: var(--radius-input); padding: var(--space-3); font-family: var(--font-mono); font-size: 12px; line-height: 1.5; margin: 0; color: var(--text); overflow: auto; max-height: 60vh; white-space: pre; } /* drag handle for rules sortable */ .drag-handle { cursor: grab; user-select: none; padding: 6px 8px; border-radius: 6px; color: var(--subtle); font-family: var(--font-mono); font-size: 14px; } .drag-handle:hover { color: var(--text); background: var(--surface-2); } .drag-handle:active { cursor: grabbing; } .rule-row.disabled { opacity: 0.5; } .rule-row.invalid td:first-child { box-shadow: inset 3px 0 0 var(--danger); } .conflict-banner { background: var(--warning-dim); border: 1px solid rgba(255, 209, 102, 0.3); color: var(--warning); padding: 10px 14px; border-radius: var(--radius-input); font-size: 12px; display: flex; gap: 10px; align-items: flex-start; } .conflict-banner.danger { background: var(--danger-dim); border-color: rgba(255, 92, 92, 0.3); color: var(--danger); } .template-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-3); } .template-card { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-input); padding: var(--space-3); display: flex; flex-direction: column; gap: 6px; } .template-card h4 { color: var(--text); text-transform: none; letter-spacing: 0; font-size: 13px; } .template-card small { color: var(--subtle); font-size: 11px; line-height: 1.4; } .events-list { display: flex; flex-direction: column; gap: 6px; } .event-row { display: grid; grid-template-columns: 16px 60px 1fr; gap: 10px; align-items: center; padding: 6px 8px; border-radius: 8px; font-size: 12px; } .event-row:hover { background: var(--surface-2); } .event-row .event-time { color: var(--subtle); font-family: var(--font-mono); font-size: 11px; } .route-result { background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--radius-input); padding: var(--space-3); display: flex; flex-direction: column; gap: var(--space-2); } .tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: var(--space-4); } .tab { padding: 8px 14px; background: transparent; border: none; color: var(--muted); cursor: pointer; font-size: 13px; font-weight: 500; border-bottom: 2px solid transparent; margin-bottom: -1px; } .tab.active { color: var(--text); border-bottom-color: var(--accent); } .tab:hover { color: var(--text); } .filter-bar { display: flex; gap: var(--space-2); flex-wrap: wrap; align-items: center; } .filter-bar .input, .filter-bar .select { width: auto; min-width: 140px; } .subscription-input { display: flex; gap: var(--space-2); align-items: stretch; } .subscription-input .input { flex: 1; } /* ============ Client overview ============ */ .client-mode .app-main { max-width: 1180px; width: 100%; margin: 0 auto; padding-top: 18px; } .client-dashboard { display: grid; gap: 12px; } .client-status-panel { display: grid; grid-template-columns: minmax(0, 1.2fr) minmax(420px, 0.8fr); gap: 16px; padding: 18px; background: #101820; border: 1px solid #263442; border-radius: 8px; } .client-status-panel.connected { border-color: rgba(109, 255, 157, 0.46); } .client-status-panel.stopped { border-color: rgba(255, 209, 102, 0.42); } .client-status-panel.empty { border-color: rgba(142, 212, 255, 0.32); } .client-status-main { min-width: 0; display: flex; align-items: flex-start; gap: 14px; } .client-status-dot { width: 12px; height: 12px; margin-top: 9px; border-radius: 50%; background: var(--subtle); box-shadow: 0 0 0 6px rgba(111, 140, 124, 0.12); flex: 0 0 12px; } .client-status-dot.connected { background: var(--success); box-shadow: 0 0 0 6px rgba(109, 255, 157, 0.12); } .client-status-dot.stopped { background: var(--warning); box-shadow: 0 0 0 6px rgba(255, 209, 102, 0.12); } .client-status-dot.empty { background: var(--info); box-shadow: 0 0 0 6px rgba(142, 212, 255, 0.12); } .client-eyebrow { color: var(--subtle); font-size: 11px; font-weight: 700; text-transform: uppercase; } .client-status-main h1 { margin: 2px 0 4px; font-size: 30px; line-height: 1.08; letter-spacing: 0; } .client-status-main p { margin: 0; color: var(--muted); } .client-status-facts { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; } .client-status-facts > div { min-width: 0; padding: 12px; background: #0b1219; border: 1px solid #253341; border-radius: 8px; } .client-status-facts small, .client-current-target small, .client-panel-title { display: block; color: var(--subtle); font-size: 11px; font-weight: 700; text-transform: uppercase; } .client-status-facts strong, .client-current-target strong { display: block; margin: 3px 0; overflow-wrap: anywhere; } .client-status-facts span { color: var(--muted); font-size: 12px; } .client-route-line { display: flex; align-items: center; gap: 8px; padding: 10px 14px; background: #0b1219; border: 1px solid #253341; border-radius: 8px; color: var(--muted); overflow-x: auto; white-space: nowrap; } .client-route-line span { color: var(--text); font-family: var(--font-mono); font-size: 12px; } .client-route-line b { color: var(--subtle); font-weight: 600; } .client-workspace { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: 12px; align-items: start; } .client-main-panel, .client-side-panel { background: #101820; border: 1px solid #263442; border-radius: 8px; padding: 14px; } .client-main-panel { display: flex; flex-direction: column; gap: 14px; } .client-mode-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; } .client-mode-button { min-width: 0; text-align: left; padding: 12px; border: 1px solid #2a3948; border-radius: 8px; background: #0b1219; cursor: pointer; transition: border-color 0.16s ease, background 0.16s ease; } .client-mode-button:hover:not(:disabled) { border-color: #4c6d88; background: #101c27; } .client-mode-button.selected { border-color: var(--info); background: rgba(142, 212, 255, 0.08); } .client-mode-button.active { border-color: var(--success); background: rgba(109, 255, 157, 0.11); } .client-mode-button strong, .client-mode-button span { display: flex; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .client-mode-button strong { font-size: 14px; } .client-mode-button span { margin-top: 3px; color: var(--muted); font-size: 12px; } .client-mode-settings { display: grid; gap: 12px; } .client-mode-settings.direct { grid-template-columns: minmax(0, 1fr) auto; display: flex; align-items: center; justify-content: space-between; gap: 16px; } .client-mode-settings.direct p { margin: 4px 0 0; } .client-inline-form { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; } .client-current-target { padding: 10px 12px; background: #0b1219; border: 1px solid #253341; border-radius: 8px; } .client-side-panel { display: grid; gap: 16px; } .client-copy-stack { display: grid; gap: 8px; margin-top: 8px; } .client-copy { width: 100%; display: flex; justify-content: space-between; align-items: center; gap: 10px; padding: 10px; background: #0b1219; border: 1px solid #253341; border-radius: 8px; cursor: pointer; } .client-copy span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-family: var(--font-mono); font-size: 12px; } .client-copy strong { color: var(--accent); font-size: 11px; } .client-port-row { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; } @media (max-width: 980px) { .client-status-panel, .client-workspace { grid-template-columns: 1fr; } .client-status-facts, .client-mode-grid { grid-template-columns: 1fr; } .client-mode-settings.direct, .client-inline-form { grid-template-columns: 1fr; } } /* For drawer rule editor */ .field-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3); } @media (max-width: 600px) { .field-row { grid-template-columns: 1fr; } }