import { css } from './plugins.js'; import type { CSSResult } from './plugins.js'; /** * Shared terminal-style theme for sw-dash components */ export const sharedStyles: CSSResult = css` :host { --sw-bg-dark: #0a0a0a; --sw-bg-panel: #0d0d0d; --sw-bg-header: #111; --sw-bg-input: #1a1a1a; --sw-border: #333; --sw-border-active: #00ff00; --sw-text-primary: #00ff00; --sw-text-secondary: #888; --sw-text-cyan: #00ffff; --sw-text-warning: #ffff00; --sw-text-error: #ff4444; --sw-gauge-good: #00aa00; --sw-gauge-warning: #aaaa00; --sw-gauge-bad: #aa0000; font-family: 'Courier New', Courier, monospace; font-size: 14px; line-height: 1.4; color: var(--sw-text-primary); } `; export const terminalStyles: CSSResult = css` .terminal { max-width: 1200px; margin: 0 auto; border: 1px solid var(--sw-border-active); background: var(--sw-bg-panel); box-shadow: 0 0 20px rgba(0, 255, 0, 0.1); } .header { border-bottom: 1px solid var(--sw-border-active); padding: 10px 15px; display: flex; justify-content: space-between; align-items: center; background: var(--sw-bg-header); } .title { color: var(--sw-text-primary); font-weight: bold; font-size: 16px; } .uptime { color: var(--sw-text-secondary); } .content { padding: 15px; min-height: 400px; } .footer { border-top: 1px solid var(--sw-border-active); padding: 10px 15px; display: flex; justify-content: space-between; align-items: center; background: var(--sw-bg-header); font-size: 12px; } .refresh-info { color: var(--sw-text-secondary); } .status { display: flex; align-items: center; gap: 8px; } .status-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--sw-text-primary); animation: pulse 2s infinite; } .prompt { color: var(--sw-text-primary); } .cursor { display: inline-block; width: 8px; height: 14px; background: var(--sw-text-primary); animation: blink 1s step-end infinite; vertical-align: middle; margin-left: 2px; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } @keyframes blink { 50% { opacity: 0; } } `; export const navStyles: CSSResult = css` .nav { display: flex; background: var(--sw-bg-header); border-bottom: 1px solid var(--sw-border); padding: 0 10px; } .nav-tab { padding: 10px 20px; cursor: pointer; color: var(--sw-text-secondary); border: none; background: transparent; font-family: inherit; font-size: 13px; transition: all 0.2s; border-bottom: 2px solid transparent; } .nav-tab:hover { color: var(--sw-text-primary); } .nav-tab.active { color: var(--sw-text-primary); border-bottom-color: var(--sw-text-primary); background: var(--sw-bg-input); } .nav-tab .count { background: var(--sw-border); padding: 1px 6px; border-radius: 8px; font-size: 11px; margin-left: 6px; } `; export const panelStyles: CSSResult = css` .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); gap: 15px; } .panel { border: 1px solid var(--sw-border); padding: 12px; background: var(--sw-bg-dark); } .panel-title { color: var(--sw-text-cyan); font-weight: bold; margin-bottom: 10px; padding-bottom: 5px; border-bottom: 1px dashed var(--sw-border); } .row { display: flex; justify-content: space-between; padding: 3px 0; } .label { color: var(--sw-text-secondary); } .value { color: var(--sw-text-primary); } .value.warning { color: var(--sw-text-warning); } .value.error { color: var(--sw-text-error); } .value.success { color: var(--sw-text-primary); } `; export const gaugeStyles: CSSResult = css` .gauge { margin: 8px 0; } .gauge-bar { height: 16px; background: var(--sw-bg-input); border: 1px solid var(--sw-border); position: relative; font-size: 12px; } .gauge-fill { height: 100%; transition: width 0.3s ease; } .gauge-fill.good { background: var(--sw-gauge-good); } .gauge-fill.warning { background: var(--sw-gauge-warning); } .gauge-fill.bad { background: var(--sw-gauge-bad); } .gauge-text { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); color: #fff; font-weight: bold; text-shadow: 1px 1px 2px #000; } `; export const tableStyles: CSSResult = css` .table-container { overflow-x: auto; } .data-table { width: 100%; border-collapse: collapse; font-size: 12px; } .data-table th, .data-table td { padding: 8px 10px; text-align: left; border-bottom: 1px solid var(--sw-border); } .data-table th { background: var(--sw-bg-input); color: var(--sw-text-cyan); cursor: pointer; user-select: none; white-space: nowrap; } .data-table th:hover { background: #252525; } .data-table th .sort-icon { margin-left: 5px; opacity: 0.5; } .data-table th.sorted .sort-icon { opacity: 1; color: var(--sw-text-primary); } .data-table tr:hover { background: #151515; } .data-table td { color: #ccc; } .data-table td.url { max-width: 400px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } .data-table td.num { text-align: right; color: var(--sw-text-primary); } .table-controls { display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px; gap: 10px; } .search-input { background: var(--sw-bg-input); border: 1px solid var(--sw-border); color: var(--sw-text-primary); padding: 6px 10px; font-family: inherit; font-size: 12px; width: 250px; } .search-input:focus { outline: none; border-color: var(--sw-border-active); } .table-info { color: var(--sw-text-secondary); font-size: 12px; } .hit-rate-bar { width: 60px; height: 10px; background: var(--sw-bg-input); border: 1px solid var(--sw-border); display: inline-block; vertical-align: middle; margin-right: 6px; } .hit-rate-fill { height: 100%; } .hit-rate-fill.good { background: var(--sw-gauge-good); } .hit-rate-fill.warning { background: var(--sw-gauge-warning); } .hit-rate-fill.bad { background: var(--sw-gauge-bad); } `; export const buttonStyles: CSSResult = css` .btn { background: var(--sw-bg-input); border: 1px solid var(--sw-border-active); color: var(--sw-text-primary); padding: 8px 16px; cursor: pointer; font-family: inherit; font-size: 12px; transition: all 0.2s ease; } .btn:hover { background: var(--sw-text-primary); color: #000; } .btn:disabled { opacity: 0.5; cursor: not-allowed; } .btn-row { display: flex; justify-content: flex-end; margin-top: 10px; } `; export const speedtestStyles: CSSResult = css` .online-indicator { display: flex; align-items: center; gap: 8px; padding: 8px 0; margin-bottom: 10px; border-bottom: 1px dashed var(--sw-border); } .online-dot { width: 12px; height: 12px; border-radius: 50%; transition: background-color 0.3s ease; } .online-dot.online { background: var(--sw-text-primary); box-shadow: 0 0 8px rgba(0, 255, 0, 0.5); } .online-dot.offline { background: var(--sw-text-error); box-shadow: 0 0 8px rgba(255, 68, 68, 0.5); } .speed-bar { height: 8px; background: var(--sw-bg-input); border: 1px solid var(--sw-border); margin: 4px 0; } .speed-fill { height: 100%; background: var(--sw-gauge-good); transition: width 0.5s ease; } /* Speedtest progress indicator */ .speedtest-progress { padding: 10px 0; } .progress-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .progress-phase { color: var(--sw-text-cyan); font-weight: bold; animation: pulse 1s infinite; } .progress-time { color: var(--sw-text-secondary); font-size: 12px; } .progress-bar { height: 20px; background: var(--sw-bg-input); border: 1px solid var(--sw-border); position: relative; overflow: hidden; } .progress-fill { height: 100%; background: linear-gradient(90deg, var(--sw-gauge-good), var(--sw-text-cyan)); transition: width 0.1s linear; position: relative; } .progress-fill::after { content: ''; position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent); animation: shimmer 1.5s infinite; } .progress-fill.complete { background: var(--sw-text-primary); } .progress-fill.complete::after { display: none; } @keyframes shimmer { 0% { transform: translateX(-100%); } 100% { transform: translateX(100%); } } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } `;