initial commit
This commit is contained in:
@@ -0,0 +1,361 @@
|
||||
/* vibedns management interface
|
||||
*
|
||||
* A thin layer on top of Bootstrap 5: an app shell with a fixed sidebar,
|
||||
* a small set of component styles, and colour tokens that follow Bootstrap's
|
||||
* own light/dark switch so the whole UI flips with one attribute.
|
||||
*/
|
||||
|
||||
:root {
|
||||
--app-sidebar-width: 248px;
|
||||
--app-navbar-height: 56px;
|
||||
--app-brand: #1b6ec2;
|
||||
--app-brand-dark: #14508c;
|
||||
--app-sidebar-bg: #ffffff;
|
||||
--app-sidebar-border: var(--bs-border-color);
|
||||
--app-sidebar-link: #495057;
|
||||
--app-sidebar-link-hover-bg: #f1f3f5;
|
||||
--app-sidebar-active-bg: #e7f1fb;
|
||||
--app-sidebar-active-color: var(--app-brand-dark);
|
||||
--app-body-bg: #f6f8fa;
|
||||
--app-card-shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 1px 3px rgba(16, 24, 40, .08);
|
||||
}
|
||||
|
||||
[data-bs-theme="dark"] {
|
||||
--app-brand: #4c9be8;
|
||||
--app-brand-dark: #7cb8f0;
|
||||
--app-sidebar-bg: #17191d;
|
||||
--app-sidebar-border: #2b2f36;
|
||||
--app-sidebar-link: #adb5bd;
|
||||
--app-sidebar-link-hover-bg: #22252b;
|
||||
--app-sidebar-active-bg: #1d2b3a;
|
||||
--app-sidebar-active-color: #8fc3f5;
|
||||
--app-body-bg: #101214;
|
||||
--app-card-shadow: 0 1px 2px rgba(0, 0, 0, .4);
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--app-body-bg);
|
||||
font-size: .9375rem;
|
||||
}
|
||||
|
||||
.skip-link {
|
||||
position: absolute;
|
||||
top: .5rem;
|
||||
left: .5rem;
|
||||
z-index: 2000;
|
||||
background: var(--bs-body-bg);
|
||||
padding: .5rem .75rem;
|
||||
border-radius: .375rem;
|
||||
}
|
||||
|
||||
/* --- Shell ------------------------------------------------------------ */
|
||||
|
||||
.app-navbar {
|
||||
background: linear-gradient(90deg, var(--app-brand-dark), var(--app-brand));
|
||||
min-height: var(--app-navbar-height);
|
||||
box-shadow: 0 1px 3px rgba(16, 24, 40, .15);
|
||||
z-index: 1030;
|
||||
}
|
||||
|
||||
.app-navbar .navbar-brand {
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
letter-spacing: .01em;
|
||||
}
|
||||
|
||||
.app-navbar .navbar-brand:hover { color: #fff; }
|
||||
|
||||
.status-dot {
|
||||
width: .55rem;
|
||||
height: .55rem;
|
||||
border-radius: 50%;
|
||||
background: #adb5bd;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.status-dot.status-up {
|
||||
background: #2fb344;
|
||||
box-shadow: 0 0 0 3px rgba(47, 179, 68, .25);
|
||||
}
|
||||
|
||||
.status-dot.status-down {
|
||||
background: #d63939;
|
||||
box-shadow: 0 0 0 3px rgba(214, 57, 57, .25);
|
||||
}
|
||||
|
||||
.app-shell { display: flex; align-items: flex-start; }
|
||||
|
||||
.app-sidebar {
|
||||
width: var(--app-sidebar-width);
|
||||
flex: 0 0 var(--app-sidebar-width);
|
||||
position: sticky;
|
||||
top: var(--app-navbar-height);
|
||||
height: calc(100vh - var(--app-navbar-height));
|
||||
overflow-y: auto;
|
||||
background: var(--app-sidebar-bg);
|
||||
border-right: 1px solid var(--app-sidebar-border);
|
||||
}
|
||||
|
||||
.app-main { flex: 1 1 auto; min-width: 0; }
|
||||
|
||||
.app-offcanvas { width: var(--app-sidebar-width); }
|
||||
|
||||
.sidebar-nav { padding: .75rem .5rem 2rem; }
|
||||
|
||||
.sidebar-heading {
|
||||
font-size: .6875rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .06em;
|
||||
color: var(--bs-secondary-color);
|
||||
padding: 1rem .75rem .35rem;
|
||||
}
|
||||
|
||||
.sidebar-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: .625rem;
|
||||
padding: .5rem .75rem;
|
||||
margin-bottom: .0625rem;
|
||||
border-radius: .375rem;
|
||||
color: var(--app-sidebar-link);
|
||||
text-decoration: none;
|
||||
font-weight: 500;
|
||||
transition: background-color .12s ease, color .12s ease;
|
||||
}
|
||||
|
||||
.sidebar-link i { font-size: 1rem; width: 1.25rem; text-align: center; flex: none; }
|
||||
|
||||
.sidebar-link:hover {
|
||||
background: var(--app-sidebar-link-hover-bg);
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.sidebar-link.active {
|
||||
background: var(--app-sidebar-active-bg);
|
||||
color: var(--app-sidebar-active-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* --- Typography and cards --------------------------------------------- */
|
||||
|
||||
.page-title {
|
||||
font-size: 1.5rem;
|
||||
font-weight: 600;
|
||||
margin-bottom: .125rem;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-color: var(--bs-border-color);
|
||||
box-shadow: var(--app-card-shadow);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background: transparent;
|
||||
border-bottom-color: var(--bs-border-color);
|
||||
font-weight: 600;
|
||||
padding-block: .75rem;
|
||||
}
|
||||
|
||||
.stat-card .card-body { padding: 1rem 1.125rem; }
|
||||
|
||||
.stat-label {
|
||||
font-size: .75rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
color: var(--bs-secondary-color);
|
||||
}
|
||||
|
||||
.stat-value {
|
||||
font-size: 1.75rem;
|
||||
font-weight: 600;
|
||||
line-height: 1.2;
|
||||
margin-top: .25rem;
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.stat-sub { font-size: .8125rem; color: var(--bs-secondary-color); margin-top: .125rem; }
|
||||
|
||||
.stat-icon { font-size: 1.125rem; color: var(--bs-secondary-color); opacity: .75; }
|
||||
|
||||
/* --- Tables ------------------------------------------------------------ */
|
||||
|
||||
.table { --bs-table-bg: transparent; margin-bottom: 0; }
|
||||
|
||||
.table > thead > tr > th {
|
||||
font-size: .75rem;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
color: var(--bs-secondary-color);
|
||||
border-bottom-width: 1px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.table > tbody > tr > td { vertical-align: middle; }
|
||||
|
||||
.table-hover > tbody > tr:hover > * { --bs-table-accent-bg: var(--app-sidebar-link-hover-bg); }
|
||||
|
||||
.table-compact > :not(caption) > * > * { padding: .5rem .625rem; }
|
||||
|
||||
.mono {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: .8125rem;
|
||||
}
|
||||
|
||||
.truncate-cell {
|
||||
max-width: 26rem;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.row-actions { white-space: nowrap; text-align: right; }
|
||||
|
||||
.row-actions .btn { --bs-btn-padding-y: .1875rem; --bs-btn-padding-x: .4375rem; }
|
||||
|
||||
/* Disabled rows read as inactive without disappearing. */
|
||||
tr.is-disabled > td:not(.row-actions) { opacity: .55; }
|
||||
|
||||
/* --- Record type chips ------------------------------------------------- */
|
||||
|
||||
.type-chip {
|
||||
display: inline-block;
|
||||
min-width: 3.75rem;
|
||||
text-align: center;
|
||||
padding: .1875rem .4375rem;
|
||||
border-radius: .25rem;
|
||||
font-size: .75rem;
|
||||
font-weight: 600;
|
||||
font-family: var(--bs-font-monospace);
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
|
||||
.type-addr { background: #e7f1fb; color: #14508c; border-color: #c9e0f7; }
|
||||
.type-alias { background: #f3e8fd; color: #6b21a8; border-color: #e4d0fb; }
|
||||
.type-service { background: #e6f7f1; color: #0f6b52; border-color: #c5ecdf; }
|
||||
.type-auth { background: #fef3e2; color: #92500e; border-color: #fbe0b8; }
|
||||
.type-text { background: #eef0f2; color: #41474d; border-color: #dde1e5; }
|
||||
.type-sec { background: #fde8ec; color: #9b1c33; border-color: #f8ccd6; }
|
||||
.type-ptr { background: #e8f4fd; color: #0b5d7a; border-color: #cbe6f6; }
|
||||
.type-other { background: #eef0f2; color: #41474d; border-color: #dde1e5; }
|
||||
|
||||
[data-bs-theme="dark"] .type-addr { background: #12283d; color: #8fc3f5; border-color: #1d3d5c; }
|
||||
[data-bs-theme="dark"] .type-alias { background: #2a1a3d; color: #cba6f7; border-color: #3d2757; }
|
||||
[data-bs-theme="dark"] .type-service { background: #12302a; color: #7ad4b3; border-color: #1c4a3f; }
|
||||
[data-bs-theme="dark"] .type-auth { background: #362508; color: #f0c674; border-color: #4d360f; }
|
||||
[data-bs-theme="dark"] .type-text { background: #22252b; color: #adb5bd; border-color: #32363d; }
|
||||
[data-bs-theme="dark"] .type-sec { background: #3a151f; color: #f2a1b2; border-color: #55202e; }
|
||||
[data-bs-theme="dark"] .type-ptr { background: #102b36; color: #86cfe8; border-color: #1a4252; }
|
||||
[data-bs-theme="dark"] .type-other { background: #22252b; color: #adb5bd; border-color: #32363d; }
|
||||
|
||||
/* --- Empty states ------------------------------------------------------ */
|
||||
|
||||
.empty-state { color: var(--bs-secondary-color); }
|
||||
|
||||
.empty-icon {
|
||||
font-size: 2.75rem;
|
||||
color: var(--bs-secondary-color);
|
||||
opacity: .45;
|
||||
}
|
||||
|
||||
/* --- Forms ------------------------------------------------------------- */
|
||||
|
||||
.form-label { font-weight: 500; margin-bottom: .3125rem; }
|
||||
|
||||
.form-text { font-size: .8125rem; }
|
||||
|
||||
.settings-nav .nav-link {
|
||||
--bs-nav-pills-border-radius: .375rem;
|
||||
padding: .375rem .75rem;
|
||||
font-size: .875rem;
|
||||
font-weight: 500;
|
||||
color: var(--bs-body-color);
|
||||
}
|
||||
|
||||
.settings-nav .nav-link:not(.active):hover { background: var(--app-sidebar-link-hover-bg); }
|
||||
|
||||
.form-section + .form-section { margin-top: 1.5rem; padding-top: 1.5rem; border-top: 1px solid var(--bs-border-color); }
|
||||
|
||||
.form-section-title { font-size: .9375rem; font-weight: 600; margin-bottom: .875rem; }
|
||||
|
||||
textarea.list-input {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: .8125rem;
|
||||
min-height: 7.5rem;
|
||||
}
|
||||
|
||||
/* Sticky action bar for long settings forms. */
|
||||
.form-actions {
|
||||
position: sticky;
|
||||
bottom: 0;
|
||||
background: var(--bs-body-bg);
|
||||
border-top: 1px solid var(--bs-border-color);
|
||||
padding: .875rem 1.125rem;
|
||||
margin: 1.5rem -1.125rem -1.125rem;
|
||||
border-radius: 0 0 var(--bs-card-border-radius) var(--bs-card-border-radius);
|
||||
}
|
||||
|
||||
/* --- Charts ------------------------------------------------------------ */
|
||||
|
||||
.chart-wrap { position: relative; height: 260px; }
|
||||
|
||||
.chart-wrap-sm { position: relative; height: 200px; }
|
||||
|
||||
/* --- Misc -------------------------------------------------------------- */
|
||||
|
||||
.bulk-bar {
|
||||
display: none;
|
||||
align-items: center;
|
||||
gap: .75rem;
|
||||
padding: .625rem .875rem;
|
||||
background: var(--app-sidebar-active-bg);
|
||||
border: 1px solid var(--bs-border-color);
|
||||
border-radius: .375rem;
|
||||
margin-bottom: .75rem;
|
||||
}
|
||||
|
||||
.bulk-bar.is-visible { display: flex; }
|
||||
|
||||
.token-secret {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: .875rem;
|
||||
word-break: break-all;
|
||||
background: var(--bs-tertiary-bg);
|
||||
padding: .625rem .75rem;
|
||||
border-radius: .375rem;
|
||||
border: 1px solid var(--bs-border-color);
|
||||
}
|
||||
|
||||
.answer-block {
|
||||
font-family: var(--bs-font-monospace);
|
||||
font-size: .8125rem;
|
||||
white-space: pre-wrap;
|
||||
word-break: break-all;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.progress-thin { height: .375rem; }
|
||||
|
||||
.list-meta { display: flex; flex-wrap: wrap; gap: 1.25rem; }
|
||||
|
||||
.list-meta > div { min-width: 7rem; }
|
||||
|
||||
.list-meta dt {
|
||||
font-size: .75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: .04em;
|
||||
color: var(--bs-secondary-color);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.list-meta dd { font-size: 1.125rem; font-weight: 600; margin-bottom: 0; }
|
||||
|
||||
@media (max-width: 991.98px) {
|
||||
.app-sidebar { display: none; }
|
||||
}
|
||||
|
||||
@media print {
|
||||
.app-sidebar, .app-navbar, .toast-container, .row-actions { display: none !important; }
|
||||
}
|
||||
Reference in New Issue
Block a user