/* Map-tool-specific styling only. Generic primitives (button, notice,
   form-row, tab-bar, .hidden, the modal itself, etc.) live in the shared
   assets/css/auth-modal.css, loaded alongside this file. */

.map-toolbar {
    display: flex;
    justify-content: space-between;
    align-items: flex-end;
    gap: 16px;
    flex-wrap: wrap;
    margin-bottom: 16px;
}

.map-toolbar .form-row {
    margin-bottom: 0;
    min-width: 220px;
}

.map-toolbar-actions {
    display: flex;
    gap: 8px;
    flex-wrap: wrap;
}

/* Overrides .map-toolbar .form-row's min-width:220px (0,2,0) - needs to
   win on specificity (0,3,0 here), not load order, so it can't quietly
   break if either rule's position in the file ever changes. */
.map-toolbar .form-row.map-overlay-toggles {
    display: flex;
    align-items: center;
    gap: 16px;
    min-width: 0;
}

.map-overlay-toggles label {
    display: inline-flex;
    align-items: center;
    gap: 7px;
    font-weight: 700;
    font-size: 14px;
    color: #d5d8e2;
    cursor: pointer;
    white-space: nowrap;
}

.map-overlay-toggles input[type="checkbox"] {
    width: 16px;
    height: 16px;
    accent-color: #ffbd66;
    cursor: pointer;
}

/* Each .palette-group (label + its buttons) is the unit that wraps, not
   individual buttons - fits as many whole groups as the row has room for,
   then wraps to the next line, rather than giving every group its own
   full-width row regardless of how few buttons it has. */
.marker-palette {
    display: flex;
    flex-wrap: wrap;
    gap: 14px 22px;
    margin-bottom: 8px;
}

.palette-group {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 6px;
}

/* Icon-only - the label lives in .marker-type-label, a hover/focus tooltip
   rather than always-visible text, so a full palette of tools doesn't take
   up several wrapped rows of the toolbar. */
.marker-type-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    position: relative;
    width: 36px;
    height: 36px;
    padding: 6px;
    font-size: 13px;
    background: #242938;
    color: #f4f4f4;
    border: 1px solid #3a4054;
}

.marker-type-label {
    display: none;
    position: absolute;
    bottom: calc(100% + 6px);
    left: 50%;
    transform: translateX(-50%);
    background: #11131a;
    border: 1px solid #3a4054;
    color: #f4f4f4;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    white-space: nowrap;
    padding: 4px 8px;
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
    pointer-events: none;
    z-index: 20;
}

.marker-type-btn:hover .marker-type-label,
.marker-type-btn:focus-visible .marker-type-label {
    display: block;
}

.palette-icon {
    display: inline-flex;
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    color: inherit;
}

.palette-icon svg {
    width: 100%;
    height: 100%;
    stroke: currentColor;
}

/* Real in-game icons are PNGs used as a mask rather than an <img> - the
   bundle mixes black-on-transparent and white-on-transparent source
   images, and masking (clip to alpha, fill with currentColor) makes both
   render identically and keeps faction tinting working the same way it did
   for the line-art SVG set. */
.palette-icon .icon-mask,
.map-marker-icon .icon-mask {
    display: block;
    width: 100%;
    height: 100%;
    background-color: currentColor;
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
}

.marker-type-btn:hover {
    background: #2c3244;
}

.marker-type-btn.is-active {
    background: #ffbd66;
    color: #11131a;
    border-color: #ffbd66;
}

/* .hidden (from auth-modal.css, loaded first) only sets display:none at
   single-class specificity - .marker-type-btn's own display:inline-flex
   above is equal specificity and loads later, so it silently won that tie
   and faction-hidden buttons kept showing. This wins on specificity
   instead of load order, so it can't regress the same way again. */
.marker-type-btn.hidden {
    display: none;
}

/* flex-basis: 100% forces this onto its own line within the group (a
   heading above the icons), without affecting how the group itself wraps
   against other groups in .marker-palette. */
.palette-group-label {
    flex-basis: 100%;
    font-size: 11px;
    font-weight: 900;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    color: #7d8296;
}

#paletteHint {
    margin-top: 0;
    margin-bottom: 14px;
    font-size: 13px;
}

/* The map image itself is square, so the container just matches its width -
   aspect-ratio keeps height locked to whatever width the panel gives it, no
   vh guessing needed. */
.map-viewer-wrap {
    width: 100%;
    aspect-ratio: 1 / 1;
    overflow: auto;
    border: 1px solid #303546;
    border-radius: 14px;
    background: #0b0d13;
    /* Panning/drawing/marker-placement are driven entirely by JS pointer
       events (scrollLeft/scrollTop, in hll-vietnam-map.js) - touch-action:
       none stops the browser's own native touch-scroll/pinch-zoom handling
       from fighting that on touch devices, letting the same pointer
       handlers that already work for mouse drive touch too. */
    touch-action: none;
}

/* Fullscreens the whole tool panel (toolbar, palette, viewer, save/share
   row), not just the map canvas - see the matching comment in
   hll-vietnam-map.js on why. Reflows into a sidebar layout (marker palette
   down the left, map filling the rest) on wider screens - much better use
   of a full screen than the normal stacked-above-the-map layout. Below the
   phone-width breakpoint further down, the sidebar instead becomes a
   compact overlay across the top so the map itself isn't squeezed into a
   sliver - see that block for why. Everything except the map viewer lives
   in one .map-tool-controls wrapper (see the matching HTML comment), so
   both layouts only ever need to place two things. */
#map-tool:fullscreen {
    display: grid;
    grid-template-columns: 260px 1fr;
    grid-template-rows: 1fr;
    grid-template-areas: "controls viewer";
    gap: 14px;
    /* 100dvh (actual visible viewport, excluding mobile browser chrome)
       after the 100vh fallback - on some mobile browsers 100vh includes
       space hidden behind a collapsing/dynamic address bar, so content
       sized to it can extend below what's actually visible/reachable.
       Older browsers that don't understand dvh just ignore that line and
       keep the vh value above it. */
    height: 100vh;
    height: 100dvh;
    background: #11131a;
    padding: 20px;
    overflow: hidden;
}

#map-tool:fullscreen .map-tool-controls {
    grid-area: controls;
    display: flex;
    flex-direction: column;
    gap: 14px;
    min-height: 0;
    overflow-y: auto;
}

#map-tool:fullscreen .map-toolbar {
    margin-bottom: 0;
}

#map-tool:fullscreen .palette-column {
    display: flex;
    flex-direction: column;
}

#map-tool:fullscreen .marker-palette {
    flex-direction: column;
    align-items: stretch;
    flex-wrap: nowrap;
}

#map-tool:fullscreen .marker-type-btn,
#map-tool:fullscreen .marker-palette .small-button {
    text-align: left;
}

#map-tool:fullscreen .map-viewer-wrap {
    grid-area: viewer;
    height: 100%;
    min-height: 0;
}

#map-tool:fullscreen .map-save-row,
#map-tool:fullscreen .share-link-row {
    margin-top: 0;
}

#map-tool:fullscreen #loginPrompt {
    margin: 0;
}

/* Triggered by touch capability (pointer:coarse), not a viewport-width
   guess - a fixed px breakpoint here would silently never match on a
   touchscreen wider than whatever number was picked (a tablet, or a phone
   bigger than assumed), leaving the exact "260px sidebar eats the map"
   problem this is meant to fix. pointer:coarse fires for any primary input
   without fine precision (finger, not mouse), regardless of screen size,
   which is what actually determines whether a fixed sidebar is a problem
   here. The map fills the whole screen and .map-tool-controls becomes a
   compact overlay pinned across the top, scrollable if it doesn't all fit,
   with group headings and redundant field labels (the select's chosen
   value already shows what it is) hidden to keep it as short as possible -
   and the marker palette itself becomes one horizontally-scrolling row
   instead of a tall stacked list. */
@media (pointer: coarse) {
    #map-tool:fullscreen {
        display: block;
        height: 100vh;
        height: 100dvh;
        padding: 0;
    }

    /* position:fixed (anchored to the real viewport) rather than absolute
       (anchored to #map-tool) - a fullscreened element can pick up its own
       positioning behaviour from the browser's built-in UA stylesheet, and
       fixed sidesteps any uncertainty about that entirely: it always
       covers the true viewport no matter what #map-tool itself resolves
       to. Explicit z-index on both, not just the overlay, so which one
       stacks on top never depends on default/auto stacking-order rules. */
    #map-tool:fullscreen .map-viewer-wrap {
        position: fixed;
        inset: 0;
        width: 100vw;
        height: 100vh;
        height: 100dvh;
        aspect-ratio: unset;
        border: 0;
        border-radius: 0;
        z-index: 1;
    }

    /* Two compact scrollable rows (toolbar, palette) and nothing else - a
       real cap as a safety net, not the thing doing the work of keeping
       this short. Save/share/login are cut entirely here (not just
       hidden further down the panel) - saving and sharing a plan isn't a
       mid-fullscreen action; exit fullscreen and use the normal view for
       that. */
    #map-tool:fullscreen .map-tool-controls {
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        z-index: 5;
        max-height: 22vh;
        overflow-y: auto;
        gap: 6px;
        padding: 8px 10px;
        background: rgba(17, 19, 26, 0.94);
        border-bottom: 1px solid #303546;
    }

    #map-tool:fullscreen .map-save-row,
    #map-tool:fullscreen .share-link-row,
    #map-tool:fullscreen #loginPrompt {
        display: none;
    }

    /* nowrap + horizontal scroll, not wrap - a wrapped toolbar is what was
       eating most of the overlay's height; this keeps it to exactly one
       row, same treatment as the marker palette already gets below. */
    #map-tool:fullscreen .map-toolbar {
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: 8px;
        padding-bottom: 2px;
    }

    #map-tool:fullscreen .map-toolbar .form-row {
        flex: 0 0 auto;
        min-width: 0;
    }

    #map-tool:fullscreen .map-toolbar-actions {
        flex-wrap: nowrap;
        flex-shrink: 0;
    }

    #map-tool:fullscreen .map-toolbar .form-row > label[for],
    #map-tool:fullscreen .palette-group-label,
    #map-tool:fullscreen #paletteHint {
        display: none;
    }

    #map-tool:fullscreen .marker-palette {
        flex-direction: row;
        flex-wrap: nowrap;
        overflow-x: auto;
        gap: 8px;
        padding-bottom: 2px;
    }

    #map-tool:fullscreen .palette-group {
        flex-wrap: nowrap;
        flex-shrink: 0;
    }
}

.map-viewer {
    /* Square, confirmed via game file datamine: every launch map is a
       2000x2000m tile - the full map image is 2170x2170 (BASE_WIDTH/
       BASE_HEIGHT in hll-vietnam-map.js). Width/height are set entirely by
       JS's applyZoom(), which scales the map to exactly fill
       .map-viewer-wrap at zoom=1 (no scrollbars fully zoomed out) and
       beyond it at higher zoom levels (scrollable/pannable) - no fixed
       size here, it would fight the JS-computed one. */
    position: relative;
    transform-origin: top left;
    cursor: grab;
}

.map-viewer.is-panning {
    cursor: grabbing;
}

.map-viewer.is-placing {
    cursor: crosshair;
}

.map-image {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    background: #12151d;
    -webkit-user-drag: none;
    user-select: none;
}

/* Part of the map itself (dead-ground dimming, playable-area border, the
   lettered/numbered callout grid, real capture-point names) - not
   interactive, sits below the marker/drawing layers and never intercepts
   clicks placing/removing them. */
#staticOverlay {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.overlay-dead-zone {
    position: absolute;
    background: rgba(6, 7, 11, 0.6);
}

.overlay-playable-border {
    position: absolute;
    border: 1px solid rgba(255, 189, 102, 0.45);
    box-sizing: border-box;
}

.overlay-grid-line {
    position: absolute;
    background: rgba(255, 255, 255, 0.1);
}

.overlay-grid-line-v {
    width: 1px;
}

.overlay-grid-line-h {
    height: 1px;
}

/* One per grid cell (eg "A5"), anchored to that cell's top-left corner. */
.overlay-grid-label {
    position: absolute;
    transform: translate(4px, 3px);
    font-size: 11px;
    font-weight: 800;
    color: #ffbd66;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 5px rgba(0, 0, 0, 0.85);
}

/* Anchor point only (left/top set from JS) - the dot and label are
   independently positioned within it, NOT a flex row centered as a whole.
   Centering dot+gap+label together as one block (the previous approach)
   put the dot itself up to several px away from the true coordinate,
   varying with each location's name length - the longer the name, the
   further the dot drifted left of where the capture point actually is. */
.overlay-location {
    position: absolute;
}

/* The real hard-capture radius per checkpoint. The game's own Field Manual
   text describes this as a "black cross-hatched circle", but a soft
   translucent white fill is what it actually looks like in-game (per
   direct observation) - going with what's actually on screen over the
   written description. border-radius:50% clips both the border and fill
   to a true circle (the map viewer is always square - see
   BASE_WIDTH/BASE_HEIGHT in hll-vietnam-map.js - so a %-width/height div
   is never stretched into an ellipse). Sized/positioned entirely from JS
   (width/height/left/top), same as every other overlay element - nothing
   here is a fixed size. */
.overlay-hardcap {
    position: absolute;
    left: 0;
    top: 0;
    transform: translate(-50%, -50%);
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.16);
    border: 1px solid rgba(255, 255, 255, 0.35);
    pointer-events: none;
}

.overlay-location-dot {
    position: absolute;
    left: 0;
    top: 0;
    transform: translate(-50%, -50%);
    width: 5px;
    height: 5px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.55);
}

.overlay-location-label {
    position: absolute;
    left: 6px;
    top: 0;
    transform: translate(0, -50%);
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0.03em;
    color: rgba(255, 255, 255, 0.7);
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 5px rgba(0, 0, 0, 0.85);
    white-space: nowrap;
}

/* Fixed team HQ points (3 per side) - same anchor-point convention as
   .overlay-location above, real icon instead of a plain dot since HQs are
   a small, fixed, high-value set rather than 15 similar capture points. */
.overlay-hq {
    position: absolute;
}

.overlay-hq-icon {
    position: absolute;
    left: 0;
    top: 0;
    transform: translate(-50%, -50%);
    display: inline-block;
    width: 16px;
    height: 16px;
    background-color: currentColor;
    -webkit-mask-size: contain;
    mask-size: contain;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    filter: drop-shadow(0 1px 2px rgba(0, 0, 0, 0.9));
}

.overlay-hq-label {
    position: absolute;
    left: 10px;
    top: 0;
    transform: translate(0, -50%);
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.03em;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.9), 0 0 5px rgba(0, 0, 0, 0.85);
    white-space: nowrap;
}

/* Reference rings around each placed garrison (build-spacing + enemy lock
   ranges, per player-reported mechanics - not officially documented).
   Own layer, rebuilt whenever markers change, independent of #staticOverlay
   (which only rebuilds on map/toggle changes) and #markerLayer (which is
   wiped and rebuilt wholesale on every marker add/remove). */
#garrisonRangeLayer {
    position: absolute;
    inset: 0;
    pointer-events: none;
}

.overlay-garrison-range {
    position: absolute;
    left: 0;
    top: 0;
    transform: translate(-50%, -50%);
    box-sizing: border-box;
    border-radius: 50%;
    border-style: dashed;
    border-width: 1px;
    pointer-events: none;
}

.overlay-garrison-range.range-build {
    border-color: rgba(255, 189, 102, 0.55);
}

.overlay-garrison-range.range-lock-hostile {
    border-color: rgba(255, 122, 122, 0.6);
}

.overlay-garrison-range.range-lock-friendly {
    border-color: rgba(115, 217, 137, 0.6);
}

.garrison-range-legend {
    margin: 6px 0 0;
    font-size: 12px;
}

.legend-dot {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 50%;
    margin: 0 2px 0 8px;
    vertical-align: middle;
}

.garrison-range-legend .legend-dot:first-child {
    margin-left: 0;
}

.legend-dot.range-build {
    background: rgba(255, 189, 102, 0.8);
}

.legend-dot.range-lock-hostile {
    background: rgba(255, 122, 122, 0.8);
}

.legend-dot.range-lock-friendly {
    background: rgba(115, 217, 137, 0.8);
}

#drawingLayer {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    pointer-events: none;
}

#markerLayer {
    position: absolute;
    inset: 0;
}

.map-marker {
    /* Every real marker icon (garrison.png etc, via MARKER_ICON_IMAGES in
       hll-vietnam-map.js) has visible padding baked into the source PNG
       above its actual glyph, so neither the true center (-50%) nor the
       bottom edge (-100%) of the icon box lands exactly on the clicked
       coordinate - -75% (halfway between the two) is what was confirmed
       to actually line up, per direct visual check against the garrison
       range rings, which are centered on the real click coordinate. */
    position: absolute;
    transform: translate(-50%, -75%);
    display: flex;
    flex-direction: column;
    align-items: center;
    cursor: pointer;
    user-select: none;
}

.map-marker .map-marker-icon {
    display: inline-flex;
    width: 26px;
    height: 26px;
    color: #ffbd66;
    filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.6));
}

.map-marker .map-marker-icon svg {
    width: 100%;
    height: 100%;
    stroke: currentColor;
}

.map-marker .map-marker-label {
    background: rgba(11, 13, 19, 0.85);
    border: 1px solid #303546;
    border-radius: 6px;
    padding: 1px 6px;
    font-size: 11px;
    font-weight: 800;
    color: #f4f4f4;
    white-space: nowrap;
    margin-top: 2px;
}

.map-marker:hover .map-marker-icon {
    transform: scale(1.15);
}

.map-marker.is-connecting-from .map-marker-icon {
    filter: drop-shadow(0 0 6px #c98a4b) drop-shadow(0 0 6px #c98a4b);
    transform: scale(1.15);
}

.map-save-row {
    display: flex;
    gap: 10px;
    align-items: center;
    flex-wrap: wrap;
    margin-top: 18px;
}

.map-save-row input {
    flex: 1;
    min-width: 220px;
}

.share-link-row {
    margin-top: 14px;
}

.share-link-input-row {
    display: flex;
    gap: 8px;
}

.share-link-input-row input {
    flex: 1;
}

/* Per-checkpoint show/hide, grouped by the game's own 5-sector structure
   (3 candidate strongpoints each, one live per match) so unchecking the
   two that aren't active this game reads as "pick one per group", not a
   flat list of 15 unrelated toggles. */
.checkpoints-panel {
    background: rgba(20, 23, 34, 0.6);
    border: 1px solid #303546;
    border-radius: 12px;
    padding: 14px 16px;
    margin-bottom: 16px;
}

.checkpoints-panel-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
}

.checkpoints-panel-title {
    font-weight: 800;
    font-size: 14px;
}

.checkpoints-panel-actions {
    display: flex;
    gap: 8px;
}

.checkpoints-panel-hint {
    font-size: 13px;
    margin: 8px 0 12px;
}

.checkpoints-list {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 10px;
}

.checkpoint-sector-group {
    background: #141722;
    border: 1px solid #303546;
    border-radius: 10px;
    padding: 8px 10px;
}

.checkpoint-sector-label {
    display: block;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: #aeb3c1;
    margin-bottom: 6px;
}

.checkpoint-row {
    display: flex;
    align-items: center;
    gap: 7px;
    font-size: 12px;
    padding: 3px 0;
    cursor: pointer;
    color: #d5d8e2;
}

.checkpoint-row input[type="checkbox"] {
    width: 14px;
    height: 14px;
    accent-color: #ffbd66;
    cursor: pointer;
    flex-shrink: 0;
}

.section-title-row {
    display: flex;
    justify-content: space-between;
    align-items: center;
    gap: 16px;
}

@media (max-width: 700px) {
    .map-toolbar {
        flex-direction: column;
        align-items: stretch;
    }

    .checkpoints-list {
        grid-template-columns: 1fr 1fr;
    }
}
