/*
 * Edison "Nova" styling for the FOSSBilling client area.
 *
 * Spec and mockups: docs/design/nova/. Structure is unchanged; this single
 * stylesheet is loaded after Huraga's stock bundle (vendor.css = Bootstrap
 * 5.3, huraga.css) from the layout overrides in html_custom/ and overrides it.
 * Bootstrap hard-codes its blue into each component's own variables, so each
 * component that carries its own colour is overridden individually below.
 *
 * Huraga switches light and dark with data-bs-theme on <html>, so every colour
 * that differs by mode is set under [data-bs-theme] and nothing mode-specific
 * sits on :root.
 *
 * Contrast, measured against WCAG AA:
 *   - White on the main action #2F7D1F is 5.2:1.
 *   - Muted #5D7380 on page #F7FBFC is 4.8:1.
 *   - Logo blue #5CC1DF is light: white on it fails (about 2:1), so text on a
 *     logo-blue fill is dark (#061C27).
 *   - Dark mode text (#E6F1F5, muted #9FB6C2) stays above 4.5:1 on #0B3347.
 *
 * Fonts: Poppins (titles, numbers, wordmark) and Inter (everything else) are
 * named first in the stacks but not yet self-hosted, so browsers fall back to
 * the system fonts. When the woff2 files are added under assets/fonts/, add
 * the @font-face rules here and nothing else changes.
 *
 * Bump the ?v= value on the <link> in layout_default / layout_public when this
 * file changes, so browsers do not serve a stale copy.
 */

:root {
    --nova-night: #061C27;
    --nova-night-end: #0B3347;
    --nova-logo-blue: #5CC1DF;
    --nova-glow: #7FD0EE;
    --nova-action: #2F7D1F;
    --nova-action-hover: #276A19;
    --nova-action-active: #215A15;
    --nova-danger: #C43838;
    --nova-pink: #EC5CA2;
    --nova-radius-card: 22px;
    --nova-radius-item: 14px;
    --nova-band: 260px;
    --nova-font: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    --nova-font-title: Poppins, Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}

[data-bs-theme="light"] {
    --nova-page: #F7FBFC;
    --nova-card: #FFFFFF;
    --nova-input: #FFFFFF;
    --nova-ink: #0F4C66;
    --nova-ink-rgb: 15, 76, 102;
    --nova-text: #0F4C66;
    --nova-muted: #5D7380;
    --nova-tint: #E3F3F9;
    --nova-line: #DCEBF1;
    --nova-link: #1F7FA8;
    --nova-link-hover: #0F4C66;
    --nova-link-rgb: 31, 127, 168;
    --nova-link-hover-rgb: 15, 76, 102;
    --nova-ok-bg: #E8F5E1;
    --nova-ok-text: #2A6B1C;
    --nova-warn-bg: #FFF1DC;
    --nova-warn-text: #8A4B00;
    --nova-bad-bg: #FBE6E6;
    --nova-bad-text: #A12C2C;
    --nova-info-bg: #E3F3F9;
    --nova-info-text: #0F4C66;
    --nova-active-bg: #0F4C66;
    --nova-top-bg: #0F4C66;
    --nova-shadow: 0 18px 40px -20px rgba(15, 76, 102, .28), 0 2px 6px rgba(15, 76, 102, .05);
    --nova-glow-ring: 0 0 0 3px rgba(127, 208, 238, .55);
    --nova-band-glow: rgba(92, 193, 223, .30);

    --nova-alert-ok-bg: #E8F5E1;
    --nova-alert-ok-text: #2A6B1C;
    --nova-alert-ok-border: #CBE7BC;
    --nova-alert-warn-bg: #FFF1DC;
    --nova-alert-warn-text: #6B3A00;
    --nova-alert-warn-border: #F5D9A8;
    --nova-alert-bad-bg: #FBE6E6;
    --nova-alert-bad-text: #A12C2C;
    --nova-alert-bad-border: #F1BFBF;
    --nova-alert-info-bg: #E3F3F9;
    --nova-alert-info-text: #0F4C66;
    --nova-alert-info-border: #BFE2F0;

    --bs-primary-text-emphasis: #0F4C66;
    --bs-primary-bg-subtle: #E3F3F9;
    --bs-primary-border-subtle: #BFE2F0;
}

[data-bs-theme="dark"] {
    --nova-page: #061C27;
    --nova-card: #0B3347;
    --nova-input: #082A3B;
    --nova-ink: #E6F1F5;
    --nova-ink-rgb: 230, 241, 245;
    --nova-text: #E6F1F5;
    --nova-muted: #9FB6C2;
    --nova-tint: rgba(127, 208, 238, .12);
    --nova-line: rgba(127, 208, 238, .16);
    --nova-link: #7FD0EE;
    --nova-link-hover: #B5E4F5;
    --nova-link-rgb: 127, 208, 238;
    --nova-link-hover-rgb: 181, 228, 245;
    --nova-ok-bg: rgba(115, 191, 68, .16);
    --nova-ok-text: #A8E08A;
    --nova-warn-bg: rgba(255, 147, 54, .16);
    --nova-warn-text: #FFC48A;
    --nova-bad-bg: rgba(255, 110, 110, .16);
    --nova-bad-text: #FFABAB;
    --nova-info-bg: rgba(127, 208, 238, .14);
    --nova-info-text: #B5E4F5;
    --nova-active-bg: #1B6F95;
    --nova-top-bg: #1B6F95;
    --nova-shadow: 0 18px 40px -20px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .2);
    --nova-glow-ring: 0 0 0 3px rgba(127, 208, 238, .45);
    --nova-band-glow: rgba(92, 193, 223, .16);

    --nova-alert-ok-bg: #1C3A2C;
    --nova-alert-ok-text: #A8E08A;
    --nova-alert-ok-border: #2F5A3F;
    --nova-alert-warn-bg: #3A2E1C;
    --nova-alert-warn-text: #FFC48A;
    --nova-alert-warn-border: #5C4727;
    --nova-alert-bad-bg: #3B2230;
    --nova-alert-bad-text: #FFABAB;
    --nova-alert-bad-border: #61364A;
    --nova-alert-info-bg: #0E3F57;
    --nova-alert-info-text: #B5E4F5;
    --nova-alert-info-border: #1B6F95;

    --bs-primary-text-emphasis: #B5E4F5;
    --bs-primary-bg-subtle: #0E3F57;
    --bs-primary-border-subtle: #1B6F95;
}

[data-bs-theme] {
    --bs-font-sans-serif: var(--nova-font);
    --bs-body-font-family: var(--nova-font);
    --bs-body-color: var(--nova-text);
    --bs-body-color-rgb: var(--nova-ink-rgb);
    --bs-emphasis-color: var(--nova-ink);
    --bs-emphasis-color-rgb: var(--nova-ink-rgb);
    --bs-secondary-color: var(--nova-muted);
    --bs-body-bg: var(--nova-page);
    --bs-tertiary-bg: var(--nova-tint);
    --bs-border-color: var(--nova-line);
    --bs-border-radius: var(--nova-radius-item);

    /* Primary as text and fill utilities (.text-primary, .bg-primary) uses the
       accessible link blue. Buttons use the green action via their own
       variables below. */
    --bs-primary: var(--nova-link);
    --bs-primary-rgb: var(--nova-link-rgb);
    --bs-success: var(--nova-action);
    --bs-success-rgb: 47, 125, 31;
    --bs-danger: var(--nova-danger);
    --bs-danger-rgb: 196, 56, 56;

    --bs-link-color: var(--nova-link);
    --bs-link-color-rgb: var(--nova-link-rgb);
    --bs-link-hover-color: var(--nova-link-hover);
    --bs-link-hover-color-rgb: var(--nova-link-hover-rgb);
}

/* ---------------------------------------------------------------- Page */

/*
 * Night-sky band: a dark ink band with faint stars and a blue glow sits at the
 * top of the page, so the header lies on it and the first cards overlap its
 * edge. Layers, top to bottom: stars, glow, band, then the page colour.
 */
body {
    font-family: var(--nova-font);
    background-color: var(--nova-page);
    background-image:
        radial-gradient(1px 1px at 12% 22%, rgba(255, 255, 255, .55), transparent),
        radial-gradient(1px 1px at 31% 64%, rgba(255, 255, 255, .4), transparent),
        radial-gradient(1.5px 1.5px at 47% 18%, rgba(255, 255, 255, .5), transparent),
        radial-gradient(1px 1px at 63% 52%, rgba(255, 255, 255, .45), transparent),
        radial-gradient(1px 1px at 78% 30%, rgba(255, 255, 255, .5), transparent),
        radial-gradient(1.5px 1.5px at 91% 70%, rgba(255, 255, 255, .4), transparent),
        radial-gradient(ellipse 60% 120% at 85% 0%, var(--nova-band-glow), transparent 70%),
        linear-gradient(180deg, var(--nova-night) 0%, var(--nova-night-end) 100%);
    background-repeat: no-repeat;
    background-size: 100% var(--nova-band);
    background-attachment: scroll;
    min-height: 100%;
}

[data-bs-theme="dark"] body {
    /* In dark mode the band melts into the page instead of ending in an edge. */
    background-image:
        radial-gradient(1px 1px at 12% 22%, rgba(255, 255, 255, .55), transparent),
        radial-gradient(1px 1px at 31% 64%, rgba(255, 255, 255, .4), transparent),
        radial-gradient(1.5px 1.5px at 47% 18%, rgba(255, 255, 255, .5), transparent),
        radial-gradient(1px 1px at 63% 52%, rgba(255, 255, 255, .45), transparent),
        radial-gradient(1px 1px at 78% 30%, rgba(255, 255, 255, .5), transparent),
        radial-gradient(1.5px 1.5px at 91% 70%, rgba(255, 255, 255, .4), transparent),
        radial-gradient(ellipse 60% 120% at 85% 0%, var(--nova-band-glow), transparent 70%),
        linear-gradient(180deg, #0A2D40 0%, var(--nova-page) 100%);
    background-size: 100% 420px;
}

h1, h2, h3, h4, h5, h6 {
    color: var(--nova-ink);
    font-family: var(--nova-font-title);
    font-weight: 600;
}

a {
    text-underline-offset: .2em;
}

/* -------------------------------------------------------------- Header */

header {
    border-bottom: 1px solid rgba(127, 208, 238, .28);
}

header,
header .navbar {
    background-color: transparent;
}

/* Air between the divider line and the first cards. The header is positioned
   so the language dropdown opens above the cards instead of behind them. */
header {
    position: relative;
    z-index: 1030;
    margin-bottom: 2rem;
}

header .navbar {
    --bs-navbar-color: #FFFFFF;
    --bs-navbar-hover-color: var(--nova-glow);
    --bs-navbar-active-color: #FFFFFF;
    --bs-navbar-brand-color: var(--nova-logo-blue);
    --bs-navbar-brand-hover-color: var(--nova-logo-blue);
    --bs-navbar-toggler-border-color: rgba(127, 208, 238, .5);
    --bs-navbar-toggler-icon-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 30 30'%3e%3cpath stroke='rgba%28255,255,255,0.9%29' stroke-linecap='round' stroke-miterlimit='10' stroke-width='2' d='M4 7h22M4 15h22M4 23h22'/%3e%3c/svg%3e");
}

/* Wordmark next to the logo: a real text node in the layout */
.edison-brand {
    display: inline-flex;
    align-items: center;
    gap: .75rem;
}

.edison-wordmark {
    color: var(--nova-logo-blue);
    font-family: var(--nova-font-title);
    font-weight: 600;
    font-size: 1.25rem;
    letter-spacing: .01em;
    white-space: nowrap;
}

/*
 * Huraga marks the sun icon .text-white and the moon .text-dark. Utility
 * classes are !important in Bootstrap, so the moon needs !important here to be
 * visible on the night band.
 */
header .icon.text-dark {
    color: #FFFFFF !important;
}

header .nav-link,
header .client-dropdown .nav-link.dropdown-toggle {
    color: #FFFFFF;
}

header .nav-link:hover,
header .nav-link:focus-visible,
header .client-dropdown .nav-link.dropdown-toggle:hover {
    color: var(--nova-glow);
}

/*
 * Language selector: glassy pill. TomSelect wraps the select in
 * .ts-wrapper.form-select, so the pill and the caret live on the wrapper and
 * the inner control is made invisible.
 */
header .form-select {
    background-color: rgba(255, 255, 255, .08);
    border: 1px solid rgba(127, 208, 238, .4);
    border-radius: 50rem;
    color: #FFFFFF;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}

header .ts-wrapper .ts-control {
    background: transparent;
    border: 0;
    box-shadow: none;
    color: #FFFFFF;
}

header .ts-wrapper .ts-control input,
header .ts-wrapper .ts-control .item {
    color: #FFFFFF;
}

header .form-select {
    --bs-form-select-bg-img: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23FFFFFF' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

/* Register and other outline buttons in the header: light-blue outline pill */
header .btn-outline-primary {
    --bs-btn-color: var(--nova-glow);
    --bs-btn-border-color: var(--nova-glow);
    --bs-btn-hover-color: var(--nova-night);
    --bs-btn-hover-bg: var(--nova-glow);
    --bs-btn-hover-border-color: var(--nova-glow);
    --bs-btn-active-color: var(--nova-night);
    --bs-btn-active-bg: var(--nova-logo-blue);
    --bs-btn-active-border-color: var(--nova-logo-blue);
    --bs-btn-disabled-color: var(--nova-glow);
    --bs-btn-disabled-border-color: var(--nova-glow);
}

/* Language list (TomSelect dropdown) */
header .ts-dropdown {
    margin-top: .5rem;
    border: 1px solid var(--nova-line);
    border-radius: var(--nova-radius-item);
    background-color: var(--nova-card);
    color: var(--nova-text);
    box-shadow: var(--nova-shadow);
    overflow: hidden;
}

header .ts-dropdown .option {
    padding: .5rem .875rem;
}

header .ts-dropdown .active,
header .ts-dropdown .option:hover {
    background-color: var(--nova-tint);
    color: var(--nova-ink);
}

header .ts-dropdown .selected {
    font-weight: 600;
}

header .dropdown-menu {
    --bs-dropdown-bg: var(--nova-card);
    --bs-dropdown-color: var(--nova-text);
    --bs-dropdown-link-color: var(--nova-text);
    --bs-dropdown-link-hover-bg: var(--nova-tint);
    --bs-dropdown-border-color: var(--nova-line);
    --bs-dropdown-border-radius: var(--nova-radius-item);
    box-shadow: var(--nova-shadow);
}

/* --------------------------------------------------------------- Cards */

.card {
    --bs-card-border-radius: var(--nova-radius-card);
    --bs-card-inner-border-radius: calc(var(--nova-radius-card) - 1px);
    --bs-card-border-color: var(--nova-line);
    --bs-card-bg: var(--nova-card);
    --bs-card-cap-bg: transparent;
    --bs-card-cap-padding-x: 1.75rem;
    --bs-card-spacer-x: 1.75rem;
    --bs-card-spacer-y: 1.5rem;
    box-shadow: var(--nova-shadow);
}

/* No grey header bar or divider: title and buttons share one row. */
.card-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    flex-wrap: wrap;
    gap: .5rem;
    background-color: transparent;
    border-bottom: 0;
    padding-top: 1.5rem;
    padding-bottom: 0;
}

.card-header + .card-body {
    padding-top: .75rem;
}

.card-header h1,
.card-header h2,
.card-header h3,
.card-header h4,
.card-header h5,
.card-header h6,
.card-header.h6,
.card-title {
    margin: 0;
    font-family: var(--nova-font-title);
    font-weight: 600;
    font-size: 1.25rem;
    color: var(--nova-ink);
}

.card-footer {
    display: flex;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: .5rem;
    background-color: transparent;
    border-top: 1px solid var(--nova-line);
}

/* Key/value rows: label left, value right, thin separators */
.card .list-group {
    --bs-list-group-bg: transparent;
    --bs-list-group-border-color: var(--nova-line);
    --bs-list-group-color: var(--nova-text);
}

.card .list-group-item {
    background-color: transparent;
}

.table {
    --bs-table-color: var(--nova-text);
    --bs-table-bg: transparent;
    --bs-table-border-color: var(--nova-line);
    --bs-table-striped-bg: var(--nova-tint);
    --bs-table-hover-bg: var(--nova-tint);
}

/* ------------------------------------------------------------- Sidebar */

/* One card; separator lines removed; rounded rows */
/* Bootstrap's .offcanvas-md .offcanvas-body sets a transparent background
   with !important at md and up, so the card colour needs !important. */
#sidebarMenu .offcanvas-body {
    background-color: var(--nova-card) !important;
    border: 1px solid var(--nova-line);
    border-radius: var(--nova-radius-card);
    box-shadow: var(--nova-shadow);
    padding: .875rem;
}

.offcanvas-item,
.offcanvas-item:first-child {
    border: 0;
}

.offcanvas-item {
    margin-bottom: .25rem;
    border-radius: var(--nova-radius-item);
}

.offcanvas-item:hover {
    background-color: var(--nova-tint);
}

.offcanvas-item > a {
    padding: .75rem 1rem;
    color: var(--nova-text);
    font-weight: 500;
}

.offcanvas-item > a .icon {
    color: var(--nova-link);
}

.offcanvas-item > a:hover {
    color: var(--nova-ink);
}

.offcanvas-item.active {
    background-color: var(--nova-tint);
    box-shadow: var(--nova-glow-ring), inset 0 0 0 1px var(--nova-glow);
}

.offcanvas-item.active > a,
.offcanvas-item > a.active {
    color: var(--nova-ink);
    font-weight: 600;
}

/*
 * Account balance: small ink-blue card (the li that holds the amount; the
 * optional sidebar note keeps the plain look).
 * Huraga sets padding with .pt-3 / .ps-3 utilities (!important), so the
 * padding here needs !important too. The h5 colour is .text-secondary.
 */
#sidebarMenu .nav > li:has(> h6) {
    margin-top: .75rem;
    padding: 1rem 1.25rem !important;
    border-radius: var(--nova-radius-item);
    color: #FFFFFF;
    background:
        radial-gradient(circle at 90% 20%, rgba(127, 208, 238, .35), transparent 55%),
        linear-gradient(135deg, #0F4C66 0%, #0B3347 100%);
}

#sidebarMenu .nav > li:has(> h6) h5 {
    color: var(--nova-glow) !important;
    font-family: var(--nova-font);
    font-size: .75rem;
    font-weight: 600;
    letter-spacing: .12em;
    text-transform: uppercase;
}

#sidebarMenu .nav > li:has(> h6) h6,
#sidebarMenu .nav > li:has(> h6) span {
    color: #FFFFFF;
    font-family: var(--nova-font-title);
}

#sidebarMenu .nav > li:has(> h6) h6 {
    font-size: 1.75rem;
}

/* ------------------------------------------------------------- Buttons */

.btn {
    --bs-btn-border-radius: 50rem;
    --bs-btn-padding-x: 1.125rem;
    font-weight: 600;
}

.btn:focus-visible {
    box-shadow: var(--nova-glow-ring);
}

/* Default action: Edison blue. White on it fails (about 2:1), so the text is
   the night ink. */
.btn-primary,
.btn-info {
    --bs-btn-color: var(--nova-night);
    --bs-btn-bg: var(--nova-logo-blue);
    --bs-btn-border-color: var(--nova-logo-blue);
    --bs-btn-hover-color: var(--nova-night);
    --bs-btn-hover-bg: #4DB3D3;
    --bs-btn-hover-border-color: #4DB3D3;
    --bs-btn-focus-shadow-rgb: 127, 208, 238;
    --bs-btn-active-color: var(--nova-night);
    --bs-btn-active-bg: #45A8C8;
    --bs-btn-active-border-color: #45A8C8;
    --bs-btn-disabled-color: var(--nova-night);
    --bs-btn-disabled-bg: var(--nova-logo-blue);
    --bs-btn-disabled-border-color: var(--nova-logo-blue);
}

/* Success keeps the green (white on #2F7D1F is 5.2:1) */
.btn-success {
    --bs-btn-color: #FFFFFF;
    --bs-btn-bg: var(--nova-action);
    --bs-btn-border-color: var(--nova-action);
    --bs-btn-hover-color: #FFFFFF;
    --bs-btn-hover-bg: var(--nova-action-hover);
    --bs-btn-hover-border-color: var(--nova-action-hover);
    --bs-btn-focus-shadow-rgb: 127, 208, 238;
    --bs-btn-active-color: #FFFFFF;
    --bs-btn-active-bg: var(--nova-action-active);
    --bs-btn-active-border-color: var(--nova-action-active);
    --bs-btn-disabled-color: #FFFFFF;
    --bs-btn-disabled-bg: var(--nova-action);
    --bs-btn-disabled-border-color: var(--nova-action);
}

/* Everything else is a quiet outline */
.btn-outline-primary,
.btn-outline-secondary,
.btn-outline-info,
.btn-secondary,
.btn-dark,
.btn-light {
    --bs-btn-color: var(--nova-ink);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: var(--nova-line);
    --bs-btn-hover-color: var(--nova-ink);
    --bs-btn-hover-bg: var(--nova-tint);
    --bs-btn-hover-border-color: var(--nova-glow);
    --bs-btn-focus-shadow-rgb: 127, 208, 238;
    --bs-btn-active-color: var(--nova-ink);
    --bs-btn-active-bg: var(--nova-tint);
    --bs-btn-active-border-color: var(--nova-glow);
    --bs-btn-disabled-color: var(--nova-muted);
    --bs-btn-disabled-bg: transparent;
    --bs-btn-disabled-border-color: var(--nova-line);
}

.btn-warning {
    --bs-btn-color: #1F1300;
    --bs-btn-bg: #FF9336;
    --bs-btn-border-color: #FF9336;
    --bs-btn-hover-color: #1F1300;
    --bs-btn-hover-bg: #F28726;
    --bs-btn-hover-border-color: #F28726;
    --bs-btn-focus-shadow-rgb: 255, 147, 54;
    --bs-btn-active-color: #1F1300;
    --bs-btn-active-bg: #E57D1C;
    --bs-btn-active-border-color: #E57D1C;
    --bs-btn-disabled-color: #1F1300;
    --bs-btn-disabled-bg: #FF9336;
    --bs-btn-disabled-border-color: #FF9336;
}

/* Danger: Edison pink. White on it fails (about 3:1), so the text is dark
   (5.5:1 on #EC5CA2). */
.btn-danger {
    --bs-btn-color: var(--nova-night);
    --bs-btn-bg: var(--nova-pink);
    --bs-btn-border-color: var(--nova-pink);
    --bs-btn-hover-color: var(--nova-night);
    --bs-btn-hover-bg: #E24C95;
    --bs-btn-hover-border-color: #E24C95;
    --bs-btn-focus-shadow-rgb: 236, 92, 162;
    --bs-btn-active-color: var(--nova-night);
    --bs-btn-active-bg: #D63F88;
    --bs-btn-active-border-color: #D63F88;
    --bs-btn-disabled-color: var(--nova-night);
    --bs-btn-disabled-bg: var(--nova-pink);
    --bs-btn-disabled-border-color: var(--nova-pink);
}

/* "Top" button: ink pill with a soft glow */
a.btn.position-fixed[href="#top"] {
    --bs-btn-color: #FFFFFF;
    --bs-btn-bg: var(--nova-top-bg);
    --bs-btn-border-color: transparent;
    --bs-btn-hover-color: #FFFFFF;
    --bs-btn-hover-bg: var(--nova-night-end);
    --bs-btn-hover-border-color: transparent;
    box-shadow: 0 8px 24px -6px rgba(92, 193, 223, .55);
}

/* ------------------------------------------------------ Badges, status */

/*
 * Soft pills with a dot (Active, Pending, Expired). Bootstrap's .bg-* and
 * .text-bg-* helpers set colours with !important, so the badge colours need
 * !important here to win against them.
 */
.badge {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    padding: .35em .8em;
    border-radius: 50rem;
    font-weight: 600;
}

.badge::before {
    content: "";
    width: .5em;
    height: .5em;
    border-radius: 50%;
    background-color: currentColor;
}

.badge.bg-success,
.badge.text-bg-success {
    background-color: var(--nova-ok-bg) !important;
    color: var(--nova-ok-text) !important;
}

.badge.bg-warning,
.badge.text-bg-warning {
    background-color: var(--nova-warn-bg) !important;
    color: var(--nova-warn-text) !important;
}

.badge.bg-danger,
.badge.text-bg-danger {
    background-color: var(--nova-bad-bg) !important;
    color: var(--nova-bad-text) !important;
}

.badge.bg-primary,
.badge.bg-info,
.badge.bg-secondary,
.badge.bg-dark,
.badge.bg-light,
.badge.text-bg-primary,
.badge.text-bg-info,
.badge.text-bg-secondary,
.badge.text-bg-dark,
.badge.text-bg-light {
    background-color: var(--nova-info-bg) !important;
    color: var(--nova-info-text) !important;
}

/*
 * Alerts sit on the page or straddle the night band, so their background has
 * to be opaque: Bootstrap's translucent tints turn dark on the band and leave
 * red text unreadable.
 */
.alert {
    --bs-alert-border-radius: var(--nova-radius-item);
    --bs-alert-padding-x: 1.25rem;
    --bs-alert-padding-y: 1rem;
}

.alert-success {
    --bs-alert-color: var(--nova-alert-ok-text);
    --bs-alert-bg: var(--nova-alert-ok-bg);
    --bs-alert-border-color: var(--nova-alert-ok-border);
    --bs-alert-link-color: var(--nova-alert-ok-text);
}

.alert-warning {
    --bs-alert-color: var(--nova-alert-warn-text);
    --bs-alert-bg: var(--nova-alert-warn-bg);
    --bs-alert-border-color: var(--nova-alert-warn-border);
    --bs-alert-link-color: var(--nova-alert-warn-text);
}

.alert-danger {
    --bs-alert-color: var(--nova-alert-bad-text);
    --bs-alert-bg: var(--nova-alert-bad-bg);
    --bs-alert-border-color: var(--nova-alert-bad-border);
    --bs-alert-link-color: var(--nova-alert-bad-text);
}

.alert-info,
.alert-primary {
    --bs-alert-color: var(--nova-alert-info-text);
    --bs-alert-bg: var(--nova-alert-info-bg);
    --bs-alert-border-color: var(--nova-alert-info-border);
    --bs-alert-link-color: var(--nova-alert-info-text);
}

.alert .btn {
    margin-top: .5rem;
}

.alert > :last-child {
    margin-bottom: 0;
}

/* --------------------------------------------------------------- Forms */

.form-control,
.form-select {
    border-radius: var(--nova-radius-item);
    background-color: var(--nova-input);
    border-color: var(--nova-line);
    color: var(--nova-text);
}

.form-control:focus,
.form-select:focus {
    background-color: var(--nova-input);
    border-color: var(--nova-glow);
    box-shadow: var(--nova-glow-ring);
}

.input-group-text {
    background-color: var(--nova-tint);
    border-color: var(--nova-line);
    color: var(--nova-muted);
}

.form-check-input:checked,
.form-check-input[type="checkbox"]:indeterminate {
    background-color: var(--nova-action);
    border-color: var(--nova-action);
}

.form-check-input:focus {
    border-color: var(--nova-glow);
    box-shadow: var(--nova-glow-ring);
}

.form-switch .form-check-input:focus:not(:checked) {
    --bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%237FD0EE'/%3e%3c/svg%3e");
}

.form-range::-webkit-slider-thumb {
    background-color: var(--nova-action);
}

.form-range::-moz-range-thumb {
    background-color: var(--nova-action);
}

/* ------------------------------------------------ Navigation components */

.nav-pills {
    --bs-nav-pills-border-radius: 50rem;
    --bs-nav-pills-link-active-color: #FFFFFF;
    --bs-nav-pills-link-active-bg: var(--nova-active-bg);
}

.nav-tabs {
    --bs-nav-tabs-link-active-color: var(--nova-ink);
    --bs-nav-tabs-link-active-bg: var(--nova-card);
    --bs-nav-tabs-link-active-border-color: var(--nova-line) var(--nova-line) var(--nova-card);
    --bs-nav-tabs-border-color: var(--nova-line);
}

.pagination {
    --bs-pagination-color: var(--nova-link);
    --bs-pagination-bg: var(--nova-card);
    --bs-pagination-border-color: var(--nova-line);
    --bs-pagination-hover-color: var(--nova-ink);
    --bs-pagination-hover-bg: var(--nova-tint);
    --bs-pagination-hover-border-color: var(--nova-line);
    --bs-pagination-active-color: #FFFFFF;
    --bs-pagination-active-bg: var(--nova-active-bg);
    --bs-pagination-active-border-color: var(--nova-active-bg);
    --bs-pagination-focus-box-shadow: var(--nova-glow-ring);
}

.dropdown-menu {
    --bs-dropdown-bg: var(--nova-card);
    --bs-dropdown-border-color: var(--nova-line);
    --bs-dropdown-border-radius: var(--nova-radius-item);
    --bs-dropdown-link-hover-bg: var(--nova-tint);
    --bs-dropdown-link-active-color: #FFFFFF;
    --bs-dropdown-link-active-bg: var(--nova-active-bg);
}

.list-group {
    --bs-list-group-active-color: #FFFFFF;
    --bs-list-group-active-bg: var(--nova-active-bg);
    --bs-list-group-active-border-color: var(--nova-active-bg);
}

.accordion {
    --bs-accordion-bg: var(--nova-card);
    --bs-accordion-border-color: var(--nova-line);
    --bs-accordion-active-color: var(--nova-ink);
    --bs-accordion-active-bg: var(--nova-tint);
    --bs-accordion-btn-focus-border-color: var(--nova-glow);
    --bs-accordion-btn-focus-box-shadow: var(--nova-glow-ring);
}

.modal {
    --bs-modal-bg: var(--nova-card);
    --bs-modal-border-color: var(--nova-line);
    --bs-modal-border-radius: var(--nova-radius-card);
}

.progress,
.progress-stacked {
    --bs-progress-bar-bg: var(--nova-logo-blue);
    --bs-progress-bar-color: var(--nova-night);
}

.breadcrumb {
    --bs-breadcrumb-divider-color: var(--nova-muted);
    --bs-breadcrumb-item-active-color: var(--nova-muted);
}

/* Huraga: payment gateway choice on invoices */
.invoice-gateway {
    border-radius: var(--nova-radius-item);
}

.invoice-gateway:hover {
    border-color: var(--nova-glow);
}

/* -------------------------------------------------------------- Footer */

footer {
    color: var(--nova-muted);
}

.edison-slogan {
    margin-bottom: .5rem;
    text-align: center;
    color: var(--nova-link);
    font-family: var(--nova-font-title);
    font-size: .95rem;
    font-weight: 500;
    letter-spacing: .02em;
}

/* ------------------------------------------------- Logged-out home page */

/* Welcome line on the night band (template edit, logged-out home only) */
.edison-welcome {
    margin: 0 0 1.75rem;
    color: #FFFFFF;
}

.edison-welcome h1 {
    margin: 0 0 .5rem;
    color: #FFFFFF;
    font-size: 2.25rem;
}

.edison-welcome p {
    margin: 0;
    color: rgba(255, 255, 255, .85);
}

/* Small icon tile beside a card title (template edit) */
.edison-card-icon {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 2.75rem;
    height: 2.75rem;
    margin-right: .75rem;
    border-radius: var(--nova-radius-item);
    background-color: var(--nova-tint);
    color: var(--nova-link);
    flex: none;
}

/* ------------------------------------------------------------ Dashboard */

/*
 * Key/value rows. Huraga renders them as <dt class="col-sm-4"> and
 * <dd class="col-sm-8"> inside a .row. The row becomes a two-column grid:
 * label left, value right in Poppins, thin separators.
 */
.card-body > .row:has(> dt) {
    --bs-gutter-x: 0;
    display: grid;
    grid-template-columns: 1fr auto;
    margin: 0;
}

.card-body > .row > dt,
.card-body > .row > dd {
    width: auto;
    max-width: none;
    margin: 0;
    padding: .75rem 0;
    border-bottom: 1px solid var(--nova-line);
}

.card-body > .row > dt {
    color: var(--nova-muted);
    font-size: .95rem;
}

.card-body > .row > dd {
    padding-left: 1rem;
    text-align: right;
    overflow-wrap: anywhere;
    color: var(--nova-ink);
    font-family: var(--nova-font-title);
    font-weight: 600;
}

.card-body > .row > :nth-last-child(-n+2) {
    border-bottom: 0;
}

/*
 * Recent orders and support tickets: each row is a tinted rounded tile.
 * Huraga puts .p-1 (!important) on the card body, so its padding needs
 * !important here.
 */
.card-body.p-1 {
    padding: .5rem 1.75rem 1.5rem !important;
}

.card-body.p-1 > .list-group {
    --bs-list-group-border-radius: var(--nova-radius-item);
    gap: .5rem;
}

.card-body.p-1 > .list-group > .list-group-item {
    padding: 1rem 1.25rem;
    border: 0;
    border-radius: var(--nova-radius-item);
    background-color: var(--nova-tint);
    color: var(--nova-ink);
}

.card-body.p-1 > .list-group > .list-group-item:hover {
    box-shadow: inset 0 0 0 1px var(--nova-glow);
}

.card-body.p-1 > .list-group strong {
    font-family: var(--nova-font-title);
    font-weight: 600;
}

/* Empty state: dashed box. .my-2 and .p-2 are !important utilities in the
   template; only border, radius and colour are set here. */
.card-body.p-1 > .d-flex.justify-content-center {
    margin: 0 !important;
    border: 1px dashed var(--nova-glow);
    border-radius: var(--nova-radius-item);
    color: var(--nova-muted);
}

/* On the logged-out home the band is taller so the welcome line fits in it */
body:has(.edison-welcome) {
    --nova-band: 300px;
}

/* .text-secondary is !important in Bootstrap; the dim grey fails on the dark tint */
.card-body.p-1 > .list-group .text-secondary {
    color: var(--nova-muted) !important;
}

/*
 * List cards get a minimum height, so a list with a single row or an empty
 * state does not leave the footer riding up under a small box. A list card is
 * a full-width card (Huraga puts it in .col-md-12) that has a table header or
 * holds only an empty-state message. Detail pages (key/value tables, message
 * cards) have neither and keep their natural height. The body grows to fill the
 * card and a lone empty-state message sits in the middle of it. Phones get a
 * smaller minimum. The dashboard cards are .col-md-6 and are not affected.
 */
.content-block .col-md-12 > .card:has(thead),
.content-block .col-md-12 > .card:has(> .card-body > .d-flex.justify-content-center:only-child) {
    display: flex;
    flex-direction: column;
    min-height: clamp(18rem, 46vh, 30rem);
}

.content-block .col-md-12 > .card:has(thead) > .card-body,
.content-block .col-md-12 > .card:has(> .card-body > .d-flex.justify-content-center:only-child) > .card-body {
    flex: 1 1 auto;
}

.card-body:has(> .d-flex.justify-content-center:only-child) {
    display: flex;
    align-items: center;
    justify-content: center;
}

@media (max-width: 767.98px) {
    .content-block .col-md-12 > .card:has(thead),
    .content-block .col-md-12 > .card:has(> .card-body > .d-flex.justify-content-center:only-child) {
        min-height: 12rem;
    }
}

/* Header row with title on the left and an action on the right: Huraga nests a
   .d-flex row inside .card-header; it has to fill the header. */
.card-header > .d-flex {
    flex: 1 1 100%;
}

/* ------------------------------------------------- Login and sign-up pages */

/*
 * The secondary actions under the main button ("Create Account", "Forgot
 * Password?", "Already a User?") are plain text links, so the one real button
 * keeps the attention. Huraga puts page-login, page-signup and
 * page-password-reset on the body.
 */
.page-login .card .btn:not(.btn-primary),
.page-signup .card .btn:not(.btn-primary),
.page-password-reset .card .btn:not(.btn-primary) {
    --bs-btn-color: var(--nova-link);
    --bs-btn-bg: transparent;
    --bs-btn-border-color: transparent;
    --bs-btn-hover-color: var(--nova-link-hover);
    --bs-btn-hover-bg: transparent;
    --bs-btn-hover-border-color: transparent;
    --bs-btn-active-color: var(--nova-link-hover);
    --bs-btn-active-bg: transparent;
    --bs-btn-active-border-color: transparent;
    --bs-btn-padding-x: .25rem;
    font-weight: 500;
    text-decoration: underline;
    text-underline-offset: .2em;
}

.page-login .card .btn:not(.btn-primary):hover,
.page-signup .card .btn:not(.btn-primary):hover,
.page-password-reset .card .btn:not(.btn-primary):hover {
    text-decoration-thickness: 2px;
}
