krz/world-incarceration

An interactive map of world incarceration statistics.

clone: git clone https://gitbay.org/krz/world-incarceration.git

v2: 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}