Skip to content

Commit 4ce26db

Browse files
committed
Added departure queue and more refinements
1 parent 19294ad commit 4ce26db

8 files changed

Lines changed: 1497 additions & 112 deletions

File tree

README.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Then open [http://localhost:3000](http://localhost:3000).
3535
- `components/route-validator-page.js`: Route Validator UI + matching/status logic
3636
- `app/tools/route-validator/styles.css`: Route Validator-specific styling
3737
- `data/zhu-routing-rules.json`: preferred route rules used by Route Validator
38+
- `data/tfms-airport-queue-boxes.json`: queue-watch airport bounding boxes for TFMS cards
3839
- `lib/tools.js`: helpers for loading tool data
3940
- `app/globals.css`: shared theme tokens and utility classes
4041
- `reference/`: source/reference docs used during development (not runtime)
@@ -116,7 +117,13 @@ Route Validator renders from `data/zhu-routing-rules.json` and compares filed ro
116117
- TFMS currently shows:
117118
- Specialty Summary
118119
- Online Positions (enroute + TRACON status)
119-
- Split Summary is intentionally hidden for now and can be re-enabled later.
120+
- Departure Queue (KIAH/KHOU/KAUS/KSAT/KMSY)
121+
- Split Summary is currently disabled while this module is being redesigned.
122+
- Queue watch area config supports either:
123+
- legacy `bounds` (`minLat/maxLat/minLon/maxLon`)
124+
- GeoJSON via `geojson` (Feature, FeatureCollection, Polygon, MultiPolygon)
125+
- GeoJSON array via `areas`
126+
- multiple entries with the same ICAO are merged into one airport card
120127

121128
### Route Validator Statuses
122129

app/tools/tfms/styles.css

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,44 @@
9494
box-shadow: inset 0 0 0 1px color-mix(in srgb, white 22%, transparent);
9595
}
9696

97+
@keyframes tfms-count-flash-up {
98+
0%,
99+
100% {
100+
transform: scale(1);
101+
box-shadow: inset 0 0 0 1px color-mix(in srgb, white 22%, transparent);
102+
}
103+
20%,
104+
60% {
105+
transform: scale(1.11);
106+
box-shadow:
107+
inset 0 0 0 1px color-mix(in srgb, white 32%, transparent),
108+
0 0 0.75rem color-mix(in srgb, #22c55e 65%, transparent);
109+
}
110+
}
111+
112+
@keyframes tfms-count-flash-down {
113+
0%,
114+
100% {
115+
transform: scale(1);
116+
box-shadow: inset 0 0 0 1px color-mix(in srgb, white 22%, transparent);
117+
}
118+
20%,
119+
60% {
120+
transform: scale(1.11);
121+
box-shadow:
122+
inset 0 0 0 1px color-mix(in srgb, white 32%, transparent),
123+
0 0 0.75rem color-mix(in srgb, #ef4444 65%, transparent);
124+
}
125+
}
126+
127+
.tfms-count-tick-up {
128+
animation: tfms-count-flash-up 0.72s ease-in-out 4;
129+
}
130+
131+
.tfms-count-tick-down {
132+
animation: tfms-count-flash-down 0.72s ease-in-out 4;
133+
}
134+
97135
:root[data-theme="dark"] .tfms-band-green {
98136
color: #86efac;
99137
}
@@ -110,6 +148,13 @@
110148
box-shadow: inset 0 0 0 1px color-mix(in srgb, white 14%, transparent);
111149
}
112150

151+
@media (prefers-reduced-motion: reduce) {
152+
.tfms-count-tick-up,
153+
.tfms-count-tick-down {
154+
animation: none;
155+
}
156+
}
157+
113158
.tfms-specialty-table tbody tr.tfms-row-warning td {
114159
background: color-mix(in srgb, #f59e0b 9%, transparent);
115160
}
@@ -126,6 +171,59 @@
126171
background: color-mix(in srgb, #ef4444 14%, transparent);
127172
}
128173

174+
.tfms-queue-grid {
175+
display: grid;
176+
gap: 0.6rem;
177+
grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));
178+
}
179+
180+
.tfms-queue-card {
181+
border: 1px solid var(--surface-border);
182+
background: color-mix(in srgb, var(--surface-soft) 72%, transparent);
183+
border-radius: 0.7rem;
184+
padding: 0.55rem 0.65rem;
185+
}
186+
187+
.tfms-queue-green {
188+
border-color: color-mix(in srgb, #16a34a 48%, var(--surface-border));
189+
}
190+
191+
.tfms-queue-yellow {
192+
border-color: color-mix(in srgb, #f59e0b 48%, var(--surface-border));
193+
}
194+
195+
.tfms-queue-red {
196+
border-color: color-mix(in srgb, #ef4444 48%, var(--surface-border));
197+
}
198+
199+
.tfms-queue-trend {
200+
border: 1px solid var(--surface-border);
201+
border-radius: 9999px;
202+
padding: 0.08rem 0.45rem;
203+
font-size: 0.62rem;
204+
font-weight: 700;
205+
letter-spacing: 0.08em;
206+
text-transform: uppercase;
207+
}
208+
209+
.tfms-queue-trend-up {
210+
color: #ef4444;
211+
border-color: color-mix(in srgb, #ef4444 55%, var(--surface-border));
212+
background: color-mix(in srgb, #ef4444 18%, var(--surface-soft));
213+
}
214+
215+
.tfms-queue-trend-down {
216+
color: #16a34a;
217+
border-color: color-mix(in srgb, #16a34a 55%, var(--surface-border));
218+
background: color-mix(in srgb, #16a34a 18%, var(--surface-soft));
219+
}
220+
221+
.tfms-queue-trend-flat {
222+
color: var(--muted);
223+
border-color: var(--surface-border);
224+
background: color-mix(in srgb, var(--surface-soft) 88%, transparent);
225+
}
226+
129227
.tfms-tracon-chip {
130228
border: 1px solid var(--surface-border);
131229
background: var(--surface-soft);

0 commit comments

Comments
 (0)