/* Fish Signals client styles.
 *
 * Dark is the default palette (the app was designed dark, and the manifest /
 * theme-color meta follow it). Light is an opt-in override on
 * :root[data-theme="light"] — the toggle lives in the header and persists to
 * localStorage under `fish.theme`.
 */

:root { --bg:#0e1117; --card:#1a1f2b; --line:#2a3040; --txt:#e6e9f0;
        --dim:#8b93a7; --buy:#2ecc71; --sell:#e74c3c; --gold:#f1c40f;
        --blue:#3b82f6; --blue-fg:#7fb0ff; --input:#10141d;
        --radius:12px; --radius-pill:20px;
        --shadow:0 6px 20px rgba(0,0,0,.35);
        --glow-buy:0 0 0 3px rgba(46,204,113,.18);
        --glow-sell:0 0 0 3px rgba(231,76,60,.18); }

:root[data-theme="light"] { --bg:#f4f6fb; --card:#ffffff; --line:#dfe3ec;
        --txt:#141824; --dim:#5e6678; --buy:#1e9e5a; --sell:#d63c2e;
        --gold:#b8860b; --blue:#2563eb; --blue-fg:#2563eb; --input:#ffffff;
        --shadow:0 6px 20px rgba(20,24,36,.10);
        --glow-buy:0 0 0 3px rgba(30,158,90,.16);
        --glow-sell:0 0 0 3px rgba(214,60,46,.16); }

* { box-sizing:border-box; margin:0; -webkit-tap-highlight-color:transparent; }
body { background:var(--bg); color:var(--txt);
       font-family:system-ui,-apple-system,sans-serif;
       padding:12px 12px calc(12px + env(safe-area-inset-bottom));
       max-width:720px; margin:0 auto; }
/* The canvas is decoration behind everything; the body keeps a real
 * background so the page is still correct if the canvas never paints. */
#bg { position:fixed; inset:0; z-index:-1; pointer-events:none; }

/* Sticky header. The safe-area inset lives inside the sticky element — on
 * body it would scroll away and leave the header under the status bar. */
header { position:sticky; top:0; z-index:5;
         display:flex; justify-content:space-between; align-items:center;
         gap:8px; margin:-12px -12px 12px; padding:8px 12px;
         padding-top:calc(8px + env(safe-area-inset-top));
         background:color-mix(in srgb, var(--bg) 78%, transparent);
         backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
         border-bottom:1px solid var(--line); }
@supports not (backdrop-filter: blur(1px)) {
  header { background:var(--bg); }
}
h1 { font-size:1.1rem; }
.hdr-actions { display:flex; align-items:center; gap:8px; }
/* Semi-transparent + blurred so the parallax chart behind shows through
 * faintly. Engines without backdrop-filter get the flat card instead. */
.card { background:color-mix(in srgb, var(--card) 82%, transparent);
        backdrop-filter:blur(12px); -webkit-backdrop-filter:blur(12px);
        border:1px solid var(--line); box-shadow:var(--shadow);
        border-radius:var(--radius); padding:14px; margin-bottom:10px;
        animation:rise .25s ease-out both; }
@supports not (backdrop-filter: blur(1px)) {
  .card { background:var(--card); }
}
@keyframes rise { from { opacity:0; transform:translateY(8px); }
                  to   { opacity:1; transform:none; } }
/* Direction is readable before any text is: a colour rail down the card. */
.card.dir-BUY { border-left:3px solid var(--buy); }
.card.dir-SELL { border-left:3px solid var(--sell); }
/* Live setups pulse on the state badge only — a whole pulsing card is noise. */
@keyframes livePulse { 0%,100% { box-shadow:var(--glow-buy); }
                       50% { box-shadow:0 0 0 6px transparent; } }
.badge.st-live { animation:livePulse 2.2s ease-in-out infinite; }
.badge { display:inline-block; padding:2px 9px; border-radius:10px;
         font-size:.72rem; font-weight:700; }

/* Badge tints follow the theme via color-mix; the @supports block below
 * restates them as flat rgba for engines without it. */
.BUY { background:color-mix(in srgb, var(--buy) 15%, transparent); color:var(--buy); }
.SELL { background:color-mix(in srgb, var(--sell) 15%, transparent); color:var(--sell); }
.forming { background:color-mix(in srgb, var(--gold) 14%, transparent); color:var(--gold); }
.completed { background:color-mix(in srgb, var(--blue) 15%, transparent); color:var(--blue-fg); }
/* two-stage entry: a suggestion is not a trade until a candle confirms it */
.st-wait { background:color-mix(in srgb, var(--gold) 14%, transparent); color:var(--gold); }
.st-live { background:color-mix(in srgb, var(--buy) 15%, transparent); color:var(--buy); }
.st-done { background:color-mix(in srgb, var(--dim) 15%, transparent); color:var(--dim); }
.tier { background:color-mix(in srgb, var(--dim) 15%, transparent); color:var(--dim); }

@supports not (color: color-mix(in srgb, red, blue)) {
  .BUY, .st-live { background:rgba(46,204,113,.15); }
  .SELL { background:rgba(231,76,60,.15); }
  .forming, .st-wait { background:rgba(241,196,15,.14); }
  .completed { background:rgba(59,130,246,.15); }
  .st-done, .tier { background:rgba(139,147,167,.15); }
}

.card.settled { opacity:.55; }

/* ---------- one button system ----------
 * .btn carries size, weight and motion; a single modifier carries colour.
 * 44px min-height is the touch target — this is a phone-first client. */
.btn { display:inline-flex; align-items:center; justify-content:center;
       gap:6px; min-height:44px; padding:10px 16px; border-radius:10px;
       border:none; font:inherit; font-weight:600; cursor:pointer;
       background:transparent; color:var(--txt);
       transition:transform .12s, box-shadow .12s, background .2s; }
.btn:active { transform:scale(.97); }
.btn[disabled] { opacity:.55; cursor:default; transform:none; }
.btn-block { width:100%; margin-top:10px; }
.btn-primary { background:linear-gradient(135deg, var(--blue), #6d5dfc);
               color:#fff; box-shadow:var(--shadow); }
.btn-ghost { border:1px solid var(--line); color:var(--dim); }
.btn-ghost:hover { background:var(--card); color:var(--txt); }
/* Focus rings are never removed without a replacement. */
.btn:focus-visible, .chip:focus-visible, select:focus-visible,
input:focus-visible { outline:2px solid var(--blue); outline-offset:2px; }

/* The tier pill is a button too, just a compact one. */
.tier { min-height:0; padding:5px 11px; border-radius:var(--radius-pill);
        font-size:.72rem; font-weight:700; border:none; cursor:pointer;
        color:var(--dim); }
.tier.premium, .btn-premium { background:linear-gradient(135deg,#f1c40f,#e67e22);
                color:#1a1005; }
#themeBtn { min-height:0; background:transparent; border:1px solid var(--line);
            color:var(--txt); border-radius:var(--radius-pill);
            padding:5px 10px; font-size:.85rem; line-height:1;
            cursor:pointer; }
.err { color:var(--sell); font-size:.78rem; margin-top:8px; min-height:1em; }
.stats { display:flex; flex-wrap:wrap; gap:8px; }
.stats div { flex:1 1 72px; text-align:center; min-width:64px; padding:8px 6px;
             border:1px solid var(--line); border-radius:10px;
             background:color-mix(in srgb, var(--txt) 4%, transparent); }
@supports not (color: color-mix(in srgb, red, blue)) {
  .stats div { background:rgba(139,147,167,.08); }
}
.stats b { font-size:1.2rem; display:block; font-variant-numeric:tabular-nums; }
.stats span { font-size:.68rem; color:var(--dim); }
.stats .good b { color:var(--buy); }
.stats .bad b { color:var(--sell); }
/* Segmented control: one pill-shaped track, with a highlight that slides to
 * the selected mode instead of every chip repainting. Still a horizontal
 * scroller, because the mode list grows. */
.chips { position:relative; display:flex; gap:4px; overflow-x:auto;
         padding:4px; margin-bottom:10px; scrollbar-width:none;
         border:1px solid var(--line); border-radius:var(--radius-pill);
         background:color-mix(in srgb, var(--card) 70%, transparent); }
@supports not (color: color-mix(in srgb, red, blue)) {
  .chips { background:var(--card); }
}
.chips::-webkit-scrollbar { display:none; }
#chipInd { position:absolute; top:4px; bottom:4px; left:0; width:0;
           border-radius:var(--radius-pill); background:var(--blue);
           transition:transform .22s ease, width .22s ease;
           pointer-events:none; z-index:0; }
.chip { position:relative; z-index:1; flex:0 0 auto; padding:7px 13px;
        border-radius:var(--radius-pill); border:1px solid transparent;
        background:transparent; color:var(--dim); font:inherit;
        font-size:.78rem; cursor:pointer; transition:color .2s; }
.chip.on { color:#fff; }
.chip.locked { opacity:.45; }
/* Muted text drawn straight onto the parallax, rather than onto a card, gets
 * its own translucent surface — otherwise its contrast is measured against
 * whichever candle happens to drift under it. */
.on-canvas { background:color-mix(in srgb, var(--bg) 82%, transparent);
             backdrop-filter:blur(8px); -webkit-backdrop-filter:blur(8px);
             border-radius:10px; padding:6px 10px; }
@supports not (backdrop-filter: blur(1px)) {
  .on-canvas { background:var(--bg); }
}
#filterBar { display:flex; align-items:center; gap:8px; margin-bottom:10px;
             font-size:.78rem; color:var(--dim); }
#filterBar select { width:auto; margin:0; padding:7px 13px;
                    border-radius:var(--radius-pill);
                    border:1px solid var(--line);
                    background:var(--input); color:var(--txt); font-size:.78rem; }
.muted { color:var(--dim); font-size:.78rem; }
.conf { font-size:.75rem; font-weight:700; letter-spacing:1px; }
.conf-hi { color:var(--buy); }
.conf-mid { color:var(--gold); }
.conf-lo { color:var(--dim); }
.sl { color:var(--sell); font-weight:600; }
.tp { color:var(--buy); font-weight:600; }
table { width:100%; border-collapse:collapse; font-size:.82rem; margin-top:6px; }
td { padding:3px 6px; border-bottom:1px solid var(--line); }
td:first-child { color:var(--dim); white-space:nowrap; width:38%; }
#status { font-size:.8rem; color:var(--dim); margin-bottom:10px;
          min-height:1.1em; }
.stale { color:var(--gold); }
.upsell { background:linear-gradient(135deg,rgba(241,196,15,.12),
          rgba(230,126,34,.08)); border-color:rgba(241,196,15,.3); }
input { width:100%; padding:10px; border-radius:8px;
        border:1px solid var(--line); background:var(--input); color:var(--txt);
        font-size:.9rem; margin-top:8px; }
dialog { background:var(--card); color:var(--txt); border:1px solid var(--line);
         border-radius:14px; padding:18px; max-width:340px; width:88%;
         box-shadow:var(--shadow); }
dialog[open] { animation:dlgIn .18s ease-out both; }
@keyframes dlgIn { from { opacity:0; transform:scale(.94); }
                   to   { opacity:1; transform:none; } }
dialog::backdrop { background:rgba(0,0,0,.55);
                   backdrop-filter:blur(4px); -webkit-backdrop-filter:blur(4px); }
.disclaimer { font-size:.68rem; color:var(--dim); margin-top:16px;
              line-height:1.5; }

/* Motion is decoration everywhere in this client; honour the OS switch. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important; scroll-behavior:auto !important;
  }
  /* The canvas stays: bg.js paints one still frame and never starts its
   * loop, which is what "reduce motion" asks for. Hiding it would remove
   * the decoration rather than the motion. */
}

/* ---- bottom tab bar --------------------------------------------------
 * Fixed, because the three sections are peers and the switch has to be
 * reachable from the bottom of a long feed. The body reserves room for it
 * so the disclaimer is never trapped underneath. */
#tabs { position:fixed; left:0; right:0; bottom:0; z-index:6;
        display:flex; justify-content:space-around;
        padding:6px 4px calc(6px + env(safe-area-inset-bottom));
        background:color-mix(in srgb, var(--bg) 88%, transparent);
        backdrop-filter:blur(14px); -webkit-backdrop-filter:blur(14px);
        border-top:1px solid var(--line); }
@supports not (backdrop-filter: blur(1px)) {
  #tabs { background:var(--bg); }
}
.tab { flex:1 1 0; display:flex; flex-direction:column; align-items:center;
       gap:2px; padding:6px 4px; font-size:.66rem; text-decoration:none;
       color:var(--dim); border-radius:var(--radius);
       transition:color .15s ease; }
.tab span { font-size:1.05rem; line-height:1.1; }
.tab.on { color:var(--txt); }
.tab.on span { transform:translateY(-1px); }
body { padding-bottom:calc(72px + env(safe-area-inset-bottom)); }

/* ---- My Trades -------------------------------------------------------- */
.sec-head { margin:14px 0 8px; font-weight:600; letter-spacing:.3px; }
.btn-row { display:flex; flex-wrap:wrap; gap:8px; margin-top:10px; }
.btn-row .btn { flex:1 1 auto; font-size:.76rem; padding:8px 10px; }
.taken-badge { margin-top:10px; text-align:center; padding:9px;
               border:1px dashed var(--line); border-radius:var(--radius);
               color:var(--buy); }
/* One line per closed trade, expandable — a history that scrolls past in
 * card form buries the summary the user actually reads. */
.hist { padding:10px 14px; }
.hist summary { cursor:pointer; list-style:none; font-size:.86rem; }
.hist summary::-webkit-details-marker { display:none; }
.hist[open] summary { margin-bottom:6px; }
.chips.filters { margin-bottom:10px; }
/* The history filters are plain chips with no sliding indicator behind
 * them, so the active one paints its own background. */
.chip.on.solid { background:var(--blue); color:#fff; }
.card.stale { border-color:var(--gold); color:var(--gold); font-size:.8rem; }

/* ---- toasts ----------------------------------------------------------- */
#toasts { position:fixed; left:0; right:0;
          bottom:calc(74px + env(safe-area-inset-bottom)); z-index:7;
          display:flex; flex-direction:column; align-items:center; gap:6px;
          pointer-events:none; padding:0 12px; }
.toast { pointer-events:auto; max-width:520px; width:100%;
         background:var(--card); border:1px solid var(--line);
         box-shadow:var(--shadow); border-radius:var(--radius);
         padding:10px 14px; font-size:.8rem; line-height:1.45;
         animation:rise .2s ease-out both; }

/* A class like .chips sets display:flex, which outranks the UA sheet's
 * [hidden] rule — so a hidden chip bar would still paint. app.js toggles
 * sections with .hidden, so this has to win. */
[hidden] { display:none !important; }

/* ---- tutorial page ----------------------------------------------------
 * A plain document, not an app screen: no tab bar, so it reclaims the space
 * the fixed bar reserves, and prose gets real line-height. */
body.doc { padding-bottom:calc(24px + env(safe-area-inset-bottom));
           line-height:1.6; }
body.doc h1 { font-size:1.35rem; margin:4px 0 10px; }
body.doc h2 { font-size:.95rem; margin-bottom:8px; }
body.doc .lede { font-size:.86rem; color:var(--dim); margin-bottom:14px; }
body.doc p { font-size:.84rem; margin-top:8px; }
body.doc ul, body.doc ol { margin:8px 0 0 18px; font-size:.84rem; }
body.doc li { margin-bottom:6px; }
body.doc pre { background:var(--input); border:1px solid var(--line);
               border-radius:var(--radius); padding:10px 12px; margin-top:8px;
               font-size:.78rem; overflow-x:auto; }
body.doc td { vertical-align:top; }
.back { color:var(--dim); text-decoration:none; font-size:.85rem;
        padding:6px 2px; }
.back:hover { color:var(--txt); }
a { color:var(--blue-fg); }
