/*
 * theme.css - the house style, layered over stock Bootstrap 5.
 *
 * Loaded last, after bootstrap.min.css and dashboard.css, so it wins
 * without needing !important except where a Bootstrap utility class is
 * set directly on an element in the markup.
 *
 * It works mostly by redefining Bootstrap's own custom properties, so
 * components nobody has styled here - dropdowns, modals, pagination -
 * still come out in the same palette rather than looking like a
 * different product.
 *
 * Nothing here needs a build step or a rebuild of the binary:
 * templates and static files are read from disk per request.
 */

:root {
  /* Brand. One blue, used for action and for "you are here", and
     nothing else - a second accent colour is how an interface starts
     looking like a toy. */
  --sp-brand: #2563eb;
  --sp-brand-dark: #1d4ed8;
  --sp-brand-soft: #eff4ff;
  --sp-brand-ring: rgba(37, 99, 235, .25);

  /* The shell: a deep navy header and rail against near-white content,
     so the working area is the brightest thing on screen. */
  --sp-shell: #0f172a;
  --sp-shell-2: #1e293b;

  /* Neutrals - a cool grey ramp, cooler than Bootstrap's, which reads
     as cleaner next to the navy. */
  --sp-bg: #f6f8fb;
  --sp-surface: #ffffff;
  --sp-border: #e4e9f0;
  --sp-border-strong: #d4dbe6;
  --sp-ink: #0f172a;
  --sp-ink-2: #334155;
  --sp-muted: #64748b;

  /* Status, muted a shade from Bootstrap's defaults: a bill that is
     merely unpaid should not shout like an outage. */
  --sp-ok: #047857;
  --sp-ok-soft: #e7f6ef;
  --sp-warn: #b45309;
  --sp-warn-soft: #fdf3e3;
  --sp-bad: #b91c1c;
  --sp-bad-soft: #fdeded;

  --sp-radius: 12px;
  --sp-radius-sm: 8px;
  --sp-shadow: 0 1px 2px rgba(15, 23, 42, .04), 0 1px 3px rgba(15, 23, 42, .06);
  --sp-shadow-lg: 0 4px 6px -2px rgba(15, 23, 42, .05), 0 12px 20px -8px rgba(15, 23, 42, .12);

  /* Hand the palette to Bootstrap itself. */
  --bs-primary: var(--sp-brand);
  --bs-primary-rgb: 37, 99, 235;
  --bs-body-color: var(--sp-ink-2);
  --bs-body-bg: var(--sp-bg);
  --bs-border-color: var(--sp-border);
  --bs-border-radius: var(--sp-radius-sm);
  --bs-link-color: var(--sp-brand-dark);
  --bs-link-hover-color: var(--sp-brand);
  --bs-secondary-color: var(--sp-muted);
}

/* ---------------------------------------------------------------- *
 * Typography
 * ---------------------------------------------------------------- */

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
    "Helvetica Neue", Arial, "Noto Sans", sans-serif;
  /* 15px: the stock dashboard's 14px reads as cramped at desktop
     widths, and this is a screen people sit in front of all day. */
  font-size: .9375rem;
  line-height: 1.55;
  color: var(--sp-ink-2);
  background-color: var(--sp-bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {
  color: var(--sp-ink);
  font-weight: 650;
  letter-spacing: -.011em;
}

h1, .h1 { font-size: 1.5rem; }
h2, .h2 { font-size: 1.25rem; }
h3, .h3 { font-size: 1.125rem; }

/* Money and dates line up column to column. In a billing app this is
   not decoration: ragged digits make two amounts hard to compare at a
   glance, which is the one thing these tables are for. */
.table,
.font-monospace,
.fs-3, .fs-4, .fs-5 {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

.text-muted { color: var(--sp-muted) !important; }

.font-monospace {
  font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas,
    "Liberation Mono", monospace;
  font-size: .9em;
}

/* ---------------------------------------------------------------- *
 * The top bar
 * ---------------------------------------------------------------- */

.navbar.sticky-top {
  background-color: var(--sp-shell) !important;
  box-shadow: none;
  border-bottom: 1px solid rgba(255, 255, 255, .06);
  min-height: 56px;
}

.navbar-brand {
  /* dashboard.css gives the brand its own darker panel and an inset
     shadow, which reads as a seam down the page. */
  background-color: transparent !important;
  box-shadow: none !important;
  font-weight: 650;
  font-size: 1.0625rem;
  letter-spacing: -.01em;
  color: #fff !important;
  padding-top: .9rem;
  padding-bottom: .9rem;
}

.navbar .nav-link {
  color: rgba(255, 255, 255, .75) !important;
  font-weight: 500;
}

.navbar .nav-link:hover,
.navbar .nav-link:focus {
  color: #fff !important;
}

.navbar .dropdown-toggle::after { opacity: .6; }

/* ---------------------------------------------------------------- *
 * The sidebar
 * ---------------------------------------------------------------- */

.sidebar {
  background-color: var(--sp-surface) !important;
  box-shadow: none;
  border-right: 1px solid var(--sp-border);
}

.sidebar .position-sticky { padding-top: 1rem !important; }

.sidebar .nav-link {
  display: flex;
  align-items: center;
  gap: .625rem;
  margin: .0625rem .5rem;
  padding: .5rem .75rem;
  border-radius: var(--sp-radius-sm);
  color: var(--sp-ink-2);
  font-weight: 500;
  font-size: .9rem;
  /* The active item grows a bar on its left edge; reserving the space
     up front stops every other item shifting when it appears. */
  border-left: 3px solid transparent;
  transition: background-color .12s ease, color .12s ease;
}

.sidebar .nav-link:hover {
  background-color: #f1f5f9;
  color: var(--sp-ink);
}

.sidebar .nav-link.active {
  background-color: var(--sp-brand-soft);
  border-left-color: var(--sp-brand);
  color: var(--sp-brand-dark);
  font-weight: 600;
}

.sidebar .nav-link .feather { color: var(--sp-muted); }
.sidebar .nav-link.active .feather,
.sidebar .nav-link:hover .feather { color: inherit; }

/* The collapsible "Administration" group header. */
.sidebar-nav-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  font-size: .75rem;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--sp-muted) !important;
  border-radius: var(--sp-radius-sm);
}

.sidebar-nav-toggle:hover { background-color: #f1f5f9; }

.sidebar-nav-toggle .chevron {
  width: 14px;
  height: 14px;
  color: var(--sp-muted);
  transition: transform .2s ease;
}

.sidebar-nav-toggle:not(.collapsed) .chevron { transform: rotate(180deg); }

.sidebar-subnav {
  border-left: 1px solid var(--sp-border);
  margin-left: 1.6rem;
  padding-left: .25rem;
}

.sidebar-subnav .nav-link {
  font-size: .875rem;
  font-weight: 500;
  padding-top: .4rem;
  padding-bottom: .4rem;
}

.sidebar hr {
  margin: .75rem 1rem;
  border-color: var(--sp-border);
  opacity: 1;
}

/* A quiet label above a group of links. */
.sidebar-heading {
  font-size: .6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .07em;
  color: var(--sp-muted);
  padding: .25rem 1.25rem;
  margin-bottom: .125rem;
}

/* ---------------------------------------------------------------- *
 * Content area
 * ---------------------------------------------------------------- */

main {
  padding-top: 1.25rem;
  padding-bottom: 3rem;
}

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

.card {
  background-color: var(--sp-surface);
  border: 1px solid var(--sp-border);
  border-radius: var(--sp-radius);
  box-shadow: none;
}

.card.shadow-sm { box-shadow: var(--sp-shadow) !important; }

.card-header {
  background-color: transparent;
  border-bottom: 1px solid var(--sp-border);
  padding: .875rem 1.125rem;
  font-weight: 600;
  color: var(--sp-ink);
  font-size: .9375rem;
}

.card-header .text-muted { font-weight: 400; }

.card-body { padding: 1.125rem; }

/* Bootstrap's subtle header tints, brought into the palette. */
.card-header.bg-warning-subtle { background-color: var(--sp-warn-soft) !important; }
.card-header.bg-primary-subtle { background-color: var(--sp-brand-soft) !important; }

.card.border-warning { border-color: #f0c88a !important; }
.card.border-primary { border-color: #b9ccf8 !important; }

/* ---------------------------------------------------------------- *
 * Tables
 * ---------------------------------------------------------------- */

.table {
  --bs-table-border-color: var(--sp-border);
  color: var(--sp-ink-2);
  margin-bottom: 0;
}

.table > thead th {
  font-size: .6875rem;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: .05em;
  color: var(--sp-muted);
  background-color: #fbfcfe;
  border-bottom: 1px solid var(--sp-border) !important;
  padding: .625rem .875rem;
  white-space: nowrap;
}

.table > tbody td {
  padding: .6875rem .875rem;
  border-color: var(--sp-border);
  vertical-align: middle;
}

.table > tbody tr:last-child td { border-bottom: 0; }

.table-hover > tbody > tr:hover > * {
  --bs-table-accent-bg: #f8fafc;
  background-color: #f8fafc;
}

.table-striped > tbody > tr:nth-of-type(odd) > * {
  --bs-table-accent-bg: #fcfdfe;
  background-color: #fcfdfe;
}

/* Row tints used to flag a problem line. */
.table-warning > * { background-color: var(--sp-warn-soft) !important; }

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

.btn {
  --bs-btn-border-radius: var(--sp-radius-sm);
  font-weight: 550;
  letter-spacing: -.005em;
  padding: .4375rem .875rem;
  transition: background-color .12s ease, border-color .12s ease, box-shadow .12s ease;
}

.btn-sm { padding: .3125rem .625rem; font-size: .8125rem; }
.btn-lg { padding: .625rem 1.125rem; font-size: 1rem; }

.btn:focus-visible { box-shadow: 0 0 0 3px var(--sp-brand-ring); }

.btn-primary {
  --bs-btn-bg: var(--sp-brand);
  --bs-btn-border-color: var(--sp-brand);
  --bs-btn-hover-bg: var(--sp-brand-dark);
  --bs-btn-hover-border-color: var(--sp-brand-dark);
  --bs-btn-active-bg: var(--sp-brand-dark);
  --bs-btn-disabled-bg: #9db9f4;
  --bs-btn-disabled-border-color: #9db9f4;
}

.btn-outline-secondary {
  --bs-btn-color: var(--sp-ink-2);
  --bs-btn-border-color: var(--sp-border-strong);
  --bs-btn-hover-bg: #f1f5f9;
  --bs-btn-hover-border-color: var(--sp-border-strong);
  --bs-btn-hover-color: var(--sp-ink);
}

.btn-success { --bs-btn-bg: var(--sp-ok); --bs-btn-border-color: var(--sp-ok); }
.btn-danger { --bs-btn-bg: var(--sp-bad); --bs-btn-border-color: var(--sp-bad); }

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

.form-control,
.form-select {
  border-color: var(--sp-border-strong);
  border-radius: var(--sp-radius-sm);
  color: var(--sp-ink);
  padding: .4375rem .75rem;
}

.form-control:focus,
.form-select:focus {
  border-color: var(--sp-brand);
  box-shadow: 0 0 0 3px var(--sp-brand-ring);
}

.form-control::placeholder { color: #9aa7b8; }

.form-label { font-weight: 600; color: var(--sp-ink); font-size: .875rem; }
.form-text { color: var(--sp-muted); font-size: .8125rem; }

.form-check-input:checked {
  background-color: var(--sp-brand);
  border-color: var(--sp-brand);
}

.form-check-input:focus { box-shadow: 0 0 0 3px var(--sp-brand-ring); }

.input-group-text {
  background-color: #f8fafc;
  border-color: var(--sp-border-strong);
  color: var(--sp-muted);
}

/* ---------------------------------------------------------------- *
 * Badges - soft chips rather than saturated blocks. A table of ten
 * solid red pills reads as an emergency; these read as a status.
 * ---------------------------------------------------------------- */

.badge {
  font-weight: 600;
  font-size: .75rem;
  letter-spacing: .01em;
  padding: .3125em .625em;
  border-radius: 999px;
}

.badge.bg-success { background-color: var(--sp-ok-soft) !important; color: var(--sp-ok) !important; }
.badge.bg-danger { background-color: var(--sp-bad-soft) !important; color: var(--sp-bad) !important; }
.badge.bg-warning { background-color: var(--sp-warn-soft) !important; color: var(--sp-warn) !important; }
.badge.bg-secondary { background-color: #eef1f6 !important; color: var(--sp-ink-2) !important; }
.badge.bg-primary { background-color: var(--sp-brand-soft) !important; color: var(--sp-brand-dark) !important; }
.badge.bg-light { background-color: #f1f5f9 !important; color: var(--sp-ink-2) !important; }

/* ---------------------------------------------------------------- *
 * Alerts
 * ---------------------------------------------------------------- */

.alert {
  border-radius: var(--sp-radius);
  border-width: 1px;
  padding: .75rem 1rem;
  font-size: .9rem;
}

.alert-success { background-color: var(--sp-ok-soft); border-color: #bfe3d2; color: #065f46; }
.alert-warning { background-color: var(--sp-warn-soft); border-color: #f2d9b0; color: #92400e; }
.alert-danger { background-color: var(--sp-bad-soft); border-color: #f3c7c7; color: #991b1b; }
.alert-info { background-color: var(--sp-brand-soft); border-color: #c7d9fb; color: #1e40af; }
.alert-secondary { background-color: #f1f5f9; border-color: var(--sp-border); color: var(--sp-ink-2); }
.alert-light { background-color: #fbfcfe; border-color: var(--sp-border); }

/* A banner run edge to edge inside a card keeps its square corners. */
.alert.rounded-0 { border-radius: 0 !important; }

/* ---------------------------------------------------------------- *
 * DataTables - the search box and length picker ship looking like
 * 2012; drag them into the same palette as everything else.
 * ---------------------------------------------------------------- */

.dataTables_wrapper .dataTables_filter input,
.dataTables_wrapper .dataTables_length select {
  border: 1px solid var(--sp-border-strong);
  border-radius: var(--sp-radius-sm);
  padding: .3125rem .625rem;
  margin-left: .375rem;
}

.dataTables_wrapper .dataTables_filter input:focus,
.dataTables_wrapper .dataTables_length select:focus {
  outline: 0;
  border-color: var(--sp-brand);
  box-shadow: 0 0 0 3px var(--sp-brand-ring);
}

.dataTables_wrapper .dataTables_filter,
.dataTables_wrapper .dataTables_length,
.dataTables_wrapper .dataTables_info {
  font-size: .8125rem;
  color: var(--sp-muted);
  padding: .625rem .875rem;
}

.dataTables_wrapper .dataTables_paginate { padding: .625rem .875rem; }

.dataTables_wrapper .page-link {
  border-color: var(--sp-border);
  color: var(--sp-ink-2);
  font-size: .8125rem;
}

.dataTables_wrapper .page-item.active .page-link {
  background-color: var(--sp-brand);
  border-color: var(--sp-brand);
}

/* ---------------------------------------------------------------- *
 * Sign-in and the other standalone pages
 * ---------------------------------------------------------------- */

.form-signin .card,
main[style] > .card {
  border-radius: var(--sp-radius);
  box-shadow: var(--sp-shadow-lg) !important;
}

.form-signin h1 {
  letter-spacing: .14em;
  font-weight: 700;
}

/* ---------------------------------------------------------------- *
 * Printing
 *
 * A bill is printed far more often than any other page here, and it
 * goes to a subscriber. The chrome has no business on the paper, and
 * the content should have the whole width.
 * ---------------------------------------------------------------- */

@media print {
  .navbar,
  #sidebarMenu,
  .no-print {
    display: none !important;
  }

  body {
    background: #fff !important;
    font-size: 11pt;
  }

  main,
  main.col-md-9,
  main.col-lg-10 {
    width: 100% !important;
    max-width: 100% !important;
    flex: 0 0 100% !important;
    margin: 0 !important;
    padding: 0 !important;
  }

  .card {
    border: 0 !important;
    box-shadow: none !important;
  }

  .card-body { padding: 0 !important; }

  a[href]::after { content: ""; }
}
