Skip to content

Commit 6ce81d6

Browse files
author
=
committed
Improve live power flow layout and device controls
1 parent ed533a0 commit 6ce81d6

5 files changed

Lines changed: 257 additions & 730 deletions

File tree

‎frontend/src/components/PowerFlow.css‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.power-flow-card {
2+
position: relative;
23
margin: 1.5rem 0;
34
padding: 1.5rem;
45
border: 1px solid var(--color-border);
Lines changed: 59 additions & 179 deletions
Original file line numberDiff line numberDiff line change
@@ -1,197 +1,77 @@
11
.simple-power-flow {
2-
position: relative;
3-
isolation: isolate;
4-
display: grid;
5-
grid-template-columns: repeat(3, 1fr);
6-
grid-template-areas:
7-
'. solar .'
8-
'battery home grid'
9-
'. car .';
10-
align-items: start;
11-
gap: 2rem 1rem;
12-
min-height: 320px;
13-
padding: 1rem 0;
2+
max-width: 700px;
3+
margin: 0 auto;
4+
padding-bottom: 1.5rem;
145
}
156

16-
/* Measured SVG connections sit below the nodes and must not intercept pointer input. */
17-
.simple-power-flow-lines {
18-
position: absolute;
19-
inset: 0;
7+
.simple-power-flow-diagram {
8+
font-family: inherit;
9+
display: block;
2010
width: 100%;
21-
height: 100%;
22-
z-index: 0;
2311
overflow: visible;
24-
pointer-events: none;
25-
}
26-
27-
.simple-node {
28-
position: relative;
29-
z-index: 1;
30-
display: flex;
31-
flex-direction: column;
32-
align-items: center;
33-
gap: 0.25rem;
34-
text-align: center;
35-
}
36-
37-
.simple-solar {
38-
grid-area: solar;
39-
}
40-
41-
.simple-battery {
42-
grid-area: battery;
43-
}
44-
45-
.simple-home {
46-
grid-area: home;
47-
}
48-
49-
.right-100 {
50-
position: relative;
51-
display: flex;
52-
flex-direction: column;
53-
left: 50px;
54-
top: -15px;
55-
}
56-
57-
.simple-grid {
58-
grid-area: grid;
59-
}
60-
61-
.simple-car {
62-
grid-area: car;
6312
}
6413

14+
.simple-node { text-anchor: middle; }
6515
.simple-node-circle {
16+
fill: var(--color-surface);
17+
stroke: currentColor;
18+
stroke-width: 2;
19+
}
20+
.simple-node-icon {
6621
display: flex;
6722
align-items: center;
6823
justify-content: center;
69-
width: 72px;
70-
height: 72px;
71-
margin: 0.25rem;
72-
border-radius: 50%;
73-
background: var(--color-bg);
74-
border: 2px solid var(--color-border);
75-
}
76-
77-
.simple-node-circle svg {
78-
font-size: 1.7rem;
79-
}
80-
81-
.simple-node strong {
82-
font-size: 0.85rem;
83-
}
84-
85-
.simple-node-power {
86-
font-size: 1.15rem;
87-
font-weight: 600;
88-
}
89-
90-
.simple-node span,
91-
.simple-node small {
92-
color: var(--color-text-muted);
93-
}
94-
95-
.simple-node small {
96-
font-size: 0.7rem;
97-
}
98-
99-
.grid-icon {
100-
width: 1.6rem;
101-
height: 1.6rem;
102-
}
103-
104-
.simple-car.is-charging .simple-node-power,
105-
.simple-car.is-charging small {
106-
color: var(--color-charge);
107-
}
108-
109-
/* Base connection line */
110-
.simple-flow-line {
111-
fill: none;
112-
stroke: currentColor;
113-
stroke-width: 3;
114-
stroke-linecap: round;
115-
vector-effect: non-scaling-stroke;
116-
}
117-
118-
/* Semantic flow colours */
119-
.flow-solar {
120-
color: var(--color-warning, #f59e0b);
121-
}
122-
123-
.flow-battery {
124-
color: var(--color-success, #16a34a);
125-
}
126-
127-
.flow-grid {
128-
color: var(--color-text-muted, #6b7280);
129-
}
130-
131-
.flow-car {
132-
color: var(--color-hold-car, #d97706);
133-
}
134-
24+
height: 100%;
25+
color: var(--color-text);
26+
}
27+
.simple-node-icon svg { width: 23px; height: 23px; }
28+
.simple-node-power { fill: currentColor; font-size: 13px; font-weight: 600; }
29+
.simple-node-label { fill: var(--color-text-muted); font-size: 14px; }
30+
.simple-node-soc { fill: var(--color-text); font-size: 12px; }
31+
.simple-node-power.is-muted { fill: var(--color-text-muted); }
32+
.flow-solar { color: var(--color-flow-solar, #f59e0b); }
33+
.flow-grid { color: var(--color-current, #3b82f6); }
34+
.flow-export { color: var(--color-export, #a855f7); }
35+
.flow-charge { color: #ec4899; }
36+
.flow-battery, .flow-home { color: #40b5ad; }
37+
.flow-car { color: var(--color-success, #22c55e); }
38+
.flow-heat-pump { color: #b9c63a; }
13539
.simple-flow-base {
40+
fill: none;
13641
stroke: currentColor;
137-
stroke-width: 2;
138-
stroke-linecap: round;
139-
vector-effect: non-scaling-stroke;
140-
transition:
141-
opacity 0.2s ease,
142-
stroke-width 0.2s ease;
143-
}
144-
145-
/* Idle connection remains visible but subdued */
146-
.simple-flow-base.is-idle {
147-
opacity: 0.2;
148-
}
149-
150-
/* Active connection becomes a little stronger */
151-
.simple-flow-base.is-active {
152-
opacity: 0.45;
153-
}
154-
155-
/* Animated energy particles */
156-
.simple-flow-dot {
157-
fill: currentColor;
158-
pointer-events: none;
159-
filter: drop-shadow(0 0 3px currentColor);
160-
}
161-
162-
.simple-flow-dot-primary {
163-
opacity: 1;
164-
}
165-
166-
.simple-flow-dot-secondary {
167-
opacity: 0.65;
168-
}
169-
170-
.simple-flow-dot-tertiary {
171-
opacity: 0.35;
172-
}
173-
174-
/* Semantic colours */
175-
176-
.flow-solar {
177-
color: var(--color-flow-solar);
42+
stroke-width: 1.3;
17843
}
179-
180-
.flow-battery {
181-
color: var(--color-flow-battery);
182-
}
183-
184-
.flow-grid {
185-
color: var(--color-flow-grid);
44+
.simple-flow-base.is-idle { opacity: 0.15; }
45+
.simple-flow-base.is-active { opacity: 0.7; }
46+
.simple-flow-dot { fill: currentColor; }
47+
.simple-flow-subtract {
48+
position: absolute;
49+
right: 0.75rem;
50+
bottom: 0.25rem;
51+
display: flex;
52+
align-items: center;
53+
justify-content: flex-end;
54+
gap: 0.3rem;
55+
min-height: 44px;
56+
color: color-mix(in srgb, var(--color-text-muted) 50%, transparent);
57+
font-size: 0.6875rem;
58+
cursor: pointer;
59+
}
60+
.simple-flow-subtract .toggle-switch { width: 32px; height: 18px; }
61+
.simple-flow-subtract .toggle-slider::before { width: 12px; height: 12px; }
62+
.simple-flow-subtract .toggle-switch input:checked + .toggle-slider::before { transform: translateX(14px); }
63+
@media (prefers-reduced-motion: reduce) {
64+
.simple-flow-dot { display: none; }
18665
}
18766

188-
.flow-car {
189-
color: var(--color-flow-car);
190-
}
67+
.simple-node.flow-solar .simple-node-power { fill: var(--color-solar-text); }
68+
.simple-power-flow-diagram .flow-heat-pump .simple-node-power { fill: var(--color-text-secondary); }
19169

192-
/* Remove animation for users who prefer reduced motion */
193-
@media (prefers-reduced-motion: reduce) {
194-
.simple-flow-dot {
195-
display: none;
196-
}
70+
@media (max-width: 480px) {
71+
.simple-node-circle { r: 49px; }
72+
.simple-node-power { font-size: 19px; }
73+
.simple-node-label { font-size: 20px; transform: translateY(6px); }
74+
.flow-solar .simple-node-label,
75+
.flow-heat-pump .simple-node-label { transform: translateY(-6px); }
76+
.simple-node-soc { font-size: 17px; }
19777
}

0 commit comments

Comments
 (0)