lobsterboard 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +95 -0
- package/LICENSE +21 -0
- package/README.md +161 -0
- package/dist/lobsterboard.css +347 -0
- package/dist/lobsterboard.esm.js +1195 -0
- package/dist/lobsterboard.esm.js.map +1 -0
- package/dist/lobsterboard.esm.min.js +8 -0
- package/dist/lobsterboard.esm.min.js.map +1 -0
- package/dist/lobsterboard.umd.js +1219 -0
- package/dist/lobsterboard.umd.js.map +1 -0
- package/dist/lobsterboard.umd.min.js +8 -0
- package/dist/lobsterboard.umd.min.js.map +1 -0
- package/package.json +67 -0
- package/src/builder.js +723 -0
- package/src/index.js +53 -0
- package/src/widgets.js +435 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# LobsterBoard Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to LobsterBoard will be documented in this file.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
- Text-header widget "Show Border" checkbox now works — toggling it off removes the card background, border, and box-shadow from the `.placed-widget` container
|
|
11
|
+
- Fix text-header, horizontal-line, and vertical-line widgets disappearing after save/reload — unknown widget types (e.g. removed `topbar`) crashed `renderWidget`, stopping all subsequent widgets from loading
|
|
12
|
+
- Add guard in `renderWidget` to skip unknown widget types gracefully
|
|
13
|
+
- Wrap each widget render in try/catch so one bad widget can't prevent others from loading
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## [0.1.0] - 2026-02-05
|
|
18
|
+
|
|
19
|
+
### 🎉 Initial Release
|
|
20
|
+
|
|
21
|
+
The first public version of LobsterBoard - a visual dashboard builder for the OpenClaw community.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
|
|
25
|
+
#### Core Builder
|
|
26
|
+
- Drag-and-drop widget placement on canvas
|
|
27
|
+
- Grid snapping (20px) for precise alignment
|
|
28
|
+
- Widget resize handles
|
|
29
|
+
- Properties panel for configuring widgets
|
|
30
|
+
- Live preview modal with inlined styles
|
|
31
|
+
- Export to ZIP (standalone HTML/CSS/JS)
|
|
32
|
+
|
|
33
|
+
#### Canvas Features
|
|
34
|
+
- 15+ screen size presets (1080p, 4K, tablets, ultrawide, portrait)
|
|
35
|
+
- Custom dimension support
|
|
36
|
+
- Zoom controls (+/-, Fit, 1:1)
|
|
37
|
+
- Keyboard shortcuts (Ctrl +/-, Ctrl+scroll)
|
|
38
|
+
|
|
39
|
+
#### Widgets (40+)
|
|
40
|
+
- **AI/LLM:** Claude Usage, GPT Usage, Gemini Usage, AI Usage (All), Cost Tracker, API Status, Active Sessions, Token Gauge
|
|
41
|
+
- **Basics:** Local Weather, World Weather, Clock, World Clock, Countdown, Stat Card, Battery Status
|
|
42
|
+
- **System:** CPU/Memory, Disk Usage, Network Speed, Docker, Uptime Monitor
|
|
43
|
+
- **OpenClaw:** Auth Status, Sleep Ring, Release, Activity List, Cron Jobs, System Log
|
|
44
|
+
- **Productivity:** Todo List, Calendar, Email Count, Pomodoro, Notes, GitHub Stats
|
|
45
|
+
- **Finance:** Stock Ticker, Crypto Price
|
|
46
|
+
- **Smart Home:** Indoor Climate, Camera Feed, Power Usage
|
|
47
|
+
- **Entertainment:** Now Playing, Quote of Day
|
|
48
|
+
- **Content:** Quick Links, RSS Feed, Image Embed, Iframe Embed
|
|
49
|
+
- **Bars:** Top Nav Bar, News Ticker, RSS Ticker
|
|
50
|
+
|
|
51
|
+
#### Branding
|
|
52
|
+
- LobsterBoard name and mascot 🦞
|
|
53
|
+
- Logo wordmark for header
|
|
54
|
+
- Mascot illustration for sidebar
|
|
55
|
+
- Favicon and Apple touch icon
|
|
56
|
+
|
|
57
|
+
#### Design
|
|
58
|
+
- Dark theme matching OpenClaw aesthetic
|
|
59
|
+
- Consistent `dash-card` styling across all widgets
|
|
60
|
+
- Widget headers with icons
|
|
61
|
+
- Sample data display (no loading spinners in builder)
|
|
62
|
+
|
|
63
|
+
### Technical Notes
|
|
64
|
+
- Weather widgets use wttr.in (free, no API key required)
|
|
65
|
+
- API keys stored as placeholders for users to fill in post-export
|
|
66
|
+
- AI usage widgets require backend proxy due to CORS
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## [0.1.1] - 2026-02-06
|
|
71
|
+
|
|
72
|
+
### Changed
|
|
73
|
+
- Moved mascot from left sidebar to right (properties panel)
|
|
74
|
+
- Mascot now pinned to bottom of panel (doesn't float up)
|
|
75
|
+
|
|
76
|
+
### Fixed
|
|
77
|
+
- Mascot positioning with `margin-top: auto` in flexbox
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Upcoming
|
|
82
|
+
|
|
83
|
+
### Planned Features
|
|
84
|
+
- GitHub Pages deployment
|
|
85
|
+
- Import/export dashboard layouts (JSON)
|
|
86
|
+
- Widget templates and presets
|
|
87
|
+
- More customization options
|
|
88
|
+
- Community widget contributions
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Links
|
|
93
|
+
|
|
94
|
+
- **GitHub:** https://github.com/curbob/LobsterBoard
|
|
95
|
+
- **Issues:** https://github.com/curbob/LobsterBoard/issues
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 curbob
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
# 🦞 LobsterBoard
|
|
2
|
+
|
|
3
|
+
A drag-and-drop dashboard builder for creating beautiful, customizable status boards.
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Visual Builder**: Drag and drop widgets onto a grid
|
|
10
|
+
- **47+ Widgets**: Weather, clocks, system stats, AI usage, and more
|
|
11
|
+
- **Dark Theme**: Easy on the eyes, perfect for always-on displays
|
|
12
|
+
- **Export to HTML**: Single-file dashboards that run anywhere
|
|
13
|
+
- **No Backend Required**: Many widgets work with just a browser
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
1. Open `index.html` in your browser
|
|
18
|
+
2. Drag widgets from the sidebar onto the canvas
|
|
19
|
+
3. Click widgets to edit their properties
|
|
20
|
+
4. Click **Export Dashboard** to download your dashboard
|
|
21
|
+
|
|
22
|
+
## Widget Categories
|
|
23
|
+
|
|
24
|
+
### ✅ Works Out of Box (No API Needed)
|
|
25
|
+
These widgets work immediately with no configuration:
|
|
26
|
+
- Weather (wttr.in)
|
|
27
|
+
- Clock, World Clock
|
|
28
|
+
- Countdown, Pomodoro Timer
|
|
29
|
+
- Images (local, web, random rotation)
|
|
30
|
+
- Quick Links
|
|
31
|
+
- Iframe Embed
|
|
32
|
+
- Release Tracker (GitHub public API)
|
|
33
|
+
|
|
34
|
+
### 🦞 OpenClaw Widgets
|
|
35
|
+
These widgets connect to a running [OpenClaw](https://github.com/openclaw/openclaw) gateway:
|
|
36
|
+
- Auth Status
|
|
37
|
+
- OpenClaw Release
|
|
38
|
+
- Activity List
|
|
39
|
+
- Cron Jobs
|
|
40
|
+
- System Log
|
|
41
|
+
- Session Count
|
|
42
|
+
- Token Gauge
|
|
43
|
+
|
|
44
|
+
**See [Using OpenClaw Widgets](#using-openclaw-widgets) below.**
|
|
45
|
+
|
|
46
|
+
### 🔑 API Key Required
|
|
47
|
+
These widgets need you to provide an API key:
|
|
48
|
+
- News Ticker (NewsAPI)
|
|
49
|
+
- Stock Ticker (Finnhub)
|
|
50
|
+
- GitHub Stats (optional, for higher rate limits)
|
|
51
|
+
|
|
52
|
+
### ⚠️ Custom Backend Required
|
|
53
|
+
These widgets need custom API endpoints:
|
|
54
|
+
- AI Usage (Claude, GPT, Gemini)
|
|
55
|
+
- CPU/Memory, Disk Usage
|
|
56
|
+
- Docker Containers
|
|
57
|
+
- And more...
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Using OpenClaw Widgets
|
|
62
|
+
|
|
63
|
+
OpenClaw widgets fetch data from your local OpenClaw gateway. Due to browser CORS restrictions, you need to either:
|
|
64
|
+
|
|
65
|
+
### Option A: Use the Included Server (Recommended)
|
|
66
|
+
|
|
67
|
+
The server proxies API requests to OpenClaw, solving CORS issues.
|
|
68
|
+
|
|
69
|
+
1. **Export your dashboard** from the builder (Download button)
|
|
70
|
+
|
|
71
|
+
2. **Extract the ZIP** to a folder
|
|
72
|
+
|
|
73
|
+
3. **`server.js` is included** in the exported ZIP
|
|
74
|
+
|
|
75
|
+
4. **Run the server**:
|
|
76
|
+
```bash
|
|
77
|
+
cd your-dashboard-folder
|
|
78
|
+
node server.js
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
5. **Open** http://localhost:8080 in your browser
|
|
82
|
+
|
|
83
|
+
**Configuration** (environment variables):
|
|
84
|
+
```bash
|
|
85
|
+
# Custom port for the dashboard server
|
|
86
|
+
PORT=3000 node server.js
|
|
87
|
+
|
|
88
|
+
# Custom OpenClaw gateway URL (if not on default port 18789)
|
|
89
|
+
OPENCLAW_URL=http://localhost:YOUR_PORT node server.js
|
|
90
|
+
|
|
91
|
+
# Expose to network (⚠️ only on trusted networks!)
|
|
92
|
+
HOST=0.0.0.0 node server.js
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
> **⚠️ Non-Default Gateway Port?**
|
|
96
|
+
>
|
|
97
|
+
> If your OpenClaw gateway runs on a port other than `18789` (the default), you **must** set the `OPENCLAW_URL` environment variable. Check your gateway port:
|
|
98
|
+
> ```bash
|
|
99
|
+
> grep '"port"' ~/.openclaw/openclaw.json
|
|
100
|
+
> ```
|
|
101
|
+
> Then start the server with:
|
|
102
|
+
> ```bash
|
|
103
|
+
> OPENCLAW_URL=http://localhost:YOUR_PORT node server.js
|
|
104
|
+
> ```
|
|
105
|
+
|
|
106
|
+
### Option B: Run OpenClaw with CORS Headers
|
|
107
|
+
|
|
108
|
+
If you control your OpenClaw config, you can add CORS headers directly.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## Exporting Dashboards
|
|
113
|
+
|
|
114
|
+
1. Click the **💾 Export** button in the toolbar
|
|
115
|
+
2. Choose **Download Dashboard**
|
|
116
|
+
3. A ZIP file is created containing:
|
|
117
|
+
- `index.html` - Your complete dashboard
|
|
118
|
+
- `server.js` - Server for OpenClaw widgets (optional)
|
|
119
|
+
- Any embedded images
|
|
120
|
+
|
|
121
|
+
The exported HTML is self-contained and can be:
|
|
122
|
+
- Opened directly in a browser (for non-API widgets)
|
|
123
|
+
- Served via the included Node.js server
|
|
124
|
+
- Hosted on any static web server
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## Development
|
|
129
|
+
|
|
130
|
+
### File Structure
|
|
131
|
+
```
|
|
132
|
+
dashboard-builder/
|
|
133
|
+
├── index.html # Main builder UI
|
|
134
|
+
├── css/
|
|
135
|
+
│ └── styles.css # Dashboard styles
|
|
136
|
+
├── js/
|
|
137
|
+
│ ├── builder.js # Builder logic
|
|
138
|
+
│ └── widgets.js # Widget definitions
|
|
139
|
+
├── server.js # Node.js server for exports
|
|
140
|
+
└── WIDGETS-STATUS.md # Widget verification status
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Adding New Widgets
|
|
144
|
+
|
|
145
|
+
See `js/widgets.js` for widget definitions. Each widget has:
|
|
146
|
+
- `name`, `icon`, `category`
|
|
147
|
+
- `description` - Shows in properties panel
|
|
148
|
+
- `defaultWidth`, `defaultHeight`
|
|
149
|
+
- `properties` - Configurable options
|
|
150
|
+
- `generateHtml()` - Returns widget HTML
|
|
151
|
+
- `generateJs()` - Returns widget JavaScript
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## License
|
|
156
|
+
|
|
157
|
+
MIT
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
Made with 🦞 by the LobsterBoard team
|
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
/* LobsterBoard v0.1.0 - Dashboard Styles */
|
|
2
|
+
/* LobsterBoard Dashboard - Generated Styles */
|
|
3
|
+
|
|
4
|
+
:root {
|
|
5
|
+
--bg-primary: #0d1117;
|
|
6
|
+
--bg-secondary: #161b22;
|
|
7
|
+
--bg-tertiary: #21262d;
|
|
8
|
+
--bg-hover: #30363d;
|
|
9
|
+
--border: #30363d;
|
|
10
|
+
--text-primary: #e6edf3;
|
|
11
|
+
--text-secondary: #8b949e;
|
|
12
|
+
--text-muted: #6e7681;
|
|
13
|
+
--accent-blue: #58a6ff;
|
|
14
|
+
--accent-green: #3fb950;
|
|
15
|
+
--accent-orange: #d29922;
|
|
16
|
+
--accent-red: #f85149;
|
|
17
|
+
--accent-purple: #a371f7;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
* {
|
|
21
|
+
box-sizing: border-box;
|
|
22
|
+
margin: 0;
|
|
23
|
+
padding: 0;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
body {
|
|
27
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
28
|
+
background: var(--bg-primary);
|
|
29
|
+
color: var(--text-primary);
|
|
30
|
+
min-height: 100vh;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.dashboard {
|
|
34
|
+
margin: 0 auto;
|
|
35
|
+
overflow: hidden;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.widget-container {
|
|
39
|
+
overflow: hidden;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* KPI Cards */
|
|
43
|
+
.kpi-card {
|
|
44
|
+
background: var(--bg-secondary);
|
|
45
|
+
border: 1px solid var(--border);
|
|
46
|
+
border-radius: 8px;
|
|
47
|
+
padding: 16px;
|
|
48
|
+
display: flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
gap: 12px;
|
|
51
|
+
height: 100%;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.kpi-sm {
|
|
55
|
+
padding: 12px;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.kpi-icon {
|
|
59
|
+
font-size: 24px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.kpi-data {
|
|
63
|
+
flex: 1;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.kpi-value {
|
|
67
|
+
font-size: 20px;
|
|
68
|
+
font-weight: 600;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.kpi-value.blue { color: var(--accent-blue); }
|
|
72
|
+
.kpi-value.green { color: var(--accent-green); }
|
|
73
|
+
.kpi-value.orange { color: var(--accent-orange); }
|
|
74
|
+
.kpi-value.red { color: var(--accent-red); }
|
|
75
|
+
|
|
76
|
+
.kpi-label {
|
|
77
|
+
font-size: 12px;
|
|
78
|
+
color: var(--text-secondary);
|
|
79
|
+
margin-top: 2px;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.kpi-indicator {
|
|
83
|
+
width: 10px;
|
|
84
|
+
height: 10px;
|
|
85
|
+
border-radius: 50%;
|
|
86
|
+
background: var(--text-muted);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.kpi-indicator.green { background: var(--accent-green); }
|
|
90
|
+
.kpi-indicator.yellow { background: var(--accent-orange); }
|
|
91
|
+
.kpi-indicator.red { background: var(--accent-red); }
|
|
92
|
+
|
|
93
|
+
/* Dash Cards */
|
|
94
|
+
.dash-card {
|
|
95
|
+
background: var(--bg-secondary);
|
|
96
|
+
border: 1px solid var(--border);
|
|
97
|
+
border-radius: 8px;
|
|
98
|
+
display: flex;
|
|
99
|
+
flex-direction: column;
|
|
100
|
+
height: 100%;
|
|
101
|
+
overflow: hidden;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.dash-card-head {
|
|
105
|
+
display: flex;
|
|
106
|
+
justify-content: space-between;
|
|
107
|
+
align-items: center;
|
|
108
|
+
padding: 12px 16px;
|
|
109
|
+
border-bottom: 1px solid var(--border);
|
|
110
|
+
background: var(--bg-tertiary);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
.dash-card-title {
|
|
114
|
+
font-size: 13px;
|
|
115
|
+
font-weight: 600;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.dash-card-badge {
|
|
119
|
+
font-size: 11px;
|
|
120
|
+
color: var(--text-secondary);
|
|
121
|
+
background: var(--bg-primary);
|
|
122
|
+
padding: 2px 8px;
|
|
123
|
+
border-radius: 10px;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
.dash-card-body {
|
|
127
|
+
flex: 1;
|
|
128
|
+
padding: 12px 16px;
|
|
129
|
+
overflow-y: auto;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.compact-list {
|
|
133
|
+
font-size: 12px;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.syslog-scroll {
|
|
137
|
+
font-family: 'SF Mono', Monaco, monospace;
|
|
138
|
+
font-size: 11px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* Top Bar */
|
|
142
|
+
.topbar {
|
|
143
|
+
display: flex;
|
|
144
|
+
justify-content: space-between;
|
|
145
|
+
align-items: center;
|
|
146
|
+
padding: 8px 20px;
|
|
147
|
+
background: var(--bg-secondary);
|
|
148
|
+
border-bottom: 1px solid var(--border);
|
|
149
|
+
height: 100%;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.topbar-left {
|
|
153
|
+
display: flex;
|
|
154
|
+
align-items: center;
|
|
155
|
+
gap: 20px;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.topbar-brand {
|
|
159
|
+
font-weight: 600;
|
|
160
|
+
font-size: 14px;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.topbar-link {
|
|
164
|
+
color: var(--text-secondary);
|
|
165
|
+
text-decoration: none;
|
|
166
|
+
font-size: 13px;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
.topbar-link:hover,
|
|
170
|
+
.topbar-link.active {
|
|
171
|
+
color: var(--accent-blue);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.topbar-right {
|
|
175
|
+
display: flex;
|
|
176
|
+
align-items: center;
|
|
177
|
+
gap: 12px;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.topbar-meta {
|
|
181
|
+
font-size: 12px;
|
|
182
|
+
color: var(--text-muted);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
.topbar-refresh {
|
|
186
|
+
background: var(--bg-tertiary);
|
|
187
|
+
border: 1px solid var(--border);
|
|
188
|
+
color: var(--text-secondary);
|
|
189
|
+
padding: 4px 8px;
|
|
190
|
+
border-radius: 4px;
|
|
191
|
+
cursor: pointer;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* List Items */
|
|
195
|
+
.list-item {
|
|
196
|
+
padding: 6px 0;
|
|
197
|
+
border-bottom: 1px solid var(--border);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.list-item:last-child {
|
|
201
|
+
border-bottom: none;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.cron-item {
|
|
205
|
+
display: flex;
|
|
206
|
+
justify-content: space-between;
|
|
207
|
+
padding: 6px 0;
|
|
208
|
+
border-bottom: 1px solid var(--border);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.cron-name {
|
|
212
|
+
color: var(--text-primary);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.cron-next {
|
|
216
|
+
color: var(--text-muted);
|
|
217
|
+
font-size: 11px;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.log-line {
|
|
221
|
+
padding: 2px 0;
|
|
222
|
+
border-bottom: 1px solid rgba(48, 54, 61, 0.5);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/* Weather */
|
|
226
|
+
.weather-row {
|
|
227
|
+
display: flex;
|
|
228
|
+
align-items: center;
|
|
229
|
+
gap: 10px;
|
|
230
|
+
padding: 8px 0;
|
|
231
|
+
border-bottom: 1px solid var(--border);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
.weather-row:last-child {
|
|
235
|
+
border-bottom: none;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
.weather-icon {
|
|
239
|
+
font-size: 18px;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
.weather-loc {
|
|
243
|
+
flex: 1;
|
|
244
|
+
color: var(--text-primary);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
.weather-temp {
|
|
248
|
+
font-weight: 600;
|
|
249
|
+
color: var(--accent-blue);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
/* Utilities */
|
|
253
|
+
.loading-sm {
|
|
254
|
+
display: flex;
|
|
255
|
+
align-items: center;
|
|
256
|
+
justify-content: center;
|
|
257
|
+
padding: 20px;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
.spinner-sm {
|
|
261
|
+
width: 20px;
|
|
262
|
+
height: 20px;
|
|
263
|
+
border: 2px solid var(--bg-tertiary);
|
|
264
|
+
border-top-color: var(--accent-blue);
|
|
265
|
+
border-radius: 50%;
|
|
266
|
+
animation: spin 1s linear infinite;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@keyframes spin {
|
|
270
|
+
to { transform: rotate(360deg); }
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
.error {
|
|
274
|
+
color: var(--accent-red);
|
|
275
|
+
padding: 10px;
|
|
276
|
+
text-align: center;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
::-webkit-scrollbar {
|
|
280
|
+
width: 6px;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
::-webkit-scrollbar-track {
|
|
284
|
+
background: var(--bg-primary);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
::-webkit-scrollbar-thumb {
|
|
288
|
+
background: var(--bg-tertiary);
|
|
289
|
+
border-radius: 3px;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/* Post-Export Edit Mode */
|
|
293
|
+
.edit-mode .widget-container {
|
|
294
|
+
cursor: move;
|
|
295
|
+
outline: 2px dashed #3b82f6;
|
|
296
|
+
outline-offset: -2px;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.edit-mode .widget-container:hover {
|
|
300
|
+
outline-color: #60a5fa;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.edit-mode .widget-container.dragging {
|
|
304
|
+
opacity: 0.8;
|
|
305
|
+
z-index: 1000;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
.resize-handle-edit {
|
|
309
|
+
display: none;
|
|
310
|
+
position: absolute;
|
|
311
|
+
bottom: 0;
|
|
312
|
+
right: 0;
|
|
313
|
+
width: 16px;
|
|
314
|
+
height: 16px;
|
|
315
|
+
cursor: se-resize;
|
|
316
|
+
background: #3b82f6;
|
|
317
|
+
border-radius: 2px 0 0 0;
|
|
318
|
+
z-index: 10;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
.edit-mode .resize-handle-edit {
|
|
322
|
+
display: block;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
#edit-toggle {
|
|
326
|
+
position: fixed;
|
|
327
|
+
bottom: 20px;
|
|
328
|
+
right: 20px;
|
|
329
|
+
z-index: 9999;
|
|
330
|
+
padding: 8px 16px;
|
|
331
|
+
background: #1e293b;
|
|
332
|
+
color: white;
|
|
333
|
+
border: none;
|
|
334
|
+
border-radius: 6px;
|
|
335
|
+
cursor: pointer;
|
|
336
|
+
font-size: 13px;
|
|
337
|
+
font-weight: 500;
|
|
338
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.3);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
#edit-toggle:hover {
|
|
342
|
+
background: #334155;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
#edit-toggle.active {
|
|
346
|
+
background: #3b82f6;
|
|
347
|
+
}
|