/*
 * Quiet Corners Field Maps — the two panels on the dashboard map, loaded by
 * layouts/_default/quiet-corners-dashboard.html ONLY. It used to dress a
 * standalone app page under layouts/_default/quiet-corners-maps.html, which is
 * documentation now; that page's frame — .qcm-header, .qcm-wordmark, .qcm-nav,
 * .qcm-body and .qcm-preview — is DELETED here rather than left inert. Unreachable
 * three independent ways: no whole-token occurrence in any source file in the repo,
 * none in the built public/**.html, and none among the className/classList
 * assignments under themes/headlessmode/static/js/ — every one of those is a
 * literal, so no name is assembled at runtime. Then counted in a real browser with
 * both panels open at 1280x900 and 390x844: zero elements each, in the same reading
 * that found .qcm-controls 2, .qcm-panel 2 and .qcm-legend 1. `.qcm-preview` never
 * reached #qcm-preview-note — that is an id, and the element's class is .qcm-status.
 *
 * .qcm-state-band and .qcm-map are gone the same way and by the same three
 * readings: the per-state pages no longer exist (scripts/qcm/layers-reach-paper
 * .test.mjs forbids main.js reading a state off the page), and main.js deleted the
 * #qcm-map second-Leaflet fallback — the dashboard's map box is .qc-map-container.
 * Nothing known-unreached is left in this file.
 *
 * That textual check is no longer a habit someone has to remember:
 * scripts/qcm/css-selector-reach.test.mjs runs it in CI. A class token in this file
 * that no template and no script writes down fails the build and names itself
 * while doing it, and there is no ignore list to add it to.
 *
 * 1023px, not 768px, wherever this file changes at a width: the two-column app
 * layout begins at 1024px, because between the two the map was 209px wide before
 * anything was even opened (audit F02). quiet-corners.css and both panel queries
 * below use that same single breakpoint.
 *
 * Contrast (WCAG AA needs 4.5:1): #e4e4e7 on the #12121e panel 14.6:1, on
 * #18181b 14.0:1, on #27272a 11.7:1; #a1a1aa on #18181b 6.9:1, on #12121e
 * 7.2:1; #34d399 on #0d0d1a 10.0:1; #f0fdf4 on #14532d 8.7:1; #d4d4d8 on
 * #27272a 10.1:1 (disabled controls, held above AA anyway). The focus ring is
 * --accent-500, #10b981 under the dashboard's dark tokens: 7.3:1 on #12121e.
 *
 * A CONTROL is styled through `.qcm-controls`, the wrapper both panel partials
 * emit — never through a panel's own name. `qcm-app` is an ID on the print
 * panel (layout.test.mjs and find-and-scale.test.mjs both address it as one),
 * so the `.qcm-app` CLASS selectors that used to carry the control chrome here
 * matched nothing for as long as they existed, which is how ten buttons and
 * selects came to be painted as bare borderless text. phone-controls.test.mjs
 * and panel-chrome.test.mjs measure what comes out, in a real browser.
 */
.qcm-status { min-height: 1.5rem; padding: 0.6rem 1.5rem; background: #14532d; color: #f0fdf4; }
.qcm-status:empty { display: none; }

/* The access caveat. Deliberately NOT styled as a hint: it is the one sentence a
   reader of a drawn boundary has to see, and a state page has no body prose to
   carry it. Amber, so it does not read as more of the green status band above. */
.qcm-access-note {
    margin: 0; padding: 0.55rem 1.5rem;
    background: #1c1917; color: #fde68a;
    border-bottom: 1px solid #292524;
    font-size: 0.85rem; line-height: 1.5;
}
/* The print-proof caveat, rendered by qcm-controls.html while the record is not
   `passed`. Red, not amber: the access note above is a standing caveat about land,
   this one says a measurement has not been taken yet. */
.qcm-proof-note {
    margin: 0 0 0.75rem; padding: 0.55rem 0.7rem;
    background: #2a1215; color: #fecaca; border: 1px solid #7f1d1d;
    border-radius: 0.25rem; font-size: 0.8rem; line-height: 1.5;
}
.qcm-proof-note strong { color: #fca5a5; }

.qcm-controls { display: flex; flex-direction: column; gap: 0.6rem; min-width: 0; }
.qcm-controls fieldset {
    margin: 0; padding: 0.6rem 0.8rem; min-width: 0;
    display: flex; flex-wrap: wrap; gap: 0.4rem 1rem; align-items: center;
    background: #18181b; border: 1px solid #3f3f46; border-radius: 6px;
}
.qcm-controls legend { padding: 0 0.3rem; color: #a1a1aa; font-size: 0.7rem; letter-spacing: 0.1em; text-transform: uppercase; }
.qcm-controls label { display: inline-flex; align-items: center; gap: 0.4rem; color: #e4e4e7; }
/* The one place a control's chrome on these panels is written down. Tailwind's
   preflight strips a button and a select back to a transparent box with a
   zero-width border, so anything not dressed here reads as a label rather than
   as something to press. `.qcm-controls` is the wrapper both partials emit, so
   this hangs off the same hook as the disabled and 44px-touch variants below —
   rename it and all three fail together instead of one going quiet. */
.qcm-controls select, .qcm-controls button {
    font: inherit; padding: 0.35rem 0.6rem; border-radius: 4px;
    color: #e4e4e7; background: #27272a; border: 1px solid #3f3f46;
}
.qcm-controls button:disabled, .qcm-controls select:disabled { color: #d4d4d8; cursor: not-allowed; opacity: 1; }
.qcm-build { font-weight: 600; padding: 0.7rem 1rem; }
.qcm-build:not(:disabled) { background: #10b981; color: #052e16; border-color: #10b981; }
.qcm-hint { margin: 0; color: #a1a1aa; font-size: 0.75rem; }
.qcm-estimate { display: grid; grid-template-columns: auto 1fr; gap: 0.25rem 1rem; margin: 0; padding: 0.6rem 0.8rem; background: #18181b; border: 1px solid #3f3f46; border-radius: 6px; }
.qcm-estimate dt { color: #a1a1aa; }
.qcm-estimate dd { margin: 0; color: #e4e4e7; overflow-wrap: anywhere; }
.qcm-controls input:not([type="radio"], [type="checkbox"]) { font: inherit; padding: 0.3rem 0.5rem; border-radius: 4px; color: #e4e4e7; background: #27272a; border: 1px solid #3f3f46; }
.qcm-controls input[type="number"] { width: 6.5rem; }
.qcm-results { list-style: none; margin: 0; padding: 0; width: 100%; max-height: 10rem; overflow-y: auto; }
.qcm-results li { padding: 0.3rem 0.5rem; cursor: pointer; border-top: 1px solid #3f3f46; }
.qcm-controls progress { width: 100%; }
.qcm-controls a.qcm-build { text-align: center; text-decoration: none; border-radius: 4px; }
.qcm-handle { width: 12px; height: 12px; background: #34d399; border: 2px solid #052e16; border-radius: 2px; }
.qcm-sheet-label { background: #0d0d1a; color: #e4e4e7; border: 1px solid #34d399; padding: 0 0.3rem; font: 600 0.7rem ui-monospace, monospace; }
/* Focus, for the two elements the site-wide ring does not reach. style.css's
   `a:focus-visible, button:focus-visible` already rings every link and button
   in these panels in --accent-500; a select or a field falls through to
   Chromium's own auto ring, a white hairline with no offset. Same token as the
   site-wide rule rather than a literal, so one gesture has one colour here. */
.qcm-controls select:focus-visible, .qcm-controls input:focus-visible {
    outline: 2px solid var(--accent-500); outline-offset: 2px;
}

/* On-page map key. The swatch markup comes from legend-view.js so it is the same
   geometry pdf.js prints; this only positions it. */
.qcm-legend { list-style: none; margin: 0; padding: 0; }
.qcm-legend li { display: flex; align-items: center; gap: 0.5rem; padding: 0.15rem 0; font-size: 0.8rem; line-height: 1.3; }
.qcm-legend-swatch { flex: 0 0 48px; height: 14px; display: block; }
.qcm-legend li[data-state="absent"], .qcm-legend li[data-state="unknown"] { opacity: 0.55; }

/* Preset buttons: a shortcut to the switches below, so they sit above them and read as
   actions rather than another row of state. The chrome came from `.qcm-controls button`
   above; what is left here is only what makes a preset different from the buttons beside
   it — smaller, left-aligned, and sharing the row. Descendant-scoped so those two
   declarations outrank the `font: inherit` in that shared rule. */
.qcm-presets { display: flex; flex-wrap: wrap; gap: 0.4rem; margin: 0 0 0.3rem; }
.qcm-controls .qcm-preset { flex: 1 1 auto; font-size: 0.8rem; line-height: 1.3;
    text-align: left; cursor: pointer; }

/* Layer panel groups. A flat list of nine checkboxes put overlays, extra SHEETS
   and state layers side by side as if they were the same kind of thing. */
.qcm-layer-group { margin: 0 0 0.7rem; }
.qcm-layer-group + .qcm-layer-group { border-top: 1px solid #262626; padding-top: 0.6rem; }
.qcm-group-title {
    margin: 0 0 0.15rem;
    font-size: 0.78rem; font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase;
    color: #a3a3a3;
}
.qcm-layer-row { margin: 0 0 0.35rem; }
/* What the layer actually answered. Colour carries the distinction the words do:
   an empty answer from a source with gaps is not the same as "nothing is here". */
.qcm-layer-report { margin: 0.1rem 0 0 1.4rem; font-size: 0.78rem; line-height: 1.45; color: #a3a3a3; }
.qcm-layer-report[data-state="ready"] { color: #86efac; }
.qcm-layer-report[data-state="empty"] { color: #fde68a; }
.qcm-layer-report[data-state="blocked"] { color: #fca5a5; }

/* The one line the map carries while a context surface is drawn. In normal flow under the
   map on a phone — where the map itself is in normal flow — and floated onto the bottom of
   the map above 1024px, where the map is `absolute inset-0` and the panels are overlays.
   Hidden whenever no surface is on, so it costs the resting layout nothing at all.

   Bottom LEFT of the map box: the print panel is top-left, the layer panel top-right and
   Leaflet's own attribution bottom-right, so this is the corner nothing else claims. */
.qcm-surface-caption {
    margin: 0.5rem 1rem; padding: 0.4rem 0.7rem;
    background: rgba(18, 18, 30, 0.96); border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 0.5rem; color: #e5e5e5; font-size: 0.85rem; line-height: 1.35;
}
@media (min-width: 1024px) {
    .qcm-surface-caption {
        position: absolute; bottom: 1rem; left: 4rem; z-index: 20;
        margin: 0; max-width: min(28rem, calc(100% - 12rem));
        backdrop-filter: blur(6px);
    }
}

/* The builder as a panel on the dashboard's map, rather than a page of its own.
   Collapsed by default: a reader who came to choose a county should not have to
   scroll past a print dialog to reach the map. */
.qcm-panel {
    background: #12121e; border: 1px solid rgba(255, 255, 255, 0.1);
    border-radius: 0.75rem; margin: 1rem; padding: 0.75rem 1rem;
    color: #e5e5e5; font-size: 0.9rem;
}

/* On the two-column layout the panel floats ON the map rather than beside it.
   `position: absolute` inside .qc-map-container (which is `relative`, and sticky,
   so the panel travels with the map) takes it out of the flex row entirely: the
   map's width no longer depends on whether this is open. Bounded by construction —
   a fixed width and a max-height inside the map box — so growing content scrolls
   here instead of pushing the map anywhere. */
/* What the two overlay panels have to share: the container's width, less the 4rem
   control lane on the left, the 1rem margin on the right, and 1.5rem of daylight
   between them. Half of that is the most either may claim.

   They are anchored to opposite sides of the MAP CONTAINER, not the viewport, and
   the container is only what is left after the results column -- about 522px at a
   1024px viewport. Two panels of a fixed 22rem and 19rem cannot both sit in that,
   so at 1024px the print panel was painted over 134px of the layer panel, title
   included (audit A04). Capping each at half the free space makes the collision
   impossible at every width instead of at the ones anyone thought to measure. */
@media (min-width: 1024px) {
    .qcm-panel {
        /* 4rem, not 1rem: the map's zoom, reset and search controls live in a lane
           down the left edge, and at 1rem this panel was painted on top of them. */
        position: absolute; top: 1rem; left: 4rem; z-index: 20;
        width: min(22rem, calc((100% - 6.5rem) / 2)); max-width: calc(100% - 2rem);
        max-height: calc(100% - 2rem); overflow-y: auto;
        margin: 0; background: rgba(18, 18, 30, 0.96);
        backdrop-filter: blur(6px);
    }
}
/* Thirty-odd switches is a taller list than any panel on a map should be, and the
   map key sits under it: unbounded, the key was 1,284px below the map on a phone
   even with the panel moved onto the map. The list scrolls in its own box so the
   key stays within reach of the thing both of them describe. */
.qcm-panel-layers #qcm-layers { max-height: 40vh; overflow-y: auto; }

/* The layer panel is the print panel's opposite corner. Same overlay treatment,
   anchored right so the two never cover each other, and narrower — it holds
   checkboxes and swatches rather than a paper recipe. */
@media (min-width: 1024px) {
    .qcm-panel-layers { left: auto; right: 1rem; width: min(19rem, calc((100% - 6.5rem) / 2)); }
}

/* Below 1024px both panels leave the map and sit in normal flow under it, and
   neither is short. The layer panel carries a switch list AND the whole map key:
   opened at 390x844 it measured 691px inside an 844px screen, 16px under a 506px
   map. Scroll far enough to read it and 138px of map was left; scroll one notch
   further, so the panel's own top reached the top of the screen, and the map was
   gone (audit A11). The print panel is worse — measured 2026-09-10 it opened to
   1416px, taller than the phone screen itself, so no scroll position showed the
   whole paper recipe and the map was at 0px by the time its bottom was reached.
   A map key, or a paper recipe naming the area it prints, that describes a map
   the reader cannot see is not describing anything.

   So an open panel gets here the bound it already has on the two-column layout: a
   height it cannot grow past, and its own scrollbar, instead of growing down the
   page. The switch list keeps its own 40vh cap above, so the key stays near the
   top of the layer panel rather than a thousand pixels into it.

   The two panels get different fractions because they start at different heights
   down the page, and what the reader is owed is map on screen, not a tidy number.
   The layer panel begins 16px under the map, so 60vh (506px of an 844px screen)
   leaves 322px of map with the whole panel in view. The print panel begins 78px
   under it — the 16px gap, the closed layer panel's own 47px summary, and a second
   16px gap — so the same 60vh left only 259px, under the floor. 50vh (422px) is
   what fits that smaller budget: 344px of map, measured 2026-09-10.

   The attribute makes these (0,2,0) against the desktop rule's (0,1,0), which is
   harmless: the two media queries are disjoint, so they never apply to the same
   screen. An id would not be — `#qcm-app` at (1,0,0) would outrank the two-column
   `max-height` as well. scripts/qcm/layout.test.mjs measures what is left of the
   map, per panel, so a panel that grows past its budget fails rather than drifts. */
@media (max-width: 1023px) {
    .qcm-panel-layers[open] { max-height: 60vh; overflow-y: auto; }
    .qcm-panel-print[open] { max-height: 50vh; overflow-y: auto; }
}
.qcm-panel-summary { cursor: pointer; font-weight: 600; letter-spacing: 0.01em; }
.qcm-panel[open] .qcm-panel-summary { margin-bottom: 0.6rem; }
.qcm-panel .qcm-controls { max-height: none; }

/* D1: Highlight shortcuts + the Advanced screen-only emphasis controls. Shares the
   `.qcm-controls fieldset`/button/select/input chrome above; this is only what makes
   these particular controls different -- a touch target big enough to press with a
   thumb, no function that only a hover can reach, and the three states an OS or a
   reader can ask for that this panel had never answered. */
.qcm-highlight-buttons { display: flex; flex-wrap: wrap; gap: 0.5rem; width: 100%; }
/* 44px is the WCAG 2.5.8 target-size minimum, not a guess -- the shared button rule
   above (0.35rem 0.6rem padding on a small type size) falls well short of it. */
.qcm-highlight-buttons button,
.qcm-advanced-controls input[type="range"],
.qcm-advanced-controls select {
    min-height: 44px;
}
.qcm-highlight-buttons button { min-width: 44px; padding: 0.6rem 0.9rem; }
.qcm-highlight-buttons button[aria-pressed="true"] {
    background: #10b981; color: #052e16; border-color: #10b981; font-weight: 600;
}
.qcm-advanced-controls { display: flex; flex-direction: column; gap: 0.6rem; width: 100%; margin-top: 0.5rem; }
.qcm-advanced-controls label { display: flex; flex-direction: column; align-items: stretch; gap: 0.3rem; }
.qcm-advanced-controls input[type="range"] { width: 100%; }
.qcm-advanced-controls output { align-self: flex-end; color: #a1a1aa; font-size: 0.8rem; }
/* Every control here is keyboard- and click-operable already (buttons, a native
   range, a native select); nothing in this block is bound to :hover, so there is no
   hover-only function to name here -- that is a statement about what was NOT added,
   not a rule with a selector. */

/* prefers-contrast: the dimming this panel draws (base opacity, legend swatch
   opacity) is a deliberate LOSS of contrast for everything but the spotlight, which
   is the opposite of what this preference asks for. Undoing it here rather than
   trying to redraw a "high-contrast dim" that would still be a contrast reduction
   by construction. */
@media (prefers-contrast: more) {
    #qc-map .leaflet-overlay-pane path,
    .qcm-legend-swatch {
        opacity: 1 !important;
    }
    .qcm-highlight-buttons button[aria-pressed="true"] { outline: 2px solid currentColor; outline-offset: 1px; }
}

/* forced-colors (Windows High Contrast): the same opacity-based dimming would sit on
   top of a system palette it cannot reason about and could hide a shape the system
   otherwise guarantees is visible. Same fix as prefers-contrast, plus letting the
   forced palette draw the pressed state instead of the literal green. */
@media (forced-colors: active) {
    #qc-map .leaflet-overlay-pane path,
    .qcm-legend-swatch {
        opacity: 1 !important;
    }
    .qcm-highlight-buttons button[aria-pressed="true"] {
        background: Highlight; color: HighlightText; border-color: HighlightText;
        forced-color-adjust: none;
    }
}

/* prefers-reduced-motion: dimming/highlighting changes are instant already (no
   transition is declared on opacity or background above), so there is nothing to
   disable for the controls this unit added -- recorded here, next to the other two
   preferences, so a future transition on `.qcm-legend-swatch` or the highlight
   buttons is not added without also being guarded. */
@media (prefers-reduced-motion: reduce) {
    .qcm-legend-swatch, .qcm-highlight-buttons button { transition: none; }
}

/* A point symbol on the preview. The divIcon wrapper is Leaflet's, not ours --
   it ships a white background and a border, which would put a box around every
   campsite. The SVG inside carries the whole symbol. */
.qcm-site-marker {
    background: none;
    border: 0;
}
.qcm-site-marker:focus-visible {
    outline: 2px solid #f0fdf4;
    outline-offset: 2px;
}

/* The card a BLM pin opens: the agency's own directions, description, fee text, vintage
   and page link. A Leaflet popup is absolutely positioned in its own pane, so nothing
   here can push the map out of the width the layout tests hold it to; the height is
   Leaflet's maxHeight, which scrolls the content rather than growing the box. */
.qcm-site-card { font-size: 0.85rem; line-height: 1.45; }
.qcm-site-card p { margin: 0 0 0.5rem; }
.qcm-site-card p:last-child { margin-bottom: 0; }
.qcm-site-card-name { font-weight: 600; }
.qcm-site-card:focus-visible { outline: 2px solid #f0fdf4; outline-offset: 2px; }

/* N2: named terrain & places (GNIS). The marker glyph reuses .qcm-site-marker's
   own "no white Leaflet divIcon box" rule; the label is an owned DOM span (not a
   raster pixel) so displayStyle's emphasis/contrast can reach it like any other
   drawn layer. Selecting a name (click, or the suppressed-names list) gives it
   label priority on the next render -- `.is-selected` is the only visual cue
   needed, since re-placement itself is what keeps it drawn. */
.qcm-name-marker { background: none; border: 0; }
.qcm-name-marker:focus-within .qcm-name-label,
.qcm-name-marker-glyph:focus-visible { outline: 2px solid #f0fdf4; outline-offset: 2px; }
.qcm-name-label {
    font-size: 0.75rem;
    line-height: 1.2;
    color: #f4f4f5;
    text-shadow: 0 0 2px #000, 0 0 2px #000;
    pointer-events: none;
    white-space: nowrap;
}
.qcm-name-label.is-selected { color: #34d399; font-weight: 600; }
.qcm-names-list { list-style: none; margin: 0.3rem 0 0; padding: 0; max-height: 8rem; overflow-y: auto; }
.qcm-names-list li { padding: 0.3rem 0.4rem; cursor: pointer; border-top: 1px solid #3f3f46; font-size: 0.8rem; }
.qcm-names-list li:focus-visible { outline: 2px solid #f0fdf4; outline-offset: -2px; }

/* The layer switches and the print builder, as a thumb meets them (audit F05).

   Below 1024px both panels are in normal flow under the map and everything in
   them is tapped rather than clicked, but they kept the desktop treatment: a
   13x13 checkbox in a 20.6px label, buttons 17-21px tall, the scale and overlap
   selects at 18px. 44px is this product's own touch-target goal, the same one
   the map's finder button already answers to in quiet-corners.css.

   `min-height`, not `height`: three of the layer labels already wrap to two
   lines at 41.2px and have to keep growing rather than be clamped. This block
   sits last in the file because its selectors are no more specific than the
   ones they override, so source order is what decides.

   16px on a field is not a style choice: mobile Safari zooms the whole page
   when a focused input's text is under it, which throws the reader out of the
   map. The panel keeps its 0.9rem prose — only what you type into moves.

   scripts/qcm/phone-controls.test.mjs measures both, in a real browser. */
@media (max-width: 1023px) {
    .qcm-controls label,
    .qcm-controls button,
    .qcm-controls select,
    .qcm-controls .qcm-build,
    .qcm-controls input:not([type="radio"], [type="checkbox"]) {
        min-height: 44px;
    }
    .qcm-controls select,
    .qcm-controls input:not([type="radio"], [type="checkbox"]) {
        font-size: 1rem;
    }
}
