diff --git a/cmd/repeater/static/index.html b/cmd/repeater/static/index.html index d53a645..9ded9ad 100644 --- a/cmd/repeater/static/index.html +++ b/cmd/repeater/static/index.html @@ -3,23 +3,27 @@ - Travel Router Control Panel + Travel Router + + +
-
+
-

- - - - Travel Router Control -

+
+
+
+

Travel Router

+

Control Panel

+
+
- Déconnecté + Disconnected
@@ -27,114 +31,63 @@
-
+
-
- - - -
-
-
0
-
Appareils connectés
-
+
Appareils
+
0
-
- - - -
-
-
0 MB
-
Données utilisées
-
+
Données
+
0 MB
-
- - - -
-
-
00:00:00
-
Temps de fonctionnement
-
+
Uptime
+
00:00:00
-
- - - -
-
-
-
-
Réseau actuel
-
+
Réseau
+
-

- - - - Connexion WiFi Upstream -

-
- +
- Chargement des réseaux... + Chargement des réseaux...
- - + +
-

- - - - Hotspot Status -

+

Hotspot

@@ -143,7 +96,7 @@
- État: + État Chargement...
@@ -153,52 +106,32 @@
-

- - - - Appareils connectés -

+

Appareils connectés

0
- - - -

Aucun appareil connecté

+

Aucun appareil connecté

-

- - - - Logs système -

+

Logs

-
- - -

Aucun log disponible

@@ -214,9 +147,7 @@
diff --git a/cmd/repeater/static/style.css b/cmd/repeater/static/style.css index b518696..9b12b92 100644 --- a/cmd/repeater/static/style.css +++ b/cmd/repeater/static/style.css @@ -1,55 +1,56 @@ -/* CSS Variables for theming */ +/* ======================================== + Travel Router — Minimal Control Panel + ======================================== */ + :root { - --primary-gradient: linear-gradient(135deg, #667eea 0%, #764ba2 100%); - --secondary-gradient: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); - --success-color: #10b981; - --danger-color: #ef4444; - --warning-color: #f59e0b; - --info-color: #3b82f6; - --background: #f3f4f6; - --card-background: #ffffff; - --text-primary: #1f2937; - --text-secondary: #6b7280; - --border-color: #e5e7eb; - --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05); - --shadow-md: 0 4px 6px -1px rgba(0, 0, 0, 0.1); - --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1); - --shadow-xl: 0 20px 25px -5px rgba(0, 0, 0, 0.1); - --radius-sm: 0.375rem; - --radius-md: 0.5rem; - --radius-lg: 0.75rem; - --radius-xl: 1rem; + --accent: #d95030; + --accent-soft: #d9503018; + --green: #2a9d6a; + --green-soft: #2a9d6a14; + --amber: #c48820; + --amber-soft: #c4882014; + --red: #c23b22; + --red-soft: #c23b2214; + --blue: #3678c2; + + --bg: #f7f6f3; + --surface: #ffffff; + --border: #e8e6e1; + --border-light: #f0eeea; + --text: #1a1a1a; + --text-secondary: #888580; + --text-tertiary: #b0ada8; + + --radius: 10px; + --radius-sm: 6px; + --font: 'DM Sans', system-ui, sans-serif; + --font-display: 'Outfit', system-ui, sans-serif; } -* { +*, *::before, *::after { margin: 0; padding: 0; box-sizing: border-box; } body { - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif; - background: var(--primary-gradient); + font-family: var(--font); + background: var(--bg); + color: var(--text); min-height: 100vh; - padding: 1.5rem; - color: var(--text-primary); + padding: 2rem; + -webkit-font-smoothing: antialiased; } .container { - max-width: 1400px; + max-width: 1200px; margin: 0 auto; - background: rgba(255, 255, 255, 0.98); - backdrop-filter: blur(20px); - border-radius: var(--radius-xl); - padding: 2rem; - box-shadow: var(--shadow-xl); } -/* Header Styles */ +/* ---- Header ---- */ + .header { - margin-bottom: 2rem; - padding-bottom: 1.5rem; - border-bottom: 2px solid var(--border-color); + margin-bottom: 2.5rem; } .header-content { @@ -57,25 +58,41 @@ body { justify-content: space-between; align-items: center; flex-wrap: wrap; - gap: 1rem; + gap: 1.25rem; +} + +.header-left { + display: flex; + align-items: center; + gap: 0.875rem; +} + +.logo-mark { + width: 36px; + height: 36px; + border-radius: 10px; + background: var(--accent); + flex-shrink: 0; } .header h1 { - color: var(--text-primary); - font-size: 2rem; - font-weight: 700; - display: flex; - align-items: center; - gap: 0.75rem; + font-family: var(--font-display); + font-size: 1.5rem; + font-weight: 600; + letter-spacing: -0.025em; + line-height: 1.1; } -.logo-icon { - color: #667eea; +.header-subtitle { + font-size: 0.8125rem; + color: var(--text-secondary); + font-weight: 400; + margin-top: 0.125rem; } .connection-info { display: flex; - gap: 1rem; + gap: 0.625rem; flex-wrap: wrap; } @@ -83,43 +100,35 @@ body { display: inline-flex; align-items: center; gap: 0.5rem; - padding: 0.5rem 1rem; - border-radius: 9999px; - font-size: 0.875rem; - font-weight: 500; - background: var(--background); - border: 1px solid var(--border-color); + padding: 0.4rem 0.875rem; + border-radius: 100px; + font-size: 0.8125rem; + font-weight: 450; + background: var(--surface); + border: 1px solid var(--border); + color: var(--text-secondary); } .status-dot { - width: 0.625rem; - height: 0.625rem; + width: 7px; + height: 7px; border-radius: 50%; - animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite; + flex-shrink: 0; } .status-dot.active { - background: var(--success-color); + background: var(--green); + box-shadow: 0 0 0 3px var(--green-soft); } .status-dot.offline { - background: var(--text-secondary); - animation: none; -} - -.status-dot.connecting { - background: var(--warning-color); - animation: blink 1s ease-in-out infinite; + background: var(--text-tertiary); } +.status-dot.connecting, .status-dot.disconnecting { - background: var(--warning-color); - animation: blink 1s ease-in-out infinite; -} - -@keyframes pulse { - 0%, 100% { opacity: 1; } - 50% { opacity: 0.5; } + background: var(--amber); + animation: blink 1.2s ease-in-out infinite; } @keyframes blink { @@ -127,239 +136,221 @@ body { 50% { opacity: 0.3; } } -/* Stats Grid */ +@keyframes pulse { + 0%, 100% { opacity: 1; } + 50% { opacity: 0.5; } +} + +/* ---- Stats ---- */ + .stats-grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); - gap: 1.5rem; - margin-bottom: 2rem; + grid-template-columns: repeat(4, 1fr); + gap: 1px; + background: var(--border); + border: 1px solid var(--border); + border-radius: var(--radius); + overflow: hidden; + margin-bottom: 1.5rem; } .stat-card { - background: var(--card-background); - border-radius: var(--radius-lg); - padding: 1.5rem; - box-shadow: var(--shadow-md); - border: 1px solid var(--border-color); - display: flex; - gap: 1rem; - align-items: center; - transition: all 0.3s ease; - max-width: 100%; + background: var(--surface); + padding: 1.25rem 1.5rem; + transition: background 0.2s; } .stat-card:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-lg); + background: #fdfcfa; } -.stat-icon { - width: 3rem; - height: 3rem; - border-radius: var(--radius-md); - background: var(--primary-gradient); - display: flex; - align-items: center; - justify-content: center; - flex-shrink: 0; -} - -.stat-icon svg { - color: white; -} - -.stat-content { - flex: 1; - min-width: 0; +.stat-label { + font-size: 0.6875rem; + text-transform: uppercase; + letter-spacing: 0.08em; + color: var(--text-tertiary); + font-weight: 500; + margin-bottom: 0.375rem; } .stat-value { - font-size: 1.875rem; - font-weight: 700; - color: var(--text-primary); - line-height: 1; - margin-bottom: 0.25rem; + font-family: var(--font-display); + font-size: 1.5rem; + font-weight: 600; + letter-spacing: -0.02em; + color: var(--text); + line-height: 1.2; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } -.stat-label { - font-size: 0.875rem; - color: var(--text-secondary); - font-weight: 500; +.stat-value.mono { + font-variant-numeric: tabular-nums; } -/* Grid Layout */ +/* ---- Grid / Cards ---- */ + .grid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(450px, 1fr)); + grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); gap: 1.5rem; margin-bottom: 1.5rem; } -/* Card Styles */ .card { - background: var(--card-background); - border-radius: var(--radius-lg); + background: var(--surface); + border: 1px solid var(--border); + border-radius: var(--radius); padding: 1.5rem; - box-shadow: var(--shadow-md); - border: 1px solid var(--border-color); - transition: all 0.3s ease; -} - -.card:hover { - box-shadow: var(--shadow-lg); } .card-header { display: flex; justify-content: space-between; align-items: center; - margin-bottom: 1.5rem; - padding-bottom: 1rem; - border-bottom: 1px solid var(--border-color); -} - -.card-header h2 { - color: var(--text-primary); - font-size: 1.25rem; - font-weight: 600; - display: flex; - align-items: center; - gap: 0.5rem; - margin: 0; -} - -.icon { - color: #667eea; -} - -/* Form Elements */ -.form-group { margin-bottom: 1.25rem; } -.form-group label { +.card-header h2 { + font-family: var(--font-display); + font-size: 1rem; + font-weight: 600; + letter-spacing: -0.01em; display: flex; align-items: center; gap: 0.5rem; - margin-bottom: 0.5rem; - color: var(--text-primary); - font-weight: 500; - font-size: 0.875rem; } -.input-icon { +.icon { color: var(--text-secondary); } + +/* ---- Forms ---- */ + +.form-group { + margin-bottom: 1rem; +} + +.form-group label { + display: block; + margin-bottom: 0.375rem; color: var(--text-secondary); + font-weight: 500; + font-size: 0.8125rem; } .form-group input, .form-group select { width: 100%; - padding: 0.75rem 1rem; - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - font-size: 0.9375rem; - transition: all 0.2s ease; - background: var(--card-background); - color: var(--text-primary); + padding: 0.625rem 0.875rem; + border: 1px solid var(--border); + border-radius: var(--radius-sm); + font-size: 0.875rem; + font-family: var(--font); + background: var(--bg); + color: var(--text); + transition: border-color 0.15s, box-shadow 0.15s; + outline: none; } .form-group input:focus, .form-group select:focus { - outline: none; - border-color: #667eea; - box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1); + border-color: var(--accent); + box-shadow: 0 0 0 3px var(--accent-soft); } -/* Buttons */ +.form-group input::placeholder { + color: var(--text-tertiary); +} + +/* ---- Buttons ---- */ + .btn { display: inline-flex; align-items: center; justify-content: center; - gap: 0.5rem; - padding: 0.75rem 1.5rem; + gap: 0.375rem; + padding: 0.6rem 1.25rem; border: none; - border-radius: var(--radius-md); - font-size: 0.9375rem; + border-radius: var(--radius-sm); + font-size: 0.8125rem; font-weight: 500; + font-family: var(--font); cursor: pointer; - transition: all 0.2s ease; + transition: all 0.15s; width: 100%; - color: white; } -.btn svg { - flex-shrink: 0; -} +.btn svg { flex-shrink: 0; } .btn-primary { - background: var(--primary-gradient); + background: var(--text); + color: #fff; } .btn-primary:hover { - transform: translateY(-1px); - box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3); + background: #333; } .btn-secondary { - background: var(--text-secondary); + background: var(--bg); + color: var(--text-secondary); + border: 1px solid var(--border); } .btn-secondary:hover { - background: #4b5563; - transform: translateY(-1px); + background: var(--border-light); + color: var(--text); } .btn-danger { - background: var(--danger-color); + background: var(--red); + color: #fff; } .btn-danger:hover { - background: #dc2626; - transform: translateY(-1px); + opacity: 0.9; } .btn:active { - transform: translateY(0); + transform: scale(0.98); } .btn:disabled { - opacity: 0.5; + opacity: 0.4; cursor: not-allowed; + transform: none; } .btn-icon { background: transparent; border: none; - padding: 0.5rem; + padding: 0.375rem; border-radius: var(--radius-sm); cursor: pointer; - color: var(--text-secondary); - transition: all 0.2s ease; + color: var(--text-tertiary); + transition: all 0.15s; display: inline-flex; align-items: center; justify-content: center; } .btn-icon:hover { - background: var(--background); - color: var(--text-primary); + background: var(--bg); + color: var(--text); } .button-group { display: grid; grid-template-columns: 1fr 1fr; - gap: 0.75rem; + gap: 0.5rem; } -/* Toggle Switch */ +/* ---- Toggle ---- */ + .toggle-switch { position: relative; - display: inline-block; - width: 50px; - height: 26px; + width: 40px; + height: 22px; } .toggle-switch input { @@ -371,57 +362,54 @@ body { .toggle-switch label { position: absolute; cursor: pointer; - top: 0; - left: 0; - right: 0; - bottom: 0; - background-color: var(--text-secondary); - transition: 0.3s; - border-radius: 34px; + inset: 0; + background: var(--border); + transition: 0.2s; + border-radius: 100px; } .toggle-switch label:before { - position: absolute; content: ""; - height: 20px; - width: 20px; + position: absolute; + height: 16px; + width: 16px; left: 3px; bottom: 3px; - background-color: white; - transition: 0.3s; + background: #fff; + transition: 0.2s; border-radius: 50%; } .toggle-switch input:checked + label { - background: var(--success-color); + background: var(--green); } .toggle-switch input:checked + label:before { - transform: translateX(24px); + transform: translateX(18px); } -/* WiFi List */ +/* ---- WiFi List ---- */ + .wifi-list { - max-height: 320px; + max-height: 280px; overflow-y: auto; - border: 1px solid var(--border-color); - border-radius: var(--radius-md); - background: var(--background); + border: 1px solid var(--border); + border-radius: var(--radius-sm); } .wifi-item { - padding: 1rem; - border-bottom: 1px solid var(--border-color); + padding: 0.75rem 1rem; + border-bottom: 1px solid var(--border-light); cursor: pointer; - transition: all 0.2s ease; + transition: background 0.12s; display: flex; justify-content: space-between; align-items: center; - background: var(--card-background); + font-size: 0.875rem; } .wifi-item:hover { - background: var(--background); + background: var(--bg); } .wifi-item:last-child { @@ -429,87 +417,90 @@ body { } .wifi-item.selected { - background: #eff6ff; - border-left: 4px solid #667eea; + background: var(--accent-soft); + border-left: 3px solid var(--accent); } .wifi-item.connected { - background: #d1fae5; - border-left-color: var(--success-color) !important; + background: var(--green-soft); + border-left: 3px solid var(--green); } .wifi-item.connected .wifi-ssid { - color: var(--success-color); - font-weight: 700; + color: var(--green); + font-weight: 600; } .wifi-item.connecting { - background: #fef3c7; - border-left-color: var(--warning-color) !important; + background: var(--amber-soft); + border-left: 3px solid var(--amber); animation: pulse-item 1.5s ease-in-out infinite; } .wifi-item.connecting .wifi-ssid { - color: var(--warning-color); - font-weight: 700; + color: var(--amber); + font-weight: 600; } .wifi-item.disconnecting { - background: #fee2e2; - border-left-color: #dc2626 !important; + background: var(--red-soft); + border-left: 3px solid var(--red); animation: pulse-item 1.5s ease-in-out infinite; } .wifi-item.disconnecting .wifi-ssid { - color: #dc2626; - font-weight: 700; + color: var(--red); + font-weight: 600; } @keyframes pulse-item { 0%, 100% { opacity: 1; } - 50% { opacity: 0.7; } + 50% { opacity: 0.6; } } .wifi-item.loading { justify-content: center; - color: var(--text-secondary); + color: var(--text-tertiary); cursor: default; + padding: 1.5rem; } -.wifi-info { - flex: 1; -} +.wifi-info { flex: 1; min-width: 0; } .wifi-ssid { - font-weight: 600; - color: var(--text-primary); - margin-bottom: 0.25rem; + font-weight: 500; + color: var(--text); + margin-bottom: 0.125rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .wifi-details { - font-size: 0.8125rem; - color: var(--text-secondary); + font-size: 0.75rem; + color: var(--text-tertiary); display: flex; - gap: 1rem; + gap: 0.75rem; } .wifi-signal { display: flex; align-items: center; - gap: 0.5rem; + gap: 0.375rem; + flex-shrink: 0; } .signal-bars { display: flex; gap: 2px; align-items: flex-end; - height: 16px; + height: 14px; } .signal-bar { width: 3px; - background: var(--border-color); - border-radius: 2px; + background: var(--border); + border-radius: 1px; } .signal-bar:nth-child(1) { height: 25%; } @@ -518,221 +509,234 @@ body { .signal-bar:nth-child(4) { height: 100%; } .signal-bar.active { - background: var(--success-color); + background: var(--green); } -/* Devices */ +/* ---- Devices ---- */ + .devices-grid { display: grid; - grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); - gap: 1rem; - min-height: 200px; + grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); + gap: 0.75rem; + min-height: 120px; } .device-card { - background: var(--background); - border-radius: var(--radius-md); - padding: 1.25rem; + background: var(--bg); + border-radius: var(--radius-sm); + padding: 1rem; text-align: center; - border: 1px solid var(--border-color); - transition: all 0.2s ease; + border: 1px solid transparent; + transition: border-color 0.15s; } .device-card:hover { - transform: translateY(-2px); - box-shadow: var(--shadow-md); + border-color: var(--border); } .device-icon { - width: 48px; - height: 48px; - margin: 0 auto 0.75rem; - color: #667eea; + width: 32px; + height: 32px; + margin: 0 auto 0.5rem; + color: var(--text-secondary); } .device-name { - font-weight: 600; - color: var(--text-primary); - margin-bottom: 0.25rem; - font-size: 0.9375rem; + font-weight: 500; + color: var(--text); + font-size: 0.8125rem; + margin-bottom: 0.125rem; } .device-type { - font-size: 0.75rem; - color: var(--text-secondary); + font-size: 0.6875rem; + color: var(--text-tertiary); text-transform: uppercase; - letter-spacing: 0.05em; - margin-bottom: 0.5rem; + letter-spacing: 0.06em; + margin-bottom: 0.375rem; } .device-info { - font-size: 0.8125rem; + font-size: 0.75rem; color: var(--text-secondary); + font-variant-numeric: tabular-nums; } .device-placeholder { grid-column: 1 / -1; text-align: center; - padding: 3rem 1rem; - color: var(--text-secondary); -} - -.device-placeholder svg { - margin-bottom: 1rem; + padding: 2.5rem 1rem; + color: var(--text-tertiary); + font-size: 0.875rem; } .device-count { - background: var(--primary-gradient); - color: white; - padding: 0.25rem 0.75rem; - border-radius: 9999px; - font-size: 0.875rem; + background: var(--bg); + color: var(--text-secondary); + padding: 0.2rem 0.625rem; + border-radius: 100px; + font-size: 0.75rem; font-weight: 600; + border: 1px solid var(--border); + font-variant-numeric: tabular-nums; } -/* Logs */ +/* ---- Logs ---- */ + .log-container { - background: #1f2937; - color: #10b981; + background: #1c1c1e; + color: #a8a8a8; padding: 1rem; - border-radius: var(--radius-md); - font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Fira Mono', 'Consolas', 'Courier New', monospace; - font-size: 0.8125rem; - max-height: 400px; + border-radius: var(--radius-sm); + font-family: 'SF Mono', 'Cascadia Code', 'Fira Code', 'Consolas', monospace; + font-size: 0.75rem; + max-height: 360px; overflow-y: auto; - line-height: 1.6; - min-height: 200px; + line-height: 1.7; + min-height: 160px; } .log-entry { - margin-bottom: 0.5rem; + margin-bottom: 0.25rem; display: flex; - gap: 0.75rem; + gap: 0.625rem; } .log-timestamp { - color: #6b7280; + color: #555; flex-shrink: 0; } .log-source { - color: #3b82f6; - font-weight: 600; + color: var(--accent); + font-weight: 500; flex-shrink: 0; - min-width: 80px; + min-width: 72px; } .log-message { - color: #d1d5db; + color: #c8c8c8; + word-break: break-word; } .log-controls { display: flex; - gap: 0.5rem; + gap: 0.25rem; } .log-placeholder { text-align: center; - padding: 3rem 1rem; - color: #6b7280; + padding: 2.5rem 1rem; + color: #555; + font-size: 0.8125rem; + font-family: var(--font); } -.log-placeholder svg { - margin-bottom: 1rem; +/* ---- Hotspot ---- */ + +.hotspot-details { + background: var(--bg); + border-radius: var(--radius-sm); + border: 1px solid var(--border-light); + overflow: hidden; } -/* Toast Notifications */ +.hotspot-info-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0.625rem 1rem; + border-bottom: 1px solid var(--border-light); +} + +.hotspot-info-item:last-child { + border-bottom: none; +} + +.info-label { + font-size: 0.8125rem; + color: var(--text-secondary); +} + +.info-value { + font-size: 0.8125rem; + font-weight: 500; + color: var(--text); +} + +/* ---- Toast ---- */ + .toast { position: fixed; - top: 1.5rem; + bottom: 1.5rem; right: 1.5rem; - max-width: 400px; - background: white; - border-radius: var(--radius-lg); - box-shadow: var(--shadow-xl); - padding: 1rem; + max-width: 360px; + background: var(--surface); + border-radius: var(--radius); + box-shadow: 0 8px 30px rgba(0,0,0,0.08), 0 1px 3px rgba(0,0,0,0.06); + padding: 0.875rem 1rem; display: flex; - gap: 0.75rem; - align-items: start; - transform: translateX(calc(100% + 2rem)); - transition: transform 0.3s ease; + gap: 0.625rem; + align-items: center; + transform: translateY(calc(100% + 2rem)); + transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1); z-index: 1000; - border: 1px solid var(--border-color); + border: 1px solid var(--border); } .toast.show { - transform: translateX(0); + transform: translateY(0); } .toast-icon { - width: 40px; - height: 40px; - border-radius: var(--radius-md); + width: 28px; + height: 28px; + border-radius: var(--radius-sm); display: flex; align-items: center; justify-content: center; flex-shrink: 0; } -.toast.success .toast-icon { - background: #d1fae5; - color: var(--success-color); -} +.toast.success .toast-icon { background: var(--green-soft); color: var(--green); } +.toast.error .toast-icon { background: var(--red-soft); color: var(--red); } +.toast.warning .toast-icon { background: var(--amber-soft); color: var(--amber); } +.toast.info .toast-icon { background: #3678c218; color: var(--blue); } -.toast.error .toast-icon { - background: #fee2e2; - color: var(--danger-color); -} - -.toast.warning .toast-icon { - background: #fef3c7; - color: var(--warning-color); -} - -.toast.info .toast-icon { - background: #dbeafe; - color: var(--info-color); -} - -.toast-content { - flex: 1; -} +.toast-content { flex: 1; min-width: 0; } .toast-title { - font-weight: 600; - color: var(--text-primary); - margin-bottom: 0.25rem; + font-weight: 500; + font-size: 0.8125rem; + color: var(--text); } .toast-message { - font-size: 0.875rem; + font-size: 0.75rem; color: var(--text-secondary); + margin-top: 0.0625rem; } .toast-close { background: transparent; border: none; - color: var(--text-secondary); + color: var(--text-tertiary); cursor: pointer; padding: 0.25rem; border-radius: var(--radius-sm); display: flex; - align-items: center; - justify-content: center; - transition: all 0.2s ease; + transition: color 0.15s; } -.toast-close:hover { - background: var(--background); - color: var(--text-primary); -} +.toast-close:hover { color: var(--text); } + +/* ---- Loading ---- */ -/* Loading Overlay */ .loading-overlay { position: fixed; inset: 0; - background: rgba(0, 0, 0, 0.5); - backdrop-filter: blur(4px); + background: rgba(247, 246, 243, 0.85); + backdrop-filter: blur(8px); display: none; align-items: center; justify-content: center; @@ -741,32 +745,30 @@ body { gap: 1rem; } -.loading-overlay.show { - display: flex; -} +.loading-overlay.show { display: flex; } .loading-overlay p { - color: white; + color: var(--text-secondary); + font-size: 0.875rem; font-weight: 500; } .spinner { - width: 48px; - height: 48px; - border: 4px solid rgba(255, 255, 255, 0.3); - border-top-color: white; + width: 32px; + height: 32px; + border: 2.5px solid var(--border); + border-top-color: var(--accent); border-radius: 50%; - animation: spin 0.8s linear infinite; + animation: spin 0.7s linear infinite; } -@keyframes spin { - to { transform: rotate(360deg); } -} +@keyframes spin { to { transform: rotate(360deg); } } + +/* ---- Scrollbars ---- */ -/* Scrollbar Styling */ .wifi-list::-webkit-scrollbar, .log-container::-webkit-scrollbar { - width: 8px; + width: 6px; } .wifi-list::-webkit-scrollbar-track, @@ -775,72 +777,23 @@ body { } .wifi-list::-webkit-scrollbar-thumb { - background: var(--border-color); - border-radius: 4px; + background: var(--border); + border-radius: 3px; } .log-container::-webkit-scrollbar-thumb { - background: #374151; - border-radius: 4px; + background: #333; + border-radius: 3px; } -.wifi-list::-webkit-scrollbar-thumb:hover, -.log-container::-webkit-scrollbar-thumb:hover { - background: var(--text-secondary); -} +/* ---- Responsive ---- */ -/* Hotspot Details */ -.hotspot-details { - margin-top: 1.5rem; - padding: 1rem; - background: var(--background); - border-radius: var(--radius-md); - border: 1px solid var(--border-color); -} - -.hotspot-info-item { - display: flex; - justify-content: space-between; - align-items: center; - padding: 0.5rem 0; - border-bottom: 1px solid var(--border-color); -} - -.hotspot-info-item:last-child { - border-bottom: none; -} - -.info-label { - font-weight: 500; - color: var(--text-secondary); - font-size: 0.875rem; -} - -.info-value { - font-weight: 600; - color: var(--text-primary); - font-size: 0.875rem; -} - -/* Responsive Design */ @media (max-width: 1024px) { - .grid { - grid-template-columns: 1fr; - } + .grid { grid-template-columns: 1fr; } } @media (max-width: 768px) { - body { - padding: 1rem; - } - - .container { - padding: 1.5rem; - } - - .header h1 { - font-size: 1.5rem; - } + body { padding: 1rem; } .header-content { flex-direction: column; @@ -848,16 +801,11 @@ body { } .stats-grid { - grid-template-columns: 1fr; + grid-template-columns: repeat(2, 1fr); } - .grid { - grid-template-columns: 1fr; - } - - .button-group { - grid-template-columns: 1fr; - } + .grid { grid-template-columns: 1fr; } + .button-group { grid-template-columns: 1fr; } .toast { left: 1rem; @@ -867,9 +815,12 @@ body { } @media (max-width: 480px) { - .stat-card { - flex-direction: column; - text-align: center; + .stats-grid { + grid-template-columns: 1fr 1fr; + } + + .stat-value { + font-size: 1.25rem; } .devices-grid {