﻿html,
body {
font-family: 'Inter', sans-serif;
background: var(--bg-base);
color: var(--text-primary);
}
html {
scroll-behavior: smooth;
}
body {
min-height: 100dvh;
margin: 0;
}
.auth-bootstrap-loading {
display: flex;
align-items: center;
justify-content: center;
min-height: 100vh;
color: #666;
}
a,
.btn-link {
color: var(--primary);
}
.btn-primary {
color: #fff;
background: var(--primary-gradient);
border-color: transparent;
border-radius: 16px;
box-shadow: 0 14px 24px rgba(var(--primary-rgb), 0.18);
}
.btn:focus,
.btn:active:focus,
.btn-link.nav-link:focus,
.form-control:focus,
.form-check-input:focus {
box-shadow: 0 0 0 4px rgba(var(--primary-rgb), 0.15);
}
.content {
padding-top: 1.1rem;
}
h1:focus {
outline: none;
}
.valid.modified:not([type=checkbox]) {
outline: 1px solid #26b050;
}
.invalid {
outline: 1px solid #e50000;
}
.validation-message {
color: #e50000;
}
.blazor-error-boundary {
background: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTYiIGhlaWdodD0iNDkiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIG92ZXJmbG93PSJoaWRkZW4iPjxkZWZzPjxjbGlwUGF0aCBpZD0iY2xpcDAiPjxyZWN0IHg9IjIzNSIgeT0iNTEiIHdpZHRoPSI1NiIgaGVpZ2h0PSI0OSIvPjwvY2xpcFBhdGg+PC9kZWZzPjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMCkiIHRyYW5zZm9ybT0idHJhbnNsYXRlKC0yMzUgLTUxKSI+PHBhdGggZD0iTTI2My41MDYgNTFDMjY0LjcxNyA1MSAyNjUuODEzIDUxLjQ4MzcgMjY2LjYwNiA1Mi4yNjU4TDI2Ny4wNTIgNTIuNzk4NyAyNjcuNTM5IDUzLjYyODMgMjkwLjE4NSA5Mi4xODMxIDI5MC41NDUgOTIuNzk1IDI5MC42NTYgOTIuOTk2QzI5MC44NzcgOTMuNTEzIDI5MSA5NC4wODE1IDI5MSA5NC42NzgyIDI5MSA5Ny4wNjUxIDI4OS4wMzggOTkgMjg2LjYxNyA5OUwyNDAuMzgzIDk5QzIzNy45NjMgOTkgMjM2IDk3LjA2NTEgMjM2IDk0LjY3ODIgMjM2IDk0LjM3OTkgMjM2LjAzMSA5NC4wODg2IDIzNi4wODkgOTMuODA3MkwyMzYuMzM4IDkzLjAxNjIgMjM2Ljg1OCA5Mi4xMzE0IDI1OS40NzMgNTMuNjI5NCAyNTkuOTYxIDUyLjc5ODUgMjYwLjQwNyA1Mi4yNjU4QzI2MS4yIDUxLjQ4MzcgMjYyLjI5NiA1MSAyNjMuNTA2IDUxWk0yNjMuNTg2IDY2LjAxODNDMjYwLjczNyA2Ni4wMTgzIDI1OS4zMTMgNjcuMTI0NSAyNTkuMzEzIDY5LjMzNyAyNTkuMzEzIDY5LjYxMDIgMjU5LjMzMiA2OS44NjA4IDI1OS4zNzEgNzAuMDg4N0wyNjEuNzk1IDg0LjAxNjEgMjY1LjM4IDg0LjAxNjEgMjY3LjgyMSA2OS43NDc1QzI2Ny44NiA2OS43MzA5IDI2Ny44NzkgNjkuNTg3NyAyNjcuODc5IDY5LjMxNzkgMjY3Ljg3OSA2Ny4xMTgyIDI2Ni40NDggNjYuMDE4MyAyNjMuNTg2IDY2LjAxODNaTTI2My41NzYgODYuMDU0N0MyNjEuMDQ5IDg2LjA1NDcgMjU5Ljc4NiA4Ny4zMDA1IDI1OS43ODYgODkuNzkyMSAyNTkuNzg2IDkyLjI4MzcgMjYxLjA0OSA5My41Mjk1IDI2My41NzYgOTMuNTI5NSAyNjYuMTE2IDkzLjUyOTUgMjY3LjM4NyA5Mi4yODM3IDI2Ny4zODcgODkuNzkyMSAyNjcuMzg3IDg3LjMwMDUgMjY2LjExNiA4Ni4wNTQ3IDI2My41NzYgODYuMDU0N1oiIGZpbGw9IiNGRkU1MDAiIGZpbGwtcnVsZT0iZXZlbm9kZCIvPjwvZz48L3N2Zz4=) no-repeat 1rem/1.8rem, #b32121;
padding: 1rem 1rem 1rem 3.7rem;
color: white;
}
.blazor-error-boundary::after {
content: "An error has occurred."
}
.darker-border-checkbox.form-check-input {
border-color: #929292;
}
#blazor-error-ui {
background: #fef2f2;
border-top: 2px solid #dc2626;
color: #1f2937;
bottom: 0;
left: 0;
right: 0;
position: fixed;
padding: 12px 56px 12px 18px;
font-size: 13px;
line-height: 1.5;
box-shadow: 0 -2px 8px rgba(0, 0, 0, 0.08);
z-index: 1000;
}
#blazor-error-ui .blazor-error-msg strong {
color: #dc2626;
margin-right: 6px;
}
#blazor-error-ui .reload {
color: #2563eb;
font-weight: 600;
text-decoration: underline;
cursor: pointer;
}
#blazor-error-ui .dismiss {
position: absolute;
right: 16px;
top: 8px;
font-size: 20px;
color: #6b7280;
cursor: pointer;
text-decoration: none;
line-height: 1;
}
#blazor-error-ui .dismiss:hover {
color: #1f2937;
}
/* Fonts (Inter + Fira Code) load from self-hosted lib/fonts/fonts.css in App.razor. */
/* ============================================================
CSS VARIABLES — Light Theme
============================================================ */
:root {
--bg-base: #F1F5F9;
--bg-surface: #FFFFFF;
--bg-elevated: #F8FAFC;
--bg-card: var(--bg-surface, #FFFFFF);
--bg-sidebar: var(--bg-surface, #FFFFFF);
--border: #E2E8F0;
--border-light: var(--border, #CBD5E1);
--bg-header: var(--bg-surface, #FFFFFF);
--header-text: var(--text-primary, #0F172A);
--primary: #009999;
--primary-dim: rgba(0, 153, 153, 0.10);
--primary-glow: rgba(0, 153, 153, 0.20);
--accent: #00B2B2;
--accent-dim: var(--primary-dim, rgba(0, 153, 153, 0.10));
--success: #10B981;
--danger: #f84545;
--warning: #F59E0B;
--text-primary: #0F172A;
--text-secondary: #475569;
--text-muted: #94A3B8;
/* Sidebar */
--sidebar-text: var(--text-secondary);
--sidebar-text-muted: var(--text-muted);
--sidebar-active-bg: var(--primary-dim);
--sidebar-active-text: var(--primary);
--sidebar-hover-bg: var(--bg-elevated);
--sidebar-border: var(--border);
--sidebar-w: clamp(220px, 22vw, 260px);
--sidebar-collapsed: 64px;
--header-h: 60px;
--radius: 6px;
--radius-lg: 12px;
--transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1);
}
/* ============================================================
RESET & BASE
============================================================ */
*,
*::before,
*::after {
box-sizing: border-box;
}
html {
scroll-behavior: smooth;
width: 100%;
overflow-x: hidden;
}
body {
font-family: 'Inter', sans-serif;
background: var(--bg-base);
color: var(--text-primary);
margin: 0;
min-height: 100vh;
font-size: clamp(11px, 0.2vw + 11px, 14px);
line-height: 1.6;
-webkit-font-smoothing: antialiased;
width: 100%;
overflow-x: hidden;
}
img,
svg,
video,
canvas,
iframe {
max-width: 100%;
height: auto;
}
::-webkit-scrollbar {
width: 4px;
height: 4px;
}
::-webkit-scrollbar-track {
background: transparent;
}
::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 20px;
}
::-webkit-scrollbar-thumb:hover {
background: var(--border-light);
}
a {
text-decoration: none;
color: inherit;
}
/* ============================================================
LOGIN PAGE
============================================================ */
.login-page {
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
background:
radial-gradient(circle at 14% 18%, rgba(var(--primary-rgb), 0.18) 0%, transparent 28%),
radial-gradient(circle at 84% 14%, rgba(var(--primary-rgb), 0.10) 0%, transparent 24%),
radial-gradient(circle at 76% 82%, rgba(var(--primary-rgb), 0.08) 0%, transparent 22%),
linear-gradient(145deg, var(--bg-base) 0%, var(--bg-elevated) 52%, var(--bg-base) 100%);
position: relative;
overflow: hidden;
}
/* Animated grid background */
.login-page::before {
content: '';
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(var(--primary-rgb), 0.06) 1px, transparent 1px),
linear-gradient(90deg, rgba(var(--primary-rgb), 0.06) 1px, transparent 1px);
background-size: 40px 40px;
animation: gridShift 20s linear infinite;
opacity: 0.75;
}
/* Radial glow orbs */
.login-page::after {
content: '';
position: absolute;
width: 600px;
height: 600px;
background: radial-gradient(circle, rgba(var(--primary-rgb), 0.14) 0%, rgba(var(--primary-rgb), 0.04) 38%, transparent 72%);
top: -100px;
right: -100px;
border-radius: 50%;
filter: blur(10px);
animation: pulseOrb 6s ease-in-out infinite alternate;
}
@keyframes gridShift {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(40px, 40px);
}
}
@keyframes pulseOrb {
0% {
transform: scale(1);
opacity: 0.6;
}
100% {
transform: scale(1.15);
opacity: 1;
}
}
.login-card {
position: relative;
z-index: 10;
width: 100%;
max-width: 420px;
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 40px;
box-shadow:
0 0 0 1px rgba(var(--primary-rgb), 0.08),
0 24px 60px rgba(15, 23, 42, 0.14),
0 8px 20px rgba(var(--primary-rgb), 0.10);
animation: slideUp 0.5s cubic-bezier(0.16, 1, 0.3, 1) both;
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(30px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.login-logo {
display: flex;
align-items: center;
gap: 10px;
margin-bottom: 32px;
}
.login-logo .logo-icon {
width: 40px;
height: 40px;
background: linear-gradient(135deg, var(--primary), var(--primary-light));
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4px 14px var(--primary-glow);
}
.login-logo .logo-icon svg {
color: #fff;
}
.login-logo .logo-text {
font-size: 18px;
font-weight: 700;
color: var(--text-primary);
}
.login-logo .logo-text span {
color: var(--primary);
}
.login-title {
font-size: 22px;
font-weight: 700;
margin-bottom: 6px;
}
.login-subtitle {
color: var(--text-secondary);
font-size: 13px;
margin-bottom: 28px;
}
.form-label {
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-secondary);
margin-bottom: 6px;
}
.form-control {
background: var(--bg-elevated) !important;
border: 1px solid var(--border) !important;
color: var(--text-primary) !important;
border-radius: var(--radius) !important;
padding: 10px 14px !important;
font-size: 14px !important;
transition: var(--transition) !important;
}
.form-control:focus {
border-color: var(--primary) !important;
box-shadow: 0 0 0 3px var(--primary-dim) !important;
outline: none !important;
}
.form-control::placeholder {
color: var(--text-muted) !important;
}
.input-icon-wrap {
position: relative;
}
.input-icon-wrap .icon-left {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--text-muted);
pointer-events: none;
}
.input-icon-wrap .form-control {
padding-left: 38px !important;
}
.input-icon-wrap .icon-right {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--text-muted);
cursor: pointer;
transition: var(--transition);
}
.input-icon-wrap .icon-right:hover {
color: var(--text-primary);
}
.btn-login {
width: 100%;
background: linear-gradient(135deg, var(--primary), #9E6DC9);
border: none;
color: #fff;
font-weight: 700;
font-size: 14px;
padding: 12px;
border-radius: var(--radius);
cursor: pointer;
transition: var(--transition);
box-shadow: 0 4px 16px var(--primary-glow);
position: relative;
overflow: hidden;
}
.btn-login::before {
content: '';
position: absolute;
inset: 0;
background: rgba(255, 255, 255, 0);
transition: var(--transition);
}
.btn-login:hover::before {
background: rgba(255, 255, 255, 0.08);
}
.btn-login:hover {
box-shadow: 0 6px 24px rgba(190, 160, 226, 0.4);
transform: translateY(-1px);
}
.btn-login:active {
transform: translateY(0);
}
.login-footer {
text-align: center;
margin-top: 24px;
font-size: 12px;
color: var(--text-muted);
}
/* ============================================================
SIDEBAR — Clean Light
============================================================ */
.sidebar {
width: var(--sidebar-w);
min-height: 100vh;
background: var(--bg-sidebar);
border-right: 1px solid var(--sidebar-border);
display: flex;
flex-direction: column;
position: fixed;
top: 0;
left: 0;
bottom: 0;
z-index: 1000;
transition: width 0.25s cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
}
.sidebar.collapsed {
width: var(--sidebar-collapsed);
}
/* ── Brand ── */
.sidebar-brand {
display: flex;
align-items: center;
gap: 10px;
padding: 0 16px;
height: var(--header-h);
border-bottom: 1px solid var(--sidebar-border);
background: var(--bg-sidebar);
flex-shrink: 0;
text-decoration: none;
overflow: hidden;
white-space: nowrap;
}
.sidebar-brand .brand-icon {
width: 30px;
height: 30px;
min-width: 30px;
background: var(--primary);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.sidebar-brand .brand-text {
font-size: 14px;
font-weight: 700;
color: var(--sidebar-text);
letter-spacing: -0.01em;
white-space: nowrap;
opacity: 1;
transition: opacity 0.2s;
}
.sidebar-brand .brand-text span {
color: var(--primary);
}
.sidebar.collapsed .brand-text {
opacity: 0;
pointer-events: none;
}
/* ── Nav scroll area ── */
.sidebar-nav {
flex: 1;
background-color: var(--bg-sidebar);
overflow-y: auto;
overflow-x: hidden;
padding: 8px 10px;
scrollbar-width: none;
}
.sidebar-nav::-webkit-scrollbar {
display: none;
}
/* ── Section label ── */
.nav-section-label {
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--sidebar-text-muted);
padding: 14px 8px 4px;
white-space: nowrap;
overflow: hidden;
transition: opacity 0.2s;
padding-left: 10px;
}
.sidebar.collapsed .nav-section-label {
opacity: 0;
}
/* .sidebar.collapsed .sidebar-nav {
padding-left: 0;
padding-right: 0;
} */
/* ── Nav item wrapper ── */
.nav-item-wrap {
position: relative;
margin-bottom: 12px;
}
/* ── Parent nav item ── */
.nav-link-item {
display: flex;
align-items: center;
gap: 9px;
padding: 8px 10px;
cursor: pointer;
border-radius: 7px;
transition: var(--transition);
color: var(--sidebar-text);
position: relative;
white-space: nowrap;
user-select: none;
}
.nav-link-item:hover {
background: var(--bg-elevated);
color: var(--text-primary);
}
.nav-link-item.active {
background: var(--sidebar-active-bg);
color: var(--sidebar-active-text);
font-weight: 600;
}
/* Left accent bar for active */
.nav-link-item.active::before {
content: '';
position: absolute;
left: -10px;
top: 6px;
bottom: 6px;
width: 3px;
background: var(--primary);
border-radius: 0 3px 3px 0;
}
/* ── Nav icon ── */
.nav-link-item .nav-icon {
width: 17px;
height: 17px;
min-width: 17px;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
opacity: 0.65;
transition: opacity 0.15s;
}
.nav-link-item:hover .nav-icon,
.nav-link-item.active .nav-icon {
opacity: 1;
}
/* ── Nav label ── */
.nav-link-item .nav-label {
flex: 1;
font-size: 13px;
font-weight: 500;
opacity: 1;
transition: opacity 0.2s;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
min-width: 0;
}
.sidebar.collapsed .nav-label {
opacity: 0;
width: 0;
flex: 0
}
/* ── Chevron ── */
.nav-link-item .nav-chevron {
width: 14px;
height: 14px;
transition: transform 0.2s;
opacity: 0.35;
flex-shrink: 0;
}
.nav-link-item.open .nav-chevron {
transform: rotate(90deg);
}
.sidebar.collapsed .nav-chevron {
opacity: 0;
width: 0;
}
/* ── Sub-menu ── */
.nav-submenu {
overflow: hidden;
max-height: 0;
transition: max-height 0.28s cubic-bezier(0.4, 0, 0.2, 1);
}
.nav-submenu.open {
max-height: 600px;
}
.sidebar.collapsed .nav-submenu {
display: none;
}
/* Sub-item container adds a vertical line on left */
.nav-submenu {
margin-left: 14px;
padding-left: 14px;
border-left: 1.5px solid #E2E8F0;
margin-top: 4px;
}
.nav-sub-item {
display: flex;
align-items: center;
padding: 6px 8px;
border-radius: 6px;
color: var(--text-muted);
cursor: pointer;
transition: var(--transition);
font-size: 12.5px;
font-weight: 400;
white-space: nowrap;
position: relative;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.nav-sub-item:hover {
background: var(--bg-elevated);
color: var(--text-secondary);
}
.nav-sub-item.active {
color: var(--primary);
font-weight: 500;
background: var(--primary-dim);
}
/* ── Collapsed: center icons ── */
.sidebar.collapsed .nav-link-item {
justify-content: center;
padding: 8px 0;
gap: 0;
}
.sidebar.collapsed .nav-link-item .nav-icon {
margin: 0 auto;
}
/* In collapsed mode the ::before is at left:-10px which gets clipped.
Re-anchor it to the sidebar's left edge. */
.sidebar.collapsed .nav-link-item.active::before {
/* left: 0; */
border-radius: 0 3px 3px 0;
width: 3px;
}
/* Slightly stronger bg so the tint is visible even with icon-only layout */
.sidebar.collapsed .nav-link-item.active {
background: var(--primary-dim);
}
.sidebar.collapsed .nav-sub-item {
display: none;
}
/* ── Collapsed flyout submenu ── */
.sidebar-flyout {
position: fixed;
left: calc(var(--sidebar-collapsed) + 8px);
z-index: 1100;
background: var(--bg-surface);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
border: 1px solid var(--border);
border-radius: 14px;
box-shadow: 0 12px 48px rgba(0,0,0,0.18), 0 0 0 1px rgba(255,255,255,0.05);
padding: 8px;
min-width: 200px;
animation: flyoutIn 0.25s cubic-bezier(0.16, 1, 0.3, 1) both;
transform-origin: left center;
}
@keyframes flyoutIn {
from {
opacity: 0;
transform: translateX(-6px) scale(0.97);
}
to {
opacity: 1;
transform: translateX(0) scale(1);
}
}
.sidebar-flyout-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--text-muted);
padding: 4px 10px 6px;
border-bottom: 1px solid var(--border);
margin-bottom: 4px;
}
.sidebar-flyout-item {
display: flex;
align-items: center;
padding: 8px 12px;
margin-bottom: 2px;
border-radius: 8px;
font-size: 13px;
font-weight: 500;
color: var(--text-secondary);
cursor: pointer;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
white-space: nowrap;
}
.sidebar-flyout-item:last-child { margin-bottom: 0; }
.sidebar-flyout-item:hover {
background: var(--primary-dim);
color: var(--primary);
}
.sidebar-flyout-item.active {
background: var(--primary-dim);
color: var(--primary);
font-weight: 600;
}
/* ── Sidebar footer / user card ── */
.sidebar-footer {
border-top: 1px solid var(--border);
padding: 10px 12px;
flex-shrink: 0;
overflow: hidden;
white-space: nowrap;
}
.user-info {
display: flex;
align-items: center;
gap: 10px;
cursor: pointer;
padding: 6px 4px;
border-radius: 8px;
transition: background 0.15s;
}
.user-info:hover {
background: var(--bg-elevated);
}
.user-avatar {
width: 30px;
height: 30px;
min-width: 30px;
border-radius: 8px;
background: var(--primary);
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 700;
color: #fff;
flex-shrink: 0;
letter-spacing: 0.02em;
}
.user-details {
overflow: hidden;
opacity: 1;
transition: opacity 0.2s;
}
.sidebar.collapsed .user-details {
opacity: 0;
width: 0;
}
.user-name {
font-size: 12.5px;
font-weight: 600;
color: var(--sidebar-text);
line-height: 1.3;
}
.user-role {
font-size: 11px;
color: var(--sidebar-text-muted);
margin-top: 1px;
}
/* ============================================================
HEADER
============================================================ */
.app-header {
height: var(--header-h);
background: var(--bg-header);
border-bottom: 1px solid var(--border);
display: flex;
align-items: center;
padding: 0 20px;
gap: 12px;
position: fixed;
top: 0;
right: 0;
left: var(--sidebar-w);
z-index: 900;
transition: left 0.25s cubic-bezier(0.4, 0, 0.2, 1);
flex-wrap: nowrap !important;
}
.app-header.collapsed {
left: var(--sidebar-collapsed);
}
.header-toggle {
width: 32px;
height: 32px;
display: flex;
align-items: center;
justify-content: center;
border: none;
background: transparent;
color: var(--header-text);
cursor: pointer;
border-radius: 6px;
transition: var(--transition);
flex-shrink: 0;
}
.header-toggle:hover {
background: var(--bg-elevated);
color: var(--text-primary);
}
.header-breadcrumb {
display: flex;
align-items: center;
gap: 6px;
flex: 1;
min-width: 0;
overflow: hidden;
}
.breadcrumb-sep {
color: var(--text-muted);
font-size: 12px;
flex-shrink: 0;
}
.breadcrumb-item {
font-size: 13px;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.breadcrumb-item.active {
color: var(--text-primary);
font-weight: 600;
}
.breadcrumb-item:first-child {
color: var(--primary);
}
.app-header-actions {
display: flex;
align-items: center;
gap: 4px;
margin-left: auto;
}
.header-search {
position: relative;
display: flex;
align-items: center;
}
.header-search input {
background: var(--bg-elevated) !important;
color: var(--text-primary) !important;
font-size: 13px;
padding: 7px 12px 7px 34px;
border-radius: 8px;
width: 220px;
transition: var(--transition);
}
.header-search input:focus {
outline: none;
background: var(--bg-surface) !important;
border-color: var(--primary) !important;
box-shadow: 0 0 0 3px var(--primary-dim);
width: 260px;
}
.header-search svg {
position: absolute;
left: 11px;
top: 50%;
transform: translateY(-50%);
color: var(--text-muted);
opacity: 0.7;
pointer-events: none;
}
.header-search input::placeholder {
color: var(--text-muted);
}
.header-btn {
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
color: var(--header-text);
cursor: pointer;
border-radius: 8px;
position: relative;
transition: var(--transition);
}
.header-btn:hover {
background: var(--bg-elevated);
color: var(--text-primary);
}
.badge-dot {
position: absolute;
top: 6px;
right: 6px;
width: 7px;
height: 7px;
background: var(--danger);
border-radius: 50%;
border: 1.5px solid var(--bg-surface);
}
.header-divider {
width: 0;
border-left: 1px solid var(--border);
height: 18px;
margin: 0 6px;
flex-shrink: 0;
opacity: 0.5;
}
.app-header .user-avatar {
width: 32px;
height: 32px;
border-radius: 8px;
background: linear-gradient(135deg, var(--primary), var(--primary-light));
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 700;
color: #fff;
cursor: pointer;
transition: var(--transition);
box-shadow: 0 2px 8px var(--primary-glow);
border: 1px solid rgba(255, 255, 255, 0.25);
flex-shrink: 0;
}
.app-header .user-avatar:hover {
box-shadow: 0 4px 16px var(--primary-glow);
transform: translateY(-1px);
}
/* ============================================================
MAIN CONTENT
============================================================ */
.app-main {
margin-left: var(--sidebar-w);
margin-top: var(--header-h);
padding: 12px 16px 10px;
height: calc(100vh - var(--header-h));
transition: margin-left 0.3s ease;
overflow-x: hidden;
/* Ensure DRP panel isn't clipped */
flex: 1;
}
.app-main.collapsed {
margin-left: var(--sidebar-collapsed);
}
/* ============================================================
PAGE CONTENT
============================================================ */
.page-view {
display: none;
}
.page-view.active {
display: block;
animation: fadeIn 0.25s ease;
}
@keyframes fadeIn {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.page-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 12px;
flex-shrink: 0;
}
.page-title {
font-size: 22px;
font-weight: 700;
color: var(--text-primary);
margin: 0;
}
.page-subtitle {
font-size: 13px;
color: var(--text-muted);
margin-top: 2px;
}
/* ============================================================
CARDS
============================================================ */
.card-bo {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 6px 10px;
overflow: visible;
max-width: 100%;
/* Fill remaining vertical space in app-main */
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
/* Filter cards need overflow:visible so absolutely-positioned dropdowns
(MultipleFilterPartnerTrees .ptt-dropdown, FilterSelect, etc.) are not
clipped by the card's bottom border. The default .card-bo { overflow:hidden }
above was introduced in bf8b1c3 to clip child rounded corners — that
rule still applies to non-filter cards. Auto-applied via :has() so any
card containing a .filter-grid opts out without per-page markup. */
.card-bo:has(.filter-grid) {
overflow: visible;
/* Filter cards keep their natural height, don't stretch */
flex: 0 0 auto;
}
.stat-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
padding: 20px;
transition: var(--transition);
cursor: default;
flex: 0 0 auto;
}
.stat-card:hover {
border-color: var(--border-light);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
transform: translateY(-2px);
}
.stat-icon {
width: 44px;
height: 44px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 14px;
}
.stat-value {
font-size: 26px;
font-weight: 700;
color: var(--text-primary);
font-family: 'Fira Code', monospace;
margin-bottom: 4px;
}
.stat-label {
font-size: 12px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.06em;
}
.stat-change {
font-size: 12px;
font-weight: 600;
margin-top: 8px;
display: flex;
align-items: center;
gap: 3px;
}
.stat-change.up {
color: var(--success);
}
.stat-change.down {
color: var(--danger);
}
/* ============================================================
TABLE
============================================================ */
.table-bo {
width: 100%;
height: auto;
border-collapse: separate;
border-spacing: 0;
font-size: 12px;
color: var(--text-primary);
border: none;
table-layout: auto !important;
min-width: 1000px; /* Ensure table is wide enough to trigger horizontal scroll */
}
.table-bo thead th {
background-color: var(--bg-elevated);
backdrop-filter: blur(12px);
-webkit-backdrop-filter: blur(12px);
color: var(--text-primary); /* Highly readable primary text color */
font-weight: 800; /* Stronger contrast header */
font-size: 10.5px;
text-transform: uppercase;
letter-spacing: 0.08em;
padding: 12px 14px; /* Premium comfortable padding */
border-bottom: 2px solid var(--border); /* Clear horizontal separator */
text-align: center;
vertical-align: middle;
position: sticky;
top: 0;
z-index: 10;
white-space: normal; /* Allow header labels to wrap naturally */
word-break: normal;
overflow-wrap: break-word;
box-shadow: inset 0 -1px 0 var(--border);
line-height: 1.25;
}
.table-bo thead th:first-child {
border-radius: 12px 0 0 0;
padding-left: 20px;
}
.table-bo thead th:last-child {
border-radius: 0 12px 0 0;
padding-right: 20px;
}
.table-bo tbody tr {
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
background-color: var(--bg-surface);
}
.table-bo tbody tr:nth-child(even) td {
background-color: rgba(var(--primary-rgb), 0.015);
}
body.theme-onyx .table-bo tbody tr:nth-child(even) td {
background-color: rgba(255, 255, 255, 0.004);
}
.table-bo tbody td {
padding: 10px 14px; /* Balanced SaaS spacing */
border-bottom: 1px solid var(--border);
color: var(--text-primary);
font-size: 12.5px;
background: var(--bg-surface);
transition: background-color 0.2s ease, color 0.2s ease;
vertical-align: middle;
text-align: left;
white-space: nowrap;
text-overflow: ellipsis;
line-height: 1.35;
position: relative;
word-break: break-word; /* Wrap long descriptions to avoid horizontal scrolling */
}
.table-bo tbody td:first-child {
padding-left: 20px;
}
.table-bo tbody td:last-child {
padding-right: 20px;
}
/* Exempt badges from truncation - they should always show fully if possible, but never overlap */
.table-bo tbody td:has(.badge-status),
.table-bo tbody td:has(.badge-currency),
.table-bo tbody td:has(.badge-type),
.table-bo tbody td:has(.badge-payout-status),
.table-bo tbody td.col-status {
overflow: hidden !important;
text-overflow: clip !important;
}
.table-bo tbody tr:hover td {
background-color: rgba(var(--primary-rgb), 0.04) !important;
}
.table-bo tbody tr:hover td:first-child {
box-shadow: inset 3px 0 0 var(--primary) !important; /* Modern focus indicators on hover */
}
/* Completed row highlight */
.table-bo tbody tr.row-completed td {
background-color: rgba(16, 185, 129, 0.04) !important;
}
/* Modern clean left accents for complete / failed rows */
.table-bo tbody tr.row-completed {
border-left: 4px solid var(--success) !important;
}
.table-bo tbody tr.row-failed {
border-left: 4px solid var(--danger) !important;
}
.table-responsive {
display: block;
width: 100%;
height: auto;
overflow-x: auto !important;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
position: relative;
border-radius: 16px 16px 0 0;
border: 1px solid var(--border);
background: var(--bg-surface);
}
/* Custom premium scrollbar for table container */
.table-responsive::-webkit-scrollbar {
height: 6px;
width: 6px;
}
.table-responsive::-webkit-scrollbar-track {
background: transparent;
}
.table-responsive::-webkit-scrollbar-thumb {
background: rgba(var(--primary-rgb), 0.15);
border-radius: 10px;
}
.table-responsive::-webkit-scrollbar-thumb:hover {
background: rgba(var(--primary-rgb), 0.3);
}
/* If the page has a filter card, restrict the table height so only the table scrolls */
.app-main:has(.filter-grid) .table-responsive {
height: calc(100vh - var(--header-h) - 240px);
max-height: calc(100vh - var(--header-h) - 240px);
}
/* If the page has both currency tabs and a filter card, restrict further */
.app-main:has(.currency-tabs):has(.filter-grid) .table-responsive {
height: calc(100vh - var(--header-h) - 350px);
max-height: calc(100vh - var(--header-h) - 350px);
}
/* For pages where currency tabs are housed inside the filter card (MatchingDetail/HeldManual), restrict height further to prevent body overflow */
.app-main:has(.card-bo:has(.currency-tabs)):has(.filter-grid) .table-responsive {
height: calc(100vh - var(--header-h) - 400px);
max-height: calc(100vh - var(--header-h) - 400px);
}
.app-main:has(.p2p-pagination):has(.filter-grid) .table-responsive {
height: calc(100vh - var(--header-h) - 280px);
max-height: calc(100vh - var(--header-h) - 280px);
}
/* Pages without filter card: card-bo has pagination → table can be much taller */
.app-main:not(:has(.filter-grid)) .card-bo:has(.p2p-pagination) .table-responsive {
height: calc(100vh - var(--header-h) - 130px);
max-height: calc(100vh - var(--header-h) - 130px);
}
.app-main:not(:has(.filter-grid)) .card-bo .table-responsive {
height: calc(100vh - var(--header-h) - 270px);
max-height: calc(100vh - var(--header-h) - 270px);
}
/* --- Non-paginated Table Overrides --- */
.card-bo:not(:has(.p2p-pagination)) .table-responsive {
height: calc(100vh - var(--header-h) - 130px);
max-height: calc(100vh - var(--header-h) - 130px);
}
.app-main:has(.filter-grid) .card-bo:not(:has(.p2p-pagination)) .table-responsive {
height: calc(100vh - var(--header-h) - 240px);
max-height: calc(100vh - var(--header-h) - 240px);
}
.app-main:has(.currency-tabs):has(.filter-grid) .card-bo:not(:has(.p2p-pagination)) .table-responsive {
height: calc(100vh - var(--header-h) - 340px);
max-height: calc(100vh - var(--header-h) - 340px);
}
.app-main:not(:has(.filter-grid)) .card-bo:not(:has(.p2p-pagination)) .table-responsive {
height: calc(100vh - var(--header-h) - 100px);
max-height: calc(100vh - var(--header-h) - 100px);
}
.card-bo:not(:has(.p2p-pagination)) .table-bo {
min-width: 100% !important;
overflow: hidden !important;
}
.table-responsive::-webkit-scrollbar {
height: 8px;
}
.table-responsive::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.05);
border-radius: 10px;
}
.table-responsive::-webkit-scrollbar-thumb {
background: var(--text-muted);
border-radius: 10px;
border: 2px solid transparent;
background-clip: content-box;
}
.table-responsive::-webkit-scrollbar-thumb:hover {
background: var(--text-secondary);
}
/* Pagination inside card-bo must not shrink */
.p2p-pagination {
flex-shrink: 0;
}
/* Completed row highlight */
.table-bo tbody tr.row-completed td {
background-color: rgba(16, 185, 129, 0.04) !important;
border-bottom-color: var(--border);
}
body.theme-onyx .table-bo tbody tr.row-completed td {
background-color: rgba(16, 185, 129, 0.06) !important;
color: #FFFFFF !important;
}
/* Failed/Error row highlight */
.table-bo tbody tr.row-failed td {
background-color: rgba(239, 68, 68, 0.04) !important;
border-bottom-color: var(--border);
}
body.theme-onyx .table-bo tbody tr.row-failed td {
background-color: rgba(239, 68, 68, 0.06) !important;
color: #FF5A5A !important;
}
/* Brighter base table text for Onyx to avoid dimness */
body.theme-onyx .table-bo td {
color: var(--text-primary);
}
/* Table border refinement for Onyx */
body.theme-onyx .table-bo thead th {
border-bottom-color: #334155 !important;
}
body.theme-onyx .table-bo tbody td {
border-bottom-color: rgba(255, 255, 255, 0.06) !important;
}
/* Explicitly force expire time to be bright red in dark mode */
body.theme-onyx .table-bo td.col-expire-time,
body.theme-onyx .table-bo td.col-expire-time * {
color: #FF3131 !important;
}
/* Brighten secondary/muted columns in dark mode (Fee, Partner Code, etc) */
body.theme-onyx .table-bo td.text-secondary,
body.theme-onyx .table-bo td.text-muted,
body.theme-onyx .table-bo td.font-diminish {
color: var(--text-secondary) !important;
opacity: 0.8;
}
/* Common Table Elements */
.table-bo .badge-status {
font-size: 0.8em !important;
font-weight: 700 !important;
padding: 4px 10px !important;
border-radius: 6px !important;
text-transform: uppercase;
}
.table-bo .amount-cell {
font-weight: 700;
font-variant-numeric: tabular-nums;
}
.table-bo .font-mono {
font-family: 'JetBrains Mono', 'Roboto Mono', monospace;
letter-spacing: -0.02em;
}
.table-card {
padding: 0 !important;
overflow: visible !important;
border: none !important;
}
body.theme-onyx .table-bo td.font-diminish,
body.theme-onyx .table-bo .text-secondary,
body.theme-onyx .table-bo .text-muted,
body.theme-onyx .table-bo .font-diminish {
color: #FFFFFF !important;
}
input::-webkit-calendar-picker-indicator {
filter: var(--calendar-filter, none);
opacity: 0.5;
cursor: pointer;
transition: var(--transition);
}
input::-webkit-calendar-picker-indicator:hover {
opacity: 1;
}
/* Badges */
.badge-status {
display: inline-flex;
align-items: center;
gap: 6px;
/* width:fit-content forces content sizing even when the parent is a flex
column with default align-items:stretch (e.g. .md-field, .md-summary-item).
Without it the colored background stretches across the row → "dài" bug. */
width: fit-content;
font-size: 11px;
font-weight: 700;
padding: 3px 8px;
border-radius: 6px;
text-transform: uppercase;
letter-spacing: 0.05em;
white-space: nowrap;
border: 1px solid transparent;
}
.badge-status.success {
background: rgba(16, 185, 129, 0.1);
color: #10B981;
border-color: rgba(16, 185, 129, 0.2);
}
.badge-status.danger {
background: rgba(239, 68, 68, 0.1);
color: #EF4444;
border-color: rgba(239, 68, 68, 0.2);
}
.badge-status.warning {
background: rgba(245, 158, 11, 0.1);
color: #F59E0B;
border-color: rgba(245, 158, 11, 0.2);
}
.badge-status.info {
background: rgba(59, 130, 246, 0.1);
color: #3B82F6;
border-color: rgba(59, 130, 246, 0.2);
}
/* ============================================================
BUTTONS
============================================================ */
.btn-primary-bo {
display: inline-flex;
align-items: center;
gap: 6px;
background: linear-gradient(135deg, var(--primary), var(--primary-light));
color: #fff;
font-weight: 600;
font-size: 13px;
padding: 7px 12px;
border-radius: var(--radius);
cursor: pointer;
transition: var(--transition);
box-shadow: 0 2px 12px var(--primary-glow);
}
.btn-primary-bo:hover {
box-shadow: 0 4px 20px var(--primary-glow);
transform: translateY(-1px);
}
.btn-secondary-bo {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--bg-elevated);
border: 1px solid var(--border);
color: var(--text-secondary);
font-weight: 600;
font-size: 13px;
padding: 7px 12px;
border-radius: var(--radius);
cursor: pointer;
transition: var(--transition);
}
.btn-secondary-bo:hover {
border-color: var(--border-light);
color: var(--text-primary);
background: var(--bg-card);
}
.btn-ghost-bo {
display: inline-flex;
align-items: center;
justify-content: center;
background: transparent;
border: none;
border-radius: 6px;
cursor: pointer;
padding: 6px;
line-height: 0;
transition: background-color 0.15s ease, transform 0.1s ease;
}
.btn-ghost-bo svg {
width: 22px !important;
height: 22px !important;
}
.btn-ghost-bo:hover:not(:disabled) {
background: rgba(239, 68, 68, 0.08);
}
.btn-ghost-bo:active:not(:disabled) {
transform: scale(0.92);
}
.btn-ghost-bo:disabled {
opacity: 0.4;
cursor: not-allowed;
}
.btn-sm-bo {
padding: 3px 8px !important;
font-size: 11px !important;
gap: 4px !important;
border-radius: 4px !important;
min-height: 24px;
}
/* ============================================================
SEARCH INPUT
============================================================ */
.search-input-wrap {
position: relative;
display: inline-flex;
align-items: center;
}
.search-input-wrap svg {
position: absolute;
left: 10px;
color: var(--text-muted);
pointer-events: none;
}
.search-input {
background: var(--bg-elevated);
border: 1px solid var(--border);
color: var(--text-primary);
border-radius: var(--radius);
padding: 8px 14px 8px 36px;
font-size: 13px;
transition: var(--transition);
outline: none;
width: 240px;
}
.search-input::placeholder {
color: var(--text-muted);
}
.search-input:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px var(--primary-dim);
}
/* ============================================================
EMPTY STATE
============================================================ */
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 60px 20px;
color: var(--text-muted);
text-align: center;
gap: 12px;
}
.empty-state svg {
opacity: 0.3;
}
.empty-state h5 {
color: var(--text-secondary);
font-size: 15px;
margin: 0;
}
.empty-state p {
font-size: 13px;
margin: 0;
}
/* ============================================================
RESPONSIVE UTILITIES & MOBILE OVERLAY
============================================================ */
.sidebar-overlay {
display: none;
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
z-index: 999;
backdrop-filter: blur(2px);
}
/* Sticky Header Utility */
.table-bo thead th {
position: sticky;
top: 0;
z-index: 10;
background: var(--table-header-bg);
box-shadow: 0 1px 0 var(--border);
}
@media (max-width: 1024px) {
.header-breadcrumb {
display: none;
}
}
@media (max-width: 1024px) {
.header-breadcrumb {
display: none;
}
}
@media (max-width: 992px) {
.app-main { padding: 20px; }
.search-input { width: auto; min-width: 100%; }
}
@media (max-width: 768px) {
.sidebar { left: calc(-1 * var(--sidebar-w)); }
.sidebar.mobile-open { left: 0; }
.sidebar-overlay.active { display: block; }
.app-header {
left: 0 !important;
padding: 0 12px;
gap: 8px;
}
.header-breadcrumb {
display: none;
}
.header-search {
flex: 1;
min-width: 0;
}
.header-search input {
width: 100% !important;
padding-right: 8px;
}
.header-search input:focus {
width: 100% !important;
}
.app-header-actions {
gap: 4px;
margin-left: auto;
flex-shrink: 0;
flex-wrap: nowrap !important;
width: auto !important;
}
.header-btn {
width: 30px;
height: 30px;
}
.app-header .user-avatar {
width: 28px;
height: 28px;
font-size: 10px;
}
.header-divider {
display: none;
}
.app-main {
margin-left: 0 !important;
padding: 16px;
}
.page-header {
flex-direction: column;
align-items: stretch;
gap: 16px;
}
.header-actions {
width: 100%;
justify-content: flex-start;
}
}
/* ============================================================
UTILITY
============================================================ */
.text-primary-color {
color: var(--primary) !important;
}
.text-muted-bo {
color: var(--text-muted) !important;
}
/* Center empty table message inside card */
.table-responsive:has(td.text-muted-bo) {
display: flex !important;
flex-direction: column !important;
}
.table-responsive:has(td.text-muted-bo) .table-bo {
flex: 1 !important;
height: 100% !important;
}
.table-responsive:has(td.text-muted-bo) tbody {
height: 100% !important;
display: table-row-group !important;
}
.table-responsive:has(td.text-muted-bo) tr:has(td.text-muted-bo) {
height: 100% !important;
}
.table-responsive:has(td.text-muted-bo) tr:has(td.text-muted-bo) td.text-muted-bo {
vertical-align: middle !important;
height: 100% !important;
}
.text-success-bo {
color: var(--success) !important;
}
.text-danger-bo {
color: var(--danger) !important;
}
.font-mono {
font-family: 'Fira Code', monospace;
}
.gap-2 {
gap: 8px;
}
.gap-3 {
gap: 12px;
}
/* Loading spinner */
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.spinner {
width: 20px;
height: 20px;
border: 2px solid var(--border);
border-top-color: var(--primary);
border-radius: 50%;
animation: spin 0.7s linear infinite;
display: block;
margin: 0 auto;
}
.spinner-xl {
width: 48px;
height: 48px;
border-width: 4px;
}
.p2p-loading-screen {
position: fixed;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-base);
z-index: 9999;
}
.spinner-screen-center {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 9999;
}
/* ============================================================
MUDBLAZOR OVERRIDES — neutralize MudBlazor global resets
so they don't conflict with bo-style.css
============================================================ */
body {
font-family: 'Inter', sans-serif !important;
background: var(--bg-base) !important;
color: var(--text-primary) !important;
}
/* PartnerTreeSelect — style MudSelect to match bo design */
.mud-input-control {
font-family: 'Inter', sans-serif;
}
.mud-select-input,
.mud-input {
font-family: 'Inter', sans-serif;
font-size: clamp(9px, 0.6vw + 5px, 13.5px);
}
/* Prevent MudBlazor from adding margins/padding to the app shell */
.mud-popover-provider { position: fixed; z-index: 9999; }
/* Ensure sidebar and header are not affected by MudBlazor resets */
.sidebar, .app-header, .app-main { font-family: 'Inter', sans-serif; }
/* ── Account Dropdown & Theme Menu ── */
.dropdown-menu {
background: rgba(var(--bg-surface-rgb), 0.95) !important;
backdrop-filter: blur(16px);
-webkit-backdrop-filter: blur(16px);
border: 1px solid var(--border) !important;
border-radius: 14px !important;
padding: 8px !important;
box-shadow: 0 15px 50px rgba(0,0,0,0.22) !important;
transition: all 0.2s cubic-bezier(0.16, 1, 0.3, 1);
z-index: 2000 !important;
}
.dropdown-item {
color: var(--text-secondary) !important;
font-size: 13.5px !important;
padding: 10px 16px !important;
border-radius: 8px !important;
transition: all 0.15s ease;
cursor: pointer;
display: flex !important;
align-items: center;
}
.dropdown-item:hover {
background: var(--primary-dim) !important;
color: var(--primary) !important;
}
.dropdown-item.active {
background: var(--primary) !important;
color: #fff !important;
}
.theme-menu-trigger {
cursor: pointer;
}
.dropdown-submenu-container {
position: relative;
}
.theme-sub-menu {
position: absolute;
left: -205px;
top: 0;
margin-top: 0 !important;
display: none;
min-width: 200px;
}
.dropdown-submenu-container:hover .theme-sub-menu {
display: block;
animation: slideInLeft 0.25s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.theme-sub-header {
border-color: var(--border) !important;
background: var(--bg-elevated);
font-size: 10px;
font-weight: 800;
color: var(--text-secondary);
letter-spacing: 0.05em;
opacity: 0.6;
}
@keyframes slideInLeft {
from { opacity: 0; transform: translateX(12px); }
to { opacity: 1; transform: translateX(0); }
}
/* Fix mobile dropdown position */
@media (max-width: 768px) {
.theme-sub-menu {
left: 0;
top: 100%;
margin-top: 5px !important;
position: relative !important;
animation: none;
}
}
/* ============================================================
SYSTEM-WIDE PREMIUM BACKOFFICE OVERRIDES
============================================================ */
/* ── 1. Global Page Layout & Typography ── */
body {
background-color: var(--bg-base) !important;
}
.page-header {
margin-bottom: 24px;
}
.page-title {
font-family: 'Outfit', 'Inter', sans-serif !important;
font-size: 24px !important;
font-weight: 800 !important;
letter-spacing: -0.02em !important;
color: var(--text-primary) !important;
}
.page-subtitle {
font-size: 13.5px !important;
color: var(--text-secondary) !important;
opacity: 0.8;
}
/* ── 2. Premium KPI Dashboard Cards (Glassmorphism & Soft Glow) ── */
.kpi-card {
background: linear-gradient(135deg, var(--bg-surface) 0%, var(--bg-elevated) 100%) !important;
border: 1px solid var(--border) !important;
border-radius: 16px !important;
padding: 20px 24px !important;
box-shadow: 0 4px 20px -2px rgba(0, 0, 0, 0.02), 0 2px 6px -1px rgba(0, 0, 0, 0.01) !important;
transition: transform 0.28s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.28s ease, border-color 0.28s ease !important;
position: relative;
overflow: hidden;
display: flex;
flex-direction: column;
gap: 8px;
}
.kpi-card:hover {
transform: translateY(-5px) scale(1.01) !important;
border-color: rgba(0, 153, 153, 0.25) !important;
box-shadow: 0 15px 35px -8px rgba(0, 153, 153, 0.08), 0 4px 12px -2px rgba(0, 0, 0, 0.03) !important;
}
/* Decorative grid watermark in KPI cards */
.kpi-card::after {
content: "";
position: absolute;
right: -10px;
bottom: -10px;
width: 80px;
height: 80px;
background-image: radial-gradient(var(--primary-dim) 1.5px, transparent 1.5px);
background-size: 8px 8px;
opacity: 0.25;
pointer-events: none;
}
.kpi-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2px;
}
.kpi-icon-wrap {
width: 40px;
height: 40px;
border-radius: 10px;
display: flex;
align-items: center;
justify-content: center;
transition: transform 0.2s ease;
}
.kpi-card:hover .kpi-icon-wrap {
transform: scale(1.1) rotate(3deg);
}
.kpi-value {
font-family: 'Outfit', 'Inter', sans-serif !important;
font-size: 26px !important;
font-weight: 800 !important;
color: var(--text-primary) !important;
letter-spacing: -0.02em !important;
line-height: 1.2;
}
.kpi-label {
font-size: 12px !important;
font-weight: 600 !important;
color: var(--text-secondary) !important;
text-transform: uppercase;
letter-spacing: 0.05em;
}
.kpi-sub {
font-size: 11px !important;
color: var(--text-muted) !important;
display: flex;
align-items: center;
gap: 5px;
margin-top: 4px;
}
.kpi-dot {
width: 6px;
height: 6px;
border-radius: 50%;
display: inline-block;
}
.kpi-dot.ok { background-color: var(--success); }
.kpi-dot.warn { background-color: var(--warning); }
.kpi-dot.err { background-color: var(--danger); }
/* ── 3. High-Fidelity Table Overrides (Clean, Compact & Structured) ── */
.card-bo.table-card {
border-radius: 16px !important;
box-shadow: 0 10px 30px -10px rgba(0, 0, 0, 0.08) !important;
border: 1.5px solid var(--border) !important;
overflow: hidden;
padding: 0 !important; /* Full width edge-to-edge table headers */
background: var(--bg-surface) !important;
}
.table-responsive {
border-radius: 16px 16px 0 0;
overflow-x: auto;
}
/* Custom premium scrollbar for table container */
.table-responsive::-webkit-scrollbar {
height: 6px;
width: 6px;
}
.table-responsive::-webkit-scrollbar-track {
background: transparent;
}
.table-responsive::-webkit-scrollbar-thumb {
background: rgba(var(--primary-rgb), 0.15);
border-radius: 10px;
}
.table-responsive::-webkit-scrollbar-thumb:hover {
background: rgba(var(--primary-rgb), 0.3);
}
.table-bo {
width: 100%;
border-collapse: separate !important;
border-spacing: 0 !important;
font-size: 12px !important;
color: var(--text-primary);
border: none !important;
}
/* Beautiful sticky header row styling */
.table-bo thead th {
background-color: var(--bg-elevated) !important;
color: var(--text-primary) !important; /* Highly readable primary text color */
font-weight: 800 !important; /* Stronger contrast header */
font-size: 10.5px !important;
text-transform: uppercase !important;
letter-spacing: 0.08em !important;
padding: 12px 14px !important; /* Premium comfortable padding */
border-bottom: 2px solid var(--border) !important; /* Clear horizontal separator */
text-align: center;
vertical-align: middle;
white-space: normal !important; /* Allow header labels to wrap naturally */
word-break: normal !important;
overflow-wrap: break-word !important;
box-shadow: inset 0 -1px 0 var(--border);
}
.table-bo thead th:first-child {
padding-left: 20px !important;
}
.table-bo thead th:last-child {
padding-right: 20px !important;
}
/* High fidelity row overrides */
.table-bo tbody tr {
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
background-color: var(--bg-surface);
}
.table-bo tbody td {
padding: 10px 14px !important; /* Balanced SaaS spacing */
border-bottom: 1px solid var(--border) !important;
vertical-align: middle;
color: var(--text-primary);
word-break: break-word !important; /* Wrap long descriptions to avoid horizontal scrolling */
}
.table-bo tbody td:first-child {
padding-left: 20px !important;
}
.table-bo tbody td:last-child {
padding-right: 20px !important;
}
/* Zebra row shading using soft dim primary */
.table-bo tbody tr:nth-child(even) {
background-color: rgba(var(--primary-rgb), 0.015) !important;
}
/* Modern clean left accents for complete / failed rows */
.table-bo tbody tr.row-completed {
border-left: 4px solid var(--success) !important;
}
.table-bo tbody tr.row-failed {
border-left: 4px solid var(--danger) !important;
}
.table-bo tbody tr:hover td {
background-color: rgba(var(--primary-rgb), 0.04) !important;
}
.table-bo tbody tr:hover td:first-child {
box-shadow: inset 3px 0 0 var(--primary) !important; /* Modern focus indicators on hover */
}
/* Monospace fonts for raw codes/hashes */
.table-bo .font-mono {
font-family: 'Fira Code', 'Roboto Mono', monospace !important;
font-size: 11px !important;
color: var(--text-secondary);
font-weight: 600;
}
/* Monospace styled as subtle premium chips (only for inline elements inside td) */
.table-bo span.font-mono,
.table-bo code.font-mono,
.table-bo a.font-mono,
.table-bo div.font-mono {
background: rgba(var(--primary-rgb), 0.04) !important;
padding: 3px 6px !important;
border-radius: 6px !important;
border: 1px solid rgba(var(--primary-rgb), 0.08) !important;
display: inline-block;
white-space: nowrap !important;
}
/* ── 3.1. Premium Actions Trigger Button (Micro-animations on hover) ── */
.btn-dots {
background: transparent !important;
border: none !important;
width: 28px !important;
height: 28px !important;
border-radius: 50% !important;
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
color: var(--text-secondary) !important;
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1) !important;
cursor: pointer !important;
padding: 0 !important;
}
.btn-dots:hover {
background: rgba(var(--primary-rgb), 0.1) !important;
color: var(--primary) !important;
transform: rotate(90deg) !important; /* Premium rotate feedback */
}
.btn-dots:active {
transform: scale(0.9) rotate(90deg) !important;
}
/* ── 3.2. Split Tables Layout Overrides (For multi-pane views like MatchMonitor) ── */
.table-split thead tr:first-child th.split-th {
font-size: 10px !important;
font-weight: 900 !important;
text-align: center !important;
padding: 8px 10px !important;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
}
.table-split thead tr:first-child th.split-th-deposit {
background: rgba(16, 185, 129, 0.08) !important; /* Soft dim success green */
color: #10B981 !important;
border-right: 1.5px solid var(--border) !important;
}
.table-split thead tr:first-child th.split-th-payout {
background: rgba(var(--primary-rgb), 0.08) !important; /* Soft dim primary color */
color: var(--primary) !important;
border-right: 1.5px solid var(--border) !important;
}
.table-split thead tr:first-child th.split-th-log {
background: rgba(245, 158, 11, 0.08) !important; /* Soft dim warning amber */
color: #F59E0B !important;
}
/* ── 3.3. Table Vertical Group Separators (Dashed grid lines) ── */
.table-bo th.col-divider,
.table-bo td.col-divider {
border-right: 1.5px dashed var(--border) !important;
}
/* ── 3.4. Elegant Empty State (No records found styling) ── */
.table-bo tr td.text-muted-bo {
font-size: 13px !important;
color: var(--text-secondary) !important;
letter-spacing: 0.02em;
background: linear-gradient(to bottom, transparent, rgba(var(--primary-rgb), 0.005)) !important;
}
/* ── 4. Unified Pastels Badges & Status Indicators ── */
.badge-status,
.badge-type,
.badge-currency,
.lb-badge {
display: inline-flex !important;
align-items: center !important;
justify-content: center !important;
gap: 6px !important;
padding: 4px 10px !important;
border-radius: 20px !important;
font-size: 10px !important;
font-weight: 800 !important;
text-transform: uppercase !important;
letter-spacing: 0.05em !important;
white-space: nowrap !important;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
}
/* Pulsing bullet dot for interactive badges */
.badge-status::before {
content: "";
display: inline-block;
width: 5px;
height: 5px;
border-radius: 50%;
background-color: currentColor;
flex-shrink: 0;
}
/* Success pastels */
.badge-status.success,
.badge-status.completed,
.badge-status.matched,
.lb-badge-deposit {
background: rgba(16, 185, 129, 0.08) !important;
color: #10B981 !important;
border: 1px solid rgba(16, 185, 129, 0.16) !important;
}
/* Danger pastels */
.badge-status.danger,
.badge-status.failed,
.badge-status.rejected,
.badge-status.expired {
background: rgba(239, 68, 68, 0.08) !important;
color: #EF4444 !important;
border: 1px solid rgba(239, 68, 68, 0.16) !important;
}
/* Warning pastels */
.badge-status.warning,
.badge-status.pending,
.badge-status.processing {
background: rgba(245, 158, 11, 0.08) !important;
color: #D97706 !important;
border: 1px solid rgba(245, 158, 11, 0.16) !important;
}
/* Info pastels */
.badge-status.info,
.badge-status.active,
.lb-badge-payout {
background: rgba(59, 130, 246, 0.08) !important;
color: #3B82F6 !important;
border: 1px solid rgba(59, 130, 246, 0.16) !important;
}
/* Currency and general pill types */
.badge-currency,
.badge-type {
background: rgba(148, 163, 184, 0.08) !important;
color: var(--text-secondary) !important;
border: 1px solid rgba(148, 163, 184, 0.15) !important;
border-radius: 6px !important;
padding: 2px 6px !important;
}
/* ── 5. Advanced Filter Panels (Modern Cards) ── */
.card-bo:has(.filter-grid) {
background: var(--bg-surface) !important;
border: 1px solid var(--border) !important;
border-radius: 16px !important;
padding: 20px !important;
box-shadow: 0 4px 20px -3px rgba(0, 0, 0, 0.02) !important;
}
.filter-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)) !important;
gap: 16px !important;
align-items: flex-end;
}
.filter-field label {
font-size: 11px !important;
font-weight: 700 !important;
color: var(--text-secondary) !important;
text-transform: uppercase;
letter-spacing: 0.04em;
margin-bottom: 6px;
display: block;
}
.filter-field input,
.filter-field select {
background-color: var(--bg-elevated) !important;
border: 1px solid var(--border) !important;
color: var(--text-primary) !important;
border-radius: 8px !important;
padding: 8px 12px !important;
font-size: 13px !important;
transition: all 0.15s ease;
width: 100%;
}
.filter-field input:focus,
.filter-field select:focus {
border-color: var(--primary) !important;
box-shadow: 0 0 0 3px var(--primary-dim) !important;
outline: none;
}
/* Currency Switcher Tabs */
.currency-tabs {
background: var(--border) !important;
padding: 3px !important;
border-radius: 8px !important;
display: inline-flex;
gap: 2px;
}
.cur-tab {
background: transparent !important;
border: none !important;
color: var(--text-secondary) !important;
font-size: 12px !important;
font-weight: 700 !important;
padding: 6px 14px !important;
border-radius: 6px !important;
cursor: pointer;
transition: all 0.15s ease;
}
.cur-tab.active {
background: var(--bg-surface) !important;
color: var(--primary) !important;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06) !important;
}
/* ── 6. Interactive Quick Actions Ring & Floating Widgets ── */
.floating-quick-actions {
background: rgba(255, 255, 255, 0.85) !important;
backdrop-filter: blur(16px) !important;
-webkit-backdrop-filter: blur(16px) !important;
border: 1px solid rgba(255, 255, 255, 0.3) !important;
box-shadow: 0 10px 30px -5px rgba(0, 0, 0, 0.15), 0 0 0 1px rgba(0, 153, 153, 0.05) !important;
border-radius: 30px !important;
padding: 8px !important;
display: flex;
align-items: center;
gap: 6px;
position: fixed;
bottom: 24px;
right: 24px;
z-index: 1000;
transition: all 0.25s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.floating-quick-actions:hover {
transform: translateY(-2px) scale(1.02);
box-shadow: 0 15px 35px -5px rgba(0, 0, 0, 0.22), 0 0 0 1px rgba(0, 153, 153, 0.1) !important;
}
.fqa-btn {
width: 40px !important;
height: 40px !important;
border-radius: 50% !important;
display: flex !important;
align-items: center !important;
justify-content: center !important;
background: var(--bg-surface) !important;
border: 1px solid var(--border) !important;
color: var(--text-secondary) !important;
cursor: pointer;
transition: all 0.2s ease !important;
}
.fqa-btn:hover {
background: var(--primary-dim) !important;
color: var(--primary) !important;
border-color: var(--primary) !important;
transform: scale(1.1);
}
/* ── 7. Merchant Rank Interactive list (Top Merchants) ── */
.merchant-rank-item {
display: flex;
align-items: center;
gap: 16px;
padding: 12px 20px;
border-bottom: 1px solid var(--border);
transition: background-color 0.15s ease;
}
.merchant-rank-item:hover {
background-color: rgba(var(--primary-rgb), 0.015);
}
.rank-badge {
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 800;
background: var(--bg-elevated);
color: var(--text-secondary);
}
.rank-badge.rank-1 { background: rgba(245, 158, 11, 0.12); color: #d97706; }
.rank-badge.rank-2 { background: rgba(148, 163, 184, 0.15); color: #475569; }
.rank-badge.rank-3 { background: rgba(180, 83, 9, 0.12); color: #b45309; }
.rank-avatar {
width: 32px;
height: 32px;
border-radius: 8px;
background: var(--primary-dim);
color: var(--primary);
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 700;
letter-spacing: 0.02em;
}
.rank-info {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
}
.rank-name {
font-size: 13.5px;
font-weight: 700;
color: var(--text-primary);
}
.rank-bar-wrap {
width: 150px;
margin-right: 20px;
}
.rank-bar {
height: 6px;
background: var(--border);
border-radius: 3px;
overflow: hidden;
}
.rank-bar-fill {
height: 100%;
background: linear-gradient(90deg, var(--primary) 0%, #a78bfa 100%);
border-radius: 3px;
transition: width 0.6s cubic-bezier(0.4, 0, 0.2, 1);
}
.rank-stats {
text-align: right;
}
.rank-count {
font-size: 14px;
font-weight: 700;
color: var(--text-primary);
}
/* ── 8. High-Fidelity Sidebar & Navigation Frame Overrides ── */
.sidebar {
background: var(--bg-sidebar) !important;
border-right: 1px solid var(--border) !important;
box-shadow: 6px 0 35px -10px rgba(15, 23, 42, 0.04) !important;
}
.sidebar-brand {
border-bottom: 1.5px solid var(--border) !important;
}
.sidebar-brand .brand-icon {
background: linear-gradient(135deg, var(--primary), var(--primary-light)) !important;
box-shadow: 0 4px 12px var(--primary-glow) !important;
}
.sidebar-brand .brand-text {
font-family: 'Outfit', 'Inter', sans-serif !important;
font-size: 15px !important;
font-weight: 800 !important;
}
.sidebar-nav {
padding: 16px 12px !important;
}
/* Slick and modern sidebar links */
.nav-link-item {
margin: 3px 0 !important;
padding: 10px 14px !important;
border-radius: 10px !important;
font-size: 13.5px !important;
font-weight: 600 !important;
transition: all 0.22s cubic-bezier(0.4, 0, 0.2, 1) !important;
color: var(--text-secondary) !important;
}
.nav-link-item:hover {
background: var(--primary-dim) !important;
color: var(--primary) !important;
transform: translateX(2px);
}
.nav-link-item.active {
background: linear-gradient(135deg, var(--primary) 0%, var(--primary-light) 100%) !important;
color: #FFFFFF !important;
box-shadow: 0 4px 15px -2px var(--primary-glow) !important;
}
.nav-link-item.active .nav-icon {
color: #FFFFFF !important;
opacity: 1 !important;
}
/* Hide old left indicator line */
.nav-link-item.active::before {
display: none !important;
}
.nav-submenu {
margin-left: 10px !important;
padding-left: 12px !important;
border-left: 1.5px dashed var(--border) !important;
margin-top: 6px !important;
margin-bottom: 6px !important;
}
.nav-sub-item {
padding: 8px 12px !important;
border-radius: 8px !important;
font-size: 13px !important;
font-weight: 500 !important;
color: var(--text-secondary) !important;
transition: all 0.18s ease !important;
}
.nav-sub-item:hover {
background: var(--primary-dim) !important;
color: var(--primary) !important;
transform: translateX(2px);
}
.nav-sub-item.active {
background: var(--primary-dim) !important;
color: var(--primary) !important;
font-weight: 600 !important;
}
.sidebar-footer {
border-top: 1.5px solid var(--border) !important;
padding: 14px 16px !important;
}
.user-info {
background: var(--bg-elevated) !important;
border: 1px solid var(--border) !important;
border-radius: 12px !important;
padding: 8px 12px !important;
transition: all 0.2s ease !important;
}
.user-info:hover {
border-color: rgba(0, 153, 153, 0.25) !important;
background: var(--bg-surface) !important;
}
.user-avatar {
background: linear-gradient(135deg, var(--primary), var(--primary-light)) !important;
box-shadow: 0 3px 8px var(--primary-glow) !important;
}
/* ── 9. Translucent Glassmorphic App Header ── */
.app-header {
background: rgba(var(--bg-surface-rgb), 0.85) !important;
backdrop-filter: blur(20px) !important;
-webkit-backdrop-filter: blur(20px) !important;
border-bottom: 1.5px solid var(--border) !important;
box-shadow: 0 4px 30px rgba(15, 23, 42, 0.02) !important;
}
.header-toggle {
background: var(--bg-elevated) !important;
border: 1px solid var(--border) !important;
border-radius: 8px !important;
width: 36px !important;
height: 36px !important;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.18s ease !important;
}
.header-toggle:hover {
background: var(--primary-dim) !important;
color: var(--primary) !important;
border-color: var(--primary) !important;
}
.header-search {
background-color: var(--bg-elevated) !important;
border: 1px solid var(--border) !important;
border-radius: 10px !important;
padding: 6px 14px !important;
transition: all 0.2s ease !important;
}
.header-search:focus-within {
background-color: var(--bg-surface) !important;
border-color: var(--primary) !important;
box-shadow: 0 0 0 3px var(--primary-dim) !important;
}
.header-btn {
background: var(--bg-elevated) !important;
border: 1px solid var(--border) !important;
border-radius: 8px !important;
width: 36px !important;
height: 36px !important;
transition: all 0.18s ease !important;
}
.header-btn:hover {
background: var(--primary-dim) !important;
color: var(--primary) !important;
border-color: var(--primary) !important;
transform: translateY(-1px);
}
/* ── 10. Sleek Dialog Modal Overrides ── */
.modal-content,
.p2p-modal {
background: var(--bg-surface) !important;
border: 1px solid var(--border) !important;
border-radius: 20px !important;
box-shadow: 0 25px 60px -15px rgba(0, 0, 0, 0.18) !important;
overflow: hidden;
}
.modal-header,
.p2p-modal-header {
border-bottom: 1.5px solid var(--border) !important;
background: var(--bg-elevated) !important;
padding: 18px 24px !important;
}
.modal-footer,
.p2p-modal-footer {
border-top: 1.5px solid var(--border) !important;
background: var(--bg-elevated) !important;
padding: 16px 24px !important;
}
/* ── 11. Premium Pagination Buttons ── */
.p2p-pagination {
margin-top: 18px !important;
padding: 16px 20px !important;
background: var(--bg-elevated) !important;
border-top: 1.5px solid var(--border) !important;
display: flex !important;
align-items: center !important;
justify-content: space-between !important;
flex-wrap: wrap !important;
gap: 12px;
}
.p2p-pagination-btn {
background: var(--bg-surface) !important;
border: 1px solid var(--border) !important;
color: var(--text-secondary) !important;
border-radius: 8px !important;
padding: 8px 16px !important;
font-size: 13px !important;
font-weight: 700 !important;
cursor: pointer;
transition: all 0.18s ease !important;
}
.p2p-pagination-btn:hover:not(:disabled) {
background: var(--primary-dim) !important;
color: var(--primary) !important;
border-color: var(--primary) !important;
}
.p2p-pagination-btn:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.p2p-pagination-info {
font-size: 13px !important;
font-weight: 600 !important;
color: var(--text-secondary) !important;
}
/* ── Stats Dashboard Row ─────────────────────────── */
.stats-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
margin-bottom: 14px;
}
.stat-card {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 8px;
padding: 8px 12px;
display: flex;
align-items: center;
gap: 10px;
box-shadow: 0 4px 20px -2px rgba(0,0,0,0.02);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 24px -4px rgba(0,0,0,0.06);
}
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 30px;
height: 30px;
border-radius: 6px;
flex-shrink: 0;
}
.stat-icon svg {
width: 14px;
height: 14px;
}
.stat-icon.purple { background: rgba(139, 92, 246, 0.08); color: #8b5cf6; }
.stat-icon.red { background: rgba(239, 68, 68, 0.08); color: #ef4444; }
.stat-icon.green { background: rgba(16, 185, 129, 0.08); color: #10b981; }
.stat-icon.blue { background: rgba(59, 130, 246, 0.08); color: #3b82f6; }
.stat-info {
display: flex;
flex-direction: column;
gap: 0;
}
.stat-label {
font-size: 9.5px;
color: var(--text-secondary);
font-weight: 500;
}
.stat-value {
font-size: 14px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
/* ── Search Bar controls ────────────────────────── */
.table-controls-row {
display: flex;
align-items: center;
gap: 12px;
padding: 16px;
border-bottom: 1px solid var(--border);
background: var(--bg-surface);
}
.search-input-wrapper {
position: relative;
width: 100%;
max-width: 320px;
}
.search-input-wrapper .search-icon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--text-secondary);
opacity: 0.6;
pointer-events: none;
}
.search-input-field {
width: 100%;
background: var(--bg-surface);
border: 1px solid var(--border);
color: var(--text-primary);
border-radius: 8px;
padding-left: 40px !important;
font-size: 13px;
transition: all 0.15s ease;
}
.search-input-field:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.12);
outline: none;
}
.btn-clear-search {
position: absolute;
right: 10px;
top: 50%;
transform: translateY(-50%);
background: transparent;
border: none;
color: var(--text-secondary);
opacity: 0.5;
cursor: pointer;
padding: 2px;
display: flex;
align-items: center;
justify-content: center;
}
.btn-clear-search:hover {
opacity: 0.8;
}
/* ── Highlights & text styling ──────────────────── */
.search-highlight {
background: rgba(245, 158, 11, 0.18);
color: #d97706;
border-bottom: 1.5px solid #f59e0b;
padding: 0 1px;
border-radius: 2px;
font-weight: 700;
}
.mo-btn-visibility {
padding: 0 12px;
border: 1px solid var(--border-color);
background: var(--surface);
border-radius: 6px;
cursor: pointer;
white-space: nowrap;
}
.mo-btn-visibility:hover {
background: var(--surface-hover);
}
/* ============================================================
P2P COMMON PAGE STYLES
Shared across: Deposits, Payouts, Match History (and similar pages)
============================================================ */
/* ── Currency selector tabs ─────────────────────────────── */
.currency-tabs {
background: var(--border);
padding: 3px;
border-radius: 8px;
display: inline-flex;
gap: 2px;
align-items: center;
}
.cur-tab {
background: transparent;
border: none;
color: var(--text-secondary);
font-size: 12px;
font-weight: 700;
padding: 6px 14px;
border-radius: 6px;
cursor: pointer;
outline: none;
transition: all 0.15s ease;
line-height: 1.2;
}
.cur-tab:hover {
color: var(--primary);
}
.cur-tab.active {
background: var(--bg-surface);
color: var(--primary);
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.06);
}
.filter-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 16px;
align-items: flex-end;
}
.filter-field {
display: flex;
flex-direction: column;
gap: 4px;
}
.filter-label {
font-size: 11px;
font-weight: 700;
color: var(--text-primary);
text-transform: uppercase;
letter-spacing: 0.02em;
}
.filter-input {
border: 1.5px solid var(--border);
border-radius: 7px;
padding: 0 10px;
height: 30px;
font-size: 12px;
color: var(--text-primary);
background: var(--bg-surface);
font-family: inherit;
outline: none;
transition: border-color 0.15s;
width: 100%;
box-sizing: border-box;
}
.filter-input::placeholder {
color: #94A3B8;
opacity: 1;
}
.filter-input:focus {
border-color: var(--primary);
}
.filter-actions {
display: flex !important;
flex-direction: row !important;
flex-wrap: nowrap !important;
gap: 8px !important;
align-items: flex-end !important;
width: max-content !important;
}
/* User Action Logs table: allow content to wrap instead of truncating. */
.table-bo.table-logs {
table-layout: auto !important;
}
.table-bo.table-logs thead th{
white-space: nowrap;
overflow: visible;
text-overflow: clip;
font-size: claimp(10px, 0.8vw, 12px);
}
.table-bo.table-logs thead th:nth-last-child(1),
.table-bo.table-logs thead th:nth-last-child(2),
.table-bo.table-logs tbody td:nth-last-child(1),
.table-bo.table-logs tbody td:nth-last-child(2) {
text-align: right;
white-space: nowrap;
}
/* ── Currency badge ──────────────────────────────────────── */
.badge-currency {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 4px 10px;
border-radius: 20px;
font-size: 10px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.05em;
white-space: nowrap;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
background: #EDE9FE;
color: #4C1D95;
width: fit-content;
}
/* ── 3-dot action button ─────────────────────────────────── */
.btn-dots {
background: transparent;
border: none;
width: 28px;
height: 28px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--text-secondary);
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
cursor: pointer;
padding: 0;
}
.btn-dots:hover {
background: rgba(var(--primary-rgb), 0.1);
color: var(--primary);
transform: rotate(90deg); /* Premium rotate feedback */
}
.btn-dots:active {
transform: scale(0.9) rotate(90deg);
}
/* ── Action dropdown menu ────────────────────────────────── */
.action-menu {
position: fixed;
/* Click coords passed via --menu-x/--menu-y inline vars on element; clamp into viewport (bug #39). */
top: clamp(8px, var(--menu-y, 8px), calc(100vh - 220px));
left: clamp(8px, var(--menu-x, 8px), calc(100vw - 200px));
min-width: 190px;
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: 0 12px 32px rgba(15, 23, 42, 0.12);
z-index: 2050;
overflow-x: hidden;
overflow-y: auto;
padding: 6px;
max-height: calc(100vh - 48px);
max-width: calc(100vw - 32px);
animation: menuFadeIn 0.15s ease both;
}
@media (max-width: 768px) {
.action-menu {
left: 12px !important;
right: 12px !important;
bottom: 12px !important;
top: auto !important;
min-width: 0 !important;
width: auto !important;
transform: none !important;
border-radius: 16px;
box-shadow: 0 -10px 40px rgba(0,0,0,0.15);
animation: menuSlideUp 0.3s cubic-bezier(0.16, 1, 0.3, 1) both;
}
.action-menu-item {
padding: 14px 16px;
font-size: 15px;
}
}
@keyframes menuSlideUp {
from { transform: translateY(20px); opacity: 0; }
to { transform: translateY(0); opacity: 1; }
}
@keyframes menuFadeIn {
from {
opacity: 0;
transform: translateY(-8px) scale(0.97);
}
to {
opacity: 1;
transform: none;
}
}
.action-menu-item {
display: flex;
align-items: center;
justify-content: flex-start;
gap: 12px;
width: 100%;
padding: 10px 12px;
border: none;
border-radius: 8px;
background: transparent;
font-size: 13.5px;
font-weight: 600;
color: var(--text-primary);
font-family: inherit;
cursor: pointer;
text-align: left;
transition: all 0.15s ease;
}
.action-menu-item:last-child {
border-bottom: none;
}
.action-menu-item:hover {
background: #F8FAFC;
color: #0F172A;
}
/* Icon cố định kích thước, không bị co lại */
.action-menu-item svg {
flex-shrink: 0;
width: 14px;
height: 14px;
}
/* ── Click-outside overlay ───────────────────────────────── */
/* touch-action:none + overscroll-behavior:contain block touch scrolling +
prevent overscroll bubbling to body (bug #34 — popup di chuyển khi scroll). */
.action-overlay {
position: fixed;
inset: 0;
z-index: 499;
touch-action: none;
overscroll-behavior: contain;
}
/* Bug #34: Blazor's @onwheel:preventDefault doesn't work because Blazor uses
a delegated passive wheel listener at root. CSS :has() blocks body scroll
at browser level whenever the action overlay is rendered. */
body:has(.action-overlay) {
overflow: hidden;
}
/* ── Typography & Base Table ────────────────────────────────── */
.font-mono {
font-family: 'Fira Code', 'JetBrains Mono', monospace !important;
letter-spacing: -0.02em !important;
}
/* Table styles moved to bo-style.css for global consistency */
.text-end { text-align: right !important; }
.text-start { text-align: left !important; }
.text-center { text-align: center !important; }
/* ─────────────────────────────────────────────────────────────────────────────
7. UTILITIES
───────────────────────────────────────────────────────────────────────────── */
.type-tag {
font-size: 10px;
font-weight: 800;
padding: 1px 6px;
border-radius: 4px;
text-transform: uppercase;
border: 1px solid transparent;
}
.type-tag.payout {
background: rgba(124,58,237,0.08);
color: #7c3aed;
border-color: rgba(124,58,237,0.15);
}
.type-tag.deposit {
background: rgba(16,185,129,0.08);
color: #10b981;
border-color: rgba(16,185,129,0.15);
}
/* ── Callback Logs: URL cell ─────────────────────────────── */
.url-text {
font-family: var(--font-mono);
font-size: 11px;
color: var(--text-secondary);
max-width: 280px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* ── Callback Logs: expand/collapse row ─────────────────── */
.expansion-toggle {
color: var(--text-muted);
transition: transform 0.2s;
}
.expansion-toggle.open {
transform: rotate(180deg);
color: var(--primary);
}
.log-expansion-row td {
background: #0f172a;
border-left: 4px solid var(--primary);
}
/* Override inherited .table-bo tbody td defaults (center + nowrap + clip) so the
embedded terminal-style detail panel renders left-aligned with natural wrapping.
Selector specificity bumped (.table-bo tbody.log-expansion-row td) so it wins
against the global `.table-bo tbody td` rule without touching that rule itself. */
.table-bo tbody .log-expansion-row td {
text-align: left;
white-space: normal;
overflow: visible;
text-overflow: clip;
}
.log-paddings {
padding: 20px 24px !important;
}
/* ── Callback Logs: terminal detail panel ───────────────── */
.split-th-log {
border-radius: 0 4px 0 0;
}
.terminal-wrap {
background: #1e293b;
border-radius: 12px;
border: 1px solid #334155;
box-shadow: 0 20px 25px -5px rgba(0,0,0,0.25);
overflow: hidden;
}
.terminal-header {
background: #334155;
padding: 8px 16px;
display: flex;
align-items: center;
gap: 6px;
}
.terminal-dot {
width: 10px;
height: 10px;
border-radius: 50%;
opacity: 0.8;
}
.terminal-dot.red {
background: #ef4444;
}
.terminal-dot.yellow {
background: #f59e0b;
}
.terminal-dot.green {
background: #10b981;
}
.terminal-title {
margin-left: 10px;
font-size: 10px;
font-weight: 800;
color: #94a3b8;
letter-spacing: 0.1em;
}
.terminal-body {
padding: 20px;
font-family: 'JetBrains Mono', 'Fira Code', monospace;
font-size: 11px;
line-height: 1.6;
display: flex;
flex-direction: column;
gap: 16px;
max-height: 70vh;
overflow-y: auto;
}
.section-title {
font-size: 10px;
font-weight: 800;
color: #64748b;
margin-bottom: 8px;
letter-spacing: 0.05em;
}
.section-content {
margin: 0;
padding: 12px;
border-radius: 8px;
background: rgba(15,23,42,0.5);
overflow-x: auto;
overflow-y: auto;
white-space: pre-wrap;
word-break: break-all;
max-height: 400px;
min-height: 40px;
}
.section-content.req {
color: #4ade80;
border: 1px solid rgba(74,222,128,0.1);
}
.section-content.res {
color: #f87171;
border: 1px solid rgba(248,113,113,0.1);
}
.table-split thead tr:first-child th {
padding: clamp(1.5px, 0.3vw, 6px) clamp(1px, 0.2vw, 5px);
font-size: clamp(8px, 0.6vw, 10px);
font-weight: 700;
letter-spacing: 0.1em;
text-transform: uppercase;
white-space: nowrap;
}
.col-divider,
.table-split tbody tr td.col-divider {
border-right: 2px solid var(--border) !important;
}
.table-split thead tr:last-child th.col-divider {
border-right: 2px solid var(--border) !important;
}
/* ── Matching type badges ─────────────────────────────────── */
.badge-type {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 4px 10px;
border-radius: 20px;
font-size: 10px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.05em;
white-space: nowrap;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.02);
}
.badge-type-real {
background: #D1FAE5;
color: #065F46;
}
.badge-type-fake {
background: #FEE2E2;
color: #991B1B;
}
.badge-type-race {
background: #FEF3C7;
color: #92400E;
}
.badge-type-botfail {
background: #FFE4E6;
color: #9F1239;
}
.badge-type-ttl {
background: #E0E7FF;
color: #3730A3;
}
/* ── MatchingDetailModal ─────────────────────────────────── */
.md-summary {
display: flex;
flex-wrap: wrap;
gap: 12px 24px;
align-items: center;
background: var(--bg-elevated);
border: 1px solid var(--border);
border-radius: 8px;
padding: 10px 16px;
margin-bottom: 16px;
}
.md-summary-item {
display: flex;
flex-direction: column;
gap: 2px;
}
.md-badge-label {
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.07em;
color: #94A3B8;
}
.md-error-bar {
background: #FEF2F2;
border: 1px solid #FECACA;
border-radius: 6px;
color: #DC2626;
font-size: 12px;
padding: 8px 12px;
margin-bottom: 14px;
}
.md-pair {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px;
}
@media (max-width: 600px) {
.md-pair {
grid-template-columns: 1fr;
}
}
.md-panel {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
}
.md-panel-header {
display: flex;
align-items: center;
gap: 7px;
padding: 9px 14px;
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
}
.md-panel-deposit {
background: #EFF6FF;
color: #1D4ED8;
border-bottom: 1px solid #DBEAFE;
}
.md-panel-payout {
background: #F0FDF4;
color: #15803D;
border-bottom: 1px solid #DCFCE7;
}
.md-fields {
padding: 12px 14px;
display: flex;
flex-direction: column;
gap: 9px;
}
.md-field {
display: flex;
flex-direction: column;
gap: 2px;
}
.md-field-full {
grid-column: 1 / -1;
}
.md-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-primary);
}
.md-val {
font-size: 13px;
color: var(--text-primary);
}
.md-pre {
font-family: 'Fira Code', 'Courier New', monospace;
font-size: 11px;
background: var(--bg-elevated);
border: 1px solid var(--border);
border-radius: 6px;
padding: 8px 10px;
margin: 0;
white-space: pre-wrap;
word-break: break-all;
color: var(--text-primary);
max-height: 400px;
overflow-y: auto;
}
/* ── Detail modal grid (Deposit / Payout / MatchHistory) ─── */
.dd-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 14px 20px;
}
.dd-row {
display: flex;
flex-direction: column;
gap: 4px;
align-items: flex-start;
}
.dd-full {
grid-column: 1 / -1;
}
.dd-label {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-primary);
}
.dd-val {
font-size: 13.5px;
color: var(--text-primary);
}
.dd-section-header {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-primary);
border-bottom: 1.5px solid var(--border);
padding-bottom: 6px;
margin-top: 4px;
}
.dd-pre {
font-family: 'Fira Code', 'Courier New', monospace;
font-size: 12px;
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 6px;
padding: 10px 12px;
margin: 0;
white-space: pre-wrap;
word-break: break-all;
color: var(--text-primary);
max-height: 400px;
overflow-y: auto;
}
/* ── Copyable Keys & Tooltips ─────────────────────────────────── */
.apikey-container {
position: relative;
display: inline-flex;
align-items: center;
cursor: copy;
}
.apikey-pill {
display: inline-block;
font-family: 'Fira Code', 'Courier New', monospace;
font-size: 11.5px;
color: #6D28D9;
background: rgba(109,40,217,0.07);
border: 1px solid rgba(109,40,217,0.15);
border-radius: 4px;
padding: 2px 7px;
letter-spacing: 0.04em;
transition: all 0.2s ease;
}
.apikey-container:hover .apikey-pill {
background: rgba(109,40,217,0.14);
border-color: rgba(109,40,217,0.4);
color: #5B21B6;
}
.apikey-container .tooltip-text {
visibility: hidden;
width: auto;
min-width: 120px;
background-color: #0F172A;
color: #fff;
text-align: center;
border-radius: 6px;
padding: 6px 12px;
position: absolute;
z-index: 1000;
bottom: 140%;
left: 50%;
transform: translateX(-50%);
opacity: 0;
transition: opacity 0.2s, transform 0.2s;
font-family: 'Fira Code', monospace;
font-size: 11px;
white-space: nowrap;
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2), 0 4px 6px -2px rgba(0, 0, 0, 0.1);
pointer-events: none;
letter-spacing: 0.02em;
}
.apikey-container:hover .tooltip-text {
visibility: visible;
opacity: 1;
transform: translateX(-50%) translateY(-2px);
}
.apikey-container .tooltip-text::after {
content: "";
position: absolute;
top: 100%;
left: 50%;
margin-left: -5px;
border-width: 5px;
border-style: solid;
border-color: #0F172A transparent transparent transparent;
}
/* High-contrast status badges for Onyx Dark theme */
body.theme-onyx .badge-status.danger {
background-color: rgba(239, 68, 68, 0.2) !important;
color: #ff8e8e !important;
border-color: rgba(239, 68, 68, 0.4) !important;
}
body.theme-onyx .badge-status.success {
background-color: rgba(16, 185, 129, 0.2) !important;
color: #86efac !important;
border-color: rgba(16, 185, 129, 0.4) !important;
}
body.theme-onyx .badge-status.warning {
background-color: rgba(245, 158, 11, 0.2) !important;
color: #fde68a !important;
border-color: rgba(245, 158, 11, 0.4) !important;
}
/* Held-manual feature: badge for the ExceptedStatus the client submitted via the public API.
Rendered next to the primary status with a distinct color so the operator notices mismatches. */
.badge-expected {
background-color: rgba(99, 102, 241, 0.15);
color: #4338ca;
border-color: rgba(99, 102, 241, 0.3);
margin-left: 4px;
font-size: 0.7em;
}
body.theme-onyx .badge-expected {
background-color: rgba(129, 140, 248, 0.2) !important;
color: #a5b4fc !important;
border-color: rgba(129, 140, 248, 0.4) !important;
}
/* Vertical indicators for highlighted rows in dark mode */
body.theme-onyx .table-bo tbody tr.row-completed td:first-child {
border-left: 2px solid #10b981 !important;
}
body.theme-onyx .table-bo tbody tr.row-failed td:first-child {
border-left: 2px solid #ef4444 !important;
}
/* ── Copyable text cell (table column with inline copy button) ─── */
.copy-cell {
display: inline-flex;
align-items: center;
gap: 4px;
max-width: 100%;
}
.copy-cell-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.btn-copy {
flex: 0 0 auto;
background: transparent;
border: none;
padding: 2px 4px;
cursor: pointer;
color: var(--text-muted);
border-radius: 4px;
display: inline-flex;
align-items: center;
transition: color .15s, background .15s;
}
.btn-copy:hover {
color: var(--primary);
background: var(--bg-elevated);
}
/* ==========================================================================
Callback Logs Table and Terminal Panel Optimizations
========================================================================== */
.table-bo.table-callbacks {
table-layout: auto !important;
}
.table-bo.table-callbacks thead th {
white-space: nowrap !important;
overflow: visible !important;
text-overflow: clip !important;
}
.table-bo.table-callbacks tbody td .url-text {
max-width: 320px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Force expanded log rows to break out of default nowrap/clip limits */
.table-bo.table-callbacks tbody .log-expansion-row td {
text-align: left !important;
white-space: normal !important;
overflow: visible !important;
text-overflow: clip !important;
padding: 16px !important;
background: var(--bg-surface) !important;
border-left: 4px solid var(--primary) !important;
}
/* Terminal Wrap and Body responsiveness and custom styling */
.table-bo.table-callbacks tbody .terminal-wrap {
overflow: hidden !important;
box-shadow: var(--shadow-lg);
}
.table-bo.table-callbacks tbody .terminal-body {
max-height: 480px !important;
overflow-y: auto !important;
display: flex;
flex-direction: column;
gap: 14px;
}
/* Custom premium scrollbar for macOS-like terminal window */
.table-bo.table-callbacks tbody .terminal-body::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.table-bo.table-callbacks tbody .terminal-body::-webkit-scrollbar-track {
background: rgba(15, 23, 42, 0.2);
border-radius: 999px;
}
.table-bo.table-callbacks tbody .terminal-body::-webkit-scrollbar-thumb {
background: rgba(148, 163, 184, 0.3);
border-radius: 999px;
transition: background 0.2s ease;
}
.table-bo.table-callbacks tbody .terminal-body::-webkit-scrollbar-thumb:hover {
background: rgba(148, 163, 184, 0.5);
}
/* ============================================================
EXTRACTED FROM: Components\Layout\MainLayout.razor
============================================================ */
.dropdown-item {
border: none;
background: transparent;
width: 100%;
text-align: left;
transition: all 0.15s ease;
cursor: pointer;
color: var(--text-primary);
}
.dropdown-item:hover {
background-color: var(--bg-elevated) !important;
color: var(--text-primary) !important;
}
.dropdown-item.active {
background-color: var(--primary-dim) !important;
color: var(--primary) !important;
font-weight: 600;
}
/* Submenu Styles */
.dropdown-submenu-container {
position: relative;
}
.theme-sub-menu {
display: none;
position: absolute;
top: -6px;
right: 100%;
margin-right: 2px;
min-width: 190px;
background: var(--bg-surface);
border: 1px solid var(--border);
box-shadow: 0 10px 30px rgba(0,0,0,0.15) !important;
z-index: 1001;
padding: 6px 0;
animation: subMenuFadeIn 0.2s ease;
}
.dropdown-submenu-container:hover .theme-sub-menu {
display: block;
}
@keyframes subMenuFadeIn {
from { opacity: 0; transform: translateX(10px); }
to { opacity: 1; transform: translateX(0); }
}
/* ============================================================
EXTRACTED FROM: Components\Layout\ThemeToggle.razor
============================================================ */
.theme-picker-container { position: relative; display: flex; align-items: center; }
.theme-main-btn {
background: none;
border: none;
width: 38px;
height: 38px;
color: var(--text-secondary);
cursor: pointer;
border-radius: 10px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
align-items: center;
justify-content: center;
}
.theme-main-btn:hover {
background: var(--bg-elevated);
color: var(--primary);
transform: translateY(-1px);
}
.theme-main-btn:active { transform: translateY(0); }
.theme-overlay {
position: fixed;
inset: 0;
z-index: 999;
background: transparent;
}
.theme-dropdown {
position: absolute;
top: calc(100% + 8px);
right: -4px;
width: 220px;
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 14px;
box-shadow: 0 10px 40px -10px rgba(0,0,0,0.15);
z-index: 1000;
padding: 6px;
animation: themeIn 0.2s cubic-bezier(0.16, 1, 0.3, 1);
transform-origin: top right;
}
@keyframes themeIn {
from { opacity: 0; transform: scale(0.95) translateY(-8px); }
to { opacity: 1; transform: scale(1) translateY(0); }
}
.theme-section-label {
font-size: 10px;
font-weight: 800;
color: var(--text-muted);
letter-spacing: 0.12em;
padding: 10px 12px 6px;
text-transform: uppercase;
}
.theme-options { display: flex; flex-direction: column; gap: 2px; }
.theme-opt {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 12px;
border-radius: 10px;
cursor: pointer;
transition: all 0.15s ease;
position: relative;
}
.theme-opt:hover { background: var(--bg-elevated); }
.theme-opt.active { background: var(--primary-dim); }
.theme-opt.active .theme-name { color: var(--primary); font-weight: 700; }
.theme-circle {
width: 14px;
height: 14px;
border-radius: 50%;
flex-shrink: 0;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.05);
}
.theme-info { display: flex; flex-direction: column; line-height: 1.25; }
.theme-name { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.theme-desc { font-size: 10px; color: var(--text-muted); margin-top: 2px; }
.theme-opt.active::after {
content: '';
position: absolute;
right: 12px;
width: 6px;
height: 6px;
background: var(--primary);
border-radius: 50%;
}
/* ============================================================
EXTRACTED FROM: Components\Modals\PoolPolicyModal.razor
============================================================ */
/* ── Overlay ── */
.policy-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(15, 23, 42, 0.45);
backdrop-filter: blur(3px);
z-index: 2000;
opacity: 0;
pointer-events: none;
transition: opacity 0.2s ease;
}
.policy-overlay.open {
opacity: 1;
pointer-events: auto;
}
/* ── Modal ── */
.policy-modal {
position: fixed;
top: 50%;
left: 50%;
width: 580px;
max-width: calc(100vw - 32px);
max-height: 85vh;
background: var(--bg-surface);
border-radius: 12px;
box-shadow: 0 24px 60px rgba(0, 0, 0, 0.25), 0 0 0 1px var(--border);
z-index: 2100;
display: flex;
flex-direction: column;
transform: translate(-50%, -50%) scale(0.95);
opacity: 0;
pointer-events: none;
transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s ease;
overflow: hidden;
border: 1px solid var(--border);
}
.policy-modal.open {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
pointer-events: auto;
}
/* ── Header ── */
.policy-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 16px 24px;
border-bottom: 1px solid var(--border);
background: var(--bg-elevated);
}
.policy-header-left {
display: flex;
align-items: center;
gap: 12px;
flex: 1;
}
.policy-header-left svg {
color: var(--primary);
flex-shrink: 0;
}
.policy-title {
font-size: 14px;
font-weight: 600;
color: var(--text-primary);
}
.policy-subtitle {
font-size: 12px;
color: var(--text-secondary);
margin-top: 2px;
}
.policy-close {
background: none;
border: none;
cursor: pointer;
color: var(--text-secondary);
padding: 4px;
display: flex;
align-items: center;
justify-content: center;
transition: color 0.2s ease;
}
.policy-close:hover {
color: var(--text-primary);
}
/* ── Body ── */
.policy-body {
flex: 1;
overflow-y: auto;
padding: 24px;
background: var(--bg-surface);
color: var(--text-primary);
}
.policy-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-bottom: 16px;
}
/* ── Footer ── */
.policy-footer {
display: flex;
justify-content: flex-end;
gap: 8px;
padding: 16px 24px;
border-top: 1px solid var(--border);
background: var(--bg-elevated);
}
.policy-btn-cancel {
padding: 8px 16px;
border: 1px solid var(--border);
border-radius: 6px;
background: transparent;
color: var(--text-secondary);
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.policy-btn-cancel:hover {
background: var(--bg-elevated);
border-color: var(--text-secondary);
}
.policy-btn-save {
padding: 8px 16px;
border: none;
border-radius: 6px;
background: var(--primary);
color: #FFFFFF;
font-size: 13px;
font-weight: 500;
cursor: pointer;
transition: all 0.2s ease;
}
.policy-btn-save:hover {
opacity: 0.9;
box-shadow: 0 4px 12px var(--primary-glow);
}
/* ── Alert ── */
.bo-alert {
display: flex;
gap: 12px;
padding: 14px 16px;
border-radius: 8px;
font-size: 13.5px;
line-height: 1.5;
}
.bo-alert.info {
background: var(--primary-dim);
border: 1px solid var(--primary-glow);
color: var(--primary);
}
.bo-alert svg {
flex-shrink: 0;
margin-top: 2px;
}
/* ── Form shared (c-*) ── */
.c-field { display:flex; flex-direction:column; }
.c-label { font-size:11.5px; font-weight:600; color:var(--text-secondary); margin-bottom:4px; }
.c-input {
width:100%; border:none; border-bottom:1.5px solid var(--border);
background:transparent; padding:7px 0; font-size:13.5px;
color:var(--text-primary); outline:none; transition:border-color 0.15s; font-family:inherit;
}
.c-input::placeholder { color:var(--text-secondary); opacity:0.6; }
.c-input:focus { border-bottom-color:var(--primary); }
.c-select-wrap { position:relative; display:flex; align-items:center; }
.c-select {
width:100%; border:none; border-bottom:1.5px solid var(--border);
background:transparent; padding:7px 24px 7px 0;
font-size:13.5px; color:var(--text-primary); appearance:none;
cursor:pointer; outline:none; transition:border-color 0.15s; font-family:inherit;
}
.c-select option { background:var(--bg-surface); color:var(--text-primary); }
.c-select:focus { border-bottom-color:var(--primary); }
.c-select-chevron { position:absolute; right:2px; top:50%; transform:translateY(-50%); color:var(--text-secondary); pointer-events:none; }
/* ============================================================
EXTRACTED FROM: Components\Pages\AccessDenied.razor
============================================================ */
.access-denied-icon {
color: var(--danger);
background: var(--danger-dim);
width: 120px;
height: 120px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin: 0 auto 1.5rem;
animation: lock-pulse 2s infinite;
}
@keyframes lock-pulse {
0% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0.4); }
70% { box-shadow: 0 0 0 20px rgba(239, 68, 68, 0); }
100% { box-shadow: 0 0 0 0 rgba(239, 68, 68, 0); }
}
/* ============================================================
EXTRACTED FROM: Components\Pages\Error.razor
============================================================ */
.error-container {
display: flex;
justify-content: center;
align-items: center;
min-height: calc(100vh - 120px);
padding: 40px;
}
.error-card {
background: #fff;
border-radius: 24px;
padding: 48px;
max-width: 500px;
width: 100%;
text-align: center;
border: 1px solid rgba(15, 23, 42, 0.08);
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
}
.error-illustration {
position: relative;
display: inline-block;
margin-bottom: 32px;
color: #94A3B8;
}
.status-badge {
position: absolute;
bottom: -5px;
right: -5px;
padding: 4px 10px;
border-radius: 8px;
font-size: 11px;
font-weight: 800;
color: white;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
}
.badge-red { background: #ef4444; }
.badge-blue { background: #3b82f6; }
.badge-orange { background: #f59e0b; }
.error-title {
font-weight: 900;
font-size: 24px;
color: #0F172A;
margin-bottom: 12px;
}
.error-msg {
color: #64748B;
font-size: 15px;
line-height: 1.6;
margin-bottom: 24px;
}
.request-id {
font-size: 12px;
color: #94a3b8;
background: #f8fafc;
padding: 6px 12px;
border-radius: 8px;
display: inline-block;
}
.request-id code { color: #475569; }
.error-container .btn-primary-bo {
text-decoration: none;
display: inline-flex;
align-items: center;
padding: 12px 28px;
font-size: 14px;
font-weight: 700;
background: #0f172a;
color: #fff;
border-radius: 12px;
}
/* ============================================================
EXTRACTED FROM: Components\Pages\PartnerBalance.razor
============================================================ */
.mbo-summary-table { border-collapse: collapse; width: 100%; max-width: 100%; margin-bottom: 1rem; }
.mbo-summary-table th { font-size: 10px; font-weight: 800; text-transform: uppercase;
color: var(--text-muted); padding: 8px 12px 8px 0; letter-spacing: .08em; border-bottom: 1px solid var(--border); }
.mbo-summary-table td { padding: 10px 12px 10px 0; border-bottom: 1px dashed var(--border); font-family: var(--font-mono); font-size: 13px; }
@media (max-width: 768px) {
.mbo-summary-table th, .mbo-summary-table td { padding: 8px 6px 8px 0; font-size: 11px; }
}
.mbo-expand-icon { font-size: 9px; color: var(--primary); width: 12px; display: inline-block;
user-select: none; transition: transform .15s; cursor: pointer; }
.mbo-child-row td { background: var(--bg-elevated); border-bottom: 1px solid var(--border); }
.mbo-child-row td:first-child { padding-left: 28px; }
.mbo-total-row td { font-weight: 700; background: var(--bg-elevated);
border-top: 2px solid var(--border) !important; color: var(--text-primary); }
.mbo-neg { color: #EF4444 !important; font-weight: 600; }
.mbo-pos { color: var(--text-primary); }
.mbo-zero { color: var(--text-muted); opacity: 0.6; }
.type-badge { display: inline-flex; align-items: center; padding: 2px 8px;
border-radius: 20px; font-size: 10px; font-weight: 700; text-transform: uppercase;
letter-spacing: .04em; }
.type-badge.deposit { background: rgba(16, 185, 129, 0.1); color: #10B981; }
.type-badge.payout  { background: rgba(239, 68, 68, 0.1);  color: #EF4444; }
.type-badge.topup   { background: rgba(16, 185, 129, 0.1); color: #059669; }
.type-badge.adj     { background: rgba(245, 158, 11, 0.1); color: #D97706; }
/* Custom scrollbar for better look in dark mode */
.table-responsive::-webkit-scrollbar { height: 6px; }
.table-responsive::-webkit-scrollbar-track { background: var(--bg-surface); }
.table-responsive::-webkit-scrollbar-thumb { background: var(--border); border-radius: 10px; }
.table-responsive::-webkit-scrollbar-thumb:hover { background: var(--text-muted); }
/* Fix table stretching when there are few rows */
.table-responsive {
height: auto !important;
}
.table-bo {
height: auto !important;
}
/* ============================================================
EXTRACTED FROM: Components\Pages\StatementDetailModal.razor
============================================================ */
.dd-section-title {
font-size: 11px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-secondary);
margin: 16px 0 8px;
padding-bottom: 4px;
border-bottom: 1px solid var(--border);
}
.dd-section-title:first-child { margin-top: 0; }
.dd-row-wide { grid-column: 1 / -1; }
/* ============================================================
EXTRACTED FROM: Components\Pages\Statements.razor
============================================================ */
.statement-search-hint {
font-size: 12px;
color: var(--text-secondary);
align-self: center;
white-space: nowrap;
}
.statement-empty-state {
display: grid;
gap: 8px;
place-items: center;
padding: 1rem 0;
}
.statement-empty-icon {
width: 42px;
height: 42px;
border-radius: 14px;
display: grid;
place-items: center;
background: rgba(var(--primary-rgb), 0.08);
color: var(--primary);
font-size: 18px;
font-weight: 800;
}
.statement-empty-title {
font-size: 14px;
font-weight: 800;
color: var(--text-primary);
}
.statement-empty-sub {
font-size: 12px;
color: var(--text-secondary);
}
/* ============================================================
EXTRACTED FROM: Components\Pages\TransactionDetail.razor
============================================================ */
.tx-summary-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 12px;
}
.tx-summary-card,
.tx-panel {
border-radius: 18px !important;
border: 1px solid var(--border) !important;
background: var(--bg-surface) !important;
box-shadow: 0 14px 30px rgba(15, 23, 42, 0.04) !important;
}
.tx-summary-card {
padding: 16px 18px;
}
.tx-summary-label,
.tx-summary-sub {
display: block;
color: var(--text-secondary);
}
.tx-summary-label {
font-size: 11px;
font-weight: 800;
text-transform: uppercase;
letter-spacing: 0.14em;
margin-bottom: 10px;
}
.tx-summary-value {
font-size: 20px;
font-weight: 800;
color: var(--text-primary);
letter-spacing: -0.03em;
}
.tx-summary-sub {
margin-top: 6px;
font-size: 12px;
}
.tx-panel-warn { border-top: 4px solid var(--warning) !important; }
.tx-panel-primary { border-top: 4px solid var(--primary) !important; }
.tx-field-list {
display: flex;
flex-direction: column;
gap: 0;
}
.tx-field-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
border-bottom: 1px solid var(--border);
padding: 0.9rem 0;
}
.tx-field-row:last-child {
border-bottom: 0;
padding-bottom: 0;
}
.tx-empty-state {
padding: 1.5rem;
border-radius: 16px;
background: var(--bg-elevated);
border: 1px dashed var(--border);
text-align: center;
}
.tx-empty-state h5 {
margin: 10px 0 4px;
font-size: 15px;
color: var(--text-primary);
}
.tx-empty-state p {
margin: 0;
color: var(--text-secondary);
font-size: 13px;
}
.tx-timeline {
margin-top: 1.5rem;
padding-top: 1rem;
border-top: 1px solid var(--border);
display: flex;
flex-direction: column;
gap: 1rem;
}
/* ============================================================
EXTRACTED FROM: Components\Pages\TransactionHistory.razor
============================================================ */
.type-filter-group { display: flex; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--bg-card); }
.type-filter-btn { border: none; background: transparent; padding: 6px 16px; font-size: 12px; font-weight: 600; color: var(--text-muted); cursor: pointer; transition: background 0.15s, color 0.15s; font-family: inherit; }
.type-filter-btn:not(:last-child) { border-right: 1px solid var(--border); }
.type-filter-btn.active { background: var(--primary); color: #fff; }
.type-filter-btn:not(.active):hover { background: var(--bg-elevated); color: var(--text-primary); }
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\Adjustment.razor
============================================================ */
.type-selector { display:flex; gap:8px; margin-top:8px; }
.type-btn {
flex:1; display:flex; align-items:center; justify-content:center; gap:6px;
padding:10px 8px; border:1.5px solid var(--border); border-radius:8px;
background:var(--bg-surface); color:var(--text-secondary); font-size:12.5px; font-weight:700;
cursor:pointer; font-family:inherit; transition:all 0.15s;
}
.type-btn:hover { border-color:var(--primary); color:var(--primary); }
.type-btn.active { color:#fff; border-color:transparent; }
.type-btn.active.green { background:linear-gradient(135deg,#10B981,#059669); }
.type-btn.active.orange { background:linear-gradient(135deg,#F59E0B,#D97706); }
.type-btn.active.purple { background:var(--primary); }
/* c-* form classes (same as Pools modal) */
.c-field { display:flex; flex-direction:column; }
.c-label { font-size:11.5px; font-weight:600; color:var(--text-secondary); margin-bottom:4px; }
.c-input {
width:100%; border:none; border-bottom:1.5px solid var(--border);
background:transparent; padding:7px 0;
color:var(--text-primary); outline:none; transition:border-color 0.15s; font-family:inherit;
}
.c-input::placeholder { color:var(--text-secondary); opacity:0.6; }
.c-input:focus { border-bottom-color:var(--primary); }
.c-select-wrap { position:relative; }
.c-select {
width:100%; border:none; border-bottom:1.5px solid var(--border);
background:transparent; padding:7px 24px 7px 0;
font-size:13.5px; color:var(--text-primary); appearance:none;
cursor:pointer; outline:none; transition:border-color 0.15s; font-family:inherit;
}
.c-select option {
background:var(--bg-surface);
color:var(--text-primary);
}
.c-select:focus { border-bottom-color:var(--primary); }
.c-select-chevron { position:absolute; right:2px; top:50%; transform:translateY(-50%); color:var(--text-secondary); pointer-events:none; }
/* reuse pmw-btn-save from Pools */
.pmw-btn-save {
background:var(--primary);
color:#fff; border:none; border-radius:8px;
font-weight:700; cursor:pointer; font-family:inherit;
box-shadow:0 2px 8px var(--primary-glow);
transition:opacity 0.15s,transform 0.1s;
}
.pmw-btn-save:hover { opacity:0.88; }
.pmw-btn-save:disabled { opacity:0.6; cursor:not-allowed; }
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\CallbackLogs.razor
============================================================ */
.cl-toast { padding:10px 16px; border-radius:8px; font-size:13px; font-weight:500; animation:clToastIn .2s ease both; }
.cl-toast-ok { background:#D1FAE5; color:#065F46; border:1px solid #6EE7B7; }
.cl-toast-err { background:#FEE2E2; color:#991B1B; border:1px solid #FCA5A5; }
@keyframes clToastIn { from { opacity:0; transform:translateY(-6px) } to { opacity:1; transform:none } }
.btn-retry {
display: inline-flex; align-items: center; gap: 4px;
padding: 4px 10px;
background: #F1F5F9; color: #334155;
border: 1px solid #CBD5E1; border-radius: 6px;
font-size: 12px; font-weight: 600; cursor: pointer;
font-family: inherit; transition: background 0.15s;
}
.btn-retry:hover { background: #E2E8F0; }
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\CircuitBreakers.razor
============================================================ */
/* ── Stats Dashboard Row ─────────────────────────── */
.stats-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
margin-bottom: 20px;
}
.stat-card {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 16px;
display: flex;
align-items: center;
gap: 14px;
box-shadow: 0 4px 20px -2px rgba(0,0,0,0.02);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 24px -4px rgba(0,0,0,0.06);
}
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 42px;
height: 42px;
border-radius: 10px;
}
.stat-icon.purple { background: rgba(139, 92, 246, 0.08); color: #8b5cf6; }
.stat-icon.red { background: rgba(239, 68, 68, 0.08); color: #ef4444; }
.stat-icon.green { background: rgba(16, 185, 129, 0.08); color: #10b981; }
.stat-icon.blue { background: rgba(59, 130, 246, 0.08); color: #3b82f6; }
.stat-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.stat-label {
font-size: 12px;
color: var(--text-secondary);
font-weight: 500;
}
.stat-value {
font-size: 20px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
.breaker-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 16px;
padding: 20px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
display: flex;
flex-direction: column;
gap: 20px;
position: relative;
overflow: hidden;
}
.breaker-card:hover { border-color: var(--primary-light); box-shadow: 0 10px 25px -5px rgba(0,0,0,0.05); }
.breaker-card.open { border-left: 4px solid #ef4444; }
.breaker-card.closed { border-left: 4px solid #10b981; }
.breaker-header { display: flex; justify-content: space-between; align-items: flex-start; }
.bank-info { display: flex; gap: 12px; align-items: center; }
.bank-avatar {
width: 36px; height: 36px; background: rgba(37,99,235,0.08); color: var(--primary);
display: flex; align-items: center; justify-content: center; border-radius: 10px;
font-weight: 700; font-size: 13px; text-transform: uppercase;
}
.bank-code { font-weight: 700; color: var(--text-primary); font-size: 15px; }
.breaker-id { font-size: 11px; color: var(--text-muted); font-family: var(--font-mono); }
.status-indicator {
display: flex; align-items: center; gap: 6px; padding: 4px 10px; border-radius: 20px;
font-size: 10px; font-weight: 800; letter-spacing: 0.05em;
}
.status-indicator.success { background: rgba(16,185,129,0.1); color: #059669; }
.status-indicator.danger { background: rgba(239, 68, 68, 0.1); color: #dc2626; }
.status-indicator .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
.metric-row { display: flex; justify-content: space-between; align-items: baseline; }
.metric-label { font-size: 10px; font-weight: 700; color: var(--text-muted); letter-spacing: 0.08em; }
.metric-value { font-family: var(--font-mono); font-weight: 700; font-size: 14px; color: var(--text-primary); }
.metric-value-sm { font-size: 12px; color: var(--text-secondary); font-weight: 600; }
.metric-value small { color: var(--text-muted); font-size: 11px; }
.progress-wrap { margin-top: 4px; }
.progress-bar { height: 6px; background: rgba(0,0,0,0.05); border-radius: 3px; overflow: hidden; }
.progress-fill { height: 100%; transition: width 0.4s ease; }
.bg-success { background: #10b981; }
.bg-danger { background: #ef4444; }
.btn-reset {
width: 100%; display: flex; align-items: center; justify-content: center; gap: 8px;
padding: 10px; border-radius: 10px; border: 1.5px solid var(--border);
background: transparent; color: var(--text-primary); font-size: 12px; font-weight: 700;
cursor: pointer; transition: all 0.2s;
}
.btn-reset:not(:disabled):hover { background: var(--border); border-color: var(--text-muted); }
.btn-reset:disabled { opacity: 0.5; cursor: not-allowed; }
.reset-success {
width: 100%; display: flex; align-items: center; justify-content: center; gap: 6px;
padding: 10px; border-radius: 10px; background: rgba(16,185,129,0.1);
color: #059669; font-size: 11px; font-weight: 800;
}
.alert-bo { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 8px; font-size: 12px; }
.alert-bo.danger { background: rgba(239, 68, 68, 0.05); border: 1px solid rgba(239, 68, 68, 0.15); color: #ef4444; }
.spinner-sm { width: 14px; height: 14px; border: 2px solid currentColor; border-top-color: transparent; border-radius: 50%; animation: spin 0.8s linear infinite; }
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\DeletedRoles.razor
============================================================ */
.header-with-back { display: flex; align-items: center; gap: 16px; }
.btn-icon-back {
width: 38px;
height: 38px;
background: var(--bg-surface);
border: 1px solid var(--border);
color: var(--text-secondary);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
transition: var(--transition);
text-decoration: none;
}
.btn-icon-back:hover {
background: var(--primary-dim);
border-color: var(--primary);
color: var(--primary);
transform: translateX(-3px);
}
.loading-state { text-align: center; padding: 4rem 2rem; }
.loading-state p { margin-top: 1rem; color: var(--text-muted); font-weight: 500; }
.error-inline { padding: 24px; background: #fee2e2; border-left: 4px solid #dc2626; border-radius: 8px; margin: 16px; }
.deleted-time { font-size: 13px; color: var(--text-secondary); display: flex; align-items: center; }
.btn-restore-item {
display: inline-flex;
align-items: center;
padding: 6px 14px;
background: var(--primary-dim);
color: var(--primary);
border: 1px solid transparent;
border-radius: 8px;
font-size: 12px;
font-weight: 700;
cursor: pointer;
transition: var(--transition);
}
.btn-restore-item:hover {
background: var(--primary);
color: white;
}
.empty-table-state { padding: 5rem 2rem; display: flex; flex-direction: column; align-items: center; gap: 16px; color: var(--text-muted); }
.empty-icon-box.sm { width: 64px; height: 64px; background: var(--bg-elevated); border-radius: 16px; display: flex; align-items: center; justify-content: center; color: var(--border); }
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\FeeRules.razor
============================================================ */
/* ── Stats Dashboard Row ─────────────────────────── */
.stats-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
margin-bottom: 20px;
}
.stat-card {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 16px;
display: flex;
align-items: center;
gap: 14px;
box-shadow: 0 4px 20px -2px rgba(0,0,0,0.02);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 24px -4px rgba(0,0,0,0.06);
}
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 42px;
height: 42px;
border-radius: 10px;
}
.stat-icon.purple { background: rgba(139, 92, 246, 0.08); color: #8b5cf6; }
.stat-icon.red { background: rgba(239, 68, 68, 0.08); color: #ef4444; }
.stat-icon.green { background: rgba(16, 185, 129, 0.08); color: #10b981; }
.stat-icon.blue { background: rgba(59, 130, 246, 0.08); color: #3b82f6; }
.stat-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.stat-label {
font-size: 12px;
color: var(--text-secondary);
font-weight: 500;
}
.stat-value {
font-size: 20px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
/* ── Search Highlight ────────────────────────────── */
.search-highlight {
background: rgba(245, 158, 11, 0.18);
color: #d97706;
border-bottom: 1.5px solid #f59e0b;
padding: 0 1px;
border-radius: 2px;
font-weight: 700;
}
/* ── Toolbar & Legend Overrides ──────────────────── */
.fr-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 16px;
border-bottom: 1px solid var(--border);
flex-wrap: wrap;
background: var(--bg-surface);
}
.search-input-wrapper {
position: relative;
width: 100%;
max-width: 320px;
}
.search-input-wrapper .search-icon {
position: absolute;
left: 12px;
top: 50%;
transform: translateY(-50%);
color: var(--text-secondary);
opacity: 0.6;
pointer-events: none;
}
.fr-search.search-input-field {
width: 100%;
background: var(--bg-surface);
border: 1px solid var(--border);
color: var(--text-primary);
border-radius: 8px;
padding: 8px 12px 8px 36px;
font-size: 13px;
transition: all 0.15s ease;
}
.fr-search.search-input-field:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.12);
outline: none;
}
.fr-legend {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.legend-badge {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 11px;
font-weight: 600;
color: var(--text-secondary);
background: var(--bg-elevated);
border: 1px solid var(--border);
padding: 4px 10px;
border-radius: 6px;
}
.legend-badge .badge-dot {
width: 6px;
height: 6px;
border-radius: 50%;
}
.legend-badge.spec-7 .badge-dot { background: #22c55e; box-shadow: 0 0 6px #22c55e; }
.legend-badge.spec-6 .badge-dot { background: #e05a2e; box-shadow: 0 0 6px #e05a2e; }
.legend-badge.spec-4 .badge-dot { background: #f8a925; box-shadow: 0 0 6px #f8a925; }
.legend-badge.spec-0 .badge-dot { background: #8590a6; }
/* ── Specificity Colors ────────────────────────── */
.fr-spec-dot { font-size: 14px; display: inline-block; line-height: 1; }
.fr-spec-0 { color: #8590a6; }
.fr-spec-1 { color: #8590a6; }
.fr-spec-2 { color: #3b7cf4; text-shadow: 0 0 8px rgba(59, 124, 244, 0.4); }
.fr-spec-3 { color: #3b7cf4; text-shadow: 0 0 8px rgba(59, 124, 244, 0.4); }
.fr-spec-4 { color: #f8a925; text-shadow: 0 0 8px rgba(248, 169, 37, 0.4); }
.fr-spec-5 { color: #f8a925; text-shadow: 0 0 8px rgba(248, 169, 37, 0.4); }
.fr-spec-6 { color: #e05a2e; text-shadow: 0 0 8px rgba(224, 90, 46, 0.4); }
.fr-spec-7 { color: #22c55e; text-shadow: 0 0 8px rgba(34, 197, 94, 0.4); }
.fr-wildcard { color: var(--text-secondary); opacity: 0.65; font-style: italic; font-size: 12px; }
.fr-code {
font-family: var(--font-mono, monospace);
font-size: 11.5px;
font-weight: 700;
background: rgba(var(--primary-rgb), 0.06);
color: var(--primary);
padding: 2.5px 7px;
border-radius: 5px;
border: 1px solid rgba(var(--primary-rgb), 0.12);
display: inline-block;
}
.fr-desc-sub {
font-size: 11px;
color: var(--text-secondary);
margin-top: 4px;
font-style: italic;
line-height: 1.3;
}
.fr-txtype {
font-size: 11px;
font-weight: 700;
padding: 3px 8px;
border-radius: 5px;
text-transform: uppercase;
letter-spacing: 0.02em;
}
.fr-txtype-deposit { background: rgba(34,197,94,.08); color: #16a34a; border: 1px solid rgba(34,197,94,.15); }
.fr-txtype-payout  { background: rgba(245,158,11,.08); color: #d97706; border: 1px solid rgba(245,158,11,.15); }
.fr-strategy {
font-size: 10.5px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: .4px;
padding: 3px 8px;
border-radius: 5px;
}
.fr-strategy-percentage { background: rgba(59,124,244,.08);  color: #2563eb; border: 1px solid rgba(59,124,244,.15); }
.fr-strategy-flat       { background: rgba(139,92,246,.08);  color: #7c3aed; border: 1px solid rgba(139,92,246,.15); }
.fr-strategy-minmaxcap  { background: rgba(245,158,11,.08);  color: #d97706; border: 1px solid rgba(245,158,11,.15); }
.fr-strategy-tiered     { background: rgba(14,165,233,.08);  color: #0284c7; border: 1px solid rgba(14,165,233,.15); }
.fr-strategy-zero       { background: rgba(100,116,139,.08); color: #64748b; border: 1px solid rgba(100,116,139,.15); }
.fr-rate-cell { font-size: 13px; font-variant-numeric: tabular-nums; }
.fr-actions {
display: flex;
gap: 5px;
flex-wrap: wrap;
}
.fr-btn {
padding: 4px 10px !important;
font-size: 11.5px !important;
font-weight: 600 !important;
}
.fr-btn-toggle { color: var(--text-secondary) !important; }
.fr-btn-toggle:hover { color: var(--text-primary) !important; }
.fr-btn-enable { color: #10b981 !important; border-color: rgba(16, 185, 129, 0.3) !important; background: rgba(16, 185, 129, 0.02) !important; }
.fr-btn-enable:hover { background: rgba(16, 185, 129, 0.08) !important; }
.fr-btn-del { color: var(--danger) !important; font-weight: 700; border-color: rgba(239, 68, 68, 0.2) !important; }
.fr-btn-del:hover { background: rgba(239, 68, 68, 0.06) !important; }
/* Modal layout helpers */
.mo-row-2 {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.mo-hint {
color: var(--text-secondary);
opacity: 0.7;
font-size: 11px;
font-weight: 400;
text-transform: none;
letter-spacing: 0;
}
.mo-hint-block {
margin-top: 4px;
font-size: 11px;
color: var(--text-secondary);
line-height: 1.4;
}
.mo-hint-block code {
background: rgba(var(--primary-rgb), 0.06);
color: var(--primary);
padding: 1px 5px;
border-radius: 4px;
font-size: 11px;
}
.fr-tiers-json {
min-height: 80px;
resize: vertical;
font-family: var(--font-mono, monospace);
font-size: 12px;
}
/* Delete confirm overlay */
.fr-confirm-backdrop {
position: fixed;
inset: 0;
background: rgba(0,0,0,.45);
z-index: 1100;
display: flex;
align-items: center;
justify-content: center;
}
.fr-confirm-box {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 14px;
padding: 24px 28px;
max-width: 400px;
width: 90%;
box-shadow: 0 20px 60px rgba(0,0,0,.25);
}
.fr-confirm-title {
font-size: 17px;
font-weight: 700;
color: var(--danger);
margin-bottom: 10px;
}
.fr-confirm-body {
font-size: 14px;
color: var(--text-secondary);
line-height: 1.5;
margin-bottom: 20px;
}
.fr-confirm-actions {
display: flex;
gap: 10px;
justify-content: flex-end;
}
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\Partners.razor
============================================================ */
.mo-select {
padding-left: 0;
text-indent: 0;
}
.mo-select option {
padding-left: 10px;
text-indent: 14px;
}
.mo-select.disabled-look {
background-color: var(--bg-elevated);
color: var(--text-secondary);
border-color: var(--border);
cursor: not-allowed;
}
.mo-select-wrap.locked .mo-select-chevron {
color: var(--text-muted);
opacity: .75;
}
.partner-config-layout {
display: grid;
grid-template-columns: 252px minmax(0, 1fr);
gap: 20px;
align-items: start;
}
.cfg-sidebar-hint {
font-size: 11px;
line-height: 1.45;
color: var(--text-secondary);
margin: 0 0 2px;
}
@media (min-width: 1101px) {
.cfg-sidebar {
position: sticky;
top: 0;
align-self: start;
max-height: min(78vh, 680px);
overflow-y: auto;
padding-bottom: 8px;
}
}
.cfg-sidebar {
border-right: 1px solid var(--border);
padding-right: 16px;
display: flex;
flex-direction: column;
gap: 14px;
}
.cfg-root-badge {
display: inline-block;
font-size: 10px;
font-weight: 800;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--primary);
background: var(--primary-dim);
border: 1px solid var(--primary-light);
border-radius: 6px;
padding: 4px 8px;
width: fit-content;
}
.cfg-sidebar-kv {
display: flex;
flex-direction: column;
gap: 4px;
}
.cfg-sidebar-label {
font-size: 10px;
font-weight: 800;
letter-spacing: 0.05em;
color: var(--text-secondary);
}
.cfg-sidebar-active {
margin-top: 2px;
}
.cfg-source-box {
background: var(--bg-elevated);
border: 1px solid var(--border);
border-radius: 10px;
padding: 12px;
}
.cfg-source-title {
font-size: 10px;
font-weight: 800;
letter-spacing: 0.08em;
color: var(--primary);
margin-bottom: 10px;
}
.cfg-source-line {
font-size: 12px;
margin-bottom: 8px;
line-height: 1.4;
}
.cfg-source-curr-row {
display: flex;
flex-direction: column;
gap: 6px;
}
.cfg-source-k {
font-weight: 700;
color: var(--text-secondary);
margin-right: 6px;
}
.cfg-source-v {
font-family: ui-monospace, monospace;
font-weight: 700;
color: var(--text-primary);
}
.cfg-source-chips {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.cfg-src-chip {
border: none;
cursor: pointer;
font-size: 11px;
font-weight: 700;
padding: 4px 10px;
border-radius: 999px;
background: var(--primary-dim);
color: var(--primary);
font-family: inherit;
}
.cfg-src-chip:hover {
background: var(--primary-light);
color: #fff;
}
.cfg-src-chip-active {
background: var(--primary) !important;
color: #fff !important;
box-shadow: 0 0 0 2px var(--primary-glow);
}
.cfg-src-chip-active:hover {
opacity: 0.9;
}
.cfg-source-note {
font-size: 11.5px;
color: var(--text-muted);
}
.cfg-chain-mini {
font-size: 10px;
color: var(--text-muted);
margin-top: 8px;
line-height: 1.35;
word-break: break-all;
}
.cfg-add-currency-btn {
width: 100%;
padding: 8px 12px;
border-radius: 8px;
border: 2px dashed var(--border);
background: var(--bg-elevated);
color: var(--primary);
font-weight: 700;
font-size: 12px;
cursor: pointer;
font-family: inherit;
}
.cfg-add-currency-btn:disabled {
opacity: 0.45;
cursor: not-allowed;
}
.cfg-extra-curr-link {
font-size: 11px;
padding: 0;
margin-top: -4px;
}
.cfg-main {
min-width: 0;
}
.cfg-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 12px;
}
.cfg-stat-pills {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
}
.cfg-stat {
font-size: 12px;
color: var(--text-secondary);
background: var(--bg-elevated);
border-radius: 999px;
padding: 5px 12px;
border: 1px solid var(--border);
}
.cfg-stat strong {
color: var(--text-primary);
font-variant-numeric: tabular-nums;
}
.cfg-stat-meta {
background: var(--primary-dim);
border-color: var(--primary-light);
color: var(--primary);
}
.cfg-empty-main {
margin-bottom: 12px;
padding: 16px 18px;
border-radius: 10px;
border: 1px dashed var(--border);
background: var(--bg-elevated);
color: var(--text-secondary);
font-size: 13px;
line-height: 1.45;
}
.cfg-empty-title {
font-weight: 600;
color: var(--text-primary);
margin: 0 0 6px 0;
}
.cfg-empty-text {
margin: 0;
}
.cfg-range-banner {
margin-bottom: 10px;
}
.cfg-table-scroll {
border: 1px solid var(--border);
border-radius: 10px;
overflow: auto;
max-height: min(560px, 68vh);
background: var(--bg-surface);
scroll-behavior: smooth;
}
.cfg-table-scroll::-webkit-scrollbar {
width: 6px;
height: 6px;
}
.cfg-table-scroll::-webkit-scrollbar-track {
background: transparent;
}
.cfg-table-scroll::-webkit-scrollbar-thumb {
background: var(--border);
border-radius: 10px;
}
.cfg-table-scroll::-webkit-scrollbar-thumb:hover {
background: var(--text-muted);
}
.cfg-unified-table {
width: 100%;
border-collapse: collapse;
min-width: 1180px;
table-layout: auto;
}
.cfg-unified-table thead th {
position: sticky;
top: 0;
z-index: 3;
box-shadow: 0 1px 0 var(--border);
}
.cfg-unified-table th {
text-align: left;
font-size: 11px;
font-weight: 700;
color: var(--text-secondary);
background: var(--bg-elevated);
border-bottom: 1px solid var(--border);
padding: 10px 8px;
cursor: help;
}
.cfg-th-curr { width: 182px; min-width: 182px; }
.cfg-th-action { width: 48px; min-width: 48px; }
.cfg-unified-table th:nth-child(2) { width: 220px; min-width: 220px; }
.cfg-unified-table th:nth-child(3) { width: 98px; min-width: 98px; }
.cfg-unified-table th:nth-child(4) { width: 96px; min-width: 96px; }
.cfg-unified-table th:nth-child(5) { width: 176px; min-width: 176px; }
.cfg-unified-table th:nth-child(6) { width: 154px; min-width: 154px; }
.cfg-unified-table th:nth-child(7) { width: 86px; min-width: 86px; }
.cfg-unified-table td {
border-bottom: 1px solid var(--border);
padding: 8px;
vertical-align: middle;
transition: background-color 0.12s ease;
min-width: 0;
}
.cfg-range-row:hover td:not(.cfg-currency-cell) {
background: var(--primary-dim) !important;
}
.cfg-zebra-a td:not(.cfg-currency-cell) {
background: var(--bg-surface);
}
.cfg-zebra-b td:not(.cfg-currency-cell) {
background: var(--bg-elevated);
}
tr.cfg-row-flash td {
animation: cfgRowFlash 1.5s ease;
}
@keyframes cfgRowFlash {
0% { box-shadow: inset 0 0 0 0 transparent; }
12% { box-shadow: inset 0 0 0 2px var(--primary); background-color: var(--primary-dim); }
100% { box-shadow: inset 0 0 0 0 transparent; }
}
.cfg-currency-cell {
vertical-align: top;
background: var(--bg-surface);
border-right: 1px solid var(--border);
}
.cfg-curr-stack {
display: flex;
flex-direction: column;
gap: 8px;
min-width: 0;
}
.cfg-curr-badge {
display: inline-block;
font-size: 13px;
font-weight: 800;
font-family: ui-monospace, monospace;
padding: 4px 12px;
border-radius: 999px;
background: var(--primary);
color: #fff;
width: fit-content;
}
.cfg-mtl-field {
margin: 0;
}
.cfg-mtl-field .mo-label {
font-size: 10px;
}
.cfg-curr-actions {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
margin-top: 4px;
}
.cfg-btn-add-r {
padding: 4px 10px;
font-size: 11px;
}
.cfg-icon-danger {
border: none;
background: transparent;
color: var(--danger);
cursor: pointer;
padding: 6px;
border-radius: 6px;
line-height: 0;
display: inline-flex;
align-items: center;
justify-content: center;
transition: background-color 0.15s ease, transform 0.1s ease;
}
.cfg-icon-danger:active {
transform: scale(0.92);
}
.cfg-icon-danger:hover:not(:disabled) {
background: var(--primary-dim);
}
.cfg-icon-danger:disabled {
opacity: 0.35;
cursor: not-allowed;
}
.cfg-td-action {
text-align: center;
vertical-align: middle;
}
.cfg-strategy-wrap {
min-width: 0;
}
.qty-stepper {
display: flex;
align-items: center;
gap: 2px;
justify-content: center;
}
.qty-step-btn {
width: 28px;
height: 30px;
border: 1px solid var(--border);
background: var(--bg-elevated);
border-radius: 6px;
font-size: 16px;
font-weight: 700;
line-height: 1;
cursor: pointer;
color: var(--text-secondary);
}
.qty-step-btn:hover {
background: var(--primary-dim);
border-color: var(--primary-light);
color: var(--primary);
}
.qty-step-input {
width: 48px;
text-align: center;
padding: 6px 4px;
}
.suggest-pills {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
}
.suggest-pill {
display: inline-flex;
align-items: center;
background: var(--primary-dim);
border: 1px solid var(--primary-light);
border-radius: 999px;
padding: 2px 8px;
max-width: 100%;
}
.suggest-pill-error {
border-color: #f87171;
background: #fef2f2;
}
.suggest-pill-input {
border: none;
background: transparent;
font-size: 11px;
font-weight: 600;
color: var(--primary);
width: 88px;
padding: 4px 2px;
font-variant-numeric: tabular-nums;
}
.suggest-pill-input:focus {
outline: none;
}
.currency-limits-hint {
margin-top: 5px;
font-size: 11px;
color: var(--text-secondary);
background: var(--bg-elevated);
border-radius: 4px;
padding: 4px 8px;
font-variant-numeric: tabular-nums;
}
.ranges-empty {
color: #94a3b8;
text-align: center;
padding: 16px;
}
.btn-link-danger {
border: 0;
background: transparent;
color: var(--danger);
font-size: 12px;
cursor: pointer;
padding: 4px 6px;
}
.cc-link-btn {
border: none;
background: transparent;
color: var(--primary);
font-weight: 600;
cursor: pointer;
text-decoration: underline;
font-family: inherit;
}
.cc-warn {
margin-top: 6px;
font-size: 11px;
color: var(--warning);
background: var(--primary-dim);
border-radius: 4px;
padding: 4px 8px;
}
.cfg-skeleton-root {
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: 20px;
min-height: 280px;
}
.cfg-skeleton-side {
display: flex;
flex-direction: column;
gap: 10px;
}
.cfg-skel-line {
height: 12px;
border-radius: 6px;
background: linear-gradient(90deg, var(--bg-elevated) 0%, var(--border) 50%, var(--bg-elevated) 100%);
background-size: 200% 100%;
animation: cfgSkelShine 1.1s ease-in-out infinite;
}
.cfg-skel-line.w-60 { width: 60%; }
.cfg-skel-line.w-80 { width: 80%; }
.cfg-skel-box {
height: 88px;
border-radius: 10px;
background: linear-gradient(90deg, var(--primary-dim) 0%, var(--bg-elevated) 50%, var(--primary-dim) 100%);
background-size: 200% 100%;
animation: cfgSkelShine 1.1s ease-in-out infinite;
}
.cfg-skeleton-main {
display: flex;
flex-direction: column;
gap: 12px;
}
.cfg-skel-toolbar {
display: flex;
gap: 8px;
flex-wrap: wrap;
}
.cfg-skel-pill {
height: 28px;
width: 88px;
border-radius: 999px;
background: var(--bg-elevated);
animation: cfgSkelShine 1.1s ease-in-out infinite;
}
.cfg-skel-pill.wide {
width: 160px;
}
.cfg-skel-table {
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
}
.cfg-skel-row {
height: 44px;
border-bottom: 1px solid var(--border);
background: linear-gradient(90deg, var(--bg-surface) 0%, var(--bg-elevated) 50%, var(--bg-surface) 100%);
background-size: 200% 100%;
animation: cfgSkelShine 1.1s ease-in-out infinite;
}
.cfg-skel-row:last-child {
border-bottom: none;
}
@keyframes cfgSkelShine {
0% { background-position: 200% 0; }
100% { background-position: -200% 0; }
}
.mo-btn-save:disabled {
opacity: 0.72;
cursor: wait;
}
.cfg-save-spinner {
display: inline-block;
width: 14px;
height: 14px;
margin-right: 8px;
border: 2px solid rgba(255, 255, 255, 0.35);
border-top-color: #fff;
border-radius: 50%;
vertical-align: -2px;
animation: cfgSpin 0.7s linear infinite;
}
@keyframes cfgSpin {
to { transform: rotate(360deg); }
}
@media (max-width: 1100px) {
.partner-config-layout {
grid-template-columns: 1fr;
gap: 24px;
}
.cfg-side {
order: -1;
}
.cfg-skeleton-root {
grid-template-columns: 1fr;
}
}
@media (max-width: 768px) {
.cfg-toolbar {
flex-direction: column;
align-items: flex-start;
}
.cfg-stat-pills {
width: 100%;
}
.cfg-stat {
flex: 1;
text-align: center;
}
.cfg-table-scroll {
border-radius: 0;
margin: 0 -18px;
width: calc(100% + 36px);
}
.cfg-unified-table {
min-width: 1100px;
}
}
@media (max-width: 480px) {
.cfg-stat-pills {
flex-direction: column;
align-items: stretch;
}
.cfg-table-scroll {
max-height: 50vh;
}
}
/* ── Stats Dashboard Row ────────────────────────── */
.tree-stats-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 12px;
margin-bottom: 20px;
}
.tree-stat-card {
display: flex;
align-items: center;
gap: 14px;
background: var(--bg-elevated);
border: 1px solid var(--border);
padding: 14px 18px;
border-radius: 12px;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
transition: all 0.2s ease;
}
.tree-stat-card:hover {
transform: translateY(-2px);
border-color: rgba(var(--primary-rgb), 0.2);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.04);
}
.tree-stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 38px;
height: 38px;
border-radius: 10px;
flex-shrink: 0;
}
.tree-stat-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.tree-stat-label {
font-size: 11.5px;
font-weight: 600;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.03em;
}
.tree-stat-value-group {
display: flex;
align-items: center;
gap: 8px;
}
.tree-stat-value {
font-size: 20px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
.tree-stat-badge {
font-size: 10px;
font-weight: 600;
padding: 2px 7px;
border-radius: 6px;
}
.tree-stat-badge.success {
background: rgba(16, 185, 129, 0.08);
color: #10b981;
border: 1px solid rgba(16, 185, 129, 0.15);
}
/* ── Toolbar & Searching ─────────────────────────── */
.tree-toolbar {
display: flex;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 16px;
padding: 4px 0;
}
.tree-toolbar-left {
display: flex;
gap: 8px;
align-items: center;
}
.btn-tree-action {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--bg-elevated);
border: 1px solid var(--border);
color: var(--text-secondary);
font-size: 12px;
font-weight: 500;
padding: 6px 12px;
border-radius: 8px;
cursor: pointer;
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
}
.btn-tree-action:hover {
background: var(--bg-surface);
color: var(--primary);
border-color: rgba(var(--primary-rgb), 0.3);
transform: translateY(-1px);
box-shadow: 0 2px 8px rgba(var(--primary-rgb), 0.04);
}
.btn-tree-action svg {
transition: transform 0.2s ease;
}
.btn-tree-action:hover svg {
transform: scale(1.08);
}
/* ── Tree List Layout ───────────────────────────── */
.tree-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.tree-node-wrap {
position: relative;
padding-left: calc(var(--level, 0) * 28px);
}
/* Vertical guide line from parent */
.tree-branch-line {
position: absolute;
left: calc(var(--level, 0) * 28px - 14px);
top: 0;
bottom: 0;
width: 1.5px;
background: linear-gradient(180deg, var(--border) 0%, rgba(var(--border-rgb), 0.4) 100%);
pointer-events: none;
}
/* horizontal branch tick connecting tree lines to cards */
.tree-branch-line::after {
content: '';
position: absolute;
left: 0;
top: 24px;
width: 14px;
height: 12px;
border-left: 1.5px solid var(--border);
border-bottom: 1.5px solid var(--border);
border-bottom-left-radius: 6px;
opacity: 0.6;
}
/* ── Tree Node Card ──────────────────────────────── */
.tree-node {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
background: var(--bg-elevated);
border: 1px solid var(--border);
border-radius: 12px;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.01);
}
/* Distinct visual stripe for root-level partner categories */
.tree-node-wrap[style*="--level: 0"] > .tree-node,
.tree-node-wrap[style*="--level:0"] > .tree-node {
border-left: 3px solid var(--primary);
background: linear-gradient(90deg, rgba(var(--primary-rgb), 0.01) 0%, var(--bg-elevated) 100%);
}
.tree-node-wrap[style*="--level: 1"] > .tree-node,
.tree-node-wrap[style*="--level: 2"] > .tree-node,
.tree-node-wrap[style*="--level: 3"] > .tree-node {
border-left: 2px solid var(--border);
}
.tree-node:hover {
border-color: rgba(var(--primary-rgb), 0.35);
box-shadow: 0 4px 16px rgba(var(--primary-rgb), 0.08);
transform: translateX(3px);
}
.node-inactive {
opacity: 0.6;
background: rgba(100, 116, 139, 0.01);
}
/* ── Collapse/Expand triggers ───────────────────── */
.tree-node-left {
display: flex;
align-items: center;
justify-content: center;
width: 26px;
flex-shrink: 0;
}
.tree-toggle-btn {
display: flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
border-radius: 50%;
border: 1px solid var(--border);
background: var(--bg-surface);
color: var(--text-secondary);
cursor: pointer;
transition: all 0.2s ease;
padding: 0;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.02);
}
.tree-toggle-btn:hover {
background: var(--primary);
border-color: var(--primary);
color: #fff;
transform: scale(1.08);
box-shadow: 0 4px 10px rgba(var(--primary-rgb), 0.25);
}
.tree-toggle-btn.expanded {
background: var(--primary-dim);
border-color: var(--primary-dim);
color: var(--primary);
}
.tree-toggle-btn.expanded:hover {
background: var(--primary);
color: #fff;
}
.tree-toggle-btn.expanded svg {
transform: rotate(90deg);
}
.tree-toggle-btn svg {
transition: transform 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.tree-leaf-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--border);
display: inline-block;
margin: auto;
}
/* ── Content Body ────────────────────────────────── */
.tree-node-body {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 4px;
}
.tree-node-header {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.partner-code-chip {
font-family: ui-monospace, 'SFMono-Regular', Menlo, Monaco, Consolas, monospace;
font-size: 12px;
font-weight: 700;
color: var(--primary);
background: rgba(var(--primary-rgb), 0.06);
border: 1px solid rgba(var(--primary-rgb), 0.12);
padding: 2px 8px;
border-radius: 6px;
letter-spacing: 0.02em;
}
.partner-fullname {
font-size: 13px;
font-weight: 600;
color: var(--text-primary);
}
.tree-node-meta {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 12px;
row-gap: 4px;
}
.meta-item {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 11.5px;
color: var(--text-secondary);
flex-shrink: 0;
}
.meta-item svg {
opacity: 0.55;
flex-shrink: 0;
}
.meta-children {
color: var(--primary);
font-weight: 600;
}
/* ── Actions Group ───────────────────────────────── */
.tree-node-actions {
display: flex;
gap: 6px;
align-items: center;
flex-shrink: 0;
opacity: 0.65;
transition: opacity 0.15s ease;
}
.tree-node:hover .tree-node-actions {
opacity: 1;
}
.btn-icon-action {
display: flex;
align-items: center;
justify-content: center;
width: 28px;
height: 28px;
border-radius: 8px;
border: 1px solid var(--border);
background: var(--bg-surface);
color: var(--text-secondary);
cursor: pointer;
transition: all 0.15s cubic-bezier(0.4, 0, 0.2, 1);
padding: 0;
}
.btn-icon-action:hover {
background: var(--bg-elevated);
color: var(--text-primary);
border-color: var(--text-secondary);
transform: translateY(-1px);
}
.btn-icon-action.danger:hover {
background: rgba(239, 68, 68, 0.08);
border-color: #ef4444;
color: #ef4444;
box-shadow: 0 4px 12px rgba(239, 68, 68, 0.12);
}
/* ── Search Highlight ────────────────────────────── */
.search-highlight {
background: rgba(245, 158, 11, 0.18);
color: #d97706;
border-bottom: 1.5px solid #f59e0b;
padding: 0 1px;
border-radius: 2px;
font-weight: 700;
}
/* ── Depth Level Badge ───────────────────────────── */
.badge-level {
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
padding: 2px 7px;
border-radius: 6px;
letter-spacing: 0.03em;
line-height: 1;
display: inline-flex;
align-items: center;
}
/* ── Linked Parent Chip ─────────────────────────── */
.partner-parent-chip {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 11px;
font-weight: 500;
color: var(--text-secondary);
background: var(--bg-surface);
border: 1px solid var(--border);
padding: 1.5px 7px;
border-radius: 5px;
}
.partner-parent-chip svg {
opacity: 0.6;
}
/* ── Premium Empty States ────────────────────────── */
.tree-empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
padding: 40px 20px;
background: var(--bg-elevated);
border: 1px dashed var(--border);
border-radius: 16px;
margin: 10px 0;
}
.tree-empty-state .empty-icon {
display: flex;
align-items: center;
justify-content: center;
width: 64px;
height: 64px;
border-radius: 50%;
background: rgba(var(--primary-rgb), 0.04);
color: var(--primary);
margin-bottom: 16px;
border: 1px solid rgba(var(--primary-rgb), 0.08);
}
.tree-empty-state h3 {
font-size: 16px;
font-weight: 600;
color: var(--text-primary);
margin: 0 0 6px 0;
}
.tree-empty-state p {
font-size: 13px;
color: var(--text-secondary);
max-width: 380px;
margin: 0 0 16px 0;
line-height: 1.5;
}
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\SupportBanks.razor
============================================================ */
/* ── Stats Dashboard Row ─────────────────────────── */
.stats-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
margin-bottom: 20px;
}
.stat-card {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 16px;
display: flex;
align-items: center;
gap: 14px;
box-shadow: 0 4px 20px -2px rgba(0,0,0,0.02);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 24px -4px rgba(0,0,0,0.06);
}
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 42px;
height: 42px;
border-radius: 10px;
}
.stat-icon.purple { background: rgba(139, 92, 246, 0.08); color: #8b5cf6; }
.stat-icon.green { background: rgba(16, 185, 129, 0.08); color: #10b981; }
.stat-icon.blue { background: rgba(59, 130, 246, 0.08); color: #3b82f6; }
.stat-icon.amber { background: rgba(245, 158, 11, 0.08); color: #f59e0b; }
.stat-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.stat-label {
font-size: 12px;
color: var(--text-secondary);
font-weight: 500;
}
.stat-value {
font-size: 20px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
/* ── Banks Grid Layout ───────────────────────────── */
.banks-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 20px;
margin-top: 8px;
}
.bank-card {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 16px;
padding: 20px;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 200px;
position: relative;
overflow: hidden;
box-shadow: 0 4px 15px -3px rgba(0,0,0,0.03);
transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
}
.bank-card:hover {
transform: translateY(-4px);
box-shadow: 0 12px 24px -6px rgba(0,0,0,0.07);
border-color: rgba(var(--primary-rgb), 0.3);
}
.bank-card.disabled {
opacity: 0.75;
border-style: dashed;
background: rgba(var(--text-secondary-rgb), 0.01);
}
.bank-card-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 16px;
}
.bank-logo-wrap {
width: 48px;
height: 48px;
border-radius: 10px;
background: var(--bg-elevated);
border: 1.5px solid var(--border);
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
padding: 6px;
box-shadow: 0 2px 8px rgba(0,0,0,0.02);
}
.bank-logo-img {
width: 100%;
height: 100%;
object-fit: contain;
}
.bank-logo-fallback {
font-size: 13px;
font-weight: 800;
color: var(--primary);
font-family: monospace;
letter-spacing: 0.5px;
}
.bank-status-tag {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 3px 8px;
border-radius: 6px;
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.02em;
}
.bank-status-tag.active {
background: rgba(16, 185, 129, 0.08);
color: #10b981;
border: 1px solid rgba(16, 185, 129, 0.15);
}
.bank-status-tag.active .tag-dot {
width: 5px;
height: 5px;
background: #10b981;
border-radius: 50%;
box-shadow: 0 0 8px #10b981;
}
.bank-status-tag.disabled {
background: rgba(239, 68, 68, 0.08);
color: #ef4444;
border: 1px solid rgba(239, 68, 68, 0.15);
}
.bank-status-tag.disabled .tag-dot {
width: 5px;
height: 5px;
background: #ef4444;
border-radius: 50%;
}
.bank-card-body {
flex-grow: 1;
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 16px;
}
.bank-code-row {
display: flex;
align-items: center;
gap: 8px;
}
.bank-code-label {
font-family: monospace;
font-size: 11px;
font-weight: 700;
color: var(--text-secondary);
background: var(--bg-elevated);
border: 1px solid var(--border);
padding: 2px 6px;
border-radius: 4px;
letter-spacing: 0.5px;
}
.bank-currency-chip {
font-family: monospace;
font-size: 11px;
font-weight: 700;
color: var(--primary);
background: rgba(var(--primary-rgb), 0.06);
padding: 2px 6px;
border-radius: 4px;
}
.bank-name {
font-size: 15px;
font-weight: 700;
color: var(--text-primary);
margin: 0;
line-height: 1.3;
}
.bank-timezone-info {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 12px;
color: var(--text-secondary);
opacity: 0.8;
}
.bank-timezone-info svg {
opacity: 0.7;
}
.bank-card-footer {
border-top: 1px solid var(--border);
padding-top: 12px;
display: flex;
justify-content: flex-end;
}
.btn-edit-bank {
background: none;
border: 1px solid var(--border);
color: var(--text-secondary);
padding: 5px 12px;
border-radius: 6px;
font-size: 12px;
font-weight: 600;
cursor: pointer;
display: inline-flex;
align-items: center;
gap: 6px;
transition: all 0.15s ease;
}
.btn-edit-bank:hover {
background: var(--bg-elevated);
color: var(--text-primary);
border-color: var(--text-secondary);
}
.banks-empty-state {
text-align: center;
padding: 48px 24px;
background: var(--bg-surface);
border: 1px dashed var(--border);
border-radius: 16px;
color: var(--text-secondary);
}
.banks-empty-state h4 {
margin: 16px 0 8px;
color: var(--text-primary);
font-weight: 700;
}
/* ── Modal & Image Overrides ────────────────────── */
.bank-modal-layout {
display: grid;
grid-template-columns: 180px minmax(0, 1fr);
gap: 16px;
align-items: start;
}
.bank-image-panel {
display: flex;
flex-direction: column;
gap: 8px;
}
.bank-image-frame {
width: 180px;
height: 180px;
border: 1px solid var(--border);
border-radius: 12px;
background: var(--bg-elevated);
overflow: hidden;
}
.bank-image-preview {
width: 100%;
height: 100%;
object-fit: contain;
background: #fff;
padding: 10px;
}
.bank-image-placeholder {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-secondary);
font-size: 12px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.6px;
}
.bank-image-help {
font-size: 11px;
color: var(--text-secondary);
line-height: 1.35;
}
.bank-form-panel {
min-width: 0;
}
.bank-image-textarea {
min-height: 72px;
resize: vertical;
}
.bank-image-counter {
font-size: 11px;
color: var(--text-secondary);
}
.bank-image-counter.near-limit {
color: #ef4444;
font-weight: 600;
}
.bank-image-meta-row {
margin-top: 4px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.bank-image-error-inline {
min-height: 18px;
}
.bank-image-error-inline .mo-error-inline {
margin: 0;
}
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\TechnicalConsole.razor
============================================================ */
/* ── Stats Dashboard Row ─────────────────────────── */
.stats-row {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 16px;
margin-bottom: 20px;
}
.stat-card {
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 12px;
padding: 16px;
display: flex;
align-items: center;
gap: 14px;
box-shadow: 0 4px 20px -2px rgba(0,0,0,0.02);
transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.stat-card:hover {
transform: translateY(-2px);
box-shadow: 0 6px 24px -4px rgba(0,0,0,0.06);
}
.stat-icon {
display: flex;
align-items: center;
justify-content: center;
width: 42px;
height: 42px;
border-radius: 10px;
}
.stat-icon.purple { background: rgba(139, 92, 246, 0.08); color: #8b5cf6; }
.stat-icon.red { background: rgba(239, 68, 68, 0.08); color: #ef4444; }
.stat-icon.green { background: rgba(16, 185, 129, 0.08); color: #10b981; }
.stat-icon.blue { background: rgba(59, 130, 246, 0.08); color: #3b82f6; }
.stat-info {
display: flex;
flex-direction: column;
gap: 2px;
}
.stat-label {
font-size: 12px;
color: var(--text-secondary);
font-weight: 500;
}
.stat-value {
font-size: 20px;
font-weight: 700;
color: var(--text-primary);
line-height: 1.2;
}
.terminal-card { background: #0F172A; border: none; padding: 0; overflow: hidden; height: 600px; display: flex; flex-direction: column; box-shadow: 0 20px 25px -5px rgba(0,0,0,0.3); }
.terminal-header { background: #1E293B; padding: 12px 20px; display: flex; align-items: center; justify-content: space-between; border-bottom: 1px solid #334155; }
.terminal-header .dots { display: flex; gap: 6px; }
.terminal-header .dot { width: 10px; height: 10px; border-radius: 50%; opacity: 0.8; }
.terminal-header .dot.r { background: #EF4444; }
.terminal-header .dot.y { background: #F59E0B; }
.terminal-header .dot.g { background: #10B981; }
.terminal-header .title { font-family: 'Fira Code', monospace; font-size: 11px; font-weight: 700; color: #94A3B8; letter-spacing: 0.1em; }
.status-wrap { display: flex; align-items: center; gap: 8px; font-size: 10px; font-weight: 800; color: #10B981; }
.pulse { width: 6px; height: 6px; background: #10B981; border-radius: 50%; box-shadow: 0 0 0 rgba(16,185,129,0.4); animation: pulse 2s infinite; }
@keyframes pulse { 0% { box-shadow: 0 0 0 0 rgba(16,185,129,0.7); } 70% { box-shadow: 0 0 0 10px rgba(16,185,129,0); } 100% { box-shadow: 0 0 0 0 rgba(16,185,129,0); } }
.terminal-body { flex: 1; padding: 20px; overflow-y: auto; font-family: 'Fira Code', 'Roboto Mono', monospace; font-size: 12px; line-height: 1.8; color: #E2E8F0; }
.log-line { margin-bottom: 4px; display: flex; gap: 12px; }
.log-line .ts { color: #64748B; flex-shrink: 0; }
.log-line .lvl { font-weight: 800; text-transform: uppercase; min-width: 50px; flex-shrink: 0; text-align: center; border-radius: 4px; font-size: 10px; padding: 0 6px; }
.log-line .lvl.info { color: #38BDF8; }
.log-line .lvl.success { color: #4ADE80; }
.log-line .lvl.warn { color: #FBBF24; }
.log-line .lvl.error { color: #F87171; }
.log-line .src { color: #94A3B8; flex-shrink: 0; }
.log-line .msg { word-break: break-all; }
.empty-log { color: #475569; font-style: italic; text-align: center; margin-top: 100px; font-size: 14px; }
.section-title { font-size: 11px; font-weight: 800; color: var(--text-muted); letter-spacing: 0.1em; margin-bottom: 20px; }
.health-grid { display: flex; flex-direction: column; gap: 16px; }
.health-item { display: flex; justify-content: space-between; align-items: center; }
.health-item .label { font-size: 12px; font-weight: 700; color: var(--text-secondary); }
.health-item .status-val { font-size: 12px; font-weight: 800; text-transform: uppercase; }
.health-item .status-val.success { color: #10B981; }
.health-item .status-val.warning { color: #F59E0B; }
.ctrl-btn { width: 100%; text-align: left; background: var(--bg-card); border: 1px solid var(--border); border-radius: 8px; padding: 12px 16px; font-size: 12px; font-weight: 700; color: var(--text-primary); transition: all 0.2s; }
.ctrl-btn:hover { background: rgba(30,41,59,0.03); transform: translateX(4px); }
.ctrl-btn.danger { color: #EF4444; border-color: rgba(239, 68, 68, 0.2); }
.ctrl-btn.danger:hover { background: rgba(239, 68, 68, 0.05); }
.warning-icon { width: 64px; height: 64px; line-height: 60px; font-size: 40px; font-weight: 900; background: rgba(239, 68, 68, 0.1); color: #EF4444; border-radius: 50%; display: inline-block; }
/* ============================================================
EXTRACTED FROM: Components\Pages\Admin\WhitelistIPs.razor
============================================================ */
.form-grid { display: flex; flex-direction: column; gap: 1rem; }
.alert-bo { display: flex; align-items: center; gap: 8px; padding: 10px 14px; border-radius: 8px; font-size: 12px; }
.alert-bo.danger { background: rgba(239, 68, 68, 0.05); border: 1px solid rgba(239, 68, 68, 0.15); color: #ef4444; }
/* ============================================================
EXTRACTED FROM: Components\Shared\AppToast.razor
============================================================ */
.app-toast-wrapper {
position: fixed;
top: 20px;
right: 24px;
z-index: 9999;
}
.app-toast {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 18px;
border-radius: 10px;
font-size: 13px;
min-width: 260px;
max-width: 380px;
box-shadow: 0 6px 24px rgba(0, 0, 0, .12);
animation: appToastIn .25s cubic-bezier(.21,1.02,.73,1) both;
}
.app-toast-ok { background: #D1FAE5; color: #065F46; border: 1px solid #6EE7B7; }
.app-toast-err { background: #FEE2E2; color: #991B1B; border: 1px solid #FCA5A5; }
.app-toast-icon {
width: 24px;
height: 24px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 12px;
font-weight: 700;
flex-shrink: 0;
}
.app-toast-ok .app-toast-icon { background: #065F46; color: #fff; }
.app-toast-err .app-toast-icon { background: #991B1B; color: #fff; }
.app-toast-body { display: flex; flex-direction: column; gap: 2px; }
.app-toast-title { font-weight: 700; font-size: 13px; }
.app-toast-msg { font-size: 12px; opacity: 0.85; }
@keyframes appToastIn {
from { opacity: 0; transform: translateX(40px) }
to   { opacity: 1; transform: none }
}
/* ============================================================
EXTRACTED FROM: Components\Shared\ConfirmActionModal.razor
============================================================ */
.cam-overlay {
position: fixed; inset: 0;
background: rgba(15, 23, 42, 0.4);
z-index: 2100;
backdrop-filter: blur(4px);
animation: camFadeIn 0.25s ease both;
}
@keyframes camFadeIn { from { opacity:0 } to { opacity:1 } }
.cam-box {
position: fixed;
top: 50%; left: 50%;
transform: translate(-50%,-50%);
width: 440px; max-width: calc(100vw - 32px);
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 20px;
box-shadow: 0 25px 50px -12px rgba(15, 23, 42, 0.15);
z-index: 2200;
padding: 28px;
display: flex; flex-direction: column; gap: 24px;
animation: camSlideIn 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) both;
/* Semantic colors for Light/Professional/Lavender */
--cam-warn: #D97706;
--cam-warn-bg: #FFFBEB;
--cam-info: #0284C7;
--cam-info-bg: #F0F9FF;
--cam-danger: #DC2626;
--cam-danger-bg: #FEF2F2;
}
body.theme-onyx .cam-box {
box-shadow: 0 25px 60px -12px rgba(0, 0, 0, 0.5);
border: 1px solid rgba(255, 255, 255, 0.08);
/* Semantic colors for Onyx (Dark) */
--cam-warn: #FBBF24;
--cam-warn-bg: rgba(217, 119, 6, 0.2);
--cam-info: #38BDF8;
--cam-info-bg: rgba(2, 132, 199, 0.2);
--cam-danger: #F87171;
--cam-danger-bg: rgba(220, 38, 38, 0.2);
}
@keyframes camSlideIn {
from { opacity:0; transform: translate(-50%,-45%) scale(0.9) }
to   { opacity:1; transform: translate(-50%,-50%) scale(1) }
}
.cam-header { display:flex; align-items:flex-start; gap:20px; }
.cam-icon {
width:48px; height:48px; border-radius:14px; flex-shrink:0;
display:flex; align-items:center; justify-content:center;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.05);
}
.cam-icon.warn   { background: var(--cam-warn-bg); color: var(--cam-warn); }
.cam-icon.info   { background: var(--cam-info-bg); color: var(--cam-info); }
.cam-icon.danger { background: var(--cam-danger-bg); color: var(--cam-danger); }
.cam-title {
font-size:18px; font-weight:800; color:var(--text-primary); margin-bottom:6px;
letter-spacing: -0.01em;
}
.cam-subtitle {
font-size:14px; color:var(--text-secondary); line-height:1.6;
white-space: pre-wrap; word-break: break-word;
opacity: 0.9;
}
.cam-reason { display:flex; flex-direction:column; gap:10px; }
.cam-reason-label {
font-size:11px; font-weight:800; text-transform:uppercase;
letter-spacing:.08em; color:var(--text-secondary);
opacity: 0.8;
}
.cam-reason-input {
border: 1.5px solid var(--border); border-radius:12px;
padding:14px; font-size:14px; color:var(--text-primary);
background: var(--bg-elevated); font-family:inherit;
resize:vertical; outline:none; transition: all .2s;
width:100%; box-sizing:border-box;
}
.cam-reason-input:focus {
border-color: var(--primary);
background: var(--bg-surface);
box-shadow: 0 0 0 4px var(--primary-glow);
}
.cam-reason-error { font-size:12px; color: #EF4444; font-weight: 600; margin-top: 4px; }
.cam-footer { display:flex; gap:12px; justify-content:flex-end; margin-top: 8px; }
.cam-btn-cancel {
padding:12px 24px; background: var(--bg-surface); color: var(--text-primary);
border: 1.5px solid var(--border); border-radius:12px;
font-size:14px; font-weight:700; cursor:pointer;
font-family:inherit; transition: all .2s;
}
.cam-btn-cancel:hover {
background: var(--bg-elevated);
border-color: var(--text-secondary);
transform: translateY(-1px);
}
.cam-btn-confirm {
padding:12px 28px;
background: var(--primary); color: #fff;
border:none; border-radius:12px;
font-size:14px; font-weight:800; cursor:pointer;
font-family:inherit; transition: all .2s;
display:inline-flex; align-items:center; gap:10px;
box-shadow: 0 10px 15px -3px var(--primary-glow);
}
.cam-btn-confirm:hover {
background: var(--primary-light);
transform: translateY(-2px);
box-shadow: 0 20px 25px -5px var(--primary-glow);
}
.cam-btn-confirm:active { transform: translateY(0); }
.cam-btn-confirm.danger {
background: #DC2626;
box-shadow: 0 10px 15px -3px rgba(220, 38, 38, 0.25);
}
.cam-btn-confirm.danger:hover {
background: #B91C1C;
box-shadow: 0 20px 25px -5px rgba(220, 38, 38, 0.35);
}
.cam-btn-confirm:disabled { opacity:.6; cursor:not-allowed; transform: none !important; box-shadow: none !important; }
.cam-spinner {
width:18px; height:18px;
border:2.5px solid rgba(255,255,255,.3);
border-top-color:#fff;
border-radius:50%;
animation:spin .8s linear infinite;
}
@keyframes spin { to { transform:rotate(360deg) } }
/* ============================================================
EXTRACTED FROM: Components\Shared\P2PConfirmModal.razor
============================================================ */
.confirm-overlay {
position: fixed; top: 0; left: 0; width: 100%; height: 100%;
background: rgba(15, 23, 42, 0.4); backdrop-filter: blur(4px);
z-index: 2000; opacity: 0; pointer-events: none; transition: opacity 0.3s ease;
}
.confirm-overlay.show { opacity: 1; pointer-events: auto; }
.confirm-modal {
position: fixed; top: 50%; left: 50%; transform: translate(-50%, -45%) scale(0.95);
width: 400px; max-width: calc(100vw - 32px); background: #fff;
border-radius: 20px; padding: 32px; z-index: 2001;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
opacity: 0; pointer-events: none; transition: all 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
text-align: center;
}
.confirm-modal.show { opacity: 1; pointer-events: auto; transform: translate(-50%, -50%) scale(1); }
.confirm-icon-blob {
width: 64px; height: 64px; border-radius: 50%; margin: 0 auto 24px;
display: flex; align-items: center; justify-content: center;
}
.danger-mode .confirm-icon-blob { background: #FEE2E2; color: #EF4444; }
.info-mode .confirm-icon-blob { background: #E0F2FE; color: #0EA5E9; }
.confirm-title { font-size: 20px; font-weight: 800; color: #0F172A; margin-bottom: 12px; }
.confirm-text { font-size: 14px; color: #64748B; line-height: 1.6; margin-bottom: 32px; }
.confirm-footer { display: flex; gap: 12px; }
.confirm-footer button {
flex: 1; padding: 12px; border-radius: 12px; font-size: 14px; font-weight: 700;
cursor: pointer; transition: all 0.2s; border: none;
}
.btn-cancel { background: #F1F5F9; color: #475569; }
.btn-cancel:hover { background: #E2E8F0; }
.danger-mode .btn-confirm { background: #EF4444; color: #fff; }
.danger-mode .btn-confirm:hover { background: #DC2626; box-shadow: 0 4px 12px rgba(239, 68, 68, 0.3); }
.info-mode .btn-confirm { background: #0EA5E9; color: #fff; }
.info-mode .btn-confirm:hover { background: #0284C7; box-shadow: 0 4px 12px rgba(14, 165, 233, 0.3); }
/* ============================================================
EXTRACTED FROM: Components\Shared\P2PModal.razor
============================================================ */
.bo-modal-overlay {
display: none;
position: fixed;
inset: 0;
background: rgba(15, 23, 42, 0.30);
z-index: 1200;
backdrop-filter: blur(2px);
animation: boFadeIn 0.2s ease both;
}
.bo-modal-overlay.open { display: block; }
@keyframes boFadeIn { from { opacity: 0; } to { opacity: 1; } }
.bo-modal {
position: fixed;
top: 50%;
left: 50%;
width: 560px;
max-width: calc(100vw - 32px);
max-height: 90vh;
background: var(--bg-surface);
color: var(--text-primary);
z-index: 1300;
display: flex;
flex-direction: column;
border-radius: 12px;
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.2);
border: 1px solid var(--border);
transform: translate(-50%, -50%) scale(0.95);
opacity: 0;
pointer-events: none;
transition: transform 0.22s cubic-bezier(0.16, 1, 0.3, 1), opacity 0.2s ease;
}
.bo-modal.open {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
pointer-events: auto;
}
.bo-modal-header {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20px 24px 16px;
border-bottom: 1px solid var(--border);
flex-shrink: 0;
}
.bo-modal-title {
font-size: 15px;
font-weight: 700;
color: var(--text-primary);
}
.bo-modal-close {
width: 34px;
height: 34px;
border: none;
background: var(--bg-elevated);
border-radius: 8px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
color: var(--text-secondary);
transition: background 0.15s, color 0.15s;
}
.bo-modal-close:hover { background: var(--bg-surface); color: var(--text-primary); }
.bo-modal-body {
flex: 1;
color: inherit;
overflow-y: auto;
padding: 24px;
display: flex;
flex-direction: column;
gap: 20px;
}
.bo-modal-footer {
padding: 14px 24px 20px;
border-top: 1px solid var(--border);
display: flex;
gap: 10px;
justify-content: flex-end;
flex-shrink: 0;
}
/* ── Form fields inside modal ── */
.mo-field { display: flex; flex-direction: column; gap: 6px; }
.mo-label {
font-size: 11px;
font-weight: 700;
color: var(--text-muted);
letter-spacing: 0.06em;
text-transform: uppercase;
}
.mo-req { color: var(--danger); }
.mo-input {
border: none;
border-bottom: 1.5px solid var(--border);
outline: none;
padding: 8px 0;
font-size: 13.5px;
color: inherit;
background: transparent;
font-family: inherit;
transition: border-color 0.15s;
width: 100%;
}
.mo-input::placeholder { color: var(--text-muted); }
.mo-input:focus { border-bottom-color: var(--primary); }
.mo-input.error { border-bottom-color: var(--danger); }
.mo-textarea {
border: 1px solid var(--border);
border-radius: 6px;
outline: none;
padding: 10px 12px;
font-size: 13px;
color: inherit;
background: var(--bg-elevated);
font-family: 'Fira Code', 'Courier New', monospace;
resize: vertical;
transition: border-color 0.15s;
width: 100%;
box-sizing: border-box;
line-height: 1.5;
}
.mo-textarea::placeholder { color: var(--text-muted); }
.mo-textarea:focus { border-color: var(--primary); background: var(--bg-surface); }
.mo-select-wrap { position: relative; }
.mo-select {
width: 100%;
border: none;
border-bottom: 1.5px solid var(--border);
outline: none;
padding: 8px 28px 8px 0;
font-size: 13.5px;
color: inherit;
background: transparent;
font-family: inherit;
cursor: pointer;
appearance: none;
transition: border-color 0.15s;
}
.mo-select option {
background: var(--bg-surface);
color: var(--text-primary);
}
.mo-select:focus { border-bottom-color: var(--primary); }
.mo-select-chevron {
position: absolute; right: 2px; top: 50%;
transform: translateY(-50%);
color: var(--text-muted); pointer-events: none;
}
.mo-check-label {
display: flex; align-items: center; gap: 10px;
cursor: pointer; font-size: 13.5px; color: var(--text-secondary); user-select: none;
}
.mo-check-label input[type="checkbox"] { display: none; }
.mo-check-box {
width: 18px; height: 18px;
border: 2px solid var(--border); border-radius: 4px;
display: flex; align-items: center; justify-content: center;
flex-shrink: 0;
transition: background 0.15s, border-color 0.15s;
background: transparent;
}
.mo-check-label input:checked + .mo-check-box { background: var(--primary); border-color: var(--primary); }
.mo-check-label input:checked + .mo-check-box::after {
content: ''; width: 5px; height: 9px;
border: 2px solid #fff; border-top: none; border-left: none;
transform: rotate(45deg) translateY(-1px);
}
.mo-two-col { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 20px; }
.mo-apikey-row { display: flex; align-items: center; gap: 10px; }
.mo-apikey-input { flex: 1; font-family: 'Fira Code', 'Courier New', monospace; font-size: 12.5px; letter-spacing: 0.04em; color: inherit; }
.mo-btn-generate {
flex-shrink: 0; display: flex; align-items: center; gap: 6px;
padding: 7px 14px;
background: var(--primary);
color: #FFFFFF; border: none; border-radius: 7px;
font-size: 11px; font-weight: 700; cursor: pointer;
font-family: inherit; white-space: nowrap;
box-shadow: 0 2px 8px var(--primary-glow);
transition: opacity 0.15s, transform 0.1s;
text-transform: uppercase;
letter-spacing: 0.02em;
}
.mo-btn-generate:hover { opacity: 0.9; }
.mo-btn-generate:active { transform: scale(0.96); }
.mo-error {
display: flex; align-items: center; gap: 8px;
padding: 10px 14px; border-radius: 8px; font-size: 12px;
background: rgba(239, 68, 68, 0.05);
border: 1px solid rgba(239, 68, 68, 0.15);
color: var(--danger);
}
.mo-error-inline {
margin-top: 4px; font-size: 12px; color: var(--danger);
}
/* btn-cancel / btn-save inside modal footer */
.mo-btn-cancel {
padding: 9px 20px; background: transparent; color: var(--text-secondary);
border: 1.5px solid var(--border); border-radius: 7px;
font-size: 13px; font-weight: 600; cursor: pointer;
font-family: inherit; transition: background 0.15s, border-color 0.15s;
}
.mo-btn-cancel:hover { background: var(--bg-elevated); border-color: var(--text-muted); }
.mo-btn-save {
padding: 9px 28px;
background: var(--primary); color: #FFFFFF;
border: none; border-radius: 7px;
font-size: 13px; font-weight: 700; cursor: pointer;
font-family: inherit; transition: opacity 0.15s, transform 0.1s;
box-shadow: 0 4px 12px var(--primary-glow);
}
.mo-btn-save:hover { opacity: 0.9; }
.mo-btn-save:active { transform: scale(0.97); }
.mo-btn-save:disabled { opacity: 0.6; cursor: not-allowed; }
/* ============================================================
EXTRACTED FROM: Components\Shared\P2PPagination.razor
============================================================ */
.p2p-pagination {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding-left:10px;
padding-top: 5px;
flex-wrap: wrap;
padding-bottom: 5px;
}
/* Left */
.p2p-pag-left {
display: flex;
align-items: center;
gap: 8px;
}
.p2p-pag-text {
font-size: 12px;
color: var(--text-muted, #94A3B8);
white-space: nowrap;
}
.p2p-pag-text strong { color: #374151; }
.p2p-pag-size-wrap {
position: relative;
display: inline-flex;
align-items: center;
}
.p2p-pag-size-select {
appearance: none;
border: 1.5px solid #E2E8F0;
border-radius: 7px;
padding: 4px 24px 4px 10px;
font-size: 12px;
font-weight: 600;
color: #374151;
background: #FFFFFF;
font-family: inherit;
cursor: pointer;
outline: none;
transition: border-color 0.15s;
}
.p2p-pag-size-select:focus { border-color: #BEA0E2; }
.p2p-pag-chevron {
position: absolute;
right: 6px;
color: #94A3B8;
pointer-events: none;
}
/* Right */
.p2p-pag-controls {
display: flex;
align-items: center;
gap: 4px;
}
.p2p-pag-btn {
min-width: 32px;
height: 32px;
padding: 0 8px;
border: 1.5px solid var(--border);
border-radius: 7px;
background: var(--bg-surface);
color: var(--text-primary);
font-size: 12px;
font-weight: 600;
font-family: inherit;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s, border-color 0.15s, color 0.15s;
}
.p2p-pag-btn:hover:not(:disabled) { background: var(--bg-surface); border-color: var(--border); }
.p2p-pag-btn.active { background: var(--primary-light); border-color: var(--border); color: var(--text-primary); }
.p2p-pag-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.p2p-pag-ellipsis { font-size: 13px; color: var(--text-primary); padding: 0 4px; }
/* ============================================================
EXTRACTED FROM: Components\Shared\TransactionCallbackActions.razor
============================================================ */
.action-menu-item-danger {
color: #DC2626 !important;
}
.action-menu-item-danger:hover {
background: #FEF2F2 !important;
}
.mo-btn-action {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 16px;
background: #0D9488;
color: #fff;
border: none;
border-radius: 7px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
transition: background 0.15s;
}
.mo-btn-action:hover {
background: #0f766e;
}
.mo-btn-action:disabled {
opacity: 0.6;
cursor: not-allowed;
}
.mo-btn-danger {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 8px 16px;
background: #EF4444;
color: #fff;
border: none;
border-radius: 7px;
font-size: 13px;
font-weight: 600;
cursor: pointer;
font-family: inherit;
transition: background 0.15s;
}
.mo-btn-danger:hover {
background: #DC2626;
}
/* ============================================================
EXTRACTED FROM: Components\Shared\Filters\FilterDateInput.razor
============================================================ */
.ff-req { color: var(--danger, #EF4444); margin-left: 2px; }
/* ============================================================
EXTRACTED FROM: Components\Shared\Filters\FilterInput.razor
============================================================ */
.ff-req {
color: var(--danger, #EF4444);
margin-left: 2px;
}
/* ============================================================
EXTRACTED FROM: Components\Shared\Filters\FilterSelect.razor
============================================================ */
.select-custom {
min-height: 32px;
height: 32px;
}
/* ============================================================
EXTRACTED FROM: Components\Shared\Filters\IanaTimezoneFilterSelect.razor
============================================================ */
.tz-select-wrap {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--bg-card, #fff);
border: 1px solid var(--border, #E2E8F0);
border-radius: 6px;
padding: 0 8px;
height: 34px;
transition: border-color 0.2s;
}
.tz-select-wrap:hover {
border-color: var(--primary, #7C3AED);
}
.tz-select {
border: none;
background: transparent;
color: var(--text-secondary, #64748B);
outline: none;
cursor: pointer;
font-size: 13px;
padding-right: 4px;
}
/* ============================================================
EXTRACTED FROM: Components\Shared\Filters\MultipleFilterPartnerTrees.razor
============================================================ */
.ptt-root { position: relative; }
.ptt-btn {
display: flex;
align-items: center;
justify-content: space-between;
width: 100%;
cursor: pointer;
background: var(--bg-surface);
text-align: left;
gap: 8px;
padding: 4px 10px !important;
border: 1px solid var(--border) !important;
border-radius: 6px !important;
transition: all 0.2s ease;
height: 32px !important;
min-height: 32px !important;
box-sizing: border-box;
}
.ptt-btn:hover {
border-color: var(--primary) !important;
box-shadow: 0 0 0 3px rgba(var(--primary-rgb), 0.12) !important;
}
.ptt-btn-text {
flex: 1;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 13px;
color: var(--text-primary, #1E293B);
}
.ptt-chevron {
width: 10px;
height: 7px;
flex-shrink: 0;
transition: transform .15s;
color: var(--text-secondary);
}
.ptt-chevron.open { transform: rotate(180deg); }
.ptt-dropdown {
position: absolute;
top: calc(100% + 4px);
left: 0;
min-width: 240px;
max-height: 300px;
overflow-y: auto;
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 8px;
box-shadow: var(--shadow-lg);
z-index: 500;
padding: 4px 0;
backdrop-filter: blur(10px);
}
.ptt-item {
display: flex;
align-items: center;
gap: 8px;
color: var(--text-primary);
padding: 6px 10px;
cursor: pointer;
font-size: 13px;
user-select: none;
transition: background .1s;
}
.ptt-item:hover { background: #F8FAFC; }
.ptt-parent { font-weight: 500; }
/* Expand/collapse arrow */
.ptt-expand {
width: 16px;
height: 16px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
cursor: pointer;
color: var(--text-secondary);
transition: transform .15s, background .1s;
}
.ptt-expand:hover { background: var(--bg-elevated); color: var(--primary); }
.ptt-expand svg {
width: 7px;
height: 10px;
transition: transform .15s;
}
/* When expanded: rotate arrow 90° to become ▼ */
.ptt-expand-open svg { transform: rotate(90deg); }
/* Spacer for nodes without children (for alignment) */
.ptt-expand-spacer {
width: 16px;
height: 16px;
flex-shrink: 0;
}
.ptt-cb {
width: 16px;
height: 16px;
border: 1.5px solid var(--border);
border-radius: 3px;
flex-shrink: 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 11px;
font-weight: 700;
color: #fff;
background: transparent;
transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
}
.ptt-cb.checked {
background: var(--primary);
border-color: var(--primary);
color: #fff;
box-shadow: 0 2px 4px rgba(0, 153, 153, 0.2);
}
.ptt-cb.partial {
background: rgba(0, 153, 153, 0.15);
border-color: var(--primary);
color: var(--primary);
}
.ptt-label { flex: 1; }
.ptt-name { color: var(--text-secondary); font-weight: 400; font-size: 0.9em; margin-left: 4px; }
.filter-input.ptt-btn {
background: var(--bg-surface);
color: var(--text-primary);
border: 1px solid var(--border);
}
/* ============================================================
EXTRACTED FROM: Components\Shared\Filters\TimezoneFilterSelect.razor
============================================================ */
.tz-select-wrap {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--bg-card, #fff);
border: 1px solid var(--border, #E2E8F0);
border-radius: 6px;
padding: 0 8px;
height: 34px;
transition: border-color 0.2s;
}
.tz-select-wrap:hover {
border-color: var(--primary, #7C3AED);
}
.tz-select {
border: none;
background: transparent;
color: var(--text-secondary, #64748B);
outline: none;
cursor: pointer;
font-size: 13px;
padding-right: 4px;
}
/* ============================================================
UNIFIED THEME SYSTEM
============================================================ */
:root {
--primary: #0f766e;
--primary-rgb: 15, 118, 110;
--primary-light: #5eead4;
--primary-dim: rgba(15, 118, 110, 0.12);
--primary-glow: rgba(15, 118, 110, 0.20);
--primary-gradient: linear-gradient(135deg, #0f766e 0%, #14b8a6 100%);
--accent: #14b8a6;
--accent-rgb: 20, 184, 166;
--bg-base: #f5f7fa;
--bg-surface: #ffffff;
--bg-surface-rgb: 255, 255, 255;
--bg-elevated: #f8fafc;
--bg-elevated-rgb: 248, 250, 252;
--border: #e3e8ef;
--text-primary: #0f172a;
--text-secondary: #475569;
--text-muted: #64748b;
/* Status Colors */
--success: #059669;
--success-dim: rgba(5, 150, 105, 0.10);
--warning: #d97706;
--warning-dim: rgba(217, 119, 6, 0.10);
--danger: #dc2626;
--danger-dim: rgba(220, 38, 38, 0.10);
--info: #0284c7;
--info-dim: rgba(2, 132, 199, 0.10);
--accent-dim: rgba(20, 184, 166, 0.10);
/* UI Fallbacks */
--bg-card: #ffffff;
--bg-header: rgba(255, 255, 255, 0.82);
--bg-sidebar: rgba(255, 255, 255, 0.88);
--shell-shadow: 0 22px 60px rgba(15, 23, 42, 0.08);
--shell-shadow-strong: 0 24px 48px rgba(15, 23, 42, 0.12);
}
/* ── Professional (Light) — Primary Brand Color ───────────────── */
body.theme-professional {
--primary: #0f766e;
--primary-rgb: 15, 118, 110;
--primary-light: #67e8f9;
--primary-dim: rgba(15, 118, 110, 0.10);
--primary-glow: rgba(15, 118, 110, 0.18);
--primary-gradient: linear-gradient(135deg, #0f766e 0%, #14b8a6 100%);
--accent: #14b8a6;
--accent-rgb: 20, 184, 166;
--bg-base: #f5f7fa;
--bg-surface: #ffffff;
--bg-surface-rgb: 255, 255, 255;
--bg-elevated: #f8fafc;
--bg-elevated-rgb: 248, 250, 252;
--bg-card: #ffffff;
--border: #e3e8ef;
--text-primary: #0f172a;
--text-secondary: #475569;
--text-muted: #64748b;
--accent-dim: rgba(20, 184, 166, 0.10);
--calendar-filter: none;
}
/* ── Onyx (Deep Slate) ─────────────────── */
body.theme-onyx {
--primary: #38bdf8;
--primary-rgb: 56, 189, 248;
--primary-light: #7dd3fc;
--primary-dim: rgba(56, 189, 248, 0.14);
--primary-glow: rgba(56, 189, 248, 0.25);
--primary-gradient: linear-gradient(135deg, #0ea5e9 0%, #38bdf8 100%);
--accent: #22d3ee;
--accent-rgb: 34, 211, 238;
--accent-dim: rgba(34, 211, 238, 0.14);
--bg-base: #07111f;
--bg-surface: #0f172a;
--bg-surface-rgb: 15, 23, 42;
--bg-elevated: #111b2f;
--bg-elevated-rgb: 17, 27, 47;
--bg-card: #0f172a;
--border: #243248;
--text-primary: #f8fafc;
--text-secondary: #94a3b8;
--text-muted: #64748b;
/* Status Colors Onyx (Vibrant) */
--success: #22c55e;
--success-dim: rgba(34, 197, 94, 0.14);
--warning: #fbbf24;
--warning-dim: rgba(251, 191, 36, 0.14);
--danger: #f87171;
--danger-dim: rgba(248, 113, 113, 0.14);
--info: #38bdf8;
--info-dim: rgba(56, 189, 248, 0.14);
--calendar-filter: invert(1);
}
/* ── Lavender Original (Heritage) ───────────────── */
body.theme-lavender {
--primary: #7c3aed;
--primary-rgb: 124, 58, 237;
--primary-light: #c4b5fd;
--primary-dim: rgba(124, 58, 237, 0.12);
--primary-glow: rgba(124, 58, 237, 0.20);
--primary-gradient: linear-gradient(135deg, #7c3aed 0%, #8b5cf6 100%);
--accent: #8b5cf6;
--accent-rgb: 139, 92, 246;
--bg-base: #f7f7fb;
--bg-surface: #ffffff;
--bg-surface-rgb: 255, 255, 255;
--bg-elevated: #f4f0ff;
--bg-elevated-rgb: 244, 240, 255;
--bg-card: #ffffff;
--border: #e4def8;
--text-primary: #1f2937;
--text-secondary: #5b21b6;
--text-muted: #7c3aed;
/* Status Colors Lavender */
--success: #10b981;
--success-dim: rgba(16, 185, 129, 0.12);
--warning: #f59e0b;
--warning-dim: rgba(245, 158, 11, 0.12);
--danger: #ef4444;
--danger-dim: rgba(239, 68, 68, 0.12);
--info: #818cf8;
--info-dim: rgba(129, 140, 248, 0.12);
--accent-dim: rgba(124, 58, 237, 0.12);
--calendar-filter: none;
}
/* ── Cross-File Variable Mapping ─────────────────────────── */
body {
--p2p-bg: var(--bg-base);
--p2p-header-bg: var(--bg-surface);
--p2p-card-bg: var(--bg-surface);
--p2p-card-border: var(--border);
--p2p-text-primary: var(--text-primary);
--p2p-text-secondary: var(--text-secondary);
--p2p-accent: var(--primary);
--p2p-accent-light: var(--primary-dim);
background-color: var(--bg-base);
color: var(--text-primary);
transition: background-color 0.25s ease, color 0.15s ease;
/* Semantic Bridges */
--bg-sidebar: var(--bg-surface);
--sidebar-text: var(--text-secondary);
--sidebar-text-muted: var(--text-secondary);
--sidebar-active-bg: var(--primary-dim);
--sidebar-active-text: var(--primary);
--bg-header: var(--bg-surface);
--header-text: var(--text-primary);
--table-header-bg: var(--bg-elevated);
--table-header-text: var(--text-secondary);
--bg-main: var(--bg-base);
/* MudBlazor Bridge */
--mud-palette-primary: var(--primary);
--mud-palette-background: var(--bg-base);
--mud-palette-surface: var(--bg-surface);
--mud-palette-text-primary: var(--text-primary);
--mud-palette-text-secondary: var(--text-secondary);
--mud-palette-lines-default: var(--border);
--mud-palette-divider: var(--border);
--mud-palette-appbar-background: var(--bg-header);
--mud-palette-drawer-background: var(--bg-sidebar);
--mud-palette-drawer-text: var(--text-secondary);
--mud-palette-success: var(--success);
--mud-palette-warning: var(--warning);
--mud-palette-error: var(--danger);
--mud-palette-info: var(--info);
}
/* P2P Design System — Modern SaaS (Fintech style)
Light indigo/purple, very large radius, generous whitespace */
/* Inter font loads from self-hosted lib/fonts/fonts.css in App.razor (this file is unused but kept). */
:root {
--p2p-bg: var(--bg-base);
--p2p-indigo-50: var(--primary-dim);
--p2p-indigo-100: var(--primary-glow);
--p2p-indigo-200: var(--primary-light);
--p2p-indigo-400: var(--primary-light);
--p2p-indigo-500: var(--primary);
--p2p-indigo-600: var(--primary);
--p2p-indigo-700: var(--primary);
--p2p-purple-500: var(--accent);
--p2p-slate-50: var(--bg-elevated);
--p2p-slate-100: var(--border);
--p2p-slate-200: var(--border);
--p2p-slate-400: var(--text-muted);
--p2p-slate-500: var(--text-secondary);
--p2p-slate-800: var(--text-primary);
--p2p-slate-900: var(--bg-surface);
--p2p-radius-sm: 0.25rem;
--p2p-radius: 0.5rem;
--p2p-radius-lg: 0.75rem;
--p2p-radius-xl: 1rem;
--p2p-radius-2xl: 1.25rem;
--p2p-shadow-card: 0 4px 20px rgba(0,0,0,0.03);
--p2p-shadow-indigo: 0 8px 24px var(--primary-glow);
}
*, *::before, *::after { box-sizing: border-box; }
html, body {
margin: 0;
padding: 0;
height: 100%;
}
body {
font-family: 'Inter', sans-serif;
background: var(--p2p-bg);
color: var(--p2p-slate-800);
overflow-x: hidden;
}
/* ── Cards ── */
.p2p-card {
background: white;
border-radius: var(--p2p-radius-lg);
border: 1px solid var(--p2p-slate-100);
box-shadow: var(--p2p-shadow-card);
overflow: hidden;
}
.p2p-card-header {
padding: 1.5rem 2rem;
border-bottom: 1px solid var(--p2p-slate-50);
background: rgba(255,255,255,0.6);
display: flex;
justify-content: space-between;
align-items: center;
}
.p2p-card-title {
font-size: clamp(11px, 0.2vw + 11px, 13px);
font-weight: 700;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.p2p-card-body {
padding: 2rem;
}
/* ── Stat Cards ── */
.p2p-stat {
background: white;
padding: 2rem;
border-radius: var(--p2p-radius-lg);
border: 1px solid var(--p2p-slate-50);
border-left-width: 6px;
box-shadow: var(--p2p-shadow-card);
}
.p2p-stat.primary { border-left-color: var(--p2p-indigo-600); }
.p2p-stat.success { border-left-color: #10b981; }
.p2p-stat.error   { border-left-color: #f43f5e; }
.p2p-stat.warning { border-left-color: #f59e0b; }
.p2p-stat.info    { border-left-color: #06b6d4; }
.p2p-stat.slate   { border-left-color: var(--p2p-slate-400); }
.p2p-stat-label {
font-size: clamp(11px, 0.2vw + 11px, 12px);
font-weight: 700;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.p2p-stat-value {
font-size: clamp(1.5rem, 2vw + 1rem, 2.5rem);
font-weight: 800;
color: var(--text-primary);
line-height: 1;
margin-top: 1rem;
letter-spacing: -0.04em;
}
.p2p-stat-sub {
font-size: 10px;
color: var(--p2p-slate-400);
font-weight: 700;
font-style: italic;
margin-top: 0.75rem;
}
.p2p-stat-icon {
width: 3rem;
height: 3rem;
border-radius: var(--p2p-radius);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.06);
}
.p2p-stat-icon.primary { background: var(--p2p-indigo-50); color: var(--p2p-indigo-600); }
.p2p-stat-icon.success { background: #ecfdf5; color: #059669; }
.p2p-stat-icon.warning { background: #fffbeb; color: #d97706; }
.p2p-stat-icon.info { background: #ecfeff; color: #0891b2; }
.p2p-stat-icon.error { background: #fef2f2; color: #dc2626; }
.p2p-stat-top {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 1.25rem;
}
.p2p-card-icon {
width: 2.75rem;
height: 2.75rem;
border-radius: var(--p2p-radius);
background: var(--p2p-indigo-50);
color: var(--p2p-indigo-600);
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.04);
}
.p2p-breadcrumb {
display: flex;
align-items: center;
gap: 0.5rem;
font-size: 10px;
font-weight: 900;
color: var(--p2p-slate-400);
text-transform: uppercase;
letter-spacing: 0.15em;
}
.p2p-breadcrumb-current { color: var(--p2p-slate-500); }
.p2p-user-box {
display: flex;
align-items: center;
gap: 1rem;
padding: 1rem 1.25rem;
background: var(--p2p-slate-50);
border-radius: var(--p2p-radius);
border: 1px solid var(--p2p-slate-100);
box-shadow: inset 0 1px 2px rgba(0,0,0,0.02);
}
.p2p-user-avatar {
width: 3rem;
height: 3rem;
border-radius: var(--p2p-radius);
background: var(--p2p-indigo-600);
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: 900;
font-size: 11px;
flex-shrink: 0;
}
.p2p-logout-btn {
display: inline-flex;
align-items: center;
gap: 0.5rem;
padding: 0.875rem 1.5rem;
background: #fef2f2;
color: #dc2626;
border: 2px solid #fecaca;
border-radius: var(--p2p-radius);
font-size: 10px;
font-weight: 900;
text-transform: uppercase;
letter-spacing: 0.1em;
text-decoration: none;
transition: all 0.2s;
cursor: pointer;
}
.p2p-logout-btn:hover { background: #dc2626; color: white; border-color: #dc2626; }
.p2p-pool-card {
padding: 2rem 1.75rem;
border-radius: var(--p2p-radius-2xl);
border: 2px solid var(--p2p-slate-100);
background: white;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
}
.p2p-pool-card:hover { box-shadow: 0 20px 40px -10px rgba(0,0,0,0.08); }
.p2p-pool-card.selected {
background: var(--p2p-indigo-600);
border-color: var(--p2p-indigo-600);
color: white;
box-shadow: var(--p2p-shadow-indigo);
}
.p2p-pool-card-icon {
width: 4rem;
height: 4rem;
border-radius: var(--p2p-radius);
background: var(--p2p-slate-50);
color: var(--p2p-indigo-600);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1.5rem;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.04);
}
.p2p-pool-card.selected .p2p-pool-card-icon {
background: rgba(255,255,255,0.2);
color: white;
}
.p2p-trend-up {
font-size: 10px;
font-weight: 900;
padding: 0.25rem 0.5rem;
border-radius: var(--p2p-radius-sm);
border: 1px solid #a7f3d0;
background: #ecfdf5;
color: #059669;
}
.p2p-trend-down {
font-size: 10px;
font-weight: 900;
padding: 0.25rem 0.5rem;
border-radius: var(--p2p-radius-sm);
border: 1px solid #fecaca;
background: #fef2f2;
color: #dc2626;
}
/* ── Status Chips ── */
.p2p-chip {
display: inline-flex;
align-items: center;
padding: 0.35rem 0.75rem;
border-radius: 9999px;
font-size: 10px;
font-weight: 900;
text-transform: uppercase;
border: 1px solid;
letter-spacing: 0.08em;
}
.p2p-chip.Pending      { background:#f1f5f9; color:#475569; border-color:#e2e8f0; }
.p2p-chip.Matched      { background:var(--p2p-indigo-50); color:var(--p2p-indigo-600); border-color:var(--p2p-indigo-200); }
.p2p-chip.Processing   { background:#ecfeff; color:#0891b2; border-color:#a5f3fc; }
.p2p-chip.Completed    { background:#ecfdf5; color:#059669; border-color:#a7f3d0; }
.p2p-chip.Failed       { background:#fef2f2; color:#dc2626; border-color:#fecaca; }
.p2p-chip.Investigation{ background:#fff7ed; color:#ea580c; border-color:#fed7aa; }
.p2p-chip.Expired      { background:#334155; color:white; border-color:#475569; }
.p2p-chip.Cancelled    { background:#94a3b8; color:white; border-color:#94a3b8; }
.p2p-chip.WaitingOtp   { background:#faf5ff; color:#7c3aed; border-color:#ddd6fe; }
/* ── Buttons ── */
.p2p-btn {
padding: 0.875rem 1.75rem;
border-radius: var(--p2p-radius);
font-size: 10px;
font-weight: 900;
text-transform: uppercase;
letter-spacing: 0.12em;
border: none;
cursor: pointer;
transition: all 0.2s;
display: inline-flex;
align-items: center;
gap: 0.5rem;
text-decoration: none;
}
.p2p-btn:active { transform: scale(0.97); }
.p2p-btn-primary {
background: var(--p2p-indigo-600);
color: white;
box-shadow: var(--p2p-shadow-indigo);
}
.p2p-btn-primary:hover { background: var(--p2p-indigo-700); color: white; }
.p2p-btn-dark {
background: var(--p2p-slate-900);
color: white;
box-shadow: 0 10px 25px -5px rgba(0,0,0,0.15);
}
.p2p-btn-dark:hover { background: #020617; color: white; }
.p2p-btn-ghost {
background: white;
color: var(--p2p-slate-500);
border: 1px solid var(--p2p-slate-100);
box-shadow: 0 1px 3px rgba(0,0,0,0.04);
border-radius: var(--p2p-radius);
}
.p2p-btn-ghost:hover { background: var(--p2p-slate-50); color: var(--p2p-slate-800); }
.p2p-btn-danger { background: #ef4444; color: white; }
.p2p-btn-danger:hover { background: #dc2626; color: white; }
/* ── Tables ── */
.p2p-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.p2p-table thead th {
padding: clamp(8px, 1.2vw + 4px, 16px) 1.5rem;
font-size: clamp(10px, 0.5vw + 7px, 13px);
font-weight: 800;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.15em;
background: var(--bg-elevated);
border-bottom: 1px solid var(--border);
}
.p2p-table thead tr:first-child th:first-child { border-radius: var(--p2p-radius) 0 0 0; }
.p2p-table thead tr:first-child th:last-child { border-radius: 0 var(--p2p-radius) 0 0; }
.p2p-table tbody tr {
border-bottom: 1px solid var(--p2p-slate-50);
transition: background 0.2s;
}
.p2p-table tbody tr:hover { background: var(--p2p-indigo-50); }
.p2p-table tbody td { padding: clamp(8px, 1vw + 4px, 16px) 1.5rem; font-weight: 500; color: var(--text-secondary); }
.p2p-table .col-id { font-family: monospace; color: var(--text-muted); font-size: clamp(9px, 0.4vw + 7px, 11px); }
.p2p-table .col-amount { font-weight: 800; font-size: clamp(11px, 0.6vw + 8px, 15px); color: var(--text-primary); letter-spacing: -0.01em; }
/* ── Forms ── */
.p2p-input {
width: 100%;
padding: 1rem 1.25rem;
background: var(--p2p-slate-50);
border: 2px solid transparent;
border-radius: var(--p2p-radius);
font-weight: 700;
color: var(--p2p-slate-800);
font-size: 14px;
outline: none;
transition: all 0.2s;
box-shadow: inset 0 2px 4px rgba(0,0,0,0.02);
}
.p2p-input:focus {
background: white;
border-color: var(--p2p-indigo-500);
box-shadow: 0 0 0 4px rgba(99,102,241,0.1);
}
.p2p-label {
font-size: 10px;
font-weight: 900;
color: var(--p2p-slate-400);
text-transform: uppercase;
letter-spacing: 0.2em;
display: block;
margin-bottom: 0.5rem;
}
.p2p-select {
width: 100%;
padding: 1rem 1.25rem;
background: var(--p2p-slate-50);
border: 2px solid transparent;
border-radius: var(--p2p-radius);
font-weight: 700;
color: var(--p2p-slate-800);
font-size: 14px;
outline: none;
cursor: pointer;
}
.p2p-select:focus { background: white; border-color: var(--p2p-indigo-500); }
/* ── Filter Bar ── */
.p2p-filter {
padding: 1.5rem 2rem;
border-bottom: 1px solid var(--p2p-slate-50);
background: rgba(255,255,255,0.5);
display: flex;
flex-wrap: wrap;
gap: 1.25rem;
align-items: center;
}
.p2p-search-wrap { position: relative; flex: 1; min-width: 280px; }
.p2p-search-wrap svg { position: absolute; left: 1.25rem; top: 50%; transform: translateY(-50%); color: var(--p2p-slate-400); }
.p2p-search { padding-left: 3.25rem !important; border-radius: var(--p2p-radius-xl) !important; }
/* ── Page Titles ── */
.p2p-page-title {
font-size: 1.875rem;
font-weight: 900;
color: var(--p2p-slate-800);
letter-spacing: -0.04em;
line-height: 1;
}
.p2p-section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 2rem;
}
/* ── Layout ── */
.p2p-sidebar {
position: fixed;
top: 0;
left: 0;
width: 22rem;
height: 100vh;
background: white;
border-right: 1px solid var(--p2p-slate-100);
box-shadow: 40px 0 100px -20px rgba(0,0,0,0.06);
overflow: hidden;
display: flex;
flex-direction: column;
z-index: 50;
transition: width 0.4s ease;
}
.p2p-sidebar nav {
flex: 1 1 0;
min-height: 0;
overflow-y: auto;
overflow-x: hidden;
scrollbar-width: thin;
scrollbar-color: #cbd5e1 transparent;
}
.p2p-sidebar nav::-webkit-scrollbar { width: 4px; }
.p2p-sidebar nav::-webkit-scrollbar-thumb { background: #cbd5e1; border-radius: 9999px; }
.p2p-sidebar nav::-webkit-scrollbar-track { background: transparent; }
.p2p-sidebar.collapsed { width: 6rem; }
.p2p-sidebar-logo {
display: flex;
align-items: center;
padding: 2.5rem 2rem;
border-bottom: 1px solid var(--p2p-slate-50);
}
.p2p-logo-icon {
width: 3.5rem;
height: 3.5rem;
background: linear-gradient(135deg, var(--p2p-indigo-700), var(--p2p-indigo-600) 50%, var(--p2p-purple-500));
border-radius: var(--p2p-radius);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-weight: 900;
font-size: 1.25rem;
flex-shrink: 0;
border: 3px solid rgba(255,255,255,0.2);
box-shadow: var(--p2p-shadow-indigo);
}
.p2p-sidebar-title {
margin-left: 1.25rem;
font-weight: 900;
font-size: 1.25rem;
letter-spacing: -0.03em;
text-transform: uppercase;
color: var(--p2p-slate-900);
}
.p2p-nav-section {
padding: 1.75rem 1.25rem 0.75rem;
}
.p2p-nav-label {
font-size: 10px;
font-weight: 900;
color: var(--p2p-slate-400);
text-transform: uppercase;
letter-spacing: 0.35em;
padding: 0 1rem;
margin-bottom: 0.75rem;
}
.p2p-nav-item {
display: flex;
align-items: center;
padding: 1rem 1.25rem;
border-radius: var(--p2p-radius-lg);
font-size: 13px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--p2p-slate-400);
cursor: pointer;
transition: all 0.3s;
text-decoration: none;
margin-bottom: 0.35rem;
border: 1px solid transparent;
background: none;
width: 100%;
gap: 0.875rem;
}
.p2p-nav-item:hover { background: var(--p2p-slate-50); color: var(--p2p-slate-800); }
.p2p-nav-item.active {
background: white;
color: var(--p2p-indigo-600);
box-shadow: 0 10px 30px -8px rgba(0,0,0,0.08);
border-color: var(--p2p-slate-100);
font-weight: 900;
}
.p2p-header {
height: 6.5rem;
background: rgba(248,249,253,0.85);
backdrop-filter: blur(20px);
border-bottom: 1px solid var(--p2p-slate-100);
padding: 0 2.5rem;
display: flex;
align-items: center;
justify-content: space-between;
position: sticky;
top: 0;
z-index: 40;
}
.p2p-layout {
display: flex;
min-height: 100vh;
background: var(--p2p-bg);
}
.p2p-main {
margin-left: 22rem;
width: calc(100% - 22rem);
display: flex;
flex-direction: column;
min-height: 100vh;
transition: margin-left 0.4s ease, width 0.4s ease;
overflow-x: hidden;
}
.p2p-main.p2p-main-collapsed {
margin-left: 6rem;
width: calc(100% - 6rem);
}
.p2p-content {
padding: 2.5rem 2.75rem 100px;
flex: 1;
width: 100%;
max-width: 1700px;
margin: 0 auto;
}
@media (max-width: 768px) {
.p2p-sidebar {
transform: translateX(-100%);
width: 22rem;
}
.p2p-sidebar.collapsed {
transform: translateX(-100%);
}
.p2p-main, .p2p-main.p2p-main-collapsed {
margin-left: 0;
width: 100%;
}
.p2p-content {
padding: 1.5rem;
}
}
/* ── Bar Chart ── */
.p2p-chart { display: flex; align-items: flex-end; height: 160px; gap: 8px; }
.p2p-bar {
flex: 1;
background: linear-gradient(to top, var(--p2p-indigo-600), var(--p2p-indigo-400));
border-radius: var(--p2p-radius-sm) var(--p2p-radius-sm) 0 0;
transition: opacity 0.2s;
cursor: pointer;
min-width: 10px;
}
.p2p-bar:hover { opacity: 0.85; }
/* ── Live Badge ── */
.p2p-live {
display: inline-flex;
align-items: center;
gap: 0.5rem;
font-size: 10px;
font-weight: 900;
color: #ef4444;
background: #fef2f2;
border: 1px solid #fecaca;
padding: 0.35rem 0.75rem;
border-radius: 9999px;
text-transform: uppercase;
letter-spacing: 0.08em;
animation: pulse 2s infinite;
}
.p2p-live-dot {
width: 0.5rem;
height: 0.5rem;
background: #ef4444;
border-radius: 50%;
animation: pulse 1.5s infinite;
}
/* ── Tabs ── */
.p2p-tabs { display: flex; border-bottom: 1px solid var(--p2p-slate-100); background: rgba(255,255,255,0.6); padding: 0 0.5rem; }
.p2p-tab {
padding: 1.25rem 1.75rem;
font-size: 10px;
font-weight: 900;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--p2p-slate-400);
border: none;
background: none;
cursor: pointer;
border-bottom: 3px solid transparent;
border-radius: var(--p2p-radius-sm) var(--p2p-radius-sm) 0 0;
transition: all 0.2s;
}
.p2p-tab.active { background: white; color: var(--p2p-indigo-600); border-bottom-color: var(--p2p-indigo-600); }
.p2p-tab:hover:not(.active) { color: var(--p2p-slate-500); }
/* ── Modal ── */
.p2p-modal-overlay {
position: fixed; inset: 0; z-index: 100;
background: rgba(15,23,42,0.4);
backdrop-filter: blur(8px);
display: flex; align-items: center; justify-content: center;
padding: 2rem;
}
.p2p-modal {
background: var(--bg-surface);
border-radius: var(--p2p-radius-xl);
box-shadow: 0 25px 60px rgba(0,0,0,0.12);
width: 100%;
max-width: 42rem;
overflow: hidden;
border: 1px solid var(--border);
}
.p2p-modal-header {
padding: 2rem 2.5rem;
border-bottom: 1px solid var(--border);
background: var(--bg-elevated);
display: flex;
justify-content: space-between;
align-items: center;
}
.p2p-modal-title {
font-size: 1.125rem;
font-weight: 900;
color: var(--text-primary);
letter-spacing: -0.02em;
}
.p2p-modal-body {
padding: 2rem 2.5rem;
background: var(--bg-surface);
color: var(--text-primary);
}
.p2p-modal-footer {
padding: 1.75rem 2.5rem;
background: var(--bg-elevated);
border-top: 1px solid var(--border);
display: flex;
justify-content: flex-end;
gap: 1rem;
}
/* ── Terminal / Callback Logs ── */
.p2p-terminal {
background: var(--p2p-slate-900);
border-radius: var(--p2p-radius-lg);
border: 4px solid var(--p2p-slate-800);
padding: 2rem;
font-family: monospace;
font-size: 11px;
overflow-y: auto;
max-height: 80vh;
}
.p2p-terminal-line { display: flex; gap: 1rem; margin-bottom: 0.75rem; }
.p2p-term-time { color: var(--p2p-slate-500); flex-shrink: 0; }
.p2p-term-status-match { color: #4ade80; font-weight: 900; text-transform: uppercase; }
.p2p-term-status-otp { color: #c084fc; font-weight: 900; text-transform: uppercase; }
.p2p-term-status-fail { color: #f87171; font-weight: 900; text-transform: uppercase; }
.p2p-term-msg { color: #cbd5e1; }
/* ── Grid helpers ── */
.p2p-grid-4 { display: grid; grid-template-columns: repeat(4,1fr); gap: 2rem; }
.p2p-grid-3 { display: grid; grid-template-columns: repeat(3,1fr); gap: 2rem; }
.p2p-grid-2 { display: grid; grid-template-columns: repeat(2,1fr); gap: 2rem; }
@media(max-width:1200px){ .p2p-grid-4{grid-template-columns:repeat(2,1fr)} .p2p-grid-3{grid-template-columns:repeat(2,1fr)} }
@media(max-width:768px){ .p2p-grid-4,.p2p-grid-3,.p2p-grid-2{grid-template-columns:1fr} }
/* ── Bank Health ── */
.p2p-bank-bar { height: 0.6rem; background:var(--p2p-slate-100); border-radius:9999px; overflow:hidden; box-shadow:inset 0 1px 3px rgba(0,0,0,0.04); }
.p2p-bank-fill { height:100%; border-radius:9999px; transition:width 1s ease; }
/* ── Pagination ── */
.p2p-pagination { display:flex; align-items:center; gap:0.5rem; padding:1.25rem 2rem; border-top:1px solid var(--p2p-slate-50); }
.p2p-page-btn {
padding:0.6rem 1rem; border-radius:var(--p2p-radius-sm); border:1px solid var(--p2p-slate-100);
font-size:10px; font-weight:900; cursor:pointer; background:white; color:var(--p2p-slate-500);
}
.p2p-page-btn.active { background:var(--p2p-indigo-600); color:white; border-color:var(--p2p-indigo-600); }
.p2p-page-btn:disabled { opacity:0.4; cursor:not-allowed; }
/* ── Misc utilities ── */
.p2p-badge-live { display:inline-block; width:0.5rem; height:0.5rem; border-radius:50%; background:#ef4444; animation:pulse 1.5s infinite; margin-right:0.5rem; }
.font-mono { font-family: monospace; }
.text-muted { color:var(--p2p-slate-400); }
.text-slate { color:var(--p2p-slate-800); }
.fw-black { font-weight:900; }
.uppercase { text-transform:uppercase; }
.tracking-wide { letter-spacing:0.1em; }
.d-flex { display:flex; }
.d-grid { display:grid; }
.align-center { align-items:center; }
.justify-between { justify-content:space-between; }
.gap-4 { gap:1rem; }
.gap-6 { gap:1.5rem; }
.mb-6 { margin-bottom:1.5rem; }
.mt-2 { margin-top:0.5rem; }
@keyframes pulse {
0%,100%{ opacity:1 }
50%{ opacity:0.5 }
}
@keyframes spin {
from{ transform:rotate(0deg) }
to{ transform:rotate(360deg) }
}
.animate-spin { animation:spin 1s linear infinite; }
/* ─────────────────────────────────────────────────────────────────────────
Bootstrap-replacement utility classes
─────────────────────────────────────────────────────────────────────────
Authored 2026-05-23 as part of the chip-away Bootstrap migration. Provides
single-purpose flexbox + spacing utilities so razor files can drop
`d-flex align-items-center justify-content-{center|between} gap-N mb-N`
composites in favor of a single class name.
Naming convention: `p2p-*` namespace so these don't collide with any
MudBlazor / Bootstrap class still on the page during the transition.
───────────────────────────────────────────────────────────────────────── */
.p2p-flex-center        { display:flex; align-items:center; justify-content:center; }
.p2p-flex-between       { display:flex; align-items:center; justify-content:space-between; }
.p2p-flex-row           { display:flex; align-items:center; }
.p2p-flex-col           { display:flex; flex-direction:column; }
.p2p-gap-2              { gap:0.5rem; }
.p2p-gap-3              { gap:1rem; }
/* Vertical spacing — common BS `mb-3` (1rem) / `mb-4` (1.5rem) / `mt-3` etc */
.p2p-mb-2               { margin-bottom:0.5rem; }
.p2p-mb-3               { margin-bottom:1rem; }
.p2p-mb-4               { margin-bottom:1.5rem; }
.p2p-mt-2               { margin-top:0.5rem; }
.p2p-mt-3               { margin-top:1rem; }
.p2p-mt-4               { margin-top:1.5rem; }
/* ============================================================
DASHBOARD PAGE STYLES
Moved from Dashboard.razor.css + new chart styles
============================================================ */
/* ── Date Range Picker ───────────────────────────────────── */
.drp-wrap {
position: relative;
}
.drp-trigger {
display: flex;
align-items: center;
gap: 7px;
padding: 6px 12px;
border: 1px solid var(--border);
border-radius: 7px;
background: var(--bg-surface);
color: var(--text-primary);
font-size: 12.5px;
font-weight: 500;
cursor: pointer;
white-space: nowrap;
font-family: inherit;
transition: border-color 0.15s, box-shadow 0.15s;
}
.drp-trigger:hover { border-color: var(--border-light); }
.drp-trigger.open {
border-color: var(--primary);
box-shadow: 0 0 0 3px var(--primary-dim);
}
.drp-panel {
position: absolute;
top: calc(100% + 8px);
left: 0;
z-index: 9999;
background: var(--bg-surface);
border: 1px solid var(--border);
border-radius: 12px;
box-shadow: 0 8px 32px rgba(0,0,0,0.2);
min-width: 340px;
padding: 14px;
opacity: 0;
transform: translateY(-6px);
pointer-events: none;
transition: opacity 0.18s ease, transform 0.18s ease;
}
.drp-panel.open {
opacity: 1;
transform: translateY(0);
pointer-events: all;
}
.drp-presets {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-bottom: 2px;
}
.drp-preset {
border: 1px solid var(--border);
border-radius: 6px;
background: var(--bg-elevated);
padding: 4px 11px;
font-size: 12px;
font-weight: 500;
color: var(--text-secondary);
cursor: pointer;
font-family: inherit;
transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.drp-preset:hover {
background: var(--primary-dim);
border-color: var(--primary-light);
color: var(--primary);
}
.drp-preset.active {
background: var(--primary);
border-color: var(--primary);
color: #fff;
}
.drp-divider { height: 1px; background: var(--border); margin: 12px 0; }
.drp-inputs { display: flex; align-items: flex-end; gap: 10px; }
.drp-input-group { flex: 1; display: flex; flex-direction: column; gap: 5px; }
.drp-input-label {
font-size: 11px;
font-weight: 600;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.drp-date-input {
border: 1px solid var(--border);
border-radius: 7px;
padding: 7px 10px;
font-size: 12.5px;
color: var(--text-primary);
font-family: inherit;
outline: none;
width: 100%;
cursor: pointer;
transition: border-color 0.15s, box-shadow 0.15s;
}
.drp-date-input:focus {
border-color: var(--primary);
box-shadow: 0 0 0 3px var(--primary-dim);
}
.drp-footer {
display: flex;
align-items: center;
gap: 8px;
margin-top: 12px;
padding-top: 12px;
border-top: 1px solid var(--border);
}
.drp-range-preview {
flex: 1;
font-size: 11.5px;
color: var(--text-muted);
font-style: italic;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.drp-cancel {
border: 1px solid var(--border);
border-radius: 7px;
background: var(--bg-surface);
padding: 6px 14px;
font-size: 12.5px;
font-weight: 500;
color: var(--text-secondary);
cursor: pointer;
font-family: inherit;
transition: background 0.12s;
}
.drp-cancel:hover { background: var(--bg-elevated); }
.drp-apply {
border: none;
border-radius: 7px;
background: var(--primary);
padding: 6px 16px;
font-size: 12.5px;
font-weight: 600;
color: #fff;
cursor: pointer;
font-family: inherit;
transition: background 0.12s;
}
.drp-apply:hover { opacity: 0.9; }
/* ── KPI Card ────────────────────────────────────────────── */
/* KPI Card inherited from bo-style.css premium styles */
/* ── Rate ring ───────────────────────────────────────────── */
.rate-ring {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
}
.rate-ring-label {
position: absolute;
font-size: 9px;
font-weight: 700;
color: var(--warning);
}
/* ── Card header helper ──────────────────────────────────── */
.card-bo-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
margin-bottom: 16px;
}
.card-bo-title { font-size: 14px; font-weight: 600; color: var(--text-primary); }
.card-bo-sub   { font-size: 12px; color: var(--text-secondary); margin-top: 2px; }
.btn-ghost-sm {
background: none;
border: none;
font-size: 12px;
font-weight: 500;
color: var(--primary);
cursor: pointer;
padding: 0;
display: inline-flex;
align-items: center;
gap: 4px;
white-space: nowrap;
}
.btn-ghost-sm:hover { text-decoration: underline; }
/* ── Merchant rank rows ──────────────────────────────────── */
.merchant-rank-item {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 0;
border-bottom: 1px solid var(--border);
}
.merchant-rank-item:last-of-type { border-bottom: none; }
.rank-badge {
width: 22px; height: 22px;
border-radius: 6px;
display: flex; align-items: center; justify-content: center;
font-size: 11px; font-weight: 700; flex-shrink: 0;
}
.rank-1 { background: var(--warning-dim); color: var(--warning); }
.rank-2 { background: var(--bg-elevated); color: var(--text-secondary); }
.rank-3 { background: var(--danger-dim);  color: var(--danger); }
.rank-4 { background: var(--success-dim); color: var(--success); }
.rank-5 { background: var(--primary-dim); color: var(--primary); }
.rank-avatar {
width: 32px; height: 32px;
border-radius: 8px;
display: flex; align-items: center; justify-content: center;
font-size: 11px; font-weight: 700; flex-shrink: 0;
background: var(--primary-dim);
color: var(--primary);
}
.rank-info { flex: 1; min-width: 0; }
.rank-name { font-size: 13px; font-weight: 600; color: var(--text-primary); }
.rank-bar-wrap { width: 80px; flex-shrink: 0; }
.rank-bar { height: 5px; border-radius: 3px; overflow: hidden; background: var(--bg-elevated); }
.rank-bar-fill {
height: 100%;
border-radius: 3px;
background: var(--primary);
transition: width 0.6s ease;
}
.rank-stats { text-align: right; flex-shrink: 0; padding-right: 30px; }
.rank-count {
font-size: 14px; font-weight: 700;
color: var(--text-primary);
font-variant-numeric: tabular-nums;
}
.rank-label { font-size: 10px; color: var(--text-secondary); }
/* ── Chart section ───────────────────────────────────────── */
.chart-section {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 16px;
margin-top: 16px;
}
@media (max-width: 900px) {
.chart-section { grid-template-columns: 1fr; }
}
.chart-card {
background: var(--bg-card);
border: 1px solid var(--border);
border-radius: 12px;
padding: 18px 20px;
}
.chart-title {
font-size: 13px;
font-weight: 600;
color: var(--text-primary);
margin-bottom: 14px;
display: flex;
align-items: center;
gap: 8px;
line-height: 1;
}
.chart-title svg {
flex-shrink: 0;
display: block;
}
.chart-canvas-wrap {
position: relative;
height: 300px;
}
/* Floating Quick Actions inherited from bo-style.css */
/* ── Tooltip ─────────────────────────────────────────────── */
[data-tooltip]::after {
content: attr(data-tooltip);
position: absolute;
bottom: calc(100% + 10px);
left: 50%;
transform: translateX(-50%) translateY(4px);
background: var(--bg-card);
color: var(--text-primary);
border: 1px solid var(--border);
font-size: 11px;
font-weight: 600;
padding: 6px 10px;
border-radius: 6px;
white-space: nowrap;
opacity: 0;
pointer-events: none;
transition: opacity 0.15s, transform 0.15s;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
[data-tooltip]::before {
content: '';
position: absolute;
bottom: calc(100% + 6px);
left: 50%;
transform: translateX(-50%) translateY(4px);
border-width: 5px 5px 0;
border-style: solid;
border-color: var(--border) transparent transparent transparent;
opacity: 0;
pointer-events: none;
transition: opacity 0.15s, transform 0.15s;
}
[data-tooltip]:hover::after,
[data-tooltip]:hover::before {
opacity: 1;
transform: translateX(-50%) translateY(0);
}
/* ============================================================
TOP 5 MERCHANTS — 2x2 grid (today × monthly × deposit × payout)
============================================================ */
.top5-grid {
display: grid;
grid-template-columns: 1fr;
gap: 1rem;
}
@media (min-width: 992px) {
.top5-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
/* ============================================================
TOP 5 MERCHANTS LEADERBOARD — mirrors SSP MasterOverview .lb-*
Tabs (Today / MTD), 2 columns (Deposit | Payout), bar + rank dot.
============================================================ */
.lb-card { margin-top: 1rem; padding: 1rem 1.25rem; }
.lb-header {
display: flex; align-items: center; justify-content: space-between;
margin-bottom: 0.75rem; flex-wrap: wrap; gap: 0.5rem;
}
.lb-title-wrap { display: flex; align-items: center; gap: 0.5rem; }
.lb-title { font-size: 14px; font-weight: 700; color: var(--text-primary); }
.lb-badge {
display: inline-block; padding: 2px 8px; border-radius: 999px;
background: var(--primary-dim); color: var(--primary);
font-size: 11px; font-weight: 700;
}
.lb-header-meta { font-size: 12px; color: var(--text-muted); }
.lb-tabs { display: flex; gap: 6px; margin-bottom: 0.75rem; }
.lb-tab {
flex: 1; padding: 8px 14px; border: 1px solid var(--border);
background: var(--bg-elevated); color: var(--text-secondary);
border-radius: 8px; font-size: 12px; font-weight: 600;
cursor: pointer; transition: all 0.15s ease;
}
.lb-tab:hover { background: var(--primary-dim); color: var(--primary); }
.lb-tab.active {
background: var(--primary); color: #fff;
border-color: var(--primary);
box-shadow: 0 2px 6px rgba(37,99,235,0.18);
}
.lb-legend { display: flex; gap: 1.5rem; margin-bottom: 0.5rem; font-size: 11px; color: var(--text-secondary); }
.lb-legend-item { display: inline-flex; align-items: center; gap: 6px; }
.lb-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; }
.lb-dot-dp { background: #10B981; }
.lb-dot-po { background: #7C3AED; }
.lb-empty { text-align: center; color: var(--text-muted); padding: 24px; font-size: 13px; }
.lb-columns {
display: grid; grid-template-columns: 1fr; gap: 1rem;
}
@media (min-width: 992px) {
.lb-columns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
.lb-col { display: flex; flex-direction: column; gap: 6px; }
.lb-range { font-size: 11px; color: var(--text-muted); margin-bottom: 2px; }
.lb-row {
display: grid;
grid-template-columns: 24px 28px 1fr auto;
align-items: center; gap: 8px;
padding: 8px 10px; border-radius: 8px;
background: var(--bg-elevated);
transition: background 0.12s ease;
}
.lb-row:hover { background: var(--primary-dim); }
.lb-rankdot {
width: 24px; height: 24px; border-radius: 50%;
display: inline-flex; align-items: center; justify-content: center;
font-size: 11px; font-weight: 800; color: #fff;
}
.lb-rank-icon { font-size: 14px; }
.lb-gold   { background: linear-gradient(135deg,#F59E0B,#D97706); }
.lb-silver { background: linear-gradient(135deg,#94A3B8,#64748B); }
.lb-bronze { background: linear-gradient(135deg,#A16207,#854D0E); }
.lb-ranknum { background: var(--bg-surface); color: var(--text-secondary); border: 1px solid var(--border); }
.lb-ava {
width: 28px; height: 28px; border-radius: 6px;
display: inline-flex; align-items: center; justify-content: center;
background: var(--primary-dim); color: var(--primary);
font-size: 10px; font-weight: 800;
}
.lb-merchant { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.lb-name { font-size: 12px; font-weight: 700; color: var(--text-primary); }
.lb-bar { height: 4px; background: var(--bg-surface); border-radius: 999px; overflow: hidden; }
.lb-fill { height: 100%; border-radius: 999px; transition: width 0.4s ease; }
.lb-fill-dp { background: linear-gradient(90deg,#10B981,#34D399); }
.lb-fill-po { background: linear-gradient(90deg,#7C3AED,#A78BFA); }
.lb-right { text-align: right; }
.lb-vol { font-size: 12px; font-weight: 700; color: var(--text-primary); font-variant-numeric: tabular-nums; }
.lb-num { color: var(--text-primary); }
.lb-ccy { color: var(--text-muted); font-weight: 600; font-size: 10px; margin-left: 4px; }
.lb-txns { font-size: 10px; color: var(--text-muted); margin-top: 2px; }
/* ============================================================
EXTRACTED FROM: Components\Pages\Dashboard.razor
============================================================ */
/* 5-up KPI grid: 5 cols on xl, 3 on lg, 2 on md, 1 on sm. */
.kpi-row-5 { display: grid; gap: 1rem;
grid-template-columns: repeat(1, minmax(0, 1fr)); }
@media (min-width: 768px)  { .kpi-row-5 { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 992px)  { .kpi-row-5 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1400px) { .kpi-row-5 { grid-template-columns: repeat(5, minmax(0, 1fr)); } }
.kpi-col { min-width: 0; }
/* Muted clarifying subtitle under a chart-card title (e.g. match-type chart scope note) */
.card-balance-subtitle {
margin: -4px 0 8px;
font-size: 11px;
color: var(--text-muted);
}
/* Overrides to prevent global list-page heights stretching the small dashboard breakdown table */
.card-bo:has(.lb-table) .table-responsive {
height: auto !important;
max-height: none !important;
border-radius: 12px;
overflow: hidden;
}
.table-bo.lb-table {
height: auto !important;
border: none !important;
}
.table-bo.lb-table thead th {
font-size: 11px !important;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
font-weight: 700;
padding: 12px 20px !important;
border-bottom: 1px solid var(--border) !important;
background: var(--bg-elevated);
}
.table-bo.lb-table tbody tr {
transition: background 0.15s ease;
}
.table-bo.lb-table tbody tr:not(.lb-total-row):hover {
background: rgba(var(--bg-elevated-rgb), 0.5) !important;
}
.table-bo.lb-table tbody td {
padding: 16px 20px !important;
font-size: 13.5px !important;
border-bottom: 1px solid var(--border);
vertical-align: middle;
}
.table-bo.lb-table .lb-total-row td {
background: var(--bg-elevated) !important;
border-top: 1.5px solid var(--border) !important;
border-bottom: none !important;
font-size: 14px !important;
font-weight: 700;
color: var(--text-primary);
}
/* Premium Dot Badges */
.lb-badge {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: 6px;
font-size: 11px !important;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.04em;
}
.lb-badge::before {
content: "";
display: inline-block;
width: 6px;
height: 6px;
border-radius: 50%;
background-color: currentColor;
}
.lb-badge-deposit {
background: var(--success-dim) !important;
color: var(--success) !important;
border: 1px solid rgba(16, 185, 129, 0.15);
}
.lb-badge-payout {
background: var(--info-dim) !important;
color: var(--info) !important;
border: 1px solid rgba(59, 130, 246, 0.15);
}
/* ============================================================
* Audit Logs — User Action Log pages styling.
* Loaded globally via App.razor.
*
* Theme reuse policy: this file ONLY contains rules that the theme
* (bo-style.css / p2p-common.css) does not already provide. Modal
* chrome / labels / values / buttons / status badges all use theme
* classes (dd-grid, dd-row, dd-label, dd-val, badge-status,
* IconButton component, etc.). Anything specific to the diff view
* lives here because no theme equivalent exists.
*
* Used by:
*   - Components/Pages/Admin/UserActionLogs.razor
*   - Components/Pages/UserActionLogs.razor (partner-side)
*   - Components/Shared/AuditChangesView.razor
*   - Components/Shared/UserActionLogDetailModal.razor
* ============================================================ */
/* ── Inline tags shown in the table row (Source / Category / Entity) ─ */
.src-tag, .cat-tag, .entity-tag {
display: inline-block;
padding: 2px 8px;
border-radius: 4px;
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
}
.src-tag    { background: #EFF6FF; color: #1E40AF; }
.cat-tag    { background: #F0FDF4; color: #15803D; }
.entity-tag { background: #F3F4F6; color: #374151; }
/* ── Changes block (AuditChangesView) — per-entity header + diff ──── */
.change-entity { margin-bottom: 12px; }
.change-entity:last-child { margin-bottom: 0; }
.change-entity-header {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 4px;
font-size: 12px;
}
.change-entity-type { color: var(--text-primary); font-weight: 600; }
.change-entity-key  { color: #FBBF24; font-weight: 600; }
.change-entity-id   { color: var(--text-muted); font-family: var(--font-mono); font-size: 11px; }
.op-tag {
display: inline-block;
padding: 1px 8px;
border-radius: 4px;
font-size: 10px;
font-weight: 700;
text-transform: uppercase;
}
.op-add    { background: #D1FAE5; color: #065F46; }
.op-update { background: #DBEAFE; color: #1E40AF; }
.op-delete { background: #FEE2E2; color: #991B1B; }
.diff-table {
border-collapse: collapse;
width: 100%;
font-size: 11px;
border-radius: 4px;
overflow: hidden;
}
.diff-table th {
text-align: left;
padding: 4px 8px;
background: rgba(0, 0, 0, 0.04);
color: var(--text-muted);
font-size: 9px;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.diff-table td {
padding: 2px 8px;
border-top: 1px solid var(--border);
vertical-align: top;
font-family: var(--font-mono);
word-break: break-word;
line-height: 1.4;
}
.diff-table .diff-col-field { width: 25%; }
.diff-table .diff-col-side  { width: 37.5%; }
.diff-table .diff-field  { color: var(--text-muted); font-weight: 600; font-family: inherit; }
.diff-table .diff-before { color: #B91C1C; }
.diff-table .diff-after  { color: #047857; }
