krz/world-incarceration
An interactive map of world incarceration statistics.
clone: git clone https://gitbay.org/krz/world-incarceration.git
main: assets/css/app.css · raw
1@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap');
2
3/* ── Design tokens ───────────────────────────────────────────────────── */
4:root {
5 --bg: #0d0d14;
6 --surface: #13131e;
7 --surface-2: #1c1c2a;
8 --surface-3: #252535;
9 --border: rgba(255, 255, 255, 0.08);
10 --border-2: rgba(255, 255, 255, 0.14);
11 --accent: #24ab48;
12 --accent-dim: rgba(36, 171, 72, 0.14);
13 --accent-glow: rgba(36, 171, 72, 0.25);
14 --text: #e2e2ef;
15 --text-muted: #5e5e78;
16 --text-soft: #9898b0;
17 --danger: #ef4444;
18 --danger-dim: rgba(239, 68, 68, 0.12);
19 --nav-h: 52px;
20 --radius-sm: 6px;
21 --radius: 10px;
22 --radius-lg: 14px;
23 --radius-pill: 100px;
24 --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4);
25 --shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
26 --shadow-lg: 0 24px 64px rgba(0, 0, 0, 0.7);
27}
28
29/* ── Reset ───────────────────────────────────────────────────────────── */
30*, *::before, *::after { box-sizing: border-box; }
31
32html, body {
33 height: 100%;
34 margin: 0;
35 background: var(--bg);
36 color: var(--text);
37 font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif;
38 font-size: 14px;
39 line-height: 1.5;
40 -webkit-font-smoothing: antialiased;
41 -moz-osx-font-smoothing: grayscale;
42}
43
44a { text-decoration: none; color: inherit; }
45
46/* Bootstrap resets we override */
47.btn { border-radius: var(--radius-sm) !important; }
48.modal-content { border-radius: var(--radius-lg) !important; }
49
50/* ── Navbar ──────────────────────────────────────────────────────────── */
51.navbar {
52 height: var(--nav-h);
53 min-height: var(--nav-h);
54 padding: 0 20px;
55 background: rgba(13, 13, 20, 0.9);
56 backdrop-filter: blur(20px);
57 -webkit-backdrop-filter: blur(20px);
58 border-bottom: 1px solid var(--border);
59 position: sticky;
60 top: 0;
61 z-index: 1000;
62 margin-bottom: 0;
63}
64
65.navbar-brand {
66 font-size: 14px;
67 font-weight: 600;
68 letter-spacing: 0.02em;
69 color: var(--text) !important;
70 opacity: 0.9;
71}
72
73.navbar-nav {
74 gap: 4px;
75 align-items: center;
76}
77
78/* ── Navbar icon buttons ─────────────────────────────────────────────── */
79.nav-icon-btn {
80 width: 36px;
81 height: 36px;
82 padding: 0;
83 display: flex;
84 align-items: center;
85 justify-content: center;
86 background: transparent;
87 border: 1px solid transparent;
88 border-radius: var(--radius-sm) !important;
89 color: var(--text-muted);
90 transition: background 0.15s, color 0.15s, border-color 0.15s;
91 cursor: pointer;
92}
93
94.nav-icon-btn svg path { fill: currentColor; }
95.navbar path { fill: currentColor; }
96
97.nav-icon-btn:hover {
98 background: var(--surface-2);
99 border-color: var(--border);
100 color: var(--text);
101}
102
103.nav-icon-btn:focus-visible {
104 outline: 2px solid var(--accent);
105 outline-offset: 2px;
106}
107
108/* ── Dropdown ────────────────────────────────────────────────────────── */
109.dropdown-menu {
110 background: var(--surface) !important;
111 border: 1px solid var(--border-2) !important;
112 border-radius: var(--radius) !important;
113 padding: 6px !important;
114 box-shadow: var(--shadow) !important;
115 min-width: 160px;
116}
117
118.dropdown-item {
119 border-radius: var(--radius-sm) !important;
120 padding: 9px 12px !important;
121 font-size: 13px;
122 font-weight: 500;
123 color: var(--text-soft) !important;
124 transition: background 0.12s, color 0.12s;
125}
126
127.dropdown-item:hover, .dropdown-item:focus {
128 background: var(--surface-2) !important;
129 color: var(--text) !important;
130}
131
132/* ── Navbar toggler (mobile) ─────────────────────────────────────────── */
133.navbar-toggler {
134 border: 1px solid var(--border) !important;
135 border-radius: var(--radius-sm) !important;
136 padding: 6px 10px;
137}
138
139.navbar-toggler-icon {
140 background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28226,226,239,0.75%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e") !important;
141}
142
143/* ── Map container ───────────────────────────────────────────────────── */
144#map-container {
145 height: calc(100vh - var(--nav-h));
146 width: 100%;
147 background: var(--bg);
148 position: relative;
149}
150
151/* ── Metric pill bar ─────────────────────────────────────────────────── */
152#gbar {
153 position: fixed;
154 bottom: 28px;
155 left: 50%;
156 transform: translateX(-50%);
157 display: flex !important;
158 align-items: center;
159 gap: 3px;
160 padding: 5px;
161 background: rgba(19, 19, 30, 0.94);
162 backdrop-filter: blur(20px);
163 -webkit-backdrop-filter: blur(20px);
164 border: 1px solid var(--border-2);
165 border-radius: var(--radius-pill);
166 box-shadow: var(--shadow), 0 2px 8px rgba(0, 0, 0, 0.4);
167 z-index: 500;
168 white-space: nowrap;
169 /* allow horizontal scroll on very small screens */
170 max-width: calc(100vw - 32px);
171 overflow-x: auto;
172 scrollbar-width: none;
173}
174
175#gbar::-webkit-scrollbar { display: none; }
176
177.metric-btn {
178 padding: 7px 18px;
179 border: none;
180 border-radius: var(--radius-pill);
181 background: transparent;
182 color: var(--text-muted);
183 font-family: inherit;
184 font-size: 12px;
185 font-weight: 500;
186 letter-spacing: 0.025em;
187 cursor: pointer;
188 transition: background 0.15s, color 0.15s;
189 white-space: nowrap;
190}
191
192.metric-btn:hover {
193 background: var(--surface-3);
194 color: var(--text-soft);
195}
196
197.metric-btn.active-metric {
198 background: var(--accent);
199 color: #000;
200 font-weight: 600;
201}
202
203/* ── Tooltip ─────────────────────────────────────────────────────────── */
204.map-tooltip {
205 position: fixed;
206 background: rgba(13, 13, 20, 0.96);
207 color: var(--text);
208 padding: 9px 14px;
209 border: 1px solid var(--border-2);
210 border-radius: var(--radius);
211 pointer-events: none;
212 font-size: 13px;
213 font-weight: 500;
214 font-family: 'Inter', system-ui, sans-serif;
215 opacity: 0;
216 transition: opacity 0.1s;
217 z-index: 9999;
218 box-shadow: var(--shadow);
219}
220
221/* ── Modals ──────────────────────────────────────────────────────────── */
222.modal-content {
223 background: rgba(13, 13, 20, 0.98) !important;
224 border: 1px solid var(--border-2) !important;
225 border-radius: var(--radius-lg) !important;
226 overflow: hidden;
227 box-shadow: var(--shadow-lg);
228 color: var(--text);
229 backdrop-filter: blur(24px);
230 -webkit-backdrop-filter: blur(24px);
231}
232
233.modal-header {
234 background: transparent !important;
235 border-bottom: 1px solid var(--border) !important;
236 padding: 20px 24px;
237}
238
239.modal-title {
240 font-size: 15px !important;
241 font-weight: 600;
242 color: var(--text) !important;
243 letter-spacing: 0.01em;
244}
245
246/* Country modal — accent title */
247#country-modal-title {
248 color: var(--accent) !important;
249}
250
251.modal-body {
252 background: transparent !important;
253 padding: 24px !important;
254 color: var(--text);
255}
256
257.modal-footer {
258 background: transparent !important;
259 border-top: 1px solid var(--border) !important;
260 padding: 16px 24px !important;
261 gap: 8px;
262}
263
264/* Modal body typography */
265.modal-body p {
266 margin-bottom: 14px;
267 font-size: 14px;
268 line-height: 1.7;
269}
270
271.modal-body p:last-child { margin-bottom: 0; }
272
273.modal-body p b {
274 color: var(--text-soft);
275 font-weight: 500;
276 margin-right: 4px;
277}
278
279.modal-body hr {
280 border: none;
281 border-top: 1px solid var(--border);
282 margin: 20px 0;
283}
284
285/* ── Modal buttons ───────────────────────────────────────────────────── */
286.btn-modal-primary {
287 padding: 9px 20px;
288 background: var(--accent);
289 color: #000;
290 border: none;
291 border-radius: var(--radius-sm) !important;
292 font-family: inherit;
293 font-size: 13px;
294 font-weight: 600;
295 cursor: pointer;
296 transition: opacity 0.15s;
297}
298
299.btn-modal-primary:hover { opacity: 0.85; }
300
301.btn-modal-ghost {
302 padding: 9px 20px;
303 background: transparent;
304 color: var(--text-soft);
305 border: 1px solid var(--border-2);
306 border-radius: var(--radius-sm) !important;
307 font-family: inherit;
308 font-size: 13px;
309 font-weight: 500;
310 cursor: pointer;
311 transition: background 0.15s, color 0.15s;
312}
313
314.btn-modal-ghost:hover {
315 background: var(--surface-2);
316 color: var(--text);
317}
318
319.btn-modal-link {
320 padding: 9px 20px;
321 background: transparent;
322 color: var(--accent);
323 border: none;
324 border-radius: var(--radius-sm) !important;
325 font-family: inherit;
326 font-size: 13px;
327 font-weight: 500;
328 cursor: pointer;
329 text-decoration: none;
330 display: inline-flex;
331 align-items: center;
332}
333
334/* ── Alert ───────────────────────────────────────────────────────────── */
335.alert-danger {
336 background: var(--danger-dim) !important;
337 border: 1px solid rgba(239, 68, 68, 0.25) !important;
338 border-radius: var(--radius) !important;
339 color: #fca5a5 !important;
340 padding: 12px 16px;
341 margin-bottom: 16px;
342 font-size: 13px;
343}
344
345.text-danger { color: var(--danger) !important; }
346
347/* ── Selects ─────────────────────────────────────────────────────────── */
348select {
349 appearance: none;
350 -webkit-appearance: none;
351 background-color: var(--surface-2);
352 background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='none' stroke='%235e5e78' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round' d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
353 background-repeat: no-repeat;
354 background-position: right 12px center;
355 border: 1px solid var(--border-2);
356 border-radius: var(--radius);
357 color: var(--text);
358 cursor: pointer;
359 font-family: inherit;
360 font-size: 13px;
361 padding: 10px 36px 10px 12px;
362 width: 100%;
363 transition: border-color 0.15s;
364}
365
366select:focus {
367 outline: none;
368 border-color: var(--accent);
369 box-shadow: 0 0 0 3px var(--accent-dim);
370}
371
372select option { background: var(--surface); }
373
374/* ── Table ───────────────────────────────────────────────────────────── */
375.table {
376 color: var(--text);
377 border-collapse: collapse;
378 width: 100%;
379 font-size: 13px;
380}
381
382.table th {
383 color: var(--text-muted);
384 font-size: 11px;
385 font-weight: 600;
386 text-transform: uppercase;
387 letter-spacing: 0.07em;
388 padding: 0 12px 10px;
389 border-bottom: 1px solid var(--border-2);
390}
391
392.table td {
393 padding: 12px;
394 border-bottom: 1px solid rgba(255, 255, 255, 0.04);
395 vertical-align: top;
396 line-height: 1.5;
397}
398
399.table td:first-child {
400 color: var(--text-soft);
401 font-size: 12px;
402 font-weight: 500;
403 white-space: nowrap;
404 padding-right: 20px;
405}
406
407.table tbody tr:last-child td { border-bottom: none; }
408
409/* ── Chart containers ────────────────────────────────────────────────── */
410#myChart2,
411#myNextChart {
412 min-height: 340px;
413 background: transparent;
414}
415
416/* D3 chart axis styling */
417#myChart2 .domain,
418#myNextChart .domain,
419#myChart2 .tick line,
420#myNextChart .tick line {
421 stroke: var(--border-2);
422}
423
424/* ── Info modal reference links ──────────────────────────────────────── */
425.modal-body .ref-btn {
426 display: block;
427 padding: 10px 16px;
428 background: var(--surface-2);
429 border: 1px solid var(--border);
430 border-radius: var(--radius);
431 color: var(--text-soft);
432 font-size: 13px;
433 font-weight: 500;
434 text-align: center;
435 transition: background 0.15s, color 0.15s, border-color 0.15s;
436}
437
438.modal-body .ref-btn:hover {
439 background: var(--surface-3);
440 border-color: var(--border-2);
441 color: var(--text);
442}