/* ==========================================================================
   Quercia viva — map view (Leaflet, hybrid aerial basemap)
   Shared skin for full-panel maps: the mowing list map view today, any other
   "customers on a map" panel later. The event-modal map keeps its own compact
   rail styles in dashboard.css.
   ========================================================================== */

/* ---- Map panel ---------------------------------------------------------- */
.qc-map__caption { color: var(--qc-text-secondary); font-size: .82rem; }

/* Three pin colours mean nothing without a key, so one sits under the title.
   Colour is never the only cue: every swatch carries its label. */
.qc-map__legend { display: flex; flex-wrap: wrap; gap: 0 .7rem; margin-top: .1rem; }
.qc-map__legend-item {
    display: inline-flex; align-items: center; gap: .3rem;
    font: 600 .72rem/1.7 var(--qc-font-body); color: var(--qc-text-secondary);
}
.qc-map__legend-item::before {
    content: ''; flex: none;
    width: .55rem; height: .55rem; border-radius: 50%;
    background: var(--qc-legend-dot, var(--qc-state-done));
}
.qc-map__legend-item--to-do { --qc-legend-dot: var(--qc-state-to-do); }
.qc-map__legend-item--scheduled { --qc-legend-dot: var(--qc-state-scheduled); }
.qc-map__legend-item--done { --qc-legend-dot: var(--qc-state-done); }

.qc-map { position: relative; overflow: hidden; }

/* Inside a modal the map fills the body, keeping the dialog's bottom corners. */
.qc-map--modal {
    height: min(72vh, 760px);
    border-radius: 0 0 var(--qc-radius-card) var(--qc-radius-card);
}
.qc-map__host { position: absolute; inset: 0; z-index: 1; }
.qc-map__host .leaflet-container {
    width: 100%; height: 100%;
    background: var(--qc-surface);
    font-family: var(--qc-font-body);
}

/* Leaflet chrome re-skinned onto brand tokens */
.qc-map .leaflet-control-zoom a {
    background: var(--qc-card-bg); color: var(--qc-text-primary); border-color: var(--qc-border);
}
.qc-map .leaflet-control-zoom a:hover { background: var(--qc-surface-light); color: var(--qc-primary); }
.qc-map .leaflet-control-attribution {
    background: color-mix(in srgb, var(--qc-card-bg) 82%, transparent);
    /* Ten pixels, before. Attribution is not decoration — it is the condition
       the tiles are used under, and it has to be legible like anything else. */
    color: var(--qc-text-tertiary); font-size: .75rem;
}
.qc-map .leaflet-control-attribution a { color: var(--qc-primary); }

/* ---- Basemap ------------------------------------------------------------- */
/* The aerial imagery is blended over the drawn map (its opacity and the zoom it
   starts at are set on the layer, in the controller) and toned down here so it
   reads as ground texture under the data instead of competing with the pins.
   Dark theme also dims it, or a sunlit field would glow against the dark chrome
   around it.

   It is no longer desaturated on the way: what the photograph is for is the
   colour of the ground — a lawn, a hedge, a bare yard — and taking that out
   left it a grey haze over a map that had just been given its own. */
.qc-map__host .qc-map__imagery { filter: contrast(.94); }
[data-bs-theme="dark"] .qc-map__host .qc-map__imagery {
    filter: saturate(.6) brightness(.72) contrast(.95);
}

/* The drawn map has one edition, and it is a daylight one: a sheet that colours
   woods green has no night version to fetch. On a dark page it is settled in
   rather than swapped out — dimmed and warmed a little, so it sits inside the
   chrome instead of glaring out of it, and never so far that the green stops
   being green. That is the whole point of the sheet.

   The pane, not the tiles: filtering each <img> leaves hairlines where they
   meet, because a filter is resolved per element. */
[data-bs-theme="dark"] .qc-map__host .leaflet-tile-pane {
    filter: brightness(.82) saturate(.9) contrast(1.02);
}

/* ---- Mowing state -------------------------------------------------------- */
/* One source for the three states the map speaks in — pins, legend and popup
   chip all read these. The hues are the app's own work-status colours (see
   Work::WORK_*_COLOR): a job still to plan is the calendar's orange, one
   already booked is its lime. "Done or not to cut" is deliberately a neutral,
   not a fourth hue: what is closed should recede, not compete for attention.
   Declared on :root because Leaflet appends popups outside .qc-map. */
:root {
    --qc-state-to-do: var(--qc-status-orange);
    --qc-state-scheduled: var(--qc-status-lime);
    --qc-state-done: var(--qc-text-tertiary);
}

/* ---- Customer pins ------------------------------------------------------- */
/* Teardrop pins (map_controller `_pinIcon`): the fill is the mowing state, set
   as a class so every colour stays a token — the theme switch re-colours them
   with no redraw. */
.qc-pin { background: none; border: 0; }
.qc-pin__shape--to-do { --qc-pin: var(--qc-state-to-do); }
.qc-pin__shape--scheduled { --qc-pin: var(--qc-state-scheduled); }
.qc-pin__shape--done { --qc-pin: var(--qc-state-done); }
.qc-pin__shape {
    display: block; width: 100%; height: 100%;
    filter: drop-shadow(0 3px 4px var(--qc-shadow-color));
    transform-origin: 50% 100%;
    transition: transform var(--qc-dur-fast) var(--qc-ease-fast);
}
.qc-pin__shape svg { display: block; width: 100%; height: 100%; }
.qc-pin__body {
    fill: var(--qc-pin, var(--qc-primary));
    stroke: var(--qc-card-bg);
    stroke-width: 1.6;
}
/* The hole in the head: card background, so the pin reads as punched out on
   either theme and stays legible over dark imagery. */
.qc-pin__eye { fill: var(--qc-card-bg); }

/* How many customers share this spot, sitting in the widened hole. Dark ink on
   the card-coloured disc, so it stays legible whatever the state colour around
   it is — white on the pale lime would not be. */
.qc-pin__shape { position: relative; }
.qc-pin__count {
    position: absolute; inset: 0 0 auto 0; height: 25px;
    display: flex; align-items: center; justify-content: center;
    font: 800 .6rem/1 var(--qc-font-body); letter-spacing: -.02em;
    color: var(--qc-text-primary);
    pointer-events: none;
}

.qc-pin:hover .qc-pin__shape,
.qc-pin:focus-visible .qc-pin__shape { transform: scale(1.14); }
.qc-pin:focus-visible { outline: none; }
.qc-pin:focus-visible .qc-pin__body { stroke: var(--qc-primary); stroke-width: 2.6; }

@media (prefers-reduced-motion: reduce) {
    .qc-pin__shape { transition: none; }
}

/* ---- Customer popup ------------------------------------------------------ */
.qc-mapop .leaflet-popup-content-wrapper {
    background: var(--qc-card-bg); color: var(--qc-text-primary);
    border: 1px solid var(--qc-border); border-radius: var(--qc-radius-card);
    box-shadow: var(--qc-shadow-md);
}
.qc-mapop .leaflet-popup-tip { background: var(--qc-card-bg); border: 1px solid var(--qc-border); }
.qc-mapop .leaflet-popup-content { margin: .8rem .9rem; line-height: 1.4; }
.qc-mapop .leaflet-popup-close-button { color: var(--qc-text-tertiary); }
.qc-mapop .leaflet-popup-close-button:hover { color: var(--qc-primary); }

.qc-mapop__title {
    display: flex; align-items: center; gap: .4rem; flex-wrap: wrap;
    margin: 0 1.1rem .2rem 0;
    font-family: var(--qc-font-display); font-weight: 800; font-size: 1rem;
    letter-spacing: -.01em; color: var(--qc-text-primary);
}
.qc-mapop__flag {
    padding: .05rem .4rem; border-radius: var(--qc-radius-pill);
    font: 700 .68rem/1.5 var(--qc-font-body); text-transform: uppercase; letter-spacing: .04em;
    color: var(--qc-error); background: color-mix(in srgb, var(--qc-error) 14%, transparent);
}
/* The pin colour, spelled out — same swatch-plus-label pairing as the legend. */
.qc-mapop__state {
    display: inline-flex; align-items: center; gap: .35rem;
    margin: 0 0 .3rem;
    font: 700 .74rem/1.5 var(--qc-font-body); color: var(--qc-text-secondary);
}
.qc-mapop__state::before {
    content: ''; flex: none;
    width: .6rem; height: .6rem; border-radius: 50%;
    background: var(--qc-state-dot, var(--qc-state-done));
}
.qc-mapop__state--to-do { --qc-state-dot: var(--qc-state-to-do); }
.qc-mapop__state--scheduled { --qc-state-dot: var(--qc-state-scheduled); }
.qc-mapop__state--done { --qc-state-dot: var(--qc-state-done); }

.qc-mapop__addr { margin: 0 0 .35rem; font-size: .82rem; color: var(--qc-text-secondary); }

/* Contacts: phone numbers and the address are links where they can be dialled
   or written to, plain text where the field holds something else. */
.qc-mapop__contacts { display: flex; flex-wrap: wrap; gap: .3rem; margin: 0 0 .1rem; }
.qc-mapop__contact {
    padding: .08rem .45rem; border-radius: var(--qc-radius-pill);
    font: 600 .78rem/1.55 var(--qc-font-body);
    color: var(--qc-text-secondary); background: var(--qc-surface-light);
    border: 1px solid var(--qc-border); text-decoration: none;
}
a.qc-mapop__contact { color: var(--qc-primary); }
a.qc-mapop__contact:hover { color: var(--qc-primary-dark); border-color: color-mix(in srgb, var(--qc-primary) 40%, var(--qc-border)); }

/* The mowing half sits under a rule, so the two halves read as two blocks. */
.qc-mapop__block--mowing { margin-top: .55rem; padding-top: .5rem; border-top: 1px solid var(--qc-divider); }
.qc-mapop__section {
    margin: 0 0 .3rem;
    font: 800 .68rem/1 var(--qc-font-display); text-transform: uppercase; letter-spacing: .08em;
    color: var(--qc-text-tertiary);
}

.qc-mapop__badge {
    display: inline-block;
    padding: .1rem .5rem; border-radius: var(--qc-radius-pill);
    font: 700 .74rem/1.6 var(--qc-font-body); color: var(--qc-text-primary);
    background: color-mix(in srgb, var(--qc-mapop-badge, var(--qc-primary)) 22%, transparent);
    border: 1px solid color-mix(in srgb, var(--qc-mapop-badge, var(--qc-primary)) 45%, transparent);
}
.qc-mapop__chips { display: inline-flex; flex-wrap: wrap; gap: .25rem; }
.qc-mapop__facts {
    display: grid; grid-template-columns: auto 1fr; gap: .2rem .6rem;
    align-items: baseline;
    margin: 0; font-size: .82rem;
}
.qc-mapop__facts dt { color: var(--qc-text-tertiary); font-weight: 600; }
.qc-mapop__facts dd { margin: 0; color: var(--qc-text-primary); font-variant-numeric: tabular-nums; }
.qc-mapop__hint { margin-left: .35rem; color: var(--qc-text-tertiary); }
.qc-mapop__note {
    margin: .3rem 0 0; font-size: .78rem; color: var(--qc-text-secondary);
}
.qc-mapop__link { margin-top: .6rem; }

/* ---- Picking between customers at one address ---------------------------- */
/* Each row carries the same coloured dot as its pin, so the list reads as the
   pin taken apart rather than as a new piece of vocabulary. The card of the
   row under the pointer opens above the list — see `_chooser` for why above
   and not below. */
.qc-mapop__preview:not(:empty) {
    margin-bottom: .5rem; padding-bottom: .5rem;
    border-bottom: 1px solid var(--qc-divider);
}
.qc-mapop__pick { list-style: none; margin: 0; padding: 0; }
.qc-mapop__pick-item {
    display: flex; align-items: center; gap: .45rem;
    width: 100%; padding: .35rem .5rem;
    border: 1px solid transparent; border-radius: var(--qc-radius-input);
    background: none; text-align: left; cursor: pointer;
    color: var(--qc-text-primary);
    transition: background var(--qc-dur-fast) var(--qc-ease-fast),
                border-color var(--qc-dur-fast) var(--qc-ease-fast);
}
.qc-mapop__pick-item::before {
    content: ''; flex: none;
    width: .6rem; height: .6rem; border-radius: 50%;
    background: var(--qc-state-dot, var(--qc-state-done));
}
.qc-mapop__pick-item:hover,
.qc-mapop__pick-item:focus-visible,
.qc-mapop__pick-item.is-current {
    background: var(--qc-surface-light);
    border-color: color-mix(in srgb, var(--qc-primary) 30%, var(--qc-border));
    outline: none;
}
.qc-mapop__pick-name { font-weight: 700; font-size: .84rem; }
.qc-mapop__pick-state { margin-left: auto; font-size: .75rem; color: var(--qc-text-tertiary); }

@media (prefers-reduced-motion: reduce) {
    .qc-mapop__pick-item { transition: none; }
}

/* Phones: the dialog goes full screen, so the map takes what the header leaves. */
@media (max-width: 575.98px) {
    .qc-map--modal { height: 100%; min-height: 60vh; border-radius: 0; }
    .modal-fullscreen-sm-down .modal-body { display: flex; }
    .modal-fullscreen-sm-down .modal-body > .qc-map { flex: 1 1 auto; }
}

/* On a page of its own, rather than inside a modal.

   The map used to exist only as a modal, which meant it could not be resized,
   printed, linked to, or left open beside the list it is about. As a panel it
   keeps its own card border — there is no dialog around it any more — and takes
   a fixed share of the viewport so the list underneath it stays reachable
   without the page becoming a map with a footnote. */
.qc-map--page {
    height: min(58vh, 640px);
    min-height: 22rem;
    border: 1px solid var(--qc-border);
    border-radius: var(--qc-radius-card);
}
