/* ==========================================================================
   mobile.css — portrait-phone fixes. Loaded LAST on every page.
   Added 2026-09-05.

   Deliberately a separate file rather than edits to the existing @media blocks:
   everything here is additive and scoped to small viewports, so it cannot change
   how the desktop dashboard renders. Each rule below fixes something that was
   measured as broken at 393px, not something that looked suspicious.
   ========================================================================== */

@media (max-width: 768px) {

    /* ---------------------------------------------------------------- safe area
       Notched phones put the home indicator over the bottom ~34px. Without this
       the chat button and the offline banner sit underneath it. */
    body {
        padding-bottom: calc(72px + env(safe-area-inset-bottom, 0px));
    }

    /* ------------------------------------------------------- section headers
       MEASURED: ".trade-ideas-title" ran 31->347px while its sibling timestamp
       wrapper sat at 248->342px on the SAME line, so "Updated: 2:26 am" printed
       straight through "TOP ALGORITHMIC TRADE IDEAS".

       The wrapper is a nested flex box (<div style="display:flex">) that collapses
       to zero used width as a flex item. flex-basis, flex:0 0 auto and even
       min-width:max-content all failed to stop it — a zero-width item then "fits"
       beside a 100%-basis sibling, so flex-wrap never triggered either.

       So we stop negotiating with the flex algorithm and take the row out of flex
       entirely on small screens. Block layout cannot overlap: two block siblings
       always stack. Fewer moving parts, and nothing to re-tune if the markup
       changes. */
    div:has(> .trade-ideas-title),
    div:has(> .finviz-title),
    div:has(> .calendar-title) {
        /* !important is load-bearing here, not laziness: the container carries an
           INLINE style="display: flex; justify-content: space-between; ..." written
           into index.html, and an inline declaration outranks any stylesheet rule.
           Without !important this whole block silently does nothing — verified: the
           selector matched and the rule was present, yet computed display stayed
           "flex". Scoped to the mobile media query, so desktop is untouched. */
        display: block !important;
    }
    .trade-ideas-title,
    .finviz-title,
    .calendar-title {
        display: block;
        width: auto;
        margin-bottom: 2px;
    }
    div:has(> .trade-ideas-title) > div:not(.trade-ideas-title),
    div:has(> .finviz-title) > div:not(.finviz-title),
    div:has(> .calendar-title) > div:not(.calendar-title) {
        /* the timestamp wrapper is also inline-styled display:flex */
        display: block !important;
        width: auto;
    }
    /* THE ACTUAL ROOT CAUSE. .trade-timestamp is position:absolute, pinned to
       .trade-ideas-container (which is position:relative). It was never in normal
       flow, which is why flex-wrap, flex-basis, min-width and even switching the
       row to block layout all failed to move it — they only ever affected boxes
       that participate in layout, and this one does not.
       Returning it to static lets it flow into the (now block) wrapper beneath the
       heading, where it simply cannot overlap. */
    .trade-timestamp,
    #dashboard-timestamp {
        position: static !important;
        top: auto !important;
        right: auto !important;
        white-space: nowrap;
        font-size: 11px;
        opacity: 0.75;
    }

    /* ------------------------------------------------------------ sub-tab strip
       MEASURED: scrollWidth 481 inside a 348px box, so "Calendar" was sliced in
       half with only a 4px arrow hinting there was more. It scrolls, but nothing
       said so. Make it an obvious, snappy, edge-faded strip. */
    div:has(> .subtab-btn) {
        display: flex;
        flex-wrap: nowrap;
        overflow-x: auto;
        overflow-y: hidden;
        -webkit-overflow-scrolling: touch;
        scroll-snap-type: x proximity;
        scrollbar-width: none;
        /* fade the right edge so a clipped tab reads as "more", not "broken" */
        -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
                mask-image: linear-gradient(to right, #000 calc(100% - 28px), transparent 100%);
    }
    div:has(> .subtab-btn)::-webkit-scrollbar { display: none; }
    .subtab-btn {
        flex: 0 0 auto;
        scroll-snap-align: start;
        white-space: nowrap;
    }

    /* --------------------------------------------------------- wide tables
       The calendar and trades tables are far wider than any phone. They already
       live in overflow:auto parents, so they scroll — but silently. A left border
       cue plus momentum scrolling makes that discoverable. */
    .calendar-table-container,
    .trades-table-container {
        overflow-x: auto;
        -webkit-overflow-scrolling: touch;
        scrollbar-width: thin;
    }
    .calendar-table,
    .trades-table {
        min-width: 560px;   /* stop the browser crushing columns into unreadable slivers */
    }

    /* ------------------------------------------------------------- chat button
       MEASURED: 60px circle overlapping the US CLOSE BRIEFING card and the DXY
       card. Smaller, lifted clear of the home indicator. */
    #ai-chat-widget {
        transform: scale(0.82);
        transform-origin: bottom right;
        bottom: calc(12px + env(safe-area-inset-bottom, 0px)) !important;
        right: 10px !important;
        z-index: 9998;
    }

    /* ---------------------------------------------------------- stat readouts
       MEASURED: "Tier 2: 31.5% (78)" is a bare inline <span>, so the line broke
       mid-pair and orphaned "(78)" onto the next row away from its percentage.
       inline-block makes each stat an unbreakable unit that wraps as a whole. */
    .stat-chip {
        display: inline-block;
        white-space: nowrap;
        margin-bottom: 4px;
    }
    .idea-reasoning,
    .reason-checkbox { word-break: normal; overflow-wrap: anywhere; }
}

/* ==========================================================================
   JOURNAL — portrait
   ========================================================================== */
@media (max-width: 768px) {

    /* MEASURED: the 60px icon rail left only 273px of a 393px viewport, which is
       why .metric-card's `flex: 1 1 calc(50% - 15px)` with min-width 140px could
       never fit two per row (50% of 273 = 136). Narrowing the rail and the card
       floor together restores the intended two-column layout. */
    .sidebar {
        width: 46px;
        min-width: 46px;
        padding-left: 0;
        padding-right: 0;
    }
    .sidebar i,
    .sidebar svg { font-size: 17px; }

    .metric-card {
        flex: 1 1 calc(50% - 8px);
        min-width: 0;
        padding: 10px 12px;
    }
    .metrics-row { gap: 8px; }
    .metric-card .metric-value,
    .metric-card strong { font-size: 17px; }
    .metric-chart { height: 30px; }

    /* MEASURED: .top-nav is flex-wrap:nowrap holding .filters (270px) plus
       .nav-actions (144px) — 414px of children in a 273px box, so both got crushed
       and the Sync button sat on top of the filter column. Letting the row wrap and
       giving the filters their own full-width line means the dropdowns get the whole
       273px and fit two or three per row instead of stacking seven deep. */
    .top-nav {
        flex-wrap: wrap;
        gap: 8px;
    }
    .top-nav > .filters { flex: 1 1 100%; }
    .top-nav > .nav-actions { flex: 1 1 100%; justify-content: flex-start; }

    /* Filter dropdowns ran off the right edge with their chevrons clipped. */
    .filters {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        padding-right: 10px;
    }
    .filters > * {
        /* min-width 0 was too aggressive: with six controls sharing the row they
           collapsed to bare chevrons with the labels ("Symbol: All", "Setup: All")
           squeezed out entirely. A 118px floor keeps the label legible and lets the
           row wrap to as many lines as it needs. */
        flex: 1 1 auto;
        min-width: 118px;
        max-width: 100%;
    }
    .filters select,
    .filters .dropdown-header,
    .filters button {
        /* NOT width:100% / min-width:0 — that was my own bug. The children are bare
           <select> elements, so forcing 100% made every one of them claim a whole
           row and the seven filters stacked seven deep. Letting them size to content
           with a floor puts two or three on a line. */
        width: auto;
        min-width: 112px;
        max-width: 100%;
        box-sizing: border-box;
    }

    /* Trade-details metric grid: 4 across is unreadable on a phone. */
    .trade-details-metrics-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 8px;
    }
    .trade-details-header { flex-wrap: wrap; gap: 8px; }

    /* Follow-through panel: two per row rather than four cramped columns. */
    .td-ft-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .td-ft-header { align-items: flex-start; }
}

/* --------------------------------------------------------------------------
   Very small phones (SE-class).
   Threshold is 360px, NOT 400px: at 400 this was catching the iPhone 14 Pro
   (393px), which forced its metric cards to full width even though two fit
   comfortably once the sidebar dropped to 46px (~285px usable, 134px a card).
   -------------------------------------------------------------------------- */
@media (max-width: 360px) {
    .metric-card { flex: 1 1 100%; }          /* two columns genuinely stop fitting */
    .trade-details-metrics-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .subtab-btn { font-size: 12px; padding-left: 10px; padding-right: 10px; }

    /* [v2.16.0] Card head: symbol + bias + play + grade comes to ~251px against a
       ~255px inner card width here, so the grade badge was wrapping onto a line of
       its own and reading as a stray. Tighter gap and no auto-margin fits all four
       on one row; both revert to the desktop rule above 360px. */
    .wl-head { gap: 6px; }
    .wl-grade { margin-left: 0; }

    /* A+ check rows: the fixed label column stops fitting alongside the detail text
       at this width, so let the pair stack instead of squeezing. */
    .wl-chk { flex-wrap: wrap; }
    .wl-chk-id { min-width: 0; }
    .wl-chk-detail { flex: 1 1 100%; padding-left: 17px; }
}

/* --------------------------------------------------------------------------
   Landscape phones: reclaim vertical space, which is the scarce axis there.
   -------------------------------------------------------------------------- */
@media (max-width: 900px) and (orientation: landscape) {
    body { padding-bottom: calc(56px + env(safe-area-inset-bottom, 0px)); }
    .metric-chart { height: 26px; }
    #wisdom-banner { padding: 10px 14px !important; }
}
