/*
 * The slippy map's structure, shared by every module that draws one.
 *
 * THE TEMPLATE'S, BECAUSE TWO MODULES NEED IT. This began inside
 * module_trade.css, which was the only stylesheet with a map in it. The cooler
 * log module plots a trip on the same engine, and what two modules need is the
 * template's -- the same rule that put assets/js/category_tree.js and
 * includes/avatar_builder.php here.
 *
 * THE SEAM IS "WHAT THE ENGINE REQUIRES" VERSUS "WHAT A MODULE WANTS IT TO LOOK
 * LIKE". assets/js/trade_map.js hardcodes the class names below -- it writes
 * .trade-map__tile elements and .trade-marker buttons whatever module asked for
 * the map -- so these rules have to exist wherever it runs, and they are the
 * only ones that do. A module's own pins, cards, keys and legends stay in that
 * module's stylesheet, because nothing outside it needs them.
 *
 * THE CLASS PREFIX IS STILL trade-, DELIBERATELY. Renaming it would touch the
 * engine, both modules' stylesheets and both modules' markup at once, for a
 * cosmetic gain, and the engine's class names are an implementation detail
 * nobody types by hand. It is a scar from where the code came from, not a
 * statement about who owns it now.
 *
 * NOTHING HERE POSITIONS A TILE OR A PIN. Those move constantly and are written
 * as rules into a stylesheet the engine creates at run time; see the note at
 * the top of assets/js/trade_map.js about why a style attribute cannot be used.
 */

:root {
    --colour-trade-map-surface: var(--colour-page-background);
    --colour-trade-map-text: var(--colour-card-text);

    /* How tall a map is by default. A module that wants a different height sets
       this on its own container rather than overriding .trade-map. */
    --trade-map-height: min(70vh, 44rem);
    --trade-marker-size: 2.25rem;
}

/* ---------------------------------------------------------------------------
 * The map itself
 * ------------------------------------------------------------------------ */

.trade-map {
    position: relative;
    height: var(--trade-map-height);
    border: 1px solid var(--colour-border);
    border-radius: var(--radius-medium);
    background-color: var(--colour-trade-map-surface);
    color: var(--colour-trade-map-text);

    /* TILES ARE ABSOLUTELY POSITIONED AND WOULD OTHERWISE SPILL. The rounded
       corner is only visible because this clips them. */
    overflow: hidden;

    /* The map handles its own dragging, so the browser must not also try to
       pan the page when a drag starts on it. */
    touch-action: none;
}

.trade-map__viewport {
    position: absolute;
    inset: 0;
    cursor: grab;
}

.trade-map__viewport.is-dragging {
    cursor: grabbing;
}

.trade-map__tiles,
.trade-map__markers,
.trade-map__track {
    position: absolute;
    inset: 0;
}

.trade-map__markers {
    /* THE MARKER LAYER MUST NOT EAT THE DRAG. It covers the whole map, so
       without this every pointerdown would land on it rather than the viewport
       and the map would never pan. The markers themselves take pointer events
       back, below. */
    pointer-events: none;
}

.trade-map__tile {
    position: absolute;
    top: 0;
    left: 0;
    width: 256px;
    height: 256px;

    /* A HALF PIXEL GAP APPEARS BETWEEN TILES WITHOUT THIS on fractional device
       pixel ratios, drawing a grid of pale lines across the whole map. */
    outline: 1px solid transparent;

    /* Dragging an image is the browser's default and it fights the pan. */
    user-select: none;
    -webkit-user-drag: none;
}

/* ---------------------------------------------------------------------------
 * The track
 *
 * A ROUTE RATHER THAN A SET OF PLACES. Markers answer "what is here"; a track
 * answers "where did it go", and a log with an order to it needs the second.
 * The line is one <polyline> however many points it has, which is what makes a
 * few hundred fixes cost nothing to draw.
 *
 * IT TAKES NO POINTER EVENTS, so a drag that begins on the route still pans the
 * map rather than stopping dead on the line.
 * ------------------------------------------------------------------------ */

.trade-map__track {
    pointer-events: none;
    overflow: visible;
}

.trade-map__track-line {
    fill: none;
    stroke: var(--colour-accent);
    stroke-width: 3;
    stroke-linejoin: round;
    stroke-linecap: round;
    opacity: 0.85;
}

/* ---------------------------------------------------------------------------
 * Pins
 * ------------------------------------------------------------------------ */

.trade-marker {
    position: absolute;
    top: 0;
    left: 0;
    display: grid;
    place-items: center;
    width: var(--trade-marker-size);
    height: var(--trade-marker-size);
    padding: 0;
    border: 2px solid rgba(255, 255, 255, 0.85);
    border-radius: 50%;
    font-size: 0.8rem;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;

    /* THE PIN POINTS AT ITS COORDINATE, not at its own top left. Without this a
       pin sits down and to the right of the thing it marks, by half its own
       width, and every pin on the map is wrong by the same amount -- which is
       the kind of error that looks like a projection bug. */
    transform-origin: center;
    margin-top: calc(var(--trade-marker-size) / -2);
    margin-left: calc(var(--trade-marker-size) / -2);

    /* Taken back from the layer above, which gave them up so the map can pan. */
    pointer-events: auto;

    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}

.trade-marker:focus-visible {
    outline: 2px solid var(--colour-accent);
    outline-offset: 2px;
}

/* The picture inside a pin. WHICH picture is the module's business: a mask
   image is set per marker kind in the module that defines that kind. */
.trade-marker::before {
    content: "";
    width: 1.3rem;
    height: 1.3rem;
    background-color: currentColor;
    -webkit-mask-repeat: no-repeat;
    mask-repeat: no-repeat;
    -webkit-mask-position: center;
    mask-position: center;
    -webkit-mask-size: contain;
    mask-size: contain;
    pointer-events: none;
}

/* THE COUNT MOVES OUT OF THE MIDDLE, because the icon is there now. A number on
   top of a picture is neither. It sits on the shoulder of the pin instead,
   which is where a count belongs and where it can overflow the circle without
   crowding it.

   :empty IS DOING REAL WORK HERE. A marker with no badge has a span with no
   child nodes, and this hides it -- no JavaScript change, and no blank chip
   hanging off every pin on the map. */
.trade-marker__face {
    position: absolute;
    top: -0.3rem;
    right: -0.3rem;
    min-width: 1.05rem;
    padding: 0 0.2rem;
    border-radius: 0.6rem;
    background-color: var(--colour-card-background);
    color: var(--colour-card-text);
    font-size: 0.65rem;
    line-height: 1.05rem;
    text-align: center;
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.35);
    pointer-events: none;
}

.trade-marker__face:empty {
    display: none;
}

/* ---------------------------------------------------------------------------
 * Map furniture
 * ------------------------------------------------------------------------ */

.trade-map__controls {
    position: absolute;
    top: var(--container-padding-tight);
    right: var(--container-padding-tight);
    display: flex;
    flex-direction: column;
    gap: var(--space-extra-small);
}

.trade-map__control {
    width: 2rem;
    height: 2rem;
    padding: 0;
    border: 1px solid var(--colour-border);
    border-radius: var(--radius-small);
    background-color: var(--colour-card-background);
    color: var(--colour-card-text);
    font-size: 1rem;
    line-height: 1;
    cursor: pointer;
}

.trade-map__status {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    max-width: 24rem;
    margin: 0;
    padding: var(--container-padding-tight);
    border-radius: var(--radius-small);
    background-color: var(--colour-card-background);
    color: var(--colour-card-text);
    text-align: center;
    box-shadow: 0 1px 6px rgba(0, 0, 0, 0.2);
}

.trade-map__attribution {
    position: absolute;
    right: 0;
    bottom: 0;
    margin: 0;
    padding: 0.15rem 0.4rem;
    background-color: rgba(255, 255, 255, 0.75);
    color: #1c2230;
    font-size: 0.7rem;

    /* REQUIRED, NOT DECORATIVE. OpenStreetMap's licence asks for visible credit
       wherever its tiles are shown, so this is not something to remove for
       tidiness -- it comes off when the tiles do. */
    border-top-left-radius: var(--radius-small);
}
