/* sidebar.css — layout + chrome for the opt-in full-height sidebar.
 *
 * Safe to load unconditionally: every rule is either scoped to
 * body.sidebar-mode, or targets IDs that only exist in sidebar mode.
 */

/* ----- Push-layout: map makes room for the sidebar ---------------------- */

body.sidebar-mode #map {
    left: 0;
    right: var(--sidebar-width, 0);
    width: auto;
}

/* Keep the original floating #menu div out of the way in sidebar mode —
 * the layer menu renders inside #sidebar-layers-pane instead. */
body.sidebar-mode #menu {
    display: none;
}

/* ----- Sidebar container ------------------------------------------------- */

body.sidebar-mode #sidebar {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    width: var(--sidebar-width, 420px);
    background: var(--chrome-bg);
    color: var(--chrome-fg);
    display: flex;
    flex-direction: column;
    z-index: var(--z-sidebar, 30);
    box-shadow: -2px 0 6px var(--chrome-shadow);
    transition: transform 200ms ease;
    /* Sidebar chat uses solid background — override any glass blur coming
     * from chat.css that assumes a translucent floating container. */
    backdrop-filter: none;
    -webkit-backdrop-filter: none;
}

/* ----- Resize handle on the left edge ----------------------------------- */

body.sidebar-mode .sidebar-resize-handle {
    position: absolute;
    top: 0;
    left: 0;
    bottom: 0;
    width: 6px;
    cursor: col-resize;
    background: transparent;
    border-left: 1px solid var(--chrome-line);
    transition: border-color 120ms ease, background 120ms ease;
    z-index: 2;
}

body.sidebar-mode .sidebar-resize-handle:hover {
    border-left-color: var(--chrome-accent);
    background: var(--chrome-accent-wash);
}

/* ----- Header ------------------------------------------------------------ */

body.sidebar-mode #sidebar-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    border-bottom: 1px solid var(--chrome-line);
    flex: 0 0 auto;
}

body.sidebar-mode #sidebar-header h3 {
    margin: 0;
    font-size: 14px;
    font-weight: 600;
    letter-spacing: 0.2px;
}

body.sidebar-mode #sidebar-hide {
    background: transparent;
    border: none;
    color: inherit;
    font-size: 16px;
    cursor: pointer;
    padding: 2px 8px;
    border-radius: 3px;
}

body.sidebar-mode #sidebar-hide:hover {
    background: var(--chrome-hover);
}

/* ----- Layers pane ------------------------------------------------------- */

body.sidebar-mode:not(.sheet-mode) #sidebar-layers-pane {
    flex: 0 0 auto;
    max-height: 40%;
    overflow-y: auto;
    padding: 8px 12px 16px;
    /* Divider line lives on .sidebar-splitter when the splitter is visible. */
}

/* Once the user drags the splitter, switch to fixed-pixel sizing.
 * Skipped when either pane is collapsed (other rules below take over). */
body.sidebar-mode.layers-pane-resized:not(.sheet-mode):not(.chat-collapsed)
    #sidebar-layers-pane:not(.collapsed) {
    flex: 0 0 var(--layers-pane-height, 200px);
    max-height: none;
}

/* When chat is collapsed, layers pane fills the available height. */
body.sidebar-mode.chat-collapsed:not(.sheet-mode) #sidebar-layers-pane {
    flex: 1 1 auto;
    max-height: none;
    border-bottom: 1px solid var(--chrome-line);
}

/* Layers pane keeps a visible divider when its own splitter is hidden
 * (which happens when the layers pane itself is collapsed). */
body.sidebar-mode #sidebar-layers-pane.collapsed {
    border-bottom: 1px solid var(--chrome-line);
}

/* Collapse behavior — mirror the floating-mode #menu rules in style.css
 * (#menu only matches in floating mode, so sidebar needs its own copies). */
body.sidebar-mode #sidebar-layers-pane.collapsed #menu-body {
    display: none;
}

body.sidebar-mode #sidebar-layers-pane:not(.collapsed) .menu-header .section-title {
    display: none;
}

body.sidebar-mode #sidebar-layers-pane:not(.collapsed) .menu-header {
    justify-content: flex-end;
    margin-bottom: 4px;
}

/* ----- Splitter between layers pane and chat ---------------------------- */

body.sidebar-mode .sidebar-splitter {
    flex: 0 0 5px;
    background: transparent;
    border-bottom: 1px solid var(--chrome-line);
    cursor: row-resize;
    transition: background 120ms ease, border-color 120ms ease;
    z-index: 1;
}

body.sidebar-mode .sidebar-splitter:hover {
    background: var(--chrome-accent-wash);
    border-bottom-color: var(--chrome-accent);
}

/* Hide the splitter when either side is fully collapsed — nothing to drag. */
body.sidebar-mode.chat-collapsed .sidebar-splitter,
body.sidebar-mode #sidebar-layers-pane.collapsed + .sidebar-splitter {
    display: none;
}

/* ----- Chat section header (collapse toggle bar) ------------------------ */

body.sidebar-mode #chat-section-header {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    justify-content: flex-end;
    padding: 4px 8px;
    font-size: 11px;
    color: var(--chrome-fg-muted);
    letter-spacing: 0.4px;
    text-transform: uppercase;
}

body.sidebar-mode #chat-section-header .section-title {
    margin: 0;
    font-weight: 600;
    /* Mirror layers menu-header: only show the title while collapsed. */
    display: none;
}

body.sidebar-mode.chat-collapsed #chat-section-header {
    justify-content: space-between;
    border-bottom: 1px solid var(--chrome-line);
}

body.sidebar-mode.chat-collapsed #chat-section-header .section-title {
    display: inline;
}

/* Opt-in via sidebar.chat_title: show the heading persistently (not just
 * while collapsed), mirroring the always-visible layers "Overlays" label. */
body.sidebar-mode #chat-section-header.has-chat-title {
    justify-content: space-between;
}

body.sidebar-mode #chat-section-header.has-chat-title .section-title {
    display: inline;
}

body.sidebar-mode #chat-section-toggle {
    background: transparent;
    border: none;
    color: inherit;
    font-size: 14px;
    line-height: 1;
    cursor: pointer;
    padding: 0 6px;
    border-radius: 3px;
}

body.sidebar-mode #chat-section-toggle:hover {
    background: var(--chrome-hover);
}

/* Hide chat content when collapsed; layers pane fills the gap. */
body.sidebar-mode.chat-collapsed #chat-messages,
body.sidebar-mode.chat-collapsed #chat-input-container {
    display: none;
}

/* ----- Chat region — override a few chat.css rules that assume a
 *       translucent floating panel. ------------------------------------- */

body.sidebar-mode #chat-messages {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 18px 12px 10px;
}

body.sidebar-mode #chat-input-container {
    flex: 0 0 auto;
    display: flex;
    align-items: flex-end;
    gap: 6px;
    padding: 8px 12px;
    border-top: 1px solid var(--chrome-line);
}

body.sidebar-mode #chat-input-container #chat-input {
    flex: 1;
}

/* ----- Footer ------------------------------------------------------------ */

body.sidebar-mode #sidebar-footer {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 6px 12px 8px;
    border-top: 1px solid var(--chrome-line);
    font-size: 11px;
    flex: 0 0 auto;
}

body.sidebar-mode #sidebar-footer #chat-footer-right {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
}

body.sidebar-mode #sidebar-footer .footer-link {
    display: inline-flex;
    align-items: center;
    padding: 2px 6px;
    margin-right: 4px;
    color: var(--chrome-fg-muted);
    text-decoration: none;
    border-radius: 3px;
}

body.sidebar-mode #sidebar-footer .footer-link:hover {
    color: var(--chrome-fg);
    background: var(--chrome-hover);
}

body.sidebar-mode #sidebar-footer .footer-link.carbon-link,
body.sidebar-mode #sidebar-footer .footer-link.carbon-link:hover {
    color: var(--chrome-carbon);
}

/* ----- Collapse / show toggle ------------------------------------------- */

body.sidebar-mode.sidebar-collapsed {
    --sidebar-width: 0px;
}

body.sidebar-mode.sidebar-collapsed #sidebar {
    transform: translateX(100%);
}

#sidebar-show-btn {
    position: fixed;
    top: 10px;
    right: 10px;
    display: none;  /* shown only while collapsed */
    background: var(--chrome-bg);
    -webkit-backdrop-filter: blur(8px);
    backdrop-filter: blur(8px);
    border: 1px solid var(--chrome-line);
    border-radius: 4px;
    padding: 4px 10px;
    font-size: 14px;
    cursor: pointer;
    z-index: var(--z-sidebar-show, 35);
    box-shadow: 0 1px 3px var(--chrome-shadow);
}

body.sidebar-mode.sidebar-collapsed #sidebar-show-btn {
    display: block;
}

/* ----- Narrow-viewport fallback: overlay instead of push --------------- */

/* ----- Narrow viewport: the sidebar becomes a bottom sheet -------------
   A side-by-side panel and map cannot both work at phone width. The panel
   moves to the bottom with three detents (peek / half / full), driven by
   mobile-sheet.js, which sets --sheet-h. The map stays full-bleed behind it
   and keeps every one of its own gestures: the sheet moves only from its
   handle. See app/mobile-sheet.js. */

@media (max-width: 700px) {
    body.sidebar-mode #map {
        right: 0;
        width: 100%;
    }

    body.sidebar-mode.sheet-mode #sidebar {
        top: auto;
        right: 0;
        left: 0;
        bottom: 0;
        width: 100%;
        height: var(--sheet-h, 96px);
        max-height: calc(100vh - var(--app-header-h));
        flex-direction: column;
        border-top: 1px solid var(--chrome-line);
        border-radius: 12px 12px 0 0;
        box-shadow: 0 -4px 16px var(--chrome-shadow);
        overflow: hidden;
        /* Nothing below the sheet is reachable, so let the browser keep the
           page from rubber-banding when the panel's list hits its end. */
        overscroll-behavior: contain;
        padding-bottom: env(safe-area-inset-bottom, 0px);
    }

    /* Only while snapping — a transition during a drag lags the finger. */
    body.sidebar-mode.sheet-mode #sidebar.sheet-animating {
        transition: height 180ms ease;
    }

    /* Desktop chrome that the sheet replaces. */
    body.sidebar-mode.sheet-mode .sidebar-resize-handle,
    body.sidebar-mode.sheet-mode .sidebar-splitter,
    body.sidebar-mode.sheet-mode #sidebar-header,
    body.sidebar-mode.sheet-mode #sidebar-show-btn,
    body.sidebar-mode.sheet-mode #chat-section-header {
        display: none;
    }

    /* ----- Handle ----- */
    #sheet-grabber {
        flex: 0 0 auto;
        display: flex;
        align-items: center;
        justify-content: center;
        /* Generous hit area around a small visual grabber: this is the one
           drag target on the screen, and a thin bar is hard to catch. */
        height: 28px;
        padding: 0;
        border: none;
        background: none;
        cursor: grab;
        touch-action: none;
    }

    #sheet-grabber span {
        display: block;
        width: 38px;
        height: 4px;
        border-radius: 2px;
        background: var(--chrome-fg-muted);
    }

    /* ----- Tabs ----- */
    #sheet-tabs {
        flex: 0 0 auto;
        display: flex;
        gap: 6px;
        padding: 0 12px 10px;
    }

    .sheet-tab {
        flex: 1;
        padding: 9px 10px;
        font: inherit;
        font-size: 14px;
        color: var(--chrome-fg);
        background: var(--chrome-hover);
        border: 1px solid transparent;
        border-radius: 6px;
        cursor: pointer;
    }

    .sheet-tab[aria-selected="true"] {
        background: var(--control-bg);
        color: var(--control-fg);
    }

    /* ----- Panes: one at a time ----- */
    body.sheet-mode:not([data-sheet-tab="layers"]) #sidebar-layers-pane,
    body.sheet-mode:not([data-sheet-tab="legend"]) #map-overlay-rail,
    body.sheet-mode:not([data-sheet-tab="chat"]) #chat-messages,
    body.sheet-mode:not([data-sheet-tab="chat"]) #chat-input-container,
    body.sheet-mode:not([data-sheet-tab="chat"]) #sidebar-footer,
    body.sheet-mode:not([data-sheet-tab="chat"]) #api-settings-panel {
        display: none;
    }

    /* The one pane on show fills the sheet and scrolls inside it. Without
       this the layers list keeps its natural height, overflows a short
       sheet, and its bottom — and the chat below it — cannot be reached. */
    body.sidebar-mode.sheet-mode #sidebar-layers-pane,
    body.sidebar-mode.sheet-mode #chat-messages,
    body.sidebar-mode.sheet-mode #map-overlay-rail {
        flex: 1 1 auto;
        min-height: 0;
        max-height: none;
        overflow-y: auto;
        overscroll-behavior: contain;
    }

    /* The desktop pane's padding is scoped out of sheet mode along with its
       splitter sizing, so restore the gutter here — without it the layer
       list and action buttons sit flush against the screen edge. */
    body.sidebar-mode.sheet-mode #sidebar-layers-pane {
        padding: 8px 16px 16px;
    }

    /* Input and footer keep their place at the bottom of the sheet. */
    body.sidebar-mode.sheet-mode #chat-input-container,
    body.sidebar-mode.sheet-mode #sidebar-footer {
        flex: 0 0 auto;
    }

    /* ----- Map overlays move into the sheet -----------------------------
       Stacked over a phone-sized map the legend, slider and hex controls
       cover most of it. On mobile they dock here instead, as their own
       pane, so the map stays a map. */
    body.sidebar-mode.sheet-mode[data-sheet-tab="legend"] #map-overlay-rail {
        position: static;
        display: flex;
        flex-direction: column;
        align-items: stretch;
        gap: 10px;
        width: auto;
        padding: 4px 12px 12px;
        pointer-events: auto;
    }

    body.sidebar-mode.sheet-mode[data-sheet-tab="legend"] #map-overlay-rail > * {
        position: static;
        max-width: none;
    }

    /* The legend is scrolled by the pane, not by itself. */
    body.sidebar-mode.sheet-mode #legend {
        max-height: none;
    }

    /* At peek there is nothing to show but the handle and the tabs. */
    body.sheet-mode[data-sheet-detent="peek"] #sidebar-layers-pane,
    body.sheet-mode[data-sheet-detent="peek"] #map-overlay-rail,
    body.sheet-mode[data-sheet-detent="peek"] #chat-messages,
    body.sheet-mode[data-sheet-detent="peek"] #chat-input-container,
    body.sheet-mode[data-sheet-detent="peek"] #sidebar-footer {
        display: none;
    }

    /* Inputs below 16px make iOS Safari zoom the whole page on focus. */
    body.sheet-mode #chat-input,
    body.sheet-mode .sheet-tab {
        font-size: 16px;
    }
}

/* ----- Chat surfaces, themed -------------------------------------------
   chat.css styles the chat for the floating panel, which is its own dark
   glass treatment on top of the map. In the sidebar the chat sits on the
   chrome surface instead, so its colours have to follow the theme or a dark
   sidebar ends up with light bubbles floating on it.

   Scoped to sidebar mode so the (deprecated) floating panel is untouched.
   This covers the chat shell and bubbles; syntax highlighting inside code
   blocks still comes from the highlight.js stylesheet and is not themed. */

body.sidebar-mode #chat-header h3 {
    color: var(--chrome-fg);
}

body.sidebar-mode #chat-messages::-webkit-scrollbar-thumb {
    background: var(--chrome-line);
}

body.sidebar-mode #chat-input {
    background: var(--chat-input-bg);
    color: var(--chat-fg);
}

body.sidebar-mode #chat-input:focus {
    background: var(--chat-input-bg-focus);
}

body.sidebar-mode .chat-message.assistant {
    background: var(--chat-surface);
    color: var(--chat-fg);
}

body.sidebar-mode .chat-message.system {
    background: var(--chat-surface-soft);
    color: var(--chrome-fg-muted);
}

body.sidebar-mode .chat-message.assistant-thinking {
    background: var(--chat-thinking-bg);
    color: var(--chat-thinking-fg);
}

body.sidebar-mode .chat-message pre,
body.sidebar-mode .chat-message th {
    background: var(--chat-code-bg);
}

body.sidebar-mode .chat-message.tool-block {
    background: var(--chat-tool-bg);
}

/* Errors: body text in the chat colour on a faint red wash, with the red
   carried by the edge. chat.css draws dark-red text on a red tint, which on
   the dark palette was red on near-black — unreadable exactly when the
   message matters (an LLM 402, a failed query). */
body.sidebar-mode .chat-message.error {
    background: color-mix(in srgb, var(--danger-fg) 12%, transparent);
    color: var(--chat-fg);
    border-left: 3px solid var(--danger-fg);
    overflow-wrap: anywhere;
}

/* The user's own message takes the control colour, so it follows the
   palette and a `theme.primary` override like every other blue here. */
body.sidebar-mode .chat-message.user {
    background: var(--control-bg);
    color: var(--control-fg);
}

/* The welcome message sits on the sidebar itself, not in a bubble: a bubble
   holding a row of pill buttons was three nested surfaces before the first
   question. The examples are outline chips — one line, no fill of their own. */
body.sidebar-mode .chat-message.welcome-message {
    background: transparent;
    color: var(--chat-fg);
    max-width: none;
    padding-left: 2px;
    padding-right: 2px;
}

body.sidebar-mode .welcome-example-btn {
    background: transparent;
    border: 1px solid var(--chrome-line);
    color: var(--chat-fg);
    font-family: inherit;
}

body.sidebar-mode .welcome-example-btn:hover {
    background: var(--chrome-accent-wash);
    border-color: var(--control-accent);
}

/* Timeline and tool labels: chat.css hard-codes a navy that disappears on
   the dark palette. */
body.sidebar-mode .agent-turn-row-summary,
body.sidebar-mode .query-summary-btn,
body.sidebar-mode .tool-call-item strong,
body.sidebar-mode .tool-result-item strong {
    color: var(--chat-accent-fg);
}

body.sidebar-mode .query-summary-btn::before {
    border-left-color: var(--chat-accent-fg);
}

body.sidebar-mode .agent-turn-row-summary:hover {
    background: var(--chrome-hover);
}

/* The rest of the timeline hard-codes light-palette text: near-black for
   an expanded tool's arguments and reasoning (so a query's SQL was
   invisible on dark), and greys for the turn summary and status rows. */
body.sidebar-mode .agent-turn-row-body,
body.sidebar-mode .tool-reasoning {
    color: var(--chat-fg);
}

body.sidebar-mode .agent-turn > .agent-turn-summary,
body.sidebar-mode .agent-turn-row.thinking,
body.sidebar-mode .agent-turn-row .row-status:not(.done):not(.error),
body.sidebar-mode .agent-turn-row.reasoning > .agent-turn-row-summary {
    color: var(--chrome-fg-muted);
}

body.sidebar-mode .agent-turn-row-body pre {
    background: var(--chat-code-bg);
    padding: 6px 8px;
    border-radius: 4px;
    overflow-x: auto;
}

/* One scrollbar treatment for everything that scrolls in the sidebar — the
   layer list had none and showed the browser's white bar on dark. The
   standard properties are inherited, cover Firefox, and in Chromium take
   over from the ::-webkit-scrollbar rules for the chat pane. */
body.sidebar-mode #sidebar {
    scrollbar-color: var(--chrome-line) transparent;
    scrollbar-width: thin;
}

body.sidebar-mode #chat-footer .footer-link {
    color: var(--chrome-fg-muted);
}

body.sidebar-mode #chat-footer .footer-link:hover {
    color: var(--chrome-fg);
    background: var(--chrome-hover);
}

/* The send button sized to its label rather than stretching. #chat-input
   is the flexible element in the row; the button should not also grow, or
   it reads as a bar across the panel instead of a control. */
body.sidebar-mode #chat-input-container {
    align-items: flex-end;
}

body.sidebar-mode #chat-input {
    flex: 1 1 auto;
    min-width: 0;
}

body.sidebar-mode #chat-send,
body.sidebar-mode #chat-mic {
    flex: 0 0 auto;
    align-self: flex-end;
}

/* Send uses the shared control fill, so it matches the panel buttons
   instead of being the one bespoke blue in the sidebar. */
body.sidebar-mode #chat-send {
    background: var(--control-bg);
    color: var(--control-fg);
}

body.sidebar-mode #chat-send:hover:not(:disabled) {
    background: var(--control-bg-hover);
}

/* The model selector is a control like any other, so it takes the shared
   fill rather than a near-invisible translucent chip. */
body.sidebar-mode #model-selector {
    background: var(--control-bg);
    color: var(--control-fg);
    opacity: 1;
}

body.sidebar-mode #model-selector:hover {
    background: var(--control-bg-hover);
    opacity: 1;
}

/* ----- API key panel, themed ------------------------------------------
   chat.css styles this for the floating panel's dark-glass surface: a
   translucent white box with dark text. On a themed sidebar that reads as a
   grey slab, and in the dark theme the text sits on the wrong ground
   entirely. Scoped to sidebar mode, so floating mode keeps its own look. */

body.sidebar-mode #api-settings-panel {
    background: var(--chat-surface-soft);
    border-bottom: 1px solid var(--chrome-line);
}

body.sidebar-mode .settings-title {
    color: var(--chrome-fg);
}

body.sidebar-mode .settings-label {
    color: var(--chrome-fg-muted);
}

body.sidebar-mode .settings-hint {
    color: var(--chrome-fg-muted);
}

body.sidebar-mode #settings-btn {
    color: var(--chrome-fg-muted);
}

body.sidebar-mode #settings-btn:hover {
    color: var(--chrome-fg);
}

body.sidebar-mode #api-settings-panel input {
    background: var(--chat-input-bg);
    color: var(--chat-fg);
    border: 1px solid var(--chrome-line);
}

body.sidebar-mode #api-settings-panel input:focus {
    border-color: var(--control-accent);
}

/* Save is a control like any other; cancel stays quiet beside it. */
body.sidebar-mode .settings-save-btn {
    background: var(--control-bg);
    color: var(--control-fg);
}

body.sidebar-mode .settings-save-btn:hover {
    background: var(--control-bg-hover);
}

body.sidebar-mode .settings-cancel-btn {
    background: var(--chrome-hover);
    color: var(--chrome-fg-muted);
}

body.sidebar-mode .settings-cancel-btn:hover {
    background: var(--chrome-hover);
    color: var(--chrome-fg);
}
