Skip to content

Commit 4521df3

Browse files
committed
fix(ui): neighborhood sidebar fix; polish control sidebar indicators; keep demographic overlays in neighborhood mode
- Fix neighborhood "All" and city average showing Unavailable - Add View/Heatmap column headers, icon-only heatmap buttons, and heatmap deselect on re-click - Hide View controls at neighborhood scale; animate control sidebar expand/collapse and button presses - Keep Pop. Kids and SES Clusters toggles visible in neighborhood mode - Remove explainer sidebar blinking dot and category row accent border
1 parent 9e88185 commit 4521df3

14 files changed

Lines changed: 426 additions & 105 deletions

docs/control-sidebar.css

Lines changed: 174 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@
122122
border-radius: 8px;
123123
padding: 2px;
124124
gap: 2px;
125+
transition: background 0.15s ease;
125126
}
126127

127128
.radio-option {
@@ -133,28 +134,33 @@
133134
padding: 6px 10px;
134135
border-radius: 6px;
135136
border: 1px solid #e5e7eb;
136-
transition: all 0.2s;
137+
transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
137138
flex: 1;
138139
justify-content: center;
139140
}
140141

142+
.radio-option:active {
143+
transform: scale(0.96);
144+
}
145+
141146
.segmented-options > label {
142147
border: none;
143148
background: transparent;
144149
border-radius: 6px;
145150
color: #6b7280;
146151
box-shadow: none;
147-
}
148-
149-
.radio-option:hover {
150-
border-color: #93c5fd;
152+
transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.12s ease;
151153
}
152154

153155
.segmented-options > label:hover {
154156
border-color: transparent;
155157
color: #374151;
156158
}
157159

160+
.segmented-options > label:active {
161+
transform: scale(0.96);
162+
}
163+
158164
.radio-option input {
159165
display: none;
160166
}
@@ -185,11 +191,15 @@
185191
padding: 6px 10px;
186192
border-radius: 6px;
187193
border: 1px solid #e5e7eb;
188-
transition: all 0.2s;
194+
transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.12s ease;
189195
flex: 1;
190196
justify-content: center;
191197
}
192198

199+
.radio-option:hover {
200+
border-color: #93c5fd;
201+
}
202+
193203
.segmented-options > label input {
194204
display: none;
195205
}
@@ -210,7 +220,11 @@
210220
align-items: center;
211221
justify-content: space-between;
212222
gap: 8px;
213-
transition: all 0.2s;
223+
transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
224+
}
225+
226+
.filter-btn:active {
227+
transform: scale(0.98);
214228
}
215229

216230
.filter-btn-label-wrap {
@@ -372,7 +386,7 @@
372386
background: transparent;
373387
border-radius: 6px;
374388
cursor: pointer;
375-
transition: all 0.2s;
389+
transition: background 0.15s ease, color 0.15s ease, box-shadow 0.15s ease, transform 0.12s ease;
376390
}
377391

378392
.radius-opt {
@@ -393,10 +407,9 @@
393407
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
394408
}
395409

396-
.hint {
397-
font-size: var(--control-sidebar-font-micro);
398-
color: #9ca3af;
399-
margin-top: 6px;
410+
.radius-opt:active,
411+
.mode-opt:active {
412+
transform: scale(0.96);
400413
}
401414

402415
.mode-toggle {
@@ -405,6 +418,7 @@
405418
background: #f3f4f6;
406419
border-radius: 10px;
407420
padding: 3px;
421+
transition: background 0.15s ease;
408422
}
409423

410424
.mode-opt {
@@ -420,6 +434,17 @@
420434

421435
.mode-opt svg {
422436
flex-shrink: 0;
437+
transition: transform 0.15s ease;
438+
}
439+
440+
.mode-opt.active svg {
441+
transform: scale(1.05);
442+
}
443+
444+
.hint {
445+
font-size: var(--control-sidebar-font-micro);
446+
color: #9ca3af;
447+
margin-top: 6px;
423448
}
424449

425450
#indicators-section.is-basemap-only .indicator-row--aux {
@@ -432,6 +457,38 @@
432457
gap: 2px;
433458
}
434459

460+
.indicator-group {
461+
display: flex;
462+
flex-direction: column;
463+
gap: 2px;
464+
}
465+
466+
.indicator-subs {
467+
display: grid;
468+
grid-template-rows: 0fr;
469+
width: 100%;
470+
transition: grid-template-rows 0.32s cubic-bezier(0.4, 0, 0.2, 1);
471+
}
472+
473+
.indicator-subs.is-open {
474+
grid-template-rows: 1fr;
475+
}
476+
477+
.indicator-subs-inner {
478+
display: flex;
479+
flex-direction: column;
480+
gap: 2px;
481+
min-height: 0;
482+
overflow: hidden;
483+
padding-top: 0;
484+
transition: padding-top 0.32s cubic-bezier(0.4, 0, 0.2, 1);
485+
}
486+
487+
.indicator-subs.is-open .indicator-subs-inner {
488+
padding-top: 2px;
489+
padding-bottom: 2px;
490+
}
491+
435492
.indicator-row {
436493
display: flex;
437494
align-items: center;
@@ -441,6 +498,7 @@
441498
border-radius: 8px;
442499
background: #fff;
443500
border: 1px solid rgba(15, 23, 42, 0.06);
501+
transition: background 0.15s ease;
444502
}
445503

446504
.indicator-row--sub {
@@ -455,7 +513,10 @@
455513

456514
.indicator-row--category {
457515
background: #fcfcfb;
458-
border-left: 3px solid var(--indicator-accent, transparent);
516+
}
517+
518+
.indicator-row--category:hover {
519+
background: #f8fafc;
459520
}
460521

461522
.indicator-row--category .indicator-label-wrap {
@@ -467,12 +528,17 @@
467528
padding: 4px;
468529
background: #f6f8fb;
469530
border-style: dashed;
531+
transition: background 0.15s ease;
470532
}
471533

472534
.indicator-row--aux .segmented-options {
473535
width: 100%;
474536
}
475537

538+
.indicator-row--aux .segmented-options > label:hover {
539+
color: #2563eb;
540+
}
541+
476542
.indicator-label-wrap {
477543
display: flex;
478544
align-items: center;
@@ -518,32 +584,103 @@
518584
color: #6b7280;
519585
cursor: pointer;
520586
flex-shrink: 0;
521-
transition: transform 0.15s ease, color 0.15s ease;
587+
transition: transform 0.28s ease, color 0.15s ease, background 0.15s ease;
522588
}
523589

524590
.indicator-collapse-btn:hover {
525591
color: #2563eb;
526592
background: rgba(37, 99, 235, 0.08);
527593
}
528594

595+
.indicator-collapse-btn:active {
596+
transform: scale(0.92);
597+
}
598+
529599
.indicator-collapse-btn.is-expanded {
530600
transform: rotate(90deg);
531601
}
532602

603+
.indicator-collapse-btn.is-expanded:active {
604+
transform: rotate(90deg) scale(0.92);
605+
}
606+
533607
.indicator-label {
534608
flex: 1;
535609
min-width: 0;
536610
color: #1f2937;
537611
line-height: 1.3;
538612
}
539613

614+
.indicators-weighted-block {
615+
margin-bottom: 4px;
616+
}
617+
618+
.indicators-section-head {
619+
display: flex;
620+
align-items: center;
621+
justify-content: space-between;
622+
gap: 8px;
623+
padding: 0 8px 6px;
624+
}
625+
626+
.indicators-section-head .section-title {
627+
margin-bottom: 0;
628+
}
629+
540630
.indicator-actions {
541631
display: flex;
542632
align-items: center;
543-
gap: 4px;
544633
flex-shrink: 0;
545634
}
546635

636+
.indicator-actions-cols {
637+
display: grid;
638+
grid-template-columns: 34px 40px;
639+
gap: 10px;
640+
align-items: center;
641+
justify-items: center;
642+
}
643+
644+
.indicator-actions-cols--titles {
645+
flex-shrink: 0;
646+
}
647+
648+
.indicator-action-title {
649+
display: inline-flex;
650+
align-items: center;
651+
justify-content: center;
652+
width: 100%;
653+
font-size: var(--control-sidebar-font-micro);
654+
font-weight: 700;
655+
color: #9ca3af;
656+
text-transform: uppercase;
657+
letter-spacing: 0.03em;
658+
line-height: 1;
659+
white-space: nowrap;
660+
cursor: default;
661+
}
662+
663+
#indicators-section.is-neighborhood-scale .indicator-action-title--view,
664+
#indicators-section.is-neighborhood-scale .indicator-show-btn {
665+
display: none;
666+
}
667+
668+
#indicators-section.is-neighborhood-scale .indicator-actions-cols,
669+
#indicators-section.is-neighborhood-scale .indicator-actions-cols--titles {
670+
grid-template-columns: 40px;
671+
}
672+
673+
.indicator-show-btn,
674+
.indicator-heat-btn {
675+
width: 100%;
676+
justify-content: center;
677+
}
678+
679+
.indicator-btn--icon-only {
680+
padding: 4px 6px;
681+
gap: 0;
682+
}
683+
547684
.indicator-btn {
548685
display: inline-flex;
549686
align-items: center;
@@ -556,14 +693,18 @@
556693
font-size: var(--control-sidebar-font-label);
557694
font-weight: 600;
558695
cursor: pointer;
559-
transition: background 0.15s, border-color 0.15s, color 0.15s;
696+
transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.12s ease;
560697
}
561698

562699
.indicator-btn:hover:not(:disabled) {
563700
border-color: #93c5fd;
564701
color: #2563eb;
565702
}
566703

704+
.indicator-btn:active:not(:disabled) {
705+
transform: scale(0.96);
706+
}
707+
567708
.indicator-btn.is-active {
568709
border-color: #2563eb;
569710
background: #eff6ff;
@@ -883,3 +1024,20 @@
8831024
-webkit-tap-highlight-color: transparent;
8841025
}
8851026
}
1027+
1028+
@media (prefers-reduced-motion: reduce) {
1029+
.indicator-subs,
1030+
.indicator-subs-inner,
1031+
.indicator-collapse-btn,
1032+
.indicator-btn,
1033+
.indicator-row,
1034+
.mode-opt,
1035+
.mode-opt svg,
1036+
.radius-opt,
1037+
.segmented-options > label,
1038+
.filter-btn,
1039+
.metric-options.segmented-options,
1040+
.radius-toggle {
1041+
transition: none;
1042+
}
1043+
}

docs/index.html

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,6 @@ <h2>Cities for Children</h2>
101101
<div class="score-explain-hero-metrics" id="score-explain-sidebar-hero"></div>
102102
<div class="score-explain-header-meta" id="score-explain-header-meta">
103103
<div class="score-explain-building-ctx" id="score-explain-building-ctx" hidden>
104-
<span class="building-ctx-dot" aria-hidden="true"></span>
105104
<div class="building-ctx-text">
106105
<span class="building-ctx-id" id="score-explain-building-ctx-id"></span>
107106
<span class="building-ctx-coords" id="score-explain-building-ctx-coords" hidden></span>

docs/js/core/appState.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@
4848
getLayerVisibility: function () { return copyLayerVisibility(layerVisibility); },
4949
setLayerVisibility: function (value) { layerVisibility = copyLayerVisibility(value); },
5050
getActiveHeatmapId: function () { return activeHeatmapId; },
51-
setActiveHeatmapId: function (value) { activeHeatmapId = value || "u95.overall"; },
51+
setActiveHeatmapId: function (value) {
52+
activeHeatmapId = value == null || value === "" ? null : value;
53+
},
5254

5355
getSelectedAmenityTypes: function () { return new Set(selectedAmenityTypes); },
5456
setSelectedAmenityTypes: function (value) { selectedAmenityTypes = copySet(value); },

docs/js/map/mapRenderers.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,14 @@
14011401
var isWeighted = d.getScoreMode() === "weighted";
14021402
var selectedAmenityTypes = d.getSelectedAmenityTypes();
14031403
var hasExpandedSelection = selectedAmenityTypes.size > 0;
1404+
var activeMetric = getActiveMetricFromDeps(d);
1405+
1406+
if (isWeighted && !activeMetric) {
1407+
if (d.map.getLayer(d.buildingsFillLayerId)) {
1408+
d.map.setPaintProperty(d.buildingsFillLayerId, "fill-color", "#cbd5e1");
1409+
}
1410+
return;
1411+
}
14041412

14051413
if (isWeighted || hasExpandedSelection) {
14061414
var scores = d.collectBuildingScores();

0 commit comments

Comments
 (0)