* { box-sizing: border-box; } body, html, #root { width: 100%; height: 100%; overflow: hidden; } body { margin: 0; font-family: Inter, system-ui, sans-serif; background: #f2f2f2; color: #1f2937; } button, input, select { font: inherit; } button { cursor: pointer; } .app { height: 100vh; width: 100vw; min-width: 1280px; display: flex; overflow: hidden; background: #f2f2f2; } /* SIDEBAR */ .sidebar { width: 250px; background: #0d0d0d; color: white; padding: 26px 16px 18px; display: flex; flex-direction: column; border-right: 1px solid #171717; } .brand { display: flex; flex-direction: column; align-items: center; gap: 8px; margin-bottom: 34px; text-align: center; } .logo { width: 72px; height: 72px; border-radius: 24px; background: linear-gradient(135deg, #5da8ff, #b7e236); display: grid; place-items: center; font-weight: 900; font-size: 24px; color: #0d0d0d; } .brand-logo { width: 115px; height: auto; display: block; } .brand strong { display: block; font-size: 18px; letter-spacing: 0.5px; color: #5da8ff; } .brand span { display: block; font-size: 13px; color: white; letter-spacing: 4px; margin-top: -2px; } nav { display: grid; gap: 8px; } nav button { background: transparent; border: 0; color: #d1d5db; padding: 12px 14px; border-radius: 9px; display: flex; align-items: center; gap: 11px; font-size: 14px; font-weight: 700; } nav button.active, nav button:hover { background: #5da8ff; color: white; } .status-card { margin-top: auto; background: #181818; border: 1px solid #262626; border-radius: 14px; padding: 16px; font-size: 14px; } .status-card strong { display: block; margin-bottom: 8px; } .status-card p { margin: 0; color: #b7e236; font-weight: 700; } .dot { width: 8px; height: 8px; border-radius: 999px; display: inline-block; margin-right: 8px; } .dot.online { background: #22c55e; box-shadow: 0 0 12px rgba(34, 197, 94, 0.7); } .dot.degraded { background: #f59e0b; box-shadow: 0 0 12px rgba(245, 158, 11, 0.7); } .dot.offline { background: #ef4444; box-shadow: 0 0 12px rgba(239, 68, 68, 0.7); } .dot.checking { background: #64748b; } /* MAIN */ .content { flex: 1; height: 100vh; padding: 30px; overflow-y: auto; overflow-x: hidden; } .page-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 24px; } .page-header h1 { margin: 0; font-size: 26px; line-height: 1.1; color: #111827; } .page-header p { margin: 6px 0 0; color: #6b7280; font-size: 14px; } .health, .primary, .secondary { border: 0; border-radius: 9px; padding: 11px 18px; font-weight: 800; font-size: 14px; } .health { background: white; color: #111827; box-shadow: 0 5px 18px rgba(0, 0, 0, 0.06); } .health::before { content: ""; width: 8px; height: 8px; background: #b7e236; display: inline-block; border-radius: 50%; margin-right: 9px; } .primary { background: #b7e236; color: #0d0d0d; min-height: 42px; } .primary, .secondary, .health { display: inline-flex; align-items: center; justify-content: center; gap: 8px; } .secondary { background: #f3f4f6; color: #374151; } .primary:disabled { opacity: 0.6; cursor: not-allowed; } /* CARDS */ .cards { display: grid; grid-template-columns: repeat(4, 1fr); gap: 18px; margin-bottom: 18px; } .metric-card, .panel { background: white; border-radius: 14px; padding: 20px; border: 1px solid #eceff3; box-shadow: 0 8px 28px rgba(15, 23, 42, 0.06); } .metric-card { min-height: 118px; } .metric-card span { color: #6b7280; font-size: 13px; font-weight: 700; } .metric-card strong { display: block; font-size: 34px; margin-top: 10px; color: #111827; } /* TABLE */ /* TABLE */ .panel { background: white; border: 1px solid #edf1f7; border-radius: 24px; overflow: hidden; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.04), 0 2px 6px rgba(15, 23, 42, 0.03); } table { width: 100%; border-collapse: separate; border-spacing: 0 10px; padding: 0 14px 14px; } thead th { text-align: left; padding: 0 18px 12px; border: none; color: #94a3b8; font-size: 12px; font-weight: 800; background: transparent; } tbody tr { background: #fbfcfe; transition: transform 0.15s ease, box-shadow 0.15s ease, background 0.15s ease; } tbody tr:hover { background: #ffffff; transform: translateY(-1px); box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06), 0 2px 8px rgba(15, 23, 42, 0.04); } tbody td { padding: 18px; border-top: 1px solid #edf1f7; border-bottom: 1px solid #edf1f7; background: inherit; font-size: 14px; font-weight: 600; color: #374151; } tbody td:first-child { border-left: 1px solid #edf1f7; border-top-left-radius: 16px; border-bottom-left-radius: 16px; } tbody td:last-child { border-right: 1px solid #edf1f7; border-top-right-radius: 16px; border-bottom-right-radius: 16px; } .badge { padding: 7px 12px; border-radius: 999px; font-size: 12px; font-weight: 800; border: none; display: inline-flex; align-items: center; gap: 6px; } .badge::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: currentColor; } .badge.provisioned, .badge.active, .badge.online, .badge.success { color: #16a34a; background: #dcfce7; } .badge.pending, .badge.inactive, .badge.warning { color: #ca8a04; background: #fef9c3; } .badge.failed, .badge.offline { color: #dc2626; background: #fee2e2; } .badge.removed { color: #6b7280; background: #f3f4f6; } /* ERROR */ .error-banner { background: #fee2e2; color: #991b1b; padding: 12px 16px; border-radius: 12px; margin-bottom: 18px; font-weight: 800; } /* MODAL */ .modal-backdrop { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.55); display: grid; place-items: center; z-index: 50; } .modal { width: 760px; max-width: calc(100vw - 48px); background: #f7f8fa; border-radius: 18px; padding: 22px; box-shadow: 0 25px 80px rgba(0, 0, 0, 0.35); } .modal-header { display: flex; justify-content: space-between; gap: 16px; margin-bottom: 18px; } .modal-header h2 { margin: 0; color: #111827; } .modal-header p { margin: 5px 0 0; color: #6b7280; font-size: 14px; } .icon-button { border: 0; background: white; border-radius: 10px; width: 36px; height: 36px; display: grid; place-items: center; } .router-form { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; } .router-form label { background: white; border: 1px solid #eceff3; border-radius: 14px; padding: 14px; display: grid; gap: 8px; font-size: 13px; font-weight: 800; color: #374151; } .router-form input { height: 40px; border: 1px solid #dfe3e8; border-radius: 8px; padding: 0 12px; background: #fbfbfc; color: #111827; } .router-form input:focus { outline: 2px solid rgba(93, 168, 255, 0.25); border-color: #5da8ff; } .modal-actions { grid-column: 1 / -1; display: flex; justify-content: flex-end; gap: 12px; margin-top: 4px; } /* RESPONSIVE */ @media (max-width: 1000px) { .cards { grid-template-columns: repeat(2, 1fr); } .router-form { grid-template-columns: 1fr; } } .custom-select { position: relative; } .custom-select-button { width: 100%; height: 46px; border: 1px solid #edf1f7; border-radius: 16px; padding: 0 14px; background: #f8fafc; color: #111827; display: flex; align-items: center; justify-content: space-between; font-weight: 700; transition: all 0.15s ease; } .custom-select-button:hover { background: white; } .custom-select-menu { position: absolute; z-index: 9999; top: calc(100% + 6px); left: 0; right: 0; max-height: 220px; overflow-y: auto; background: white; border: 1px solid #e5e7eb; border-radius: 12px; box-shadow: 0 18px 50px rgba(15, 23, 42, 0.18); padding: 6px; } .custom-select-option { width: 100%; border: 0; background: transparent; color: #111827; text-align: left; padding: 9px 10px; border-radius: 8px; font-weight: 700; } .custom-select-option:hover { background: #eef6ff; } .table-action { width: 34px; height: 34px; border: 0; border-radius: 10px; display: grid; place-items: center; background: #f3f4f6; color: #374151; } .table-action.danger { color: #dc2626; } .table-action.danger:hover { background: #fee2e2; } .confirm-dialog { width: 430px; background: white; border-radius: 18px; padding: 24px; box-shadow: 0 25px 80px rgba(0, 0, 0, 0.28); } .confirm-dialog h2 { margin: 0; color: #111827; } .confirm-dialog p { margin: 10px 0 22px; color: #6b7280; line-height: 1.5; } .danger-button { border: 0; border-radius: 9px; padding: 11px 18px; font-weight: 800; font-size: 14px; background: #ef4444; color: white; } .danger-button:hover { background: #dc2626; } .panel-empty { padding: 22px; margin: 0; color: #6b7280; font-weight: 700; } .table-actions { display: flex; align-items: center; gap: 8px; } .small-action { height: 36px; border: 1px solid #edf1f7; border-radius: 12px; padding: 0 13px; display: inline-flex; align-items: center; gap: 7px; background: white; color: #374151; font-weight: 800; font-size: 13px; transition: all 0.15s ease; } .small-action:hover { transform: translateY(-1px); background: #f8fafc; } .primary-action { background: #b7e236; color: #0d0d0d; } .table-action.warning { color: #ca8a04; } .table-action.warning:hover { background: #fef9c3; } .table-action:disabled, .small-action:disabled { opacity: 0.55; cursor: not-allowed; } .warning-action { color: #ca8a04; background: #fef9c3; } .deployment-modal { width: 720px; max-width: calc(100vw - 48px); background: white; border-radius: 18px; padding: 24px; box-shadow: 0 25px 80px rgba(0, 0, 0, 0.3); } .deployment-summary { display: flex; justify-content: space-between; align-items: center; background: #f8fafc; border: 1px solid #e5e7eb; border-radius: 14px; padding: 14px; margin-bottom: 16px; font-weight: 800; color: #64748b; } .deployment-status { display: flex; align-items: center; gap: 10px; } .log-box { background: #050505; border-radius: 14px; padding: 16px; min-height: 220px; max-height: 360px; overflow: auto; } .log-box pre { margin: 0; color: #b7e236; font-size: 13px; line-height: 1.5; white-space: pre-wrap; font-family: "JetBrains Mono", Consolas, monospace; } .table-toolbar { display: flex; justify-content: space-between; gap: 14px; padding: 18px; background: white; position: relative; z-index: 20; } .search-box { height: 46px; min-width: 320px; display: flex; align-items: center; gap: 10px; background: #f8fafc; border: 1px solid #edf1f7; border-radius: 16px; padding: 0 14px; color: #64748b; transition: all 0.15s ease; } .search-box:focus-within { background: white; border-color: #dbe5f0; box-shadow: 0 0 0 4px rgba(93, 168, 255, 0.08); } .search-box input { width: 100%; border: 0; outline: 0; background: transparent; color: #111827; font-weight: 700; } .toolbar-select { width: 200px; } .toolbar-select .custom-select-button { height: 40px; } .chevron { color: #64748b; transition: transform 0.2s ease; flex-shrink: 0; } .chevron.open { transform: rotate(180deg); } td .small-action { white-space: nowrap; } .page-stack { display: grid; gap: 24px; } .toolbar-filters { display: flex; align-items: center; gap: 12px; } .dashboard-page { display: flex; flex-direction: column; gap: 22px; } .page-header { display: flex; align-items: center; justify-content: space-between; } .page-header h1 { margin: 0; font-size: 28px; } .page-header p { margin: 6px 0 0; color: #64748b; } .system-pill { display: inline-flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 999px; background: white; border: 1px solid #e5e7eb; font-weight: 700; font-size: 13px; } .metric-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; } .metric-card { display: flex; gap: 16px; align-items: center; padding: 22px; border-radius: 18px; background: white; border: 1px solid #e5e7eb; box-shadow: 0 12px 30px rgba(15, 23, 42, 0.06); } .metric-icon { width: 48px; height: 48px; border-radius: 16px; display: grid; place-items: center; background: #5da8ff; color: white; } .metric-card p { margin: 0; color: #64748b; font-size: 13px; font-weight: 700; } .metric-card strong { display: block; margin-top: 4px; font-size: 30px; } .metric-card span { color: #94a3b8; font-size: 12px; } .dashboard-grid { display: grid; grid-template-columns: 2fr 1fr; gap: 16px; } .dashboard-card { background: white; border: 1px solid #e5e7eb; border-radius: 18px; padding: 20px; box-shadow: 0 12px 30px rgba(15, 23, 42, 0.06); } .dashboard-card.wide { min-height: 260px; } .card-header { display: flex; justify-content: space-between; margin-bottom: 18px; } .card-header h2 { margin: 0; font-size: 17px; } .card-header p { margin: 5px 0 0; color: #64748b; font-size: 13px; } .activity-chart-placeholder { height: 190px; border-radius: 16px; border: 1px dashed #cbd5e1; background: linear-gradient(180deg, #f8fbff, #ffffff); display: grid; place-items: center; color: #64748b; gap: 8px; } .health-stack { display: flex; flex-direction: column; gap: 14px; } .health-row { display: flex; align-items: center; justify-content: space-between; padding: 14px; border-radius: 14px; background: #f8fafc; } .health-row div { display: flex; align-items: center; font-weight: 700; gap: 8px; } .health-row strong { font-size: 13px; } .dashboard-table { width: 100%; border-collapse: collapse; } .dashboard-table th, .dashboard-table td { padding: 14px 10px; text-align: left; border-bottom: 1px solid #eef2f7; font-size: 13px; } .dashboard-table th { color: #64748b; font-weight: 800; } .table-status { display: inline-flex; align-items: center; gap: 6px; font-weight: 800; } .table-status.success { color: #16a34a; } .table-status.failed { color: #ef4444; } .empty-cell { color: #94a3b8; text-align: center !important; } .quick-actions { display: flex; flex-direction: column; gap: 10px; } .quick-actions button { border: 1px solid #e5e7eb; background: #f8fafc; border-radius: 12px; padding: 12px 14px; font-weight: 800; cursor: pointer; text-align: left; } .quick-actions button:hover { background: #eef6ff; } .activity-chart { width: 100%; height: 220px; } .vps-hero-card { background: white; border: 1px solid #edf1f7; border-radius: 24px; padding: 24px; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.04), 0 2px 6px rgba(15, 23, 42, 0.03); display: grid; gap: 24px; } .vps-hero-main { display: flex; align-items: center; gap: 18px; } .vps-server-icon { width: 64px; height: 64px; border-radius: 20px; display: grid; place-items: center; background: #f3f4f6; color: #64748b; } .vps-server-icon.online { background: #dcfce7; color: #16a34a; } .vps-server-icon.degraded { background: #fef9c3; color: #ca8a04; } .vps-server-icon.offline { background: #fee2e2; color: #dc2626; } .vps-server-icon.checking { background: #e5e7eb; color: #64748b; } .vps-title-row { display: flex; align-items: center; gap: 12px; } .vps-title-row h2 { margin: 0; font-size: 22px; } .vps-hero-main p { margin: 6px 0 0; color: #64748b; } .vps-health-summary { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; } .health-mini-card { display: flex; align-items: center; gap: 12px; background: #f8fafc; border: 1px solid #edf1f7; border-radius: 18px; padding: 16px; } .health-mini-icon { width: 38px; height: 38px; border-radius: 14px; display: grid; place-items: center; background: #e5e7eb; color: #64748b; } .health-mini-icon.online { background: #dcfce7; color: #16a34a; } .health-mini-icon.degraded { background: #fef9c3; color: #ca8a04; } .health-mini-icon.offline { background: #fee2e2; color: #dc2626; } .health-mini-icon.checking { background: #e5e7eb; color: #64748b; } .health-mini-card span { display: block; color: #64748b; font-size: 12px; font-weight: 700; } .health-mini-card strong { display: block; margin-top: 3px; color: #111827; font-size: 14px; } .vps-grid { display: grid; grid-template-columns: 1.3fr 1fr; gap: 16px; } .wide-panel { min-height: auto; } .service-check-list { display: grid; gap: 12px; } .service-check { display: flex; gap: 12px; align-items: flex-start; background: #f8fafc; border: 1px solid #edf1f7; border-radius: 16px; padding: 14px; } .service-check-icon { width: 34px; height: 34px; border-radius: 12px; display: grid; place-items: center; background: #e5e7eb; color: #64748b; flex-shrink: 0; } .service-check-icon.online { background: #dcfce7; color: #16a34a; } .service-check-icon.degraded { background: #fef9c3; color: #ca8a04; } .service-check-icon.offline { background: #fee2e2; color: #dc2626; } .service-check-icon.checking { background: #e5e7eb; color: #64748b; } .service-check strong { display: block; color: #111827; } .service-check span { display: block; margin-top: 3px; color: #64748b; font-size: 13px; } .detail-list { display: grid; gap: 10px; } .detail-row { display: flex; justify-content: space-between; gap: 12px; padding: 13px 0; border-bottom: 1px solid #edf1f7; } .detail-row:last-child { border-bottom: 0; } .detail-row span { color: #64748b; font-weight: 700; } .detail-row strong { color: #111827; } .vps-actions-grid { display: grid; gap: 12px; } .vps-action-card { width: 100%; border: 1px solid #edf1f7; background: #f8fafc; border-radius: 16px; padding: 16px; display: flex; align-items: flex-start; gap: 12px; text-align: left; transition: all 0.15s ease; } .vps-action-card:hover:not(:disabled) { background: white; transform: translateY(-1px); box-shadow: 0 8px 24px rgba(15, 23, 42, 0.06), 0 2px 8px rgba(15, 23, 42, 0.04); } .vps-action-card:disabled { opacity: 0.55; cursor: not-allowed; } .vps-action-card strong { display: block; color: #111827; } .vps-action-card span { display: block; margin-top: 4px; color: #64748b; font-size: 13px; } .status-note { display: flex; gap: 12px; align-items: flex-start; background: #f8fafc; border: 1px solid #edf1f7; border-radius: 16px; padding: 16px; color: #64748b; line-height: 1.5; } .status-note p { margin: 0; } .settings-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; } .settings-card { background: white; border: 1px solid #edf1f7; border-radius: 24px; padding: 22px; box-shadow: 0 10px 30px rgba(15, 23, 42, 0.04), 0 2px 6px rgba(15, 23, 42, 0.03); } .settings-card-header { display: flex; align-items: flex-start; gap: 14px; margin-bottom: 20px; } .settings-card-icon { width: 44px; height: 44px; border-radius: 16px; display: grid; place-items: center; background: #eef6ff; color: #5da8ff; flex-shrink: 0; } .settings-card h2 { margin: 0; font-size: 18px; color: #111827; } .settings-card p { margin: 5px 0 0; color: #64748b; font-size: 13px; } .settings-list { display: grid; gap: 10px; } .setting-row { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 13px 0; border-bottom: 1px solid #edf1f7; } .setting-row:last-child { border-bottom: 0; } .setting-row span { color: #64748b; font-weight: 700; font-size: 14px; } .setting-row strong { display: inline-flex; align-items: center; color: #111827; font-size: 14px; font-weight: 800; text-align: right; } .settings-actions { display: flex; gap: 10px; padding-top: 10px; } .settings-actions button { border: 1px solid #edf1f7; background: #f8fafc; border-radius: 14px; padding: 10px 13px; display: inline-flex; align-items: center; gap: 8px; font-weight: 800; color: #374151; transition: all 0.15s ease; } .settings-actions button:hover { background: white; transform: translateY(-1px); } .openwrt-form { display: grid; grid-template-columns: 1fr 1fr 1fr auto; align-items: end; gap: 14px; } .openwrt-form label { display: grid; gap: 8px; color: #374151; font-size: 13px; font-weight: 800; } .openwrt-form input { height: 44px; border: 1px solid #edf1f7; border-radius: 14px; padding: 0 14px; background: #f8fafc; color: #111827; font-weight: 700; } .openwrt-form input:focus { outline: 0; background: white; border-color: #5da8ff; box-shadow: 0 0 0 4px rgba(93, 168, 255, 0.1); } .openwrt-grid { display: grid; gap: 24px; } .openwrt-grid .dashboard-card { padding: 26px; border-radius: 24px; } .openwrt-grid .card-header { margin-bottom: 22px; }