* {
    box-sizing: border-box;
}

html {
    font-size: 16px; /* Base font size */
}

body {
    margin: 0;
    padding: 0;
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
    font-size: 1rem;
    background: #f0f0f0;
    color: #333;
}

.screen-reader-only {
    position: absolute;
    width: 1px;
    height: 1px;
    padding: 0;
    margin: -1px;
    overflow: hidden;
    clip: rect(0, 0, 0, 0);
    white-space: nowrap;
    border: 0;
}

/* Skip links — off-screen until focused, then pinned top-left. White on dark
   blue is ~9:1 (AAA); generous height/padding clears the WCAG 2.2 target size. */
/* An authored display beats the [hidden] attribute's UA display:none — make
   hidden mean hidden (the compass toggle hides the skip-to-compass link; the
   disclaimer gate hides the whole app main until accepted). */
.skip-link[hidden],
main[hidden] {
    display: none;
}

/* ---- Disclaimer gate: shown before the map, like every map in this family. */
.map-gate {
    max-width: 44rem;
    margin: 0 auto;
    padding: 1.5rem 1.25rem 3rem;
    font-size: 1rem;
    line-height: 1.55;
    color: #1a1a1a;
}
.map-gate h1 {
    font-size: 1.5rem;
    margin: 0 0 0.25rem;
}
.map-gate h2 {
    font-size: 1.125rem;
    margin: 0 0 0.75rem;
}
.map-gate__body ul {
    padding-left: 1.25rem;
}
.map-gate__body li {
    margin-bottom: 0.5rem;
}
.map-gate__consent label {
    display: flex;
    gap: 0.625rem;
    align-items: flex-start;
}
.map-gate__consent input {
    width: 1.375rem;
    height: 1.375rem;
    flex: none;
}
.map-gate__start {
    width: auto;
    font-size: 1rem;
    padding: 0.625rem 1.25rem;
    margin-top: 0.75rem;
}
.map-gate__start:disabled {
    opacity: 0.55;
    cursor: not-allowed;
}
/* Dark mode for the gate — it inherited the dark body background while keeping
   its light-mode #1a1a1a text: black on black (seen live). */
@media (prefers-color-scheme: dark) {
    .map-gate { color: #e0e0e0; }
    .map-gate h1,
    .map-gate h2 { color: #f0f0f0; }
}

.skip-link {
    position: absolute;
    left: 0.5rem;
    top: -10rem;
    z-index: 200;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0.5rem 0.875rem;
    background: #08407a;
    color: #ffffff;
    font-size: 1rem;
    text-decoration: underline;
    border-radius: 0 0 4px 4px;
}

.skip-link:focus {
    top: 0;
    outline: 3px solid #ffffff;
    outline-offset: -3px;
}


/* Control Sidebar */
.control-sidebar {
    position: fixed;
    top: 1rem;
    left: 1rem;
    width: 15rem; /* 240px */
    max-height: calc(100vh - 2rem);
    background: rgba(255, 255, 255, 0.98);
    backdrop-filter: blur(10px);
    -webkit-backdrop-filter: blur(10px);
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    border-radius: 0.5rem;
    z-index: 90;
    transition: transform 0.3s ease;
    overflow-y: auto;
    overflow-x: hidden;
}

.control-sidebar.collapsed {
    width: auto;
    overflow: hidden;
}

.control-sidebar.collapsed .sidebar-content {
    display: none;
}

.control-sidebar.collapsed .sidebar-header {
    border-bottom: none;
}

/* Sidebar Header */
.sidebar-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 0.5rem 0.75rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.sidebar-title {
    margin: 0;
    font-size: 0.875rem; /* 14px */
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.sidebar-toggle {
    background: transparent;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    padding: 0.5rem;
    font-size: 1.25rem;
    transition: all 0.2s;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 2rem;
    height: 2rem;
    margin-left: 0.5rem;
    flex-shrink: 0;
}

.sidebar-toggle:hover {
    background: rgba(0, 0, 0, 0.05);
}

.sidebar-toggle:focus {
    outline: 2px solid #0066ff;
    outline-offset: 2px;
}

.control-sidebar.collapsed .sidebar-toggle .icon {
    transform: rotate(180deg);
}

/* Sidebar Content */
.sidebar-content {
    padding: 0.75rem;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
}

/* Control Buttons */
.control-button {
    width: 100%;
    padding: 0.5rem 0.75rem;
    border: 1px solid #ddd;
    background: #fff;
    border-radius: 6px;
    cursor: pointer;
    font-size: 1rem; /* 16px - default */
    display: flex;
    align-items: center;
    gap: 0.5rem;
    transition: background 0.15s ease, border-color 0.15s ease;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
}

.control-button:hover {
    background: #f8f8f8;
    border-color: #999;
}

.control-button:focus {
    outline: 2px solid #0066ff;
    outline-offset: 2px;
}

.control-button[aria-pressed="true"] {
    background: #e3f2fd;
    color: #0066ff;
    border-color: #0066ff;
}

.control-button .icon {
    font-size: 0.875rem;
    flex-shrink: 0;
}

.control-button .label {
    flex: 1;
    white-space: nowrap;
}

/* Accordion Styles */
.accordion-item {
    border: 1px solid #ddd;
    border-radius: 6px;
    overflow: hidden;
}

.accordion-header {
    width: 100%;
    padding: 0.5rem 0.75rem;
    background: #fff;
    border: none;
    cursor: pointer;
    font-size: 0.8rem;
    display: flex;
    align-items: center;
    gap: 0.5rem;
    transition: background 0.15s ease;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
}

.accordion-header:hover {
    background: #f8f8f8;
}

.accordion-header:focus {
    outline: 2px solid #0066ff;
    outline-offset: -2px;
}

.accordion-header .icon {
    font-size: 0.875rem;
    flex-shrink: 0;
}

.accordion-arrow {
    margin-left: auto;
    transition: transform 0.2s;
    font-size: 0.8rem;
}

.accordion-header[aria-expanded="true"] .accordion-arrow {
    transform: rotate(180deg);
}

.accordion-content {
    padding: 0.5rem 0.75rem;
    background: #f9f9f9;
}

.accordion-content fieldset {
    border: none;
    padding: 0;
    margin: 0;
}

.accordion-content label {
    display: block;
    padding: 0.25rem 0;
    cursor: pointer;
    font-size: 0.6875rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.accordion-content label:hover {
    background: rgba(0, 0, 0, 0.05);
    padding-left: 0.5rem;
    margin-left: -0.5rem;
    margin-right: -0.5rem;
}

.accordion-content input {
    margin-right: 0.5rem;
}

/* Filter and Rotor Categories */
.filter-category,
.rotor-category {
    margin-bottom: 0.75rem;
    padding-bottom: 0.5rem;
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}

.filter-category:last-child,
.rotor-category:last-child {
    border-bottom: none;
    margin-bottom: 0;
}

.filter-category-title,
.rotor-category-title {
    font-size: 0.625rem;
    font-weight: 600;
    text-transform: uppercase;
    color: #333;
    margin: 0 0 0.25rem 0;
    letter-spacing: 0.02em;
}

.filter-category label,
.rotor-category label {
    margin-left: 0.5rem;
    font-size: 0.6875rem;
}

/* Filter Subcategories */
.filter-subcategory {
    margin-bottom: 0.5rem;
    margin-left: 0.5rem;
    padding-left: 0.5rem;
    border-left: 2px solid rgba(0, 0, 0, 0.1);
}

.filter-subcategory:last-child {
    margin-bottom: 0;
}

.filter-subcategory-title {
    font-size: 0.5625rem;
    font-weight: 500;
    color: #333;
    margin: 0 0 0.25rem 0;
    text-transform: none;
}

.filter-subcategory label {
    margin-left: 0.25rem;
    font-size: 0.625rem;
}

/* Filter Accordion Items */
.filter-accordion-item {
    border: 1px solid rgba(0, 0, 0, 0.1);
    border-radius: 4px;
    margin-bottom: 0.25rem;
    overflow: hidden;
}

.filter-accordion-item:last-child {
    margin-bottom: 0;
}

.filter-accordion-header {
    width: 100%;
    padding: 0.375rem 0.5rem;
    background: #f8f9fa;
    border: none;
    cursor: pointer;
    font-size: 0.6875rem;
    display: flex;
    align-items: center;
    gap: 0.375rem;
    transition: background 0.15s ease;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
}

.filter-accordion-header:hover {
    background: #e9ecef;
}

.filter-accordion-header:focus {
    outline: 2px solid #0066ff;
    outline-offset: -2px;
}

.filter-accordion-header .icon {
    font-size: 0.75rem;
    flex-shrink: 0;
}

.filter-accordion-header .label {
    flex: 1;
    font-weight: 500;
}

.filter-accordion-header .accordion-arrow {
    margin-left: auto;
    transition: transform 0.2s;
    font-size: 0.625rem;
}

.filter-accordion-header[aria-expanded="true"] .accordion-arrow {
    transform: rotate(180deg);
}

.filter-accordion-content {
    padding: 0.375rem 0.5rem;
    background: #ffffff;
    border-top: 1px solid rgba(0, 0, 0, 0.05);
}

.filter-accordion-content label {
    display: block;
    padding: 0.1875rem 0;
    cursor: pointer;
    font-size: 0.625rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.filter-accordion-content label:hover {
    background: rgba(0, 0, 0, 0.03);
    padding-left: 0.25rem;
    margin-left: -0.25rem;
    margin-right: -0.25rem;
}

.filter-accordion-content input {
    margin-right: 0.375rem;
}

/* Subgroups inside a filter/rotor section: native fieldset+legend so a screen
   reader announces and skims the grouping without a second accordion level.
   The boundary is a GREY line (invert-safe — carried on luminance, not hue). */
.filter-subgroup {
    margin: 0.375rem 0;
    padding: 0.125rem 0.375rem 0.25rem;
    border: 1px solid #767676;
    border-radius: 4px;
    min-inline-size: 0;
}

.filter-subgroup legend {
    font-size: 0.625rem;
    font-weight: 700;
    padding: 0 0.25rem;
}


main {
    display: block;
    height: 100vh;
    position: relative;
}

#map-container {
    width: 100%;
    height: 100%;
    position: relative;
    background: #e5e3df;
    overflow: hidden;
    /* Enable touch events for pinch-to-zoom */
    touch-action: none;
}

#map-svg {
    width: 100%;
    height: 100%;
    background: #e5e3df;
}

/* Ensure map tiles render properly */
#map-tiles {
    /* Ensure tiles are behind features */
    opacity: 1;
    transition: opacity 0.3s ease;
}

#map-tiles image {
    /* Ensure no borders */
    border: none;
    stroke: none;
    /* Prevent selection highlighting */
    pointer-events: none;
}

/* Remove outlines but preserve intentional strokes */
#map-svg * {
    outline: none;
}

/* Remove default focus styles from map features */
#map-features polygon:focus,
#map-features polyline:focus,
#map-features circle:focus {
    outline: none;
}

/* Focus outline styling */
#focus-outline {
    pointer-events: none;
    z-index: 1000;
}

/* The GPS layer (accuracy disc + blue dot + heading arrow) is an overlay,
   not a feature: nothing in it is interactive (the explorable "you" is the
   avatar), so it must never shadow the map beneath — the accuracy disc can
   be tens of metres wide and was a hover/explore dead zone over everything
   it covered. */
#user-location {
    pointer-events: none;
}

/* Style map features */
#map-features polygon,
#map-features polyline,
#map-features circle {
    stroke-linejoin: round;
    stroke-linecap: round;
    pointer-events: auto;
    cursor: pointer;
}

/* ---- Target size (WCAG 2.5.8): marker dots at a constant 24px SCREEN target ----
   Markers are baked as r=5 in SVG user units, so they'd scale with zoom. The
   viewer instead drives the radius from the current scale (MapRenderer.updateViewBox
   sets --target-r = 12 * 2^(18-zoom) user-units = a 12px screen radius), so every
   dot renders at a 24px hittable target at EVERY zoom. The CSS geometry property
   `r` overrides the baked attribute. Aggregation has already spaced markers >=24px
   apart, so the dots sit tangent, not overlapping. Cluster markers are a little
   larger so they read as a group. Fallbacks keep markers visible if the var is
   ever unset. */
/* POI markers: a SMALL visible dot with a transparent 24px-screen TOUCH ring
   (WCAG 2.5.8). The dot stays small so it never buries the map (Bob 2026-06-20) —
   the target size is carried by the transparent stroke (pointer-events:all), not
   by the visible mark. Sizes are constant-screen via vars set per zoom in
   MapRenderer.updateViewBox (paint-order:stroke keeps the colour fill on top). */
#map-tiles circle {
    r: var(--dot-r, 5px);
    stroke: transparent;
    stroke-width: var(--hit-ring, 14px);
    paint-order: stroke;
    pointer-events: all;
}
#map-tiles g.cluster > circle { r: var(--cluster-r, 7px); }

/* ---- Road rendering pass (target size + low-vision perceptibility) ----
   Hit-corridor (WCAG 2.5.8): the baked transparent .road-hit stroke makes the
   whole road a 24px-SCREEN hittable target regardless of its thin visible line.
   non-scaling-stroke keeps it a constant 24px at every zoom; pointer-events:stroke
   so only the corridor catches (the visible stroke is pointer-events:none). */
#map-tiles .road-hit {
    vector-effect: non-scaling-stroke;
    stroke: transparent;
    fill: none;
    stroke-width: 24px;
    pointer-events: stroke;
}
/* Never-hairline (low vision): pin road + casing strokes to a constant screen
   width so they never thin to a hair when zoomed out. */
#map-tiles g.road [stroke]:not([stroke="none"]),
#map-tiles g.road-casings [stroke]:not([stroke="none"]) {
    vector-effect: non-scaling-stroke;
}

/* Ensure proper rendering order */
#roads-group {
    /* Roads should render under buildings */
}

.road-casing {
    /* Road casings provide the border */
    opacity: 0.8;
}

.road {
    /* Road surface */
}

/* In-road street names. Bob: a thin minor-road casing isn't wide enough to back the
   name, so it spilled onto the terrain as unreadable dark-on-green. Give the label a
   WHITE HALO so it stays legible wherever it sits — on the road OR off it. The halo
   is non-scaling (constant screen width) and painted BEHIND the fill; the text size
   is the constant-screen --label-size. The dark-map + high-contrast blocks flip the
   colours (light text, dark halo) and inherit the rest. (Halo + text invert together
   under macOS Invert, so legibility survives.) */
#map-tiles text.road-label {
    font-size: var(--label-size);
    font-weight: 600;
    fill: #1a1a1a;
    stroke: #ffffff;
    stroke-width: 3.5px;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
    paint-order: stroke;
}

/* Heading-up rotation: labels RIDE the rotating map (a road name stays in its casing,
   along the road). When the map's rotation would make a label read UPSIDE-DOWN, the
   viewer adds .label-flip and we rotate it 180° around its own centre (transform-box:
   fill-box) so it reads the right way up — still in the casing. */
#map-tiles text.label-flip {
    transform-box: fill-box;
    transform-origin: center;
    transform: rotate(180deg);
}

#map-container:focus {
    outline: 3px solid #4285F4;
    outline-offset: -3px;
}

/* The map canvas is tab-reachable (tabindex on #map-svg); inset so the ring
   stays visible when the canvas fills the viewport edge-to-edge. */
#map-svg:focus {
    outline: 3px solid #4285F4;
    outline-offset: -3px;
}

/* ---- Non-text contrast: feature boundaries (WCAG 1.4.11) ----
   The soft OSM fills are kept, but every area feature and road casing gets a
   mid-GREY boundary that clears 3:1 on the light map background (#e5e3df ~5:1
   at #5f5f5f). Grey is deliberate: macOS "Invert colours" just flips a grey's
   luminance so the boundary's contrast survives, whereas a coloured edge can
   invert into a low-contrast hue (green -> magenta). Road COLOURS are left
   alone (they carry meaning) — the casing provides their boundary. The high-
   contrast media query darkens these further. */
#map-tiles :is(g.building, g.landuse, g.park, g.vegetation, g.water, g.parking,
               g.religious, g.natural, g.aeroway, g.indoor, g.man_made,
               g.barrier, g.railway) [stroke]:not([stroke="none"]):not(.level-line):not(.level-halo):not(.level-casing):not(.level-area):not(.underpass-line),
#map-tiles g.road-casings [stroke]:not([stroke="none"]) {
    stroke: #5f5f5f;
}


/* ---- Multi-level model: independent OVERLAY toggles (checkboxes) -------
   Tile features carry data-level for off-surface planes (path / subway / above); the
   street level is untagged. Each plane is an independent checkbox (Bob, 2026-06-23):
   LevelSwitch adds a `show-<plane>` class to #map-tiles when its box is checked, so
   you can show any COMBINATION (e.g. street + Gardiner + subway). Pure CSS so it also
   governs tiles injected later. */
/* An off-surface plane is hidden UNLESS its toggle is on. */
#map-tiles:not(.show-above)  [data-level="above"]  { display: none; }
#map-tiles:not(.show-path)   [data-level="path"]   { display: none; }
#map-tiles:not(.show-transit) [data-level="transit"] { display: none; }
/* The street level (untagged groups + their per-category casings) hides only if its
   own toggle is off. (Exclude the pooled level casings, which follow their plane.) */
#map-tiles:not(.show-surface) :is([role="img"]:not([data-level]), [class$="-casings"]:not(.levels-casings)) { display: none; }
/* The whole map keeps working as usual when an overlay is on (Bob, 2026-06-23) —
   FULL brightness AND fully interactive (hover, keyboard, tooltips). An overlay just
   sits ON TOP and COVERS its own footprint: where the Gardiner is drawn it's opaque
   and its wide hit-corridor (below) intercepts the pointer, so you get the Gardiner
   there, not Lake Shore peeping through — everywhere else the street is untouched. */

/* Active sub-plane PROMINENCE: when its plane is selected, an off-surface feature
   reads as a BOLD CASED ROUTE over the FULL-BRIGHTNESS street level — a wide light
   HALO (clear-space moat that punches clear space through the base map) + a dark
   CASING + a bold coloured line. This halo is what makes the overlay legible without
   dimming anything else. The .level-* parts are baked by the generator and only
   paint when the feature is shown (its plane is active); they ride the top z-tier so
   the halo clears the base. Constant screen width via non-scaling-stroke. */
#map-tiles :is(.level-halo, .level-casing, .level-line) {
    fill: none; vector-effect: non-scaling-stroke;
    stroke-linecap: round; stroke-linejoin: round; pointer-events: none;
}
#map-tiles .level-halo   { stroke: #f4f3ef; stroke-width: 18px; }
#map-tiles .level-casing { stroke: #2c3034; stroke-width: 10px; }
#map-tiles .level-line   { stroke-width: 6px; stroke-dasharray: none; }
#map-tiles [data-level="path"]   .level-line { stroke: #1565c0; }
#map-tiles [data-level="transit"] .level-line { stroke: #7b1fa2; }
#map-tiles [data-level="above"]  .level-line { stroke: #c0561f; }
/* The elevated road (Gardiner) COVERS its whole footprint, like a solid deck on top
   of the map: a WIDE opaque halo spans the parallel carriageways (covering the
   surface POIs / labels / Lake Shore beneath), the casing is the structure edge, and
   the orange lanes ride on top. A matching wide HIT-corridor means hovering anywhere
   across the deck reports "Gardiner Expressway", never the surface peeping through.
   Scoped to the above plane so the PATH/subway keep their slim cased look. The rest
   of the map stays fully interactive — only the deck's own footprint is covered. */
/* NB: the halo is POOLED (a sibling of the feature group, carrying data-level on
   ITSELF), so it's matched by .level-halo[data-level=...], not a descendant selector.
   The hit-corridor stays INSIDE the group, so it is a descendant. */
#map-tiles .level-halo[data-level="above"] { stroke-width: 44px; }  /* light deck surface, spans + COVERS the footprint */
#map-tiles [data-level="above"] .road-hit  { stroke-width: 44px; }  /* match: whole deck reports the Gardiner */
/* Off-surface AREAS (e.g. the PATH concourse): solid prominent fill + dark edge. */
#map-tiles .level-area {
    vector-effect: non-scaling-stroke; stroke: #2c3034; stroke-width: 2px; paint-order: stroke;
}
#map-tiles [data-level="path"]   .level-area { fill: #cfe3f7; fill-opacity: 0.9; }
#map-tiles [data-level="transit"] .level-area { fill: #e7d6f2; fill-opacity: 0.9; }
#map-tiles [data-level="above"]  .level-area { fill: #f3ddcf; fill-opacity: 0.9; }
@media (prefers-color-scheme: dark) {
    #map-tiles .level-halo   { stroke: #14171a; }
    #map-tiles .level-casing { stroke: #c9cdd1; }
    #map-tiles [data-level="path"]   .level-line { stroke: #6db3f2; }
    #map-tiles [data-level="transit"] .level-line { stroke: #c79df0; }
    #map-tiles [data-level="above"]  .level-line { stroke: #f0a06b; }
    #map-tiles .level-area { stroke: #c9cdd1; }
    #map-tiles [data-level="path"]   .level-area { fill: #16314a; }
    #map-tiles [data-level="transit"] .level-area { fill: #2e1a40; }
    #map-tiles [data-level="above"]  .level-area { fill: #43271a; }
}

/* Underpasses — non-PATH underground pedestrian connections (station underpasses,
   ped tunnels). A DOTTED surface annotation, shown by default with its own filter
   (the .underpass group class drives hide/show; this styles the line). Distinct from
   the PATH (its own plane) and from ordinary footways. Round dots via a 0-length
   dash + round cap; constant screen size. */
#map-tiles .underpass-line {
    stroke: #5a6b7a;
    stroke-width: 2.5px;
    stroke-dasharray: 0 7;
    stroke-linecap: round;
    vector-effect: non-scaling-stroke;
}
@media (prefers-color-scheme: dark) {
    #map-tiles .underpass-line { stroke: #a6b6c4; }
}

/* Underground parking — vehicle infrastructure, OFF by default (its own filter).
   When toggled on it reads as an 'underground structure': a muted fill with a dashed
   outline (areas), distinct from surface parking. Carved out of the dark catch-alls
   so the colour holds. Areas get the dashed stroke; a node keeps its marker hit-ring
   (stroke only on polygon/path) and just takes the fill colour. */
#map-tiles .ugparking { fill: #2f6090; }
#map-tiles :is(polygon, path).ugparking {
    fill-opacity: 0.45; stroke: #1f4366;
    stroke-width: 1.5px; stroke-dasharray: 5 3; vector-effect: non-scaling-stroke;
}
@media (prefers-color-scheme: dark) {
    #map-tiles .ugparking { fill: #6fa3d6; }
    #map-tiles :is(polygon, path).ugparking { fill: #1c3450; fill-opacity: 0.55; stroke: #7ea8d6; }
}

/* The Map Level accordion is retired — the vertical planes are driven from
   the chat ("show the PATH"); LevelSwitch.js owns the state. */


#directions-list {
    max-height: 200px;
    overflow-y: auto;
    font-size: 0.75rem;
    line-height: 1.4;
}

.location-info {
    position: absolute;
    bottom: 1rem;
    left: 1rem;
    background: #fff;
    padding: 1rem;
    border-radius: 4px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
    font-size: 0.9rem;
}

.location-info p {
    margin: 0 0 0.5rem 0;
}

.location-info p:last-child {
    margin-bottom: 0;
}

.debug-panel {
    position: absolute;
    bottom: 1rem;
    right: 1rem;
    background: #fff;
    padding: 1rem;
    border-radius: 4px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.2);
    width: 300px;
}

.debug-panel h3 {
    margin: 0 0 1rem 0;
    font-size: 1rem;
}

.debug-panel label {
    display: block;
    margin-bottom: 0.25rem;
    font-size: 0.9rem;
}

.debug-panel input {
    width: 100%;
    padding: 0.25rem;
    margin-bottom: 0.5rem;
    border: 1px solid #ddd;
    border-radius: 2px;
}

.debug-panel button {
    padding: 0.5rem 1rem;
    background: #4285F4;
    color: #fff;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 0.9rem;
}

/* Dark mode support */
@media (prefers-color-scheme: dark) {
    body {
        background: #1a1a1a;
        color: #e0e0e0;
    }
    
    .control-sidebar {
        background: rgba(30, 30, 30, 0.95);
        box-shadow: 0 4px 20px rgba(0, 0, 0, 0.5);
    }
    
    .sidebar-header {
        border-bottom-color: rgba(255, 255, 255, 0.1);
    }
    
    .sidebar-title {
        color: #e0e0e0;
    }
    
    .sidebar-toggle {
        background: transparent;
        border-color: #555;
        color: #e0e0e0;
    }
    
    .sidebar-toggle:hover {
        background: rgba(255, 255, 255, 0.1);
        border-color: #777;
    }
    
    .control-button,
    .accordion-item {
        background: #2a2a2a;
        border-color: #444;
        color: #e0e0e0;
    }
    
    .control-button:hover,
    .accordion-header:hover {
        background: #333;
        border-color: #555;
    }
    
    .control-button[aria-pressed="true"] {
        background: #1976d2;
        color: #fff;
        border-color: #1976d2;
    }
    
    .accordion-header {
        background: #2a2a2a;
        color: #e0e0e0;
    }
    
    .accordion-content {
        background: #252525;
        color: #e0e0e0;
    }
    
    #map-container {
        background: #1a1a1a;
    }
    
    #map-svg {
        background: #1a1a1a;
    }
    
    /* Map FEATURE colours for dark mode are themed in one consolidated block at
       the end of this file (targets the shapes, covers every category). These
       old g-level rules were ineffective — a shape's own fill/stroke attribute
       wins over a value inherited from its <g>. */

    .location-info,
    .debug-panel {
        background: rgba(30, 30, 30, 0.95);
        color: #e0e0e0;
    }
    
    input {
        background: #2a2a2a;
        color: #e0e0e0;
        border-color: #555;
    }
    
    input:focus {
        border-color: #1976d2;
    }
    
    /* Compass navigator dark mode */
    .nav-button {
        background: rgba(40, 40, 40, 0.95);
        border-color: rgba(255, 255, 255, 0.2);
    }
    
    .nav-button:hover {
        background: rgba(60, 60, 60, 0.95);
    }
    
    .nav-center {
        background: rgba(40, 40, 40, 0.98);
        border-color: rgba(255, 255, 255, 0.1);
    }
    
    .nav-zoom {
        background: linear-gradient(135deg, #2a2a2a 0%, #333 100%);
    }
    
    .nav-zoom:hover {
        background: linear-gradient(135deg, #333 0%, #3a3a3a 100%);
    }
    
    .nav-center-btn {
        background: #2a2a2a;
        border-color: rgba(255, 255, 255, 0.3);
    }
    
    .nav-center-btn:hover {
        background: #333;
    }
}

/* Filter Category Titles - Dark Mode */
@media (prefers-color-scheme: dark) {
    .filter-category-title,
    .rotor-category-title {
        color: #b0b0b0 !important;
    }
    
    .filter-subcategory-title {
        color: #a0a0a0 !important;
    }
    
    /* Filter Accordion Items - Dark Mode */
    .filter-accordion-item {
        border-color: #444;
    }
    
    .filter-accordion-header {
        background: #2a2a2a;
        color: #e0e0e0;
    }
    
    .filter-accordion-header:hover {
        background: #333;
    }
    
    .filter-accordion-content {
        background: #252525;
        color: #e0e0e0;
        border-top-color: rgba(255, 255, 255, 0.1);
    }
    
    .filter-accordion-content label {
        color: #e0e0e0;
    }
    
    .filter-accordion-content label:hover {
        background: rgba(255, 255, 255, 0.05);
    }

    .filter-subgroup {
        border-color: #8a8a8a;
    }
}

/* High contrast mode support */
@media (prefers-contrast: high) {
    body {
        background: #000;
        color: #fff;
    }
    
    .control-sidebar {
        background: #000;
        border: 2px solid #fff;
        box-shadow: none;
    }
    
    .sidebar-header {
        border-bottom: 2px solid #fff;
    }
    
    .sidebar-toggle,
    .control-button,
    .accordion-item {
        background: #000;
        border: 2px solid #fff;
        color: #fff;
    }
    
    .sidebar-toggle:hover,
    .control-button:hover,
    .accordion-header:hover {
        background: #fff;
        color: #000;
    }
    
    .control-button[aria-pressed="true"] {
        background: #fff;
        color: #000;
    }
    
    .accordion-content {
        background: #000;
        border-top: 2px solid #fff;
    }
    
    /* Map background for high contrast is set with the feature-boundary block
       at the end of this file (#ffffff — soft fills + dark edges, invert-safe). */
    
    /* Map FEATURE colours for high contrast are themed in the consolidated block
       at the end of this file (targets the shapes, covers every category). */

    /* Focus outlines more prominent */
    *:focus {
        outline: 3px solid #ff0;
        outline-offset: 2px;
    }
    
    /* Compass navigator high contrast */
    .nav-button {
        background: #000;
        border: 2px solid #fff;
    }
    
    .nav-button:hover,
    .nav-button:focus {
        background: #fff;
    }
    
    .nav-button:hover svg,
    .nav-button:focus svg {
        fill: #000;
        stroke: #000;
    }
    
    .nav-center {
        background: #000;
        border: 2px solid #fff;
    }
    
    .nav-zoom {
        background: #000;
        border: 2px solid #fff;
    }
    
    .nav-zoom:hover {
        background: #fff;
    }
    
    .nav-zoom:hover svg {
        stroke: #000;
    }
    
    .nav-center-btn {
        background: #000;
        border: 2px solid #fff;
    }
    
    .nav-center-btn:hover {
        background: #fff;
    }
    
    .nav-center-btn:hover svg {
        fill: #000;
        stroke: #000;
    }
}

/* Filter Accordion High Contrast Support */
@media (prefers-contrast: high) {
    /* Filter Category Titles - High Contrast */
    .filter-category-title,
    .rotor-category-title,
    .filter-subcategory-title {
        color: #fff;
    }
    
    /* Filter Accordion Items - High Contrast */
    .filter-accordion-item {
        background: #000;
        border: 2px solid #fff;
    }
    
    .filter-accordion-header {
        background: #000;
        color: #fff;
        border: none;
    }
    
    .filter-accordion-header:hover {
        background: #fff;
        color: #000;
    }
    
    .filter-accordion-content {
        background: #000;
        color: #fff;
        border-top: 2px solid #fff;
    }
    
    .filter-accordion-content label {
        color: #fff;
    }
    
    .filter-accordion-content label:hover {
        background: #fff;
        color: #000;
    }
    
    .filter-accordion-content input {
        background: #000;
        border: 1px solid #fff;
    }

    .filter-subgroup {
        border: 2px solid #fff;
    }
}

/* Compass Navigator */
/* Defensive: keep the [hidden] attribute authoritative for the settings
   toggle even if a display rule is ever added to the compass. */
.compass-navigator[hidden] {
    display: none;
}

.compass-navigator {
    position: fixed;
    right: 1rem;
    bottom: 1rem;
    width: 15rem; /* 240px - expanded for better spacing */
    height: 15rem;
    z-index: 80;
}

.compass-ring {
    position: relative;
    width: 100%;
    height: 100%;
}

/* Direction buttons - positioned absolutely in circle */
.nav-button {
    position: absolute;
    width: 3rem;  /* 48px - exceeds WCAG 2.2 AA minimum */
    height: 3rem;
    border: 2px solid rgba(0, 0, 0, 0.2);
    background: rgba(255, 255, 255, 0.95);
    border-radius: 50%;
    cursor: pointer;
    transition: transform 0.2s ease, box-shadow 0.2s ease, background 0.2s ease;
    box-shadow: 0 3px 10px rgba(0, 0, 0, 0.2);
    display: flex;
    align-items: center;
    justify-content: center;
    backdrop-filter: blur(10px);
}

.nav-button svg {
    width: 2rem; /* 32px */
    height: 2rem;
    fill: #333;
    stroke: #333;
    stroke-width: 2;
    transition: all 0.2s ease;
}

.nav-button:hover,
.nav-button:focus {
    background: #fce4ec;
    transform: scale(1.1);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.25);
    border-color: rgba(233, 30, 99, 0.3);
}

.nav-button:hover svg,
.nav-button:focus svg {
    fill: #e91e63;
    stroke: #e91e63;
}

.nav-button:focus,
.nav-button:hover {
    outline: none;
}

.nav-button:focus::after,
.nav-button:hover::after {
    content: '';
    position: absolute;
    top: -6px;
    left: -6px;
    right: -6px;
    bottom: -6px;
    border: 3px solid #0066ff;
    border-radius: 50%;
    opacity: 0;
    animation: focusPulse 0.3s ease forwards;
}

@keyframes focusPulse {
    to {
        opacity: 1;
    }
}

/* Respect reduced motion preference */
@media (prefers-reduced-motion: reduce) {
    .nav-button {
        transition: none;
    }
    
    .nav-button svg {
        transition: none;
    }
    
    .nav-button:hover,
    .nav-button:focus {
        transform: none;
    }
    
    .nav-button:focus::after,
    .nav-button:hover::after {
        animation: none;
        opacity: 1;
    }
}

/* Position each button around the circle - sunburst pattern */
.nav-n {
    top: 0.5rem;
    left: 50%;
    transform: translateX(-50%);
}

.nav-n:hover {
    transform: translateX(-50%) scale(1.1);
}

.nav-n:focus {
    transform: translateX(-50%);
}

.nav-ne {
    top: 15%;
    right: 15%;
}

.nav-e {
    top: 50%;
    right: 0.5rem;
    transform: translateY(-50%);
}

.nav-e:hover {
    transform: translateY(-50%) scale(1.1);
}

.nav-e:focus {
    transform: translateY(-50%);
}

.nav-se {
    bottom: 15%;
    right: 15%;
}

.nav-s {
    bottom: 0.5rem;
    left: 50%;
    transform: translateX(-50%);
}

.nav-s:hover {
    transform: translateX(-50%) scale(1.1);
}

.nav-s:focus {
    transform: translateX(-50%);
}

.nav-sw {
    bottom: 15%;
    left: 15%;
}

.nav-w {
    top: 50%;
    left: 0.5rem;
    transform: translateY(-50%);
}

.nav-w:hover {
    transform: translateY(-50%) scale(1.1);
}

.nav-w:focus {
    transform: translateY(-50%);
}

.nav-nw {
    top: 15%;
    left: 15%;
}

/* Ensure reduced motion works for positioned buttons */
@media (prefers-reduced-motion: reduce) {
    .nav-n:hover, .nav-n:focus {
        transform: translateX(-50%);
    }
    .nav-e:hover, .nav-e:focus {
        transform: translateY(-50%);
    }
    .nav-s:hover, .nav-s:focus {
        transform: translateX(-50%);
    }
    .nav-w:hover, .nav-w:focus {
        transform: translateY(-50%);
    }
}

/* Center control area */
.nav-center {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 7rem; /* 112px - larger for better icon sizing */
    height: 7rem;
    border-radius: 50%;
    background: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
}

/* Zoom controls - semi-circular halves */
.nav-zoom {
    position: absolute;
    width: 7rem; /* 112px - matches nav-center */
    height: 3.5rem; /* 56px - half of width */
    border: 2px solid rgba(233, 30, 99, 0.3);
    background: linear-gradient(135deg, #fce4ec 0%, #f8bbd0 100%);
    cursor: pointer;
    transition: all 0.2s ease;
    display: flex;
    align-items: center;
    justify-content: center;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    left: 50%;
    transform: translateX(-50%);
}

.nav-zoom-in {
    top: 0;
    border-radius: 3.5rem 3.5rem 0 0;
    border-bottom: 1px solid rgba(233, 30, 99, 0.1);
}

.nav-zoom-out {
    bottom: 0;
    border-radius: 0 0 3.5rem 3.5rem;
    border-top: 1px solid rgba(233, 30, 99, 0.1);
}

.nav-zoom svg {
    width: 1.5rem; /* 24px */
    height: 1.5rem;
    stroke: #333;
    stroke-width: 2;
    fill: none;
}

.nav-zoom-in svg {
    transform: translateY(-30%);
}

.nav-zoom-out svg {
    transform: translateY(30%);
}

.nav-zoom:hover {
    background: linear-gradient(135deg, #f8bbd0 0%, #f48fb1 100%);
    box-shadow: 0 3px 12px rgba(0, 0, 0, 0.2);
}


.nav-zoom:focus,
.nav-zoom:hover {
    outline: none;
}

/* Disabled state for zoom buttons */
.nav-zoom.disabled,
.nav-zoom[aria-disabled="true"] {
    opacity: 0.5;
    cursor: not-allowed;
    background: linear-gradient(135deg, #e0e0e0 0%, #d0d0d0 100%);
}

.nav-zoom.disabled:hover,
.nav-zoom[aria-disabled="true"]:hover {
    background: linear-gradient(135deg, #e0e0e0 0%, #d0d0d0 100%);
    box-shadow: none;
}

.nav-zoom.disabled svg,
.nav-zoom[aria-disabled="true"] svg {
    stroke: #999;
}

/* High contrast mode disabled styles */
@media (prefers-contrast: high) {
    .nav-zoom.disabled,
    .nav-zoom[aria-disabled="true"] {
        opacity: 0.6;
        background: #666;
        border-color: #999;
    }
    
    .nav-zoom.disabled svg,
    .nav-zoom[aria-disabled="true"] svg {
        stroke: #999;
    }
}

/* Zoom button outline divs */
.zoom-in-outline,
.zoom-out-outline {
    position: absolute;
    width: 7rem;
    height: 3.5rem;
    left: 50%;
    transform: translateX(-50%);
    pointer-events: none;
    z-index: 1;
    opacity: 0;
    transition: opacity 0.2s ease;
    box-shadow: inset 0 0 0 3px #0066ff;
}

.zoom-in-outline {
    top: 0;
    border-radius: 3.5rem 3.5rem 0 0;
    clip-path: inset(2px 2px 0 2px);
}

.zoom-out-outline {
    bottom: 0;
    border-radius: 0 0 3.5rem 3.5rem;
    clip-path: inset(0 2px 2px 2px);
}

/* Show outlines on hover/focus of corresponding buttons */
.nav-zoom-in:hover ~ .zoom-in-outline,
.nav-zoom-in:focus ~ .zoom-in-outline {
    opacity: 1;
}

.nav-zoom-out:hover ~ .zoom-out-outline,
.nav-zoom-out:focus ~ .zoom-out-outline {
    opacity: 1;
}

/* Remove zoom outline divs - not needed with new layout */

/* Center location button */
.nav-center-btn {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 3rem; /* 48px - slightly larger */
    height: 3rem;
    border-radius: 50%;
    border: 2px solid rgba(233, 30, 99, 0.3);
    background: white;
    box-shadow: 0 3px 12px rgba(0, 0, 0, 0.3);
    cursor: pointer;
    transition: all 0.2s ease;
    z-index: 2;
    display: flex;
    align-items: center;
    justify-content: center;
}

.nav-center-btn svg {
    width: 1.25rem; /* 20px */
    height: 1.25rem;
    fill: #333;
    stroke: #333;
}

.nav-center-btn:hover {
    background: #fce4ec;
    border-color: #e91e63;
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.35);
}

.nav-center-btn:focus,
.nav-center-btn:hover {
    outline: none;
}

.nav-center-btn:focus::after,
.nav-center-btn:hover::after {
    content: '';
    position: absolute;
    top: -6px;
    left: -6px;
    right: -6px;
    bottom: -6px;
    border: 3px solid #0066ff;
    border-radius: 50%;
    opacity: 0;
    animation: focusPulse 0.3s ease forwards;
}

/* Respect reduced motion for all animated elements */
@media (prefers-reduced-motion: reduce) {
    .nav-zoom {
        transition: none;
    }
    
    .nav-center-btn {
        transition: none;
    }
    
}

/* Decorative compass rose background - sunburst effect */
.compass-navigator::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 100%;
    height: 100%;
    border-radius: 50%;
    background: radial-gradient(circle at center, 
        transparent 35%, 
        rgba(233, 30, 99, 0.03) 40%, 
        rgba(233, 30, 99, 0.06) 55%, 
        rgba(233, 30, 99, 0.08) 70%, 
        rgba(233, 30, 99, 0.1) 100%);
    pointer-events: none;
}

/* Add subtle connecting lines for sunburst effect */
.compass-navigator::after {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 90%;
    height: 90%;
    background-image: 
        linear-gradient(to top, rgba(233, 30, 99, 0.1) 1px, transparent 1px),
        linear-gradient(to right, rgba(233, 30, 99, 0.1) 1px, transparent 1px),
        linear-gradient(45deg, rgba(233, 30, 99, 0.1) 1px, transparent 1px),
        linear-gradient(-45deg, rgba(233, 30, 99, 0.1) 1px, transparent 1px);
    background-size: 100% 50%, 50% 100%, 71% 71%, 71% 71%;
    background-position: center;
    background-repeat: no-repeat;
    pointer-events: none;
    opacity: 0.5;
}

/* Responsive design */
@media (max-width: 1024px) {
    .sidebar-title {
        font-size: 0.875rem;
    }
}

@media (max-width: 768px) {
    /* Scale down nav buttons on smaller screens */
    .nav-button {
        width: 2.75rem; /* 44px - WCAG minimum */
        height: 2.75rem;
    }
    
    .nav-center {
        width: 6rem;
        height: 6rem;
    }
    
    .nav-zoom {
        width: 6rem;
        height: 3rem;
    }
    
    .zoom-in-outline,
    .zoom-out-outline {
        width: 6rem;
        height: 3rem;
    }
    
    .nav-zoom-in,
    .zoom-in-outline {
        border-radius: 3rem 3rem 0 0;
    }
    
    .nav-zoom-out,
    .zoom-out-outline {
        border-radius: 0 0 3rem 3rem;
    }
    .control-sidebar {
        width: 15rem;
    }
    
    .control-sidebar.collapsed {
        width: 2.5rem;
    }
    
    /* Adjust compass navigator position */
    .compass-navigator {
        width: 12rem; /* 192px - still larger than before */
        height: 12rem;
        right: 0.5rem;
        bottom: 0.5rem;
    }
    
    
    .location-info {
        font-size: 0.8rem;
        padding: 0.5rem;
        left: 60px; /* Account for collapsed sidebar */
    }
}

/* Small screens */
@media (max-width: 600px) {
    .control-sidebar {
        width: 100%;
        max-width: 280px;
    }
    
    .control-sidebar.collapsed {
        width: 2.5rem;
    }
    
    /* Stack buttons vertically on very small screens */
    .control-button .label,
    .accordion-header .label {
        font-size: 0.8125rem;
    }
    
    /* Move compass to top right on mobile */
    .compass-navigator {
        bottom: auto;
        top: 0.5rem;
        width: 10rem; /* 160px - maintain WCAG compliance */
        height: 10rem;
    }
    
    .location-info {
        bottom: 0.5rem;
        left: 0.5rem;
        right: 0.5rem;
        max-width: none;
    }
}

/* Landscape orientation */
@media (max-height: 600px) and (orientation: landscape) {
    .control-sidebar {
        width: 220px;
    }
    
    .sidebar-header {
        padding: 0.5rem;
    }
    
    .sidebar-content {
        padding: 0.5rem;
        gap: 0.4rem;
    }
    
    .control-button,
    .accordion-header {
        padding: 0.4rem 0.5rem;
    }
    
    /* Smaller compass in landscape */
    .compass-navigator {
        width: 11rem; /* 176px - still meets WCAG */
        height: 11rem;
    }
    
    .location-info {
        font-size: 0.75rem;
        padding: 0.4rem;
    }
}

/* Very small screens */
@media (max-width: 400px) {
    .control-sidebar {
        font-size: 0.85rem;
    }
    
    .control-button,
    .accordion-header {
        padding: 0.6rem 0.75rem;
        gap: 0.6rem;
    }
    
    .control-button .icon,
    .accordion-header .icon {
        font-size: 1rem;
    }
    
    /* Even smaller compass on tiny screens */
    .compass-navigator {
        width: 9rem; /* 144px - minimum for WCAG compliance */
        height: 9rem;
    }
}

/* Map container takes full width */
#map-container {
    margin-left: 0;
    width: 100%;
}

/* Clear All Button */
.clear-all-rotor {
    width: 100%;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.5rem;
    border: 1px solid #dc3545;
    background: #fff;
    color: #dc3545;
    border-radius: 6px;
    cursor: pointer;
    font-size: 0.875rem;
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    transition: all 0.15s ease;
}

.clear-all-rotor:hover {
    background: #dc3545;
    color: #fff;
}

.clear-all-rotor:focus {
    outline: 2px solid #dc3545;
    outline-offset: 2px;
}

/* Filter Sub-Accordion Items (Nested) */
.filter-sub-accordion-item {
    border: 1px solid rgba(0, 0, 0, 0.05);
    border-radius: 3px;
    margin-bottom: 0.1875rem;
    overflow: hidden;
}

.filter-sub-accordion-item:last-child {
    margin-bottom: 0;
}

.filter-sub-accordion-header {
    width: 100%;
    padding: 0.25rem 0.375rem;
    background: #f0f0f0;
    border: none;
    cursor: pointer;
    font-size: 0.5625rem;
    display: flex;
    align-items: center;
    gap: 0.25rem;
    transition: background 0.15s ease;
    text-align: left;
    white-space: nowrap;
    overflow: hidden;
}

.filter-sub-accordion-header:hover {
    background: #e8e8e8;
}

.filter-sub-accordion-header:focus {
    outline: 2px solid #0066ff;
    outline-offset: -2px;
}

.filter-sub-accordion-header .icon {
    font-size: 0.625rem;
    flex-shrink: 0;
}

.filter-sub-accordion-header .label {
    flex: 1;
    font-weight: 500;
}

.filter-sub-accordion-header .accordion-arrow {
    margin-left: auto;
    transition: transform 0.2s;
    font-size: 0.5rem;
}

.filter-sub-accordion-header[aria-expanded="true"] .accordion-arrow {
    transform: rotate(180deg);
}

.filter-sub-accordion-content {
    padding: 0.25rem 0.375rem;
    background: #fafafa;
    border-top: 1px solid rgba(0, 0, 0, 0.03);
}

.filter-sub-accordion-content label {
    display: block;
    padding: 0.125rem 0;
    cursor: pointer;
    font-size: 0.5625rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    margin-left: 0.75rem;
}

.filter-sub-accordion-content label:hover {
    background: rgba(0, 0, 0, 0.02);
    padding-left: 0.1875rem;
    margin-left: 0.5625rem;
    margin-right: -0.1875rem;
}

.filter-sub-accordion-content input {
    margin-right: 0.25rem;
}


/* Filter Sub-Accordion Dark Mode Support */
@media (prefers-color-scheme: dark) {
    .filter-sub-accordion-item {
        border-color: rgba(255, 255, 255, 0.1);
    }
    
    .filter-sub-accordion-header {
        background: #1a1a1a;
        color: #e0e0e0;
    }
    
    .filter-sub-accordion-header:hover {
        background: #333;
    }
    
    .filter-sub-accordion-content {
        background: #1a1a1a;
        color: #e0e0e0;
        border-top-color: rgba(255, 255, 255, 0.05);
    }
    
    .filter-sub-accordion-content label {
        color: #e0e0e0;
    }
    
    .filter-sub-accordion-content label:hover {
        background: rgba(255, 255, 255, 0.03);
    }
}

/* Filter Sub-Accordion High Contrast Support */
@media (prefers-contrast: high) {
    .filter-sub-accordion-item {
        background: #000;
        border: 1px solid #fff;
    }
    
    .filter-sub-accordion-header {
        background: #000;
        color: #fff;
    }
    
    .filter-sub-accordion-header:hover {
        background: #fff;
        color: #000;
    }
    
    .filter-sub-accordion-content {
        background: #000;
        color: #fff;
        border-top: 1px solid #fff;
    }
    
    .filter-sub-accordion-content label {
        color: #fff;
    }
    
    .filter-sub-accordion-content label:hover {
        background: #fff;
        color: #000;
    }
    
    .filter-sub-accordion-content input {
        background: #000;
        border: 1px solid #fff;
    }
}



/* Avatar styles */
.map-avatar {
    cursor: pointer;
    z-index: 500;
}

.map-avatar:focus {
    outline: 3px solid #0066ff;
    outline-offset: 4px;
    border-radius: 50%;
}

/* Avatar pulse animation */
@keyframes avatarPulse {
    0% {
        r: 20;
        opacity: 0.6;
    }
    100% {
        r: 40;
        opacity: 0;
    }
}

.avatar-pulse {
    pointer-events: none;
}

/* Overlay filter highlight — POI / accessibility filters mark features
   (a path, a building) without hiding them. Strong, high-contrast outline. */
#map-tiles .filter-highlight :is(polygon, polyline, circle, path, rect) {
    stroke: #b5179e;
    stroke-width: 4;
    paint-order: stroke;
}

@media (prefers-contrast: high) {
    #map-tiles .filter-highlight :is(polygon, polyline, circle, path, rect) {
        stroke: #ff0;
        stroke-width: 5;
    }
}

/* Sticky name tooltip (ported from the east-end Toronto / terminal maps). A pill
   anchored above the pointer/feature, fed from the feature's aria-label.
   pointer-events:none so it never blocks the marker; sticky so magnifier users
   can pan/zoom to read it. */
.poi-tooltip {
    position: fixed;
    max-width: 260px;
    padding: 0.5rem 0.75rem;
    background: rgba(255, 255, 255, 0.97);
    color: black;
    border: 1px solid #1E3A8A;
    border-radius: 6px;
    box-shadow: 0 4px 14px rgba(8, 17, 46, 0.22);
    font-size: 1rem;
    font-weight: 600;
    line-height: 1.25;
    z-index: 200;
    pointer-events: none;
    transform: translate(-50%, calc(-100% - 22px));
    white-space: normal;
}
.poi-tooltip[hidden] { display: none; }
.poi-tooltip::before,
.poi-tooltip::after {
    content: "";
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    width: 0; height: 0;
    border-style: solid;
    border-color: transparent;
}
/* Navy outline of the tail — continues the bubble's 1px border down the V. */
.poi-tooltip::before {
    top: 100%;
    border-width: 11px;
    border-top-color: #1E3A8A;
}
/* White fill, 1px smaller and nudged back into the bubble so the fill is
   continuous and navy shows only on the sides. */
.poi-tooltip::after {
    top: calc(100% - 1px);
    border-width: 10px;
    border-top-color: rgba(255, 255, 255, 0.97);
}
/* When the feature is near the top edge, flip the pill below the point. */
body.tooltip-below .poi-tooltip {
    transform: translate(-50%, calc(0% + 22px));
}
body.tooltip-below .poi-tooltip::before {
    top: auto;
    bottom: 100%;
    border-top-color: transparent;
    border-bottom-color: #1E3A8A;
}
body.tooltip-below .poi-tooltip::after {
    top: auto;
    bottom: calc(100% - 1px);
    border-top-color: transparent;
    border-bottom-color: rgba(255, 255, 255, 0.97);
}
/* Dark tooltip: dark pill, light text, a lighter blue edge (the light-mode
   navy vanishes against a dark map). The tail's fill must match the pill. */
@media (prefers-color-scheme: dark) {
    .poi-tooltip {
        background: rgba(30, 30, 30, 0.97);
        color: #f0f0f0;
        border-color: #8ab0f0;
    }
    .poi-tooltip::before { border-top-color: #8ab0f0; }
    .poi-tooltip::after { border-top-color: rgba(30, 30, 30, 0.97); }
    body.tooltip-below .poi-tooltip::before { border-top-color: transparent; border-bottom-color: #8ab0f0; }
    body.tooltip-below .poi-tooltip::after { border-top-color: transparent; border-bottom-color: rgba(30, 30, 30, 0.97); }
}

/* Point marker — a constant-size ring pinned at the feature point. Navy ring +
   white halo so it shows over parks, water, roads and buildings alike. Lives in
   the screen-space overlay, so it never scales with the map zoom. aria-hidden —
   the name is announced from the feature itself. */
.poi-marker {
    position: fixed;
    box-sizing: border-box;
    width: 16px;
    height: 16px;
    border: 3px solid #1E3A8A;
    border-radius: 50%;
    background: transparent;
    box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.95);
    transform: translate(-50%, -50%);
    z-index: 199;
    pointer-events: none;
}

/* ---- Place suggestions: the chat input's combobox listbox (ChatSuggest) ----
   Anchored under the input row inside the chat panel; grey borders carry the
   non-text contrast (invert-safe). The active option is marked with the same
   blue focus idiom as everything else, driven by aria-activedescendant (DOM
   focus stays in the input). */
.chat-form { position: relative; }
.chat-suggest {
    list-style: none;
    margin: 0.25rem 0 0;
    padding: 0.25rem;
    position: absolute;
    left: 0.75rem;
    right: 0.75rem;
    z-index: 10;              /* over the transcript below */
    max-height: 14rem;
    overflow-y: auto;
    background: #fff;
    border: 2px solid #5a5a5a;
    border-radius: 8px;
    box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}
.chat-suggest[hidden] { display: none; }
.chat-suggest__opt {
    display: flex;
    flex-direction: column;
    gap: 0.1rem;
    min-height: 1.75rem;      /* 24px target floor (WCAG 2.5.8) */
    padding: 0.375rem 0.5rem;
    border-radius: 6px;
    cursor: pointer;
}
.chat-suggest__opt:hover { background: #f0f4f8; }
.chat-suggest__opt.is-active {
    background: #e3f2fd;
    outline: 2px solid #0066ff;
    outline-offset: -2px;
}
.chat-suggest__name {
    font-weight: 600;
    font-size: 0.875rem;
    color: #1a1a1a;
}
.chat-suggest__detail {
    font-size: 0.8125rem;
    color: #444;
}
/* Accessibility badge — dark green on pale green, comfortably above AAA.
   The accessible attributes are surfaced right on the suggestion. */
.chat-suggest__a11y {
    align-self: flex-start;
    margin-top: 0.1rem;
    padding: 0.05rem 0.4rem;
    font-size: 0.7rem;
    font-weight: 600;
    color: #14532d;
    background: #dcfce7;
    border: 1px solid #86c79b;
    border-radius: 999px;
}
@media (prefers-color-scheme: dark) {
    .chat-suggest { background: #1e1e1e; border-color: #9a9a9a; }
    .chat-suggest__opt:hover { background: #2a2a2a; }
    .chat-suggest__opt.is-active { background: #103050; outline-color: #5b8def; }
    .chat-suggest__name { color: #f0f0f0; }
    .chat-suggest__detail { color: #c4c4c4; }
}
@media (prefers-contrast: high) {
    .chat-suggest { border-color: #000; border-width: 3px; }
    .chat-suggest__name, .chat-suggest__detail { color: #000; }
}
.poi-marker[hidden] { display: none; }

/* ---- Filter / rotor checkbox rows: WCAG 2.2 target size + legibility ----
   The list rows were ~16px tall at 10px and truncated with an ellipsis, which
   hid the band labels ("Good smoothness (wheelchair-passable)"). Give each row
   a >=24px target, a readable size, and let long labels wrap instead of clip. */
.accordion-content label,
.filter-accordion-content label {
    display: flex;
    align-items: center;
    min-height: 1.75rem; /* >= 24px clickable target */
    padding: 0.25rem 0;
    font-size: 0.8125rem;
    line-height: 1.3;
    white-space: normal;
    overflow: visible;
    text-overflow: clip;
}

.accordion-content input,
.filter-accordion-content input {
    flex: 0 0 auto;
    width: 1rem;
    height: 1rem;
    margin-right: 0.5rem;
}

/* ---- Reduced motion (WCAG 2.3.3) ----
   Last in the file so it overrides the per-button rules above. Kills all
   animation/transition, and resets the compass hover "grow" to each button's
   resting transform so nothing jumps for vestibular-sensitive users. */
@media (prefers-reduced-motion: reduce) {
    *, *::before, *::after {
        animation-duration: 0.01ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.01ms !important;
        scroll-behavior: auto !important;
    }
    .nav-button:hover,
    .nav-button:focus { transform: none; }
    .nav-n:hover,
    .nav-s:hover { transform: translateX(-50%); }
    .nav-e:hover,
    .nav-w:hover { transform: translateY(-50%); }
}

/* ============================================================================
   Map feature theming — dark mode & high contrast (audit #12).

   Tiles bake each feature's colour as a fill/stroke ATTRIBUTE on the shape, so
   we recolour the SHAPES — NOT the wrapping <g>, whose inherited value the
   shape's own attribute would just override (why the old .building{fill} rules
   did nothing). Each category gets a pair of rules keyed off what the shape
   already does:
     [fill]:not([fill="none"])     -> an area  -> recolour fill
     [stroke]:not([stroke="none"]) -> a line   -> recolour stroke
   so a road (fill="none") only ever takes the stroke colour, never a fill. A
   catch-all themes anything not named, so EVERY feature adapts. These rules live
   ONLY inside the media queries, so the default light map is untouched. Palette
   is the custom-property block at the top of each mode — tweak there.
   ============================================================================ */

@media (prefers-color-scheme: dark) {
    #map-container,
    #map-svg { background: #16191d; }

    /* A LIGHTNESS LADDER, darkest to lightest: ground (the svg background)
       < landuse < misc (the catch-all — most of the base polygons, so it
       must stay LOW or the whole map goes pale, seen live) < buildings.
       EDGES carry the detail; roads are the bright skeleton on near-black
       casings. All knobs live here — tune by eye. */
    #map-tiles {
        --c-misc-fill:  #23272d;  --c-misc-stroke:  #4d545e;
        --c-water-fill: #173a4a;  --c-water-stroke: #2b5f78;
        --c-bldg-fill:  #2f353d;  --c-bldg-stroke:  #5d656f;
        --c-park-fill:  #1e3d23;  --c-park-stroke:  #35663c;
        --c-veg-fill:   #1b3720;  --c-veg-stroke:   #2f5836;
        --c-land-fill:  #1d2025;  --c-land-stroke:  #383e46;
        --c-road:       #848c99;  --c-road-casing:  #14171b;
    }

    /* Generic re-colour for tangible features — but NEVER the overlay elements
       that carry their own treatment: POI marker circles (small colour dot +
       TRANSPARENT touch ring), the transparent road hit-corridors, and the faint
       container-region fills/boundaries (.region-area, own dark rule below).
       Without the :not()s the dark catch-all paints their transparent strokes
       grey, turning markers into donuts and hit-corridors into thick grey roads. */
    #map-tiles [fill]:not([fill="none"]):not(circle):not(.region-area):not(.level-area):not(.ugparking)     { fill: var(--c-misc-fill); }
    #map-tiles [stroke]:not([stroke="none"]):not(circle):not(.road-hit):not(.region-area):not(.level-line):not(.level-halo):not(.level-casing):not(.level-area):not(.underpass-line):not(.ugparking) { stroke: var(--c-misc-stroke); }

    #map-tiles g.water [fill]:not([fill="none"])            { fill: var(--c-water-fill); }
    #map-tiles g.water [stroke]:not([stroke="none"])        { stroke: var(--c-water-stroke); }
    #map-tiles g.building [fill]:not([fill="none"])         { fill: var(--c-bldg-fill); }
    #map-tiles g.building [stroke]:not([stroke="none"])     { stroke: var(--c-bldg-stroke); }
    #map-tiles g.park [fill]:not([fill="none"])             { fill: var(--c-park-fill); }
    #map-tiles g.park [stroke]:not([stroke="none"])         { stroke: var(--c-park-stroke); }
    #map-tiles g.vegetation [fill]:not([fill="none"])       { fill: var(--c-veg-fill); }
    #map-tiles g.vegetation [stroke]:not([stroke="none"])   { stroke: var(--c-veg-stroke); }
    #map-tiles g.landuse [fill]:not([fill="none"])          { fill: var(--c-land-fill); }
    #map-tiles g.landuse [stroke]:not([stroke="none"])      { stroke: var(--c-land-stroke); }
    #map-tiles g.road [stroke]:not([stroke="none"]):not(.road-hit) { stroke: var(--c-road); }
    #map-tiles g.road-casings [stroke]:not([stroke="none"]) { stroke: var(--c-road-casing); }

    /* In-road labels on the dark map: the baked light-mode dark text would vanish,
       so flip to a LIGHT fill with a dark halo. (Markers + hit-corridors keep their
       transparent touch surfaces and POI colours via the :not()s above.) */
    #map-tiles text.road-label { fill: #ececec; stroke: #16191d; }

    /* Container regions on the dark map: keep the faint fill + a light grey dashed
       boundary, and flip the centred name to light text with a dark halo. */
    #map-tiles .region-area    { fill: #c7ccd1; fill-opacity: .08; stroke: #aab0b6; }
    #map-tiles text.region-label { fill: #e8eaed; stroke: #16191d; }
}

@media (prefers-contrast: high) {
    /* KEEP the soft OSM fills; carry the contrast on strong GREY-DARK boundaries
       instead. A coloured high-contrast edge (the bright green I had before)
       inverts into a low-contrast hue under macOS "Invert colours" — grey just
       flips luminance and survives. Near-white background + near-black edges =
       the maximum luminance boundary; under invert it reads as a dark map with
       light edges. Road colours are kept (the casing carries their boundary). */
    #map-container,
    #map-svg { background: #ffffff; }

    #map-tiles :is(g.building, g.landuse, g.park, g.vegetation, g.water, g.parking,
                   g.religious, g.natural, g.aeroway, g.indoor, g.man_made,
                   g.barrier, g.railway) [stroke]:not([stroke="none"]):not(.level-line):not(.level-halo):not(.level-casing):not(.level-area):not(.underpass-line),
    #map-tiles g.road-casings [stroke]:not([stroke="none"]) {
        stroke: #1a1a1a;
    }
}

/* ── Detailed surroundings modal ─────────────────────────────────────────────
   A real dialog for the deliberate one-off read-out (focus trapped in JS, Escape
   closes, focus returns to its button). The continuous Auto-describe never uses
   this — it would steal focus every few seconds. Grey panel border for invert. */
.detail-modal {
    position: fixed;
    inset: 0;
    z-index: 1000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 1rem;
    background: rgba(0, 0, 0, 0.5);
}
.detail-modal[hidden] { display: none; }
.detail-modal__panel {
    width: 100%;
    max-width: 32rem;
    max-height: 85vh;
    overflow-y: auto;
    padding: 1.25rem 1.5rem;
    background: #fff;
    border: 2px solid #5a5a5a;
    border-radius: 8px;
    box-shadow: 0 6px 30px rgba(0, 0, 0, 0.3);
}
.detail-modal__title {
    margin: 0 0 0.75rem;
    font-size: 1.25rem;
    color: #111;
}
.detail-modal__body {
    font-size: 1rem;
    line-height: 1.5;
    color: #1a1a1a;
}
/* The settings dialog's body is a short stack of toggle buttons. */
.settings-body {
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
    min-width: 16rem;
}

/* ---- Busy state between Start and the first full render ---- */
.map-busy {
    position: absolute;
    inset: 0;
    /* Above ALL the map chrome — sidebar (90), chat panel (85), rose (80) —
       the loading note must never sit half-hidden behind a panel. Only the
       modal dialogs (1000) outrank it. */
    z-index: 200;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;   /* a note, not a shield — the chrome stays usable */
}
.map-busy[hidden] { display: none; }
.map-busy__text {
    margin: 0;
    padding: 0.875rem 1.5rem;
    background: rgba(255, 255, 255, 0.98);
    border: 2px solid #5a5a5a;
    border-radius: 8px;
    font-size: 1.125rem;
    font-weight: 600;
    color: #111;
}
@media (prefers-color-scheme: dark) {
    .map-busy__text {
        background: rgba(30, 30, 30, 0.98);
        border-color: #9a9a9a;
        color: #e0e0e0;
    }
}
@media (prefers-contrast: high) {
    .map-busy__text { border-color: #000; border-width: 3px; color: #000; }
}

/* ---- Chat (the Knowledge Map's conversation, in a panel over the map) ----
   Two housings, one markup (see index.html):
   - DESKTOP (default): a floating panel — moveable, resizable, closeable from
     Settings. Docks at the bottom by default, sized to clear the menu sidebar
     (left) and the navigation rose (right). Geometry rides on custom
     properties (set inline by ChatPanel.js — the sanctioned inline use).
   - MOBILE (body.chat-split, set by ChatPanel.js): split screen — map on top,
     panel across the bottom, a draggable divider controls the ratio.
   Grey borders carry the non-text contrast (invert-safe). */
.chat-panel {
    position: fixed;
    left: var(--chat-left, 17rem);         /* clears the 15rem sidebar + gaps */
    bottom: var(--chat-bottom, 1rem);
    width: var(--chat-width, min(50vw, calc(100vw - 34rem)));  /* …and the rose */
    height: var(--chat-height, 21rem);     /* ≈ an 8-line transcript + chrome */
    min-width: 18rem;
    min-height: 13rem;
    max-width: calc(100vw - 2rem);
    max-height: calc(100vh - 2rem);
    display: flex;
    flex-direction: column;
    background: rgba(255, 255, 255, 0.98);
    border: 2px solid #5a5a5a;
    border-radius: 0.5rem;
    box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
    z-index: 85;   /* over the rose (80), under the sidebar (90) when dragged there */
}
.chat-panel[hidden] { display: none; }

/* The bar: drag surface for MOVE, plus the keyboard Move/Resize buttons. */
.chat-panel__bar {
    display: flex;
    align-items: center;
    gap: 0.375rem;
    padding: 0.25rem 2.25rem 0.25rem 0.75rem; /* right inset clears the grip */
    border-bottom: 1px solid rgba(0, 0, 0, 0.1);
    cursor: grab;
    user-select: none;
    -webkit-user-select: none;
    touch-action: none;
}
.chat-panel__bar.dragging { cursor: grabbing; }
.chat-panel__title {
    flex: 1;
    font-size: 0.875rem;
    font-weight: 600;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.chat-panel__tool {
    flex: none;
    min-height: 1.75rem;
    padding: 0.25rem 0.5rem;
    font-size: 0.8125rem;
    background: #fff;
    color: #1a1a1a;
    border: 1px solid #767676;
    border-radius: 6px;
    cursor: pointer;
}
.chat-panel__tool:hover { background: #f8f8f8; border-color: #444; }
.chat-panel__tool:focus { outline: 2px solid #0066ff; outline-offset: 2px; }

/* Resize grip — POINTER twin of the Resize button, top-right corner (the
   bottom edge stays docked; you pull the top corner up/out). aria-hidden. */
.chat-panel__grip {
    position: absolute;
    top: 0;
    right: 0;
    width: 1.75rem;
    height: 1.75rem;
    border-left: 1px solid #767676;
    border-bottom: 1px solid #767676;
    border-radius: 0 0.4rem 0 0.4rem;
    background:
        repeating-linear-gradient(45deg,
            transparent 0 5px, #767676 5px 7px, transparent 7px 10px);
    cursor: nesw-resize;
    touch-action: none;
}

.chat-form { padding: 0.5rem 0.75rem 0; }

.chat-logwrap {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    margin: 0.25rem 0.75rem;
}

/* ── Mobile split screen: map on top, panel across the bottom. ────────────── */
.chat-divider { display: none; }
.chat-divider[hidden] { display: none; }

/* :not([hidden]) keeps the disclaimer gate's main[hidden] authoritative. */
body.chat-split main:not([hidden]) {
    display: flex;
    flex-direction: column;
}
body.chat-split #map-container {
    flex: 1 1 auto;
    min-height: 0;
    height: auto;
}
body.chat-split .chat-divider {
    display: block;
    flex: none;
    position: relative;
    height: 1.5rem;   /* 24px band — WCAG 2.5.8 target floor */
    background: #fff;
    border-top: 2px solid #5a5a5a;
    border-bottom: 2px solid #5a5a5a;
    cursor: row-resize;
    touch-action: none;
}
.chat-divider::after {   /* the visible pill affordance */
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    width: 3rem;
    height: 0.375rem;
    border-radius: 999px;
    background: #5a5a5a;
}
.chat-divider:focus { outline: 3px solid #0066ff; outline-offset: -3px; }
body.chat-split .chat-panel {
    position: static;
    flex: none;
    height: var(--chat-split-h, 40vh);
    width: auto;
    min-width: 0;
    max-width: none;
    max-height: none;
    border: none;
    border-radius: 0;
    box-shadow: none;
}
/* No float chrome in split mode: the divider does the resizing, and the
   panel is always open, so Move/Resize/grip (and their Settings toggle,
   see below) retire. */
body.chat-split .chat-panel__bar { display: none; }
body.chat-split .chat-panel__grip { display: none; }
body.chat-split #toggle-chat-panel { display: none; }
/* Keep the location read-out above the panel, not underneath it. */
body.chat-split .location-info {
    bottom: calc(var(--chat-split-h, 40vh) + 2.25rem);
}
.chat-msg {
    margin: 0.375rem 0;
}
.chat-msg__text {
    margin: 0;
    padding: 0.375rem 0.625rem;
    border-radius: 8px;
    font-size: 0.875rem;
    line-height: 1.45;
    color: #1a1a1a;
    background: #fff;
    border: 1px solid #767676; /* grey boundary — invert-safe */
}
.chat-msg--user .chat-msg__text {
    background: #eef2f7;
    margin-left: 1.5rem;
}
.chat-msg--bot .chat-msg__text {
    margin-right: 1.5rem;
}
/* Map announcements (the visible twin of everything spoken — hover, proximity,
   status). Styled APART from conversation turns: no card, muted-but-AAA text,
   a grey left rule as the invert-safe marker. */
.chat-msg--announce .chat-msg__text {
    background: transparent;
    border: none;
    border-left: 3px solid #767676;
    border-radius: 0;
    padding: 0.125rem 0.625rem;
    color: #333;
    font-size: 0.8125rem;
}
@media (prefers-color-scheme: dark) {
    .chat-msg--announce .chat-msg__text { color: #c9c9c9; border-left-color: #9a9a9a; }
}
@media (prefers-contrast: high) {
    .chat-msg--announce .chat-msg__text { color: #000; border-left-color: #000; }
}
.chat-label {
    display: block;
    font-size: 0.8125rem;
    font-weight: 600;
    margin-bottom: 0.125rem;
}
.chat-hint {
    font-size: 0.8125rem;
    line-height: 1.45;
    margin: 0 0 0.375rem;
    color: #333;
}
.chat-inputrow {
    display: flex;
    gap: 0.375rem;
    align-items: stretch;
}
.chat-input {
    flex: 1;
    min-width: 0;
    min-height: 1.75rem;
    font-size: 0.875rem;
    padding: 0.25rem 0.5rem;
    border: 1px solid #767676;
    border-radius: 6px;
}
.chat-btn {
    width: auto;
    flex: none;
    min-height: 1.75rem;
}
.chat-status {
    font-size: 0.8125rem;
    margin: 0 0.75rem 0.5rem;
    color: #333;
    min-height: 1.2em; /* keep the layout steady when it empties */
}
.detail-modal__body h3 {
    margin: 0.875rem 0 0.25rem;
    font-size: 1rem;
    color: #111;
}
.detail-modal__body ul { margin: 0.25rem 0; padding-left: 1.25rem; }
.detail-modal__body li { margin: 0.15rem 0; }
.detail-modal__close {
    margin-top: 1rem;
    padding: 0.5rem 1.25rem;
    border: 2px solid #0066ff;
    border-radius: 6px;
    background: #fff;
    color: #0033aa;
    font-size: 1rem;
    cursor: pointer;
}
.detail-modal__close:hover { background: #e3f2fd; }
.detail-modal__close:focus { outline: 2px solid #0066ff; outline-offset: 2px; }
/* Dark mode for the dialogs (Detailed surroundings + Settings share the idiom). */
@media (prefers-color-scheme: dark) {
    .detail-modal__panel {
        background: #1e1e1e;
        border-color: #9a9a9a;
    }
    .detail-modal__title,
    .detail-modal__body h3 { color: #f0f0f0; }
    .detail-modal__body { color: #e0e0e0; }
    .detail-modal__close {
        background: #2a2a2a;
        border-color: #5b8def;
        color: #cfe0ff;
    }
    .detail-modal__close:hover { background: #333; }
}

@media (prefers-contrast: high) {
    .detail-modal__panel { border-color: #000; border-width: 3px; }
    .detail-modal { background: rgba(0, 0, 0, 0.7); }
    .detail-modal__close { border-color: #000; color: #000; }
    .chat-panel { border-color: #000; border-width: 3px; }
    body.chat-split .chat-divider { border-color: #000; }
    .chat-divider::after { background: #000; }
    .chat-panel__tool, .chat-panel__grip { border-color: #000; }
    .chat-status { color: #000; }
}

@media (prefers-color-scheme: dark) {
    .chat-panel {
        background: rgba(30, 30, 30, 0.98);
        color: #e0e0e0;
        border-color: #9a9a9a;   /* grey luminance boundary, invert-safe */
    }
    .chat-panel__bar { border-bottom-color: rgba(255, 255, 255, 0.1); }
    .chat-panel__tool {
        background: #2a2a2a;
        color: #e0e0e0;
        border-color: #9a9a9a;
    }
    .chat-panel__tool:hover { background: #333; }
    .chat-panel__grip {
        border-color: #9a9a9a;
        background:
            repeating-linear-gradient(45deg,
                transparent 0 5px, #9a9a9a 5px 7px, transparent 7px 10px);
    }
    body.chat-split .chat-divider { background: #1e1e1e; border-color: #9a9a9a; }
    .chat-divider::after { background: #9a9a9a; }
    .chat-label { color: #e0e0e0; }
    .chat-hint, .chat-status { color: #c9c9c9; }
    .chat-msg__text {
        background: #252525;
        color: #e0e0e0;
        border-color: #9a9a9a;
    }
    .chat-msg--user .chat-msg__text { background: #103050; }
}

/* ---- Go-to highlight: the arrived-at feature, every segment of it ---------
   A road spans many tiles (same data-osm-id per segment); an area is a shape.
   Amber carries the state in BOTH themes — bright enough to read on the light
   and dark maps alike, and luminance-distinct so it survives macOS Invert.
   !important is deliberate and load-bearing: the dark-mode recolour rules
   carry long :not() chains with higher specificity, and a transient STATE
   must beat every theme SKIN. Excluded: the transparent .road-hit corridors
   (the donut gotcha), circles (POI dots keep their category colour — points
   are marked by the focus outline + tooltip), and text (in-road labels stay
   legible on the amber). Cleared by the next go-to or Escape. */
#map-tiles .goto-highlight [stroke]:not([stroke="none"]):not(.road-hit):not(text) {
    stroke: #ffb300 !important;
}
#map-tiles .goto-highlight [fill]:not([fill="none"]):not(circle):not(text) {
    fill: #ffb300 !important;
    fill-opacity: 0.28;
}

/* ---- Conversational result sets ("show me all the benches") ---------------
   The same treatment as the go-to highlight, applied to EVERY member of the
   set (each result's geometry carries .result-highlight; same exclusions),
   but in the DARKER amber: result geometry borders the spotlight's dimmed,
   near-white ground, where #ffb300 is only ~1.7:1 — #c77800 holds >=3:1
   (WCAG 1.4.11) in both themes. */
#map-tiles .result-highlight [stroke]:not([stroke="none"]):not(.road-hit):not(text) {
    stroke: #c77800 !important;
}
#map-tiles .result-highlight [fill]:not([fill="none"]):not(circle):not(text) {
    fill: #c77800 !important;
    fill-opacity: 0.28;
}

/* Numbered result pins (r + font-size are set by the app per zoom, so they
   hold a constant SCREEN size): amber dot, dark rim — luminance-stepped so
   they read on light and dark ground alike and survive macOS Invert. */
#result-pins .result-pin circle {
    /* Constant SCREEN size via the same per-zoom vars as the marker dots
       (updateViewBox maintains them on EVERY scale change — the old JS
       resize hung off viewBoxChanged, which pure zooms never fire, so pins
       ballooned when zooming in from a wide fit; seen live). */
    r: var(--pin-r, 12px);
    fill: #ffb300;
    stroke: #1a1a1a;
    stroke-width: 2.5px;
    vector-effect: non-scaling-stroke;
    cursor: pointer;
}
#result-pins .result-pin__num {
    font-size: var(--pin-fs, 14px);
    fill: #1a1a1a;
    font-weight: 700;
    pointer-events: none;
    user-select: none;
}
/* The shared #focus-outline ring marks a focused pin; no double outline. */
#result-pins .result-pin:focus { outline: none; }

/* Spotlight: while a result set is live, the map steps back so the results
   carry the contrast — SELECTIVELY: roads (and the street names they carry)
   and the result features stay at full strength, because the street layout
   is the frame that makes result positions mean anything. The level comes
   from the Settings "Result dimming" slider via --spotlight-keep (1 = off). */
body.results-active #map-tiles [role="img"]:not(.road):not(.has-result) {
    opacity: var(--spotlight-keep, 0.3);
}

/* Dimmed content is stepped BACK, so it must not answer either: no hover, no
   explore-by-touch, no click while the spotlight is live. Children must be
   silenced explicitly — pointer-events is per-element and the marker/hit
   rules (pointer-events: all/auto on circles etc.) would otherwise override
   the group. Roads and the asked-for content stay fully interactive; the
   tab order and aria-hidden halves live in AccessibilityManager. */
body.results-active #map-tiles [role="img"]:not(.road):not(.has-result),
body.results-active #map-tiles [role="img"]:not(.road):not(.has-result) * {
    pointer-events: none !important;
}


/* Settings: the Result dimming slider. */
.settings-slider {
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
}
.settings-slider label {
    font-weight: 600;
}
.settings-slider input[type="range"] {
    inline-size: 100%;
}
