/**
 * Explore dock — global slide-up chat panel, admin-only.
 * File: styles/explore-dock.css
 *
 * Token values match chat/index.php's own inline styles exactly (same blue
 * #0d6efd, same borders/greys) so Explore reads as the same product, not a
 * reskin. New here: the FAB, backdrop, and sliding-panel chrome.
 */

/* A tab, not a floating pill — sits flush against the bottom edge of the
   viewport (rounded top corners only, square bottom) so it reads as
   anchored chrome rather than a call-to-action hovering over the page.
   Right edge lines up with #explore-panel's own right edge (both at 5%
   inset). Only ever visible collapsed — once the panel's open, the panel's
   own header (title + #explore-close) is the control; the tab just
   disappears rather than trying to relocate itself on top of the panel. */
#explore-fab {
    position: fixed;
    right: 5%;
    /* top:100dvh + translateY(-100%) instead of bottom:0 — mobile browsers
       show/hide their address-bar toolbar shortly after a page loads,
       dynamically changing the true visible viewport height, and a plain
       `bottom:0` fixed element doesn't reliably re-anchor when that
       happens (a known cross-browser inconsistency) — hence the tab
       starting flush, then appearing to jump up and settle a few px above
       the real bottom edge once the toolbar retracts. `dvh` is specifically
       designed to track that dynamic viewport live, so anchoring off it
       instead keeps the tab flush regardless of toolbar state. No effect
       on desktop (100dvh there just equals 100vh, unaffected by any of this). */
    top: 100dvh;
    transform: translateY(-100%);
    z-index: 99996;
    display: inline-flex;
    align-items: center;
    gap: 8px;
    border: 0;
    border-radius: 10px 10px 0 0;
    /* !important: front.css's blanket `button { background-color: #edeced
       !important; }` otherwise wins and flattens this to grey — same fix
       chat/index.php's own #chat-send-btn already needed for the same rule. */
    background: var(--tmb-blue-alt) !important;
    color: #fff;
    font: inherit;
    font-size: 14px;
    font-weight: 700;
    padding: 10px 16px;
    cursor: pointer;
    text-decoration: none;
    box-shadow: 0 -6px 18px -8px color-mix(in srgb, var(--tmb-blue-alt) 45%, transparent);
    transition: opacity 0.18s ease, background 0.18s ease, box-shadow 0.18s ease;
}
#explore-fab:hover { background: var(--tmb-blue-alt-hover) !important; }
#explore-fab:focus-visible { outline: 2px solid #fff; outline-offset: 2px; }
#explore-fab, #explore-fab-label { text-decoration: none !important; }
/* Small "beta" pill after the "Explore" label, both on the collapsed FAB
   and the open panel's header title. Same orange as includes/beta-badge.php's
   .badge-beta so it reads as one beta-status system across the site. */
.explore-beta-tag {
    display: inline-block;
    background: color-mix(in srgb, var(--tmb-red), var(--tmb-chart-orange) 57%);
    color: #fff;
    font-size: 9px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    padding: 2px 6px;
    border-radius: 3px;
    line-height: 1;
    vertical-align: middle;
    margin-left: 6px;
}
/* Reuses #explore-close's own chevron icon (same SVG path) rotated to
   point up — "pull this open" — rather than a separate glyph. It's only
   ever seen in this state since the tab hides once the panel opens, so
   there's no matching "point down" state to toggle to. */
#explore-fab svg { width: 16px; height: 16px; flex-shrink: 0; transform: rotate(180deg); }
body.explore-open #explore-fab { opacity: 0; pointer-events: none; }

/* One-shot radiating pulse, plays once as the tab first paints on a fresh
   page load — draws the eye to it without nagging forever. animation-
   iteration-count defaults to 1, and fill-mode forwards holds the faded-out
   end state, so it never restarts just because the tab toggles visibility
   later (closing/reopening the panel doesn't re-trigger it). */
#explore-fab-pulse {
    position: absolute;
    inset: 0;
    border-radius: 10px 10px 0 0;
    border: 2px solid var(--tmb-blue-alt);
    pointer-events: none;
    animation: explore-fab-pulse-ring 1.5s ease-out forwards;
}
@keyframes explore-fab-pulse-ring {
    0% { opacity: 0.6; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.45); }
}

#explore-backdrop {
    position: fixed;
    inset: 0;
    background: color-mix(in srgb, var(--tmb-gray-900) 32%, transparent);
    opacity: 0;
    pointer-events: none;
    transition: opacity 0.3s ease;
    z-index: 99997;
}
body.explore-open #explore-backdrop { opacity: 1; pointer-events: auto; }
/* The whole point of popping out is to see/use the rest of the page WHILE
   the chat is open — a dimmed, click-blocking backdrop behind a floating
   window defeats that, so floating mode skips it entirely (docked mode is
   unaffected — it's still a modal-style slide-up sheet there). */
body.explore-floating #explore-backdrop { opacity: 0 !important; pointer-events: none !important; }

#explore-panel {
    position: fixed;
    left: 5%;
    right: 5%;
    bottom: 0;
    height: 82vh;
    background: #fff;
    border-radius: 16px 16px 0 0;
    box-shadow: 0 -18px 40px -12px color-mix(in srgb, var(--tmb-brand-dark) 30%, transparent);
    transform: translateY(102%);
    transition: transform 0.36s cubic-bezier(0.22, 1, 0.36, 1);
    z-index: 99998;
    display: flex;
    flex-direction: column;
    overflow: hidden;
}
body.explore-open #explore-panel { transform: translateY(0); }
body.explore-no-anim #explore-panel { transition: none; }

/* Docked mode is a modal-style slide-up sheet, so locking body scroll while
   it's open is appropriate there. Floating mode is explicitly meant to be
   used ALONGSIDE the rest of the page (dragged/resized to a spot that
   leaves whatever the admin wants to keep looking at visible), so it must
   NOT lock scroll — see the matching #explore-backdrop override below. */
body.explore-open:not(.explore-floating) { overflow: hidden; }

/* Floating mode — scripts/explore-dock.js sets explicit top/left/width/
   height inline (arbitrary, drag/resize-driven), so the docked left/right/
   bottom/height rules above need to get out of the way entirely rather than
   fight the inline styles via specificity. All four corners round (not just
   top), and the shadow reads as a normal floating window instead of the
   docked panel's upward-only glow. transform:translateY(0) still applies
   from the .explore-open rule above (open/close slide) — harmless once
   top/left are pinned by inline styles, since translateY(0) is a no-op. */
body.explore-floating #explore-panel {
    left: auto; right: auto; bottom: auto;
    border-radius: 14px;
    box-shadow: 0 12px 40px -8px color-mix(in srgb, var(--tmb-brand-dark) 35%, transparent), 0 0 0 1px var(--tmb-black-5);
    min-width: 340px;
    min-height: 360px;
}
/* The docked panel hides itself via `transform: translateY(102%)`, which
   only reliably clears the viewport because a docked panel always starts
   flush at the bottom edge — slide it down another 102% of its own height
   and it's guaranteed off-screen. A floating panel can be positioned
   anywhere (including near the top), so that same transform could leave a
   visible sliver in the wrong place while closed. Swap to opacity/pointer-
   events for floating instead, which hides correctly regardless of position. */
body.explore-floating:not(.explore-open) #explore-panel { transform: none; opacity: 0; pointer-events: none; }
body.explore-floating.explore-open #explore-panel { opacity: 1; pointer-events: auto; }
/* No slide-up transition while floating — the panel should track the
   pointer 1:1 during drag/resize, and animating position/size on every
   frame during a drag would lag behind the cursor. */
body.explore-floating #explore-panel,
body.explore-dragging #explore-panel { transition: none; }
body.explore-floating #explore-handle { display: none; }
/* Whole header becomes the drag handle (matches a native window titlebar);
   individual header buttons still get pointer-events via their own
   click handlers since mousedown-vs-click on the SAME element doesn't
   conflict — see scripts/explore-dock.js's e.target.closest('button') guard. */
/* Docked mode gets its ~19px of breathing room above the header content from
   #explore-handle (9px top padding + 4px pill + 4px bottom padding = 17px)
   sitting above .explore-panel-header's own 2px top padding. Floating mode
   hides #explore-handle entirely (the whole header IS the drag handle now,
   no separate grip needed) — without compensating here, the header content
   loses that whole 17px and sits almost flush against the panel's rounded
   top edge. Restore the same total (~19px) directly on the header's own
   padding instead. */
body.explore-floating .explore-panel-header { cursor: move; user-select: none; padding-top: 19px; }
body.explore-dragging, body.explore-resizing { cursor: inherit; }
body.explore-dragging *, body.explore-resizing * { user-select: none !important; }

/* One handle per corner — [data-handle] is "nw"/"ne"/"sw"/"se" (compass
   notation, matched in scripts/explore-dock.js by checking for 'n'/'s'/'e'/
   'w' substrings). Each sits in its own corner and gets the cursor that
   actually matches its diagonal (nw/se share one diagonal, ne/sw the
   other). Bigger hit-box (18x18) than the visible corner mark (14x14) drawn
   via ::before, so it's easy to grab without needing pixel precision. */
.explore-resize-handle {
    display: none;
    position: absolute;
    width: 18px; height: 18px;
    z-index: 1;
}
.explore-resize-handle[data-handle="nw"] { top: 0; left: 0; cursor: nwse-resize; }
.explore-resize-handle[data-handle="ne"] { top: 0; right: 0; cursor: nesw-resize; }
.explore-resize-handle[data-handle="sw"] { bottom: 0; left: 0; cursor: nesw-resize; }
.explore-resize-handle[data-handle="se"] { bottom: 0; right: 0; cursor: nwse-resize; }
/* The visible mark traces the SAME curve as the panel's own corner — sized
   14x14 with a 14px radius on the relevant corner (matching #explore-panel's
   own `border-radius: 14px` in floating mode exactly) and pinned flush to
   that corner (0,0 / top-right / etc., not inset), rather than the previous
   sharp right-angle bracket sitting a few px inside it. */
.explore-resize-handle::before {
    content: '';
    position: absolute;
    width: 14px; height: 14px;
    border-color: var(--tmb-gray-400);
    border-style: solid;
    border-width: 0;
}
.explore-resize-handle[data-handle="nw"]::before { top: 0; left: 0; border-top-width: 2px; border-left-width: 2px; border-radius: 14px 0 0 0; }
.explore-resize-handle[data-handle="ne"]::before { top: 0; right: 0; border-top-width: 2px; border-right-width: 2px; border-radius: 0 14px 0 0; }
.explore-resize-handle[data-handle="sw"]::before { bottom: 0; left: 0; border-bottom-width: 2px; border-left-width: 2px; border-radius: 0 0 0 14px; }
.explore-resize-handle[data-handle="se"]::before { bottom: 0; right: 0; border-bottom-width: 2px; border-right-width: 2px; border-radius: 0 0 14px 0; }
.explore-resize-handle:hover::before { border-color: var(--tmb-blue-alt); }
body.explore-floating .explore-resize-handle { display: block; }

/* Narrow floating window — same collapsible-history-as-overlay pattern as
   the mobile media query further down, but driven by the FLOATING PANEL's
   own rendered width (body.explore-narrow, toggled by a ResizeObserver in
   scripts/explore-dock.js) rather than the viewport width, since a floating
   window can be dragged/resized down to a narrow width at any screen size —
   the always-visible-210px-rail layout below doesn't scale down. Only ever
   applied while also .explore-floating (see the JS), so docked desktop mode
   (which has real room for the rail) is unaffected. */
body.explore-narrow #explore-history-toggle { display: inline-flex; }
body.explore-narrow #explore-panel .chat-history-panel {
    display: flex;
    position: absolute;
    inset: 0;
    width: 100%;
    z-index: 5;
    transform: translateX(-100%);
    transition: transform 0.25s ease;
}
body.explore-narrow #explore-panel.explore-history-open .chat-history-panel { transform: translateX(0); }

#explore-handle {
    display: flex;
    justify-content: center;
    padding: 9px 0 4px;
    flex-shrink: 0;
    cursor: pointer;
}
#explore-handle span { width: 36px; height: 4px; border-radius: 999px; background: var(--tmb-gray-300); }

.explore-panel-header {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 2px 18px 8px;
    flex-shrink: 0;
}
/* Feedback line under the header — same copy/links as includes/beta-badge.php's
   .beta-message so it reads as one beta-status system across the site. */
.explore-panel-subtitle {
    padding: 0 18px 10px;
    border-bottom: 1px solid var(--tmb-gray-300);
    font-size: 11px;
    color: var(--tmb-gray-600);
    line-height: 1.4;
    flex-shrink: 0;
}
.explore-panel-subtitle a { color: var(--tmb-brand-dark); font-weight: 600; text-decoration: underline; }
.explore-panel-subtitle a:hover { color: color-mix(in srgb, var(--tmb-red), var(--tmb-chart-orange) 57%); }
/* front.css's blanket `h5 { width:100%; padding-bottom:11px; background:
   linear-gradient(#ccc,#ccc) bottom left no-repeat; background-size: 33%
   1px; }` draws a partial underline under every <h5> — override all four
   of those properties, not just background, since width:100% would also
   push .chat-remaining off onto its own line. */
.explore-panel-title { font-size: 16px; font-weight: 700; letter-spacing: -0.01em; margin: 0; width: auto; padding-bottom: 0; background: none; }
.explore-panel-header .chat-remaining { margin-left: auto; white-space: nowrap; }
/* Chevron-down, not an X — this minimizes Explore (the conversation and
   scroll position are kept, see scripts/explore-dock.js's sessionStorage
   persistence), it doesn't end it, so the icon shouldn't read as "close". */
#explore-close {
    border: 0; background: var(--tmb-gray-100) !important; color: var(--tmb-gray-600) !important;
    width: 26px; height: 26px; border-radius: 50%;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    transition: background 0.15s ease, color 0.15s ease;
}
#explore-close svg { width: 15px; height: 15px; }
#explore-close:hover { background: var(--tmb-gray-300) !important; color: var(--tmb-gray-900) !important; }

/* Pop-out toggle — same visual treatment as #explore-close/#explore-history-
   toggle (grey circle, front.css !important fight). Desktop-only, hidden in
   the mobile media query below — dragging/resizing a floating window isn't
   a mobile-appropriate interaction. */
#explore-popout {
    border: 0; background: var(--tmb-gray-100) !important; color: var(--tmb-gray-600) !important;
    width: 26px; height: 26px; border-radius: 50%;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    transition: background 0.15s ease, color 0.15s ease;
}
#explore-popout svg { width: 14px; height: 14px; }
#explore-popout:hover { background: var(--tmb-gray-300) !important; color: var(--tmb-gray-900) !important; }
body.explore-floating #explore-popout { background: var(--tmb-blue-alt) !important; color: #fff !important; }

/* Hidden on desktop — the history rail is always visible there (see
   .explore-body/.chat-history-panel below). Only shown in the mobile
   media query, where that rail becomes a toggleable overlay instead. */
#explore-history-toggle {
    display: none;
    border: 0; background: var(--tmb-gray-100) !important; color: var(--tmb-gray-600) !important;
    width: 26px; height: 26px; border-radius: 50%;
    cursor: pointer;
    align-items: center; justify-content: center;
    flex-shrink: 0;
    transition: background 0.15s ease, color 0.15s ease;
}
#explore-history-toggle svg { width: 14px; height: 14px; }
#explore-history-toggle:hover { background: var(--tmb-gray-300) !important; color: var(--tmb-gray-900) !important; }
#explore-panel.explore-history-open #explore-history-toggle { background: var(--tmb-blue-alt) !important; color: #fff !important; }

.explore-body { flex: 1; display: flex; min-height: 0; position: relative; }

/* Chat log / bubbles / history / input — same rules as chat/index.php's
   inline <style>, scoped under #explore-panel instead of the page body so
   the two can coexist if /chat/ is ever visited directly while the dock's
   CSS is also loaded (admin-only page anyway, but keeps the cascade clean). */
#explore-panel .chat-history-panel { width: 210px; flex-shrink: 0; background: #fff; border: 0; border-right: 1px solid var(--tmb-gray-300); border-radius: 0; max-height: none; display: flex; flex-direction: column; }
#explore-panel .chat-history-header { padding: 10px 12px; border-bottom: 1px solid var(--tmb-gray-300); display: flex; justify-content: space-between; align-items: center; }
#explore-panel .chat-history-header h6 { margin: 0; font-size: 13px; font-weight: 600; color: var(--tmb-gray-700); width: auto; text-align: left; border-bottom: none; padding-bottom: 0; }
/* !important: real <button> elements (unlike the .chat-links/.chat-inline-
   citation <a> tags above, which front.css's button-only rule can't touch)
   all need this fight — see the FAB/Send/stop-button comments elsewhere in
   this file for the actual rule. */
#explore-panel .chat-history-new-btn { font-size: 12px; line-height: 1; font-weight: 600; padding: 4px 10px; white-space: nowrap; background: transparent !important; border: 1px solid var(--tmb-gray-400) !important; color: var(--tmb-gray-700) !important; border-radius: 4px; cursor: pointer; }
#explore-panel .chat-history-new-btn:hover { background: var(--tmb-gray-100) !important; }
#explore-panel .chat-history-list { overflow-y: auto; flex: 1; }
#explore-panel .chat-history-empty { padding: 16px 12px; font-size: 12px; color: var(--tmb-gray-600); text-align: center; }
#explore-panel .chat-history-item { padding: 8px 10px; cursor: pointer; border-bottom: 1px solid var(--tmb-gray-300); display: flex; align-items: center; gap: 6px; }
#explore-panel .chat-history-item:hover { background: var(--tmb-gray-100); }
#explore-panel .chat-history-item.active { background: var(--tmb-blue-100); }
#explore-panel .chat-history-star { cursor: pointer; color: var(--tmb-gray-400); font-size: 14px; flex-shrink: 0; }
#explore-panel .chat-history-star.starred { color: var(--tmb-yellow); }
#explore-panel .chat-history-body { flex: 1; min-width: 0; }
#explore-panel .chat-history-title { font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#explore-panel .chat-history-date { font-size: 11px; color: var(--tmb-gray-600); }
#explore-panel .chat-history-actions { display: none; gap: 6px; flex-shrink: 0; }
#explore-panel .chat-history-item:hover .chat-history-actions { display: flex; }
#explore-panel .chat-history-action { cursor: pointer; color: var(--tmb-gray-600); font-size: 12px; white-space: nowrap; }
#explore-panel .chat-history-action:hover { color: var(--tmb-red); }
#explore-panel .chat-history-action.confirming { color: var(--tmb-red); font-weight: 600; }
#explore-panel .chat-history-title-input { font-size: 13px; width: 100%; border: 1px solid var(--tmb-blue-alt); border-radius: 3px; padding: 1px 4px; }

.explore-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
#explore-panel .chat-log { flex: 1; height: auto; overflow-y: auto; padding: 16px 18px; border: 0; border-radius: 0; background: var(--tmb-gray-100); }
#explore-panel .chat-msg { margin-bottom: 14px; display: flex; }
#explore-panel .chat-msg.user { justify-content: flex-end; }
#explore-panel .chat-bubble { max-width: 78%; padding: 10px 14px; border-radius: 14px; font-size: 13.5px; line-height: 1.55; white-space: pre-wrap; }
#explore-panel .chat-msg.user .chat-bubble { background: var(--tmb-blue-alt); color: #fff; border-bottom-right-radius: 3px; }
#explore-panel .chat-msg.assistant .chat-bubble { background: #fff; color: var(--tmb-gray-900); border: 1px solid var(--tmb-gray-300); border-bottom-left-radius: 3px; }
#explore-panel .chat-bubble .chat-section-header { display: block; margin-top: 10px; font-size: 12.5px; text-transform: uppercase; letter-spacing: 0.02em; color: var(--tmb-gray-700); }
#explore-panel .chat-bubble .chat-section-header:first-child { margin-top: 0; }
#explore-panel .chat-table-wrap { overflow-x: auto; margin: 8px 0; -webkit-overflow-scrolling: touch; }
#explore-panel .chat-table { border-collapse: collapse; font-size: 12.5px; white-space: nowrap; }
#explore-panel .chat-table th, #explore-panel .chat-table td { padding: 5px 10px; border-bottom: 1px solid var(--tmb-gray-300); text-align: left; }
#explore-panel .chat-table th { font-size: 11px; text-transform: uppercase; letter-spacing: 0.02em; color: var(--tmb-gray-600); font-weight: 600; border-bottom: 1px solid var(--tmb-gray-300); }
#explore-panel .chat-table tr:last-child td { border-bottom: 0; }
#explore-panel .chat-table td.chat-table-num { text-align: right; font-variant-numeric: tabular-nums; }
#explore-panel .chat-table-chart { margin: 10px 0 4px; padding: 10px 12px; background: var(--tmb-gray-100); border: 1px solid var(--tmb-blue-100); border-radius: 8px; }
#explore-panel .chat-table-chart-title { font-size: 11px; text-transform: uppercase; letter-spacing: 0.02em; color: var(--tmb-gray-600); font-weight: 600; margin-bottom: 8px; }
#explore-panel .chat-chart-row { display: flex; align-items: center; gap: 8px; margin-bottom: 5px; }
#explore-panel .chat-chart-row:last-child { margin-bottom: 0; }
#explore-panel .chat-chart-label { flex: 0 0 34%; font-size: 12px; color: var(--tmb-gray-700); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#explore-panel .chat-chart-track { flex: 1 1 auto; background: var(--tmb-blue-50); border-radius: 4px; height: 12px; overflow: hidden; }
#explore-panel .chat-chart-bar { height: 100%; background: var(--tmb-blue-alt); border-radius: 4px; }
#explore-panel .chat-chart-bar.negative { background: var(--tmb-red); }
#explore-panel .chat-chart-value { flex: 0 0 auto; font-size: 11.5px; color: var(--tmb-gray-700); font-variant-numeric: tabular-nums; min-width: 44px; text-align: right; }
#explore-panel .chat-inline-citation { color: var(--tmb-blue-alt); text-decoration: none; border-bottom: 1px dotted var(--tmb-blue-alt); cursor: pointer; }
#explore-panel .chat-inline-citation:hover { text-decoration: none; border-bottom-style: solid; }
#explore-panel .chat-links { margin-top: 8px; display: flex; flex-wrap: wrap; gap: 6px; }
#explore-panel .chat-links a { font-size: 11.5px; padding: 4px 10px; border-radius: 12px; background: var(--tmb-blue-100); color: var(--tmb-blue-alt); text-decoration: none; border: 1px solid var(--tmb-blue-200); cursor: pointer; }
#explore-panel .chat-links a:hover { background: var(--tmb-blue-200); }
#explore-panel .chat-suggestions { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 6px; }
#explore-panel .chat-suggestion-chip { font: inherit; font-size: 12px; padding: 6px 12px; border-radius: 14px; background: #fff !important; color: var(--tmb-blue-alt) !important; border: 1px solid var(--tmb-blue-alt); cursor: pointer; transition: background 0.15s ease, color 0.15s ease; }
#explore-panel .chat-suggestion-chip:hover { background: var(--tmb-blue-alt) !important; color: #fff !important; }
#explore-panel .chat-suggestion-hint { opacity: 0.55; font-size: 11px; margin-left: 3px; }
/* "Save as system" under a reply whose query ran (explore-dock.js). The
   bubble is pre-wrap, so the block resets it. !important on the buttons for
   front.css's blanket button rule, as on the chips above. */
#explore-panel .chat-save-system { margin-top: 10px; white-space: normal; }
#explore-panel .chat-save-system-btn { font: inherit; font-size: 12px; font-weight: 600; padding: 6px 12px; border-radius: 14px; background: var(--tmb-blue-alt) !important; color: #fff !important; border: 1px solid var(--tmb-blue-alt); cursor: pointer; margin-bottom: 0 !important; }
#explore-panel .chat-save-system-btn:hover { background: var(--tmb-blue-800) !important; border-color: var(--tmb-blue-800); }
#explore-panel .chat-save-which { margin-left: 8px; font-size: 11.5px; color: var(--tmb-gray-600); font-family: monospace; overflow-wrap: anywhere; }
#explore-panel .chat-save-form { margin-top: 8px; padding: 10px; background: var(--tmb-gray-100); border: 1px solid var(--tmb-gray-300); border-radius: 8px; display: flex; flex-direction: column; gap: 6px; }
#explore-panel .chat-save-form[hidden] { display: none; }
#explore-panel .chat-save-row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
#explore-panel .chat-save-form input, #explore-panel .chat-save-form select { font: inherit; font-size: 12.5px; height: 30px; box-sizing: border-box; padding: 0 8px; border: 1px solid var(--tmb-gray-400); border-radius: 4px; background: #fff; color: var(--tmb-gray-900); margin: 0; width: auto; }
#explore-panel .chat-save-form input { flex: 1 1 140px; min-width: 0; }
#explore-panel .chat-save-form input:focus, #explore-panel .chat-save-form select:focus { outline: 2px solid var(--tmb-blue-alt); outline-offset: 1px; }
#explore-panel .chat-save-form .chat-save-syntax { font-family: monospace; font-size: 12px; }
#explore-panel .chat-save-league { font-size: 11px; font-weight: 700; letter-spacing: 0.02em; color: var(--tmb-gray-700); background: #fff; border: 1px solid var(--tmb-gray-300); border-radius: 4px; padding: 0 7px; height: 30px; line-height: 28px; box-sizing: border-box; }
#explore-panel .chat-save-submit, #explore-panel .chat-save-cancel { font: inherit; font-size: 12px; font-weight: 600; height: 30px; box-sizing: border-box; padding: 0 14px; border-radius: 4px; cursor: pointer; margin-bottom: 0 !important; }
#explore-panel .chat-save-submit { background: var(--tmb-gray-700) !important; color: #fff !important; border: 1px solid var(--tmb-gray-700); }
#explore-panel .chat-save-submit:disabled { opacity: 0.5; cursor: default; }
#explore-panel .chat-save-cancel { background: transparent !important; color: var(--tmb-gray-700) !important; border: 1px solid var(--tmb-gray-400); }
#explore-panel .chat-save-cancel:hover { background: #fff !important; }
#explore-panel .chat-save-msg:empty { display: none; }
#explore-panel .chat-save-msg { font-size: 12px; }
#explore-panel .chat-save-error { color: var(--tmb-red); }
#explore-panel .chat-save-done { margin-top: 8px; padding: 8px 10px; font-size: 12.5px; background: var(--tmb-success-bg); border: 1px solid var(--tmb-green-300); border-radius: 8px; color: var(--tmb-gray-900); }
#explore-panel .chat-save-done a { color: var(--tmb-blue-alt); text-decoration: none; border-bottom: 1px dotted var(--tmb-blue-alt); }
#explore-panel .chat-save-done a:hover { border-bottom-style: solid; }
#explore-panel .chat-save-note { margin-top: 4px; color: var(--tmb-gray-700); }
#explore-panel .chat-typing { color: var(--tmb-gray-600); font-size: 13px; font-style: italic; animation: explore-typing-pulse 1.4s ease-in-out infinite; }
@keyframes explore-typing-pulse { 0%, 100% { opacity: 0.35; } 50% { opacity: 1; } }
#explore-panel .chat-cursor { display: inline-block; width: 2px; height: 0.95em; background: var(--tmb-blue-alt); margin-left: 1px; vertical-align: text-bottom; animation: explore-cursor-blink 1s steps(1) infinite; }
@keyframes explore-cursor-blink { 0%, 49% { opacity: 1; } 50%, 100% { opacity: 0; } }
/* !important throughout — same front.css blanket `button { background-color:
   #edeced !important; margin-bottom: 3px !important; }` rule the FAB and
   Send button need to fight (see those two above); chat/index.php's own
   version of this button already needed the same treatment. */
#explore-panel .chat-stop-btn {
    display: inline-flex; align-items: center; justify-content: center;
    width: 26px; height: 26px; border-radius: 5px;
    background: var(--tmb-red) !important; border: 1px solid var(--tmb-red) !important; color: #fff !important;
    cursor: pointer; flex-shrink: 0; margin: 0 0 0 8px !important; align-self: center; padding: 0;
    transition: background 0.15s ease, border-color 0.15s ease;
}
#explore-panel .chat-stop-btn:hover { background: var(--tmb-red-700) !important; border-color: var(--tmb-red-700) !important; }
#explore-panel .chat-stop-btn svg { width: 12px; height: 12px; }

.explore-input-row { border-top: 1px solid var(--tmb-gray-300); padding: 12px 18px 16px; background: #fff; flex-shrink: 0; }
.explore-input-row .explore-input-inner { display: flex; align-items: center; gap: 8px; }
#explore-input {
    flex: 1; font: inherit; font-size: 13.5px; height: 38px; box-sizing: border-box;
    padding: 0 14px; border: 1px solid var(--tmb-gray-300); border-radius: 999px; background: var(--tmb-gray-100); color: var(--tmb-gray-900);
}
#explore-input:focus { outline: 2px solid var(--tmb-blue-alt); outline-offset: 1px; }
#explore-send-btn {
    font: inherit; font-size: 13px; font-weight: 700; height: 38px; box-sizing: border-box;
    /* !important for the same reason #explore-fab needs it above — front.css's
       blanket button rule otherwise wins. */
    background: var(--tmb-gray-700) !important; color: #fff; border: 0; border-radius: 999px; padding: 0 20px; cursor: pointer;
}
#explore-send-btn:hover:not(:disabled) { background: var(--tmb-gray-700) !important; }
#explore-send-btn:disabled { opacity: 0.5; cursor: default; }
.explore-error { color: var(--tmb-red); font-size: 13px; margin-top: 6px; }
.explore-remaining { font-size: 11px; color: var(--tmb-gray-600); }

/* Same-page citation-scroll highlight — see scripts/explore-dock.js and
   scripts/matchup-init.js's hash-scroll handler. */
.tmb-explore-highlight {
    animation: tmb-explore-flash 1.8s ease-out 1;
    border-radius: 6px;
}
@keyframes tmb-explore-flash {
    0% { background-color: color-mix(in srgb, var(--tmb-blue-alt) 16%, transparent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--tmb-blue-alt) 28%, transparent); }
    100% { background-color: transparent; box-shadow: 0 0 0 3px color-mix(in srgb, var(--tmb-blue-alt) 0%, transparent); }
}

/* ---------------------------------------------------------------
   Snap to a side (since 2026-10-08): the floating window at full height
   against the left or right edge, under the site's fixed header, OVER the
   page (the page keeps its width). body.explore-snap-left / -right ride on
   body.explore-floating; the rect itself is inline, from snapRect() in
   scripts/explore-dock.js. The corner grips give way to one grip, the
   inner edge, which sets the width.
   --------------------------------------------------------------- */
#explore-instructions-toggle, #explore-snap {
    border: 0; background: var(--tmb-gray-100) !important; color: var(--tmb-gray-600) !important;
    width: 26px; height: 26px; border-radius: 50%;
    cursor: pointer;
    display: flex; align-items: center; justify-content: center;
    flex-shrink: 0;
    transition: background 0.15s ease, color 0.15s ease;
}
#explore-instructions-toggle svg, #explore-snap svg { width: 14px; height: 14px; }
#explore-instructions-toggle:hover, #explore-snap:hover { background: var(--tmb-gray-300) !important; color: var(--tmb-gray-900) !important; }
#explore-panel.explore-instructions-open #explore-instructions-toggle,
body.explore-snap-left #explore-snap, body.explore-snap-right #explore-snap { background: var(--tmb-blue-alt) !important; color: #fff !important; }
/* The icon shows the side the click sends the window to: snapped left,
   that is the right. */
body.explore-snap-left #explore-snap svg { transform: scaleX(-1); }
/* A snapped window is not floating free: the pop-out button reads as it
   does docked (its click docks the window back to the bottom). */
body.explore-snap-left #explore-popout, body.explore-snap-right #explore-popout { background: var(--tmb-gray-100) !important; color: var(--tmb-gray-600) !important; }

body.explore-snap-left #explore-panel, body.explore-snap-right #explore-panel { border-radius: 0; min-height: 0; }
body.explore-snap-left #explore-panel { box-shadow: 6px 0 24px -10px color-mix(in srgb, var(--tmb-brand-dark) 35%, transparent), 0 0 0 1px var(--tmb-black-5); }
body.explore-snap-right #explore-panel { box-shadow: -6px 0 24px -10px color-mix(in srgb, var(--tmb-brand-dark) 35%, transparent), 0 0 0 1px var(--tmb-black-5); }
body.explore-snap-left .explore-resize-handle, body.explore-snap-right .explore-resize-handle { display: none; }
.explore-snap-edge { display: none; position: absolute; top: 0; bottom: 0; width: 7px; cursor: col-resize; z-index: 6; }
.explore-snap-edge:hover, body.explore-dragging .explore-snap-edge { background: color-mix(in srgb, var(--tmb-blue-alt) 35%, transparent); }
body.explore-snap-left .explore-snap-edge { display: block; right: 0; }
body.explore-snap-right .explore-snap-edge { display: block; left: 0; }

/* The page beside a snapped, open window: syncPageShift() hands the side and
   width to TMB.pageShift (scripts/tmb-common.js), and the rules that move
   the body and its fixed chrome are styles/page-shift.css (body.tmb-shift,
   --tmb-shift-left / -right), shared with the admin Write-up popup since
   2026-10-08. A new fixed element of the page gets its rule THERE. */

/* The header in a narrow window (a snapped panel is one): the count alone,
   "23/25", without its words. */
body.explore-narrow .explore-remaining-words { display: none; }
body.explore-narrow .explore-panel-header { gap: 7px; padding-left: 14px; padding-right: 14px; }
body.explore-narrow .explore-panel-subtitle { padding-left: 14px; padding-right: 14px; }

/* ---------------------------------------------------------------
   Notes box and "My instructions" (since 2026-10-08). The buttons fight
   front.css's blanket button rule like every other one in this file.
   --------------------------------------------------------------- */
.explore-main { position: relative; }
#explore-panel .explore-text-btn {
    font: inherit; font-size: 12px; font-weight: 600; line-height: 1; padding: 5px 4px; margin: 0 !important;
    background: transparent !important; border: 0; color: var(--tmb-gray-600) !important; cursor: pointer; white-space: nowrap;
}
#explore-panel .explore-text-btn:hover { color: var(--tmb-gray-900) !important; text-decoration: underline; }
#explore-panel .explore-solid-btn {
    font: inherit; font-size: 12.5px; font-weight: 700; line-height: 1; height: 30px; padding: 0 16px; margin: 0 !important;
    background: var(--tmb-gray-700) !important; color: #fff !important; border: 0; border-radius: 999px; cursor: pointer; white-space: nowrap;
}
#explore-panel .explore-solid-btn:disabled { opacity: 0.5; cursor: default; }
#explore-panel .explore-count { font-size: 11px; color: var(--tmb-gray-600); font-variant-numeric: tabular-nums; white-space: nowrap; }
#explore-panel .explore-count.is-full { color: var(--tmb-red); font-weight: 600; }

#explore-notes-toggle {
    font: inherit; font-size: 12.5px; font-weight: 600; height: 38px; box-sizing: border-box; padding: 0 13px; margin: 0 !important;
    background: #fff !important; color: var(--tmb-gray-700) !important; border: 1px solid var(--tmb-gray-400); border-radius: 999px;
    cursor: pointer; white-space: nowrap; flex-shrink: 0;
}
#explore-notes-toggle:hover { background: var(--tmb-gray-100) !important; }
/* The message box gives way to the button beside it: an <input> will not
   shrink under its default width without this, and on a phone or in a
   snapped panel the row then runs past the Send button's margin. */
.explore-input-row #explore-input { min-width: 0; }
/* The box holds notes: they go out with the next message. */
#explore-notes-toggle.has-notes { background: var(--tmb-blue-100) !important; color: var(--tmb-blue-alt) !important; border-color: var(--tmb-blue-alt); }
#explore-notes-toggle.has-notes::after { content: ' on'; }

.explore-notes { margin-bottom: 10px; }
.explore-notes[hidden], .explore-instructions-panel[hidden] { display: none !important; }
.explore-notes-head { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 14px; margin-bottom: 6px; }
#explore-panel .explore-notes-title { font-size: 12.5px; font-weight: 700; color: var(--tmb-gray-900); margin: 0; }
.explore-notes-modes { display: flex; flex-wrap: wrap; gap: 2px 12px; }
#explore-panel .explore-notes-modes label { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 400; color: var(--tmb-gray-700); margin: 0; cursor: pointer; white-space: nowrap; }
#explore-panel .explore-notes-modes input { margin: 0; width: auto; accent-color: var(--tmb-blue-alt); }
#explore-notes-text, #explore-instructions-text {
    display: block; width: 100%; box-sizing: border-box; font: inherit; font-size: 13px; line-height: 1.45;
    padding: 9px 12px; border: 1px solid var(--tmb-gray-300); border-radius: 10px; background: var(--tmb-gray-100); color: var(--tmb-gray-900);
    resize: vertical;
}
#explore-notes-text { height: 104px; min-height: 60px; max-height: 40vh; }
#explore-notes-text:focus, #explore-instructions-text:focus { outline: 2px solid var(--tmb-blue-alt); outline-offset: 1px; }
.explore-notes-foot, .explore-instructions-foot { display: flex; align-items: center; gap: 10px; margin-top: 5px; }
.explore-notes-hint, .explore-instructions-status { flex: 1; min-width: 0; font-size: 11px; line-height: 1.35; color: var(--tmb-gray-600); }
.explore-instructions-status.is-error { color: var(--tmb-red); }
.explore-instructions-status.is-ok { color: var(--tmb-green-700); }

/* Over the chat log and the input row, inside .explore-main: the history
   rail (desktop) stays where it is. */
.explore-instructions-panel {
    position: absolute; inset: 0; z-index: 4;
    display: flex; flex-direction: column;
    padding: 14px 18px 16px; background: #fff;
}
.explore-instructions-head { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 6px; }
#explore-panel .explore-instructions-head h6 { margin: 0; font-size: 14px; font-weight: 700; color: var(--tmb-gray-900); width: auto; text-align: left; border-bottom: none; padding-bottom: 0; }
#explore-panel .explore-instructions-help { margin: 0 0 10px; font-size: 12px; line-height: 1.45; color: var(--tmb-gray-600); }
#explore-instructions-text { flex: 1; min-height: 90px; resize: none; }

/* A user message's notes, folded under it. */
#explore-panel .chat-notes-attached { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--tmb-white-30); font-size: 12.5px; }
#explore-panel .chat-notes-attached summary { cursor: pointer; font-weight: 600; font-size: 12px; opacity: 0.9; }
#explore-panel .chat-notes-attached .chat-notes-body { margin-top: 6px; white-space: pre-wrap; opacity: 0.95; }

@media (max-width: 767px) {
    /* Explicit top instead of height:100dvh + implicit top:0 — the site's
       own .header is position:fixed, height:60px !important (front.css,
       same 767px breakpoint) at a much lower z-index, so in principle the
       panel's z-index already covers it regardless of top; relying on that
       leaves the gap above the panel to whatever 100dvh happens to resolve
       to on a given mobile browser's dynamic toolbar, which isn't reliably
       0. Pinning top explicitly (60px header + 10px breathing room) fixes
       the actual gap regardless of that per-device inconsistency. */
    /* !important: overrides floating mode's inline top/left/width/height (a
       genuine specificity fight, not just cascade order — inline styles set
       by scripts/explore-dock.js otherwise always win) in case a floating
       session's saved state is somehow reopened at a mobile width; the JS
       also proactively re-docks below this breakpoint (see isDesktop()). */
    /* height:auto (a real bug, not a floating-mode leftover) let the panel
       grow to fit however much conversation content existed instead of
       being capped to the viewport: #explore-panel is `display:flex;
       flex-direction:column` with .explore-body as a `flex:1` child, and
       flex-grow has NO effect when the container's own height is auto
       (shrink-to-fit) — there's no extra space to distribute. So instead of
       the intended fixed-height panel with an internally scrolling chat log
       (.chat-log already has its own overflow-y:auto), the WHOLE PANEL just
       kept growing taller than the screen as messages accumulated, while
       body scroll stayed locked (`body.explore-open { overflow:hidden }`) —
       reads exactly like "a floating area blocking the page that can't be
       minimized" even though the close button itself was working the whole
       time; a few screens' worth of un-scrollable overflow made it look and
       feel stuck regardless. dvh (not vh) tracks the mobile browser's
       dynamic toolbar live — same reasoning as #explore-fab's own top:100dvh
       elsewhere in this file. */
    /* Flush against the site's own sticky header (60px, front.css) — no gap.
       An earlier version left a deliberate 10px of breathing room here
       (top:70px), but a `position:fixed` panel with empty space above it
       shows the scrolling page underneath through that gap as a visible
       seam the instant the background page scrolls, which read as a visual
       glitch rather than intentional spacing. .explore-panel-header gets
       its own top padding below to compensate (see the mobile-specific rule
       further down) so the title/icons still get breathing room — the
       panel's outer edge is what needed to go flush, not its content. */
    #explore-panel { left: 0 !important; right: 0 !important; top: 60px !important; bottom: auto !important; width: auto !important; height: calc(100dvh - 60px) !important; border-radius: 0; box-shadow: none; }
    #explore-handle { display: none; }
    #explore-popout { display: none; }
    #explore-snap { display: none; }
    .explore-snap-edge { display: none !important; }
    .explore-resize-handle { display: none !important; }
    /* The count without its words, as in a narrow floating window: the
       header holds one more button than it did. */
    .explore-remaining-words { display: none; }
    body.explore-floating .explore-panel-header { cursor: default; }
    /* #explore-handle (the little drag-pill above the header) is hidden on
       mobile too, same as floating mode — same fix, same reasoning as
       body.explore-floating .explore-panel-header's own padding-top above:
       without it the title/icons would sit almost flush against the
       panel's now-square top edge. */
    .explore-panel-header { padding-top: 19px; }
    #explore-history-toggle { display: inline-flex; }
    /* No longer just hidden — the history rail was previously display:none
       here with no other way to reach it at all (a real gap: there was no
       substitute access point). Now a full-width overlay toggled by
       #explore-history-toggle in the header, sliding in over the chat log
       rather than squeezing beside it (no room for a 210px side rail on a
       phone-width screen). */
    #explore-panel .chat-history-panel {
        display: flex;
        position: absolute;
        inset: 0;
        width: 100%;
        z-index: 5;
        transform: translateX(-100%);
        transition: transform 0.25s ease;
    }
    #explore-panel.explore-history-open .chat-history-panel { transform: translateX(0); }
    /* Backdrop was still inset:0 (full viewport) even after the panel itself
       moved down to top:60px — it dimmed that whole strip above the panel
       too, so what should've read as plain page background (light grey)
       came through as dark instead. Only dim from where the panel actually
       starts — kept in sync with #explore-panel's own top above. */
    #explore-backdrop { top: 60px; }
    /* Real device gap below a plain `bottom:0` fixed element is a known
       mobile-browser issue (home-indicator / gesture-nav safe areas, and
       inconsistent handling of the dynamic address-bar viewport) — extend
       the tab's own box into that inset with padding rather than leaving it
       as a transparent gap below the tab. env() resolves to 0 and this is a
       no-op on devices/browsers without a bottom safe area. */
    #explore-fab { padding-bottom: calc(10px + env(safe-area-inset-bottom, 0px)); }
}

/* A phone turned sideways (body.explore-phone, set by the script for a
   touch-first device whose short side is under 600px) is wider than the
   phone breakpoint above, so none of that block applies to it: without this
   the panel is the desktop's sheet, 90% of the screen wide and 82% of its
   390px high. Explore is full screen on a phone in either orientation
   (Zach, 2026-10-08), under the header, which is the desktop's 70px at this
   width. The script gives a phone no pop-out and no snap; the history rail
   has room here (a phone in landscape is 660px wide at least) and stays. */
@media (min-width: 768px) {
    body.explore-phone #explore-panel { left: 0 !important; right: 0 !important; top: 70px !important; bottom: auto !important; width: auto !important; height: calc(100dvh - 70px) !important; border-radius: 0; box-shadow: none; }
    body.explore-phone #explore-handle { display: none; }
    body.explore-phone .explore-panel-header { padding-top: 19px; }
    body.explore-phone #explore-backdrop { top: 70px; }
    body.explore-phone #explore-popout, body.explore-phone #explore-snap { display: none; }
    body.explore-phone .explore-resize-handle, body.explore-phone .explore-snap-edge { display: none !important; }
}

@media (prefers-reduced-motion: reduce) {
    #explore-panel, #explore-fab, #explore-backdrop { transition: none !important; }
}
