/* =====================================================================
   MTF Trading Desk — theme layer over Bootstrap 5
   A dealing-room surface: dark slate, tabular figures everywhere,
   green up / red down, and one accent (amber) reserved for money
   the broker is charging you.
   ===================================================================== */

:root {
  --bg:        #0d1117;
  --panel:     #151b24;
  --panel-2:   #1b222d;
  --line:      #262e3a;
  --line-soft: #1e252f;
  --txt:       #e4e8ee;
  --txt-2:     #9aa4b2;
  /* #667080 measured 3.45:1 on --panel and 3.19:1 on --panel-2, both
     under the 4.5:1 WCAG AA minimum for text at these sizes. This is
     used for every explanatory sub-line and form hint in the app, which
     is exactly the text people most need to be able to read. Raised to
     5.14:1 / 4.75:1. */
  --txt-3:     #828d9c;
  --txt-4:     #6b7686;   /* decorative only: rules, disabled, watermarks */

  --up:        #26b877;
  --up-soft:   rgba(38,184,119,.13);
  /* #e5484d measured 4.09:1 on --panel-2, which only clears the large-text
     threshold. It is also used on 12px table figures, so it is lifted to
     the smallest red that passes AA on every surface (4.66:1) while
     staying unmistakably a loss colour. */
  --down:      #ea5a5f;
  --down-soft: rgba(234,90,95,.14);
  --amber:     #d9a441;
  --amber-soft:rgba(217,164,65,.13);
  --blue:      #4c8dff;

  /* Brand, taken from the logo. The navy is lifted for dark surfaces;
     the original #18437B is kept for print and light backgrounds. */
  --brand:        #6ba3de;
  --brand-deep:   #18437B;
  --brand-green:  #8ac27f;
  --brand-grey:   #848483;

  /* Plus Jakarta Sans is geometric enough to sit with the logo's
     rounded letterforms, but it was drawn for interfaces, so it stays
     legible at 12px in a dense table. Inter remains the fallback. */
  --mono: "IBM Plex Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;
  --sans: "Plus Jakarta Sans", "Inter", system-ui, -apple-system, "Segoe UI", sans-serif;

  --tap: 44px;            /* smallest comfortable touch target */
  --radius: 9px;

  /* Native controls are drawn by the browser, not by this stylesheet:
     select popups, date pickers, scrollbars, autofill, spinners. Without
     this they come out in the OS light theme, which is how a dropdown
     ends up as pale grey text on white. One line fixes all of them. */
  color-scheme: dark;
}

[data-bs-theme="dark"] {
  --bs-body-bg: var(--bg);
  --bs-body-color: var(--txt);
  --bs-border-color: var(--line);
  --bs-emphasis-color: var(--txt);
}

body {
  background: var(--bg);
  color: var(--txt);
  font-family: var(--sans);
  font-size: 14px;
  -webkit-font-smoothing: antialiased;
}

/* Every figure in this app is a figure. Line them up. */
.num, td.num, th.num, .kpi-value, .tape-price, table.dataTable td.num {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  text-align: right;
  white-space: nowrap;
}

.up   { color: var(--up)    !important; }
.down { color: var(--down)  !important; }
.flat { color: var(--txt-3) !important; }
.amber{ color: var(--amber) !important; }

/* ---------------------------------------------------------------------
   Ticker tape
   --------------------------------------------------------------------- */
.tape {
  display: flex; align-items: stretch;
  background: #090d13;
  border-bottom: 1px solid var(--line);
  height: 38px; overflow: hidden;
}
.tape-label {
  display: flex; align-items: center; gap: 6px;
  padding: 0 14px;
  font: 600 10.5px/1 var(--mono);
  letter-spacing: .14em;
  color: var(--down);
  background: #0d1117;
  border-right: 1px solid var(--line);
  flex: 0 0 auto;
}
.tape-label .bi { animation: blip 2s ease-in-out infinite; }
@keyframes blip { 0%,100%{opacity:1} 50%{opacity:.25} }

.tape-viewport { flex: 1 1 auto; overflow: hidden; position: relative; }
.tape-track {
  display: flex; align-items: center; gap: 30px;
  height: 100%; width: max-content;
  padding-left: 20px;
  animation: tapescroll 60s linear infinite;
}
.tape:hover .tape-track { animation-play-state: paused; }
@keyframes tapescroll { from { transform: translateX(0) } to { transform: translateX(-50%) } }

.tape-item {
  display: flex; align-items: baseline; gap: 8px;
  font: 500 12px/1 var(--mono); white-space: nowrap;
}
.tape-sym   { color: var(--txt-2); letter-spacing: .04em; }
.tape-price { color: var(--txt); font-weight: 600; }
.tape-chg   { font-size: 11.5px; }
.tape-empty { color: var(--txt-3); font: 12px var(--mono); }
.tape-item.stale .tape-price { opacity: .5; }

@media (prefers-reduced-motion: reduce) {
  .tape-track { animation: none; }
  .tape-viewport { overflow-x: auto; }
  .tape-label .bi { animation: none; }
}

/* ---------------------------------------------------------------------
   Top bar
   --------------------------------------------------------------------- */
.deskbar {
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  padding: .35rem 0;
}
.navbar-brand { display: flex; align-items: center; gap: 10px; }
.brand-mark {
  font: 700 11px/1 var(--mono); letter-spacing: .1em;
  background: var(--up); color: #06120c;
  padding: 6px 8px; border-radius: 3px;
}
.brand-text { font-size: 15px; font-weight: 600; color: var(--txt); }

.deskbar .nav-link {
  color: var(--txt-2); font-size: 13px; font-weight: 500;
  padding: .5rem .8rem; border-radius: 5px;
}
.deskbar .nav-link:hover { color: var(--txt); background: var(--panel-2); }
.deskbar .nav-link.active { color: var(--up); background: var(--up-soft); }
.deskbar .nav-link .bi { font-size: 12px; margin-right: 3px; opacity: .8; }

.clientchip {
  display: flex; flex-direction: column; line-height: 1.15;
  padding-left: 14px; border-left: 1px solid var(--line);
}
.clientchip .k { font: 500 9px/1 var(--mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--txt-3); }
.clientchip .v { font: 600 12.5px/1.3 var(--mono); color: var(--txt); }
.clock { font: 500 12px var(--mono); color: var(--txt-2); }

/* ---------------------------------------------------------------------
   Panels and KPI cards
   --------------------------------------------------------------------- */
.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  margin-bottom: 20px;
}
/* Aligned to the top, not centred: against a two-line title block a
   centred control floats in the middle of nothing. The title column is
   capped at a readable measure so the explanatory line does not run the
   full width of a 1900px screen, which is roughly 160 characters and
   past the point where the eye reliably finds the next line. */
.panel-head {
  display: flex; align-items: flex-start; justify-content: space-between;
  gap: 12px 20px; flex-wrap: wrap;
  padding: 14px 18px; border-bottom: 1px solid var(--line);
}
.panel-head > div:first-child { min-width: 0; flex: 1 1 320px; }
.panel-head h2 {
  margin: 0; font: 600 11px/1.35 var(--mono);
  letter-spacing: .13em; text-transform: uppercase; color: var(--txt-2);
}
.panel-head .sub {
  font-size: 12px; color: var(--txt-3); margin: 5px 0 0;
  line-height: 1.55; max-width: 68ch;
}

/* Controls and timestamps on the right of a panel head. */
.panel-head > .btn,
.panel-head > .form-select,
.panel-head > .meta { flex: 0 0 auto; margin-top: 1px; }

.panel-head .meta {
  display: inline-flex; align-items: center; gap: 5px;
  font: 500 11px var(--mono); color: var(--txt-3);
  white-space: nowrap;
}
.panel-head .meta .bi { font-size: 11px; opacity: .75; }

.panel-body { padding: 18px; }

/* In an equal-height row the shorter panel used to leave dead space
   under its content. Let the body grow and the chart inside it fill. */
.panel.h-100 { display: flex; flex-direction: column; }
.panel.h-100 > .panel-body { flex: 1 1 auto; display: flex; flex-direction: column; }
.panel.h-100 > .panel-body > .chart-wrap { flex: 1 1 auto; min-height: 200px; }

.kpi {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 16px 18px;
  height: 100%;
  position: relative; overflow: hidden;
}
.kpi::after {
  content: ""; position: absolute; left: 0; top: 0; bottom: 0; width: 3px;
  background: var(--line);
}
.kpi.is-up::after    { background: var(--up); }
.kpi.is-down::after  { background: var(--down); }
.kpi.is-amber::after { background: var(--amber); }
.kpi.is-blue::after  { background: var(--blue); }

.kpi-label {
  font: 500 9.5px/1 var(--mono); letter-spacing: .13em;
  text-transform: uppercase; color: var(--txt-3);
}
.kpi-value {
  font-family: var(--mono); font-size: 25px; font-weight: 600;
  letter-spacing: -.02em; margin: 9px 0 3px; text-align: left;
}
.kpi-note { font-size: 11.5px; color: var(--txt-3); }

/* ---------------------------------------------------------------------
   Tables (DataTables + Bootstrap 5)
   --------------------------------------------------------------------- */
table.dataTable {
  border-collapse: collapse !important;
  font-size: 13px; width: 100% !important;
}
table.dataTable thead th {
  background: var(--panel-2);
  border-bottom: 1px solid var(--line) !important;
  color: var(--txt-3);
  font: 600 9.5px/1.6 var(--mono);
  letter-spacing: .1em; text-transform: uppercase;
  padding: 10px 12px !important; white-space: nowrap;
}
table.dataTable tbody td {
  border-top: 1px solid var(--line-soft) !important;
  padding: 9px 12px !important;
  color: var(--txt); vertical-align: middle;
}
table.dataTable tbody tr:hover td { background: var(--panel-2); }
table.dataTable tbody tr.row-net td {
  background: rgba(76,141,255,.06);
  font-weight: 600;
  border-top: 1px solid var(--blue) !important;
}
table.dataTable tfoot th {
  border-top: 1px solid var(--line) !important;
  font: 600 12px var(--mono); color: var(--txt);
  padding: 10px 12px !important;
}

/* The DataTables toolbar is styled once, further down, under
   "TABLE TOOLBAR". An earlier block lived here and set
   `padding: 5px 9px` on the filter input at a higher specificity than
   the replacement, which is what pushed the placeholder text under the
   search icon. Two stylesheets describing the same control is how that
   happens, so the old one is gone rather than overridden. */
.dataTables_wrapper { padding: 0; }

/* Symbol cell */
.sym { font: 600 12.5px var(--mono); color: var(--txt); letter-spacing: .02em; }
.sym-name { display: block; font: 400 11px var(--sans); color: var(--txt-3); margin-top: 1px; }

/* ---------------------------------------------------------------------
   Pills and badges
   --------------------------------------------------------------------- */
.pill {
  display: inline-block; padding: 3px 8px; border-radius: 4px;
  font: 600 9.5px/1.4 var(--mono); letter-spacing: .09em; text-transform: uppercase;
  border: 1px solid transparent;
}
.pill-buy   { background: var(--up-soft);    color: var(--up);    border-color: rgba(38,184,119,.3); }
.pill-sell  { background: var(--down-soft);  color: var(--down);  border-color: rgba(234,90,95,.3); }
.pill-mtf   { background: var(--amber-soft); color: var(--amber); border-color: rgba(217,164,65,.3); }
.pill-mute  { background: var(--panel-2);    color: var(--txt-3); border-color: var(--line); }
.pill-blue  { background: rgba(76,141,255,.13); color: var(--blue); border-color: rgba(76,141,255,.3); }

.signal {
  display: inline-block; padding: 5px 12px; border-radius: 5px;
  font: 700 12px/1 var(--mono); letter-spacing: .08em;
}
.signal-strong-buy  { background: var(--up);   color: #06120c; }
.signal-buy         { background: var(--up-soft);   color: var(--up);   border: 1px solid var(--up); }
.signal-hold        { background: var(--panel-2);   color: var(--txt-2);border: 1px solid var(--line); }
.signal-sell        { background: var(--down-soft); color: var(--down); border: 1px solid var(--down); }
.signal-strong-sell { background: var(--down); color: #fff; }

/* ---------------------------------------------------------------------
   Forms
   --------------------------------------------------------------------- */
.form-control, .form-select {
  background: var(--panel-2); border: 1px solid var(--line);
  color: var(--txt); font-size: 13.5px;
}
.form-control:focus, .form-select:focus {
  background: var(--panel-2); border-color: var(--up);
  box-shadow: 0 0 0 .18rem var(--up-soft); color: var(--txt);
}
.form-label {
  font: 500 9.5px/1 var(--mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--txt-3); margin-bottom: 6px;
}
.btn-desk {
  background: var(--up); border: 0; color: #06120c;
  font: 600 12.5px var(--sans); padding: 8px 16px; border-radius: 5px;
}
.btn-desk:hover { background: #1fa066; color: #06120c; }
.btn-ghost {
  background: transparent; border: 1px solid var(--line); color: var(--txt-2);
  font-size: 12.5px; padding: 7px 14px; border-radius: 5px;
}
.btn-ghost:hover { border-color: var(--txt-3); color: var(--txt); }

/* ---------------------------------------------------------------------
   Drop zone
   --------------------------------------------------------------------- */
.dropzone {
  border: 1.5px dashed var(--line); border-radius: 8px;
  background: var(--panel-2); padding: 44px 24px; text-align: center;
  transition: border-color .15s, background .15s; cursor: pointer;
}
.dropzone:hover, .dropzone.hot { border-color: var(--up); background: var(--up-soft); }
.dropzone .bi { font-size: 30px; color: var(--txt-3); }
.dropzone h3 { font-size: 15px; margin: 12px 0 5px; }
.dropzone p  { color: var(--txt-3); font-size: 12.5px; margin: 0; }

/* ---------------------------------------------------------------------
   Charts, misc
   --------------------------------------------------------------------- */
.chart-wrap { position: relative; height: 320px; }
.chart-wrap.tall { height: 420px; }

.metric-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: 6px; overflow: hidden;
}
.metric { background: var(--panel); padding: 12px 14px; }
.metric .k { font: 500 9px/1 var(--mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--txt-3); }
.metric .v { font: 600 15px/1.4 var(--mono); margin-top: 5px; }

.empty-state { text-align: center; padding: 56px 20px; color: var(--txt-3); }
.empty-state .bi { font-size: 34px; opacity: .4; display: block; margin-bottom: 12px; }

.deskfoot {
  border-top: 1px solid var(--line); padding: 16px 0 26px;
  color: var(--txt-3); font-size: 11.5px; margin-top: 10px;
}
.deskfoot .sep { margin: 0 8px; opacity: .5; }

.toast-host { position: fixed; right: 18px; bottom: 18px; z-index: 1080; }

::-webkit-scrollbar { width: 9px; height: 9px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--line); border-radius: 5px; }
::-webkit-scrollbar-thumb:hover { background: var(--txt-3); }

@media (max-width: 991px) {
  .clientchip { display: none; }
  .kpi-value  { font-size: 21px; }
}

:focus-visible { outline: 2px solid var(--up); outline-offset: 2px; }

/* ---------------------------------------------------------------------
   Client / account switcher in the top bar
   --------------------------------------------------------------------- */
.ctxpick { display: flex; flex-direction: column; gap: 2px; }
.ctxpick label {
  font: 500 8.5px/1 var(--mono); letter-spacing: .13em;
  text-transform: uppercase; color: var(--txt-3); padding-left: 2px;
}
.ctxpick .form-select {
  background: var(--panel-2); border: 1px solid var(--line); color: var(--txt);
  font: 500 12px var(--sans); padding: 4px 26px 4px 9px; min-width: 150px;
}
.ctxpick .form-select:focus { border-color: var(--up); box-shadow: none; }

.dropdown-menu-dark {
  background: var(--panel); border: 1px solid var(--line);
  --bs-dropdown-link-hover-bg: var(--panel-2);
  --bs-dropdown-link-active-bg: var(--up-soft);
  --bs-dropdown-link-active-color: var(--up);
}
.dropdown-menu-dark .dropdown-item { color: var(--txt-2); font-size: 13px; }

/* ---------------------------------------------------------------------
   Scoreboard: the per-client P&L strip
   --------------------------------------------------------------------- */
.scoreboard {
  display: grid; gap: 1px; background: var(--line);
  border: 1px solid var(--line); border-radius: 8px; overflow: hidden;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  margin-bottom: 20px;
}
.score { background: var(--panel); padding: 13px 15px; position: relative; }
.score .k {
  font: 500 8.5px/1 var(--mono); letter-spacing: .13em;
  text-transform: uppercase; color: var(--txt-3);
}
.score .v {
  font: 600 18px/1.25 var(--mono); margin-top: 7px;
  font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}
.score .s { font-size: 10.5px; color: var(--txt-3); margin-top: 3px; }
.score.lead { background: var(--panel-2); }
.score.lead .v { font-size: 22px; }

/* Waterfall from gross to net, used on the client screen */
.flow { display: flex; height: 30px; border: 1px solid var(--line);
  border-radius: 4px; overflow: hidden; margin: 14px 0 8px; }
.flow span { display: block; min-width: 2px; }
.flow .keep { background: var(--up); }
.flow .int  { background: var(--down); }
.flow .dp   { background: #c4703f; }
.flow .fee  { background: var(--amber); }
.flow-key { display: flex; flex-wrap: wrap; gap: 16px;
  font: 400 11px/1.5 var(--mono); color: var(--txt-2); }
.flow-key i { display: inline-block; width: 9px; height: 9px;
  margin-right: 6px; font-style: normal; border-radius: 2px; }

/* Comparison winner */
tr.is-best td { background: var(--up-soft) !important; }
tr.is-best td:first-child { box-shadow: inset 3px 0 0 var(--up); }

/* Audit diff */
.diff { display: grid; grid-template-columns: 150px 1fr 1fr; gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: 6px;
  overflow: hidden; font: 400 12px var(--mono); }
.diff > div { background: var(--panel); padding: 7px 10px; }
.diff .h { background: var(--panel-2); color: var(--txt-3);
  font: 600 9px/1.6 var(--mono); letter-spacing: .1em; text-transform: uppercase; }
.diff .was { color: var(--down); }
.diff .now { color: var(--up); }
.diff .same { color: var(--txt-3); }

/* Setup hint used on empty screens */
.hint { border-left: 3px solid var(--blue); background: var(--panel-2);
  padding: 13px 16px; border-radius: 0 6px 6px 0; font-size: 13px;
  color: var(--txt-2); margin-bottom: 18px; }
.hint b { color: var(--txt); }

.rowlink { cursor: pointer; }
.rowlink:hover td { background: var(--panel-2); }

@media (max-width: 1199px) {
  .ctxpick .form-select { min-width: 130px; }
}

/* Ledger rows the broker's own P&L report omits */
tr.row-cost td:first-child { box-shadow: inset 3px 0 0 var(--amber); }

/* ---------------------------------------------------------------------
   Import screen
   --------------------------------------------------------------------- */
.dropzone {
  border: 1.5px dashed var(--line); border-radius: 10px; padding: 38px 20px;
  text-align: center; cursor: pointer; transition: border-color .15s, background .15s;
  background: var(--panel-2);
}
.dropzone:hover, .dropzone.over { border-color: var(--up); background: var(--up-soft); }
.dropzone i { font-size: 30px; color: var(--txt-3); display: block; margin-bottom: 10px; }
.dropzone.over i { color: var(--up); }

.import-row {
  padding: 11px 13px; border: 1px solid var(--line); border-radius: 6px;
  margin-bottom: 8px; font-size: 13px; background: var(--panel-2);
}

/* =====================================================================
   BRAND, SPLASH AND SIGN-IN
   ===================================================================== */

.brand-logo { height: 30px; width: auto; display: block; }
.brand-logo-mark { height: 30px; width: auto; display: none; }

.brand-stack { display: flex; flex-direction: column; gap: 1px; line-height: 1; }
.brand-co {
  font: 600 10px/1.2 var(--sans); letter-spacing: .06em;
  color: var(--txt-3); text-transform: uppercase;
  max-width: 230px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* ---- splash --------------------------------------------------------- */
.splash {
  position: fixed; inset: 0; z-index: 3000;
  display: grid; place-items: center;
  background: radial-gradient(ellipse at 50% 40%, #182130 0%, var(--bg) 70%);
  transition: opacity .45s ease, visibility .45s;
}
.splash.gone { opacity: 0; visibility: hidden; }
.splash-inner { text-align: center; padding: 24px; max-width: 90vw; }
.splash-logo {
  width: min(340px, 74vw); height: auto;
  animation: splashIn .7s cubic-bezier(.2,.7,.3,1) both;
}
.splash-co {
  margin: 14px 0 0; font: 600 12px/1.4 var(--sans);
  letter-spacing: .16em; text-transform: uppercase; color: var(--txt-2);
  animation: splashIn .7s .12s cubic-bezier(.2,.7,.3,1) both;
}
.splash-msg { margin: 10px 0 0; font-size: 14px; color: var(--txt-2); }
.splash-bar {
  width: 150px; height: 2px; margin: 22px auto 0;
  background: var(--line); border-radius: 2px; overflow: hidden;
}
.splash-bar span {
  display: block; height: 100%; width: 40%; border-radius: 2px;
  background: linear-gradient(90deg, var(--brand-green), var(--brand));
  animation: splashSlide 1.1s ease-in-out infinite;
}
.splash-bar.run span { animation: splashFill 2s linear forwards; width: 0; }
.splash-link {
  display: inline-block; margin-top: 18px; font-size: 13px;
  color: var(--brand); text-decoration: none;
}
.splash-link:hover { text-decoration: underline; }

@keyframes splashIn  { from { opacity: 0; transform: translateY(9px) scale(.985); }
                       to   { opacity: 1; transform: none; } }
@keyframes splashSlide { 0% { transform: translateX(-110%); }
                       100% { transform: translateX(360%); } }
@keyframes splashFill { from { width: 0; } to { width: 100%; } }

/* ---- sign-in -------------------------------------------------------- */
.auth-body {
  min-height: 100dvh;
  background:
    radial-gradient(ellipse at 20% 0%, rgba(107,163,222,.10) 0%, transparent 55%),
    radial-gradient(ellipse at 85% 100%, rgba(138,194,127,.08) 0%, transparent 55%),
    var(--bg);
}
.auth-wrap {
  min-height: 100dvh; display: grid; place-items: center;
  padding: 24px 16px calc(24px + env(safe-area-inset-bottom));
}
.auth-card {
  width: 100%; max-width: 400px;
  background: var(--panel); border: 1px solid var(--line);
  border-radius: 14px; padding: 30px 28px 24px;
  box-shadow: 0 20px 50px rgba(0,0,0,.42);
  animation: splashIn .5s .1s cubic-bezier(.2,.7,.3,1) both;
}
.auth-head { text-align: center; margin-bottom: 24px; }
.auth-logo { width: 210px; max-width: 100%; height: auto; }
.auth-co {
  margin: 14px 0 0; font: 700 13px/1.3 var(--sans);
  letter-spacing: .04em; color: var(--txt);
}
.auth-tag { margin: 3px 0 0; font-size: 11.5px; color: var(--txt-3); }
.auth-lead { font-size: 13px; color: var(--txt-2); margin-bottom: 18px; }
.auth-alert {
  background: var(--down-soft); border: 1px solid rgba(234,90,95,.35);
  color: #ffb3b6; border-radius: 8px; padding: 11px 13px;
  font-size: 13px; margin-bottom: 18px; line-height: 1.5;
}
.auth-foot {
  margin: 20px 0 0; text-align: center;
  font-size: 11px; color: var(--txt-3); line-height: 1.6;
}
.auth-card .form-control { min-height: var(--tap); font-size: 15px; }
.auth-card .btn-lg { min-height: var(--tap); font-size: 15px; }

.pw-wrap { position: relative; }
.pw-wrap .form-control { padding-right: 46px; }
.pw-eye {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 40px; height: 40px; display: grid; place-items: center;
  background: none; border: 0; color: var(--txt-3); cursor: pointer;
}
.pw-eye:hover { color: var(--txt); }

.pw-meter { height: 3px; background: var(--line); border-radius: 2px;
  margin-top: 8px; overflow: hidden; }
.pw-meter span { display: block; height: 100%; width: 0; transition: width .25s, background .25s; }
.pw-meter.s1 span { width: 20%;  background: var(--down); }
.pw-meter.s2 span { width: 40%;  background: var(--down); }
.pw-meter.s3 span { width: 60%;  background: var(--amber); }
.pw-meter.s4 span { width: 80%;  background: var(--brand-green); }
.pw-meter.s5 span { width: 100%; background: var(--up); }

/* =====================================================================
   ACCOUNT MENU
   ===================================================================== */
.usermenu .btn {
  display: flex; align-items: center; gap: 8px;
  background: var(--panel-2); border: 1px solid var(--line);
  color: var(--txt); padding: 5px 10px; border-radius: 8px;
  min-height: 36px;
}
.usermenu .btn:hover { border-color: var(--brand); }
.avatar {
  width: 24px; height: 24px; border-radius: 6px; flex: 0 0 24px;
  display: grid; place-items: center;
  background: linear-gradient(135deg, var(--brand), var(--brand-green));
  color: #0d1117; font: 700 10px/1 var(--sans);
}
.usermenu .who { display: flex; flex-direction: column; line-height: 1.15; text-align: left; }
.usermenu .who b { font-size: 12px; font-weight: 600; }
.usermenu .who small { font-size: 9.5px; color: var(--txt-3); }

/* =====================================================================
   MOBILE — everything below reshapes rather than merely shrinks
   ===================================================================== */

/* Charts need a floor, or they collapse on short screens. */
.chart-wrap { position: relative; width: 100%; height: 300px; min-height: 220px; }

@media (max-width: 1199.98px) {
  .brand-logo { height: 26px; }
  .navbar-collapse { max-height: 78vh; overflow-y: auto; }
  .ctxpick { width: 100%; }
  .ctxpick .form-select { width: 100%; }
}

@media (max-width: 991.98px) {
  body { font-size: 13.5px; }

  /* Two columns of figures reads far better than four squeezed ones. */
  .scoreboard { grid-template-columns: repeat(auto-fit, minmax(136px, 1fr)); }
  .score { padding: 11px 12px; }
  .score .v { font-size: 16px; }
  .score.lead .v { font-size: 18px; }

  .panel-head { flex-wrap: wrap; gap: 10px; }
  .chart-wrap { height: 260px; }

  /* Page headers stack, and their controls become full width so they
     are actually tappable rather than 22px slivers. */
  .pagehead { flex-direction: column; align-items: stretch !important; }
  .pagehead .toolbar { width: 100%; }
  .pagehead .toolbar > * { flex: 1 1 140px; min-height: var(--tap); }
}

@media (max-width: 767.98px) {
  main.container-fluid { padding-left: 12px !important; padding-right: 12px !important;
                         padding-bottom: calc(20px + env(safe-area-inset-bottom)); }

  .brand-logo { display: none; }
  .brand-logo-mark { display: block; height: 28px; }
  .brand-co { max-width: 150px; }

  .scoreboard { grid-template-columns: repeat(2, 1fr); }
  .score .k { font-size: 8px; }
  .chart-wrap { height: 230px; }

  /* A modal that fills the screen beats one that floats in a 320px
     window with its buttons off the bottom edge. */
  .modal-dialog { margin: 0; max-width: 100%; min-height: 100dvh; }
  .modal-content { min-height: 100dvh; border-radius: 0; border: 0; }
  .modal-body { padding-bottom: 90px; }
  .modal-footer {
    position: sticky; bottom: 0; background: var(--panel);
    padding-bottom: calc(12px + env(safe-area-inset-bottom));
    z-index: 5;
  }
  .modal-footer .btn { flex: 1; min-height: var(--tap); }

  /* DataTables controls stack instead of colliding. */
  .dataTables_wrapper .row > [class^="col-"] { width: 100%; max-width: 100%; flex: 0 0 100%; }
  .dataTables_filter { text-align: left !important; margin-top: 8px; }
  .dataTables_filter input { width: 100% !important; margin-left: 0 !important; }
  .dt-buttons { display: flex; flex-wrap: wrap; gap: 4px; }

  .form-control, .form-select { min-height: 42px; font-size: 16px; } /* 16px stops iOS zooming */
  .btn { min-height: 40px; }
  .btn-sm { min-height: 36px; }

  .flow-key { gap: 9px; font-size: 10.5px; }
  .diff { grid-template-columns: 1fr; }
  .diff .h:nth-child(2)::after { content: " (before)"; }
  .diff .h:nth-child(3)::after { content: " (after)"; }

  .tape-label { display: none; }
  .deskfoot { font-size: 10.5px; text-align: center; }
}

@media (max-width: 575.98px) {
  .auth-card { padding: 24px 20px 20px; border-radius: 12px; }
  .scoreboard { grid-template-columns: 1fr 1fr; }
  h1.h4 { font-size: 1.05rem; }
}

/* Respect the setting rather than animating over it. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important; scroll-behavior: auto !important;
  }
}

/* Visible focus. Removing outlines makes an app unusable by keyboard. */
:focus-visible {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  border-radius: 4px;
}

/* Skip link, for keyboard and screen-reader users. */
.skip {
  position: absolute; left: -9999px; top: 0; z-index: 4000;
  background: var(--brand); color: #0b0f14; padding: 10px 16px;
  border-radius: 0 0 8px 0; font-weight: 600;
}
.skip:focus { left: 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* =====================================================================
   ANALYTICS
   ===================================================================== */
.chipbar {
  display: flex; gap: 8px; overflow-x: auto; padding: 2px 0 12px;
  -webkit-overflow-scrolling: touch; scrollbar-width: none;
  position: sticky; top: 0; z-index: 5;
}
.chipbar::-webkit-scrollbar { display: none; }
.chip {
  flex: 0 0 auto; padding: 7px 14px; border-radius: 999px;
  background: var(--panel-2); border: 1px solid var(--line);
  color: var(--txt-2); font-size: 12px; text-decoration: none;
  white-space: nowrap; min-height: 34px; display: inline-flex; align-items: center;
}
.chip:hover, .chip:focus { color: var(--txt); border-color: var(--brand); }

.chart-section { margin-bottom: 26px; scroll-margin-top: 80px; }
.section-title {
  font: 600 11px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase;
  color: var(--txt-3); margin: 0 0 12px; padding-bottom: 8px;
  border-bottom: 1px solid var(--line);
}

.chart-grid { display: grid; gap: 14px; grid-template-columns: repeat(6, 1fr); }
.span-wide  { grid-column: span 6; }
.span-half  { grid-column: span 3; }
.span-third { grid-column: span 2; }

.chart-card .panel-body { padding-top: 10px; }
.chart-asks { font-size: 11.5px; color: var(--txt-3); margin: 0 0 10px; line-height: 1.5; }
.echart { width: 100%; height: 300px; }
.span-wide .echart { height: 360px; }
.span-third .echart { height: 260px; }
.chart-empty {
  font-size: 12px; color: var(--txt-3); text-align: center;
  padding: 40px 16px; margin: 0;
}
.chart-expand { padding: 3px 8px; }

@media (max-width: 1199.98px) {
  .chart-grid { grid-template-columns: repeat(4, 1fr); }
  .span-wide { grid-column: span 4; }
  .span-half { grid-column: span 2; }
  .span-third { grid-column: span 2; }
}
@media (max-width: 767.98px) {
  .chart-grid { grid-template-columns: 1fr; gap: 12px; }
  .span-wide, .span-half, .span-third { grid-column: span 1; }
  .echart, .span-wide .echart, .span-third .echart { height: 260px; }
  .chart-expand { display: none; }   /* a modal on a phone is the same size */
}

@media print {
  .tape, .deskbar, .chipbar, .deskfoot, .toolbar, .chart-expand { display: none !important; }
  .panel { break-inside: avoid; border-color: #ccc; }
  body { background: #fff; color: #000; }
}

/* Permission picker */
.permgroup { border: 1px solid var(--line); border-radius: 8px;
  padding: 12px 14px; margin-bottom: 10px; background: var(--panel-2); }
.permgroup h6 { font: 600 9.5px/1 var(--mono); letter-spacing: .13em;
  text-transform: uppercase; color: var(--txt-3); margin: 0 0 10px; }
.permrow { display: flex; gap: 10px; align-items: flex-start;
  padding: 6px 0; min-height: 32px; }
.permrow label { font-size: 12.5px; color: var(--txt-2); cursor: pointer; line-height: 1.4; }
.permrow code { font-size: 10px; color: var(--txt-3); display: block; }

/* Danger zone */
.danger-panel { border-color: rgba(234,90,95,.4); }
.danger-panel .panel-head { background: rgba(234,90,95,.06); }
.reset-grid { display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); }
.reset-card {
  border: 1px solid var(--line); border-radius: 10px;
  padding: 15px 16px; background: var(--panel-2);
  display: flex; flex-direction: column; gap: 9px;
}
.reset-card h4 { font: 600 13px/1.3 var(--sans); margin: 0; color: var(--txt); }
.reset-card p { font-size: 11.5px; color: var(--txt-3); margin: 0; line-height: 1.55; }
.reset-card .rows { font: 600 12px var(--mono); color: var(--amber); }
.reset-card.sev-3 { border-color: rgba(234,90,95,.45); }
.reset-card .btn { margin-top: auto; }
.pulse { animation: pulseBtn 1.6s ease-in-out infinite; }
@keyframes pulseBtn {
  0%,100% { box-shadow: 0 0 0 0 rgba(38,184,119,.45); }
  50%     { box-shadow: 0 0 0 6px rgba(38,184,119,0); }
}

/* =====================================================================
   NAVBAR — corrected layout
   ---------------------------------------------------------------------
   The bar was wrapping onto two rows because the context pickers stacked
   their label above the select and reserved 150px each. Once the row
   wrapped, nothing on it lined up with anything else.

   Fix: one row that never wraps. The navigation is allowed to scroll
   sideways if it must; the identity and context controls on the right
   are never the things that get pushed away, because they are how you
   tell which client's money you are looking at.
   ===================================================================== */
@media (min-width: 1200px) {
  .deskbar > .container-fluid {
    display: flex; align-items: center; gap: 14px; flex-wrap: nowrap;
  }
  .deskbar .navbar-collapse {
    display: flex !important; align-items: center;
    flex: 1 1 auto; min-width: 0; gap: 10px;
  }

  /* Nav takes the slack but must NOT clip: an overflow value of anything
     other than visible traps the Setup dropdown inside the nav box and
     it silently never appears. The labels collapse to icons below
     1900px instead, so there is nothing left to scroll anyway. */
  .deskbar .navbar-nav {
    flex: 1 1 auto; min-width: 0;
    flex-wrap: nowrap; overflow: visible;
  }
  .deskbar .nav-item { flex: 0 0 auto; }

  /* The right cluster is fixed and never wraps. */
  .deskbar .navbar-collapse > .d-flex {
    flex: 0 0 auto; flex-wrap: nowrap !important; padding: 0 !important;
  }
}

.deskbar { padding: .3rem 0; }
.deskbar .nav-link {
  display: inline-flex; align-items: center; gap: 5px;
  padding: .42rem .62rem; white-space: nowrap; line-height: 1.2;
}
.deskbar .nav-link .bi { margin-right: 0; }

/* Context pickers: label beside the control, not above it. Halves the
   height of the bar and stops the wrap that caused the misalignment. */
.ctxpick {
  flex-direction: row; align-items: center; gap: 0;
  border: 1px solid var(--line); border-radius: 7px;
  background: var(--panel-2); overflow: hidden; height: 34px;
}
.ctxpick label {
  padding: 0 8px; margin: 0; height: 100%;
  display: flex; align-items: center;
  font: 600 8.5px/1 var(--mono); letter-spacing: .1em;
  text-transform: uppercase; color: var(--txt-3);
  background: rgba(255,255,255,.025);
  border-right: 1px solid var(--line); white-space: nowrap;
}
.ctxpick .form-select {
  border: 0; height: 100%;
  min-width: 0; width: auto; max-width: 190px;
  padding: 0 24px 0 8px; font-size: 12.5px;
  border-radius: 0;
  /* Opaque, always. Chrome samples this exact value to paint the popup
     list, and it samples it while the control is focused — which is the
     moment you click to open it. A translucent value here is what made
     the client list render as pale text on white. */
  background-color: var(--panel-2);
}
.ctxpick .form-select:focus,
.ctxpick .form-select:hover { box-shadow: none; background-color: #202836; }
.ctxpick:focus-within { border-color: var(--brand); }

/* The OS already shows a clock. Ours only earns its place on a wide
   screen where the space is genuinely spare. */
/* The OS already shows a clock; ours only earns space on a wide screen.
   !important because Bootstrap's d-xl-inline utility is itself important. */
.clock { display: none !important; }
@media (min-width: 1600px) {
  .clock { display: inline-block !important;
           font: 500 11.5px var(--mono); color: var(--txt-3); }
}

.usermenu .btn { height: 34px; padding: 0 9px; }
.usermenu .who b { font-size: 11.5px; max-width: 130px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; display: block; }
.usermenu .who small { font-size: 9px; }

@media (max-width: 1399.98px) {
  .usermenu .who small { display: none; }   /* role is in the dropdown header */
  .ctxpick .form-select { max-width: 140px; }
}

/* =====================================================================
   SCOREBOARD — corrected
   ---------------------------------------------------------------------
   Three faults fixed here:
     1. Long figures were clipped mid-digit. A truncated number on a
        financial dashboard is worse than no number.
     2. The direction arrow wrapped onto its own line.
     3. Sub-lines of different lengths gave every tile a different height.
   ===================================================================== */
.scoreboard { grid-template-columns: repeat(auto-fit, minmax(158px, 1fr)); }

.score {
  display: flex; flex-direction: column; min-width: 0;
  padding: 12px 14px 11px;
}
.score .k {
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* The value never wraps and never clips: it shrinks to fit instead. */
.score .v {
  margin-top: 6px; min-width: 0;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  font-size: clamp(14px, 1.35vw, 19px);
}
.score.lead .v { font-size: clamp(16px, 1.7vw, 24px); }

.kpi-num {
  display: inline-flex; align-items: baseline; gap: 4px;
  white-space: nowrap;                 /* keeps the arrow beside the number */
  font-variant-numeric: tabular-nums;
  cursor: help;                        /* the exact figure is in the tooltip */
}
.kpi-dir { font-style: normal; font-size: .68em; line-height: 1; }

/* Two lines of sub-text, always, so every tile is the same height. */
.score .s {
  margin-top: 4px; font-size: 10.5px; line-height: 1.35;
  color: var(--txt-3);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; min-height: calc(2 * 1.35 * 10.5px);
}

/* A faint tint marks the headline tile without shouting. */
.score.lead {
  background: linear-gradient(180deg, rgba(107,163,222,.07), transparent 60%), var(--panel-2);
}
.score.lead .k { color: var(--txt-2); }

/* ---------------------------------------------------------------------
   Adaptive navigation labels
   ---------------------------------------------------------------------
   Ten labelled items need roughly 960px. Between the logo, the client
   and account pickers and the account menu, a 1366px laptop has about
   520px to give them. Something has to yield.

   Sideways-scrolling navigation is the worst option: items you cannot
   see are items you will not use. Instead the labels drop away below
   1500px and the icons carry the meaning, with the label still present
   as a tooltip and as the accessible name. The active item keeps its
   label, so you never lose track of where you are.
   --------------------------------------------------------------------- */
.deskbar .nav-label { margin-left: 5px; }

/* Measured, not guessed. Ten labelled items need ~960px; after the logo,
   both context pickers and the account menu, that much is only free from
   about 1900px up. Below that the icons carry it. */
@media (min-width: 1200px) and (max-width: 1899.98px) {
  .deskbar .nav-link { padding: .42rem .5rem; }
  .deskbar .nav-link .nav-label { display: none; }
  .deskbar .nav-link.active .nav-label { display: inline; }  /* keep your place */
  .deskbar .nav-link .bi { font-size: 14.5px; opacity: 1; }
  .deskbar .navbar-nav { gap: 1px; }
}

@media (min-width: 1900px) {
  .deskbar .nav-link { padding: .42rem .62rem; }
}

/* Below 1200 Bootstrap collapses the bar into the toggler, where labels
   are always shown because there is vertical room for them. */
@media (max-width: 1199.98px) {
  .deskbar .nav-label { display: inline !important; }
  .deskbar .navbar-nav { flex-direction: column; }
  .deskbar .nav-link { padding: .6rem .7rem; min-height: var(--tap); }
}

/* =====================================================================
   NATIVE SELECT POPUPS
   ---------------------------------------------------------------------
   color-scheme above does most of the work, but Chrome on Windows takes
   the popup's background from the select's own background-color. Ours was
   transparent, so the list fell back to white while the text stayed light
   grey. Explicit colours on the option elements cover that, and every
   other select in the app at the same time.
   ===================================================================== */
select,
select.form-select,
.form-select {
  color-scheme: dark;
}

select option,
select optgroup,
.form-select option,
.form-select optgroup {
  background-color: #1b222d;      /* literal: some engines ignore vars here */
  color: #e4e8ee;
}
select option:checked,
.form-select option:checked {
  background-color: #24405f;
  color: #ffffff;
}
select option:disabled,
.form-select option:disabled { color: #667080; }

/* Native date pickers, for the same reason. */
input[type="date"], input[type="time"], input[type="datetime-local"] {
  color-scheme: dark;
}
input[type="date"]::-webkit-calendar-picker-indicator,
input[type="time"]::-webkit-calendar-picker-indicator {
  filter: invert(0.7);
  cursor: pointer;
  opacity: .7;
}
input[type="date"]::-webkit-calendar-picker-indicator:hover { opacity: 1; }

/* Number spinners are noise on money fields and easy to nudge by accident. */
input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
  -webkit-appearance: none; margin: 0;
}
input[type="number"] { -moz-appearance: textfield; appearance: textfield; }

/* =====================================================================
   DROPDOWN MENUS — make sure nothing can clip them again
   ===================================================================== */
/* Scoped to the expanded bar only. Below 1200px the menu is collapsed
   and genuinely does need to scroll on a short screen, so this must not
   reach it — `.deskbar .navbar-collapse` would otherwise outrank the
   mobile rule and leave the bottom of a long menu unreachable. */
@media (min-width: 1200px) {
  .deskbar, .deskbar > .container-fluid, .deskbar .navbar-collapse,
  .deskbar .navbar-nav, .deskbar .nav-item { overflow: visible; }
}

.dropdown-menu {
  z-index: 1080;                 /* above the sticky bar and the tape */
  box-shadow: 0 12px 30px rgba(0,0,0,.5);
  border-radius: 9px; padding: 6px;
  min-width: 190px;
}
.dropdown-menu .dropdown-item {
  border-radius: 6px; padding: 8px 10px; min-height: 36px;
  display: flex; align-items: center;
}
.dropdown-header {
  font: 600 9px/1 var(--mono); letter-spacing: .12em;
  text-transform: uppercase; color: var(--txt-3); padding: 8px 10px 6px;
}
.dropdown-divider { border-color: var(--line); margin: 5px 2px; }

/* =====================================================================
   TABLE TOOLBAR
   ---------------------------------------------------------------------
   The stock DataTables layout put the page-size select and the export
   buttons on one line and the search box on another, with a wide dead
   gap between them. Three faults followed from that: it cost 70px of
   vertical space above every table, the two halves read as unrelated,
   and the controls kept the browser's default styling on a dark panel.

   This is one row: the filter on the left where the attention goes,
   size and exports grouped on the right, everything on the same
   baseline and in the app's own palette.
   ===================================================================== */
.dt-toolbar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap;
  margin-bottom: 12px;
}
.dt-toolbar:empty { display: none; }

/* ---- filter ---- */
.dt-find { flex: 1 1 240px; min-width: 0; max-width: 380px; }
.dataTables_filter { margin: 0; text-align: left; width: 100%; }
.dataTables_filter label {
  display: block; margin: 0; width: 100%; position: relative;
}
/* DataTables ships `div.dataTables_wrapper div.dataTables_filter input`,
   which outranks a plain `.dataTables_filter input`. The left padding
   never applied and the placeholder started underneath the icon. Match
   its depth so this wins on its own merits rather than on !important. */
.dataTables_filter label::before {
  content: "\F52A";                       /* bootstrap-icons search glyph */
  font-family: "bootstrap-icons"; font-size: 13px; line-height: 1;
  position: absolute; left: 12px; top: 50%; transform: translateY(-50%);
  color: var(--txt-3); pointer-events: none; z-index: 2;
}

div.dataTables_wrapper div.dataTables_filter input,
div.dataTables_wrapper div.dataTables_filter input[type="search"] {
  box-sizing: border-box;
  width: 100%; margin: 0; display: block;
  height: 34px; line-height: 32px;
  /* 12px icon offset + 13px glyph + 10px gap = text starts at 35px */
  padding: 0 12px 0 35px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 7px; color: var(--txt); font-size: 12.5px;
}
div.dataTables_wrapper div.dataTables_filter input::placeholder {
  color: var(--txt-3); opacity: 1;
}
div.dataTables_wrapper div.dataTables_filter input:focus {
  outline: none; border-color: var(--brand); background: #202836;
}

/* WebKit draws its own clear button on type=search, which lands on top
   of the right padding and looks like a second control. */
div.dataTables_wrapper div.dataTables_filter input::-webkit-search-decoration,
div.dataTables_wrapper div.dataTables_filter input::-webkit-search-cancel-button {
  -webkit-appearance: none; appearance: none;
}

/* ---- page size and exports ---- */
.dt-tools { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; }

.dataTables_length { margin: 0; }
.dataTables_length label {
  margin: 0; display: flex; align-items: center; gap: 0;
  font-size: 0;                            /* hides the stray text nodes */
}
.dataTables_length select {
  height: 34px; padding: 0 26px 0 10px;
  background-color: var(--panel-2); border: 1px solid var(--line);
  border-radius: 7px; color: var(--txt-2); font-size: 12px;
  font-family: var(--mono);
}
.dataTables_length select:focus { outline: none; border-color: var(--brand); }

.dt-buttons { display: flex; gap: 4px; margin: 0; }
.dt-buttons .btn {
  height: 34px; min-height: 34px; width: 34px; padding: 0;
  display: inline-grid; place-items: center;
  background: var(--panel-2); border: 1px solid var(--line);
  color: var(--txt-3); border-radius: 7px;
}
.dt-buttons .btn:hover { color: var(--txt); border-color: var(--brand); background: #202836; }
.dt-buttons .btn i { font-size: 13px; }

/* ---- table body and footer ---- */
.dt-scroll { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; }
.dt-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; margin-top: 12px;
}
.dt-info, .dataTables_info {
  padding: 0 !important; margin: 0;
  font: 400 11.5px var(--mono); color: var(--txt-3);
}
.dt-page { margin-left: auto; }
.dataTables_paginate { margin: 0 !important; padding: 0 !important; }
.dataTables_paginate .page-link {
  background: var(--panel-2); border-color: var(--line); color: var(--txt-2);
  min-width: 32px; height: 32px; display: grid; place-items: center;
  font-size: 12px; padding: 0 8px;
}
.dataTables_paginate .page-item.active .page-link {
  background: var(--up-soft); border-color: var(--up); color: var(--up);
}
.dataTables_paginate .page-item.disabled .page-link { opacity: .4; }
.dataTables_paginate .page-link:hover { background: #202836; color: var(--txt); }

/* A single page of results means the pager can only say "1". Hide it. */
.dataTables_paginate .pagination:has(.page-item:only-of-type) { display: none; }

@media (max-width: 575.98px) {
  .dt-toolbar { gap: 8px; }
  .dt-find { flex: 1 1 100%; max-width: none; }
  .dt-tools { width: 100%; justify-content: space-between; }
  div.dataTables_wrapper div.dataTables_filter input {
    height: 40px; line-height: 38px; font-size: 16px;   /* 16px: no iOS zoom */
    padding: 0 12px 0 35px;                             /* keep clear of the icon */
  }
  .dataTables_length select, .dt-buttons .btn { height: 38px; }
  .dt-buttons .btn { width: 38px; }
  .dt-foot { justify-content: center; }
  .dt-page { margin-left: 0; }
}

/* =====================================================================
   VERTICAL RHYTHM — tightening the panel stack
   ---------------------------------------------------------------------
   A panel header was costing 86px to show a title and two lines of
   supporting text, and there was a 33px void between the header and the
   first row of the table: the header's bottom padding, the divider, and
   the body's top padding all stacked on top of each other.

   Nothing here removes information. It removes repetition of the same
   gap three times over.
   ===================================================================== */
.panel { margin-bottom: 15px; }

.panel-head { padding: 11px 16px 10px; }
.panel-head h2 { font-size: 10.5px; line-height: 1.35; }
.panel-head .sub {
  font-size: 11.5px; line-height: 1.45; margin-top: 3px;
  max-width: 74ch;
}

.panel-body { padding: 13px 16px 15px; }

/* A body that opens with a toolbar or a table does not need its own top
   padding on top of the header's bottom padding. */
.panel-body > .dt-toolbar:first-child,
.panel-body > .table-responsive:first-child,
.panel-body > .dt-scroll:first-child { margin-top: -2px; }

.dt-toolbar { margin-bottom: 10px; }
.dt-foot { margin-top: 10px; }

/* The scoreboard sits directly under the page title; it does not need
   the same gap as a panel. */
.scoreboard { margin-bottom: 15px; }

/* ---------------------------------------------------------------------
   Equal-height rows
   ---------------------------------------------------------------------
   Two panels side by side stretch to the taller one. Where the shorter
   holds a table rather than a chart, the surplus used to appear as a
   void beneath its content. Let the table region absorb it instead, so
   the extra height reads as ordinary empty table rather than as a hole,
   and any trailing note stays pinned to the bottom edge.
   --------------------------------------------------------------------- */
.panel.h-100 > .panel-body > .table-responsive,
.panel.h-100 > .panel-body > .dt-scroll,
.panel.h-100 > .panel-body > table { flex: 1 1 auto; }
.panel.h-100 > .panel-body > p:last-child { margin-top: auto; padding-top: 10px; }

/* ---------------------------------------------------------------------
   Table density
   --------------------------------------------------------------------- */
table.dataTable thead th {
  padding: 9px 12px; font-size: 9.5px; letter-spacing: .1em;
}
table.dataTable tbody td { padding: 10px 12px; }
table.dataTable tbody tr:last-child td { border-bottom: 0; }

@media (max-width: 767.98px) {
  .panel { margin-bottom: 12px; }
  .panel-head { padding: 10px 13px 9px; }
  .panel-body { padding: 11px 13px 13px; }
  .panel-head .sub { max-width: none; }
}

/* =====================================================================
   GAP BETWEEN A ROW OF PANELS AND WHAT FOLLOWS
   ---------------------------------------------------------------------
   A panel with h-100 is exactly the height of its column, so its own
   margin-bottom falls outside the column box and pushes nothing. The
   row carried no bottom spacing of its own, so the next panel sat
   flush against the row above with no seam at all.

   The gap therefore belongs on the row, not on the panel inside it.
   Scoped to rows that are direct children of <main>: every form in the
   app uses `class="row g-3"` too, and those live inside modals and
   panel bodies where this must not reach them.
   ===================================================================== */
main > .row { margin-bottom: 15px; }
main > .row:last-child { margin-bottom: 0; }

/* Inside a column the panel's own margin is redundant, and on an h-100
   panel it is actively misleading. The last one in a column drops it;
   panels stacked above a sibling keep theirs as the separator. */
main > .row > [class*="col-"] > .panel:last-child { margin-bottom: 0; }

/* Bootstrap's h-100 sets height:100%, which is what put the margin
   outside the column in the first place. Stretch with flex instead, so
   the panel stays inside its column and the row's margin does the work.
   Scoped to top-level rows only: every form in the app is also a `.row`,
   and turning its columns into flex columns would reflow the fields. */
main > .row > [class*="col-"] { display: flex; flex-direction: column; }
main > .row > [class*="col-"] > .panel.h-100 { height: auto; flex: 1 1 auto; }

@media (max-width: 767.98px) {
  main > .row { margin-bottom: 12px; }
}

/* =====================================================================
   SCREENER
   ===================================================================== */
.screenlist { max-height: 620px; overflow-y: auto; margin: -4px; padding: 4px; }
.screengroup { margin-bottom: 14px; }
.screengroup h6 {
  font: 600 9px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase;
  color: var(--txt-3); margin: 0 0 7px;
}
.screenitem {
  display: block; width: 100%; text-align: left; margin-bottom: 5px;
  background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 8px; padding: 9px 11px; color: var(--txt-2); cursor: pointer;
}
.screenitem:hover { border-color: var(--brand); }
.screenitem.on { border-color: var(--up); background: var(--up-soft); }
.si-name { display: block; font: 600 12.5px var(--sans); color: var(--txt); }
.si-name .bi { font-size: 10px; color: var(--amber); margin-left: 4px; }
.si-desc {
  display: block; font-size: 11px; color: var(--txt-3); margin-top: 2px;
  line-height: 1.4;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden;
}
.si-meta { display: block; font: 400 10px var(--mono); color: var(--txt-3); margin-top: 4px; }

/* ---- filter rows ---- */
.filterrow {
  display: grid; align-items: center; gap: 8px; margin-bottom: 8px;
  grid-template-columns: minmax(150px,1.4fr) minmax(120px,1fr) 110px 110px 28px 30px;
}
.filterrow.nodata { opacity: .75; }
.fr-metric {
  text-align: left; background: var(--panel-2); border: 1px solid var(--line);
  border-radius: 7px; padding: 5px 10px; color: var(--txt); min-height: 34px;
  cursor: pointer; overflow: hidden;
}
.fr-metric:hover { border-color: var(--brand); }
.fr-metric span { display: block; font-size: 12.5px; font-weight: 600;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fr-metric small { display: block; font-size: 9.5px; color: var(--txt-3); }
.fr-unit { font: 500 11px var(--mono); color: var(--txt-3); text-align: center; }
.fr-del {
  background: none; border: 0; color: var(--txt-3); cursor: pointer;
  width: 30px; height: 30px; border-radius: 6px;
}
.fr-del:hover { color: var(--down); background: var(--down-soft); }
.fr-warn {
  grid-column: 1 / -1; font-size: 10.5px; color: var(--amber);
  margin-top: -3px;
}
@media (max-width: 991.98px) {
  .filterrow { grid-template-columns: 1fr 1fr; }
  .fr-metric { grid-column: 1 / -1; }
  .fr-unit { display: none; }
}

/* ---- metric picker ---- */
.metricgroup { margin-bottom: 16px; }
.metricgroup h6 {
  font: 600 9px/1 var(--mono); letter-spacing: .13em; text-transform: uppercase;
  color: var(--txt-3); margin: 0 0 8px; padding-bottom: 6px;
  border-bottom: 1px solid var(--line);
}
.metricitem {
  display: block; width: 100%; text-align: left; margin-bottom: 4px;
  background: transparent; border: 1px solid transparent; border-radius: 7px;
  padding: 7px 10px; color: var(--txt-2); cursor: pointer;
}
.metricitem:hover { background: var(--panel-2); border-color: var(--line); }
.mi-label { display: block; font-size: 12.5px; color: var(--txt); }
.mi-label code { font-size: 10px; color: var(--txt-3); margin-left: 6px; }
.mi-meta { display: flex; gap: 8px; align-items: center; margin-top: 3px; }
.mi-help { display: block; font-size: 10.5px; color: var(--txt-3); margin-top: 2px; }
.src {
  font: 600 8.5px/1 var(--mono); letter-spacing: .08em; padding: 3px 6px;
  border-radius: 4px; background: var(--panel-2); color: var(--txt-3);
}
.src-PRICE   { color: var(--up);    background: var(--up-soft); }
.src-YAHOO   { color: var(--brand); background: rgba(107,163,222,.12); }
.src-DERIVED { color: #a89be0;      background: rgba(124,107,212,.12); }
.src-APP     { color: var(--amber); background: rgba(217,164,65,.12); }
.src-MANUAL  { color: var(--down);  background: var(--down-soft); }
.cov { font: 400 10px var(--mono); color: var(--txt-3); }
.cov.none { color: var(--down); }

.chip.on { border-color: var(--up); color: var(--up); background: var(--up-soft); }
.chip-n { opacity: .6; margin-left: 3px; }

.formularow {
  display: flex; justify-content: space-between; align-items: center; gap: 10px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 7px;
  margin-bottom: 6px; background: var(--panel-2);
}
.formularow code { font-size: 10.5px; color: var(--brand); }

/* Screener first-run panel */
.setup-panel { border-color: rgba(107,163,222,.4); }
.setup-title { font: 600 15px/1.3 var(--sans); color: var(--txt); margin: 0 0 8px; }
.setup-title .bi { color: var(--brand); margin-right: 6px; }
.setup-lead { font-size: 13px; color: var(--txt-2); margin: 0 0 12px; }
.setup-steps { font-size: 12.5px; color: var(--txt-2); line-height: 1.7;
  padding-left: 20px; margin: 0 0 12px; }
.setup-steps b { color: var(--txt); }
.setup-progress .bar {
  height: 6px; background: var(--panel-2); border-radius: 4px; overflow: hidden;
  border: 1px solid var(--line);
}
.setup-progress .bar span {
  display: block; height: 100%; width: 0;
  background: linear-gradient(90deg, var(--brand-green), var(--brand));
  transition: width .3s ease;
}

/* =====================================================================
   ABOUT
   ===================================================================== */
.about-hero { text-align: center; padding: 12px 16px 26px; }
.about-logo { width: min(320px, 72vw); height: auto; }
.about-tag {
  margin: 16px 0 0; font-size: 13.5px; color: var(--txt-2);
  max-width: 46ch; margin-inline: auto; line-height: 1.6;
}
.about-badges { display: flex; gap: 7px; justify-content: center;
  flex-wrap: wrap; margin-top: 14px; }

.about-prose p { font-size: 13px; color: var(--txt-2); line-height: 1.75;
  max-width: 68ch; margin-bottom: 12px; }

.about-checks { margin: 0; padding: 0; list-style: none; }
.about-checks li {
  position: relative; padding-left: 24px; margin-bottom: 11px;
  font-size: 12.5px; color: var(--txt-2); line-height: 1.65; max-width: 70ch;
}
.about-checks li::before {
  content: "\F26E";                       /* bootstrap-icons check-circle */
  font-family: "bootstrap-icons"; font-size: 12px;
  position: absolute; left: 0; top: 1px; color: var(--up);
}
.about-checks.plain li::before { content: "\F28A"; color: var(--txt-3); }  /* dash-circle */
.about-checks li:last-child { margin-bottom: 0; }
.about-checks b { color: var(--txt); }

.about-libs td { vertical-align: middle; }

/* ---- developer card ---- */
.dev-panel {
  border-color: rgba(107,163,222,.35);
  background:
    radial-gradient(ellipse at 100% 0%, rgba(107,163,222,.10), transparent 62%),
    var(--panel);
}
.dev-eyebrow {
  font: 600 9px/1 var(--mono); letter-spacing: .16em; text-transform: uppercase;
  color: var(--txt-3); margin: 0 0 6px;
}
.dev-name { font: 700 22px/1.2 var(--sans); color: var(--txt); margin: 0 0 4px; }
.dev-line { font-size: 13px; color: var(--brand); margin: 0 0 10px; font-weight: 600; }
.dev-about { font-size: 12.5px; color: var(--txt-2); line-height: 1.7; margin: 0 0 12px; }
.dev-offices { display: flex; gap: 6px; flex-wrap: wrap; margin: 0 0 14px; }

.dev-contact { display: flex; flex-direction: column; gap: 8px; }
.dev-contact a, .dev-contact span {
  display: flex; align-items: flex-start; gap: 9px;
  font-size: 12.5px; color: var(--txt-2); text-decoration: none; line-height: 1.55;
}
.dev-contact a:hover { color: var(--brand); }
.dev-contact .bi { color: var(--txt-3); font-size: 13px; margin-top: 2px; flex: 0 0 14px; }
.dev-taglinetext {
  margin: 16px 0 0; padding-top: 13px; border-top: 1px solid var(--line);
  font-size: 12px; color: var(--txt-3); font-style: italic;
}

.author-card { display: flex; gap: 14px; align-items: flex-start; }
.author-avatar { width: 44px; height: 44px; flex: 0 0 44px;
  border-radius: 10px; font-size: 15px; }
.author-name { font: 600 15px/1.3 var(--sans); color: var(--txt); margin: 0; }
.author-role { font-size: 11.5px; color: var(--txt-3); margin: 3px 0 0; }

/* ---- principles ---- */
.principles { list-style: none; margin: 0; padding: 0; counter-reset: pr; }
.principles li { display: flex; gap: 12px; margin-bottom: 13px; }
.principles li:last-child { margin-bottom: 0; }
.pr-num {
  font: 600 10px/1.6 var(--mono); color: var(--brand);
  flex: 0 0 22px; letter-spacing: .06em;
}
.pr-body b { display: block; font-size: 12.5px; color: var(--txt); font-weight: 600; }
.pr-body span { display: block; font-size: 11.5px; color: var(--txt-3);
  line-height: 1.55; margin-top: 2px; }

/* ---- awards ---- */
.awards { list-style: none; margin: 0; padding: 0; }
.awards li { display: flex; gap: 11px; align-items: flex-start; margin-bottom: 11px; }
.awards li:last-child { margin-bottom: 0; }
.awards .bi { color: var(--amber); font-size: 15px; margin-top: 1px; }
.awards b { display: block; font-size: 12.5px; color: var(--txt); }
.awards span span { display: block; font-size: 11.5px; color: var(--txt-3); margin-top: 1px; }

.about-copy {
  text-align: center; font-size: 11.5px; color: var(--txt-3);
  margin: 22px 0 0; padding-top: 16px; border-top: 1px solid var(--line);
}

@media (max-width: 767.98px) {
  .about-logo { width: 78vw; }
  .dev-name { font-size: 19px; }
}
.foot-credit { color: var(--txt-3); text-decoration: none; }
.foot-credit:hover { color: var(--brand); text-decoration: underline; }
