/* Fx2Owl.UI — Design Tokens */
:root {
  --bg:            #1a1d23;
  --surface:       #22262f;
  --surface-2:     #2b3040;
  --orange:        #f07b20;
  --orange-dim:    #c4611a;
  --text:          #e8eaf0;
  --text-muted:    #7a8099;
  --radius:        12px;
  --area-gap:      0.75rem;
  --footer-height: 3.5rem;
  --color-success: #4ade80;
  --color-error:   #f87171;
  --color-warning: #facc15;

  /* Secondary "selected/on" accent for toggle-style controls (view filters, day pickers, inline
     settings toggles) where the primary orange is reserved for the tile's one primary action.
     Matches the activity-bar blue (Fx2ActivityBars' --ab-active) so the two vocabularies agree;
     -dim is the resting "on" fill, the full brightness is used for borders/hover. */
  --accent-blue:     #3b82f6;
  --accent-blue-dim: #2955a3;
}

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background: radial-gradient(ellipse at 100% 0%, #2e2010 0%, var(--bg) 55%);
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  color: var(--text);
  font-family: system-ui, sans-serif;
  font-size: 14px;
}

/* Blazor's <FocusOnNavigate Selector="h1" /> (Fx2Owl/Components/Routes.razor) programmatically
   focuses the page's first <h1> after every navigation, for screen-reader accessibility. Without
   this reset the browser draws its default focus outline around that h1 for a moment on load -
   visible as a boxed/highlighted flash around the heading text (e.g. Home.razor's hero-hello). */
h1:focus { outline: none; }

/* Utility */
.label        { font-size: 11px; text-transform: uppercase; letter-spacing: .08em; color: var(--text-muted); margin-bottom: .35rem; }
.value-lg     { font-size: 2rem; font-weight: 700; color: var(--orange); line-height: 1; }
.value-md     { font-size: 1.3rem; font-weight: 600; color: var(--text); }
.tag          { display: inline-block; padding: 2px 8px; border-radius: 99px; font-size: 11px; background: rgba(240,123,32,.15); color: var(--orange); }
.muted        { color: var(--text-muted); }
.row          { display: flex; align-items: center; gap: .5rem; }
.col          { display: flex; flex-direction: column; }
.spacer       { flex: 1; }
.divider      { width: 100%; height: 1px; background: rgba(255,255,255,.06); margin: .75rem 0; }
.btn-section-label { font-size: 11px; color: var(--text-muted); margin-top: 1rem; margin-bottom: .1rem; text-transform: uppercase; letter-spacing: .07em; }
.footer-item        { display: flex; align-items: center; gap: .4rem; }
.footer-dot         { width: 6px; height: 6px; border-radius: 50%; background: var(--orange); flex-shrink: 0; }
.footer-link        { color: var(--text-muted); text-decoration: none; transition: color .15s ease; }
.footer-link:hover  { color: var(--orange); }

.data-table         { width: 100%; border-collapse: collapse; }
.data-table th      { padding: .5rem .5rem; text-align: left; white-space: nowrap; }
.data-table td      { padding: .5rem .5rem; font-size: 13px; white-space: nowrap; }
.data-table tr:not(:last-child) td { border-bottom: 1px solid rgba(255,255,255,.06); }
.data-table th:first-child, .data-table td:first-child  { padding-left: 0; }
.data-table th:last-child, .data-table td:last-child    { padding-right: 0; }

/* Global (non-scoped) wrapper for any table whose content can exceed its card's width - every
   .data-table cell is nowrap, so a narrow card must scroll the overflow horizontally instead of
   letting the browser squeeze columns down to unreadable widths. Global rather than per-component
   scoped CSS because scoped rules only apply within their own component's render tree - a
   .table-scroll div rendered from a different .razor file wouldn't pick up a scoped rule at all.
   Usage: wrap every <table class="data-table ..."> in a plain <div class="table-scroll">. */
.table-scroll {
    overflow-x: auto;
    /* Thin, theme-matched scrollbar instead of the OS default chunky bar. */
    scrollbar-width: thin;                         /* Firefox */
    scrollbar-color: var(--surface-2) transparent; /* Firefox: thumb / track */
}

.table-scroll::-webkit-scrollbar {
    height: 8px;
    width: 8px;
}

.table-scroll::-webkit-scrollbar-track {
    background: transparent;
}

.table-scroll::-webkit-scrollbar-thumb {
    background: var(--surface-2);
    border-radius: 99px;
}

.table-scroll:hover::-webkit-scrollbar-thumb {
    background: #3a4152;
}

.table-scroll::-webkit-scrollbar-thumb:hover {
    background: var(--orange-dim);
}

/* Global (non-scoped) utility for a table cell whose content (a free-text Notes column, most
   commonly) can run much longer than its column should ever get - caps the column width and cuts
   the overflow with an ellipsis instead of letting it dominate the row. Global for the same reason
   as .table-scroll above: multiple indicators' Runs tables (IntradayActivityIndicator,
   WindowDirectionPatternIndicator, CandleSequencePatternIndicator) need the identical rule, and a
   scoped .razor.css rule can't cross a component boundary. Pair with a title="..." attribute on the
   same cell so the full text is still reachable on hover. */
.cell-truncate {
    max-width: 8.5rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Global (non-scoped) equivalent of Fx2AppButton.razor.css, for plain <button>/<a> markup on
   static SSR Account pages where a real form-post/native anchor is needed instead of an
   EventCallback-driven Fx2AppButton (which has no live circuit to bind to there). Keep
   visually in sync with that file if the design changes. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  padding: .5rem 1.1rem;
  border-radius: 6px;
  font-size: 13px;
  font-weight: 500;
  cursor: pointer;
  border: 1px solid rgba(255,255,255,.12);
  background: var(--surface-2);
  color: var(--text);
  transition: background .15s, border-color .15s, color .15s, opacity .15s;
  white-space: nowrap;
  line-height: 1;
  text-decoration: none;
}
.btn:hover:not(:disabled) { background: #333849; border-color: rgba(255,255,255,.2); }
.btn--primary { background: var(--orange); border-color: var(--orange); color: #fff; }
.btn--primary:hover:not(:disabled) { background: var(--orange-dim); border-color: var(--orange-dim); }
.btn--ghost { background: transparent; border-color: transparent; color: var(--text); }
.btn--ghost:hover:not(:disabled) { background: rgba(255,255,255,.06); }
.btn--outline { background: transparent; border-color: rgba(255,255,255,.2); color: var(--text); }
.btn--outline:hover:not(:disabled) { background: rgba(255,255,255,.05); border-color: rgba(255,255,255,.35); }
.btn--sm { padding: .3rem .75rem; font-size: 11px; border-radius: 4px; }
.btn:disabled { opacity: .35; cursor: not-allowed; }
.btn--block { display: flex; width: 100%; }

/* Cookie/analytics consent banner - global, non-scoped, because it's rendered as plain static
   markup directly in Fx2Owl/Components/App.razor rather than inside any component's render tree
   (see analytics-consent-helpers.js / docs/decisions/0023-google-analytics-consent.md). Hidden by
   default via the [hidden] attribute; JS un-hides it only when GA is configured and no consent
   choice has been made yet. */
.consent-banner {
  position: fixed;
  left: 1rem;
  right: 1rem;
  bottom: 1rem;
  z-index: 1000;
  max-width: 640px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  gap: 1rem;
  padding: 1rem 1.25rem;
  border-radius: var(--radius);
  border: 1px solid rgba(255,255,255,.12);
  background: var(--surface);
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
}
/* Author rules always beat the UA stylesheet's [hidden] { display: none }, regardless of source
   order, so the unconditional display:flex above otherwise keeps the banner visible even after JS
   sets the hidden attribute. This selector's higher specificity (class + attribute) restores the
   expected hide behavior. */
.consent-banner[hidden] { display: none; }
.consent-banner p          { color: var(--text-muted); font-size: 13px; line-height: 1.5; }
.consent-banner p a        { color: var(--orange); text-decoration: none; }
.consent-banner p a:hover  { text-decoration: underline; }
.consent-banner__actions   { display: flex; gap: .5rem; flex-shrink: 0; }
@media (max-width: 560px) {
  .consent-banner { flex-direction: column; align-items: stretch; }
  .consent-banner__actions { justify-content: flex-end; }
}

/* Blazor Server circuit disconnect overlay. Same "plain static markup in App.razor" situation as
   .consent-banner above - it must be global, non-scoped CSS. Blazor's own built-in fallback UI
   renders inside a closed shadow root that page CSS can never reach, so instead each host's
   App.razor supplies a real #components-reconnect-modal element (the exact id blazor.web.js looks
   for before falling back to that unstylable shadow-DOM widget), and this theme takes over instead.
   blazor.web.js toggles components-reconnect-{show,hide,retrying,failed,paused,resume-failed,
   rejected} directly on #components-reconnect-modal, and fills in the components-reconnect-current-
   attempt / components-reconnect-max-retries spans itself - nothing here needs JS of its own. */
#components-reconnect-modal {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 10001;
  align-items: center;
  justify-content: center;
  background: rgba(10, 12, 16, .65);
  backdrop-filter: blur(2px);
}

#components-reconnect-modal.components-reconnect-show,
#components-reconnect-modal.components-reconnect-retrying,
#components-reconnect-modal.components-reconnect-failed,
#components-reconnect-modal.components-reconnect-rejected,
#components-reconnect-modal.components-reconnect-paused,
#components-reconnect-modal.components-reconnect-resume-failed {
  display: flex;
}

#components-reconnect-modal.components-reconnect-hide { display: none; }

#components-reconnect-modal .reconnect-dialog {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  width: 320px;
  max-width: calc(100vw - 2rem);
  padding: 2rem 1.75rem;
  border-radius: var(--radius);
  border: 1px solid rgba(255,255,255,.08);
  background: var(--surface);
  box-shadow: 0 8px 24px rgba(0,0,0,.35);
  text-align: center;
}

#components-reconnect-modal .reconnect-spinner {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 3px solid rgba(240,123,32,.2);
  border-top-color: var(--orange);
  animation: fx2-reconnect-spin .9s linear infinite;
}

#components-reconnect-modal.components-reconnect-failed .reconnect-spinner,
#components-reconnect-modal.components-reconnect-rejected .reconnect-spinner,
#components-reconnect-modal.components-reconnect-paused .reconnect-spinner,
#components-reconnect-modal.components-reconnect-resume-failed .reconnect-spinner {
  display: none;
}

@keyframes fx2-reconnect-spin { to { transform: rotate(360deg); } }

#components-reconnect-modal .reconnect-status {
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
}
#components-reconnect-modal .reconnect-status::before                                { content: "Rejoining the server…"; }
#components-reconnect-modal.components-reconnect-failed .reconnect-status::before        { content: "We couldn't reconnect."; }
#components-reconnect-modal.components-reconnect-rejected .reconnect-status::before       { content: "Your session has expired."; }
#components-reconnect-modal.components-reconnect-paused .reconnect-status::before         { content: "This session was paused by the server."; }
#components-reconnect-modal.components-reconnect-resume-failed .reconnect-status::before  { content: "We couldn't resume your session."; }

#components-reconnect-modal .reconnect-attempt {
  display: none;
  color: var(--text-muted);
  font-size: 12px;
}
#components-reconnect-modal.components-reconnect-retrying .reconnect-attempt { display: block; }

#components-reconnect-modal .reconnect-reload { display: none; }
#components-reconnect-modal.components-reconnect-failed .reconnect-reload,
#components-reconnect-modal.components-reconnect-rejected .reconnect-reload,
#components-reconnect-modal.components-reconnect-paused .reconnect-reload,
#components-reconnect-modal.components-reconnect-resume-failed .reconnect-reload {
  display: inline-flex;
}

.input {
  width: 100%;
  padding: .55rem .75rem;
  border-radius: 6px;
  font-size: 13px;
  border: 1px solid rgba(255,255,255,.12);
  background: var(--bg);
  color: var(--text);
  transition: border-color .15s;
}
.input:focus { outline: none; border-color: var(--orange); }
.input::placeholder { color: var(--text-muted); }
textarea.input { resize: vertical; min-height: 90px; font-family: inherit; line-height: 1.5; }

.form-group { display: flex; flex-direction: column; gap: .35rem; margin-bottom: 1rem; }
.field-message { font-size: 12px; color: var(--color-error); }

.alert {
  display: flex;
  align-items: center;
  gap: .5rem;
  padding: .65rem .9rem;
  border-radius: 6px;
  font-size: 13px;
  margin-bottom: 1rem;
  border: 1px solid transparent;
}
.alert--success { background: rgba(74,222,128,.12); border-color: rgba(74,222,128,.3); color: var(--color-success); }
.alert--error   { background: rgba(248,113,113,.12); border-color: rgba(248,113,113,.3); color: var(--color-error); }
.alert--warning { background: rgba(250,204,21,.12); border-color: rgba(250,204,21,.3); color: var(--color-warning); }
.alert--info    { background: rgba(240,123,32,.12); border-color: rgba(240,123,32,.3); color: var(--orange); }
