/*
 * The mountain graph. Newsprint: the revealed ridge is three misregistered plates (cyan, magenta,
 * ink) multiplied over a halftone; the fog is a hatch in the surface tone with a dashed line.
 * No box around it — the drawing sits on the page.
 */
@layer components {
    .mountain-graph {
        display: flex;
        flex-direction: column;
        gap: var(--space-1);
        padding-block-start: var(--space-4);
    }

    /* SVG elements do not all honour the HTML `hidden` attribute (the fog, its caption).
       `data-zoom-hidden`: what the horizontal zoom has no room for at the moment — dates the axis
       cannot fit, or a label, photo or print a squeezed route would pile up (assets/profile/stretch.ts). */
    .mountain-graph svg :is([hidden], [data-zoom-hidden]) {
        display: none;
    }

    /* What stays put over the scrolling route (the wheel hint). */
    .mountain-graph__viewport {
        position: relative;
    }

    .mountain-graph__scroll {
        overflow-x: auto;
        overflow-y: hidden;
        overscroll-behavior-x: contain;
        scrollbar-width: none;
        /* Momentum on iOS before 13 (later ones have it by default). */
        -webkit-overflow-scrolling: touch;
        /* One finger pans (sideways is the graph's, up and down the page's); no native pinch here:
           two fingers stretch the route's time axis, not the page (assets/profile/graph_zoom.ts).
           The zoom is horizontal only: the box never grows taller, nothing pans up and down in it. */
        touch-action: pan-x pan-y;
    }

    .mountain-graph__scroll::-webkit-scrollbar {
        display: none;
    }

    .mountain-graph__scroll:focus-visible {
        outline: 2px solid var(--color-focus);
        outline-offset: 2px;
    }

    /* The stage: the campaign layer (UI/CampaignLayer) and the panorama's ridges (UI/Panorama) fill
       it exactly, over and behind the drawing; the zoom widens the SVG, they follow. */
    .mountain-graph__canvas {
        position: relative;
        inline-size: max-content;
    }

    .mountain-graph__svg {
        /* Positioned, so it paints over the panorama's ridges moved in before it. */
        position: relative;
        display: block;
        max-inline-size: none;
        font-family: var(--font-body);
    }

    /*
     * Another person's ridge in front (UI/Panorama, `panorama:foreground` → `data-route-away`): the
     * route steps back to a faint ridge of the panorama — only its line and ground stay, faded; its
     * kilograms, photos, prints, dates and captions go, and nothing of it takes a pointer. The zoom
     * is held at the whole drawing, so its controls and hints have nothing to offer.
     */
    .mountain-graph[data-route-away] .mountain-graph__svg {
        opacity: 0.22;
        pointer-events: none;
    }

    .mountain-graph[data-route-away] .mountain-graph__svg > :not(defs, [data-part="stretch"]),
    .mountain-graph[data-route-away] :is(.mountain-graph__zoom, .mountain-graph__hint) {
        visibility: hidden;
    }

    @media (prefers-reduced-motion: no-preference) {
        .mountain-graph__svg {
            transition: opacity 240ms ease-out;
        }
    }

    .mountain-graph__zoom {
        display: flex;
        justify-content: flex-end;
        gap: var(--space-1);

        &[hidden] {
            display: none;
        }
    }

    .mountain-graph__zoom-button {
        min-inline-size: 44px;
        min-block-size: 44px;
        font-size: var(--text-m);

        &[aria-disabled="true"] {
            opacity: 0.4;
            cursor: default;
        }
    }

    .mountain-graph__zoom-button--fit {
        font-size: var(--text-s);
    }

    /* "Priblíž: Ctrl + koliesko" — a moment over the route after a plain wheel, once per session. */
    .mountain-graph__zoom-hint {
        position: absolute;
        inset-block-start: var(--space-2);
        inset-inline-end: var(--space-2);
        z-index: 3;
        margin: 0;
        padding: var(--space-2xs) var(--space-xs);
        background: var(--color-surface);
        box-shadow: var(--shadow-md);
        border-radius: var(--radius-s);
        color: var(--color-text);
        font-size: var(--text-xs);
        pointer-events: none;
        opacity: 0;
        visibility: hidden;
    }

    .mountain-graph[data-zoom-hint="on"] .mountain-graph__zoom-hint {
        opacity: 1;
        visibility: visible;
    }

    @media (prefers-reduced-motion: no-preference) {
        .mountain-graph__zoom-hint {
            transition: opacity 200ms ease-out, visibility 200ms;
        }
    }

    .mountain-graph__halftone-dot {
        fill: var(--color-text);
        opacity: 0.5;
    }

    .mountain-graph__fog-hatch {
        stroke: var(--color-neutral-400);
        stroke-width: 0.8;
    }

    .mountain-graph__fog-ground {
        fill: var(--color-surface);
    }

    .mountain-graph__fog-line {
        fill: none;
        stroke: var(--color-neutral-500);
        stroke-width: 1.5;
        stroke-dasharray: 2 4;
        stroke-linejoin: round;
    }

    .mountain-graph__revealed-ground {
        fill: var(--color-bg);
    }

    .mountain-graph__plates {
        mix-blend-mode: multiply;
    }

    .mountain-graph__plate {
        fill: none;
        stroke-width: 2;
        stroke-linejoin: round;
    }

    .mountain-graph__plate--cyan {
        stroke: var(--color-accent);
    }

    .mountain-graph__plate--magenta {
        stroke: var(--color-accent-2);
    }

    .mountain-graph__plate--ink {
        stroke: var(--color-text);
    }

    /* A period without weighing (more than half a year between two points): the same plates,
       dashed, over a paler halftone — the line is a guess there, not a measurement. */
    .mountain-graph__plates--unmeasured .mountain-graph__plate {
        stroke-dasharray: 6 5;
        stroke-linecap: butt;
    }

    .mountain-graph__revealed-fill--unmeasured {
        opacity: 0.35;
    }

    /* Labels get a halo in the paper colour so they stay legible over the hatch and the dots. */
    .mountain-graph__fog-label,
    .mountain-graph__gap-label,
    .mountain-graph__axis,
    .mountain-graph__kg,
    .mountain-graph__date,
    .mountain-graph__book-caption {
        paint-order: stroke;
        stroke: var(--color-bg);
        stroke-width: 3px;
        stroke-linejoin: round;
        text-anchor: middle;
    }

    .mountain-graph__fog-label {
        fill: var(--color-neutral-700);
        stroke: var(--color-surface);
        font-size: 13px;
        font-style: italic;
    }

    .mountain-graph__gap-label {
        fill: var(--color-neutral-700);
        font-size: 10px;
        font-style: italic;
    }

    .mountain-graph__axis {
        fill: var(--color-neutral-700);
        font-size: 9.5px;
        text-anchor: start;
    }

    .mountain-graph__kg {
        fill: var(--color-text);
        font-size: 11px;
        font-weight: 600;
    }

    /* Beside the point (UI/MountainGraph/LabelPlacer): the text runs away from it. */
    .mountain-graph__kg--start {
        text-anchor: start;
    }

    .mountain-graph__kg--end {
        text-anchor: end;
    }

    .mountain-graph__date {
        fill: var(--color-neutral-700);
        font-size: 9.5px;
    }

    .mountain-graph__book-caption {
        fill: var(--color-accent-2-700);
        font-size: 10px;
        font-style: italic;
    }

    .mountain-graph__photo-ground {
        fill: var(--color-neutral-300);
    }

    .mountain-graph__photo-frame {
        fill: none;
        stroke: none;
    }

    .mountain-graph__point--book .mountain-graph__photo-frame {
        stroke: var(--color-text);
        stroke-width: 1.2;
    }

    .mountain-graph__dot {
        fill: var(--color-bg);
        stroke: var(--color-text);
        stroke-width: 1.5;
    }

    .mountain-graph__point--book .mountain-graph__dot {
        fill: var(--color-accent-2);
    }

    .mountain-graph__point.is-selected .mountain-graph__dot {
        fill: var(--color-accent);
    }

    .mountain-graph__point.is-selected .mountain-graph__photo-frame {
        stroke: var(--color-accent);
        stroke-width: 2;
    }

    .mountain-graph__hit {
        cursor: pointer;
    }

    /* `>`: a gallery link also holds its prints' rects. The zoom never scales a target (it moves
       with its point at its natural size), so it is finger-sized at every zoom. */
    .mountain-graph__hit > rect {
        fill: transparent;
        stroke: none;
    }

    .mountain-graph__hit:focus-visible {
        outline: none;
    }

    .mountain-graph__hit:focus-visible > rect {
        stroke: var(--color-focus);
        stroke-width: 2;
    }

    /* The gallery: prints of the photos on thin stems from the time axis up to the ridge. The
       photo is shown as it is (no dot screen, no grey — user decision, 2026-10-26) inside a paper
       border and a 1 px ink frame, small enough that the ridge stays the drawing. */
    .mountain-graph__stem {
        stroke: var(--color-text);
        stroke-width: 1;
    }

    .mountain-graph__stem-tip {
        fill: var(--color-text);
    }

    .mountain-graph__print-paper {
        fill: var(--color-bg);
    }

    .mountain-graph__print-frame {
        fill: none;
        stroke: var(--color-text);
        stroke-width: 1;
    }

    .mountain-graph__print-badge {
        fill: var(--color-text);
    }

    .mountain-graph__print-play {
        fill: var(--color-text);
        fill-opacity: 0.82;
        stroke: var(--color-bg);
        stroke-width: 1;
    }

    .mountain-graph__print-play-mark {
        fill: var(--color-bg);
    }

    .mountain-graph__print-count {
        fill: var(--color-bg);
        font-size: 9.5px;
        font-weight: 600;
        text-anchor: middle;
    }

    .mountain-graph__print-pile {
        transform-box: fill-box;
        transform-origin: center;
    }

    .mountain-graph__photo-hit:hover .mountain-graph__print--front .mountain-graph__print-frame,
    .mountain-graph__photo-hit:focus-visible .mountain-graph__print--front .mountain-graph__print-frame,
    .mountain-graph__photo-marker.is-selected .mountain-graph__print--front .mountain-graph__print-frame {
        stroke: var(--color-accent);
        stroke-width: 2;
    }

    .mountain-graph__photo-hit:active .mountain-graph__print--front .mountain-graph__print-frame {
        stroke: var(--color-accent-600);
    }

    .mountain-graph__photo-marker.is-selected .mountain-graph__stem {
        stroke: var(--color-accent);
    }

    /* A photo the campaign just revealed (assets/campaign/graph_refresh.ts): the pile lifts once
       and its frame flashes cyan — once, 600 ms, nothing for whoever asked for less motion. */
    @media (prefers-reduced-motion: no-preference) {
        .mountain-graph__photo-marker.is-new .mountain-graph__print-pile {
            animation: mountain-graph-print-arrive 600ms ease-out 1;
        }

        .mountain-graph__photo-marker.is-new .mountain-graph__print--front .mountain-graph__print-frame {
            animation: mountain-graph-print-flash 600ms ease-out 1;
        }
    }

    @keyframes mountain-graph-print-arrive {
        0% { transform: scale(0.6); opacity: 0; }
        55% { transform: scale(1.12); opacity: 1; }
        100% { transform: scale(1); }
    }

    @keyframes mountain-graph-print-flash {
        0%, 55% { stroke: var(--color-accent); stroke-width: 3; }
        100% { stroke: var(--color-text); stroke-width: 1; }
    }

    /* No route yet: a faint veiled ridge as wide as the column (no sideways scroll), and a line. */
    .mountain-graph__placeholder {
        display: flex;
        flex-direction: column;
        gap: var(--space-1);
        opacity: 0.8;
    }

    .mountain-graph__placeholder-svg {
        display: block;
        inline-size: 100%;
        block-size: auto;
        max-block-size: 7rem;
    }

    .mountain-graph__placeholder-fill {
        opacity: 0.6;
    }

    .mountain-graph__placeholder-caption {
        margin: 0;
        color: var(--color-neutral-700);
        font-size: var(--text-s);
        font-style: italic;
    }

    .mountain-graph__hint {
        display: flex;
        justify-content: space-between;
        gap: var(--space-2);
        margin: 0;
        font-size: var(--text-xs);
        color: var(--color-neutral-700);
    }

    .mountain-graph__hint-taps {
        display: flex;
        flex-wrap: wrap;
        justify-content: flex-end;
        column-gap: var(--space-2);
    }

    /* The gallery hint is the one a first-time visitor needs: in the ink, not the grey. */
    .mountain-graph__hint-photo {
        color: var(--color-text);
    }

    /*
     * The hints follow the pointer: "Ťukni" where a finger taps, "Klikni" where a mouse clicks — a
     * desktop is never told to tap. Without a fine pointer that hovers (a phone, a tablet) the
     * finger's wording stays; a touch laptop with a mouse gets the mouse's.
     */
    .mountain-graph__hint-mouse {
        display: none;
    }

    @media (hover: hover) and (pointer: fine) {
        .mountain-graph__hint-touch {
            display: none;
        }

        .mountain-graph__hint-mouse {
            display: inline;
        }
    }

    /*
     * Desktop (the page is the whole 980 px route, Page/Home): the zoom controls share one row with
     * the hints, so the drawing with its dates and the controls stay above the fold together with
     * the hero — and above the sticky Donio bar (QA 2026-10-31).
     */
    @media (min-width: 64rem) {
        .mountain-graph {
            display: grid;
            grid-template-columns: minmax(0, 1fr) auto;
            align-items: center;
            column-gap: var(--space-3);
        }

        .mountain-graph > * {
            grid-column: 1 / -1;
        }

        .mountain-graph > .mountain-graph__zoom {
            grid-row: 2;
            grid-column: 2;
        }

        .mountain-graph > .mountain-graph__hint {
            grid-row: 2;
            grid-column: 1;
        }
    }
}
