Redesign Purple theme with proper contrast and professional chart axes

Rebuilt the purple color palette from scratch using a 4-level luminance
scale (~3-5x jump per level: #06000f → #110028 → #1d0845 → #3a158a),
matching the approach of high-contrast Bootswatch dark themes (Darkly,
Cyborg). All contrast ratios are now WCAG-compliant: body text 16:1,
card header white text 8.5:1, primary button 5.5:1.

Chart axis improvements: Y-axis large numbers abbreviated (1.4M, 568K),
X-axis max 6 ticks at 30° rotation, Inter font throughout, dark-glass
tooltips, network_charts settings added to settings.json.tmpl with
transparent canvas background
This commit is contained in:
2026-04-28 14:50:22 +02:00
parent 6f03cf10b3
commit 88cba13e77
5 changed files with 472 additions and 598 deletions
+34
View File
@@ -98,6 +98,40 @@
"enabled": true,
"display_order": 4
},
"network_charts": {
"nethash_chart": {
"enabled": true,
"chart_title": { "enabled": false, "title_text": "", "alignment": "center", "color": "#666", "font": { "family": "Arial", "size": 14, "weight": "bold" } },
"legend": { "enabled": true, "position": "bottom" },
"bgcolor": "transparent",
"line_color": "rgba(54,162,235,1)",
"fill_color": "rgba(54,162,235,0.2)",
"crosshair_color": "#aaa",
"block_line": { "enabled": true, "block_line_color": "rgba(0,128,0,0.2)" },
"round_decimals": 3,
"chart_height": 320,
"full_row": false,
"stretch_to_fit": false
},
"difficulty_chart": {
"enabled": true,
"chart_title": { "enabled": false, "title_text": "", "alignment": "center", "color": "#666", "font": { "family": "Arial", "size": 14, "weight": "bold" } },
"legend": { "enabled": true, "position": "bottom" },
"bgcolor": "transparent",
"pow_line_color": "rgba(255,99,132,1)",
"pow_fill_color": "rgba(255,99,132,0.2)",
"pos_line_color": "rgba(255,161,0,1)",
"pos_fill_color": "rgba(255,161,0,0.2)",
"crosshair_color": "#aaa",
"block_line": { "enabled": true, "block_line_color": "rgba(0,128,0,0.2)" },
"round_decimals": 3,
"chart_height": 320,
"full_row": false,
"stretch_to_fit": false
},
"reload_chart_seconds": 60,
"sync_charts": true
},
"custom_menus": []
},
"page_footer": {
+127 -320
View File
@@ -1,55 +1,29 @@
/* ============================================================
BitcoinPurple Explorer custom UX overrides (Purple theme)
BitcoinPurple Explorer explorer-specific component styles
The base dark theme is in themes/purple/_bootswatch.scss.
This file adds only what Bootstrap + bootswatch don't cover.
============================================================ */
/* ── Variables ──────────────────────────────────────────────── */
/* ── CSS vars (available to JS and inline styles) ────────────── */
:root {
--btcp-900: #0e001c;
--btcp-800: #1c003a;
--btcp-700: #2d1052;
--btcp-600: #3d1278;
--btcp-500: #5b21b6;
--btcp-400: #7c3aed;
--btcp-300: #9333ea;
--btcp-200: #c084fc;
--btcp-100: #f0e6ff; /* leggermente più luminoso per contrasto testo */
--btcp-text: #f5eeff; /* testo principale quasi bianco con tinta viola */
--btcp-text-muted: #c8a8f0; /* secondario viola chiaro leggibile */
--btcp-search-text: #f0d9ff; /* testo dentro search bar caldo/luminoso */
--btcp-glow: 0 0 12px rgba(147,51,234,.45), 0 0 32px rgba(147,51,234,.15);
--btcp-glow-sm: 0 0 6px rgba(147,51,234,.35);
--radius: .6rem;
--btcp-bg: #06000f;
--btcp-surface: #110028;
--btcp-card: #1d0845;
--btcp-header: #3a158a;
--btcp-border: #7c3aed;
--btcp-accent: #9333ea;
--btcp-bright: #a855f7;
--btcp-label: #c084fc;
--btcp-text: #ece0ff;
--btcp-text-dim: #9d6ae8;
--btcp-glow: 0 0 14px rgba(147,51,234,.5), 0 0 40px rgba(147,51,234,.18);
--btcp-glow-sm: 0 0 8px rgba(147,51,234,.4);
--radius: .55rem;
--radius-pill: 50rem;
}
/* ── Fix btn-success → purple ────────────────────────────────── */
.btn-success,
.btn-success:not(:disabled):not(.disabled) {
background: linear-gradient(135deg, var(--btcp-400), var(--btcp-300)) !important;
border: none !important;
color: #fff !important;
font-weight: 600;
letter-spacing: .02em;
box-shadow: var(--btcp-glow-sm);
transition: all .2s ease;
}
.btn-success:hover,
.btn-success:focus {
background: linear-gradient(135deg, var(--btcp-300), var(--btcp-200)) !important;
box-shadow: var(--btcp-glow) !important;
transform: translateY(-1px);
}
.btn-success:active {
transform: translateY(0);
box-shadow: var(--btcp-glow-sm) !important;
}
/* ── Search bar ──────────────────────────────────────────────── */
.search-box-custom,
#index-search,
#search-row {
padding: .75rem 0;
}
.search-box-custom, #index-search, #search-row { padding: .75rem 0; }
.search-for,
#index-search .form-group {
@@ -59,36 +33,65 @@
position: relative;
}
/* Input field */
.search-for .form-control,
#index-search input.form-control {
background: rgba(18, 0, 40, .95) !important;
border: 1.5px solid var(--btcp-500) !important;
background: var(--btcp-surface) !important;
border: 1.5px solid var(--btcp-border) !important;
border-right: none !important;
border-radius: var(--radius-pill) 0 0 var(--radius-pill) !important;
color: var(--btcp-search-text) !important;
padding: .6rem 1.25rem !important;
color: #fff !important;
padding: .6rem 1.25rem .6rem 2.6rem !important;
font-size: .95rem;
font-weight: 500;
letter-spacing: .01em;
transition: border-color .2s, box-shadow .2s;
height: 44px;
caret-color: var(--btcp-200);
caret-color: var(--btcp-label);
transition: border-color .2s, box-shadow .2s;
}
.search-for .form-control:focus,
#index-search input.form-control:focus {
border-color: var(--btcp-300) !important;
box-shadow: 0 0 0 3px rgba(147,51,234,.25) !important;
background: rgba(20, 0, 45, 1) !important;
border-color: var(--btcp-accent) !important;
box-shadow: 0 0 0 3px rgba(147,51,234,.28) !important;
background: #16003a !important;
color: #fff !important;
outline: none;
}
.search-for .form-control::placeholder,
#index-search input.form-control::placeholder {
color: #d8b4fe;
opacity: .85;
font-weight: 400;
color: rgba(192,132,252,.7);
}
/* Search icon */
.search-for::before {
content: "";
position: absolute;
left: 1rem;
top: 50%;
transform: translateY(-50%);
color: var(--btcp-label);
font-size: 1.1rem;
pointer-events: none;
z-index: 5;
}
/* btn-success → purple (used as search button) */
.btn-success,
.btn-success:not(:disabled):not(.disabled) {
background: linear-gradient(135deg, var(--btcp-border), var(--btcp-accent)) !important;
border: none !important;
color: #fff !important;
font-weight: 600;
box-shadow: var(--btcp-glow-sm);
transition: all .2s ease;
}
.btn-success:hover,
.btn-success:focus {
background: linear-gradient(135deg, var(--btcp-accent), var(--btcp-bright)) !important;
box-shadow: var(--btcp-glow) !important;
transform: translateY(-1px);
}
.btn-success:active { transform: translateY(0); }
.search-for .btn-success,
#index-search .btn-success {
border-radius: 0 var(--radius-pill) var(--radius-pill) 0 !important;
@@ -97,31 +100,13 @@
font-size: .9rem;
}
/* Search icon prefix */
.search-for::before {
content: "";
position: absolute;
left: 1rem;
top: 50%;
transform: translateY(-50%);
color: var(--btcp-200);
font-size: 1.1rem;
pointer-events: none;
z-index: 5;
}
.search-for .form-control {
padding-left: 2.5rem !important;
}
/* ── Stat panels (header) ─────────────────────────────────────── */
/* ── Stat panels (header area) ───────────────────────────────── */
.panel-box,
.card.panel,
.stat-panel,
[class*="stat-"] .card,
.summary-panel .card {
.stat-panel {
border: 1px solid rgba(124,58,237,.55) !important;
background: var(--btcp-card) !important;
border-radius: var(--radius) !important;
border: 1px solid var(--btcp-600) !important;
background: linear-gradient(145deg, rgba(45,16,82,.95), rgba(28,0,58,.95)) !important;
transition: transform .18s, box-shadow .18s;
}
.panel-box:hover,
@@ -130,280 +115,102 @@
box-shadow: var(--btcp-glow) !important;
}
/* Panel values big numbers */
/* Big numbers */
.panel-box .panel-value,
.card .display-4,
.card h3,
.card .h3 {
color: var(--btcp-100) !important;
.card h3, .card .h3 {
color: #fff !important;
font-weight: 700;
}
/* Panel labels */
/* Labels */
.panel-box .panel-label,
.card .card-title,
.card small {
color: var(--btcp-200) !important;
font-size: .75rem;
color: var(--btcp-label) !important;
font-size: .73rem;
text-transform: uppercase;
letter-spacing: .08em;
font-weight: 500;
letter-spacing: .09em;
font-weight: 600;
}
/* ── Tables ───────────────────────────────────────────────────── */
.table {
border-radius: var(--radius);
overflow: hidden;
/* ── Text helpers ────────────────────────────────────────────── */
body { color: var(--btcp-text) !important; }
.card-body, .panel-body { color: var(--btcp-text) !important; }
p, li, span, div, td, th, label { color: inherit; }
.text-muted, small, .small {
color: var(--btcp-text-dim) !important;
opacity: 1 !important;
}
.table thead th {
background: linear-gradient(90deg, var(--btcp-700), var(--btcp-600)) !important;
color: var(--btcp-200) !important;
font-size: .78rem !important;
font-weight: 600 !important;
text-transform: uppercase !important;
letter-spacing: .07em !important;
border: none !important;
padding: .85rem 1rem !important;
white-space: nowrap;
}
.table tbody tr {
transition: background .12s;
}
.table tbody tr:nth-child(odd) td {
background: rgba(45,16,82,.25) !important;
}
.table tbody tr:nth-child(even) td {
background: rgba(28,0,58,.25) !important;
}
.table tbody tr:hover td {
background: rgba(124,58,237,.18) !important;
}
.table td {
border-color: rgba(61,18,120,.4) !important;
padding: .7rem 1rem !important;
vertical-align: middle !important;
font-size: .875rem;
}
/* Hash / tx links in tables */
/* ── Hash / monospace links in tables ────────────────────────── */
.table td a {
color: var(--btcp-200) !important;
font-family: "SF Mono", "Fira Code", monospace;
font-size: .8rem;
}
.table td a:hover {
color: #fff !important;
text-shadow: 0 0 8px rgba(192,132,252,.7);
}
/* ── Cards & containers ──────────────────────────────────────── */
.card {
border-radius: var(--radius) !important;
border: 1px solid var(--btcp-600) !important;
background: rgba(28,0,58,.85) !important;
backdrop-filter: blur(6px);
}
.card-header {
border-radius: calc(var(--radius) - 1px) calc(var(--radius) - 1px) 0 0 !important;
background: linear-gradient(90deg, var(--btcp-700), rgba(45,16,82,.8)) !important;
border-bottom: 1px solid var(--btcp-600) !important;
padding: .85rem 1.25rem !important;
}
.card-header h4,
.card-header h5,
.card-header .card-title {
margin: 0;
font-size: .9rem;
font-weight: 600;
color: var(--btcp-100) !important;
letter-spacing: .04em;
text-transform: uppercase;
}
/* ── Navbar / sidebar ─────────────────────────────────────────── */
header,
.navbar,
#main-header,
#main-header-side {
background: linear-gradient(135deg, #160032 0%, #1e0040 100%) !important;
border-bottom: 1px solid var(--btcp-600) !important;
box-shadow: 0 2px 20px rgba(0,0,0,.5) !important;
}
.navbar-brand {
font-weight: 700 !important;
font-size: 1.1rem !important;
color: var(--btcp-100) !important;
letter-spacing: .04em;
}
.nav-link {
color: rgba(233,213,255,.7) !important;
font-size: .875rem !important;
font-weight: 500 !important;
padding: .5rem .85rem !important;
border-radius: .4rem;
transition: color .15s, background .15s;
}
.nav-link:hover,
.nav-link.active,
.nav-item.active .nav-link {
color: #fff !important;
background: rgba(124,58,237,.25) !important;
}
/* ── Sidebar (side menu layout) ──────────────────────────────── */
#sidebar,
.sidebar-wrapper,
nav.sidebar {
background: linear-gradient(180deg, #130028 0%, #0e001c 100%) !important;
border-right: 1px solid var(--btcp-600) !important;
}
/* ── Badges ──────────────────────────────────────────────────── */
.badge {
border-radius: var(--radius-pill) !important;
font-weight: 500 !important;
font-size: .72rem !important;
padding: .3em .7em !important;
}
.badge.bg-success,
.badge.text-bg-success {
background: rgba(74,222,128,.15) !important;
color: #4ade80 !important;
border: 1px solid rgba(74,222,128,.3) !important;
}
.badge.bg-danger,
.badge.text-bg-danger {
background: rgba(248,113,113,.15) !important;
color: #f87171 !important;
border: 1px solid rgba(248,113,113,.3) !important;
}
.badge.bg-primary,
.badge.text-bg-primary {
background: rgba(147,51,234,.2) !important;
color: var(--btcp-200) !important;
border: 1px solid var(--btcp-500) !important;
}
/* ── Confirmations color ─────────────────────────────────────── */
/* ── Status badges ───────────────────────────────────────────── */
.text-success { color: #4ade80 !important; }
.text-danger { color: #f87171 !important; }
.text-warning { color: #fbbf24 !important; }
/* ── Pagination ──────────────────────────────────────────────── */
.pagination {
gap: 3px;
}
.page-link {
border-radius: .4rem !important;
background: var(--btcp-700) !important;
border: 1px solid var(--btcp-600) !important;
color: var(--btcp-200) !important;
transition: all .15s;
font-size: .85rem;
}
.page-link:hover {
background: var(--btcp-400) !important;
border-color: var(--btcp-400) !important;
color: #fff !important;
box-shadow: var(--btcp-glow-sm);
}
.page-item.active .page-link {
background: linear-gradient(135deg, var(--btcp-400), var(--btcp-300)) !important;
border-color: transparent !important;
box-shadow: var(--btcp-glow-sm);
}
.page-item.disabled .page-link {
background: rgba(45,16,82,.4) !important;
border-color: var(--btcp-700) !important;
color: var(--btcp-500) !important;
}
/* ── Global text contrast boost ─────────────────────────────── */
body {
color: var(--btcp-text) !important;
}
p, li, span, div, td, th, label {
color: inherit;
}
/* Testo secondario / muted più leggibile */
.text-muted,
small,
.small {
color: var(--btcp-text-muted) !important;
opacity: 1 !important;
}
/* Valori numerici nei pannelli massima leggibilità */
.card-body,
.panel-body {
color: var(--btcp-text) !important;
}
/* Intestazioni */
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
color: var(--btcp-100) !important;
}
/* ── Loading bar ─────────────────────────────────────────────── */
#loading-bar,
.loading-bar,
#nprogress .bar {
background: linear-gradient(90deg, var(--btcp-400), var(--btcp-200)) !important;
box-shadow: 0 0 8px var(--btcp-300);
#loading-bar, .loading-bar, #nprogress .bar {
background: linear-gradient(90deg, var(--btcp-border), var(--btcp-label)) !important;
box-shadow: 0 0 8px var(--btcp-accent);
}
/* ── Charts ──────────────────────────────────────────────────── */
/* ── Chart canvas subtle glow ────────────────────────────────── */
canvas {
filter: drop-shadow(0 0 6px rgba(147,51,234,.2));
filter: drop-shadow(0 0 4px rgba(147,51,234,.12));
}
/* ── Footer ──────────────────────────────────────────────────── */
footer,
#footer {
background: linear-gradient(135deg, #130028 0%, #0e001c 100%) !important;
border-top: 1px solid var(--btcp-600) !important;
color: var(--btcp-500) !important;
font-size: .8rem;
/* ── Network chart card overrides ────────────────────────────── */
#nethashChartParent,
#difficultyChartParent {
.card { background: var(--btcp-card) !important; overflow: hidden; }
.card-header {
background: var(--btcp-header) !important;
border-bottom: 2px solid var(--btcp-border) !important;
padding: .6rem 1rem !important;
display: flex;
align-items: center;
gap: .5rem;
&::before {
content: '';
display: inline-block;
width: 3px;
height: 14px;
border-radius: 2px;
background: linear-gradient(180deg, var(--btcp-label), var(--btcp-accent));
flex-shrink: 0;
}
strong {
color: #fff !important;
font-size: .78rem;
letter-spacing: .08em;
text-transform: uppercase;
font-weight: 700;
}
}
.card-body { padding: .75rem !important; }
canvas { display: block; border-radius: .3rem; }
}
/* ── Scrollbar ───────────────────────────────────────────────── */
* {
scrollbar-width: thin;
scrollbar-color: var(--btcp-500) var(--btcp-900);
}
* { scrollbar-width: thin; scrollbar-color: var(--btcp-border) var(--btcp-bg); }
::-webkit-scrollbar { width: 5px; height: 5px; }
::-webkit-scrollbar-track { background: var(--btcp-900); }
::-webkit-scrollbar-thumb {
background: var(--btcp-500);
border-radius: 99px;
}
::-webkit-scrollbar-thumb:hover { background: var(--btcp-300); }
::-webkit-scrollbar-track { background: var(--btcp-bg); }
::-webkit-scrollbar-thumb { background: var(--btcp-border); border-radius: 99px; }
::-webkit-scrollbar-thumb:hover { background: var(--btcp-accent); }
/* ── Inputs & forms ──────────────────────────────────────────── */
.form-control,
.form-select {
border-radius: .45rem !important;
}
.form-control:focus,
.form-select:focus {
border-color: var(--btcp-300) !important;
box-shadow: 0 0 0 3px rgba(147,51,234,.2) !important;
}
/* ── Tooltips ────────────────────────────────────────────────── */
/* ── Tooltip ─────────────────────────────────────────────────── */
.tooltip-inner {
background: var(--btcp-700) !important;
border: 1px solid var(--btcp-600);
background: var(--btcp-card) !important;
border: 1px solid var(--btcp-border);
color: var(--btcp-text);
font-size: .8rem;
}
/* ── Links ───────────────────────────────────────────────────── */
a { transition: color .15s; }
a:hover { text-decoration: none !important; }
+109 -151
View File
@@ -1,258 +1,216 @@
// BitcoinPurple Theme
// BitcoinPurple Bootswatch overrides
// Handles everything Bootstrap's SCSS variables can't reach
@use "sass:color";
// Fonts
// Web font
$web-font-path: "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" !default;
@if $web-font-path {
@import url($web-font-path);
}
// Glow mixins
@mixin glow($color) {
box-shadow: 0 0 6px rgba($color, .5), 0 0 20px rgba($color, .2);
// Mixins
@mixin purple-glow($size: 8px) {
box-shadow: 0 0 $size rgba(168, 85, 247, .55), 0 0 #{$size * 3} rgba(168, 85, 247, .2);
}
@mixin text-glow($color) {
text-shadow: 0 0 8px rgba($color, .6), 0 0 20px rgba($color, .3);
}
// Body deep purple gradient background
// Body
body {
background-image: linear-gradient(160deg, #130025 0%, #0e001c 40%, #0a0018 100%);
background-attachment: fixed;
background: #06000f !important;
}
// Headings glow
// Headings
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
@include text-glow(#a855f7);
color: #fff;
}
// Navbar rich purple
// Navbar
.navbar {
background: linear-gradient(135deg, #1a003a 0%, #2d0057 100%) !important;
border-bottom: 1px solid #5b21b6;
@include glow(#7c3aed);
background: #110028 !important;
border-bottom: 2px solid #7c3aed;
box-shadow: 0 2px 20px rgba(0, 0, 0, .8);
}
.navbar-brand,
.navbar-brand { color: #fff !important; font-weight: 700; }
.nav-link {
color: #e9d5ff !important;
}
color: rgba(236, 224, 255, .65) !important;
border-radius: .35rem;
transition: color .15s, background .15s;
.nav-link:hover,
.nav-link.active {
&:hover, &.active {
color: #fff !important;
@include text-glow(#c084fc);
background: rgba(168, 85, 247, .2) !important;
}
}
// Sidebar menu
// Sidebar
#sidebar,
.sidebar,
[id*="sidebar"],
.nav-sidebar,
.col-sidebar {
background: linear-gradient(180deg, #1a003a 0%, #120028 100%) !important;
border-right: 1px solid #3d1278;
background: #110028 !important;
border-right: 2px solid #7c3aed;
}
// Cards dark purple glass effect
// Cards
.card {
background: rgba(28, 0, 58, .85) !important;
border: 1px solid #3d1278 !important;
backdrop-filter: blur(4px);
background: #1d0845 !important;
border: 1px solid rgba(124, 58, 237, .55) !important;
}
.card-header {
background: rgba(45, 16, 82, .9) !important;
border-bottom: 1px solid #4c1a8f !important;
color: #d8b4fe !important;
background: #3a158a !important;
border-bottom: 2px solid rgba(124, 58, 237, .7) !important;
color: #fff !important;
font-weight: 600;
}
// Tables
// Tables
.table {
color: #e9d5ff;
color: #ece0ff;
th {
background: #2d1052 !important;
color: #c084fc !important;
border-bottom: 2px solid #5b21b6 !important;
font-weight: 600;
thead th {
background: #3a158a !important;
color: #fff !important;
border-bottom: 2px solid #7c3aed !important;
border-top: none !important;
font-weight: 700;
text-transform: uppercase;
font-size: .82rem;
letter-spacing: .04em;
font-size: .78rem;
letter-spacing: .07em;
white-space: nowrap;
}
td {
border-color: #2d1052 !important;
}
td { border-color: rgba(124, 58, 237, .3) !important; }
tbody tr:hover td {
background: rgba(147, 51, 234, .12) !important;
tbody tr:nth-child(odd) td { background: rgba(58, 21, 138, .2) !important; }
tbody tr:nth-child(even) td { background: rgba(17, 0, 40, .15) !important; }
tbody tr:hover td { background: rgba(168, 85, 247, .15) !important; }
// Monospace hash links
td a {
color: #c084fc;
&:hover { color: #fff; text-shadow: 0 0 8px rgba(192, 132, 252, .8); }
}
}
// Buttons glowing purple
// Buttons
.btn-primary {
background: linear-gradient(135deg, #7c3aed, #9333ea) !important;
border: none !important;
@include glow(#9333ea);
&:hover {
background: linear-gradient(135deg, #6d28d9, #7c3aed) !important;
@include glow(#a855f7);
&:hover, &:focus {
background: linear-gradient(135deg, #9333ea, #a855f7) !important;
@include purple-glow(10px);
}
}
.btn-secondary {
background: #2d1052 !important;
border: 1px solid #5b21b6 !important;
color: #e9d5ff !important;
background: #3a158a !important;
border: 1px solid #7c3aed !important;
color: #ece0ff !important;
}
// Badges & labels
.badge.bg-primary {
background: #7c3aed !important;
}
// Badges
.badge.bg-primary { background: #7c3aed !important; }
.badge.bg-secondary { background: #3a158a !important; }
.badge.bg-success {
background: #166534 !important;
background: rgba(74, 222, 128, .18) !important;
color: #4ade80 !important;
border: 1px solid rgba(74, 222, 128, .4) !important;
}
// Links
a {
color: #c084fc;
&:hover {
color: #e9d5ff;
}
.badge.bg-danger {
background: rgba(248, 113, 113, .18) !important;
color: #f87171 !important;
border: 1px solid rgba(248, 113, 113, .4) !important;
}
// Inputs
// Inputs
.form-control,
.form-select {
background: #1c003a !important;
border-color: #3d1278 !important;
color: #e9d5ff !important;
background: #110028 !important;
border-color: rgba(124, 58, 237, .55) !important;
color: #ece0ff !important;
&::placeholder { color: rgba(192, 132, 252, .6); }
&:focus {
background: #1c003a !important;
background: #110028 !important;
border-color: #9333ea !important;
box-shadow: 0 0 0 3px rgba(147, 51, 234, .25) !important;
color: #fff !important;
}
}
// Panels / stat boxes
.panel,
.stats-panel,
[class*="panel-"] {
background: rgba(28, 0, 58, .9) !important;
border: 1px solid #3d1278 !important;
}
// Pagination
// Pagination
.page-link {
background: #2d1052 !important;
border-color: #5b21b6 !important;
color: #d8b4fe !important;
background: #1d0845 !important;
border-color: rgba(124, 58, 237, .5) !important;
color: #c084fc !important;
transition: all .15s;
&:hover {
background: #9333ea !important;
background: #7c3aed !important;
border-color: #7c3aed !important;
color: #fff !important;
@include purple-glow(6px);
}
}
.page-item.active .page-link {
background: #7c3aed !important;
border-color: #7c3aed !important;
background: linear-gradient(135deg, #7c3aed, #9333ea) !important;
border-color: transparent !important;
color: #fff !important;
@include purple-glow(6px);
}
// Scrollbar styling
// Scrollbar
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: #06000f; }
::-webkit-scrollbar-thumb { background: #7c3aed; border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: #9333ea; }
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background: #0e001c;
}
::-webkit-scrollbar-thumb {
background: #5b21b6;
border-radius: 3px;
&:hover {
background: #9333ea;
}
}
// Breadcrumbs
.breadcrumb {
background: #2d1052 !important;
}
.breadcrumb-item a {
color: #c084fc !important;
}
// Code / pre
// Breadcrumbs
.breadcrumb { background: #1d0845 !important; }
.breadcrumb-item a { color: #c084fc !important; }
// Code / pre
code {
color: #e879f9;
background: rgba(45, 16, 82, .6);
color: #f0abfc;
background: rgba(58, 21, 138, .5);
padding: .1em .3em;
border-radius: .2em;
}
pre {
background: #1c003a;
border: 1px solid #3d1278;
color: #e9d5ff;
background: #110028;
border: 1px solid rgba(124, 58, 237, .4);
color: #ece0ff;
}
// Footer
// Footer
footer,
.footer {
background: linear-gradient(135deg, #1a003a 0%, #0e001c 100%) !important;
border-top: 1px solid #3d1278 !important;
color: #a855f7 !important;
background: #110028 !important;
border-top: 2px solid #7c3aed !important;
color: rgba(168, 85, 247, .8) !important;
}
// Alerts
// Alerts
.alert {
border: none;
color: $white;
}
// Misc utility
.text-muted {
color: #a855f7 !important;
}
// Misc
.text-muted { color: #9d6ae8 !important; }
hr {
border-color: #3d1278;
opacity: .5;
border-color: rgba(124, 58, 237, .4);
opacity: .6;
}
+106 -97
View File
@@ -1,27 +1,46 @@
// BitcoinPurple Theme (based on Vapor 5.1.3)
// BitcoinPurple Theme
// Contrast-aware dark palette inspired by Darkly + Cyborg structure
//
// Luminance scale (each level ~3-5x the previous):
// $gray-900 #06000f 0.1% body background
// $gray-800 #110028 0.6% navbar / sidebar
// $gray-700 #1d0845 2.4% card body
// $gray-600 #3a158a 7.3% card header / table thead
// $gray-500 #7c3aed 18% borders / interactive
// $gray-400 #9d6ae8 31% secondary interactive
// $gray-300 #c084fc 47% links / accent labels
// $gray-200 #ddb8ff 63% secondary text
// $gray-100 #f0e8ff 79% near-white text
//
// Key contrast ratios:
// body text (#ece0ff) on bg (#06000f) 16:1 AAA
// white on card header (#3a158a) 8.5:1 AAA
// white on primary (#9333ea) 5.5:1 AA
// link (#c084fc) on bg (#06000f) 10:1 AAA
// link (#c084fc) on card (#1d0845) 7:1 AA
@use "sass:color";
$theme: "purple" !default;
// Color system
// Color scale
$white: #fff !default;
$gray-100: #f3e8ff !default;
$gray-200: #e9d5ff !default;
$gray-300: #d8b4fe !default;
$gray-400: #c084fc !default;
$gray-500: #a855f7 !default;
$gray-600: #7e22ce !default;
$gray-700: #581c87 !default;
$gray-800: #3b0764 !default;
$gray-900: #160026 !default;
$black: #08000f !default;
$gray-100: #f0e8ff !default;
$gray-200: #ddb8ff !default;
$gray-300: #c084fc !default;
$gray-400: #9d6ae8 !default;
$gray-500: #7c3aed !default;
$gray-600: #3a158a !default;
$gray-700: #1d0845 !default;
$gray-800: #110028 !default;
$gray-900: #06000f !default;
$black: #020008 !default;
$blue: #818cf8 !default;
$indigo: #6366f1 !default;
$purple: #a855f7 !default;
$pink: #e879f9 !default;
// Named colors
$blue: #60a5fa !default;
$indigo: #818cf8 !default;
$purple: #c084fc !default;
$pink: #f0abfc !default;
$red: #f87171 !default;
$orange: #fb923c !default;
$yellow: #fbbf24 !default;
@@ -29,8 +48,10 @@ $green: #4ade80 !default;
$teal: #2dd4bf !default;
$cyan: #22d3ee !default;
// Theme colors
// Primary: #9333ea white contrast 5.5:1 (AA )
$primary: #9333ea !default;
$secondary: #7c3aed !default;
$secondary: $gray-600 !default;
$success: $green !default;
$info: $blue !default;
$warning: $yellow !default;
@@ -38,116 +59,104 @@ $danger: $red !default;
$light: $gray-200 !default;
$dark: $gray-900 !default;
$min-contrast-ratio: 2 !default;
$min-contrast-ratio: 2.5 !default;
// Body
$body-bg: #0e001c !default;
$body-color: #e9d5ff !default;
// Links
// Body
$body-bg: $gray-900 !default;
$body-color: #ece0ff !default; // 16:1 contrast on body-bg
// Links
$link-color: $gray-300 !default;
$link-hover-color: $white !default;
$link-decoration: none !default;
$link-hover-decoration: underline !default;
// Fonts
// Typography
$font-family-sans-serif: "Inter", "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !default;
$text-muted: $gray-500 !default;
$text-muted: $gray-400 !default;
// Tables
$table-border-color: #2d1052 !default;
// Tables
$table-color: $body-color !default;
$table-border-color: rgba($gray-500, .35) !default;
$table-bg-scale: 0 !default;
// Forms
// Forms
$input-bg: $gray-800 !default;
$input-color: $gray-100 !default;
$input-border-color: rgba($gray-500, .6) !default;
$input-placeholder-color: rgba($gray-300, .6) !default;
$input-group-addon-color: $gray-200 !default;
$input-group-addon-bg: $gray-600 !default;
$input-bg: #1c003a !default;
$input-color: $gray-200 !default;
$input-border-color: #3d1278 !default;
$input-group-addon-color:$gray-400 !default;
$input-group-addon-bg: #2d1052 !default;
$form-check-input-bg: $gray-800 !default;
$form-check-input-border: 1px solid rgba($gray-500, .6) !default;
$form-check-input-bg: #1c003a !default;
$form-check-input-border: 1px solid #3d1278 !default;
// Nav
$nav-link-padding-x: 1.2rem !default;
$nav-link-disabled-color: $gray-500 !default;
$nav-tabs-border-color: $gray-500 !default;
$nav-tabs-link-active-color:$white !default;
// Dropdowns
// Navbar
$navbar-dark-color: rgba($white, .7) !default;
$navbar-dark-hover-color: $white !default;
$dropdown-bg: #1c003a !default;
$dropdown-border-color: #3d1278 !default;
$dropdown-divider-bg: #3d1278 !default;
// Dropdowns
$dropdown-bg: $gray-700 !default;
$dropdown-border-color: $gray-500 !default;
$dropdown-divider-bg: $gray-600 !default;
$dropdown-link-color: $gray-200 !default;
$dropdown-link-hover-color: $white !default;
$dropdown-link-hover-bg: $primary !default;
// Navs
$nav-link-padding-x: 2rem !default;
$nav-link-disabled-color: $gray-600 !default;
$nav-tabs-border-color: #3d1278 !default;
$nav-tabs-link-active-color:$white !default;
// Navbar
$navbar-dark-color: rgba($white, .75) !default;
$navbar-dark-hover-color: $white !default;
// Pagination
// Pagination
$pagination-color: $white !default;
$pagination-bg: $primary !default;
$pagination-border-width: 0 !default;
$pagination-border-color: transparent !default;
$pagination-bg: $gray-700 !default;
$pagination-border-width: 1px !default;
$pagination-border-color: rgba($gray-500, .55) !default;
$pagination-hover-color: $white !default;
$pagination-hover-bg: color.adjust($primary, $lightness: 8%) !default;
$pagination-hover-border-color: transparent !default;
$pagination-active-bg: color.adjust($primary, $lightness: 8%) !default;
$pagination-active-border-color: transparent !default;
$pagination-disabled-color: $gray-300 !default;
$pagination-disabled-bg: color.adjust($primary, $lightness: -15%) !default;
$pagination-disabled-border-color:transparent !default;
$pagination-hover-bg: $primary !default;
$pagination-hover-border-color: $primary !default;
$pagination-active-bg: $primary !default;
$pagination-active-border-color: $primary !default;
$pagination-disabled-color: $gray-500 !default;
$pagination-disabled-bg: rgba($gray-700, .5) !default;
$pagination-disabled-border-color:rgba($gray-500, .3) !default;
// Cards
// Cards
$card-cap-bg: $gray-600 !default;
$card-bg: $gray-700 !default;
$card-border-color: rgba($gray-500, .55) !default;
$card-cap-color: $white !default;
$card-cap-bg: #2d1052 !default;
$card-bg: #1c003a !default;
// Modals
$modal-content-bg: $gray-700 !default;
$modal-content-border-color: $gray-500 !default;
$modal-header-border-color: $gray-500 !default;
// Popovers
// Popovers
$popover-bg: $gray-700 !default;
$popover-header-bg: $gray-600 !default;
$popover-bg: #1c003a !default;
$popover-header-bg: #2d1052 !default;
// Modals
$modal-content-bg: #1c003a !default;
$modal-content-border-color: #3d1278 !default;
$modal-header-border-color: #3d1278 !default;
// Progress bars
$progress-bg: #2d1052 !default;
// List group
// Progress
$progress-bg: $gray-600 !default;
// List group
$list-group-color: $body-color !default;
$list-group-bg: #1c003a !default;
$list-group-border-color: #3d1278 !default;
$list-group-hover-bg: #2d1052 !default;
$list-group-action-hover-color: $list-group-color !default;
$list-group-bg: $gray-700 !default;
$list-group-border-color: $gray-500 !default;
$list-group-hover-bg: $gray-600 !default;
$list-group-action-hover-color: $white !default;
$list-group-action-active-bg: $gray-900 !default;
// Breadcrumbs
// Breadcrumbs
$breadcrumb-padding-y: .375rem !default;
$breadcrumb-padding-x: .75rem !default;
$breadcrumb-bg: #2d1052 !default;
$breadcrumb-bg: $gray-700 !default;
$breadcrumb-border-radius:.25rem !default;
// Close button
// Misc
$btn-close-color: $white !default;
$btn-close-opacity: .5 !default;
$btn-close-hover-opacity:1 !default;
// Code
$pre-color: inherit !default;
+67 -1
View File
@@ -1,3 +1,69 @@
$(document).ready(function() {
/* Add custom javascript code here */
if (typeof Chart === 'undefined') return;
// ── Y-axis: abbreviate large numbers ─────────────────────────
// 1400000 → "1.4M", 45000 → "45K", 999 → "999"
function fmtAxis(value) {
var abs = Math.abs(value);
if (abs >= 1e9) return (value / 1e9).toFixed(1).replace(/\.0$/, '') + 'B';
if (abs >= 1e6) return (value / 1e6).toFixed(1).replace(/\.0$/, '') + 'M';
if (abs >= 1e3) return (value / 1e3).toFixed(1).replace(/\.0$/, '') + 'K';
return value;
}
var font = { family: 'Inter, system-ui, sans-serif', size: 11 };
// ── Linear scale (Y-axis on both charts) ─────────────────────
var lin = Chart.defaults.scales.linear;
if (lin) {
lin.ticks = Object.assign({}, lin.ticks, {
callback: fmtAxis,
font: font,
color: 'rgba(200,160,255,0.85)',
padding: 8,
maxTicksLimit: 6
});
lin.title = Object.assign({}, lin.title, {
font: Object.assign({}, font, { weight: '700', size: 11 }),
color: 'rgba(216,180,254,1)'
});
lin.grid = Object.assign({}, lin.grid, {
color: 'rgba(80,40,130,0.3)'
});
}
// ── Time scale (X-axis) ───────────────────────────────────────
// Reduce label density and avoid 90° rotation
['time', 'timeseries'].forEach(function(t) {
var s = Chart.defaults.scales[t];
if (!s) return;
s.ticks = Object.assign({}, s.ticks, {
font: font,
color: 'rgba(200,160,255,0.75)',
maxTicksLimit: 6,
maxRotation: 30,
minRotation: 0,
padding: 6
});
s.grid = Object.assign({}, s.grid, {
color: 'rgba(80,40,130,0.3)'
});
});
// ── Tooltip ───────────────────────────────────────────────────
Object.assign(Chart.defaults.plugins.tooltip, {
backgroundColor: 'rgba(10,0,28,0.96)',
borderColor: 'rgba(93,33,182,0.65)',
borderWidth: 1,
titleColor: 'rgba(216,180,254,1)',
titleFont: Object.assign({}, font, { weight: '700', size: 12 }),
bodyColor: 'rgba(240,230,255,0.9)',
bodyFont: Object.assign({}, font, { size: 12 }),
padding: 11,
cornerRadius: 7
});
// ── Legend ────────────────────────────────────────────────────
Chart.defaults.plugins.legend.labels.font = Object.assign({}, font, { size: 12 });
Chart.defaults.plugins.legend.labels.color = 'rgba(216,180,254,1)';
});