billing frontend for mariadb. setup as otb_billing for outsidethebox.top accounting. also involved with outsidethedb
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

587 lines
10 KiB

:root{
--bg:#0b0f14;
--card:#121825;
--card-soft:rgba(18,24,37,.78);
--text:#e8eefc;
--muted:#aab6d6;
--line:#24304a;
--accent:#7aa2ff;
--accent2:#62e6b7;
--success:#4ade80;
--warn:#fbbf24;
--danger:#f87171;
--radius:16px;
--shadow:0 16px 40px rgba(0,0,0,.35);
}
*{box-sizing:border-box}
html,body{height:100%}
body{
margin:0;
font-family: ui-sans-serif, system-ui, -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, Arial, "Apple Color Emoji","Segoe UI Emoji";
background:
radial-gradient(1200px 600px at 20% 0%, rgba(122,162,255,.22), transparent 60%),
radial-gradient(900px 500px at 90% 20%, rgba(98,230,183,.15), transparent 60%),
linear-gradient(180deg, #081225 0%, #09172d 100%);
color:var(--text);
line-height:1.45;
}
a{color:inherit}
/* ===== Shared container ===== */
.container{
max-width:1100px;
margin:0 auto;
padding:20px 18px;
}
/* ===== Header / branded nav ===== */
.header{width:100%}
.nav{
display:flex;
align-items:center;
justify-content:space-between;
gap:18px;
padding:12px 0 22px 0;
}
.brand{
display:flex;
align-items:center;
gap:14px;
text-decoration:none;
}
.brand img{
height:60px;
width:auto;
display:block;
object-fit:contain;
background: rgba(255,255,255,0.92);
padding: 6px 12px;
border-radius: 999px;
box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}
.title{
display:flex;
flex-direction:column;
line-height:1.1;
}
.title strong{letter-spacing:.2px}
.title span{
color:var(--muted);
font-size:13px;
margin-top:2px;
}
.navlinks{
display:flex;
gap:12px;
flex-wrap:wrap;
justify-content:flex-end;
}
.navlinks a{
text-decoration:none;
padding:8px 10px;
border-radius:12px;
color:var(--muted);
border:1px solid transparent;
}
.navlinks a:hover{
color:var(--text);
border-color:rgba(255,255,255,.08);
background:rgba(255,255,255,.03);
}
.navlinks a.active{
color:var(--text);
border-color:rgba(255,255,255,.10);
background:rgba(255,255,255,.04);
}
/* ===== Generic portal shell ===== */
.portal-shell{
max-width:1100px;
margin:16px auto 28px auto;
padding:0 18px 20px 18px;
}
.portal-card,
.detail-card,
.summary-card,
.pay-card{
background: var(--card-soft);
border: 1px solid rgba(255,255,255,.07);
border-radius: var(--radius);
box-shadow: var(--shadow);
}
.portal-card{
max-width:760px;
margin:24px auto 12px auto;
padding:22px;
}
.portal-page-header{
display:flex;
align-items:flex-start;
justify-content:space-between;
gap:16px;
flex-wrap:wrap;
margin:6px 0 18px 0;
}
.portal-page-title{
margin:0;
font-size:24px;
line-height:1.1;
}
.portal-page-subtitle{
margin:8px 0 0 0;
color:var(--muted);
}
.portal-client-name{
margin:8px 0 0 0;
color:var(--text);
font-size:15px;
}
.portal-toolbar{
display:flex;
gap:10px;
flex-wrap:wrap;
align-items:center;
}
.portal-btn,
.btn,
.pay-btn,
.quote-pick-btn{
display:inline-flex;
align-items:center;
justify-content:center;
gap:8px;
min-height:42px;
padding:10px 14px;
border-radius:12px;
text-decoration:none;
border:1px solid rgba(255,255,255,.10);
background: rgba(255,255,255,.05);
color:var(--text);
font-weight:600;
cursor:pointer;
}
.portal-btn:hover,
.btn:hover,
.pay-btn:hover,
.quote-pick-btn:hover{
border-color:rgba(122,162,255,.45);
box-shadow:0 0 0 4px rgba(122,162,255,.12);
text-decoration:none;
}
.portal-btn.primary,
.btn.primary{
background: linear-gradient(135deg, rgba(122,162,255,.95), rgba(98,230,183,.85));
border-color: transparent;
color:#071017;
font-weight:700;
}
.portal-btn.primary:hover,
.btn.primary:hover{
box-shadow:0 0 0 4px rgba(98,230,183,.18);
}
/* ===== Login / forms ===== */
.portal-sub{
color:var(--muted);
margin:0 0 16px 0;
}
.portal-form{
display:grid;
gap:14px;
}
.portal-form label{
display:block;
font-weight:600;
margin-bottom:6px;
}
.portal-form input,
.portal-form select,
.pay-selector{
width:100%;
padding:12px 14px;
border-radius:12px;
border:1px solid rgba(255,255,255,.14);
background: rgba(255,255,255,.06);
color:var(--text);
box-sizing:border-box;
outline:none;
}
.portal-form input:focus,
.portal-form select:focus,
.pay-selector:focus{
border-color:rgba(122,162,255,.65);
box-shadow:0 0 0 4px rgba(122,162,255,.12);
}
.portal-actions{
display:flex;
gap:10px;
flex-wrap:wrap;
margin-top:4px;
}
.portal-note{
margin-top:16px;
color:var(--muted);
font-size:14px;
line-height:1.5;
}
.portal-msg,
.error-box,
.success-box{
margin-bottom:16px;
padding:12px 14px;
border-radius:12px;
border:1px solid rgba(255,255,255,.16);
background: rgba(255,255,255,.04);
}
.error-box{
border-color: rgba(239, 68, 68, 0.55);
background: rgba(127, 29, 29, 0.22);
color: #fecaca;
}
.success-box{
border-color: rgba(34, 197, 94, 0.55);
background: rgba(22, 101, 52, 0.18);
color: #dcfce7;
}
/* ===== Dashboard ===== */
.portal-wrap{
max-width:1100px;
margin:0 auto;
padding:0;
}
.summary-grid,
.detail-grid{
display:grid;
grid-template-columns: repeat(3, minmax(0, 1fr));
gap:14px;
margin: 0 0 18px 0;
}
.summary-card,
.detail-card{
padding:18px;
}
.summary-card h3,
.detail-card h3{
margin:0 0 8px 0;
font-size:14px;
color:var(--muted);
}
.summary-card .summary-value,
.detail-card .detail-value{
font-size:28px;
font-weight:800;
line-height:1.1;
color:var(--text);
}
.summary-card .summary-sub{
margin-top:6px;
font-size:12px;
color:var(--muted);
}
.section-title{
margin:18px 0 10px 0;
font-size:22px;
}
.table-card{
background: var(--card-soft);
border: 1px solid rgba(255,255,255,.07);
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow:hidden;
}
/* ===== Tables ===== */
table,
.portal-table,
.quote-table{
width:100%;
border-collapse: collapse;
}
table.portal-table th,
table.portal-table td,
.quote-table th,
.quote-table td{
padding: 0.9rem 0.85rem;
border-bottom: 1px solid rgba(255,255,255,0.10);
text-align: left;
vertical-align: middle;
}
table.portal-table th,
.quote-table th{
background: rgba(255,255,255,.06);
color: var(--text);
font-size:13px;
letter-spacing:.02em;
}
table.portal-table tr:hover td,
.quote-table tr:hover td{
background: rgba(255,255,255,.02);
}
.invoice-link{
color: var(--text);
text-decoration: none;
font-weight: 700;
}
.invoice-link:hover{
color: var(--accent);
text-decoration: underline;
}
/* ===== Badges ===== */
.status-badge,
.quote-badge{
display: inline-block;
padding: 0.22rem 0.62rem;
border-radius: 999px;
font-size: 0.82rem;
font-weight: 700;
}
.status-paid{ background: rgba(34, 197, 94, 0.18); color: var(--success); }
.status-pending{ background: rgba(245, 158, 11, 0.20); color: var(--warn); }
.status-overdue{ background: rgba(239, 68, 68, 0.18); color: var(--danger); }
.status-other{ background: rgba(148, 163, 184, 0.20); color: #cbd5e1; }
.quote-live{ background: rgba(34, 197, 94, 0.18); color: var(--success); }
.quote-stale{ background: rgba(239, 68, 68, 0.18); color: var(--danger); }
/* ===== Payments / invoice detail ===== */
.pay-card{
padding:18px;
margin-top: 1.25rem;
}
.pay-selector-row{
display:flex;
gap:0.75rem;
align-items:center;
flex-wrap:wrap;
margin-top:0.75rem;
}
.pay-panel{
margin-top: 1rem;
padding: 1rem;
border: 1px solid rgba(255,255,255,0.12);
border-radius: 12px;
background: rgba(255,255,255,0.02);
}
.pay-panel.hidden{ display:none; }
.pay-btn-square { background:#16a34a; border-color:transparent; color:#fff; }
.pay-btn-wallet { background:#2563eb; border-color:transparent; color:#fff; }
.pay-btn-mobile { background:#7c3aed; border-color:transparent; color:#fff; }
.pay-btn-copy { background:#374151; border-color:transparent; color:#fff; }
.snapshot-wrap{
position: relative;
margin-top: 1rem;
border: 1px solid rgba(255,255,255,0.14);
border-radius: 14px;
padding: 1rem;
background: rgba(255,255,255,0.02);
}
.snapshot-header{
display:flex;
justify-content:space-between;
gap:1rem;
align-items:flex-start;
}
.snapshot-meta{
flex: 1 1 auto;
min-width: 0;
line-height: 1.65;
}
.snapshot-timer-box{
width: 220px;
min-height: 132px;
border: 1px solid rgba(255,255,255,0.16);
border-radius: 14px;
background: rgba(0,0,0,0.18);
display:flex;
flex-direction:column;
justify-content:center;
align-items:center;
text-align:center;
padding: 0.9rem;
}
.snapshot-timer-value{
font-size: 2rem;
font-weight: 800;
line-height: 1.1;
}
.snapshot-timer-label{
margin-top: 0.55rem;
font-size: 0.95rem;
opacity: 0.95;
}
.snapshot-timer-expired{ color: var(--danger); }
.lock-box{
margin-top: 1rem;
border: 1px solid rgba(34, 197, 94, 0.28);
background: rgba(22, 101, 52, 0.16);
border-radius: 12px;
padding: 1rem;
}
.lock-box.expired{
border-color: rgba(239, 68, 68, 0.55);
background: rgba(127, 29, 29, 0.22);
}
.lock-grid{
display:grid;
grid-template-columns: 1fr 220px;
gap:1rem;
align-items:start;
}
.lock-code{
display:block;
margin-top:0.35rem;
padding:0.65rem 0.8rem;
background: rgba(0,0,0,0.22);
border-radius: 8px;
overflow-wrap:anywhere;
}
.wallet-actions{
display:flex;
gap:0.75rem;
flex-wrap:wrap;
margin-top:0.9rem;
align-items:center;
}
.wallet-help{
margin-top: 0.85rem;
padding: 0.9rem 1rem;
border-radius: 10px;
background: rgba(255,255,255,0.04);
border: 1px solid rgba(255,255,255,0.10);
}
.wallet-help h4{
margin: 0 0 0.55rem 0;
font-size: 1rem;
}
.wallet-help p{ margin: 0.35rem 0; }
.wallet-note{ opacity:0.9; margin-top:0.65rem; }
.mono{ font-family: monospace; }
.copy-row{
display:flex;
gap:0.5rem;
flex-wrap:wrap;
align-items:center;
margin-top:0.65rem;
}
.copy-target{
flex: 1 1 420px;
min-width: 220px;
}
.copy-status{
display:inline-block;
margin-left: 0.5rem;
opacity: 0.9;
}
/* ===== Footer ===== */
footer{
margin:28px auto 20px auto;
max-width:1100px;
padding:0 18px;
color:var(--muted);
font-size:13px;
}
/* ===== Responsive ===== */
@media (max-width: 900px){
.summary-grid,
.detail-grid{
grid-template-columns:1fr;
}
.nav{
align-items:flex-start;
flex-direction:column;
}
.navlinks{
justify-content:flex-start;
}
.brand img{
height:54px;
}
}
@media (max-width: 820px){
.snapshot-header,
.lock-grid{
grid-template-columns: 1fr;
display:block;
}
.snapshot-timer-box{
width: 100%;
margin-top: 1rem;
min-height: 110px;
}
}