/* Altstars — shared theme. Same palette proven out in the UI mockups
   (altstars_ui_concepts.html, altstars_home_login_concepts.html).
   Include this once per layout; toggle via <body data-theme="dark|light">.
   Font scaling: html[data-font-size] sets the rem root. All font-sizes in
   this file use rem so every component scales automatically. */

:root{
  --bg:#0a0a0f; --panel:#14141c; --panel-2:#1a1a24; --border:#262631;
  --text:#e8e8ee; --muted:#8a8a98; --muted-2:#5c5c6b;
  --accent:#8b5cf6; --accent-soft:rgba(139,92,246,.15); --accent-text:#c4b5fd;
  --green:#4ade80; --green-soft:rgba(74,222,128,.12);
  --red:#f87171; --red-soft:rgba(248,113,113,.12);
  --amber:#fbbf24; --amber-soft:rgba(251,191,36,.12);
  --mono:'SF Mono',Consolas,Monaco,monospace;
  --sans:-apple-system,'Segoe UI',Roboto,sans-serif;
}
body[data-theme="light"]{
  --bg:#f7f7fa; --panel:#ffffff; --panel-2:#f0f0f5; --border:#e2e2ea;
  --text:#15151c; --muted:#6b6b78; --muted-2:#9999a6;
  --accent:#7c3aed; --accent-soft:#f1ebfe; --accent-text:#7c3aed;
  --green:#16a34a; --green-soft:#e8f8ee;
  --red:#dc2626; --red-soft:#fdeaea;
  --amber:#b45309; --amber-soft:#fdf3e3;
}

/* ── Font scale root — all rem values below scale from here ─────────── */
html{font-size:14px;}
html[data-font-size="small"]{font-size:12px;}
html[data-font-size="large"]{font-size:16px;}

*{box-sizing:border-box;}

/* `hidden` must actually hide. The browser's own [hidden]{display:none} is a
   plain user-agent rule, so ANY class that sets display beats it — .btn is
   display:inline-flex, which means <button class="btn" hidden> renders. That is
   a silent one: the element is there, styled, clickable, and nothing about the
   markup looks wrong. Two components had already worked around it locally
   (.pg-backdrop[hidden], .pg-drawer[hidden]); this fixes the class of bug so the
   next el.hidden = true behaves the way it reads. */
[hidden]{display:none !important;}

body{margin:0;background:var(--bg);color:var(--text);font-family:var(--sans);font-size:1rem;
     transition:background .15s,color .15s;}
h1,h2,h3{margin:0;font-weight:700;}
a{color:inherit;text-decoration:none;}

/* Buttons and fields had no hover, no focus ring and no transition — which is
   most of what makes an interface feel dated. Added here rather than per page
   so every screen picks it up at once.
   :focus-visible, not :focus — a mouse click should not leave a ring behind,
   but a keyboard user must always be able to see where they are. */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:7px;border-radius:8px;
     padding:9px 16px;font:inherit;font-weight:700;font-size:0.929rem;cursor:pointer;
     border:1px solid var(--border);
     transition:background .14s,border-color .14s,color .14s,transform .08s,box-shadow .14s;}
.btn:hover{border-color:var(--accent);}
.btn:active{transform:translateY(1px);}
.btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--accent-soft);border-color:var(--accent);}
.btn.outline{background:none;color:var(--text);}
.btn.outline:hover{background:var(--accent-soft);color:var(--accent-text);}
.btn.filled{background:var(--accent);color:#fff;border-color:var(--accent);}
.btn.filled:hover{filter:brightness(1.12);border-color:var(--accent);}
.btn.danger{background:none;color:var(--red);border-color:var(--border);}
.btn.danger:hover{background:var(--red-soft);border-color:var(--red);}
.btn:disabled{opacity:.5;cursor:not-allowed;transform:none;filter:none;border-color:var(--border);}
.btn .ico{width:1em;height:1em;flex:none;}

/* Form fields */
.field{margin-bottom:14px;}
.field label{display:block;font-size:0.786rem;color:var(--muted);margin-bottom:6px;
             text-transform:uppercase;letter-spacing:.04em;}
.field input,.field select,.field textarea{width:100%;background:var(--panel-2);
             border:1px solid var(--border);color:var(--text);border-radius:8px;
             padding:10px 12px;font:inherit;font-size:0.929rem;
             transition:border-color .14s,box-shadow .14s,background .14s;}
.field input:hover,.field select:hover,.field textarea:hover{border-color:var(--muted-2);}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--accent);
             box-shadow:0 0 0 3px var(--accent-soft);background:var(--panel);}
.field input::placeholder{color:var(--muted-2);}
.field input:disabled{opacity:.55;cursor:not-allowed;}
/* A single control that lives in a toolbar or a header row rather than in a stacked
   form. Same tokens as `.field input` on purpose — an input should not look like a
   different kind of thing for being on its own, which is exactly what happened when the
   Bot page's position cap was written with ad-hoc inline styles. */
.input-inline{background:var(--panel-2);border:1px solid var(--border);color:var(--text);
             border-radius:8px;padding:7px 11px;font:inherit;font-size:0.929rem;
             transition:border-color .14s,box-shadow .14s,background .14s;}
.input-inline:hover{border-color:var(--muted-2);}
.input-inline:focus{outline:none;border-color:var(--accent);
             box-shadow:0 0 0 3px var(--accent-soft);background:var(--panel);}
.input-inline::placeholder{color:var(--muted-2);}
.input-inline:disabled{opacity:.55;cursor:not-allowed;}
/* Spinners are noise on a value typed once and then left alone, and they crowd a
   narrow field. Firefox and WebKit need saying separately. */
.input-inline[type=number]{-moz-appearance:textfield;appearance:textfield;}
.input-inline[type=number]::-webkit-outer-spin-button,
.input-inline[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0;}

/* Checkboxes and radios follow the brand rather than the operating system.
   One line, and it reaches every native control in the app — the alternative is a
   hand-built replacement per page, which is how a form ends up with three different
   ticks. `accent-color` keeps the native control (and its keyboard behaviour and its
   accessibility tree) and only recolours it. */
input[type=checkbox],input[type=radio]{accent-color:var(--accent);}

/* Status line beside an inline field: saving / saved / refused. Sized so the row does
   not reflow as the text changes. */
.input-note{font-size:0.786rem;color:var(--muted-2);margin-left:8px;
             transition:color .14s,opacity .14s;}
.input-note.ok{color:var(--green);}
.input-note.bad{color:var(--red);}

/* Native validation styling is browser-specific and fires while typing; the
   server is the authority here, so only an explicitly-marked field goes red. */
.field.has-error input,.field.has-error select{border-color:var(--red);}
.field .error{color:var(--red);font-size:0.857rem;margin-top:5px;}
/* Both classes on ONE element: the form-level banner above the fields, as
   opposed to `.field .error` above, which is a message nested inside a
   field. Seven views already emit this markup; they were unstyled because
   no rule matched it. Styled as a banner rather than bare red text so it
   mirrors the confirmation box on the forgot-password page. */
.field.error{color:var(--red);background:var(--red-soft);
  border:1px solid color-mix(in srgb,var(--red) 34%,transparent);
  border-radius:8px;padding:10px 13px;font-size:0.893rem;line-height:1.5;}

/* ── Password strength meter ─────────────────────────────────────────────
   Four discrete segments rather than one sliding fill: the segment count is
   readable at a glance and without colour, which a continuous bar is not.

   The colour is the secondary channel; the word beneath it ("Weak", "Very
   strong") is what actually carries the verdict, so the meter still works for
   a reader who cannot separate red from green. */
.pw-meter{margin-top:8px;}
.pw-meter-track{display:flex;gap:4px;}
.pw-meter-seg{flex:1 1 0;height:4px;border-radius:999px;background:var(--panel-2);
  border:1px solid var(--border);transition:background-color .18s ease,border-color .18s ease;}

.pw-meter[data-level="1"] .pw-meter-seg:nth-child(-n+1),
.pw-meter[data-level="2"] .pw-meter-seg:nth-child(-n+2),
.pw-meter[data-level="3"] .pw-meter-seg:nth-child(-n+3),
.pw-meter[data-level="4"] .pw-meter-seg:nth-child(-n+4){border-color:transparent;}

.pw-meter[data-level="1"] .pw-meter-seg:nth-child(-n+1){background:var(--red);}
.pw-meter[data-level="2"] .pw-meter-seg:nth-child(-n+2){background:var(--amber);}
.pw-meter[data-level="3"] .pw-meter-seg:nth-child(-n+3){background:var(--green);}
.pw-meter[data-level="4"] .pw-meter-seg:nth-child(-n+4){background:var(--green);}

.pw-meter-note{display:block;margin-top:6px;font-size:0.821rem;line-height:1.45;
  font-weight:600;color:var(--muted-2);}
.pw-meter[data-level="1"] .pw-meter-note{color:var(--red);}
.pw-meter[data-level="2"] .pw-meter-note{color:var(--amber);}
.pw-meter[data-level="3"] .pw-meter-note,
.pw-meter[data-level="4"] .pw-meter-note{color:var(--green);}

@media (prefers-reduced-motion:reduce){
  .pw-meter-seg{transition:none;}
}

/* ── "Did you mean …?" email suggestion ──────────────────────────────────
   Amber, not red: this is advice about an address that may well be correct,
   and colouring it like a rejection would teach people to ignore it. */
.email-suggest{margin-top:6px;font-size:0.821rem;line-height:1.5;color:var(--amber);}
.email-suggest-apply{background:none;border:none;padding:0;font:inherit;
  font-weight:700;color:var(--amber);text-decoration:underline;cursor:pointer;}
.email-suggest-apply:hover{opacity:.8;}
.email-suggest-apply:focus-visible{outline:2px solid var(--amber);outline-offset:2px;
  border-radius:3px;}

/* Copy-to-clipboard control. The confirmation is the point: without it there is
   no way to tell a successful copy from a dead button. */
.copy-btn{display:inline-flex;align-items:center;gap:5px;background:none;
  border:1px solid var(--border);border-radius:7px;color:var(--muted);
  padding:4px 9px;font:inherit;font-size:0.714rem;font-weight:600;cursor:pointer;
  transition:color .14s,border-color .14s,background .14s;}
.copy-btn:hover{color:var(--text);border-color:var(--accent);background:var(--accent-soft);}
.copy-btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--accent-soft);border-color:var(--accent);}
.copy-btn.copied{color:var(--green);border-color:var(--green);background:var(--green-soft);}
.copy-btn svg{width:12px;height:12px;flex:none;}

/* Cards / panels */
.card{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:18px;}
.pill{display:inline-flex;padding:4px 11px;border-radius:20px;font-size:0.786rem;font-weight:700;
      letter-spacing:.04em;}
.pill.accent{background:var(--accent-soft);color:var(--accent-text);}
.pill.green{background:var(--green-soft);color:var(--green);}
.pill.red{background:var(--red-soft);color:var(--red);}
.pill.gray{background:var(--panel-2);color:var(--muted);}

/* App shell nav (authenticated layout) */
nav.top{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;
        border-bottom:1px solid var(--border);gap:16px;}
nav.top .logo{display:flex;align-items:center;gap:8px;font-weight:700;font-size:1.143rem;flex-shrink:0;}
nav.top .navlinks{display:flex;gap:18px;color:var(--muted);font-size:0.929rem;font-weight:600;}
nav.top .navlinks a.active{color:var(--text);}
.nav-right{display:flex;align-items:center;gap:6px;flex-shrink:0;}
.nav-icon-btn{display:flex;align-items:center;justify-content:center;width:34px;height:34px;
  border-radius:9px;background:var(--panel-2);border:1px solid var(--border);color:var(--muted);
  transition:color .12s,border-color .12s,background .12s;flex-shrink:0;}
.nav-icon-btn:hover{color:var(--text);border-color:var(--muted);}
.nav-icon-btn.active{color:var(--text);background:var(--accent-soft);border-color:var(--accent);}

/* Notification bell */
.notif-bell-wrap{position:relative;}
.notif-bell-btn{position:relative;}
.notif-badge{position:absolute;top:4px;right:4px;min-width:16px;height:16px;
  background:var(--red);color:#fff;border-radius:9999px;font-size:9px;font-weight:700;
  display:flex;align-items:center;justify-content:center;padding:0 3px;pointer-events:none;}
.notif-dropdown{position:absolute;top:calc(100% + 6px);right:0;width:280px;
  background:var(--panel);border:1px solid var(--border);border-radius:10px;
  box-shadow:0 8px 24px rgba(0,0,0,.35);z-index:200;overflow:hidden;}
.notif-dropdown-header{padding:10px 14px 8px;font-size:.7rem;text-transform:uppercase;
  letter-spacing:.07em;color:var(--muted);border-bottom:1px solid var(--border);
  display:flex;align-items:center;justify-content:space-between;}
.notif-clear-btn{background:none;border:none;color:var(--muted);font-size:.75rem;
  cursor:pointer;padding:0;text-transform:none;letter-spacing:0;}
.notif-clear-btn:hover{color:var(--text);}
/* Footer link out of the bell into the full history. Sticky-bottom feel without
   position:sticky — the dropdown scrolls its list, not this. */
.notif-see-all{display:block;padding:10px 14px;text-align:center;font-size:.78rem;
  color:var(--accent-text);border-top:1px solid var(--border);text-decoration:none;}
.notif-see-all:hover{background:var(--panel-2);}
.notif-item{display:flex;align-items:flex-start;gap:10px;padding:10px 14px;
  font-size:.82rem;border-bottom:1px solid var(--border);}
.notif-item:last-child{border-bottom:none;}
.notif-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0;margin-top:4px;}
.notif-dot.error{background:var(--red);}
.notif-dot.warning{background:#f59e0b;}
.notif-item-body{flex:1;}
.notif-item-label{font-weight:600;color:var(--text);}
.notif-item-detail{color:var(--muted);font-size:.77rem;margin-top:2px;}
.notif-clear{padding:12px 14px;color:var(--muted);font-size:.82rem;text-align:center;}
.notif-dropdown-footer{padding:8px 10px;border-top:1px solid var(--border);}
.notif-action-btn{width:100%;padding:7px 10px;border:1px solid var(--border);border-radius:7px;
  background:var(--panel-2);color:var(--text);font-size:.78rem;cursor:pointer;}
.notif-action-btn:hover{border-color:var(--red);color:var(--red);}
.notif-action-btn:disabled{opacity:.6;cursor:not-allowed;}

/* Status banner (e.g. "Account created.") */
.status-banner{background:var(--green-soft);color:var(--green);border-radius:8px;padding:10px 14px;
               font-size:0.929rem;margin-bottom:16px;}

.container{max-width:760px;margin:0 auto;padding:24px 20px;}
table.data{width:100%;border-collapse:collapse;font-size:0.929rem;}
table.data th{text-align:left;color:var(--muted-2);font-size:0.786rem;text-transform:uppercase;
              letter-spacing:.04em;padding:8px 10px;border-bottom:1px solid var(--border);}
table.data td{padding:10px;border-bottom:1px solid var(--border);}

/* ── Wide container ─────────────────────────────────────────────────── */
.container-wide{width:100%;padding:0;}

/* ── Page layouts ───────────────────────────────────────────────────── */
.page-split{display:grid;grid-template-columns:220px 1fr;min-height:calc(100vh - 57px);overflow:hidden;}
.page-sidebar{border-right:1px solid var(--border);padding:12px;overflow-y:auto;background:var(--panel);}
.page-main{overflow-x:auto;overflow-y:auto;}
.settings-layout{display:grid;grid-template-columns:190px 1fr;min-height:calc(100vh - 57px);}
.settings-nav-panel{border-right:1px solid var(--border);padding:16px 10px;background:var(--panel);}
.settings-nav-panel a{display:flex;align-items:center;gap:8px;padding:9px 12px;border-radius:8px;
  font-size:0.929rem;color:var(--muted);margin-bottom:2px;transition:background .1s,color .1s;}
.settings-nav-panel a:hover{background:var(--panel-2);color:var(--text);}
.settings-nav-panel a.active{background:var(--panel-2);color:var(--text);font-weight:600;}
.settings-nav-panel .nav-section{font-size:0.714rem;text-transform:uppercase;letter-spacing:.06em;
  color:var(--muted-2);padding:12px 12px 4px;margin-top:8px;}
.settings-body{padding:28px;max-width:660px;}
.settings-body h2{font-size:1.143rem;margin-bottom:20px;}
.display-option-group{display:flex;gap:10px;flex-wrap:wrap;}
.display-option{display:flex;align-items:center;gap:8px;padding:10px 16px;border-radius:9px;
  border:1px solid var(--border);cursor:pointer;font-size:0.929rem;color:var(--muted);
  background:var(--panel-2);transition:border-color .12s,color .12s,background .12s;}
.display-option input[type=radio]{display:none;}
.display-option:hover{border-color:var(--accent);color:var(--text);}
.display-option.active{border-color:var(--accent);background:var(--accent-soft);color:var(--text);font-weight:600;}
.display-option-icon{font-size:1.071rem;}
/* Previews use fixed px — they demonstrate size, not inherit from scale */
.display-option-size-preview[data-size="small"]{font-size:11px;font-weight:700;color:inherit;}
.display-option-size-preview[data-size="medium"]{font-size:14px;font-weight:700;color:inherit;}
.display-option-size-preview[data-size="large"]{font-size:18px;font-weight:700;color:inherit;}

/* ── Profile page ───────────────────────────────────────────────────── */
.profile-page{max-width:460px;margin:0 auto;padding:48px 20px 40px;text-align:center;}
.profile-avatar{width:72px;height:72px;border-radius:50%;background:var(--accent-soft);
  border:2px solid var(--accent);color:var(--accent-text);font-size:2rem;font-weight:700;
  display:flex;align-items:center;justify-content:center;margin:0 auto 16px;}
.profile-name{font-size:1.429rem;font-weight:700;margin-bottom:8px;}
.profile-role{margin-bottom:24px;}
.profile-card{text-align:left;margin-bottom:20px;}
.profile-row{display:flex;align-items:center;gap:12px;padding:9px 0;border-bottom:1px solid var(--border);}
.profile-row:last-child{border-bottom:none;}
.profile-label{font-size:0.857rem;color:var(--muted);min-width:90px;text-transform:uppercase;
  letter-spacing:.04em;}
.profile-actions{display:flex;gap:10px;justify-content:center;}

/* ── Exchange tabs (scanner) ────────────────────────────────────────── */
.exchange-bar{display:flex;align-items:center;gap:6px;padding:10px 16px;border-bottom:1px solid var(--border);
  background:var(--panel);}
.ex-tab{padding:5px 13px;border-radius:6px;font-size:0.857rem;font-weight:600;cursor:pointer;
  border:1px solid transparent;background:none;color:var(--muted);font-family:var(--sans);}
.ex-tab.active{background:var(--accent);color:#fff;border-color:var(--accent);}
.ex-tab:disabled{opacity:.35;cursor:not-allowed;}
/* The market tabs are links, not buttons: switching venue reloads the board, the profile
   sidebar and the detail panel together, and the URL then names the market so it can be
   bookmarked and shared. An anchor needs the button-ish bits an anchor does not inherit. */
a.ex-tab{text-decoration:none;white-space:nowrap;}
a.ex-tab:hover{color:var(--text);background:var(--panel-2);}
a.ex-tab.active:hover{color:#fff;background:var(--accent);}
.scanner-toolbar{display:flex;align-items:center;gap:10px;padding:10px 16px;
  border-bottom:1px solid var(--border);background:var(--panel-2);}
.scanner-toolbar input{flex:1;max-width:240px;background:var(--panel);border:1px solid var(--border);
  color:var(--text);border-radius:7px;padding:7px 11px;font:inherit;font-size:0.857rem;}
.scanner-toolbar label{font-size:0.786rem;color:var(--muted);}
.scanner-toolbar select{background:var(--panel);border:1px solid var(--border);color:var(--text);
  border-radius:7px;padding:6px 10px;font:inherit;font-size:0.857rem;}
.refresh-dot{width:7px;height:7px;border-radius:50%;background:var(--muted-2);display:inline-block;margin-right:4px;}
.refresh-dot.live{background:var(--green);animation:pulse 2s infinite;}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.4}}

/* ── Scanner data table ─────────────────────────────────────────────── */
.scanner-table-wrap{overflow-x:auto;}
table.scanner{width:100%;border-collapse:collapse;font-size:0.857rem;}
table.scanner th{position:sticky;top:0;background:var(--panel);color:var(--muted-2);font-size:0.714rem;
  text-transform:uppercase;letter-spacing:.05em;padding:8px 10px;border-bottom:1px solid var(--border);
  white-space:nowrap;text-align:right;z-index:1;}
table.scanner th:first-child,table.scanner td:first-child{text-align:left;position:sticky;left:0;
  background:var(--panel);z-index:2;}
table.scanner th:first-child{z-index:3;}
table.scanner td{padding:7px 10px;border-bottom:1px solid var(--border);font-family:var(--mono);
  white-space:nowrap;text-align:right;color:var(--text);}
table.scanner tr:hover td{background:var(--panel-2);}
/* Sortable headers */
table.scanner th.sortable{cursor:pointer;user-select:none;}
table.scanner th.sortable:hover{color:var(--text);}
table.scanner th.sortable.sorted{color:var(--accent-text);}
.sort-arrow{display:inline-block;width:9px;font-size:0.6rem;margin-left:3px;color:var(--accent-text);vertical-align:middle;}
/* Pagination */
#scanner-pagination:empty{display:none;}
.pager{display:flex;align-items:center;justify-content:space-between;gap:12px;
  padding:8px 14px;border-top:1px solid var(--border);background:var(--panel);flex-wrap:wrap;}
.pager-info{font-size:0.714rem;color:var(--muted);white-space:nowrap;}
.pager-controls{display:flex;align-items:center;gap:3px;}
.pager-btn{min-width:26px;height:26px;padding:0 7px;background:var(--panel-2);
  border:1px solid var(--border);border-radius:5px;color:var(--muted);
  font-size:0.75rem;font-weight:600;cursor:pointer;font-family:var(--sans);
  transition:background .12s,color .12s;}
.pager-btn:hover:not(:disabled){background:var(--panel);color:var(--text);}
.pager-btn.active{background:var(--accent);border-color:var(--accent);color:#fff;}
.pager-btn:disabled{opacity:.4;cursor:default;}
.pager-ellipsis{color:var(--muted-2);padding:0 2px;font-size:0.75rem;}
/* Send Signal action column */
table.scanner th.action-col,table.scanner td:last-child{text-align:center;}
.send-signal-btn{background:var(--accent-soft);border:1px solid rgba(139,92,246,.3);
  color:var(--accent-text);border-radius:5px;padding:3px 12px;font-size:0.7rem;font-weight:700;
  letter-spacing:.02em;cursor:pointer;font-family:var(--sans);white-space:nowrap;
  transition:background .12s,color .12s;}
.send-signal-btn:hover{background:var(--accent);color:#fff;border-color:var(--accent);}
table.scanner tr.watchlisted td:first-child{border-left:2px solid var(--accent);}
/* Meta match — pair satisfies ALL active profiles simultaneously */
table.scanner tr.meta-match td{background:linear-gradient(90deg,var(--accent-soft),transparent 60%);}
table.scanner tr.meta-match td:first-child{border-left:2px solid #ec4899;}
table.scanner tr.meta-match:hover td{background:linear-gradient(90deg,var(--accent-soft),var(--panel-2) 60%);}
.meta-badge{font-size:0.571rem;font-weight:700;letter-spacing:.05em;line-height:1;
  padding:2px 5px;border-radius:4px;color:#fff;background:linear-gradient(135deg,#8b5cf6,#ec4899);}
.profile-badge{font-size:0.571rem;font-weight:600;letter-spacing:.03em;line-height:1;
  padding:2px 6px;border-radius:4px;color:var(--accent-text);background:var(--accent-soft);
  border:1px solid rgba(139,92,246,.3);white-space:nowrap;}
.pair-cell{display:flex;align-items:center;gap:8px;}
.pair-sym{font-weight:700;font-size:0.857rem;font-family:var(--mono);}
.pair-exbadge{font-size:0.643rem;color:var(--muted-2);background:var(--panel-2);padding:1px 5px;border-radius:3px;}
.pair-actions{display:none;gap:4px;margin-left:auto;}
table.scanner tr:hover .pair-actions{display:flex;}
.pair-action-btn{background:none;border:none;cursor:pointer;color:var(--muted);padding:2px 4px;border-radius:4px;font-size:0.929rem;}
.pair-action-btn:hover{color:var(--text);background:var(--panel-2);}
.chg{font-size:0.857rem;font-family:var(--mono);}
.chg.pos{color:var(--green);}
.chg.neg{color:var(--red);}
.chg.nil{color:var(--muted-2);}
/* The change columns show the bar in progress. A pair with no live candle in the cache
   (~10% of them on 15m and slower, illiquid or newly listed) falls back to its last
   CLOSED bar, and that has to look different — the number is not wrong, it is just about
   a different stretch of time than the cell beside it. Dotted underline, hover says which. */
.chg-stale{opacity:.55;text-decoration:underline dotted currentColor 1px;text-underline-offset:3px;}
.sparkline{display:inline-flex;align-items:flex-end;gap:2px;height:18px;vertical-align:middle;}
.sparkline span{width:5px;border-radius:2px 2px 0 0;min-height:2px;}

/* ── Profile sidebar ────────────────────────────────────────────────── */
.sidebar-heading{font-size:0.714rem;text-transform:uppercase;letter-spacing:.06em;color:var(--muted-2);
  padding:4px 6px 8px;margin-top:8px;}
.profile-row{display:flex;align-items:center;gap:8px;padding:8px 10px;border-radius:8px;
  cursor:pointer;font-size:0.929rem;margin-bottom:2px;}
.profile-row:hover{background:var(--panel-2);}
.profile-row.selected{background:var(--accent-soft);color:var(--accent-text);}
.profile-row .pname{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.profile-row .pcnt{font-size:0.786rem;color:var(--muted);font-family:var(--mono);}

/* ── Toggle switch ──────────────────────────────────────────────────── */
.toggle{position:relative;width:32px;height:17px;flex-shrink:0;}
.toggle input{opacity:0;width:0;height:0;position:absolute;}
.toggle-track{position:absolute;inset:0;background:var(--border);border-radius:17px;cursor:pointer;transition:.2s;}
.toggle input:checked~.toggle-track{background:var(--accent);}
.toggle-thumb{position:absolute;width:11px;height:11px;top:3px;left:3px;background:#fff;
  border-radius:50%;transition:.2s;pointer-events:none;}
.toggle input:checked~.toggle-thumb{transform:translateX(15px);}

/* ── Chip row (profile notification toggles) ────────────────────────── */
.chip-row{display:flex;gap:6px;flex-wrap:wrap;margin-bottom:16px;}
.chip{padding:5px 13px;border-radius:20px;font-size:0.857rem;font-weight:600;border:1px solid var(--border);
  background:none;color:var(--muted);cursor:pointer;font-family:var(--sans);transition:.15s;}
.chip.on{background:var(--accent-soft);color:var(--accent-text);border-color:rgba(139,92,246,.3);}

/* ── Condition builder rows ─────────────────────────────────────────── */
.condition-row{display:flex;align-items:center;gap:6px;padding:9px;background:var(--panel-2);
  border-radius:8px;margin-bottom:6px;flex-wrap:wrap;}
.condition-row select,.condition-row input[type=number]{background:var(--panel);border:1px solid var(--border);
  color:var(--text);border-radius:6px;padding:5px 8px;font:inherit;font-size:0.857rem;}
.condition-sep{font-size:0.714rem;font-weight:700;text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted-2);text-align:center;margin:4px 0;}
.condition-del{background:none;border:none;color:var(--muted);cursor:pointer;padding:4px;
  border-radius:4px;font-size:1rem;line-height:1;}
.condition-del:hover{color:var(--red);}

/* Starter (preset) profiles: the value is editable in place, the structure is
   not. The lock replaces the delete button so the row keeps its shape rather
   than reflowing between preset and normal profiles. */
.cond-value{background:var(--panel);border:1px solid var(--border);color:var(--text);
  border-radius:6px;padding:4px 7px;font:inherit;font-family:var(--mono);font-size:0.786rem;
  width:88px;transition:border-color .15s,background .15s;}
.cond-value:focus{outline:none;border-color:var(--accent,#8b5cf6);}
.cond-value.saved{border-color:var(--green,#22c55e);background:rgba(34,197,94,.08);}
.cond-value.failed{border-color:var(--red,#ef4444);background:rgba(239,68,68,.08);}
.condition-locked{color:var(--muted-2);font-size:0.786rem;padding:4px;cursor:help;line-height:1;}
.badge.preset{background:rgba(139,92,246,.14);color:var(--accent,#8b5cf6);
  border:1px solid rgba(139,92,246,.3);}

/* ── Stat cards (dashboard) ─────────────────────────────────────────── */
.stats-row{display:grid;grid-template-columns:repeat(4,1fr);gap:12px;margin-bottom:20px;}
@media(max-width:900px){.stats-row{grid-template-columns:repeat(2,1fr);}}
.stat-card{background:var(--panel);border:1px solid var(--border);border-radius:12px;padding:16px 18px;}
.stat-val{font-size:1.857rem;font-weight:700;font-family:var(--mono);line-height:1;}
.stat-val.pos{color:var(--green);}
.stat-val.neg{color:var(--red);}
.stat-lbl{font-size:0.786rem;color:var(--muted);text-transform:uppercase;letter-spacing:.04em;margin-top:6px;}

/* ── Report language (Statistics, Plans, AI Usage, Access Codes) ─────────
   Lifted out of statistics/index.blade.php so the admin report pages share one
   definition rather than each re-declaring a near-copy. The class names are
   unchanged so that page's markup and its scoreboard JS still match. */
.stat-flex{display:grid;grid-template-columns:repeat(auto-fill,minmax(155px,1fr));gap:12px;margin-bottom:20px;}

.s-title{font-size:1.286rem;font-weight:700;margin-bottom:4px;}
.s-sub{font-size:0.929rem;color:var(--muted);margin-bottom:24px;line-height:1.6;}

.chart-card{background:var(--panel);border:1px solid var(--border);border-radius:12px;
  padding:18px;margin-bottom:16px;}
.chart-card:last-child{margin-bottom:0;}
.cc-title{font-size:0.929rem;font-weight:700;margin-bottom:3px;}
.cc-sub{font-size:0.786rem;color:var(--muted);margin-bottom:14px;line-height:1.55;}

/* Data table. Right-aligned by default because most columns are numbers; the
   first column opts back out with .l. */
.sb-table{width:100%;border-collapse:collapse;font-size:0.929rem;}
.sb-table th{font-size:0.786rem;text-transform:uppercase;letter-spacing:.04em;color:var(--muted-2);
  font-weight:600;text-align:right;padding:6px 12px;border-bottom:1px solid var(--border);white-space:nowrap;}
.sb-table td{text-align:right;padding:9px 12px;border-bottom:1px solid var(--border);white-space:nowrap;}
.sb-table th.l,.sb-table td.l{text-align:left;}
.sb-table tbody tr:last-child td{border-bottom:none;}
.sb-table tbody tr:hover{background:var(--panel-2);}
.sb-row-fail td{background:color-mix(in srgb,var(--red) 6%,transparent);}
.sb-mono{font-family:var(--mono);}
.sb-name{font-weight:600;}
.sb-id{color:var(--muted-2);font-size:0.786rem;margin-left:5px;}

.sb-badge{display:inline-block;font-size:0.714rem;font-weight:700;letter-spacing:.04em;
  padding:2px 8px;border-radius:999px;border:1px solid transparent;}
.sb-badge.pass{color:var(--green);background:color-mix(in srgb,var(--green) 14%,transparent);border-color:color-mix(in srgb,var(--green) 30%,transparent);}
.sb-badge.fail{color:var(--red);background:color-mix(in srgb,var(--red) 14%,transparent);border-color:color-mix(in srgb,var(--red) 30%,transparent);}
.sb-badge.thin{color:var(--muted);background:var(--panel-2);border-color:var(--border);}
.sb-badge.no-data{color:var(--muted-2);background:transparent;border-color:var(--border);}
.sb-badge.accent{color:var(--accent-text);background:var(--accent-soft);border-color:color-mix(in srgb,var(--accent) 34%,transparent);}
.sb-legend{display:flex;flex-wrap:wrap;gap:16px;margin-top:14px;font-size:0.857rem;color:var(--muted);}
.sb-legend > span{display:flex;align-items:center;gap:7px;}

/* ── Guest theme toggle (login, register, reset, 2FA challenge) ──────────── */
/* Matches .mkt-icon-btn so the control looks the same either side of the click
   from the marketing site into Log In. Fixed rather than in a header: the guest
   pages are a single centred card with no chrome to hang it from. */
.guest-theme-toggle{position:fixed;top:18px;right:18px;z-index:20;
  width:36px;height:36px;border-radius:9px;background:var(--panel-2);
  border:1px solid var(--border);color:var(--muted);display:flex;align-items:center;
  justify-content:center;cursor:pointer;transition:color .15s,border-color .15s;}
.guest-theme-toggle:hover{color:var(--text);border-color:var(--muted);}
@media(max-width:600px){.guest-theme-toggle{top:12px;right:12px;}}

/* ── Social sign-in buttons (login / register) ───────────────────────────── */
.social-divider{display:flex;align-items:center;gap:12px;margin:20px 0 16px;
  color:var(--muted-2);font-size:0.786rem;text-transform:uppercase;letter-spacing:.06em;}
.social-divider::before,.social-divider::after{content:"";flex:1;height:1px;background:var(--border);}
/* Buttons flow rather than stack, and the BASIS decides when they wrap, so
   the row reacts to the card it sits in and not to the viewport: two
   providers sit together in the wide register form and take their own
   lines in the narrow login card, with no breakpoint to keep in step. */
.social-buttons{display:flex;flex-direction:row;flex-wrap:wrap;gap:9px;}
.social-btn{flex:1 1 190px;justify-content:center;
  display:flex;align-items:center;gap:11px;padding:10px 14px;border-radius:9px;
  border:1px solid var(--border);background:var(--panel-2);color:var(--text);
  font-size:0.929rem;font-weight:600;text-decoration:none;transition:border-color .12s,transform .12s;}
.social-btn:hover{border-color:var(--accent);transform:translateY(-1px);}
/* Now a plain box holding a real brand SVG, not a coloured tile behind a
   white letter. The background and the white text colour are gone on
   purpose: Google's mark carries its own four colours and must not sit on
   a tinted square, and GitHub's uses currentColor so it follows the theme.
   flex:none keeps every label starting at the same x whatever the mark. */
.social-mark{width:22px;height:22px;display:flex;align-items:center;justify-content:center;
  line-height:1;flex:none;}

/* Linked-account rows in Settings → Profile */
.social-link-row{display:flex;align-items:center;gap:12px;padding:11px 0;
  border-bottom:1px solid var(--border);font-size:0.929rem;}
.social-link-row:last-child{border-bottom:none;}
.social-link-row .meta{flex:1;min-width:0;}
.social-link-row .meta small{display:block;color:var(--muted-2);font-size:0.786rem;margin-top:2px;}

/* A settings page that is a report rather than a form needs the whole width.
   .settings-body's 660px cap is right for forms and wrong for tables. */
.settings-body.wide{max-width:none;padding:28px 32px;}
@media(max-width:900px){.settings-body.wide{padding:20px 16px;}}

/* ── Heatmap calendar ───────────────────────────────────────────────── */
.heatmap-wrap{background:var(--panel);border:1px solid var(--border);border-radius:12px;
  padding:18px;margin-bottom:20px;}
.heatmap-month-label{font-size:0.786rem;color:var(--muted);margin-bottom:10px;}
.heatmap-dow-row{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;margin-bottom:4px;}
.heatmap-dow-row span{font-size:0.643rem;color:var(--muted-2);text-align:center;text-transform:uppercase;}
.heatmap-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:4px;}
.heatmap-cell{aspect-ratio:1;border-radius:4px;background:var(--panel-2);cursor:default;
  position:relative;}
.heatmap-cell[title]:hover::after{content:attr(title);position:absolute;bottom:calc(100% + 4px);
  left:50%;transform:translateX(-50%);background:var(--panel);border:1px solid var(--border);
  border-radius:6px;padding:4px 8px;font-size:0.786rem;white-space:nowrap;z-index:10;pointer-events:none;}
.heatmap-cell.p1{background:rgba(74,222,128,.2);}
.heatmap-cell.p2{background:rgba(74,222,128,.4);}
.heatmap-cell.p3{background:rgba(74,222,128,.65);}
.heatmap-cell.p4{background:var(--green);}
.heatmap-cell.n1{background:rgba(248,113,113,.2);}
.heatmap-cell.n2{background:rgba(248,113,113,.4);}
.heatmap-cell.n3{background:rgba(248,113,113,.65);}
.heatmap-cell.n4{background:var(--red);}

/* ── Signal type badges ─────────────────────────────────────────────── */
.badge{display:inline-flex;padding:2px 8px;border-radius:4px;font-size:0.714rem;font-weight:700;
  letter-spacing:.04em;text-transform:uppercase;}
.badge.gainer{background:var(--green-soft);color:var(--green);}
.badge.loser{background:var(--red-soft);color:var(--red);}
.badge.technical{background:var(--accent-soft);color:var(--accent-text);}
.badge.combined{background:rgba(251,146,60,.12);color:#fb923c;}
.badge.manual{background:var(--panel-2);color:var(--muted);}
.badge.meta{background:rgba(236,72,153,.12);color:#f472b6;}
.badge.open{background:var(--green-soft);color:var(--green);}
.badge.closed{background:var(--panel-2);color:var(--muted);}

/* ── Modal ──────────────────────────────────────────────────────────── */
.modal-backdrop{display:none;position:fixed;inset:0;background:rgba(0,0,0,.6);
  z-index:200;align-items:center;justify-content:center;}
.modal-backdrop.open{display:flex;}
.modal{background:var(--panel);border:1px solid var(--border);border-radius:14px;padding:24px;
  min-width:380px;max-width:92vw;max-height:90vh;overflow-y:auto;}
.modal-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:18px;}
.modal-title{font-size:1.071rem;font-weight:700;margin:0;}
.modal-close{background:none;border:none;color:var(--muted);font-size:1.286rem;cursor:pointer;
  padding:2px 6px;border-radius:4px;}
.modal-close:hover{color:var(--text);}
.modal-footer{display:flex;gap:8px;justify-content:flex-end;margin-top:18px;padding-top:14px;
  border-top:1px solid var(--border);}

/* ── Floating action button ─────────────────────────────────────────── */
.fab{position:fixed;bottom:24px;right:24px;width:48px;height:48px;border-radius:50%;
  background:var(--accent);border:none;color:#fff;font-size:1.571rem;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  box-shadow:0 4px 16px rgba(139,92,246,.45);z-index:50;transition:transform .15s;}
.fab:hover{transform:scale(1.08);}

/* ── Bot page ───────────────────────────────────────────────────────── */
.bot-status-bar{display:flex;align-items:center;gap:12px;padding:14px 20px;
  background:var(--panel);border:1px solid var(--border);border-radius:12px;margin-bottom:20px;}
.bot-indicator{width:10px;height:10px;border-radius:50%;background:var(--muted-2);}
.bot-indicator.running{background:var(--green);animation:pulse 2s infinite;}
.bot-indicator.stopped{background:var(--red);}
.log-tail{background:var(--panel);border:1px solid var(--border);border-radius:10px;
  padding:12px;font-family:var(--mono);font-size:0.786rem;color:var(--muted);
  height:260px;overflow-y:auto;white-space:pre-wrap;}
.log-line{padding:1px 0;line-height:1.5;}
.log-line.ok{color:var(--green);}
.log-line.err{color:var(--red);}
.log-line.info{color:var(--accent-text);}

/* ── Utility ────────────────────────────────────────────────────────── */
.divider{height:1px;background:var(--border);margin:16px 0;}
.section-title{font-size:0.929rem;font-weight:700;color:var(--muted);text-transform:uppercase;
  letter-spacing:.05em;margin-bottom:12px;}
.empty-state{text-align:center;padding:48px 24px;color:var(--muted);}
.empty-state .es-icon{font-size:2.286rem;margin-bottom:12px;}
.empty-state .es-msg{font-size:1rem;}
.filter-bar{display:flex;align-items:center;gap:8px;padding:12px 16px;
  border-bottom:1px solid var(--border);flex-wrap:wrap;}
.filter-bar select,.filter-bar input{background:var(--panel);border:1px solid var(--border);
  color:var(--text);border-radius:7px;padding:6px 10px;font:inherit;font-size:0.857rem;}
.actions-col{display:flex;gap:6px;justify-content:flex-end;}
.icon-btn{background:none;border:1px solid var(--border);color:var(--muted);border-radius:6px;
  padding:4px 8px;cursor:pointer;font-size:0.857rem;line-height:1;}
.icon-btn:hover{color:var(--text);border-color:var(--muted);}
a.icon-btn{display:inline-flex;align-items:center;}

/* ── Pair Detail Panel ──────────────────────────────────────────────── */
.pd-tf-btn{background:var(--panel-2);border:1px solid var(--border);color:var(--muted);
  border-radius:5px;padding:4px 9px;font:inherit;font-size:0.786rem;font-weight:600;cursor:pointer;}
.pd-tf-btn.active{background:var(--accent);color:#fff;border-color:var(--accent);}
.pd-ema-row{display:flex;justify-content:space-between;align-items:baseline;padding:6px 0;
  border-bottom:1px solid var(--border);}
.pd-ema-row:last-of-type{border-bottom:none;}
.pd-ema-name{color:var(--muted);font-size:0.857rem;}
.pd-ema-val{font-family:var(--mono);font-size:0.857rem;font-weight:600;text-align:right;}
.pd-verdict{margin-top:10px;padding:8px 10px;border-radius:7px;font-size:0.786rem;font-weight:600;line-height:1.4;}
.pd-verdict.green{background:var(--green-soft);color:var(--green);}
.pd-verdict.red{background:var(--red-soft);color:var(--red);}
.pd-verdict.muted{background:var(--panel-2);color:var(--muted);}
.pd-gauge{height:6px;border-radius:3px;background:var(--panel-2);position:relative;margin:6px 0 2px;overflow:hidden;}
.pd-gauge-zone-low{position:absolute;left:0;width:30%;height:100%;background:rgba(248,113,113,.18);}
.pd-gauge-zone-high{position:absolute;right:0;width:30%;height:100%;background:rgba(74,222,128,.18);}
.pd-gauge-marker{position:absolute;top:-2px;width:3px;height:10px;background:var(--text);border-radius:2px;}
table.scanner tbody tr{cursor:pointer;}
table.scanner tr.scanner-selected td{background:var(--accent-soft)!important;}

/* ── Nav global search ──────────────────────────────────────────────── */
.nav-search{position:relative;display:flex;align-items:center;}
.nav-search-input{background:var(--panel-2);border:1px solid var(--border);color:var(--text);
  border-radius:20px;padding:7px 36px 7px 14px;font:inherit;font-size:0.929rem;width:160px;
  transition:border-color .15s,width .2s;}
.nav-search-input:focus{outline:none;border-color:var(--muted);width:220px;}
.nav-search-input::placeholder{color:var(--muted-2);}
.nav-search-icon{position:absolute;right:12px;pointer-events:none;color:var(--muted-2);
  display:flex;align-items:center;}

/* ── Autocomplete dropdown (shared by nav + scanner + signals) ────────── */
/* Sizes to its CONTENT, with the field's width only as a floor.
   It used to take its width from the input, and `overflow:hidden` (there for the
   rounded corners) then CLIPPED anything longer instead of scrolling it — so once
   the venue badge joined each row, the symbol it is meant to disambiguate was the
   part that disappeared. Several of these boxes hang off a 140px filter field.
   max-width keeps it on screen on a phone. */
.search-dropdown{position:absolute;top:calc(100% + 6px);right:0;left:auto;
  width:max-content;min-width:220px;max-width:min(90vw,420px);
  background:var(--panel);border:1px solid var(--border);border-radius:10px;
  overflow:hidden;z-index:300;display:none;box-shadow:0 8px 24px rgba(0,0,0,.3);}
.search-dropdown.open{display:block;}
.search-dropdown-item{padding:9px 14px;cursor:pointer;font-size:0.929rem;display:flex;
  align-items:center;gap:10px;border-bottom:1px solid var(--border);}
.search-dropdown-item:last-child{border-bottom:none;}
.search-dropdown-item:hover{background:var(--accent-soft);}
/* Never wrapped and never shrunk: the symbol is the answer the list exists to give,
   so it is the last thing that should lose room to the badge beside it. */
.search-dropdown-sym{font-family:var(--mono);font-weight:700;white-space:nowrap;flex:none;}
/* The venue leads the row, and is sized so the symbols line up underneath each
   other — 236 symbols are listed on BOTH venues, so two rows of a search differ
   only by this badge and the eye has to be able to find it in one place. It used
   to sit at the far right behind `margin-left:auto`, which put the one
   distinguishing field as far from the name as the row allowed. */
.search-dropdown-exch{font-size:0.679rem;font-weight:700;letter-spacing:.04em;
  text-transform:uppercase;color:var(--muted);background:var(--panel-2);
  border:1px solid var(--border);border-radius:5px;padding:2px 6px;
  flex:none;min-width:58px;text-align:center;white-space:nowrap;}
.search-dropdown-empty{padding:10px 14px;font-size:0.857rem;color:var(--muted);text-align:center;}

/* ══════════════════════════════════════════════════════════════════════
   Responsive — tablet & mobile. Desktop-first; these blocks only narrow
   things down. Breakpoints: 1100 (app nav → hamburger), 900 (stat grids,
   handled above), 768 (split sidebars → drawers, settings stacks), 700/560
   (nav shrinks), 600/480 (containers, modals, phones).
   ══════════════════════════════════════════════════════════════════════ */

/* Mobile sidebar toggle (scanner, filter-profiles) — CSS the JS relies on */
.sidebar-toggle-btn{display:inline-flex;align-items:center;gap:6px;background:var(--panel-2);
  border:1px solid var(--border);color:var(--text);border-radius:7px;padding:7px 12px;
  font:inherit;font-size:0.857rem;font-weight:600;cursor:pointer;flex-shrink:0;}
.sidebar-toggle-btn:hover{border-color:var(--muted);}
.sidebar-toggle-btn.active{background:var(--accent-soft);border-color:var(--accent);color:var(--accent-text);}

/* Nav hamburger — hidden on desktop, revealed when the app nav collapses */
.nav-toggle{display:none;align-items:center;justify-content:center;width:34px;height:34px;
  border-radius:9px;background:var(--panel-2);border:1px solid var(--border);color:var(--muted);
  cursor:pointer;flex-shrink:0;}
.nav-toggle:hover{color:var(--text);border-color:var(--muted);}
.nav-toggle.active{color:var(--text);background:var(--accent-soft);border-color:var(--accent);}

/* ── ≤1100px: app nav collapses into a hamburger dropdown ─────────────── */
@media(max-width:1100px){
  nav.top.app-nav{position:relative;flex-wrap:wrap;}
  nav.top.app-nav .nav-toggle{display:flex;}
  nav.top.app-nav .navlinks{position:absolute;top:100%;left:0;right:0;flex-direction:column;
    align-items:stretch;gap:0;background:var(--panel);border-bottom:1px solid var(--border);
    box-shadow:0 10px 24px rgba(0,0,0,.35);padding:6px 14px 10px;display:none;z-index:150;}
  nav.top.app-nav .navlinks.open{display:flex;}
  nav.top.app-nav .navlinks a{padding:12px 6px;border-bottom:1px solid var(--border);font-size:1rem;}
  nav.top.app-nav .navlinks a:last-child{border-bottom:none;}
}

/* ── ≤700px: shrink nav so the search + icons still fit one row ────────── */
@media(max-width:700px){
  nav.top{padding:10px 14px;gap:10px;}
  .nav-search-input{width:120px;}
  .nav-search-input:focus{width:150px;}
  nav.top .navlinks{gap:12px;}
}
@media(max-width:560px){
  /* The global search also lives on the scanner page — reclaim the room */
  nav.top.app-nav .nav-search{display:none;}
  nav.top .navlinks{font-size:0.85rem;}
}

/* ── ≤768px: page-split (scanner, profiles) → single column + drawer ──── */
@media(max-width:768px){
  .page-split{grid-template-columns:1fr!important;height:auto!important;min-height:0!important;
    overflow:visible!important;}
  .page-sidebar{display:none;max-width:none!important;min-width:0!important;width:100%!important;
    border-right:none;border-bottom:1px solid var(--border);}
  .page-sidebar.mob-open{display:block;}

  /* Settings: nav becomes a wrapping top strip, body below */
  .settings-layout{grid-template-columns:1fr;min-height:0;}
  .settings-nav-panel{border-right:none;border-bottom:1px solid var(--border);
    display:flex;flex-wrap:wrap;gap:4px;padding:10px 12px;}
  .settings-nav-panel .nav-section{width:100%;margin-top:4px;padding:6px 6px 2px;}
  .settings-nav-panel a{margin-bottom:0;}
  .settings-body{padding:20px 16px;max-width:none;}

  /* Toolbars wrap instead of overflowing off-screen */
  .exchange-bar,.scanner-toolbar,.filter-bar{flex-wrap:wrap;}
}

/* ── ≤600px: containers & panels tighten ──────────────────────────────── */
@media(max-width:600px){
  .container{padding:18px 14px;}
  .settings-body{padding:16px 14px;}
  .profile-page{padding:32px 16px 28px;}
  .card{padding:16px;}
}

/* ── ≤560px: modals go full-width. !important overrides the inline
   min-width some modals carry (e.g. signals: 460px/340px/320px). ───────── */
@media(max-width:560px){
  .modal{min-width:0!important;max-width:94vw!important;width:94vw;padding:18px;}
  .modal-footer{flex-wrap:wrap;}
}

/* ── Wide tables scroll inside their own box instead of blowing out the
   page width. Scanner & Signals already wrap their tables; this covers the
   rest (users, logs, dashboard, bot, backtest, blacklist/watchlist, etc.). ─ */
@media(max-width:768px){
  table.data, table.db-tbl, table.log-table{
    display:block;max-width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;}
}

/* ── Scanner table on tablet/phone: keep the frozen Pair column snug ───────
   table.scanner is width:100% with auto layout, so whenever its content is
   narrower than the container the browser dumps ALL the surplus width into the
   flexible, text-based Pair column — which is also position:sticky (frozen),
   so it ends up covering most of a narrow screen and pushes the %-change
   columns into the scroll region where they're unreachable. width:1% shrinks
   Pair to its content, so the surplus spreads across the numeric columns
   instead; the table still scrolls horizontally as a unit when truly too wide. */
@media(max-width:1024px){
  table.scanner th:first-child,
  table.scanner td:first-child{width:1%;}
}
@media(max-width:560px){
  /* Reclaim room on phones: override the Pair th's inline min-width:140px. */
  table.scanner th:first-child{min-width:104px!important;}
  table.scanner .pair-sym{font-size:0.8rem;}
}
@media(max-width:768px){
  /* Stack the profile-match badges under the symbol so they don't widen the
     frozen Pair column and cover the %-change columns. Ultra-compact: badges
     wrap (white-space:normal) so the width:1% rule can crush the column to its
     longest word (~74px), keeping every %-change column visible without
     horizontal scrolling. */
  table.scanner .pair-cell{flex-direction:column;align-items:flex-start;gap:3px;}
  table.scanner .pair-cell .profile-badge,
  table.scanner .pair-cell .meta-badge{white-space:normal;max-width:150px;}
  table.scanner td{vertical-align:top;}
}

/* ── ≤480px: phones — comfortable FAB, single-column stat rows ─────────── */
@media(max-width:480px){
  .stats-row{grid-template-columns:1fr 1fr;}
  .fab{bottom:16px;right:16px;}
}

/* ── Profile scoreboard badges & rank ──────────────────────────────────────
   Shared by Profiles, Signals and Scanner so one profile cannot look like a
   PASS on one page and a FAIL on another. Colours follow the existing
   green/red/muted vocabulary rather than introducing new ones. */
.sb-badge{
  display:inline-block;flex-shrink:0;font-size:9px;font-weight:700;letter-spacing:.05em;
  padding:1px 5px;border-radius:4px;line-height:1.5;text-align:center;min-width:34px;
}
.sb-badge.sb-pass{background:var(--green-soft);color:var(--green);}
.sb-badge.sb-fail{background:var(--red-soft);color:var(--red);}
.sb-badge.sb-thin{background:var(--panel-2);color:var(--muted);}
.sb-badge.sb-no-data{background:transparent;color:var(--muted-2);}
.sb-rank{
  margin-left:5px;font-family:var(--mono);font-size:10px;font-weight:700;
  color:var(--muted-2);vertical-align:baseline;
}
/* Only #1 is highlighted — ranking every position in colour turns a glanceable
   list into a heat map nobody reads. */
.sb-rank.sb-rank-top{color:var(--accent-text);}

/* ── Searchable country combobox (partials/phone-field) ───────────────
   Lives here, not in a @push('styles') block: neither layout has a
   'styles' stack, so a pushed <style> is silently discarded — and this
   is a reusable control, which is what theme.css is for. */
.cc-trigger{width:100%;height:100%;display:flex;align-items:center;justify-content:space-between;
      gap:6px;background:var(--panel-2);border:1px solid var(--border);color:var(--text);
      border-radius:8px;padding:10px 10px;font:inherit;font-size:0.929rem;cursor:pointer;
      transition:border-color .14s,box-shadow .14s,background .14s;}
    .cc-trigger:hover{border-color:var(--muted-2);}
    .cc-trigger[aria-expanded="true"],.cc-trigger:focus-visible{outline:none;border-color:var(--accent);
      box-shadow:0 0 0 3px var(--accent-soft);background:var(--panel);}
    .cc-value{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
    .cc-ph{color:var(--muted-2);}

    .cc-panel{position:absolute;z-index:40;top:calc(100% + 5px);left:0;width:290px;max-width:78vw;
      background:var(--panel);border:1px solid var(--border);border-radius:10px;
      box-shadow:0 12px 32px rgba(0,0,0,.32);overflow:hidden;}
    .cc-search{width:100%;border:none;border-bottom:1px solid var(--border);background:var(--panel-2);
      color:var(--text);padding:10px 12px;font:inherit;font-size:0.929rem;}
    .cc-search:focus{outline:none;}
    .cc-list{list-style:none;margin:0;padding:4px;max-height:246px;overflow-y:auto;}
    .cc-opt{display:flex;align-items:center;gap:9px;padding:7px 9px;border-radius:7px;cursor:pointer;
      font-size:0.929rem;line-height:1.3;}
    .cc-opt:hover,.cc-opt.cc-active{background:var(--accent-soft);}
    .cc-opt[aria-selected="true"]{color:var(--accent-text);font-weight:600;}
    .cc-flag{flex:none;}
    .cc-name{flex:1 1 auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
    .cc-dial{flex:none;font-family:var(--mono);font-size:0.786rem;color:var(--muted-2);}
    .cc-none{padding:14px 12px;color:var(--muted-2);font-size:0.857rem;text-align:center;}

/* ── Ambient marketing background ─────────────────────────────────────
   Two blurred brand glows plus a masked grid, fixed behind the page.
   Moved here from the marketing layout so login and register can share
   it: the same background either side of the click is what makes signing
   in feel like the same product as the page that sold it.
   Class names kept as .mkt-* so the marketing markup did not have to
   change. */
/* Animated ambient background — soft violet/pink glows drifting */
    .mkt-bg{position:fixed;inset:0;z-index:-2;overflow:hidden;pointer-events:none;}
    .mkt-bg::before,.mkt-bg::after{content:"";position:absolute;border-radius:50%;
      filter:blur(90px);opacity:.5;}
    .mkt-bg::before{width:620px;height:620px;top:-220px;left:-160px;
      background:radial-gradient(circle,#8b5cf6,transparent 70%);animation:mktFloat1 22s ease-in-out infinite;}
    .mkt-bg::after{width:560px;height:560px;top:280px;right:-180px;
      background:radial-gradient(circle,#ec4899,transparent 70%);animation:mktFloat2 26s ease-in-out infinite;}
    body[data-theme="light"] .mkt-bg::before,
    body[data-theme="light"] .mkt-bg::after{opacity:.22;}
    /* faint grid overlay */
    .mkt-grid{position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:.4;
      background-image:linear-gradient(var(--border) 1px,transparent 1px),
        linear-gradient(90deg,var(--border) 1px,transparent 1px);
      background-size:64px 64px;
      -webkit-mask-image:radial-gradient(ellipse 80% 60% at 50% 0%,#000 0%,transparent 75%);
      mask-image:radial-gradient(ellipse 80% 60% at 50% 0%,#000 0%,transparent 75%);}
    @keyframes mktFloat1{50%{transform:translate(80px,60px) scale(1.1);}}
    @keyframes mktFloat2{50%{transform:translate(-70px,-50px) scale(1.08);}}

/* Drifting glows are decoration, and decoration that moves is exactly what
   prefers-reduced-motion is for. The glows stay; only the drift stops. */
@media (prefers-reduced-motion: reduce){
  .mkt-bg::before,.mkt-bg::after{animation:none;}
}

/* Guest shell (login, register, two-factor). The card now sits over the drifting
   marketing background rather than a flat colour, so it needs a shadow to read
   as placed on top of it instead of cut out of it. The panel itself stays fully
   opaque: a translucent card over moving glows makes form text swim. */
.guest-shell .card{box-shadow:0 18px 48px rgba(0,0,0,.34);}
body[data-theme="light"] .guest-shell .card{box-shadow:0 14px 38px rgba(24,20,40,.11);}

/* ── Auth cards ──────────────────────────────────────────────────────────
   The narrow column IS the mobile layout, so it is the base here and the
   wide one is the override. Written that way round deliberately: a phone
   then needs no media query at all, and a rule that fails to apply leaves
   the small screen correct rather than the small screen broken.

   `--auth-card` is a variable rather than a literal so the two-column form
   below can widen without every page that uses .auth-card having to know. */
.auth-card{width:100%;max-width:340px;padding:30px;}

/* Registration asks for six things; at 340px the two name fields could not
   sit side by side (2 x 140px + gap exceeded the 280px of content the card
   left them) and the phone number got 124px next to its country picker. */
@media (min-width:620px){
  .auth-card--wide{max-width:520px;padding:34px 36px;}
}

/* ══ Page guides — the "How to Use" button and its slide-over ═════════════
   A right-hand drawer rather than a modal, because the whole point is to read
   the instructions while still looking at the controls they describe. On
   desktop the backdrop is a transparent click-catcher only; the page stays
   fully legible beside the panel. Below 768px there is no room for that, so
   it dims and behaves like a sheet. */
.pg-open-btn{display:inline-flex;align-items:center;gap:6px;height:34px;padding:0 11px;
  border-radius:9px;background:var(--accent-soft);border:1px solid var(--accent);
  color:var(--accent-text);font:inherit;font-size:0.786rem;font-weight:700;cursor:pointer;
  flex-shrink:0;transition:filter .12s,background .12s;}
.pg-open-btn:hover{filter:brightness(1.12);}
.pg-open-btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--accent-soft);}
.pg-open-btn svg{flex:none;}

.pg-backdrop{position:fixed;inset:0;z-index:290;background:rgba(0,0,0,0);
  transition:background .2s;}
.pg-backdrop[hidden]{display:none;}

.pg-drawer{position:fixed;top:0;right:0;bottom:0;z-index:300;width:min(420px,100vw);
  display:flex;flex-direction:column;background:var(--panel);
  border-left:1px solid var(--border);box-shadow:-14px 0 40px rgba(0,0,0,.38);
  transform:translateX(100%);transition:transform .22s ease;}
.pg-drawer.open{transform:translateX(0);}
.pg-drawer[hidden]{display:none;}

.pg-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;
  padding:18px 20px 14px;border-bottom:1px solid var(--border);flex:none;}
.pg-eyebrow{font-size:0.643rem;text-transform:uppercase;letter-spacing:.09em;
  color:var(--accent-text);font-weight:700;margin-bottom:3px;}
.pg-title{font-size:1.071rem;font-weight:700;margin:0;}
.pg-close{background:none;border:none;color:var(--muted);font-size:1.5rem;line-height:1;
  cursor:pointer;padding:0 2px;flex:none;}
.pg-close:hover{color:var(--text);}
.pg-close:focus-visible{outline:none;box-shadow:0 0 0 3px var(--accent-soft);border-radius:6px;}

.pg-body{flex:1;overflow-y:auto;padding:18px 20px 22px;font-size:0.893rem;line-height:1.6;
  color:var(--text);}
.pg-body > p:first-child{margin-top:0;}
.pg-body p{margin:0 0 12px;color:var(--muted);}
.pg-body strong{color:var(--text);font-weight:700;}
.pg-body code{font-family:var(--mono);font-size:.85em;background:var(--panel-2);
  border:1px solid var(--border);border-radius:5px;padding:1px 5px;color:var(--text);}
.pg-body a{color:var(--accent-text);text-decoration:underline;}

/* One numbered step. The counter lives on .pg-body so steps can be reordered
   or removed in a partial without renumbering anything by hand. */
.pg-body{counter-reset:pg-step;}
.pg-step{position:relative;padding:0 0 14px 30px;margin-bottom:14px;
  border-bottom:1px solid var(--border);}
.pg-step:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0;}
.pg-step::before{counter-increment:pg-step;content:counter(pg-step);
  position:absolute;left:0;top:1px;width:20px;height:20px;border-radius:6px;
  background:var(--accent-soft);color:var(--accent-text);
  font-size:0.643rem;font-weight:700;display:flex;align-items:center;justify-content:center;}
.pg-step h3{font-size:0.929rem;font-weight:700;margin:0 0 5px;}
.pg-step p:last-child{margin-bottom:0;}

/* Unnumbered block, for "what the columns mean" style reference lists. */
.pg-note{background:var(--panel-2);border:1px solid var(--border);border-left:2px solid var(--accent);
  border-radius:8px;padding:10px 12px;margin:10px 0 0;font-size:0.821rem;color:var(--muted);}
.pg-note strong{color:var(--text);}
.pg-warn{border-left-color:var(--amber);background:var(--amber-soft);color:var(--text);}
.pg-defs{margin:0;padding:0;list-style:none;font-size:0.857rem;}
.pg-defs li{padding:7px 0;border-bottom:1px solid var(--border);color:var(--muted);}
.pg-defs li:last-child{border-bottom:none;}
.pg-defs b{color:var(--text);font-weight:700;}

.pg-foot{flex:none;display:flex;align-items:center;justify-content:space-between;gap:10px;
  padding:12px 20px;border-top:1px solid var(--border);background:var(--panel-2);}
.pg-foot a{font-size:0.786rem;color:var(--accent-text);text-decoration:none;font-weight:600;}
.pg-foot a:hover{text-decoration:underline;}
.pg-done{font-size:0.821rem;padding:7px 14px;}

/* ≤900px: the nav row is tight — keep the icon, drop the words. */
@media(max-width:900px){
  .pg-open-btn{padding:0;width:34px;justify-content:center;}
  .pg-open-label{display:none;}
}
/* ≤768px: full-width sheet, and the backdrop actually dims. */
@media(max-width:768px){
  .pg-drawer{width:100vw;}
  .pg-backdrop.open{background:rgba(0,0,0,.55);}
}
@media (prefers-reduced-motion:reduce){
  .pg-drawer{transition:none;}
  .pg-backdrop{transition:none;}
}

/* ══ Product tour — the play button beside "How to Use", and its modal ════
   The button is deliberately quieter than the guide button next to it: one
   explains the screen you are on and is the useful one day to day, the other
   is a tour you watch once. Same height so the pair reads as a unit. */
.pv-open-btn{display:inline-flex;align-items:center;justify-content:center;
  width:34px;height:34px;border-radius:9px;background:var(--panel-2);
  border:1px solid var(--border);color:var(--muted);cursor:pointer;flex-shrink:0;
  transition:color .12s,border-color .12s,background .12s;}
.pv-open-btn:hover{color:var(--accent-text);border-color:var(--accent);
  background:var(--accent-soft);}
.pv-open-btn:focus-visible{outline:none;box-shadow:0 0 0 3px var(--accent-soft);
  border-color:var(--accent);}

/* The dialog is sized to the video, not to text — 16:9 at a comfortable
   reading distance, capped so it never exceeds the viewport on either axis. */
.pv-modal{width:min(880px,94vw);max-width:none;padding:18px;}
.pv-video{display:block;width:100%;aspect-ratio:16/9;border-radius:10px;
  background:#000;border:1px solid var(--border);}
.pv-foot{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex-wrap:wrap;margin-top:12px;font-size:0.786rem;color:var(--muted-2);}
.pv-foot a{color:var(--accent-text);text-decoration:none;font-weight:600;}
.pv-foot a:hover{text-decoration:underline;}

@media(max-width:560px){
  .pv-modal{padding:14px;}
  .pv-foot{justify-content:center;text-align:center;}
}

/* ── Pricing cards ───────────────────────────────────────────────────
   Moved here from the home page's inline styles when Plan & Usage began
   showing the same cards. One definition, two pages: the settings copy had
   already been written at smaller sizes with a different background, which is
   exactly the drift that makes "the same card" stop being the same card.

   `.featured` means different things in the two places and that is deliberate —
   on the marketing page it flags the plan being sold, on Plan & Usage it flags
   the plan you are on. The treatment is identical either way. */
.price-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(260px,1fr));gap:20px;
  max-width:820px;margin:0 auto;}
.price-card{position:relative;border:1px solid var(--border);border-radius:16px;padding:26px 24px;
  background:var(--panel);display:flex;flex-direction:column;}
.price-card.featured{border-color:color-mix(in srgb,var(--accent) 50%,transparent);
  background:radial-gradient(120% 130% at 50% 0%,var(--accent-soft),transparent 62%),var(--panel);}
.price-flag{position:absolute;top:-11px;left:50%;transform:translateX(-50%);
  background:linear-gradient(135deg,#8b5cf6,#ec4899);color:#fff;font-size:10.5px;font-weight:700;
  letter-spacing:.05em;text-transform:uppercase;padding:4px 12px;border-radius:20px;white-space:nowrap;}
.price-card h4{font-size:17px;font-weight:800;margin:0 0 4px;}
.price-tag{color:var(--muted);font-size:13px;line-height:1.5;margin:0 0 16px;min-height:38px;}
.price-amount{font-size:38px;font-weight:800;letter-spacing:-.03em;line-height:1;
  background:linear-gradient(135deg,#8b5cf6,#ec4899);-webkit-background-clip:text;background-clip:text;color:transparent;}
.price-amount .cur{font-size:22px;}
.price-amount .per{font-size:13px;font-weight:500;color:var(--muted);
  -webkit-text-fill-color:var(--muted);letter-spacing:0;}
.price-annual{color:var(--muted-2);font-size:12px;margin-top:6px;}
.price-list{list-style:none;padding:0;margin:20px 0 22px;display:grid;gap:9px;flex:1;}
.price-list li{display:flex;gap:9px;align-items:flex-start;font-size:13.5px;line-height:1.5;color:var(--muted);}
.price-list .tick{color:var(--green);font-weight:700;flex:none;}
.price-note{text-align:center;color:var(--muted);font-size:13px;line-height:1.7;
  max-width:640px;margin:26px auto 0;}
/* The "you are here" CTA. Sized to match .mkt-btn so the current card is the
   same height as the ones beside it — a shorter card reads as a lesser plan. */
.price-current{display:inline-flex;align-items:center;justify-content:center;gap:8px;width:100%;
  padding:11px 20px;border-radius:10px;font-size:14px;font-weight:700;
  color:var(--accent-text);border:1px solid color-mix(in srgb,var(--accent) 40%,transparent);
  background:color-mix(in srgb,var(--accent) 8%,transparent);}

/* ══════════════════════════════════════════════════════════════════════════
   MOBILE SUBTRACTION (September 3, 2026)

   Every other mobile rule in this file REFLOWS — it makes something fit. These
   rules REMOVE, and that distinction is the whole point. Nothing had ever been
   dropped from a phone, only squeezed, so the Dashboard arrived as eighteen
   numeric tiles before the first open position and the Scanner crushed its Pair
   column to 74px to keep eleven columns on a 390px screen. Fitting is not the
   same as being usable.

   The principle: a phone answers "is anything happening, and do I need to act?"
   Anything whose job is to COMPARE, EXPLAIN or DIAGNOSE is desktop work.

   `.desk-only` is applied in the MARKUP rather than by listing selectors here,
   so what a phone drops is legible in the view you are already reading instead
   of in a stylesheet nobody opens.
   ══════════════════════════════════════════════════════════════════════════ */

/* !important is load-bearing here, not laziness. Several blocks marked
   .desk-only have their display driven by JS — the statistics sections, the
   scanner's timeframe filter, dashboard cards toggled on refresh — and an
   author !important is the one thing that outranks a non-important inline
   style. Without it every one of them reappears the moment its script runs. */
@media(max-width:768px){
  .desk-only{display:none !important;}
}

/* ── Scanner: four columns, not eleven ──────────────────────────────────────
   Pair, Price, 1d%, Signal. 1d is the reading the daily gainer profiles and
   Alpha Stack actually trade on; the other five timeframes, 24h volume and the
   trend sparkline are all comparison, which is desktop work.

   Both the th and the td carry data-tf now. They did not before — the filter
   matched columns by nth-child INDEX, which silently breaks if anyone reorders
   a column, and which no stylesheet can hook into. */
@media(max-width:768px){
  table.scanner [data-tf]:not([data-tf="1d"]),
  table.scanner .col-vol,
  table.scanner .col-trend,
  .scanner-toolbar .tf-filter-wrap{display:none !important;}

  /* Undo the crush. These two rules exist ONLY to survive eleven columns:
     width:1% starves the frozen Pair column and the stacking wraps its badges
     under the symbol. With four columns there is room, and keeping them is what
     made the table look cramped rather than merely narrow. */
  table.scanner th:first-child{min-width:0 !important;width:auto !important;}
  table.scanner td:first-child{width:auto !important;}
  table.scanner .pair-cell{flex-direction:row;align-items:center;gap:6px;flex-wrap:wrap;}
  table.scanner .pair-sym{font-size:0.929rem;}
}

/* ── Signals: cards, not a table ────────────────────────────────────────────
   ONE renderer, reshaped by CSS. A second mobile template would be two things
   to keep in sync, and this codebase already knows what that costs — every
   divergence bug in it started as two code paths that were "obviously" the
   same. So the tds carry data-label and the table becomes blocks.

   Pair and P&L are the two things worth reading at arm's length, so they go on
   the top row at full size; profile, status and elapsed time drop underneath as
   one muted line. Everything else the table shows is detail the row's own modal
   already carries, so it is hidden rather than relabelled. */
@media(max-width:768px){
  table.signals-tbl thead{display:none;}
  table.signals-tbl,
  table.signals-tbl tbody,
  table.signals-tbl tr,
  table.signals-tbl td{display:block;width:auto;}

  table.signals-tbl tr{
    position:relative;border:1px solid var(--border);border-radius:12px;
    background:var(--panel);padding:12px 14px;margin-bottom:10px;}

  /* Hidden outright: index, type, timeframe, entry, exit. All of it is in the
     detail modal a tap away, and none of it changes what you would do next. */
  table.signals-tbl td[data-label="#"],
  table.signals-tbl td[data-label="Type"],
  table.signals-tbl td[data-label="TF"],
  table.signals-tbl td[data-label="Entry Price"],
  table.signals-tbl td[data-label="Exit Price"]{display:none;}

  table.signals-tbl td{border:none;padding:0;text-align:left !important;}

  table.signals-tbl td[data-label="Pair"]{
    font-size:1.071rem;font-weight:700;padding-right:90px;}

  /* P&L is the number you opened the app for: pinned top-right, large. */
  table.signals-tbl td[data-label="P&L"]{
    position:absolute;top:12px;right:14px;font-size:1.071rem;font-weight:700;}

  /* Profile · status · when — one muted line under the pair. */
  table.signals-tbl td[data-label="Profile"],
  table.signals-tbl td[data-label="Status"],
  table.signals-tbl td[data-label="Triggered"]{
    display:inline;font-size:0.821rem;color:var(--muted);}
  table.signals-tbl td[data-label="Profile"]::after,
  table.signals-tbl td[data-label="Status"]::after{content:" · ";color:var(--muted-2);}

  table.signals-tbl td[data-label="Actions"]{margin-top:10px;}
}

/* Statistics carries .desk-only on six of its eight NAV ITEMS rather than on
   the sections themselves. showSection() sets an inline style.display, and the
   !important above would win that fight — but a nav item leading to a blank
   screen is worse than no nav item at all. Hiding the entry point also means
   initSection() never runs for those six, and chart init is lazy, so the cut
   genuinely avoids the work rather than hiding its result. No extra rule is
   needed here; the utility above already covers them. */

/* ── Scanner timeframe groups (desktop) ────────────────────────────────────
   The "Show TF" filter, expressed as one class on the table rather than inline
   styles on every cell. Inline styles did not survive renderTable() replacing
   the tbody, so the filter silently reset itself on the next refresh — a bug
   that had been there as long as the control. */
table.scanner.tfg-short [data-tf="4h"],
table.scanner.tfg-short [data-tf="1d"],
table.scanner.tfg-short [data-tf="7d"],
table.scanner.tfg-long [data-tf="1m"],
table.scanner.tfg-long [data-tf="15m"],
table.scanner.tfg-long [data-tf="1h"]{display:none;}

/* ── Settings "add a pair" rows (blacklist, watchlist, monitoring tags) ─────
   Symbol box + note box + button on one line. They were an inline
   `display:flex` with NO wrap, so on a phone the three share ~358px and the
   symbol input — the one carrying an autocomplete — is squeezed to about
   120px. Its dropdown then had less room than one result row needs, and
   `overflow:hidden` clipped the symbol rather than scrolling it.

   Stacking them below 620px is the fix at the cause; the dropdown sizing to
   its content is the belt to that braces. */
.pair-add-row{display:flex;gap:8px;align-items:flex-start;}
@media(max-width:620px){
  .pair-add-row{flex-wrap:wrap;}
  .pair-add-row > *{flex:1 1 100%;min-width:0;}
}
