/* MapTrax v2.13.0.0 — VS Code-style app shell (Phase 1: scaffolding).
 *
 * Provides a 3-column grid below the toolbar:
 *   1. Activity rail   — icon strip that toggles docked panels (Phase 2+)
 *   2. Dock panel slot — holds Map Controls / Assets / etc. when docked
 *   3. Main column     — existing #main-container (map + attribute table)
 *
 * Phase 1 is pure scaffolding. The rail and dock are inert and hidden, so
 * the grid collapses to `0px 0px 1fr` and renders identically to the
 * pre-shell layout. Subsequent phases will:
 *   - Phase 2: populate the rail with toggle buttons and migrate Map
 *              Controls into the dock with a float ↔ dock mode switch.
 *   - Phase 3: migrate the Assets panel into the same dock slot.
 *   - Phase 4: drag-to-resize divider, persistence, keyboard shortcuts.
 *
 * Floating panels (#sidebar-controls, #info-panel, #assets-panel,
 * #quarter-editor) remain positioned against the viewport. They sit
 * above the shell exactly as today, with no z-index changes needed.
 */

:root {
    /* Phase 1: 0px keeps the shell invisible. Phase 2 will set
     * --shell-rail-width to ~40px and --shell-dock-width to a per-panel
     * value (typically 280-380px) when a panel is docked open. */
    --shell-rail-width: 0px;
    --shell-dock-width: 0px;
    --shell-toolbar-height: 60px;
}

.app-shell {
    position: fixed;
    top: var(--shell-toolbar-height);
    left: 0;
    right: 0;
    bottom: 0;
    display: grid;
    grid-template-columns: var(--shell-rail-width)
                           var(--shell-dock-width)
                           1fr;
    grid-template-rows: 1fr;
    overflow: hidden;
    /* No z-index: floating .map-overlay panels (z-index:1) overlay the
     * shell exactly as they overlay #main-container today. */
}

.activity-rail {
    grid-column: 1;
    grid-row: 1;
    background: var(--primary);
    border-right: 1px solid var(--chrome-border);
    overflow: hidden;
}

.activity-rail[hidden] { display: none !important; }

.dock-panel {
    grid-column: 2;
    grid-row: 1;
    background: #fff;
    border-right: 1px solid var(--border-strong);
    box-shadow: 1px 0 4px rgba(0, 0, 0, 0.06);
    overflow: hidden;
}

.dock-panel[hidden] { display: none !important; }

/* Main column: override the legacy `position: fixed` from
 * attribute-table.css so the grid can place it. The interior layout
 * (flex column with #map-container + .divider + #attribute-drawer) is
 * unchanged — #map-container still uses position:relative as a
 * containing block for the absolutely-positioned #map child. */
.app-shell #main-container {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    bottom: auto;
    grid-column: 3;
    grid-row: 1;
    height: 100%;
}

/* === Phase 2 (v2.13.1.0): activity rail + docked Map Controls === */

.activity-rail {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    padding: 6px 0;
    gap: 2px;
    background: var(--primary);
    border-right: 1px solid var(--chrome-border);
}

.rail-btn {
    background: transparent;
    border: 0;
    color: var(--chrome-text-muted);
    height: 36px;
    cursor: pointer;
    font-size: 16px;
    line-height: 1;
    padding: 0;
    transition: background 0.15s, color 0.15s, border-left-color 0.15s;
    border-left: 3px solid transparent;
    display: flex;
    align-items: center;
    justify-content: center;
}

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

.rail-btn.active {
    background: rgba(255, 255, 255, 0.14);
    color: #fff;
    border-left-color: var(--gold);
}

/* Working Interest entry (js/wi/railButton.js): a navigation action, not a
   panel toggle. Pinned to the rail's bottom and divided from the toggles
   above so it reads as a separate "open the WI page" affordance. */
.rail-btn.wi-rail-btn {
    margin-top: auto;
    height: 42px;
    border-top: 1px solid rgba(255, 255, 255, 0.14);
}

/* WI New sandbox entry (js/wi-new/railButton.js): stacks directly beneath the
   WI button at the rail's bottom. No margin-top:auto (a second auto would split
   the pair apart) and no top divider (it's grouped with the WI button above). */
.rail-btn.wi-new-rail-btn {
    height: 42px;
}

/* Docked panel: when #sidebar-controls is moved into #dock-panel, it
 * fills the dock cell. We override the floating-mode positioning so
 * the panel renders edge-to-edge inside the dock with a normal scroll
 * (the floating panel's collapse-via-translateX does NOT apply here —
 * collapse in dock mode is handled by --shell-dock-width: 0px). */
#sidebar-controls.docked {
    position: relative !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    width: 100%;
    max-width: 100%;
    height: 100%;
    margin: 0;
    border-radius: 0;
    box-shadow: none;
    transform: none !important;
    overflow-y: auto;
    padding: 12px 14px;
}

/* The floating-mode chevron (stuck to the right edge via right:-30px)
 * is meaningless when docked — the rail icon takes over collapse duty. */
#sidebar-controls.docked .sidebar-toggle {
    display: none;
}

/* Header row inside Map Controls (injected by dockManager): existing
 * h3 plus a Float / Dock toggle button. Layout matches the panel's
 * 8px content rhythm. */
.controls-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}

.controls-header h3 {
    margin: 0;
}

.dock-toggle-btn {
    /* v2.13.2.19: solid white fill so the Float/Dock button reads
     * cleanly on either the light Map Controls header (almost
     * white) or the dark Assets / Layers headers (brown gradient).
     * Was transparent + brown text, which disappeared on the
     * brown headers. */
    background: #fff;
    border: 1px solid var(--border-strong);
    color: var(--text-primary);
    border-radius: 4px;
    padding: 4px 8px;
    cursor: pointer;
    font-size: 11px;
    font-weight: 600;
    line-height: 1;
    white-space: nowrap;
    transition: background 0.15s, color 0.15s, border-color 0.15s;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.12);
}

.dock-toggle-btn:hover {
    background: var(--bg-tertiary);
    color: var(--text-primary);
    border-color: var(--ink-300);
}

/* === Phase 3 (v2.13.2.0): Assets panel docking + permanent rail === */

/* Mirrors #sidebar-controls.docked but with Assets-specific overrides:
 *   - `display: flex !important` defeats the legacy auto-hide-when-empty
 *     behavior (assetSidebar.js sets style.display='none' when there are
 *     zero assets). In docked mode the dock cell controls visibility via
 *     --shell-dock-width, not via the panel's own display.
 *   - Internal layout stays flex-column so the existing header/body
 *     structure renders correctly inside the dock cell.
 */
#assets-panel.docked {
    position: relative !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    width: 100% !important;
    max-width: 100% !important;
    height: 100%;
    margin: 0;
    border-radius: 0;
    box-shadow: none;
    transform: none !important;
    overflow: hidden;
    display: flex !important;
    flex-direction: column;
    /* Reset the floating-mode z-index:850 from asset-detail.css so
     * the dock-panel's resize handle (z-index:10) sits above the
     * panel content and is reachable. */
    z-index: auto !important;
}

/* Right-edge drag handle is meaningless inside the fixed-width dock —
 * the existing handler would write panel.style.width and break the
 * grid layout. Hidden via CSS; mousedown listener never fires. */
#assets-panel.docked .assets-panel-resize {
    display: none;
}

/* Legacy collapse chevron (the `<` button in the panel header) is
 * redundant when docked — the rail icon owns collapse duty. Hide it
 * along with the wrap-names chevron is intentionally NOT hidden
 * because name-wrapping is still useful inside the dock. */
#assets-panel.docked .assets-panel-collapse {
    display: none;
}

/* The legacy .collapsed rule narrows the floating panel to 44px
 * (rail style). In docked mode collapse is conveyed by the dock cell
 * shrinking to 0px (--shell-dock-width:0), so we neutralize the
 * width override here. */
#assets-panel.docked.collapsed {
    width: 100% !important;
}
#assets-panel.docked.collapsed .assets-panel-body,
#assets-panel.docked.collapsed .assets-panel-title,
#assets-panel.docked.collapsed .assets-panel-wrap {
    /* Defeat the legacy "hide everything when collapsed" rules — when
     * docked, we want the panel rendered at full size; the cell width
     * is what hides it. */
    display: revert;
}

/* Drag-to-resize handle on the right edge of the dock cell. Hidden
 * naturally when #dock-panel has the `hidden` attribute. The handle is
 * an absolute child of #dock-panel (which we set position:relative
 * dynamically in dockManager). 4px wide, full height, transparent
 * by default with a subtle hover hint. */
.dock-resize-handle {
    position: absolute;
    top: 0;
    right: -2px;       /* sit right on the boundary so it's grabbable */
    width: 4px;
    height: 100%;
    cursor: ew-resize;
    /* High enough to beat any panel content (Assets has z-index:850
     * in floating mode and creates a stacking context the handle
     * needs to clear). */
    z-index: 1000;
    background: transparent;
    transition: background 0.12s;
}

.dock-resize-handle:hover,
.dock-resize-handle:active {
    background: color-mix(in srgb, var(--gold, #c9a962) 45%, transparent);
}

/* When two docked panels coexist as siblings inside #dock-panel, hide
 * the one that's currently collapsed via `.dock-hidden` (set by
 * dockManager.updateChrome). Specificity matches the docked rules
 * above so this `display: none` wins. */
#sidebar-controls.docked.dock-hidden,
#assets-panel.docked.dock-hidden,
#prospects-panel.docked.dock-hidden,
#inactive-prospects-panel.docked.dock-hidden,
#worklists-panel.docked.dock-hidden {
    display: none !important;
}

/* v2.13.15.3 + v2.13.15.10: floating-mode hide for rail-inactive
   panels. dockManager adds `.float-hidden` (instead of `.collapsed`
   so the user's manual collapse button can still show the 44px tab
   without phantom tabs piling up at the rail edge when switching
   panels via the rail).

   v2.13.15.10 — user feedback: panels used to slide under the rail
   on switch; the v2.13.15.3 fix replaced that with display:none and
   they started snap-vanishing. Re-introduce the slide: the float-
   hidden state translates left off-screen + fades out, the visible
   state translates back in. pointer-events:none while hidden so the
   off-screen panel doesn't catch clicks during the animation. */
#sidebar-controls:not(.docked),
#assets-panel:not(.docked),
#prospects-panel:not(.docked),
#inactive-prospects-panel:not(.docked),
#worklists-panel:not(.docked),
#layers-panel:not(.docked) {
    /* Visibility flips back instantly on show (no delay), so the panel
       re-enters the a11y tree as soon as it starts sliding in. */
    transition: transform 220ms ease, opacity 220ms ease, visibility 0s 0s;
    transform: translateX(0);
    opacity: 1;
    visibility: visible;
}
#sidebar-controls.float-hidden,
#assets-panel.float-hidden,
#prospects-panel.float-hidden,
#inactive-prospects-panel.float-hidden,
#worklists-panel.float-hidden,
#layers-panel.float-hidden {
    /* Slide the panel left under the rail. The extra rail-width offset
       guarantees the panel's right edge clears the rail strip, so it
       fully disappears behind the rail icons. */
    transform: translateX(calc(-100% - var(--shell-rail-width, 40px) - 20px));
    opacity: 0;
    pointer-events: none;
    /* v2.13.15.11 (PR #92 P2): visibility:hidden drops the off-screen
       panel out of the tab order + accessibility tree, so Tab key and
       screen readers don't reach invisible controls. The 220ms delay
       on visibility waits for the slide to finish before hiding (so
       the slide-out animation still plays); on slide-in the rule
       above flips visibility back instantly. */
    visibility: hidden;
    transition: transform 220ms ease, opacity 220ms ease, visibility 0s 220ms;
}

/* v2.13.14.9 (PR #81 review): when prospects-panel / inactive-prospects-
   panel are docked, inherit the same layout the assets-panel uses —
   they share the .assets-panel class so most rules already apply, but
   dockManager toggles .docked on the panel root which needs the same
   sizing/position selectors as #assets-panel.docked.
   v1.6.0.0: worklists-panel joins the same family (PR #33 review). */
#prospects-panel.docked,
#inactive-prospects-panel.docked,
#worklists-panel.docked {
    position: relative;
    top: auto;
    left: auto;
    right: auto;
    bottom: auto;
    width: 100%;
    height: 100%;
    max-height: none;
    min-width: 0;
    border: none;
    box-shadow: none;
    border-radius: 0;
    z-index: auto;
}
#prospects-panel.docked .assets-panel-resize,
#inactive-prospects-panel.docked .assets-panel-resize {
    display: none;
}
#prospects-panel.docked .assets-panel-collapse,
#inactive-prospects-panel.docked .assets-panel-collapse {
    display: none;
}

/* === v2.13.2.2: cross-mode mutual exclusivity + floating slide-off === */

/* v2.13.2.4: legacy in-panel slide chevrons are hidden globally —
 * the rail icons are the single show/hide trigger now (per user
 * request: "you can get rid of the slide tab completely"). */
.sidebar-toggle,
.assets-panel-collapse {
    display: none !important;
}

/* v2.13.15.11 (PR #92 P1): the legacy `transition: transform 0.3s
   ease` rules that lived here for #assets-panel and #sidebar-controls
   were removed — they came AFTER the unified v2.13.15.10 transition
   declaration at the top of this file and overrode it, leaving the
   most-used floating panels (Map Controls + Assets) snapping
   invisible because opacity and visibility never animated. The
   unified `transition: transform 220ms ease, opacity 220ms ease,
   visibility 0s 0s` (above) now drives the slide for ALL floating
   panels.

   The legacy `.collapsed` slide-off treatment (user's manual collapse
   button — distinct from rail-driven inactive .float-hidden) is
   updated to use the same a11y treatment as .float-hidden so
   screen readers + tab order don't reach the slid-off panel. */
#sidebar-controls:not(.docked).collapsed,
#assets-panel:not(.docked).collapsed {
    transform: translateX(calc(-100% - var(--shell-rail-width, 40px) - 20px)) !important;
    opacity: 0;
    pointer-events: none;
    visibility: hidden;
    transition: transform 220ms ease, opacity 220ms ease, visibility 0s 220ms;
}

/* Defeat the legacy `.assets-panel.collapsed { width: 44px }` rule
 * from asset-detail.css — Assets stays at full width while sliding,
 * matching the Map Controls slide. The legacy `display: none` on
 * inner children is also reverted so the slid panel keeps its full
 * layout (just visually offscreen). */
#assets-panel:not(.docked).collapsed {
    width: 280px !important;
}
#assets-panel:not(.docked).collapsed .assets-panel-body,
#assets-panel:not(.docked).collapsed .assets-panel-title,
#assets-panel:not(.docked).collapsed .assets-panel-wrap,
#assets-panel:not(.docked).collapsed .assets-panel-resize {
    display: revert !important;
}

/* When the activity rail is visible, push floating panels right of it
 * so the floating overlay doesn't visually overlap a panel's own rail
 * icon. --shell-rail-width is 0 when no panels are registered, 40px
 * once at least one is — so this rule is a no-op pre-Phase-2. */
#sidebar-controls:not(.docked) {
    left: calc(10px + var(--shell-rail-width, 0px)) !important;
}
#assets-panel:not(.docked) {
    left: calc(14px + var(--shell-rail-width, 0px)) !important;
}
/* v2.13.15.3: same rail-offset for the v2.13.14.9 split-out prospects
   panels — without this the floating panel sat at left:14px and
   covered the rail icons entirely. */
#prospects-panel:not(.docked) {
    left: calc(14px + var(--shell-rail-width, 0px)) !important;
}
#inactive-prospects-panel:not(.docked) {
    left: calc(14px + var(--shell-rail-width, 0px)) !important;
}
#worklists-panel:not(.docked) {
    left: calc(14px + var(--shell-rail-width, 0px)) !important;
}

/* === v2.13.2.18: Layers panel — third dock panel === */

/* Floating-mode geometry. Default size matches Map Controls / Assets
 * floating widths; sits a bit further right so a side-by-side float
 * preview is clearer when the user toggles modes. left/top match the
 * existing pattern (offset by --shell-rail-width). */
#layers-panel {
    position: fixed;
    top: 90px;
    left: calc(18px + var(--shell-rail-width, 0px));
    width: 320px;
    max-height: calc(100vh - 110px);
    background: white;
    border: 1px solid var(--border-strong);
    border-radius: 6px;
    box-shadow: var(--shadow-lg);
    z-index: 850;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    transition: transform 0.3s ease;
}

/* Layers panel header — same brown gradient + flex row used on the
 * Assets panel header so the dockManager-injected Float button sits
 * comfortably to the right of the title. */
.layers-panel-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 6px;
    padding: 8px 10px;
    background: var(--primary);
    color: white;
    border-bottom: 1px solid var(--chrome-border);
    font-size: 13px;
    font-weight: 600;
    flex-shrink: 0;
}
.layers-panel-title {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Body: scrollable column.
 * v2.13.2.19: only flex-fill in DOCKED mode (where the parent has a
 * defined 100% height — the dock cell). In FLOATING mode the panel
 * has only `max-height`, no explicit height, so `flex: 1 1 0` would
 * collapse the body to zero (flex-basis 0 with no remaining space
 * to grow into). Instead, the floating body sizes to content and
 * scrolls when its own max-height clips it. */
.layers-panel-body {
    overflow-y: auto;
    padding: 10px 12px;
    background: var(--bg-page);
}
#layers-panel.docked .layers-panel-body {
    flex: 1 1 0;
    min-height: 0;
}
#layers-panel:not(.docked) .layers-panel-body {
    /* Floating: clamp the body so the panel doesn't grow past the
     * viewport, but let it size to its natural content otherwise. */
    max-height: calc(100vh - 160px);
}

.layers-section {
    background: white;
    border: 1px solid var(--border-primary);
    border-radius: 6px;
    padding: 10px 12px;
    margin-bottom: 10px;
}
.layers-section:last-child {
    margin-bottom: 0;
}
.layers-section-title {
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: var(--gold-text);
    font-weight: 700;
    margin: 0 0 8px 0;
}
.layers-empty-hint {
    font-size: 11px;
    color: #888;
    line-height: 1.45;
    padding: 4px 0 2px;
    font-style: italic;
}
.layers-empty-hint em {
    font-style: italic;
    color: var(--text-secondary);
}

/* Docked variant — fill the dock cell edge-to-edge, matching the
 * Map Controls / Assets pattern. z-index:auto so the dock-resize
 * handle (z-index:1000) stays on top of the panel content. */
#layers-panel.docked {
    position: relative !important;
    top: auto !important;
    left: auto !important;
    right: auto !important;
    bottom: auto !important;
    width: 100% !important;
    max-width: 100% !important;
    height: 100%;
    margin: 0;
    border-radius: 0;
    box-shadow: none;
    transform: none !important;
    overflow: hidden;
    display: flex !important;
    flex-direction: column;
    z-index: auto !important;
}

/* Two docked panels coexist as siblings in #dock-panel; hide the
 * collapsed one (matches the .dock-hidden override pattern used by
 * the other panels). */
#layers-panel.docked.dock-hidden {
    display: none !important;
}

/* Floating + collapsed: slide off-screen with the same transform the
 * other floating panels use. */
#layers-panel:not(.docked) {
    transition: transform 0.3s ease;
}
#layers-panel:not(.docked).collapsed {
    transform: translateX(calc(-100% - 60px)) !important;
    pointer-events: none;
}

/* === Source-chip strip when rendered inside the Layers panel ===
 *
 * The strip used to be a horizontal pill row floating at the top-left
 * of the map. Inside the dock column it needs to flow vertically (one
 * row per source, full-width pills) to match the Wells / Permits /
 * Production rows visually. css/source-chips.css handles the
 * floating-overlay styling; these rules override the geometry when
 * the strip is a child of #layers-panel. */
#layers-panel #source-chips-strip {
    /* Drop the position:absolute / left:320px / top inheritance from
     * the legacy floating-overlay rule. Inside the panel the strip
     * is in normal flow. */
    position: static !important;
    left: auto !important;
    top: auto !important;
    background: transparent !important;
    box-shadow: none !important;
    border: none !important;
    padding: 0 !important;
    display: flex;
    flex-direction: column;
    gap: 4px;
    max-width: none !important;
    width: 100%;
}
#layers-panel .source-chip {
    /* Full-width row with the icon at left, name in the middle, count
     * pill at right — mirroring the entity-toggle-group rows so the
     * Layers panel reads as one cohesive list. */
    display: flex;
    align-items: center;
    gap: 6px;
    width: 100%;
    padding: 4px 8px;
    background: var(--bg-tertiary);
    border: 1px solid var(--border-primary);
    border-radius: 4px;
    cursor: pointer;
    font-size: 12px;
    color: var(--text-secondary);
    text-align: left;
}
#layers-panel .source-chip:hover {
    background: var(--bg-elevated);
}
#layers-panel .source-chip-icon {
    flex-shrink: 0;
    font-size: 14px;
    line-height: 1;
}
#layers-panel .source-chip-text {
    flex: 1;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
#layers-panel .source-chip-count {
    flex-shrink: 0;
    background: #fff;
    border: 1px solid var(--border-strong);
    border-radius: 8px;
    padding: 1px 6px;
    font-size: 10px;
    color: var(--text-muted);
    min-width: 20px;
    text-align: center;
}
#layers-panel .source-chip-hidden {
    opacity: 0.55;
    background: var(--bg-tertiary);
}
#layers-panel .source-chip-hidden .source-chip-text {
    text-decoration: line-through;
}

/* Sources label (rendered by sourceChips.js as the first child) is
 * redundant inside a section that already has its own header — hide
 * it. */
#layers-panel .source-chips-label {
    display: none;
}

/* Status-badge tweaks inside the Layers panel: stack vertically with
 * a small gap, cleaner spacing than the inline pills they were inside
 * #sidebar-controls. */
#layers-panel #visibility-filter-status,
#layers-panel #color-rule-status,
#layers-panel #label-rule-status {
    margin: 4px 0;
}
#layers-panel #label-clear-btn {
    margin-top: 6px;
    width: 100%;
}

/* Display-rules empty-state hint: visible by default; hidden when any
 * of the three badge elements is currently rendered. The badges all
 * carry an inline `style="display: none;"` until their rule activates,
 * at which point colorByAttribute / labelByAttribute / visibilityFilter
 * code clears the inline display, removing the `display: none` token
 * from the [style] attribute. CSS :has() lets the section observe its
 * own descendants' inline styles without any JS observer. */
#layers-panel .layers-section:has(#visibility-filter-status:not([style*="display: none"])) #layers-rules-empty,
#layers-panel .layers-section:has(#color-rule-status:not([style*="display: none"])) #layers-rules-empty,
#layers-panel .layers-section:has(#label-rule-status:not([style*="display: none"])) #layers-rules-empty {
    display: none;
}

/* Entity-toggle group inside Layers — keep the existing checkbox-row
 * layout (defined in css/wells.css) but tighten the section-title
 * alignment. */
#layers-panel .entity-toggle-group .checkbox-row {
    margin: 4px 0;
}
#layers-panel .entity-toggle-group .laterals-row {
    margin-left: 22px;
    font-size: 11px;
    color: var(--text-tertiary);
}
