.chart-controls {
    /* Overlay & drag positioning */
    position: absolute;
    z-index: 10;
    top: 20px;
    left: 20px;

    /* Row: the grab handle on the left, spanning the full height, with the
       actual content (see .chart-controls-content) filling the rest. */
    display: flex;
    flex-direction: row;
    align-items: stretch;
    /* Widened from clamp(220px, 17vw, 380px)/min-width 200px - the old max
       (380px) was cramped now that .tab-sidebar permanently shares this
       same width with whichever tab's content is showing (see
       mobilePanelTabs.js), on top of already being tight for longer button
       labels on their own (see the .tool-row .btn cqw fix above). */
    width: clamp(320px, 26vw, 560px);
    min-width: 280px;
    height: auto;
    gap: 0.3em;

    padding: 1.2vh 1vw;
    background: var(--color-raised);
    border-radius: 0.5em;
    border: none;
    box-shadow: var(--shadow-raised);

    container-type: inline-size;
    line-height: 1.25;
    text-align: center;
    font-size: clamp(13px, 1.2vw, 20px);

    /* Fallback for the instant before resizePanel.js's refitPanel() runs
       and replaces this with an exact, position-aware scale - without this
       there'd be a flash of an overflowing panel on first paint. Content
       taller than the cap scrolls internally instead of ever pushing the
       panel's edge past the viewport (see also the JS-side guarantee, which
       is what actually keeps this true: it shrinks the WHOLE panel - text,
       buttons, padding, everything - together via --panel-scale so it always
       fits without ever needing that scrollbar in practice). */
    max-height: calc(100vh - 40px);
    overflow-y: auto;

    cursor: grab; /* still draggable from any non-interactive spot, not just the handle - this just cascades down to plain background */
    pointer-events: auto;
    /* Without this, touch browsers often treat a drag on the panel as a
       page-scroll gesture instead of handing it to dragPanel.js's pointer
       events - this is what makes touch dragging feel broken/unresponsive. */
    touch-action: none;
    /* Set by resizePanel.js; read back via getBoundingClientRect() (which,
       unlike offsetWidth/offsetHeight, reflects the size AFTER this
       transform) so dragPanel.js's viewport clamping agrees with what's
       actually rendered. */
    transform: scale(var(--panel-scale, 1));
    /* Scales from the top-left corner (where top/left positions it) instead
       of the center, so scaling never shifts the panel's apparent position -
       every resize handle below relies on this to anchor consistently. */
    transform-origin: top left;
}

.chart-controls:active {
    cursor: grabbing;
}

/* Everything that isn't the grab/resize handles - owns the old vertical
   stacking layout that used to live directly on .chart-controls. */
.chart-controls-content {
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: stretch;
    /* Tightened from 1cqw - fewer, denser rows (several selects/buttons
       paired up per row now) read better with less air between them than
       the original single-column stack needed. Still relative to the
       panel's own resized width (container-type on .chart-controls), not
       the viewport, so it keeps scaling sensibly as the panel is resized. */
    gap: 0.6cqw;
    flex: 1 1 auto;
    min-width: 0; /* let it actually shrink inside the row instead of overflowing */
}

/* Tab split (see mobilePanelTabs.js) - .mobile-tab-panels only ever shows
   the one .mobile-tab-group carrying .active, on every layout. What differs
   between desktop and mobile is how you switch tabs and what's visible to
   do it with, both handled by the two mobile media queries further down
   (matching resizePanel.js's isFloatingPanelLayout() breakpoints exactly):
   on desktop (here, the un-queried default) that's .tab-sidebar's clickable
   labels to the left, on mobile it's swiping the active tab's content plus
   a fallback dot indicator - .tab-sidebar hides and .mobile-tab-dots shows
   there instead. */
.mobile-tab-panels {
    display: block;
    flex: 1 1 auto;
    min-width: 0;
}

.mobile-tab-group {
    display: none;
}

.mobile-tab-group.active {
    display: flex;
    flex-direction: column;
    gap: 0.4em;
}

.mobile-tab-dots {
    display: none;
}

/* Strategy/Indicators: never shown as a tab - their buttons are only
   grabbed through the radial menu (radialMenu.js), which hands its drag
   off to them. Rendered off-screen instead of display:none so they stay
   valid pointer-capture targets. Specific enough to beat every layout's
   .mobile-tab-group rules (controls-responsive.css). */
.mobile-tab-group[data-mobile-tab="strategy"],
.mobile-tab-group[data-mobile-tab="indicators"] {
    display: flex;
    position: fixed;
    left: -10000px;
    top: 0;
    visibility: visible;
}

/* Puts .tab-sidebar and .mobile-tab-panels side by side on desktop -
   display:contents on mobile (see the mobile media queries further down)
   makes this wrapper transparent there, so .mobile-tab-panels (with
   .tab-sidebar hidden) is free to stack full-width in the normal column
   flow exactly as if this wrapper didn't exist. */
.tab-layout {
    display: flex;
    flex-direction: row;
    gap: 0.6em;
    min-width: 0;
    flex: 1 1 auto;
}

.tab-sidebar {
    display: flex;
    flex-direction: column;
    gap: 0.2em;
    flex-shrink: 0;
    padding-right: 0.6em;
    border-right: 1px solid rgba(255, 255, 255, 0.12);
}

/* Scoped as .tab-sidebar .tab-sidebar-btn (not just .tab-sidebar-btn) so
   this outranks the generic ".chart-controls button" sizing rule further
   below (which would otherwise blow every label up to a full-size, centered,
   flex:1 button, same reasoning as .mobile-tab-dots' own buttons) - every
   property that rule sets is also explicitly reset here for the same
   reason, even ones that look like plain defaults. */
.tab-sidebar .tab-sidebar-btn {
    display: block;
    width: auto;
    height: auto;
    flex: 0 0 auto;
    min-height: 0;
    max-height: none;
    box-sizing: content-box;
    background: none;
    border: none;
    color: rgba(255, 255, 255, 0.6);
    text-align: left;
    white-space: nowrap;
    padding: 0.4em 0.6em;
    border-radius: 4px;
    cursor: pointer;
    font-size: clamp(12px, 1.1cqw, 15px);
    font-weight: 600;
}

.tab-sidebar .tab-sidebar-btn:hover {
    background: rgba(255, 255, 255, 0.08);
    color: #fff;
}

.tab-sidebar .tab-sidebar-btn.active {
    background: rgba(41, 98, 255, 0.18);
    color: #fff;
}

/* Full-height grab strip on the left - on a cramped mobile layout there's
   barely any empty background left between the stacked buttons/selects to
   drag from otherwise, this guarantees one obvious, always-reachable spot. */
.chart-controls-handle {
    width: 1.2em;
    flex-shrink: 0;
    align-self: stretch;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: grab;
}

.chart-controls-handle:active {
    cursor: grabbing;
}

.chart-controls-handle::before {
    content: '';
    width: 0.3em;
    height: 2.6em;
    border-radius: 0.2em;
    background: rgba(255, 255, 255, 0.25);
}

.chart-controls-handle:hover::before {
    background: rgba(255, 255, 255, 0.4);
}

/* Resize grip in the bottom-right corner - dot-grid pattern, the classic
   resize-handle affordance (see resizePanel.js for the actual dragging).
   Above the plain edge strips below so it wins in their shared corner. */
.chart-controls-resize-handle {
    position: absolute;
    z-index: 21;
    right: 2px;
    bottom: 2px;
    width: 1.1em;
    height: 1.1em;
    cursor: nwse-resize;
    touch-action: none;
    background-image: radial-gradient(circle, rgba(255, 255, 255, 0.5) 1px, transparent 1.5px);
    background-size: 4px 4px;
    background-position: bottom right;
    background-repeat: repeat;
    opacity: 0.7;
}

.chart-controls-resize-handle:hover {
    opacity: 1;
}

/* Plain edge strips - "grab a side and drag" resizing like a typical desktop
   window, in addition to the corner grip above (both drive the same
   --panel-scale as the corner - see resizePanel.js). Kept fully inside the
   panel's own box (not overlapping past its border) so .chart-controls'
   overflow:auto never clips them. */
.chart-controls-resize-right,
.chart-controls-resize-bottom {
    position: absolute;
    z-index: 20;
    touch-action: none;
}

.chart-controls-resize-right {
    top: 0;
    right: 0;
    bottom: 0;
    width: 8px;
    cursor: ew-resize;
}

.chart-controls-resize-bottom {
    left: 0;
    right: 0;
    bottom: 0;
    height: 8px;
    cursor: ns-resize;
}
