/*
 * Start-up loader: a bomb whose fuse burns down while the app downloads, above a strip of
 * mine-field tiles that are uncovered as loading progresses.
 *
 * Blazor sets --blazor-load-percentage (0% to 100%) and --blazor-load-percentage-text on the
 * root element. Geometry inside the SVG is driven by those values directly:
 *   - percentages on x/width/cx resolve against the SVG viewport width (viewBox width 200),
 *   - percentages on cy resolve against the viewport height (viewBox height 170),
 * so the SVG element keeps the viewBox aspect ratio and the fractions below map to viewBox units.
 */

.mh-loader {
    display: flex;
    align-items: center;
    flex-direction: column;
    gap: var(--mh-space-4);
    justify-content: center;
    min-block-size: 100dvh;
    padding: var(--mh-space-6);
    color: var(--mh-color-on-page);
    text-align: center;
}

.mh-loader__art {
    aspect-ratio: 200 / 170;
    inline-size: min(16rem, 70vw);
    overflow: visible;
}

.mh-loader__bomb-body {
    fill: url(#mh-loader-bomb-gradient);
}

.mh-loader__bomb-stop-light {
    stop-color: var(--mh-color-loader-bomb-shine);
}

.mh-loader__bomb-stop-dark {
    stop-color: var(--mh-color-loader-bomb);
}

.mh-loader__bomb-shine {
    fill: var(--mh-color-on-page);
    opacity: 0.35;
}

.mh-loader__cap {
    fill: var(--mh-color-loader-cap);
    stroke: var(--mh-color-loader-bomb);
    stroke-width: 2;
}

.mh-loader__fuse {
    fill: none;
    stroke: var(--mh-color-loader-fuse);
    stroke-linecap: round;
    stroke-width: 5;
}

.mh-loader__fuse-twist {
    fill: none;
    stroke: var(--mh-color-loader-fuse-twist);
    stroke-dasharray: 2.5 3.5;
    stroke-width: 5;
}

/* Fuse runs from x=118 (59%) to x=178 (89%): the visible part shrinks from the tip as loading grows */
.mh-loader__fuse-mask-rect {
    fill: var(--mh-white);
    height: 100%;
    width: calc(30% - var(--blazor-load-percentage, 0%) * 0.3);
    x: 59%;
    y: 0;
    transition: width var(--mh-duration-fast) linear;
}

/* The spark sits on the burning end of the fuse: tip (178, 6) at 0%, cap (118, 30) at 100% */
.mh-loader__spark {
    cx: calc(89% - var(--blazor-load-percentage, 0%) * 0.3);
    cy: calc(3.53% + var(--blazor-load-percentage, 0%) * 0.1412);
    transition:
        cx var(--mh-duration-fast) linear,
        cy var(--mh-duration-fast) linear;
}

.mh-loader__spark-glow {
    fill: url(#mh-loader-spark-gradient);
    r: 13px;
    animation: mh-loader-flicker 0.35s var(--mh-ease-in-out) infinite alternate;
}

.mh-loader__spark-stop-core {
    stop-color: var(--mh-color-loader-spark-core);
}

.mh-loader__spark-stop-mid {
    stop-color: var(--mh-color-loader-spark);
}

.mh-loader__spark-stop-edge {
    stop-color: var(--mh-color-loader-glow);
    stop-opacity: 0;
}

.mh-loader__ember {
    fill: var(--mh-color-loader-spark);
    r: 1.4px;
    animation: mh-loader-ember 0.7s ease-out infinite;
}

.mh-loader__ember--a { cx: calc(91.5% - var(--blazor-load-percentage, 0%) * 0.3); cy: calc(0.5% + var(--blazor-load-percentage, 0%) * 0.1412); }
.mh-loader__ember--b { cx: calc(86% - var(--blazor-load-percentage, 0%) * 0.3); cy: calc(1.5% + var(--blazor-load-percentage, 0%) * 0.1412); animation-delay: 0.2s; }
.mh-loader__ember--c { cx: calc(92% - var(--blazor-load-percentage, 0%) * 0.3); cy: calc(7% + var(--blazor-load-percentage, 0%) * 0.1412); animation-delay: 0.45s; }

.mh-loader__bomb-group {
    transform-box: view-box;
    transform-origin: 44% 45%;
    animation: mh-loader-bob 2.4s var(--mh-ease-in-out) infinite;
}

.mh-loader__tile-hidden {
    fill: var(--mh-color-tile-hidden);
    stroke: var(--mh-color-tile-hidden-edge);
    stroke-width: 1;
}

.mh-loader__tile-revealed {
    fill: var(--mh-color-tile-revealed);
    stroke: var(--mh-color-tile-revealed-edge);
    stroke-width: 1;
}

.mh-loader__tile-flag {
    fill: var(--mh-color-accent);
}

.mh-loader__tile-pole {
    stroke: var(--mh-color-tile-glyph-outline);
    stroke-width: 1.2;
}

.mh-loader__tile-number {
    font-family: var(--mh-font-family-sans);
    font-size: 10px;
    font-weight: var(--mh-font-weight-bold);
    text-anchor: middle;
}

.mh-loader__tile-number--1 { fill: var(--mh-color-number-1); }
.mh-loader__tile-number--2 { fill: var(--mh-color-number-2); }
.mh-loader__tile-number--3 { fill: var(--mh-color-number-3); }

/* Tiles span x=16.5 (8.25%) to x=183.5 (91.75%): the reveal mask grows across 83.5% of the width */
.mh-loader__tiles-mask-rect {
    fill: var(--mh-white);
    height: 100%;
    width: calc(var(--blazor-load-percentage, 0%) * 0.835);
    x: 8.25%;
    y: 0;
    transition: width var(--mh-duration-fast) linear;
}

.mh-loader__title {
    margin: 0;
    color: var(--mh-color-on-page);
    font-size: var(--mh-font-size-2xl);
    font-weight: var(--mh-font-weight-bold);
    letter-spacing: var(--mh-letter-spacing-caps);
}

.mh-loader__progress {
    display: flex;
    align-items: baseline;
    gap: var(--mh-space-2);
    margin: 0;
    color: var(--mh-color-on-page-muted);
    font-size: var(--mh-font-size-md);
}

.mh-loader__percent {
    min-inline-size: 4ch;
    color: var(--mh-color-on-page-strong);
    font-family: var(--mh-font-family-mono);
    font-size: var(--mh-font-size-lg);
    font-weight: var(--mh-font-weight-bold);
    text-align: start;
}

.mh-loader__percent::after {
    content: var(--blazor-load-percentage-text, "0%");
}

@keyframes mh-loader-flicker {
    from {
        opacity: 0.75;
        r: 10px;
    }
    to {
        opacity: 1;
        r: 14px;
    }
}

@keyframes mh-loader-ember {
    0% {
        opacity: 1;
        transform: translate(0, 0);
    }
    100% {
        opacity: 0;
        transform: translate(3px, -6px);
    }
}

@keyframes mh-loader-bob {
    0%,
    100% {
        transform: translateY(0) rotate(0deg);
    }
    50% {
        transform: translateY(-3px) rotate(-2deg);
    }
}
