diff options
| author | Christian Cleberg <[email protected]> | 2026-04-17 19:51:24 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-17 19:51:24 -0500 |
| commit | 92c574a2f415f50115831e4a125ce1ca95135be3 (patch) | |
| tree | bd64cbc7561fe5494cfc8e2f0f4360d4c9184ac2 | |
| parent | 623ae07ebacb9d596b225179727dc87641ad1cca (diff) | |
| download | world-incarceration-92c574a2f415f50115831e4a125ce1ca95135be3.tar.gz world-incarceration-92c574a2f415f50115831e4a125ce1ca95135be3.tar.bz2 world-incarceration-92c574a2f415f50115831e4a125ce1ca95135be3.zip | |
revamp UI/UX with dark design system and modern layoutv2
Replace Bootstrap color utilities and legacy layout patterns with a
cohesive dark-mode design system. Key changes:
- CSS: full rewrite using custom property tokens (--bg, --surface,
--accent, --text-muted, etc.), Inter font, glassmorphism modals
(backdrop-filter + semi-transparent backgrounds), and a fixed
pill-bar metric selector centered at the bottom of the viewport
- Navbar: unified nav-icon-btn style for all icon buttons, removed
the gradient-toggle collapse button, settings dropdown aligned end
- Metric bar: promoted from Bootstrap collapse to always-visible
fixed pill bar; metric-btn replaces btn; active-metric pre-applied
to match default currentMetric
- Modals: removed inline bg overrides, h4 → h5, custom close buttons
(nav-icon-btn + SVG), btn-modal-primary / btn-modal-ghost / ref-btn
replace Bootstrap color variants
- Dropped Font Awesome dependency (all icons are inline SVGs)
| -rw-r--r-- | assets/css/app.css | 473 | ||||
| -rw-r--r-- | index.html | 184 |
2 files changed, 484 insertions, 173 deletions
diff --git a/assets/css/app.css b/assets/css/app.css index af5e95c..d5b2f84 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -1,145 +1,442 @@ -html { +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap'); + +/* ── Design tokens ───────────────────────────────────────────────────── */ +:root { + --bg: #0d0d14; + --surface: #13131e; + --surface-2: #1c1c2a; + --surface-3: #252535; + --border: rgba(255, 255, 255, 0.08); + --border-2: rgba(255, 255, 255, 0.14); + --accent: #24ab48; + --accent-dim: rgba(36, 171, 72, 0.14); + --accent-glow: rgba(36, 171, 72, 0.25); + --text: #e2e2ef; + --text-muted: #5e5e78; + --text-soft: #9898b0; + --danger: #ef4444; + --danger-dim: rgba(239, 68, 68, 0.12); + --nav-h: 52px; + --radius-sm: 6px; + --radius: 10px; + --radius-lg: 14px; + --radius-pill: 100px; + --shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.4); + --shadow: 0 8px 32px rgba(0, 0, 0, 0.5); + --shadow-lg: 0 24px 64px rgba(0, 0, 0, 0.7); +} + +/* ── Reset ───────────────────────────────────────────────────────────── */ +*, *::before, *::after { box-sizing: border-box; } + +html, body { height: 100%; margin: 0; + background: var(--bg); + color: var(--text); + font-family: 'Inter', system-ui, -apple-system, BlinkMacSystemFont, sans-serif; + font-size: 14px; + line-height: 1.5; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } -body { - background: #161616; +a { text-decoration: none; color: inherit; } + +/* Bootstrap resets we override */ +.btn { border-radius: var(--radius-sm) !important; } +.modal-content { border-radius: var(--radius-lg) !important; } + +/* ── Navbar ──────────────────────────────────────────────────────────── */ +.navbar { + height: var(--nav-h); + min-height: var(--nav-h); + padding: 0 20px; + background: rgba(13, 13, 20, 0.9); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border-bottom: 1px solid var(--border); + position: sticky; + top: 0; + z-index: 1000; + margin-bottom: 0; } -a, -.fa-question-circle { - text-decoration: none; +.navbar-brand { + font-size: 14px; + font-weight: 600; + letter-spacing: 0.02em; + color: var(--text) !important; + opacity: 0.9; } -.btn, -.nav-link, -.dropdown-menu, -.dropdown-item, -.modal-content { - border-radius: 0; +.navbar-nav { + gap: 4px; + align-items: center; } -.navbar { - background: #161616; - margin-bottom: 0; +/* ── Navbar icon buttons ─────────────────────────────────────────────── */ +.nav-icon-btn { + width: 36px; + height: 36px; + padding: 0; + display: flex; + align-items: center; + justify-content: center; + background: transparent; + border: 1px solid transparent; + border-radius: var(--radius-sm) !important; + color: var(--text-muted); + transition: background 0.15s, color 0.15s, border-color 0.15s; + cursor: pointer; +} + +.nav-icon-btn svg path { fill: currentColor; } +.navbar path { fill: currentColor; } + +.nav-icon-btn:hover { + background: var(--surface-2); + border-color: var(--border); + color: var(--text); +} + +.nav-icon-btn:focus-visible { + outline: 2px solid var(--accent); + outline-offset: 2px; +} + +/* ── Dropdown ────────────────────────────────────────────────────────── */ +.dropdown-menu { + background: var(--surface) !important; + border: 1px solid var(--border-2) !important; + border-radius: var(--radius) !important; + padding: 6px !important; + box-shadow: var(--shadow) !important; + min-width: 160px; +} + +.dropdown-item { + border-radius: var(--radius-sm) !important; + padding: 9px 12px !important; + font-size: 13px; + font-weight: 500; + color: var(--text-soft) !important; + transition: background 0.12s, color 0.12s; +} + +.dropdown-item:hover, .dropdown-item:focus { + background: var(--surface-2) !important; + color: var(--text) !important; } -.modal-title path, -.navbar path { - fill: white; +/* ── Navbar toggler (mobile) ─────────────────────────────────────────── */ +.navbar-toggler { + border: 1px solid var(--border) !important; + border-radius: var(--radius-sm) !important; + padding: 6px 10px; } -#settings-icon { - fill: black; +.navbar-toggler-icon { + 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; } +/* ── Map container ───────────────────────────────────────────────────── */ +#map-container { + height: calc(100vh - var(--nav-h)); + width: 100%; + background: var(--bg); + position: relative; +} + +/* ── Metric pill bar ─────────────────────────────────────────────────── */ +#gbar { + position: fixed; + bottom: 28px; + left: 50%; + transform: translateX(-50%); + display: flex !important; + align-items: center; + gap: 3px; + padding: 5px; + background: rgba(19, 19, 30, 0.94); + backdrop-filter: blur(20px); + -webkit-backdrop-filter: blur(20px); + border: 1px solid var(--border-2); + border-radius: var(--radius-pill); + box-shadow: var(--shadow), 0 2px 8px rgba(0, 0, 0, 0.4); + z-index: 500; + white-space: nowrap; + /* allow horizontal scroll on very small screens */ + max-width: calc(100vw - 32px); + overflow-x: auto; + scrollbar-width: none; +} + +#gbar::-webkit-scrollbar { display: none; } + +.metric-btn { + padding: 7px 18px; + border: none; + border-radius: var(--radius-pill); + background: transparent; + color: var(--text-muted); + font-family: inherit; + font-size: 12px; + font-weight: 500; + letter-spacing: 0.025em; + cursor: pointer; + transition: background 0.15s, color 0.15s; + white-space: nowrap; +} + +.metric-btn:hover { + background: var(--surface-3); + color: var(--text-soft); +} + +.metric-btn.active-metric { + background: var(--accent); + color: #000; + font-weight: 600; +} + +/* ── Tooltip ─────────────────────────────────────────────────────────── */ +.map-tooltip { + position: fixed; + background: rgba(13, 13, 20, 0.96); + color: var(--text); + padding: 9px 14px; + border: 1px solid var(--border-2); + border-radius: var(--radius); + pointer-events: none; + font-size: 13px; + font-weight: 500; + font-family: 'Inter', system-ui, sans-serif; + opacity: 0; + transition: opacity 0.1s; + z-index: 9999; + box-shadow: var(--shadow); +} + +/* ── Modals ──────────────────────────────────────────────────────────── */ .modal-content { - border: 1px solid #fff; + background: rgba(13, 13, 20, 0.98) !important; + border: 1px solid var(--border-2) !important; + border-radius: var(--radius-lg) !important; + overflow: hidden; + box-shadow: var(--shadow-lg); + color: var(--text); + backdrop-filter: blur(24px); + -webkit-backdrop-filter: blur(24px); } .modal-header { - background-color: #24ab48; - border-bottom: #000; - color: white; + background: transparent !important; + border-bottom: 1px solid var(--border) !important; + padding: 20px 24px; +} + +.modal-title { + font-size: 15px !important; + font-weight: 600; + color: var(--text) !important; + letter-spacing: 0.01em; +} + +/* Country modal — accent title */ +#country-modal-title { + color: var(--accent) !important; +} + +.modal-body { + background: transparent !important; + padding: 24px !important; + color: var(--text); } -.modal-body, .modal-footer { - background-color: #000; - color: #ffffff; + background: transparent !important; + border-top: 1px solid var(--border) !important; + padding: 16px 24px !important; + gap: 8px; } -.alert { - background-color: rgb(66, 133, 244); - background-color: rgba(66, 133, 244, 0.5); - color: #ffffff; - margin: 1.5rem auto; - width: 90%; +/* Modal body typography */ +.modal-body p { + margin-bottom: 14px; + font-size: 14px; + line-height: 1.7; } -#gradientbtn { - background-color: #9966ff; - color: #ffffff; +.modal-body p:last-child { margin-bottom: 0; } + +.modal-body p b { + color: var(--text-soft); + font-weight: 500; + margin-right: 4px; } -#totPop, -#perCapita, -#women, -#juveniles, -#occupancy { - background-color: #9966ff; - color: #ffffff; - margin: 5px; - padding: 10px; +.modal-body hr { + border: none; + border-top: 1px solid var(--border); + margin: 20px 0; +} + +/* ── Modal buttons ───────────────────────────────────────────────────── */ +.btn-modal-primary { + padding: 9px 20px; + background: var(--accent); + color: #000; + border: none; + border-radius: var(--radius-sm) !important; + font-family: inherit; + font-size: 13px; + font-weight: 600; + cursor: pointer; + transition: opacity 0.15s; +} + +.btn-modal-primary:hover { opacity: 0.85; } + +.btn-modal-ghost { + padding: 9px 20px; + background: transparent; + color: var(--text-soft); + border: 1px solid var(--border-2); + border-radius: var(--radius-sm) !important; + font-family: inherit; + font-size: 13px; + font-weight: 500; + cursor: pointer; + transition: background 0.15s, color 0.15s; +} + +.btn-modal-ghost:hover { + background: var(--surface-2); + color: var(--text); +} + +.btn-modal-link { + padding: 9px 20px; + background: transparent; + color: var(--accent); + border: none; + border-radius: var(--radius-sm) !important; + font-family: inherit; + font-size: 13px; + font-weight: 500; + cursor: pointer; + text-decoration: none; + display: inline-flex; + align-items: center; +} + +/* ── Alert ───────────────────────────────────────────────────────────── */ +.alert-danger { + background: var(--danger-dim) !important; + border: 1px solid rgba(239, 68, 68, 0.25) !important; + border-radius: var(--radius) !important; + color: #fca5a5 !important; + padding: 12px 16px; + margin-bottom: 16px; + font-size: 13px; } +.text-danger { color: var(--danger) !important; } + +/* ── Selects ─────────────────────────────────────────────────────────── */ select { - -webkit-appearance: none; - -moz-appearance: none; appearance: none; - background: url(../images/down-arrow.png) no-repeat #24ab48; - background-color: #000; - background-position: 95%; - border: 1px solid #24ab48; - border-radius: 0; - color: white; + -webkit-appearance: none; + background-color: var(--surface-2); + 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"); + background-repeat: no-repeat; + background-position: right 12px center; + border: 1px solid var(--border-2); + border-radius: var(--radius); + color: var(--text); cursor: pointer; - font-size: 16px; - overflow: hidden; - padding: 0.5rem; + font-family: inherit; + font-size: 13px; + padding: 10px 36px 10px 12px; width: 100%; + transition: border-color 0.15s; } -select::-ms-expand { - display: none; +select:focus { + outline: none; + border-color: var(--accent); + box-shadow: 0 0 0 3px var(--accent-dim); } +select option { background: var(--surface); } + +/* ── Table ───────────────────────────────────────────────────────────── */ .table { - color: #ddd; + color: var(--text); + border-collapse: collapse; + width: 100%; + font-size: 13px; } -th { - color: #fff; - font-size: 16px; +.table th { + color: var(--text-muted); + font-size: 11px; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.07em; + padding: 0 12px 10px; + border-bottom: 1px solid var(--border-2); } -#map-container { - height: calc(100vh - 56px); - width: 100%; - background: #161616; +.table td { + padding: 12px; + border-bottom: 1px solid rgba(255, 255, 255, 0.04); + vertical-align: top; + line-height: 1.5; } -.map-tooltip { - position: absolute; - background: #1a1a1a; - color: #fff; - padding: 8px 12px; - border: 1px solid #24ab48; - border-radius: 0; - pointer-events: none; - font-size: 13px; - opacity: 0; - transition: opacity 0.1s; - z-index: 9999; +.table td:first-child { + color: var(--text-soft); + font-size: 12px; + font-weight: 500; + white-space: nowrap; + padding-right: 20px; } -/* chart containers inside graph modal */ +.table tbody tr:last-child td { border-bottom: none; } + +/* ── Chart containers ────────────────────────────────────────────────── */ #myChart2, #myNextChart { - min-height: 300px; - background: #000; -} - -/* active metric button highlight */ -.active-metric { - outline: 2px solid #fff; + min-height: 340px; + background: transparent; } -/* D3 axis lines */ +/* D3 chart axis styling */ #myChart2 .domain, #myNextChart .domain, #myChart2 .tick line, #myNextChart .tick line { - stroke: #555; + stroke: var(--border-2); +} + +/* ── Info modal reference links ──────────────────────────────────────── */ +.modal-body .ref-btn { + display: block; + padding: 10px 16px; + background: var(--surface-2); + border: 1px solid var(--border); + border-radius: var(--radius); + color: var(--text-soft); + font-size: 13px; + font-weight: 500; + text-align: center; + transition: background 0.15s, color 0.15s, border-color 0.15s; +} + +.modal-body .ref-btn:hover { + background: var(--surface-3); + border-color: var(--border-2); + color: var(--text); } @@ -24,17 +24,23 @@ <link rel="manifest" href="./assets/images/icons/manifest.json" /> <meta name="msapplication-TileColor" content="#ffffff" /> <meta name="msapplication-TileImage" content="./assets/images/icons/ms-icon-144x144.png" /> - <meta name="theme-color" content="#ffffff" /> + <meta name="theme-color" content="#0d0d14" /> + + <!-- Fonts --> + <link rel="preconnect" href="https://fonts.googleapis.com" /> + <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> + <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600&display=swap" rel="stylesheet" /> + <link rel="stylesheet" href="./assets/css/bootstrap-5.0.0.min.css" /> - <link rel="stylesheet" href="./assets/css/fontawesome-5.1.10.min.css" /> <link rel="stylesheet" href="./assets/css/app.css" /> </head> <body> - <!-- navbar --> - <nav class="navbar navbar-expand-lg navbar-dark"> + <!-- ── Navbar ──────────────────────────────────────────────────────── --> + <nav class="navbar navbar-expand-lg"> <div class="container-fluid"> - <a class="navbar-brand mx-2" href="./">World Incarceration</a> + <a class="navbar-brand" href="./">World Incarceration</a> + <button class="navbar-toggler" type="button" @@ -46,53 +52,41 @@ > <span class="navbar-toggler-icon"></span> </button> + <div class="collapse navbar-collapse" id="navbarSupportedContent"> <ul class="navbar-nav ms-auto me-0 mb-2 mb-lg-0"> <!-- settings dropdown --> <li class="nav-item dropdown"> <button - class="btn btn-warning" + class="nav-icon-btn" data-bs-toggle="dropdown" aria-expanded="false" + title="Settings" > - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path id="settings-icon" d="M24 14.187v-4.374c-2.148-.766-2.726-.802-3.027-1.529-.303-.729.083-1.169 1.059-3.223l-3.093-3.093c-2.026.963-2.488 1.364-3.224 1.059-.727-.302-.768-.889-1.527-3.027h-4.375c-.764 2.144-.8 2.725-1.529 3.027-.752.313-1.203-.1-3.223-1.059l-3.093 3.093c.977 2.055 1.362 2.493 1.059 3.224-.302.727-.881.764-3.027 1.528v4.375c2.139.76 2.725.8 3.027 1.528.304.734-.081 1.167-1.059 3.223l3.093 3.093c1.999-.95 2.47-1.373 3.223-1.059.728.302.764.88 1.529 3.027h4.374c.758-2.131.799-2.723 1.537-3.031.745-.308 1.186.099 3.215 1.062l3.093-3.093c-.975-2.05-1.362-2.492-1.059-3.223.3-.726.88-.763 3.027-1.528zm-4.875.764c-.577 1.394-.068 2.458.488 3.578l-1.084 1.084c-1.093-.543-2.161-1.076-3.573-.49-1.396.581-1.79 1.693-2.188 2.877h-1.534c-.398-1.185-.791-2.297-2.183-2.875-1.419-.588-2.507-.045-3.579.488l-1.083-1.084c.557-1.118 1.066-2.18.487-3.58-.579-1.391-1.691-1.784-2.876-2.182v-1.533c1.185-.398 2.297-.791 2.875-2.184.578-1.394.068-2.459-.488-3.579l1.084-1.084c1.082.538 2.162 1.077 3.58.488 1.392-.577 1.785-1.69 2.183-2.875h1.534c.398 1.185.792 2.297 2.184 2.875 1.419.588 2.506.045 3.579-.488l1.084 1.084c-.556 1.121-1.065 2.187-.488 3.58.577 1.391 1.689 1.784 2.875 2.183v1.534c-1.188.398-2.302.791-2.877 2.183zm-7.125-5.951c1.654 0 3 1.346 3 3s-1.346 3-3 3-3-1.346-3-3 1.346-3 3-3zm0-2c-2.762 0-5 2.238-5 5s2.238 5 5 5 5-2.238 5-5-2.238-5-5-5z"/> + <!-- gear icon --> + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"> + <path d="M24 14.187v-4.374c-2.148-.766-2.726-.802-3.027-1.529-.303-.729.083-1.169 1.059-3.223l-3.093-3.093c-2.026.963-2.488 1.364-3.224 1.059-.727-.302-.768-.889-1.527-3.027h-4.375c-.764 2.144-.8 2.725-1.529 3.027-.752.313-1.203-.1-3.223-1.059l-3.093 3.093c.977 2.055 1.362 2.493 1.059 3.224-.302.727-.881.764-3.027 1.528v4.375c2.139.76 2.725.8 3.027 1.528.304.734-.081 1.167-1.059 3.223l3.093 3.093c1.999-.95 2.47-1.373 3.223-1.059.728.302.764.88 1.529 3.027h4.374c.758-2.131.799-2.723 1.537-3.031.745-.308 1.186.099 3.215 1.062l3.093-3.093c-.975-2.05-1.362-2.492-1.059-3.223.3-.726.88-.763 3.027-1.528zm-4.875.764c-.577 1.394-.068 2.458.488 3.578l-1.084 1.084c-1.093-.543-2.161-1.076-3.573-.49-1.396.581-1.79 1.693-2.188 2.877h-1.534c-.398-1.185-.791-2.297-2.183-2.875-1.419-.588-2.507-.045-3.579.488l-1.083-1.084c.557-1.118 1.066-2.18.487-3.58-.579-1.391-1.691-1.784-2.876-2.182v-1.533c1.185-.398 2.297-.791 2.875-2.184.578-1.394.068-2.459-.488-3.579l1.084-1.084c1.082.538 2.162 1.077 3.58.488 1.392-.577 1.785-1.69 2.183-2.875h1.534c.398 1.185.792 2.297 2.184 2.875 1.419.588 2.506.045 3.579-.488l1.084 1.084c-.556 1.121-1.065 2.187-.488 3.58.577 1.391 1.689 1.784 2.875 2.183v1.534c-1.188.398-2.302.791-2.877 2.183zm-7.125-5.951c1.654 0 3 1.346 3 3s-1.346 3-3 3-3-1.346-3-3 1.346-3 3-3zm0-2c-2.762 0-5 2.238-5 5s2.238 5 5 5 5-2.238 5-5-2.238-5-5-5z"/> </svg> </button> - <div class="dropdown-menu"> - <a class="dropdown-item" href="#" data-action="labels">Labels</a> + <div class="dropdown-menu dropdown-menu-end"> + <a class="dropdown-item" href="#" data-action="labels">Toggle Labels</a> <a class="dropdown-item" href="#" data-action="reset">Reset Map</a> </div> </li> - <!-- gradient toggle --> - <li class="nav-item"> - <button - id="gradientbtn" - type="button" - class="btn selected" - data-bs-toggle="collapse" - data-bs-target="#gbar" - title="Gradient Maps" - > - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> - <path d="M13.144 8.171c-.035-.066.342-.102.409-.102.074.009-.196.452-.409.102zm-2.152-3.072l.108-.031c.064.055-.072.095-.051.136.086.155.021.248.008.332-.014.085-.104.048-.149.093-.053.066.258.075.262.085.011.033-.375.089-.304.171.096.136.824-.195.708-.176.225-.113.029-.125-.097-.19-.043-.215-.079-.547-.213-.68l.088-.102c-.206-.299-.36.362-.36.362zm13.008 6.901c0 6.627-5.373 12-12 12-6.628 0-12-5.373-12-12s5.372-12 12-12c6.627 0 12 5.373 12 12zm-8.31-5.371c-.006-.146-.19-.284-.382-.031-.135.174-.111.439-.184.557-.104.175.567.339.567.174.025-.277.732-.063.87-.025.248.069.643-.226.211-.381-.355-.13-.542-.269-.574-.523 0 0 .188-.176.106-.166-.218.027-.614.786-.614.395zm6.296 5.371c0-1.035-.177-2.08-.357-2.632-.058-.174-.189-.312-.359-.378-.256-.1-1.337.597-1.5.254-.107-.229-.324.146-.572.008-.12-.066-.454-.515-.605-.46-.309.111.474.964.688 1.076.201-.152.852-.465.992-.038.268.804-.737 1.685-1.251 2.149-.768.694-.624-.449-1.147-.852-.275-.211-.272-.66-.55-.815-.124-.07-.693-.725-.688-.813l-.017.166c-.094.071-.294-.268-.315-.321 0 .295.48.765.639 1.001.271.405.416.995.748 1.326.178.178.858.914 1.035.898.193-.017.803-.458.911-.433.644.152-1.516 3.205-1.721 3.583-.169.317.138 1.101.113 1.476-.029.433-.37.573-.693.809-.346.253-.265.745-.556.925-.517.318-.889 1.353-1.623 1.348-.216-.001-1.14.36-1.261.007-.094-.256-.22-.45-.353-.703-.13-.248-.015-.505-.173-.724-.109-.152-.475-.497-.508-.677-.002-.155.117-.626.28-.708.229-.117.044-.458.016-.656-.048-.354-.267-.646-.53-.851-.389-.299-.188-.537-.097-.964 0-.204-.124-.472-.398-.392-.564.164-.393-.44-.804-.413-.296.021-.538.209-.813.292-.346.104-.7-.082-1.042-.125-1.407-.178-1.866-1.786-1.499-2.946.037-.19-.114-.542-.048-.689.158-.352.48-.747.762-1.014.158-.15.361-.112.547-.229.287-.181.291-.553.572-.781.4-.325.946-.318 1.468-.388.278-.037 1.336-.266 1.503-.06 0 .038.191.604-.019.572.433.023 1.05.749 1.461.579.211-.088.134-.736.567-.423.262.188 1.436.272 1.68.069.15-.124.234-.93.052-1.021.116.115-.611.124-.679.098-.12-.044-.232.114-.425.025.116.055-.646-.354-.218-.667-.179.131-.346-.037-.539.107-.133.108.062.18-.128.274-.302.153-.53-.525-.644-.602-.116-.076-1.014-.706-.77-.295l.789.785c-.039.025-.207-.286-.207-.059.053-.135.02.579-.104.347-.055-.089.09-.139.006-.268 0-.085-.228-.168-.272-.226-.125-.155-.457-.497-.637-.579-.05-.023-.764.087-.824.11-.07.098-.13.201-.179.311-.148.055-.287.126-.419.214l-.157.353c-.068.061-.765.291-.769.3.029-.075-.487-.171-.453-.321.038-.165.213-.68.168-.868-.048-.197 1.074.284 1.146-.235.029-.225.046-.487-.313-.525.068.008.695-.246.799-.36.146-.168.481-.442.724-.442.284 0 .223-.413.354-.615.131.053-.07.376.087.507-.01-.103.445.057.489.033.104-.054.684-.022.594-.294-.1-.277.051-.195.181-.253-.022.009.34-.619.402-.413-.043-.212-.421.074-.553.063-.305-.024-.176-.52-.061-.665.089-.115-.243-.256-.247-.036-.006.329-.312.627-.241 1.064.108.659-.735-.159-.809-.114-.28.17-.509-.214-.364-.444.148-.235.505-.224.652-.476.104-.178.225-.385.385-.52.535-.449.683-.09 1.216-.041.521.048.176.124.104.324-.069.19.286.258.409.099.07-.092.229-.323.298-.494.089-.222.901-.197.334-.536-.374-.223-2.004-.672-3.096-.672-.236 0-.401.263-.581.412-.356.295-1.268.874-1.775.698-.519-.179-1.63.66-1.808.666-.065.004.004-.634.358-.681-.153.023 1.247-.707 1.209-.859-.046-.18-2.799.822-2.676 1.023.059.092.299.092-.016.294-.18.109-.372.801-.541.801-.505.221-.537-.435-1.099.409l-.894.36c-1.328 1.411-2.247 3.198-2.58 5.183-.013.079.334.226.379.28.112.134.112.712.167.901.138.478.479.744.74 1.179.154.259.41.914.329 1.186.108-.178 1.07.815 1.246 1.022.414.487.733 1.077.061 1.559-.217.156.33 1.129.048 1.368l-.361.093c-.356.219-.195.756.021.982 1.818 1.901 4.38 3.087 7.22 3.087 5.517 0 9.989-4.472 9.989-9.989zm-11.507-6.357c.125-.055.293-.053.311-.22.015-.148.044-.046.08-.1.035-.053-.067-.138-.11-.146-.064-.014-.108.069-.149.104l-.072.019-.068.087.008.048-.087.106c-.085.084.002.139.087.102z"/> - </svg> - </button> - </li> - <!-- compare --> <li class="nav-item"> <button id="comparebtn" type="button" - class="btn btn-success text-white" + class="nav-icon-btn" data-bs-toggle="modal" data-bs-target="#compareModal" - title="Compare" + title="Compare Countries" > - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <!-- compare arrows icon --> + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"> <path d="M6 11v-4l-6 5 6 5v-4h12v4l6-5-6-5v4z"/> </svg> </button> @@ -103,12 +97,13 @@ <button id="graphsbtn" type="button" - class="btn btn-secondary text-dark" + class="nav-icon-btn" data-bs-toggle="modal" data-bs-target="#graphModal" - title="Graphs" + title="Charts" > - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <!-- pie/chart icon --> + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"> <path d="M13.012 5.007v-1.668l2.802-2.771c.409.136.809.293 1.197.471l-3.999 3.968zm7.089-1.93l-7.089 7.058v.853h.877l7.044-7.076c-.263-.292-.541-.57-.832-.835zm-7.089-1.468l1.437-1.406c-.46-.094-.96-.163-1.437-.203v1.609zm10.789 7.962l-1.386 1.417h1.585c-.04-.47-.106-.964-.199-1.417zm-.363-1.366c-.135-.41-.292-.81-.469-1.199l-3.951 3.982h1.668l2.752-2.783zm-1.063-2.337c-.205-.346-.426-.682-.664-1.004l-6.093 6.124h1.668l5.089-5.12zm-3.225-3.57c-.322-.238-.657-.459-1.003-.665l-5.135 5.104v1.668l6.138-6.107zm-8.15 10.702v-13c-6.161.519-11 5.683-11 11.978 0 6.639 5.382 12.022 12.021 12.022 6.296 0 11.46-4.839 11.979-11h-13z"/> </svg> </button> @@ -119,12 +114,13 @@ <button id="infobtn" type="button" - class="btn btn-primary text-white" + class="nav-icon-btn" data-bs-toggle="modal" data-bs-target="#infoModal" title="Information" > - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <!-- info circle icon --> + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"> <path d="M13.25 7c0 .69-.56 1.25-1.25 1.25s-1.25-.56-1.25-1.25.56-1.25 1.25-1.25 1.25.56 1.25 1.25zm10.75 5c0 6.627-5.373 12-12 12s-12-5.373-12-12 5.373-12 12-12 12 5.373 12 12zm-2 0c0-5.514-4.486-10-10-10s-10 4.486-10 10 4.486 10 10 10 10-4.486 10-10zm-13-2v2h2v6h2v-8h-4z"/> </svg> </button> @@ -135,12 +131,13 @@ <button id="alertbtn" type="button" - class="btn btn-danger text-white" + class="nav-icon-btn" data-bs-toggle="modal" data-bs-target="#alertModal" title="Precautions" > - <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"> + <!-- warning triangle icon --> + <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"> <path d="M12 5.177l8.631 15.823h-17.262l8.631-15.823zm0-4.177l-12 22h24l-12-22zm-1 9h2v6h-2v-6zm1 9.75c-.689 0-1.25-.56-1.25-1.25s.561-1.25 1.25-1.25 1.25.56 1.25 1.25-.561 1.25-1.25 1.25z"/> </svg> </button> @@ -151,44 +148,51 @@ </div> </nav> - <!-- gradient bar menu --> - <nav id="gbar" class="collapse-navbar collapse"> - <div class="d-flex flex-row-reverse"> - <button id="totPop" type="button" class="btn" title="Total Prison Populations">Total Prison Population</button> - <button id="perCapita" type="button" class="btn" title="Prisoners Per Capita">Prisoners Per Capita</button> - <button id="women" type="button" class="btn" title="Percent Women Imprisoned">Percent Women Imprisoned</button> - <button id="juveniles" type="button" class="btn" title="Percent Juveniles Imprisoned">Percent Juveniles Imprisoned</button> - <button id="occupancy" type="button" class="btn" title="Prison Occupancy Level">Prison Occupancy Level</button> - </div> - </nav> + <!-- ── Map ─────────────────────────────────────────────────────────── --> + <div id="map-container"></div> - <!-- ── MODALS ─────────────────────────────────────────────────────── --> + <!-- ── Metric pill bar ─────────────────────────────────────────────── --> + <div id="gbar"> + <button id="totPop" type="button" class="metric-btn active-metric" title="Total Prison Populations">Total Population</button> + <button id="perCapita" type="button" class="metric-btn" title="Prisoners Per Capita">Per Capita</button> + <button id="women" type="button" class="metric-btn" title="Percent Women Imprisoned">% Women</button> + <button id="juveniles" type="button" class="metric-btn" title="Percent Juveniles Imprisoned">% Juveniles</button> + <button id="occupancy" type="button" class="metric-btn" title="Prison Occupancy Level">Occupancy</button> + </div> + + <!-- ── MODALS ──────────────────────────────────────────────────────── --> <!-- country detail modal (populated by modal.js) --> - <div class="modal fade" id="countryModal" role="dialog"> + <div class="modal fade" id="countryModal" tabindex="-1" role="dialog"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> - <h4 class="modal-title" id="country-modal-title"></h4> + <h5 class="modal-title" id="country-modal-title"></h5> + <button type="button" class="nav-icon-btn ms-auto" data-bs-dismiss="modal" aria-label="Close"> + <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M23.954 21.03l-9.184-9.095 9.092-9.174-2.832-2.807-9.09 9.179-9.176-9.088-2.81 2.81 9.186 9.105-9.1 9.179 2.81 2.81 9.074-9.185 9.19 9.075z"/></svg> + </button> </div> <div class="modal-body" id="country-modal-body"></div> <div class="modal-footer"> - <button type="button" class="btn btn-outline-success" data-bs-dismiss="modal">Close</button> + <button type="button" class="btn-modal-ghost" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div> <!-- compare: country selection --> - <div class="modal fade" id="compareModal" role="dialog"> + <div class="modal fade" id="compareModal" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg"> <div class="modal-content"> - <div class="modal-header" style="background-color:#24ab48;"> - <h4 class="modal-title">Country Comparison</h4> + <div class="modal-header"> + <h5 class="modal-title">Country Comparison</h5> + <button type="button" class="nav-icon-btn ms-auto" data-bs-dismiss="modal" aria-label="Close"> + <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M23.954 21.03l-9.184-9.095 9.092-9.174-2.832-2.807-9.09 9.179-9.176-9.088-2.81 2.81 9.186 9.105-9.1 9.179 2.81 2.81 9.074-9.185 9.19 9.075z"/></svg> + </button> </div> <div class="modal-body"> <div id="compare-alert"></div> - <div class="row"> + <div class="row g-3"> <div class="col-md-6"> <select id="compare-select-1"></select> </div> @@ -198,19 +202,22 @@ </div> </div> <div class="modal-footer"> - <button type="button" class="btn btn-success" id="compare-go-btn">Compare!</button> - <button type="button" class="btn btn-outline-success" data-bs-dismiss="modal">Close</button> + <button type="button" class="btn-modal-ghost" data-bs-dismiss="modal">Cancel</button> + <button type="button" class="btn-modal-primary" id="compare-go-btn">Compare</button> </div> </div> </div> </div> <!-- compare: side-by-side result --> - <div class="modal fade" id="compareResultModal" role="dialog"> + <div class="modal fade" id="compareResultModal" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg"> <div class="modal-content"> - <div class="modal-header" style="background-color:#24ab48;"> - <h4 class="modal-title">Side-By-Side Comparison</h4> + <div class="modal-header"> + <h5 class="modal-title">Side-by-Side Comparison</h5> + <button type="button" class="nav-icon-btn ms-auto" data-bs-dismiss="modal" aria-label="Close"> + <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M23.954 21.03l-9.184-9.095 9.092-9.174-2.832-2.807-9.09 9.179-9.176-9.088-2.81 2.81 9.186 9.105-9.1 9.179 2.81 2.81 9.074-9.185 9.19 9.075z"/></svg> + </button> </div> <div class="modal-body"> <table class="table"> @@ -225,81 +232,88 @@ </table> </div> <div class="modal-footer"> - <button type="button" class="btn btn-outline-success" data-bs-dismiss="modal">Close</button> + <button type="button" class="btn-modal-ghost" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div> <!-- information modal --> - <div class="modal fade" id="infoModal" role="dialog"> + <div class="modal fade" id="infoModal" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg"> <div class="modal-content"> - <div class="modal-header bg-primary"> - <h4 class="modal-title">Information</h4> + <div class="modal-header"> + <h5 class="modal-title">Information</h5> + <button type="button" class="nav-icon-btn ms-auto" data-bs-dismiss="modal" aria-label="Close"> + <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M23.954 21.03l-9.184-9.095 9.092-9.174-2.832-2.807-9.09 9.179-9.176-9.088-2.81 2.81 9.186 9.105-9.1 9.179 2.81 2.81 9.074-9.185 9.19 9.075z"/></svg> + </button> </div> <div class="modal-body"> - <p>Hover over any country to view its name and click to see its statistics!</p> - <p>To reset the map, please click the <b>Reset Map</b> button.</p> - <p>If you'd like to compare two countries' statistics, please use the <b>Compare</b> button.</p> - <p>In the <b>Graphs</b> modal, click any pie slice to see that country's incarceration metrics. Click <b>← Back</b> to return to the pie chart.</p> + <p>Hover over any country to view its name and click to see its statistics.</p> + <p>Use the <b>Settings</b> menu to toggle country labels or reset the map view.</p> + <p>To compare two countries, click the <b>Compare</b> button in the navbar.</p> + <p>In the <b>Charts</b> modal, click any pie slice to drill into that country's incarceration metrics. Click <b>← Back</b> to return.</p> <hr /> - <p><b>References:</b></p> - <div class="row"> + <p><b>References</b></p> + <div class="row g-2"> <div class="col-sm-6"> - <a class="btn btn-primary w-100" href="http://www.prisonstudies.org" target="_blank">World Prison Brief</a> + <a class="ref-btn" href="http://www.prisonstudies.org" target="_blank" rel="noopener">World Prison Brief</a> </div> <div class="col-sm-6"> - <a class="btn btn-primary w-100" href="https://en.wikipedia.org/wiki/List_of_countries_by_system_of_government" target="_blank">Wikipedia</a> + <a class="ref-btn" href="https://en.wikipedia.org/wiki/List_of_countries_by_system_of_government" target="_blank" rel="noopener">Wikipedia — Governments</a> </div> </div> </div> <div class="modal-footer"> - <button type="button" class="btn btn-outline-primary" data-bs-dismiss="modal">Close</button> + <button type="button" class="btn-modal-ghost" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div> <!-- alert / precautions modal --> - <div class="modal fade" id="alertModal" role="dialog"> + <div class="modal fade" id="alertModal" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg"> <div class="modal-content"> - <div class="modal-header bg-danger"> - <h4 class="modal-title">Precautions</h4> + <div class="modal-header"> + <h5 class="modal-title">Precautions</h5> + <button type="button" class="nav-icon-btn ms-auto" data-bs-dismiss="modal" aria-label="Close"> + <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M23.954 21.03l-9.184-9.095 9.092-9.174-2.832-2.807-9.09 9.179-9.176-9.088-2.81 2.81 9.186 9.105-9.1 9.179 2.81 2.81 9.074-9.185 9.19 9.075z"/></svg> + </button> </div> <div class="modal-body"> - <p>If any part of this site is inaccurate or confusing, <a class="text-danger" href="#">send me an email</a>!</p> + <p>Data is sourced from the <a class="btn-modal-link p-0" href="http://www.prisonstudies.org" target="_blank" rel="noopener">World Prison Brief</a> and may not reflect the most current figures. Always consult primary sources for research purposes.</p> + <p>If any part of this site is inaccurate or confusing, please reach out.</p> </div> <div class="modal-footer"> - <button type="button" class="btn btn-outline-danger" data-bs-dismiss="modal">Close</button> + <button type="button" class="btn-modal-ghost" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div> <!-- graph modal --> - <div class="modal fade" id="graphModal" role="dialog"> + <div class="modal fade" id="graphModal" tabindex="-1" role="dialog"> <div class="modal-dialog modal-lg"> <div class="modal-content"> - <div class="modal-header bg-secondary text-dark"> - <h4 class="modal-title">Top Five Prison Populations</h4> + <div class="modal-header"> + <h5 class="modal-title">Top 5 by Current Metric</h5> + <button type="button" class="nav-icon-btn ms-auto" data-bs-dismiss="modal" aria-label="Close"> + <svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><path d="M23.954 21.03l-9.184-9.095 9.092-9.174-2.832-2.807-9.09 9.179-9.176-9.088-2.81 2.81 9.186 9.105-9.1 9.179 2.81 2.81 9.074-9.185 9.19 9.075z"/></svg> + </button> </div> <div class="modal-body"> <div id="myChart2"></div> <div id="myNextChart" style="display:none;"></div> </div> <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> + <button type="button" class="btn-modal-ghost" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div> - <!-- map area --> - <div id="map-container"></div> - - <!-- js --> + <!-- ── Scripts ─────────────────────────────────────────────────────── --> <script src="./assets/js/bootstrap.bundle.min.js"></script> <script type="module" src="./assets/js/app.js"></script> </body> |
