/* The bouldering page as a guidebook (see script.js): the chart pinned to the
   left of the window, the reviews in a column on the right; on phones the
   chart is a band at the top that stays while the reviews scroll. Applies
   once the script has set body.gymmap; otherwise the page is the plain list. */

/* Map colors, all mixed from the site's paper, ink and flag colors. */
body.gymmap {
    --map-ink: color-mix(in srgb, var(--primary) 62%, var(--yellow-ink));
    --map-paper: var(--theme);
    --map-land: var(--theme);
    --map-water: color-mix(in srgb, var(--theme) 86%, var(--blue));
    --halo: var(--theme);
    --map-w: 56vw;
    --band: max(40vh, 240px);
}

/* The chart is the navigation; the page date gives way to each review's. */
body.gymmap .toc,
body.gymmap .post-header .post-meta {
    display: none;
}

/* ---- The column: title, intro and every review ---- */
body.gymmap .post-content h2 {
    margin: 30px 0 2px;
    font-size: var(--step-2);
    line-height: 1.25;
    scroll-margin-top: 28px;
}

.gym-written {
    margin: 0 0 8px;
    font-size: var(--step--2);
    font-style: italic;
    color: var(--secondary);
}

/* ---- The chart: map, Chicago inset and zoom buttons ---- */
.guide-chart {
    position: relative;
    overflow: hidden;
    background: var(--map-water);
}

/* The map takes every touch itself: one finger drags, two pinch. */
.map-view {
    position: absolute;
    inset: 0;
    overflow: hidden;
    cursor: grab;
    touch-action: none;
    -webkit-user-select: none;
    user-select: none;
    -webkit-touch-callout: none;
}

.map-view.dragging {
    cursor: grabbing;
}

.map-sheet {
    position: absolute;
    top: 0;
    left: 0;
    line-height: 0;
    will-change: transform;
    opacity: 0;
}

.drawn .map-sheet,
.drawn .inset-sheet,
.drawn .map-zoom {
    opacity: 1;
}

.map-sheet.gliding {
    transition: transform 0.7s cubic-bezier(0.25, 0.7, 0.2, 1);
}

.map-sheet > svg,
.inset-sheet > svg {
    display: block;
    width: 100%;
    height: 100%;
}

.map-marks {
    position: absolute;
    inset: 0;
    line-height: 1.2;
}

.inset-sheet {
    position: absolute;
    z-index: 2;
    left: 16px;
    bottom: 16px;
    width: 180px;
    margin: 0;
    line-height: 0;
    filter: drop-shadow(0 4px 10px rgba(60, 40, 10, 0.14));
    opacity: 0;
}

/* Zoom: a small double-ruled stack of +, − and reset in the corner. */
.map-zoom {
    position: absolute;
    z-index: 3;
    right: 16px;
    bottom: 16px;
    display: flex;
    flex-direction: column;
    padding: 3px;
    background: var(--theme);
    border: 1.5px solid var(--map-ink);
    box-shadow:
        inset 0 0 0 2px var(--theme),
        inset 0 0 0 2.6px var(--map-ink),
        0 2px 6px rgba(60, 40, 10, 0.08);
    opacity: 0;
    transition: opacity 0.3s ease;
}

.map-zoom button {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    font-size: 20px;
    line-height: 1;
    color: var(--map-ink);
    cursor: pointer;
}

.map-zoom button + button {
    border-top: 0.6px solid color-mix(in srgb, var(--map-ink) 45%, transparent);
}

@media (hover: hover) {
    .map-zoom button:hover {
        color: var(--pink-ink);
    }
}

.map-zoom button:focus-visible {
    color: var(--pink-ink);
    outline: 1.5px solid var(--pink);
    outline-offset: -3px;
}

.map-zoom button:disabled {
    color: color-mix(in srgb, var(--map-ink) 35%, transparent);
    cursor: default;
}

.map-reset svg {
    width: 14px;
    height: 14px;
    fill: none;
    stroke: currentColor;
    stroke-width: 1.4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

/* ---- A gym on the chart: a boulder in red ink and its name, set bolder than
   the place names so the gyms read first (and read as clickable). ---- */
.mark {
    position: absolute;
    width: 0;
    height: 0;
    padding: 0;
    border: 0;
    background: none;
    font: inherit;
    cursor: pointer;
    --dx: 0px;
    --dy: 0px;
}

.mark:focus-visible {
    outline: none;
}

.mark-rock {
    position: absolute;
    left: calc(var(--dx) - 10px);
    top: calc(var(--dy) - 11px);
    width: 20px;
    height: 15px;
    overflow: visible;
    transition: transform 0.25s cubic-bezier(0.2, 0.7, 0.2, 1), opacity 0.25s ease;
}

.mark-rock .rock {
    fill: var(--pink-ink);
    stroke: var(--halo);
    stroke-width: 1.6;
    stroke-linejoin: round;
    paint-order: stroke;
}

.mark-rock .rock-shade {
    fill: none;
    stroke: var(--halo);
    stroke-width: 0.8;
    stroke-linejoin: round;
    opacity: 0.75;
}

.mark-name {
    position: absolute;
    top: calc(var(--dy) - 0.72em);
    padding: 0 3px 1px;
    border-radius: 2px;
    font-size: 15px;
    font-weight: bold;
    line-height: 1.2;
    white-space: nowrap;
    color: var(--primary);
    text-shadow: 0 0 2px var(--halo), 0 0 2px var(--halo), 0 0 3px var(--halo), 0 0 5px var(--halo), 0 0 8px var(--halo);
    transition: color 0.2s ease, background-color 0.2s ease;
}

.inset-sheet .mark-name {
    font-size: 12.5px;
}

.mark[data-side="e"] .mark-name { left: calc(var(--dx) + 11px); }
.mark[data-side="w"] .mark-name { right: calc(11px - var(--dx)); }
.mark[data-side="n"] .mark-name { top: auto; bottom: calc(13px - var(--dy)); left: var(--dx); transform: translateX(-50%); }
.mark[data-side="s"] .mark-name { top: calc(var(--dy) + 6px); left: var(--dx); transform: translateX(-50%); }

/* Hover: the boulder lifts and the name takes the boulder's red. */
@media (hover: hover) {
    .mark:hover .mark-rock {
        transform: translateY(-2px) scale(1.15);
    }

    .mark:hover .mark-name {
        color: var(--pink-ink);
    }
}

.mark:focus-visible .mark-name {
    color: var(--pink-ink);
}

/* The gym being read: the others step back, and its name sits on a wash of
   pink, its boulder a size up. */
.following .mark:not(.current) .mark-rock {
    opacity: 0.55;
}

.following .mark:not(.current) .mark-name {
    color: var(--secondary);
}

.mark.current {
    z-index: 2;
}

.mark.current .mark-rock {
    transform: translateY(-2px) scale(1.3);
}

.mark.current .mark-name {
    color: var(--primary);
    background: color-mix(in srgb, var(--pink) 40%, var(--theme));
    text-shadow: none;
}

/* ---- Load: the coast inks in while the gyms settle onto the map ---- */
.inking .coast {
    stroke-dasharray: 1000;
    animation: ink 2.4s cubic-bezier(0.4, 0.1, 0.3, 1) both;
}

.inking .wl,
.inking .hills,
.inking .labels,
.inking .rose,
.inking .ship,
.inking .wave,
.inking .rhumb {
    animation: fade 1.2s ease 0.6s both;
}

.inking .mark {
    animation: settle 0.5s cubic-bezier(0.2, 0.7, 0.2, 1) 0.9s both;
}

@keyframes ink {
    from { stroke-dashoffset: 1000; }
    to { stroke-dashoffset: 0; }
}

@keyframes fade {
    from { opacity: 0; }
}

/* ---- Wide screens: the chart pinned on the left, the page on the right ---- */
@media (min-width: 1100px) {
    .guide-chart {
        position: fixed;
        z-index: 1;
        top: 0;
        left: 0;
        bottom: 0;
        width: var(--map-w);
        border-right: 1px solid var(--border);
    }

    body.gymmap .site-header,
    body.gymmap .main {
        max-width: none;
        margin: 0 0 0 var(--map-w);
        padding-left: 44px;
        padding-right: 44px;
    }

    body.gymmap .main {
        padding-top: 24px;
    }

    /* One plain column, not the note page's centered grid. */
    body.gymmap .post-single {
        display: block;
        max-width: 620px;
    }
}

/* ---- Phones and narrow windows: the chart is a band that stays on top ---- */
@media (max-width: 1099px) {
    .guide-chart {
        position: sticky;
        z-index: 4;
        top: 0;
        height: var(--band);
        margin: 18px calc(var(--gap) * -1) 4px;
        border-block: 1px solid var(--border);
    }

    body.gymmap .post-content h2 {
        scroll-margin-top: calc(var(--band) + 16px);
    }

    .inset-sheet {
        left: 10px;
        bottom: 10px;
        width: 112px;
    }

    .map-zoom {
        right: 10px;
        bottom: 10px;
    }

    .map-zoom button {
        width: 26px;
        height: 26px;
        font-size: 18px;
    }

    .mark-name {
        font-size: 13.5px;
    }

    .inset-sheet .mark-name {
        font-size: 11px;
    }
}

@media (prefers-reduced-motion: reduce) {
    .mark-rock,
    .mark-name,
    .map-sheet,
    .map-zoom {
        transition: none;
    }

    .inking .coast,
    .inking .mark {
        animation: none;
    }
}

/* The note page's settle-in moves the content with a transform, and a
   transformed parent would pin the fixed chart to itself (it would load in the
   right column, then jump). Here the content only fades in. */
body.gymmap .post-content {
    animation-name: fade;
}
