UI polish, bug fixes, and README
Changes since last commit: NATS airspace - Remove D and D_OTHER types from parser — UK small-arms ranges covered the entire country and made the layer unusable - Replace title-attribute tooltips on type filters with clickable ⓘ icons (mobile-friendly); info text appears in a shared box below the grid - Add Select All / Deselect All controls (moved to bottom of all layers, now applies to every layer checkbox not just NATS types) - Fix per-type filter using expression syntax ['match', ...] — legacy filter syntax was unreliable in MapLibre GL JS 4.x Map style switching - Fix overlay layers being lost when switching Terrain / Satellite / Streets by waiting for the 'idle' event instead of 'style.load'; MapTiler styles fire style.load before the map is ready to accept addSource/addLayer calls - Defensive cleanup at top of addAllLayers() removes all custom layers and sources before re-adding, preventing "source already exists" crashes Location tracking - Move locate button from floating bottom-right into the left panel - Auto-request location on page load - Dynamic button label: "Getting location…" → "Stop Tracking" → "Track location" - Suppress alert on permission-denied (error code 1); show inline message for other errors Panel UX - Move planning disclaimer out of panel body into a ⚠ icon in the header; click to expand, includes hyperlinked NOTAM link - Add NOTAM link to the data-links section at the bottom - Danger / Restricted and MoD / Military rows now have ⓘ icons explaining that these layers have no built-in data and require a GeoJSON upload; removes the old "Override: load GeoJSON below" note and "(override)" labels from the dropdown - Load Data section: stacked full-width layout (dropdown above button) - Lighten grey text (#555 → #888, #666 → #999) across section labels, layer notes, info icons, hints, data links, and popup close button Map bounds and attribution - Restrict panning to UK + Channel Islands with maxBounds - Replace default attribution control with custom one appending "© Bournemouth Technology" with link to bournemouthtechnology.co.uk README - Add full project description, feature list, tech stack table, setup instructions, and data source reference table
This commit is contained in:
108
style.css
108
style.css
@@ -44,12 +44,28 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
padding: 10px 14px; border-bottom: 1px solid #2a2d38;
|
||||
}
|
||||
.panel-title { font-weight: 700; font-size: .95rem; letter-spacing: .5px; }
|
||||
.header-btns { display: flex; align-items: center; gap: 2px; }
|
||||
|
||||
#warn-btn {
|
||||
background: none; border: none; color: #f59e0b; cursor: pointer;
|
||||
padding: 2px 5px; border-radius: 4px; line-height: 1;
|
||||
display: flex; align-items: center;
|
||||
}
|
||||
#warn-btn:hover { background: #ffffff15; }
|
||||
#warn-btn svg { width: 15px; height: 15px; }
|
||||
|
||||
#panel-toggle {
|
||||
background: none; border: none; color: #aaa; font-size: 1.1rem;
|
||||
cursor: pointer; line-height: 1; padding: 2px 4px; border-radius: 4px;
|
||||
}
|
||||
#panel-toggle:hover { background: #ffffff15; color: #fff; }
|
||||
|
||||
#warn-popup {
|
||||
padding: 8px 14px; border-bottom: 1px solid #5a4200;
|
||||
background: #2a2206; font-size: .7rem; color: #c9a84c; line-height: 1.5;
|
||||
}
|
||||
#warn-popup.hidden { display: none; }
|
||||
|
||||
#panel-body {
|
||||
padding: 12px 14px 14px;
|
||||
max-height: calc(100dvh - 90px);
|
||||
@@ -59,7 +75,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
|
||||
.section-label {
|
||||
font-size: .62rem; font-weight: 700; letter-spacing: 1.3px;
|
||||
color: #555; margin: 8px 0 5px; text-transform: uppercase;
|
||||
color: #888; margin: 8px 0 5px; text-transform: uppercase;
|
||||
border-top: 1px solid #2a2d38; padding-top: 8px;
|
||||
}
|
||||
.section-label:first-child { border-top: none; padding-top: 0; margin-top: 0; }
|
||||
@@ -83,8 +99,13 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
.dot-sssi { background: #06b6d4; }
|
||||
.dot-forestry { background: #4d7c0f; }
|
||||
|
||||
.layer-row-outer {
|
||||
display: flex; align-items: center; gap: 4px;
|
||||
}
|
||||
.layer-row-outer .layer-row { flex: 1; }
|
||||
|
||||
.layer-note {
|
||||
font-size: .7rem; color: #555; margin: 1px 0 4px 23px; line-height: 1.4;
|
||||
font-size: .7rem; color: #888; margin: 1px 0 4px 23px; line-height: 1.4;
|
||||
}
|
||||
.layer-note a { color: #5aacff; text-decoration: none; }
|
||||
.layer-note a:hover { text-decoration: underline; }
|
||||
@@ -104,7 +125,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
margin-top: 7px; padding: 2px 1px; font-size: .82rem; color: #ccc;
|
||||
}
|
||||
.hint { font-size: .68rem; color: #555; }
|
||||
.hint { font-size: .68rem; color: #888; }
|
||||
|
||||
.switch { position: relative; display: inline-block; width: 36px; height: 20px; flex-shrink: 0; }
|
||||
.switch input { opacity: 0; width: 0; height: 0; }
|
||||
@@ -122,21 +143,21 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
.switch input:checked ~ .switch-track .switch-thumb { transform: translateX(16px); background: #fff; }
|
||||
|
||||
/* ── Load data ── */
|
||||
.load-row { display: flex; gap: 6px; margin-top: 4px; align-items: center; }
|
||||
.layer-select {
|
||||
flex: 1; padding: 6px 8px; border-radius: 6px; border: 1px solid #333;
|
||||
background: #2a2d38; color: #ccc; font-size: .75rem; cursor: pointer;
|
||||
appearance: none; outline: none;
|
||||
width: 100%; margin-top: 5px; padding: 7px 8px; border-radius: 6px;
|
||||
border: 1px solid #333; background: #2a2d38; color: #ccc;
|
||||
font-size: .75rem; cursor: pointer; appearance: none; outline: none;
|
||||
}
|
||||
.layer-select:focus { border-color: #555; }
|
||||
|
||||
.load-btn {
|
||||
flex-shrink: 0; padding: 6px 10px; border-radius: 6px;
|
||||
padding: 7px 10px; border-radius: 6px;
|
||||
border: 1px solid #333; background: #2a2d38;
|
||||
color: #ccc; font-size: .75rem; cursor: pointer; white-space: nowrap;
|
||||
transition: background .15s;
|
||||
}
|
||||
.load-btn:hover { background: #34384a; color: #fff; }
|
||||
.load-btn-full { display: block; width: 100%; margin-top: 5px; text-align: center; }
|
||||
|
||||
/* ── Progress bar ── */
|
||||
.progress-bar {
|
||||
@@ -153,45 +174,67 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
/* ── NATS type filter grid ── */
|
||||
.nats-type-grid {
|
||||
display: grid; grid-template-columns: repeat(3, 1fr);
|
||||
gap: 2px 4px; margin: 3px 0 5px 22px;
|
||||
gap: 2px 4px; margin: 3px 0 3px 22px;
|
||||
}
|
||||
.type-cell { display: flex; align-items: center; gap: 2px; }
|
||||
.type-check {
|
||||
display: flex; align-items: center; gap: 3px;
|
||||
display: flex; align-items: center; gap: 3px; flex: 1;
|
||||
font-size: .7rem; cursor: pointer; user-select: none; color: #999;
|
||||
}
|
||||
.type-check input[type=checkbox] { width: 11px; height: 11px; cursor: pointer; flex-shrink: 0; }
|
||||
.tc-r { color: #ef4444; font-weight: 600; }
|
||||
.tc-d { color: #f97316; font-weight: 600; }
|
||||
.tc-ctr { color: #facc15; font-weight: 600; }
|
||||
.tc-cta { color: #60a5fa; font-weight: 600; }
|
||||
.tc-ras { color: #818cf8; font-weight: 600; }
|
||||
.tc-tmz { color: #c084fc; font-weight: 600; }
|
||||
|
||||
.info-btn {
|
||||
width: 14px; height: 14px; border-radius: 50%; flex-shrink: 0;
|
||||
border: none; background: none;
|
||||
color: #888; cursor: pointer; padding: 0;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
transition: color .15s;
|
||||
}
|
||||
.info-btn:hover { color: #5aacff; }
|
||||
.info-btn.active { color: #5aacff; }
|
||||
.info-btn svg { width: 13px; height: 13px; }
|
||||
|
||||
.type-all-row {
|
||||
display: flex; gap: 6px; margin: 4px 0 2px 22px;
|
||||
}
|
||||
.type-all-btn {
|
||||
flex: 1; padding: 4px 6px; border-radius: 5px;
|
||||
border: 1px solid #333; background: #2a2d38;
|
||||
color: #bbb; font-size: .68rem; cursor: pointer;
|
||||
transition: background .15s, color .15s;
|
||||
}
|
||||
.type-all-btn:hover { background: #34384a; color: #fff; }
|
||||
|
||||
.type-info-box {
|
||||
margin: 4px 0 4px 22px; padding: 6px 8px; border-radius: 5px;
|
||||
background: #1a1d24; border: 1px solid #2a2d38;
|
||||
font-size: .7rem; color: #aaa; line-height: 1.45;
|
||||
}
|
||||
.type-info-box.hidden { display: none; }
|
||||
|
||||
.data-links {
|
||||
margin-top: 7px; font-size: .68rem; color: #555; line-height: 1.9;
|
||||
margin-top: 7px; font-size: .68rem; color: #888; line-height: 1.9;
|
||||
}
|
||||
.data-links a { color: #5aacff; text-decoration: none; }
|
||||
.data-links a:hover { text-decoration: underline; }
|
||||
|
||||
.disclaimer {
|
||||
margin-top: 12px; padding: 9px 10px; border-radius: 6px;
|
||||
background: #2a2206; border: 1px solid #5a4200;
|
||||
font-size: .7rem; color: #c9a84c; line-height: 1.5;
|
||||
}
|
||||
|
||||
/* ── Locate button ── */
|
||||
/* ── Locate button (inside panel) ── */
|
||||
#locate-btn {
|
||||
position: absolute; bottom: 30px; right: 12px; z-index: 100;
|
||||
width: 44px; height: 44px; border-radius: 50%;
|
||||
border: 1px solid #333; background: #1e2027cc; backdrop-filter: blur(10px);
|
||||
color: #ccc; cursor: pointer; display: flex; align-items: center; justify-content: center;
|
||||
transition: all .15s;
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
width: 100%; margin-top: 4px; padding: 8px 8px; border-radius: 6px;
|
||||
border: 1px solid #333; background: #2a2d38;
|
||||
color: #ccc; font-size: .83rem; cursor: pointer; text-align: left;
|
||||
transition: background .15s, color .15s, border-color .15s;
|
||||
}
|
||||
#locate-btn:hover { background: #2a2d38cc; color: #fff; }
|
||||
#locate-btn.locating { color: #2563eb; animation: btn-pulse 1s infinite; }
|
||||
#locate-btn.tracking { color: #2563eb; border-color: #2563eb44; background: #1a2f5acc; }
|
||||
#locate-btn.tracking:hover { background: #1d3560cc; }
|
||||
#locate-btn svg { width: 20px; height: 20px; }
|
||||
#locate-btn:hover { background: #34384a; color: #fff; }
|
||||
#locate-btn.locating { color: #2563eb; border-color: #2563eb44; animation: btn-pulse 1s infinite; }
|
||||
#locate-btn.tracking { color: #2563eb; border-color: #2563eb55; background: #1a2f5a88; }
|
||||
#locate-btn svg { width: 16px; height: 16px; flex-shrink: 0; }
|
||||
|
||||
@keyframes btn-pulse { 0%,100% { opacity: 1; } 50% { opacity: .4; } }
|
||||
|
||||
@@ -215,7 +258,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
|
||||
/* ── Popup ── */
|
||||
#popup {
|
||||
position: absolute; bottom: 84px; right: 12px; z-index: 100;
|
||||
position: absolute; bottom: 30px; right: 12px; z-index: 100;
|
||||
width: min(280px, calc(100vw - 24px));
|
||||
background: #1e2027ee; backdrop-filter: blur(10px);
|
||||
border: 1px solid #333; border-radius: 10px; padding: 14px 16px;
|
||||
@@ -223,7 +266,7 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
#popup.hidden { display: none; }
|
||||
#popup-close {
|
||||
position: absolute; top: 10px; right: 12px;
|
||||
background: none; border: none; color: #666; font-size: .85rem;
|
||||
background: none; border: none; color: #999; font-size: .85rem;
|
||||
cursor: pointer; line-height: 1;
|
||||
}
|
||||
#popup-close:hover { color: #fff; }
|
||||
@@ -255,6 +298,5 @@ body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; b
|
||||
/* ── Mobile ── */
|
||||
@media (max-width: 480px) {
|
||||
#panel { width: calc(100vw - 24px); top: 8px; left: 8px; right: 8px; }
|
||||
#locate-btn { bottom: 20px; right: 8px; }
|
||||
#popup { right: 8px; bottom: 74px; width: calc(100vw - 16px); }
|
||||
#popup { right: 8px; bottom: 20px; width: calc(100vw - 16px); }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user