/* ═════════════════════════════════════════════════════════════════════════
   SEAMLESS MONO PASS

   Loaded LAST - after style.css, auth_popup.css, measure.css,
   ui_mobile_popups.css and ui_borders_squared.css - so it wins on source
   order. Self-contained: remove this one <link> in index.html and the app
   goes back to exactly what those five sheets describe.

   Six promises, one per section below:

     1. BLACK AND WHITE ONLY.  Every surface is #000, every line, glyph and
        label is #ffffff, and every "on / selected / hovered" state is the
        straight inversion of that (white ground, black ink). No greys, no
        tints, no translucent fills standing in for a colour - the step
        palette's near-blacks (6,6,6 / 22,22,22 / 40,40,40) and the last
        handful of hard-coded hues (the amber corrected-value text, the gold
        selected-shape row, the red compass needle, the blue geolocate dot,
        the OAuth brand glyphs) all resolve here.

     2. ONE LINE, NEVER TWO.  ui_borders_squared gives EVERY element its own
        four-sided box. Where a full-bleed child sits inside a bordered
        parent that produced two lines a pixel apart, and where two stacked
        rows met it produced two more. Structural children now draw only the
        line that SEPARATES them - a stack draws bottoms, a row of cells
        draws rights, the last one in either direction draws nothing and
        lets the container's own edge be the closing line. Free-standing
        controls (a button with margin around it) keep their box: they are
        not sharing an edge with anything, so there is nothing to collapse.

     3. POPUPS ARE CAPPED AT 610px.  Every popup, panel, sheet, bar and
        modal is at most 610px wide (or the space between the left sidebar
        and the right tool rail, if that is narrower), so the basemap stays
        visible beside it on any screen wider than a phone. Popups also
        stack above every overlay drawn on the map - see section 3b.

     4. THE LAYERS TAB EXPANDS ALL THE WAY.  Both expandable wrappers in the
        layers list animated open to a max-height of 9999px. A REST category
        with a few hundred layers under it - or one whose sub-panels are
        themselves open - is taller than that, and everything past 9999px
        was silently clipped with no way to reach it. Expanded now means
        max-height:none, so a category is as tall as its contents.

     5. EVERY EXPAND ARROW LEADS ITS ROW.  Category headers, service
        sub-panel headers, measurement panel headers, overlay rows and the
        collapse chevron on every popup all put their arrow in the first
        cell on the left, before the checkbox/title/thumbnail, so one column
        down the left edge of the app is "open this".

     6. THE SEARCH ROW AND THE BUTTON STRIPS ARE REBUILT.  A search field is
        one 48px module: a bordered glyph cell on the left, the input
        running to the panel's right edge, and an inversion on focus. Tab /
        source / feature strips are flush 48px cells divided by one shared
        line, inverted when active.
   ═════════════════════════════════════════════════════════════════════════ */


/* ═══ 1. BLACK AND WHITE ONLY ═════════════════════════════════════════════
   Set at :root so every one of the several hundred rules already reading
   these tokens resolves to black or white without being named again. The
   three duplicate :root blocks further down style.css (lines ~3134, ~13726)
   redefine the step palette, which is why these are re-stated on :root here
   rather than edited in place - source order settles it. */
:root,
:root:root {
  /* the two colours */
  --mono_ground: #000000;
  --mono_ink: #ffffff;

  /* the step palette: every "one shade lighter" surface in the app is the
     same black now. Depth is carried by the line grid in section 2 and by
     indentation, not by four near-identical greys. */
  --step-0: #000000;
  --step-1: #000000;
  --step-2: #000000;
  --step-3: #000000;
  --step-4: #000000;

  --color_background_primary: #000000;
  --color_background_secondary: #000000;
  --color_background_tertiary: #000000;
  --color_background_quaternary: #000000;
  --color_background_input: #000000;
  --primary-bg: #000000;
  --panel-bg: #000000;
  --panel-bg-alpha: #000000;
  --input-bg: #000000;

  /* the inversion. Everything that used to be a translucent white wash -
     hover fills, active tints, the two layer-depth shades - is now the
     full white ground that the :hover/.active rules in section 2 pair with
     black ink. */
  /* Hover and active are white: every rule reading one of these three
     tokens is a :hover / :focus / .active rule, so the token itself can
     carry the inversion. */
  --color_background_hover: #ffffff;
  --panel-bg-hover: #ffffff;
  --panel-bg-alpha-hover: #ffffff;
  --active_item_bg: #ffffff;
  /* ...but --accent-bg and --button-bg-light are NOT state tokens. They were
     a 0.08-alpha white wash used as the RESTING background of upload areas,
     input rails, sub-navs and callout blocks - inverting them turned whole
     panel bodies white. They go to the same black as every other surface;
     the states that used them for a "selected" tint are named explicitly in
     the inversion block below instead. */
  --accent-bg: #000000;
  --button-bg-light: #000000;
  --layer_depth_1: #000000;
  --layer_depth_2: #000000;

  /* ink */
  --text-color: #ffffff;
  --text-muted: #ffffff;
  --muted: #ffffff;
  --color_text_primary: #ffffff;
  --color_text_secondary: #ffffff;
  --color_text_tertiary: #ffffff;
  --accent-color: #ffffff;
  --error-color: #ffffff;
  --success-color: #ffffff;
  --warning-color: #ffffff;
  --info-color: #ffffff;

  /* the one line the whole app is drawn with - pure white, fully opaque,
     replacing ui_borders_squared's 85%/45% pair so there is exactly one
     border colour in the app rather than two weights of it */
  --ui_border_visible: #ffffff;
  --ui_border_visible_soft: #ffffff;
  --panel-border: #ffffff;
  --panel-border-alpha: #ffffff;
  --accent-border: #ffffff;
  --popup_border_dark: #ffffff;
  --color_border_primary: #ffffff;
  --color_border_secondary: #ffffff;
  --color_border_focus: #ffffff;
  --color_border_active: #ffffff;

  /* panel grounds. --popup_gradient_topdown_dark is a two-stop gradient of
     rgba(6,6,6,.88); flattened to solid black so a panel is one surface
     rather than a wash that lets the map tint it grey. */
  --popup_gradient_topdown_dark: linear-gradient(#000000, #000000);
  --popup_content_text_shadow: none;

  /* the last coloured literals in the app's chrome and its map marks */
  --map_marker_selected_accent: #ffffff;
  --placemark_accent: #ffffff;
  --placemark_accent_light: #ffffff;
  --placemark_bg_translucent: rgba(0, 0, 0, 0.55);
  --geolocate_accent: #ffffff;
  --geolocate_accent_light: #ffffff;
  --geolocate_bg_translucent: rgba(0, 0, 0, 0.55);
  --compass_needle_north_color: #ffffff;
  --map_marker_fill_neutral: rgba(0, 0, 0, 0.45);
  --map_marker_fill_geolocate: rgba(0, 0, 0, 0.45);
  --map_marker_fill_placemark: rgba(0, 0, 0, 0.45);
  --map_marker_fill_search: rgba(0, 0, 0, 0.45);
  --map_feature_bg_translucent: rgba(0, 0, 0, 0.25);
  --map_feature_bg_translucent_strong: rgba(0, 0, 0, 0.3);
  --map_marker_border: 2px solid #ffffff;
}

/* The compass needle keeps its north/south reading without a second hue:
   the north half is the solid line weight, the south half is the same white
   at a third of the opacity. Same fact, told with opacity instead of colour. */
.mini_compass_needle_south,
.compass_needle_south {
  stroke: #ffffff !important;
  fill: #ffffff !important;
  opacity: 0.35;
}

/* the four literals left in the chrome after the token pass: the amber
   "this value was corrected" text and its primary edit button, the gold
   selected-shape row, and the two OAuth brand glyphs in the auth popup.
   All of them said "look here" with a hue; they say it with weight now. */
.cs_feature_popup_value_corrected,
.cs_feature_popup_edit_button.state_primary,
.cs_shape_item.state_selected .feature-name,
.cs_shape_item.state_selected .feature-icon,
.auth_oauth_button i,
.auth_oauth_button svg,
.overlay_item_btn.danger,
.overlay_item_btn.danger i {
  color: #ffffff !important;
  fill: #ffffff !important;
}
.cs_feature_popup_edit_button.state_primary {
  /* the primary action in a pair of buttons is the inverted one */
  background: #ffffff !important;
  color: #000000 !important;
  border-color: #ffffff !important;
}
.cs_shape_item.state_selected,
.cs_points_square.state_just_added {
  border-color: #ffffff !important;
}
/* the just-added pulse was a gold ring fading out; same pulse, white */
.cs_points_square.state_just_added {
  animation: none !important;
  box-shadow: 0 0 0 2px #ffffff !important;
}

/* Selected / active / hovered is always the straight inversion: white
   ground, black ink, black glyph. Stated once here so no component has to
   re-describe it, and so the ink flips together with the ground instead of
   white-on-white. */
.panel-tab.active,
.panel-tab:hover:not(.active),
.layers-source-nav-button.active,
.layers-source-nav-button:hover:not(.active),
.features-nav-button.active,
.features-nav-button:hover:not(.active),
.view_controls_tab.active,
.filemanager_panel_tab.active,
.auth_tab.active,
.basemap-option.active,
.basemap-option:hover,
.cs_category_header:hover,
.cs_service_sub_panel_header:hover,
.cs_layer_item:hover,
.layer-item:hover,
.sliding_menu_item:hover,
.nav_list_item:hover,
.user_dropdown_item:hover,
.cs_autocomplete_item:hover,
.search_result_item:hover,
.overlay_item_btn:hover,
.overlay_item_btn.active,
.overlay_export_option.active,
.sliding_menu_item.active,
.top-nav-inner .search_result_item.active,
.search_result_item.active,
.nav-scroll-btn:hover,
.cs_search_clear_button:hover,
.search_div:hover,
.overlay_upload_area:hover,
.fm_file_upload_area:hover,
.filemanager_upload_area:hover,
.cs_popup_collapse_btn:hover,
.cs_popup_close_btn:hover,
.close-button:hover {
  background: #ffffff !important;
  background-color: #ffffff !important;
  color: #000000 !important;
}
.panel-tab.active i,
.panel-tab.active span,
.panel-tab:hover:not(.active) i,
.panel-tab:hover:not(.active) span,
.layers-source-nav-button.active i,
.layers-source-nav-button.active span,
.layers-source-nav-button:hover:not(.active) i,
.layers-source-nav-button:hover:not(.active) span,
.features-nav-button.active i,
.features-nav-button.active span,
.features-nav-button:hover:not(.active) i,
.features-nav-button:hover:not(.active) span,
.basemap-option.active *,
.basemap-option:hover *,
.cs_category_header:hover *,
.cs_service_sub_panel_header:hover *,
.cs_layer_item:hover *,
.sliding_menu_item:hover *,
.nav_list_item:hover *,
.user_dropdown_item:hover *,
.search_result_item:hover *,
.overlay_item_btn:hover i,
.overlay_item_btn.active i,
.overlay_export_option.active *,
.sliding_menu_item.active *,
.search_result_item.active *,
.nav-scroll-btn:hover i,
.cs_search_clear_button:hover i,
.overlay_upload_area:hover *,
.fm_file_upload_area:hover *,
.filemanager_upload_area:hover *,
.cs_popup_collapse_btn:hover i,
.cs_popup_close_btn:hover i,
.close-button:hover i {
  color: #000000 !important;
} /* end inversion ink */

/* a checkbox inside an inverted row has to flip too, or it disappears into
   the white ground it is sitting on */
.cs_category_header:hover .cs_checkbox_input,
.cs_service_sub_panel_header:hover .cs_checkbox_input,
.cs_layer_item:hover .cs_checkbox_input {
  border-color: #000000 !important;
  background-color: transparent !important;
}
.cs_category_header:hover .cs_checkbox_input:checked,
.cs_service_sub_panel_header:hover .cs_checkbox_input:checked,
.cs_layer_item:hover .cs_checkbox_input:checked {
  background-color: #000000 !important;
}
.cs_category_header:hover .cs_checkbox_input:checked::after,
.cs_service_sub_panel_header:hover .cs_checkbox_input:checked::after,
.cs_layer_item:hover .cs_checkbox_input:checked::after {
  color: #ffffff !important;
  border-color: #ffffff !important;
}


/* ═══ 2. ONE LINE, NEVER TWO ══════════════════════════════════════════════

   The rule underneath everything here: an element that sits FLUSH inside a
   bordered parent - same left edge, same right edge, no margin between them
   - never draws the side that touches the parent's own line, and never
   draws the side that touches the sibling above or below it. It draws one
   separator, in the direction the stack runs, and the last one in the stack
   draws nothing at all because the container's closing edge is already
   there.

   Containers keep the four-sided box ui_borders_squared gave them. Only
   what is INSIDE them is collapsed. */

/* ── 2a. Full-bleed vertical stacks: bottom line only ─────────────────── */
.panel-header,
.panel-tabs,
.panel-content,
.search-container,
.layers-source-nav,
.features-nav-container,
.sliding_menu_header,
.sliding_menu_item,
.view_controls_header,
.view_controls_tabs,
.vc_control_block,
.vc_input_row,
.vc_distance_row,
.overlay_panel_header,
.overlay_item,
.overlay_item_header,
.overlay_item_content,
.overlay_item_footer,
.overlay_stats,
.overlay_export_section,
.overlay_upload_area,
.filemanager_panel_header,
.filemanager_panel_tabs,
.filemanager_modal_header,
.filemanager_modal_content,
.filemanager_modal_actions,
.filemanager_active_project,
.filemanager_export_section,
.filemanager_file_item,
.fm_file_upload_area,
.cs_panel_header_collapsible,
.cs_panel_header_container_sticky,
.cs_measurement_panel_expandable,
.cs_measurement_panel_header,
.cs_measurement_panel_content,
.cs_measurement_section_container,
.cs_popup_content_area,
.cs_category_container,
.cs_category_header,
.cs_category_content_wrapper,
.cs_service_sub_panel,
.cs_service_sub_panel_header,
.cs_service_sub_panel_content,
.cs_layer_item,
.cs_layer_list_container > *,
.layer-item,
.layer-category-layers,
.auth_modal_header,
.auth_tabs,
.auth_input_group,
.auth_quick_actions,
.auth_oauth_actions,
.nav_list_item,
.user_dropdown_header,
.user_dropdown_item,
.cs_autocomplete_item,
.cs_autocomplete_empty,
.search_recent_header,
.search_result_item,
.top-nav-inner .search_result_item,
.gis_stat_row,
.gis_info_note,
.cs_points_toolbar,
.cs_points_folder_header,
.feature-item {
  border-top: 0 !important;
  border-left: 0 !important;
  border-right: 0 !important;
  border-bottom: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  box-sizing: border-box;
}

/* the closing line of a stack is the container's own bottom edge, so the
   last row in one never draws its own */
.panel-content > .tab-content > :last-child,
.cs_layer_list_container > :last-child,
.cs_category_content_wrapper > :last-child,
.cs_service_sub_panel_content > :last-child,
.side-panel > .panel-content,
.overlay_panel > .overlay_panel_content,
.filemanager_panel > .filemanager_panel_content,
.overlay_item:last-child,
.filemanager_file_item:last-child,
.nav_list_item:last-child,
.user_dropdown_item:last-child,
.cs_autocomplete_item:last-child,
.search_result_item:last-child,
.sliding_menu_item:last-child,
.feature-item:last-child,
.cs_measurement_panel_expandable:last-child,
.gis_stat_row:last-child {
  border-bottom: 0 !important;
}

/* ── 2b. Full-bleed horizontal cell rows: right line only ─────────────── */
.panel-tab,
.layers-source-nav-button,
.features-nav-button,
.view_controls_tab,
.filemanager_panel_tab,
.auth_tab,
.overlay_item_btn,
.cs_crosshair_distance_unit_option,
.cs_points_toolbar_button {
  border-top: 0 !important;
  border-bottom: 0 !important;
  border-left: 0 !important;
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  box-sizing: border-box;
}
/* the last cell in a row closes against the container's own right edge */
.panel-tab:last-child,
.layers-source-nav-button:last-child,
.features-nav-button:last-child,
.view_controls_tab:last-child,
.filemanager_panel_tab:last-child,
.auth_tab:last-child,
.overlay_item_btn:last-child,
.cs_crosshair_distance_unit_option:last-child,
.cs_points_toolbar_button:last-child {
  border-right: 0 !important;
}

/* ── 2c. The chrome cells in a header row ─────────────────────────────────
   Close button, collapse chevron and the panel title all live in the same
   48px header. The chevron leads on the left (section 5) and the close
   button closes on the right, so each draws the ONE line that faces the
   title between them - never a box that doubles against the header's own
   top and bottom rules. */
.cs_popup_collapse_btn {
  border: 0 !important;
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
}
.cs_popup_close_btn,
.close-button,
#close-layers {
  border: 0 !important;
  border-left: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  box-sizing: border-box;
}
/* floated into a corner rather than sitting in the header's flow: it is not
   sharing an edge with anything, so it needs its own two closing sides */
.cs_popup_collapse_btn_floating {
  border-right: 0 !important;
  border-left: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  border-bottom: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
}

/* ── 2d. Nothing inside a collapsed row draws a line of its own ───────────
   The cells INSIDE a header/list row - checkbox wrapper, icon box, count
   box, arrow box, indent spacers, text - are laid out with a 10px gap, so a
   border on any of them floats in the middle of the row instead of meeting
   anything. They carry no line; the row's own bottom rule is the only
   line at that level. */
.cs_checkbox_container,
.cs_icon_container_uniform,
.cs_category_count_box,
.cs_category_text,
.cs_expansion_arrow_container,
.cs_sub_panel_spacer,
.cs_sub_panel_checkbox_container,
.cs_sub_panel_text,
.cs_sub_panel_arrow_container,
.cs_layer_indent_spacer,
.cs_layer_alignment_container,
.cs_legend_symbol_container,
.cs_layer_text,
.panel-header-title,
.cs_panel_header_title,
.overlay_item_thumbnail,
.overlay_item_info,
.overlay_item_actions,
.basemap-thumbnail,
.basemap-info,
.feature-icon,
.cs_points_folder_name,
.cs_points_folder_count,
.cs_progress_bar_container,
.gis_stat_value {
  border: 0 !important;
}

/* ── 2e. The basemap grid is drawn by its own gaps ────────────────────────
   Cards in a gapped grid each carrying a box gave three lines and two gutters
   between every pair. Collapsed the classic way instead: the grid's gap IS
   the line (the container paints white behind a 1px gap, the cards paint
   black over it), so every interior division is exactly one pixel and the
   outer edges are left to the panel's own border. */
#basemap-list {
  gap: 0 !important;
  padding: 0 !important;
  background: #000000 !important;
  /* the grid is deliberately one pixel wider and one pixel taller than the
     column it sits in. Every card draws its own right and bottom line, so
     the interior divisions are single lines already; the overhang is what
     puts the LAST column's right line and the LAST row's bottom line
     exactly on the panel's own border instead of one pixel inside it. The
     scroller clips the overhang, so the two lines become one. */
  margin: 0 calc(var(--ui_border_uniform_width, 1px) * -1)
    calc(var(--ui_border_uniform_width, 1px) * -1) 0 !important;
  box-sizing: border-box;
}
.basemap-option {
  border: 0 !important;
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  border-bottom: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  background: #000000;
  padding: 8px 6px;
  margin: 0 !important;
}

/* ── 2f. Free-standing controls keep their box ────────────────────────────
   A button with margin around it shares no edge with anything, so there is
   no doubled line to collapse and stripping it would leave an unreadable
   control. What they DO get here is the mono treatment: black ground,
   white line, inverted on hover. */
.overlay_export_option,
.filemanager_modal_field,
.vc_button,
.auth_button,
.auth_input,
.cs_feature_popup_edit_button,
.cs_local_filter_input {
  background: #000000;
  color: #ffffff;
}


/* ═══ 3. POPUPS ARE CAPPED AT 610px ═══════════════════════════════════════
   ui_mobile_popups builds every popup on --popup_column_width: 610px, or the
   space between the two rails when that is narrower. This pass had widened
   the token to the full map area; it is back to the 610px cap so the
   basemap stays visible beside every panel. The two rails stay - a popup
   still never covers the left sidebar or the right tool column. */
:root,
:root:root {
  --popup_column_width: min(
    610px,
    calc(100vw - var(--popup_left_margin) - var(--popup_right_margin))
  );
}

/* every popup box, side panel and modal dialog takes the same capped
   column, including the ones that set their own width in style.css rather
   than reading the token */
.side-panel,
.sliding_menu,
.control_panel,
.view_controls_panel,
.overlay_panel,
.filemanager_panel,
.search_popup,
.cs_feature_profile_popup,
.cs_panel_container_expandable,
.cs_measurement_panels_container,
.cs_input_bar,
.bottom_popup_container,
.footer_nav_bar,
.marker_direction_nav_bar,
.marker_travel_panel,
.cs_toolbar_controls_container,
.filemanager_modal,
.cs_qr_share_modal_content,
.auth_modal,
.overlay_export_modal {
  max-width: var(--popup_column_width) !important;
  width: var(--popup_column_width) !important;
  margin-left: 0 !important;
  margin-right: 0 !important;
}

/* every popup's own inner column follows it out to the new width instead of
   staying at the old centred cap */
.panel-content,
.sliding_menu_content,
.overlay_panel_content,
.filemanager_panel_content,
.view_controls_content,
.cs_panel_content_scrollable,
.cs_popup_content_area,
.search_results_container,
.cs_scrollable_content_container,
.cs_layer_list_container,
.cs_content_scrollable_area {
  width: 100% !important;
  max-width: 100% !important;
  box-sizing: border-box;
}


/* ═══ 3b. POPUPS STACK ABOVE EVERYTHING DRAWN ON THE MAP ══════════════════
   The map overlays sit between z-index 800 and 10100 (the ruler at 9999, its
   unit bar at 10000, the compass and altitude scale at 10060, the grid at
   10100), and most docked panels sat BELOW them at 700-2000 - so switching
   on the ruler or the compass painted its scrim and strokes across an open
   panel. Every popup and container now lives in one band above all of
   them, 21000-23000, and still under the app frame (top bar, sidebar,
   footer bar at 30000).

   Inside the band the old relative order is kept, one step per former
   level, so two panels that overlapped before still overlap the same way:
   docked panels, then the menu scrim, the sliding menus over it, modal
   dialogs, the account dropdown, and toasts on top. !important because
   navigation.js injects #nav-panel's own z-index at runtime, after this
   sheet. Map-feature popups (.maplibregl-popup) are not in here: they are
   drawn inside #map's own stacking context, which all overlays sit above. */
.marker_direction_nav_bar,
.marker_travel_panel {
  z-index: 21000 !important;
}
#info_container {
  z-index: 21001 !important;
}
.control_panel {
  z-index: 21002 !important;
}
.cs_panel_container_expandable {
  z-index: 21003 !important;
}
.search_popup,
.side-panel,
.sidebar_flyout {
  z-index: 21004 !important;
}
.bottom_popup_container,
.cs_toolbar_controls_container {
  z-index: 21005 !important;
}
#nav-banner {
  z-index: 21006 !important;
}
.view_controls_panel,
.overlay_panel,
.filemanager_panel {
  z-index: 21007 !important;
}
#nav-panel {
  z-index: 21008 !important;
}
.cs_feature_profile_popup {
  z-index: 21009 !important;
}
.cs_input_bar {
  z-index: 21010 !important;
}
/* the scrim behind an open sliding menu, then the menus on it */
.menu_overlay {
  z-index: 21500 !important;
}
.sliding_menu {
  z-index: 21600 !important;
}
.auth_modal_overlay,
.filemanager_modal_overlay,
.overlay_export_modal {
  z-index: 22000 !important;
}
.cs_qr_share_modal,
.cs_map_shot_modal,
.cs_shoe_size_modal {
  z-index: 22100 !important;
}
.user_dropdown {
  z-index: 22500 !important;
}
.toast-container {
  z-index: 23000 !important;
}
/* the map error notice is a popup box too - capped with the rest */
#map_error_container {
  max-width: min(610px, 80%) !important;
}


/* ═══ 4. THE LAYERS TAB EXPANDS ALL THE WAY ═══════════════════════════════
   Both wrappers animated from max-height:0 to max-height:9999px. 9999px is
   ~260 rows at the layers list's own 38px module - and a REST category can
   carry more than that on its own, never mind one whose service sub-panels
   are open inside it, each of which is separately capped at the same 9999px.
   Everything past the cap was clipped and unreachable: the list simply
   stopped.

   Expanded is now max-height:none, which no content can outgrow. The
   height transition goes with it (there is no number to animate towards),
   so opening is instant - which is the right trade against a category that
   cannot be fully opened at all. The panel's own scroller
   (#layers-scrollable-container) is what the extra height scrolls in. */
.cs_category_container.state_expanded > .cs_category_content_wrapper,
.cs_category_container.state_expanded .cs_category_content_wrapper,
.cs_service_sub_panel.state_expanded > .cs_service_sub_panel_content,
.cs_service_sub_panel.state_expanded .cs_service_sub_panel_content,
.layer-category.expanded .layer-category-layers {
  max-height: none !important;
  height: auto !important;
  overflow: visible !important;
  transition: none !important;
}
/* collapsed keeps clipping - that is what collapsed means */
.cs_category_content_wrapper,
.cs_service_sub_panel_content {
  transition: none !important;
}

/* The list itself stops imposing a height or a scrollport of its own, so the
   only thing that decides how tall an open category is, is the category. */
.cs_layer_list_container,
#layer-list {
  max-height: none !important;
  height: auto !important;
  overflow: visible !important;
}

/* ...and the ONE scrollport that height lands in stays the tab's own
   scrollable container, not the panel around it. A flex item's default
   min-height is `auto`, which means "at least as tall as my content" - so
   with an unbounded list inside it, .tab-content grew to the full ~3000px
   of layers and the scrolling moved up to .panel-content, taking the tab
   strip and the search row off the top of the panel with it. min-height:0
   is what lets flex:1 actually mean "whatever height is left": the scroller
   fills the panel, the list scrolls inside it, and the chrome above stays
   put at every scroll position. */
.panel-content > .tab-content,
.panel-content > .tab-content.active {
  min-height: 0;
}
#layers-scrollable-container,
#basemap-scrollable-container,
#features-scrollable-container,
.cs_scrollable_content_container {
  flex: 1 1 auto;
  min-height: 0;
  max-height: none !important;
  overflow-y: auto !important;
  overflow-x: hidden !important;
}
/* the panel shell itself never becomes the scrollport - the tab content
   inside it is already one, and two nested scrollbars for one list is one
   too many */
.side-panel > .panel-content {
  overflow: hidden !important;
}


/* ═══ 5. EVERY EXPAND ARROW LEADS ITS ROW ═════════════════════════════════
   One column down the left edge of every header bar in the app means
   "open this". The arrows were scattered: trailing the count in a category
   header, trailing the title in a sub-panel and measurement header, fourth
   in a row of four action buttons in an overlay row, and in the top-RIGHT
   chrome cell of every popup.

   All of them move with `order`, not with new markup - the two grid headers
   get a re-cut template to match, since a grid's explicit columns do not
   follow the items that `order` reshuffles. */

/* category header: was [checkbox][icon][1fr title][count][arrow],
   now      [arrow][checkbox][icon][1fr title][count] */
.cs_category_header {
  grid-template-columns: auto auto auto 1fr auto !important;
}
.cs_category_header .cs_expansion_arrow_container {
  order: -1;
}

/* sub-panel header: was [spacer][checkbox][1fr title][arrow],
   now      [spacer][arrow][checkbox][1fr title] */
.cs_service_sub_panel_header {
  grid-template-columns: var(--cs_layer_indent_step) auto auto 1fr !important;
}
.cs_service_sub_panel_header .cs_sub_panel_arrow_container {
  order: -1;
}
.cs_service_sub_panel_header .cs_sub_panel_spacer {
  order: -2;
}

/* measurement / feature-profile panel headers are flex rows: the chevron
   was the last child after the title */
.cs_measurement_panel_header,
.cs_panel_header_collapsible {
  display: flex;
  align-items: center;
}
.cs_measurement_panel_header .cs_panel_expand_indicator,
.cs_panel_header_collapsible .cs_panel_expand_indicator {
  order: -1;
  width: 38px;
  min-width: 38px;
  text-align: center;
  flex: 0 0 38px;
}

/* the collapse chevron every popup gets from popup_mobile.js. It was pushed
   to the right corner by `margin-left:auto`; that margin is what has to go,
   not just the order, or it would take the free space with it and land in
   the middle of the row. */
.cs_popup_collapse_btn {
  order: -10;
  margin-left: 0 !important;
  margin-right: 0 !important;
}
/* the first row of a popup with FLOATING chrome keeps clear of whatever is
   floated over it: the chevron now on its left, and the close button on its
   right where there is one. The old rule reserved two cells on the right for
   both of them, which is where the chevron used to be - left as-is it would
   put the chevron straight on top of the search field. */
.js_popup_has_floating_chrome > *:first-child {
  padding-left: var(--popup_header_cell) !important;
  padding-right: 0 !important;
}
.js_popup_has_floating_chrome:has(> .cs_popup_close_btn) > *:first-child {
  padding-right: var(--popup_header_cell) !important;
}
/* a floated chevron (a popup with no header row of its own) leads on the
   left of the popup's top edge for the same reason */
.cs_popup_collapse_btn_floating,
.js_popup_has_floating_chrome > .cs_popup_collapse_btn_floating,
.cs_popup_collapse_btn_floating.cs_popup_collapse_btn_beside_close {
  left: 0 !important;
  right: auto !important;
  margin-right: 0 !important;
}
.cs_popup_collapse_btn_clear_of_close {
  margin-right: 0 !important;
}

/* overlay rows: script.js now renders the expand control as the header's
   first child (see renderOverlayList), and this is the geometry that goes
   with it - a 48px cell divided from the thumbnail by the same one line
   every other cell boundary uses. */
.overlay_item_header {
  display: flex;
  align-items: center;
}
.overlay_item_header > .overlay_item_btn.expand {
  order: -1;
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 0 !important;
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
}

/* the folder caret in the Project tab already led its row; it just needs
   the same 38px cell and divider the rest of the arrows now have */
.cs_points_folder_caret {
  order: -1;
  width: 38px;
  min-width: 38px;
  flex: 0 0 38px;
  border: 0 !important;
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  background: transparent;
  color: #ffffff;
}


/* ═══ 6. THE SEARCH ROW, REBUILT ══════════════════════════════════════════
   Was: a 48px bar, a search glyph absolutely positioned over the input's
   left 48px, and the input padded 44px to clear it - which meant the glyph
   floated over the field with no edge of its own and the field's own box
   doubled against the bar's.

   Now: one 48px module cut into two cells by a single shared line. The
   glyph cell is a real 48px box on the left; the input takes the rest of
   the row and runs flush to the panel's right edge with no box of its own.
   Focus inverts the glyph cell rather than tinting the field, so the row
   says where the caret is without changing the colour of what is typed. */
.search-container {
  display: flex;
  align-items: stretch;
  height: 48px;
  min-height: 48px;
  max-height: 48px;
  padding: 0 !important;
  background: #000000;
}
/* the relative-positioned div index.html wraps each field in stops being a
   positioning context and becomes the flex row itself */
.search-container > div {
  display: flex !important;
  align-items: stretch;
  flex: 1;
  min-width: 0;
  position: static !important;
}
.search-icon {
  position: static !important;
  transform: none !important;
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 !important;
  margin: 0;
  font-size: 14px;
  color: #ffffff;
  background: #000000;
  border: 0 !important;
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  box-sizing: border-box;
  transition: background-color 0.12s linear, color 0.12s linear;
}
.search-box {
  flex: 1;
  min-width: 0;
  height: 48px;
  min-height: 48px;
  padding: 0 12px !important;
  border: 0 !important;
  background: #000000 !important;
  color: #ffffff;
  /* the field is the one place in the app where text is typed rather than
     read, so it is set apart the only way a two-colour palette allows:
     the app's mono stack, small, wide-tracked and upper-cased */
  font-family: ui-monospace, "SFMono-Regular", "Liberation Mono", Menlo,
    Consolas, monospace;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  outline: none !important;
  box-shadow: none !important;
}
.search-box::placeholder {
  color: #ffffff;
  opacity: 0.55;
  text-transform: uppercase;
  letter-spacing: 0.09em;
}
.search-box:focus {
  background: #000000 !important;
  color: #ffffff;
}
/* the inversion lands on the glyph cell, so the row shows focus at the same
   48px module every other "this one is on" state in the app uses */
.search-container:focus-within .search-icon {
  background: #ffffff;
  color: #000000;
}
/* the clear button, when one is rendered, is the closing cell on the right */
.cs_search_clear_button {
  flex: 0 0 48px;
  width: 48px;
  height: 48px;
  border: 0 !important;
  border-left: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  background: #000000;
  color: #ffffff;
  border-radius: 0;
}
.cs_search_clear_button:hover {
  background: #ffffff;
  color: #000000;
}

/* the in-list filter row under the fast-offline category gets the same
   two-cell treatment one level down, at the list's own 38px module */
.cs_local_filter_row {
  display: flex;
  align-items: stretch;
  height: 38px;
  padding: 0 !important;
  gap: 0 !important;
  border-bottom: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
}
.cs_local_filter_icon {
  flex: 0 0 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  color: #ffffff;
}
.cs_local_filter_input {
  flex: 1;
  min-width: 0;
  border: 0 !important;
  background: #000000 !important;
  color: #ffffff;
  padding: 0 10px !important;
  font-family: ui-monospace, "SFMono-Regular", "Liberation Mono", Menlo,
    Consolas, monospace;
  font-size: 10px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  outline: none !important;
}
.cs_local_filter_count {
  flex: 0 0 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-left: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  font-size: 10px;
  color: #ffffff;
}


/* ═══ 6b. THE BUTTON STRIPS, REBUILT ══════════════════════════════════════
   Tabs, the Offline/Online switch and the Points/Lines/Shapes switch were
   three different shapes: different heights, a 3px bottom rule on one, a
   background tint on another, a pill on a third. They are one thing now -
   a row of flush 48px cells, equal width, divided by the single line from
   section 2b, labelled in the same wide-tracked upper case as the search
   field, and INVERTED when the cell is the active one. No underline, no
   tint, no second weight of border: the cell is either black-on-white or
   white-on-black. */
.panel-tabs,
.layers-source-nav,
.features-nav {
  display: flex;
  align-items: stretch;
  height: 48px;
  min-height: 48px;
  max-height: 48px;
  padding: 0 !important;
  gap: 0 !important;
  background: #000000;
}
.panel-tab,
.layers-source-nav-button,
.features-nav-button,
.filemanager_panel_tab,
.view_controls_tab,
.auth_tab {
  flex: 1 1 0;
  min-width: 0;
  height: 48px;
  min-height: 48px;
  max-height: 48px;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 0 6px !important;
  margin: 0 !important;
  background: #000000;
  color: #ffffff;
  cursor: pointer;
  border-radius: 0 !important;
  box-shadow: none !important;
  transition: background-color 0.12s linear, color 0.12s linear;
}
.panel-tab span,
.layers-source-nav-button span,
.features-nav-button span,
.filemanager_panel_tab span,
.view_controls_tab span,
.auth_tab span {
  font-family: ui-monospace, "SFMono-Regular", "Liberation Mono", Menlo,
    Consolas, monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.panel-tab i,
.layers-source-nav-button i,
.features-nav-button i,
.filemanager_panel_tab i,
.view_controls_tab i,
.auth_tab i {
  font-size: 13px;
  line-height: 1;
}
/* the 3px accent underline the active tab used to carry is what the
   inversion replaces - two cues for one fact is one too many */
.panel-tab.active,
.layers-source-nav-button.active,
.features-nav-button.active,
.filemanager_panel_tab.active,
.view_controls_tab.active,
.auth_tab.active {
  border-bottom-width: 0 !important;
  font-weight: 700;
}

/* every other button in the chrome, held to the same module: black ground,
   one white line, square, inverted on hover, and nothing else. */
.cs_points_toolbar_button,
.vc_button,
.overlay_export_option,
.auth_button,
.filemanager_modal_button,
.cs_feature_popup_edit_button {
  background: #000000;
  color: #ffffff;
  border-radius: 0 !important;
  font-family: ui-monospace, "SFMono-Regular", "Liberation Mono", Menlo,
    Consolas, monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: background-color 0.12s linear, color 0.12s linear;
}
.cs_points_toolbar_button:hover,
.vc_button:hover,
.overlay_export_option:hover,
.auth_button:hover,
.filemanager_modal_button:hover,
.cs_feature_popup_edit_button:hover:not(:disabled) {
  background: #ffffff;
  color: #000000;
}
.cs_points_toolbar_button:hover i,
.vc_button:hover i,
.auth_button:hover i,
.filemanager_modal_button:hover i,
.cs_feature_popup_edit_button:hover:not(:disabled) i {
  color: #000000;
}


/* ═══ 7. LOOSE ENDS ═══════════════════════════════════════════════════════
   Colours named as literals rather than through a token, so section 1's
   :root pass could not reach them - plus the one border in the app that
   style.css deliberately blanks and nothing switches back on. */

/* The layers-list checkboxes. style.css's "No borders" pass ends with
   `.side-panel * { border-color: transparent !important }` - a catch-all
   that ui_borders_squared out-specifies for every element it NAMES, but
   .cs_checkbox_input is not one of them (section 3d there excludes
   [type=checkbox] outright), so the checkboxes have been drawing a 1px
   TRANSPARENT border inside a transparent container: present in the
   layout, invisible on screen. Named here at the same !important weight,
   so a checkbox is a visible white square whether it is ticked or not. */
.cs_checkbox_input,
.side-panel .cs_checkbox_input,
.cs_checkbox_input:hover,
.cs_checkbox_input:checked,
.cs_checkbox_input:indeterminate {
  border-color: #ffffff !important;
  background-color: #000000 !important;
}
.cs_checkbox_input:checked::after,
.cs_checkbox_input:indeterminate::after {
  background-color: #ffffff !important;
}

/* the translucent-white washes the layers list used to separate a service
   sub-panel from the category around it, and the local filter row from the
   layers under it. The line grid does that job now, so all of them go to
   the same black every other surface is. */
.cs_service_sub_panel,
.cs_service_sub_panel_content,
.cs_local_filter_row,
.filemanager_add_btn {
  background-color: #000000 !important;
  background-image: none !important;
}
.cs_feature_popup_card_close:hover {
  background-color: #ffffff !important;
  color: #000000 !important;
}

/* every popup surface flattened to solid black - the .88-alpha near-black
   these carried let the basemap tint the panel a slightly different grey
   depending on what happened to be underneath it */
.side-panel,
.sliding_menu,
.sliding_menu_content,
.control_panel,
.view_controls_panel,
.overlay_panel,
.filemanager_panel,
.filemanager_modal,
.search_popup,
.cs_feature_profile_popup,
.cs_panel_container_expandable,
.cs_measurement_panels_container,
.cs_input_bar,
.bottom_popup_container,
.marker_direction_nav_bar,
.marker_travel_panel,
.top_nav_container,
.left_nav_sidebar,
.footer_nav_bar,
.user_dropdown,
.auth_modal,
.cs_qr_share_modal_content,
.maplibregl-popup-content {
  background-color: #000000 !important;
  background-image: linear-gradient(#000000, #000000) !important;
  backdrop-filter: none !important;
  -webkit-backdrop-filter: none !important;
}


/* ═══ 8. THE SCROLLBAR IS ONE MORE CELL IN THE GRID ═══════════════════════
   A classic scrollbar carves its width out of the content area, so a 4px
   track left every row in the layers list ending 4px short of the panel's
   own right border - one black gutter running down the outside of an
   otherwise seamless grid. It cannot be made to overlay the content, so it
   is drawn as part of the grid instead: a black track divided from the rows
   by the same single white line every other cell boundary uses, and a solid
   white thumb with no radius and no border of its own. */
.cs_scrollable_content_container,
.panel-content,
.sliding_menu_content,
.overlay_panel_content,
.filemanager_panel_content,
.cs_panel_content_scrollable {
  scrollbar-width: thin;
  scrollbar-color: #ffffff #000000;
}
.cs_scrollable_content_container::-webkit-scrollbar,
.panel-content::-webkit-scrollbar,
.sliding_menu_content::-webkit-scrollbar,
.overlay_panel_content::-webkit-scrollbar,
.filemanager_panel_content::-webkit-scrollbar,
.cs_panel_content_scrollable::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}
.cs_scrollable_content_container::-webkit-scrollbar-track,
.panel-content::-webkit-scrollbar-track,
.sliding_menu_content::-webkit-scrollbar-track,
.overlay_panel_content::-webkit-scrollbar-track,
.filemanager_panel_content::-webkit-scrollbar-track,
.cs_panel_content_scrollable::-webkit-scrollbar-track {
  background-color: #000000;
  border-radius: 0;
  border-left: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible);
}
.cs_scrollable_content_container::-webkit-scrollbar-thumb,
.panel-content::-webkit-scrollbar-thumb,
.sliding_menu_content::-webkit-scrollbar-thumb,
.overlay_panel_content::-webkit-scrollbar-thumb,
.filemanager_panel_content::-webkit-scrollbar-thumb,
.cs_panel_content_scrollable::-webkit-scrollbar-thumb {
  background-color: #ffffff;
  border: 0;
  border-radius: 0;
}


/* ═══ 9. THE LAST FEW INSETS ══════════════════════════════════════════════
   Wrappers that pad their contents away from the panel edge, which is what
   leaves a row's line stopping short of the border it should be meeting.
   Every list in the app is edge-to-edge now, so the padding goes and the
   rows inside close against the panel's own box. */
.features-content,
.feature-content,
.panel-content,
.tab-content,
.cs_content_scrollable_area,
.cs_scrollable_content_container,
#basemap-scrollable-container,
#layers-scrollable-container,
#features-scrollable-container {
  padding: 0 !important;
  max-height: none !important;
}
/* the Project tab's toolbar was a floating strip with 6px of margin under
   it; it is a row in the list now, the same 48px module as every other */
.cs_points_toolbar {
  margin: 0 !important;
  min-height: 48px;
  padding: 0 !important;
  gap: 0 !important;
  flex-wrap: nowrap;
}
.cs_points_toolbar_button {
  height: 48px !important;
  min-height: 48px;
  padding: 0 14px !important;
  margin: 0 !important;
}
.feature-list,
#points-content,
#lines-content,
#shapes-content {
  padding: 0 !important;
}

/* The basemap cards were sized for the 240px panel this side sheet used to
   be (auto-fill of 64px minimum, three columns). At the full map width that
   is nineteen columns of thumbnail with the name truncated to two words and
   an ellipsis. The same auto-fill against a 150px minimum keeps the card
   readable and still fills whatever width the panel actually has - three
   columns on a phone, seven or eight on a desktop - rather than pinning a
   column count to either. */
#basemap-list {
  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)) !important;
}

/* Section 7 sets the checkbox border unconditionally, which is later in this
   file than section 1's inverted-row rules and therefore wins over them - so
   the checkbox in a hovered (white) row was drawing a white border on white.
   Re-stated here, last, at one level deeper so the inversion holds all the
   way down the row. */
.cs_category_header:hover .cs_checkbox_input,
.cs_service_sub_panel_header:hover .cs_checkbox_input,
.cs_layer_item:hover .cs_checkbox_input,
.side-panel .cs_category_header:hover .cs_checkbox_input,
.side-panel .cs_service_sub_panel_header:hover .cs_checkbox_input,
.side-panel .cs_layer_item:hover .cs_checkbox_input {
  border-color: #000000 !important;
  background-color: #ffffff !important;
}
.cs_category_header:hover .cs_checkbox_input:checked::after,
.cs_service_sub_panel_header:hover .cs_checkbox_input:checked::after,
.cs_layer_item:hover .cs_checkbox_input:checked::after,
.cs_category_header:hover .cs_checkbox_input:indeterminate::after,
.cs_service_sub_panel_header:hover .cs_checkbox_input:indeterminate::after,
.cs_layer_item:hover .cs_checkbox_input:indeterminate::after {
  background-color: #000000 !important;
}

/* an empty count cell is not a cell - the filter row shows it only once a
   filter is actually narrowing the list */
.cs_local_filter_count:empty {
  display: none;
}

/* the View Controls blocks were separated by a margin rather than by a line,
   which read as two rules a gap apart instead of one. They stack flush now,
   like every other list of rows in the app. */
.vc_control_block,
.vc_input_row,
.vc_distance_row,
.overlay_control_group,
.overlay_export_section,
.filemanager_modal_field {
  margin: 0 !important;
}


/* ═══ 10. THE SEARCH POPUP ════════════════════════════════════════════════
   The top search bar is the same one-row-of-cells shape as the panel search
   field in section 6, just built from different class names (.search_container
   with an underscore is the popup's row; .search-container with a hyphen is
   the one inside a side panel). It is the only child of .search_popup and
   spans it exactly, so its own four-sided box doubled the popup's on all
   four sides. */
.search_container,
.search_results_container {
  border-top: 0 !important;
  border-left: 0 !important;
  border-right: 0 !important;
  border-bottom: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  background: #000000 !important;
  box-sizing: border-box;
}
.search_popup > .search_container:last-child,
.search_results_container:last-child {
  border-bottom: 0 !important;
}
.search_icon_left {
  position: static !important;
  transform: none !important;
  flex: 0 0 var(--popup_header_cell);
  width: var(--popup_header_cell);
  height: var(--popup_header_cell);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 !important;
  padding: 0 !important;
  color: #ffffff;
  border: 0 !important;
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  box-sizing: border-box;
}
.search_input {
  flex: 1;
  min-width: 0;
  height: var(--popup_header_cell);
  padding: 0 12px !important;
  margin: 0 !important;
  border: 0 !important;
  border-radius: 0 !important;
  background: #000000 !important;
  color: #ffffff;
  font-family: ui-monospace, "SFMono-Regular", "Liberation Mono", Menlo,
    Consolas, monospace;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  outline: none !important;
  box-shadow: none !important;
}
.search_input::placeholder {
  color: #ffffff;
  opacity: 0.55;
  text-transform: uppercase;
  letter-spacing: 0.08em;
}
.clear_search,
.search_div {
  flex: 0 0 var(--popup_header_cell);
  width: var(--popup_header_cell) !important;
  height: var(--popup_header_cell) !important;
  min-width: var(--popup_header_cell);
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 0 !important;
  padding: 0 !important;
  border: 0 !important;
  border-left: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  border-radius: 0 !important;
  background: #000000 !important;
  color: #ffffff;
  box-sizing: border-box;
}
.clear_search:hover,
.search_div:hover {
  background: #ffffff !important;
  color: #000000 !important;
}
.clear_search:hover i,
.search_div:hover i {
  color: #000000 !important;
}


/* ═══ 11. THE MEASUREMENT PANEL ═══════════════════════════════════════════
   measure.css carries its own --cs_* design-token set, parallel to
   style.css's, so section 1's :root pass never reached it: the panel kept a
   three-step translucent grey palette and a 16%-white border while the rest
   of the app went to one black and one white. The tokens are re-pointed here
   for the same reason they were re-pointed there - one edit rather than a
   hundred - and the panel's own insets go the same way every other list's
   did. */
:root,
:root:root {
  --cs_color_background_primary: #000000;
  --cs_color_background_secondary: #000000;
  --cs_color_background_tertiary: #000000;
  --cs_color_background_hover: #ffffff;
  --cs_color_border_primary: #ffffff;
  --cs_color_border_secondary: #ffffff;
  --cs_color_border_muted: #ffffff;
  --cs_color_text_primary: #ffffff;
  --cs_color_text_secondary: #ffffff;
  --cs_color_text_muted: #ffffff;
  --cs_color_accent_primary: #ffffff;
  --cs_color_accent_secondary: #ffffff;
}

/* the panel body ran its sections as free-floating cards - 10px of padding
   round the scroller, 10px between each card, and a box on each. They are
   rows in a stack now, like every other list in the app. */
.cs_panel_content_scrollable {
  padding: 0 !important;
}
.cs_measurement_section_container,
.cs_measurement_panel_expandable {
  margin: 0 !important;
  border: 0 !important;
  border-bottom: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  background: #000000 !important;
}
.cs_measurement_section_container {
  padding: 12px !important;
}
.cs_measurement_panels_container {
  gap: 0 !important;
  width: 100% !important;
  max-width: 100% !important;
  box-sizing: border-box;
}
.cs_section_label_typography {
  margin: 0 0 8px 0 !important;
  height: auto;
}
.cs_select_dropdown_input,
.cs_inline_input_field {
  margin: 0 !important;
  background: #000000 !important;
  color: #ffffff !important;
  border-radius: 0 !important;
}

/* the header row: with the chevron moved into the first cell, the old
   space-between pushed the title all the way to the panel's right edge and
   clipped it. The row packs from the left now and the title takes the
   remaining width. */
.cs_measurement_panel_header,
.cs_panel_header_collapsible {
  justify-content: flex-start !important;
  padding: 0 !important;
  gap: 0;
}
.cs_measurement_panel_header .cs_panel_header_title,
.cs_panel_header_collapsible .panel-header-title,
.cs_panel_header_collapsible .cs_panel_header_title {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0 12px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
/* the chevron cell, divided from the title by the same single line */
.cs_measurement_panel_header .cs_panel_expand_indicator,
.cs_panel_header_collapsible .cs_panel_expand_indicator {
  border-right: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible);
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: transform 0.2s ease;
}
/* whatever trails the title (a close button, a control group) closes the
   row on the right rather than floating in the middle of it */
.cs_panel_header_collapsible > *:last-child {
  margin-left: auto;
}
.cs_close_button_circular {
  background: #000000 !important;
  border: 0 !important;
  border-left: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  border-radius: 0 !important;
  width: 48px !important;
  height: 48px !important;
  min-width: 48px !important;
  max-width: 48px !important;
  min-height: 48px !important;
  max-height: 48px !important;
  font-size: 14px !important;
}
.cs_close_button_circular:hover {
  background: #ffffff !important;
  color: #000000 !important;
}

/* the same 400px clip the layers list had, for the same reason and with the
   same fix - an open measurement list is as tall as its contents and
   scrolls in the panel's own scroller */
.cs_measurement_panel_content {
  max-height: none !important;
}
.cs_measurement_panel_content.state_collapsed,
.cs_measurement_panel_expandable.state_collapsed .cs_measurement_panel_content {
  max-height: 0 !important;
}

/* the clear-all action is a full-width row at the foot of the panel, not a
   card floating inside it */
.cs_clear_all_button_action {
  width: 100% !important;
  margin: 0 !important;
  border: 0 !important;
  border-top: var(--ui_border_uniform_width, 1px) solid var(--ui_border_visible) !important;
  border-radius: 0 !important;
  background: #000000 !important;
  color: #ffffff !important;
  height: 48px;
  font-family: ui-monospace, "SFMono-Regular", "Liberation Mono", Menlo,
    Consolas, monospace;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
}
.cs_clear_all_button_action:hover {
  background: #ffffff !important;
  color: #000000 !important;
}

/* the running total is deliberately the inverted row - white ground, black
   figure - which is exactly the "on" state the rest of the app uses. It just
   has to be a ROW: it was floating on 10px of margin, which left a white
   card with a black gutter round it instead of one band across the panel. */
.cs_total_distance_display {
  margin: 0 !important;
  border-radius: 0 !important;
  width: 100%;
  box-sizing: border-box;
}


/* ═══ 12. THE FIELDS THAT ARE CELLS, NOT BOXES ════════════════════════════
   ui_borders_squared gives every field in the app a box through
   `input:not([type=range]):not([type=checkbox]):not([type=radio])`. Three
   attribute selectors inside :not() make that (0,3,1) - more specific than
   the single class each of the rules above uses, so `border: 0 !important`
   on `.search-box` lost to it and the search field kept a full four-sided
   box: doubled against the glyph cell on its left, against the tab strip
   above it, and against the row's own bottom line.

   These three fields are the ones that are CELLS in a row - their edges
   are already drawn by the row and the cell beside them. Repeating the
   class carries them to (0,4,0), which outranks (0,3,1) on class count
   without reaching for an id. Every other field in the app is
   free-standing (section 2f) and keeps the box it is given. */
.search-box.search-box.search-box.search-box,
.search_input.search_input.search_input.search_input,
.cs_local_filter_input.cs_local_filter_input.cs_local_filter_input.cs_local_filter_input {
  border: 0 !important;
  border-radius: 0 !important;
  outline: none !important;
  box-shadow: none !important;
}


/* ═══ 13. IN THE LAYERS TREE, ONLY ROWS DRAW LINES ════════════════════════
   Section 2a gave every box in the layers tab the same "bottom line only"
   treatment - but that tab is four containers deep, and a container's
   closing edge lands on the same pixel as the last row inside it. A
   collapsed service sub-panel stacked three lines in two pixels: the
   header's bottom rule at 38px, the collapsed content's own rule (a
   max-height:0 box still paints its border) one pixel below it, and the
   sub-panel's closing rule one pixel below that. The same happened at the
   foot of every expanded category.

   The tree is re-cut here on one rule: a ROW draws a line, a CONTAINER
   never does. There is no closing edge to double against any more, so the
   last row in a stack keeps the line section 2a took off it - and that
   line IS the division between one category and the next. */
.cs_category_container,
.cs_category_content_wrapper,
.cs_service_sub_panel,
.cs_service_sub_panel_content,
.cs_layer_list_container {
  border-bottom: 0 !important;
}
/* rows: the last one in a stack now closes it, so it keeps the rule
   section 2a took off it. The list's own last child is deliberately NOT in
   this set - it is a category CONTAINER, and a container that drew a line
   here would put one a pixel under the last header's, then a third against
   the panel's bottom edge. */
.cs_category_content_wrapper > :last-child,
.cs_service_sub_panel_content > :last-child {
  border-bottom: var(--ui_border_uniform_width, 1px) solid
    var(--ui_border_visible) !important;
}

/* The foot of the list is the one place a row's line still meets an edge it
   did not draw: scrolled to the bottom, the last row's rule lands on the
   panel's own bottom border and the two read as a 2px band. Same fix the
   basemap grid uses - the list hangs one pixel past the scrollport, the
   scroller clips it, and the panel's border is the single closing line. */
.cs_layer_list_container,
#layer-list,
#features-list,
.cs_feature_list_container {
  margin-bottom: calc(var(--ui_border_uniform_width, 1px) * -1) !important;
}
