/*
 * Companion styles for the components and effect scripts in this library.
 * Blazor CSS isolation only reaches elements a component itself renders;
 * hit-wave.js, note-hit-effect.js and combo-milestone.js all create their
 * DOM nodes directly (document.createElement/appendChild), outside any
 * component's render tree, so their styling has to live in a plain,
 * unscoped stylesheet instead of a *.razor.css file. Both apps load this
 * alongside LaneDeck/ComboDisplay/CountdownOverlay/ComboAura.
 */

.note-hit-effect {
    position: fixed;
    z-index: 100;
    pointer-events: none;
    border: 1px solid rgba(223, 250, 255, .75);
    border-radius: 5px;
    background: rgba(100, 216, 255, .55);
    box-shadow: 0 0 8px rgba(100, 216, 255, .75), 0 0 18px rgba(47, 124, 255, .35);
    animation: note-hit-burst 300ms ease-out both;
}

@keyframes note-hit-burst {
    0% { opacity: .72; transform: scale(1); }
    100% { opacity: 0; transform: scale(1.3, 1.8); }
}

/* Shared, lane-local impulses aligned to the actual judgment line by JS. */
.hit-wave {
    position: absolute;
    z-index: 8;
    left: 0;
    width: 100%;
    height: 80px;
    overflow: visible;
    pointer-events: none;
}

.hit-wave path {
    fill: none;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.hit-wave .core {
    stroke: var(--wave-stroke, #9eeeff);
    stroke-width: 2;
}

.hit-wave .halo {
    stroke: var(--wave-stroke, #72cfff);
    stroke-width: 4;
    opacity: calc(.4 + var(--wave-energy, 0) * .2);
    filter: blur(3px);
}

@media (prefers-reduced-motion: reduce) {
    .hit-wave { display: none; }
}

@media (prefers-reduced-motion: no-preference) {
    /* Preserve the original elements' geometry for note timing calculations. */
    .lane-deck:has(> .hit-wave) .hit-line { visibility: hidden; }

    /* The decorative horizon also runs beneath the lanes, where each app
       provides one. Keep its outside wings while removing the straight
       segment behind the moving baseline. */
    .playfield:has(.hit-wave) .horizon,
    .game-field:has(.hit-wave) .horizon {
        mask-image: linear-gradient(to right,
            #000 calc((100% - var(--hit-wave-width)) / 2),
            transparent calc((100% - var(--hit-wave-width)) / 2),
            transparent calc((100% + var(--hit-wave-width)) / 2),
            #000 calc((100% + var(--hit-wave-width)) / 2));
    }
}

.lane {
    overflow: hidden;
}

.lane .hit-line {
    transition: transform 150ms ease, background-color 150ms ease, box-shadow 180ms ease;
}

.lane.pressed .hit-line {
    transform: scaleY(1.25);
    background: #c9f3ff;
    box-shadow: 0 0 10px rgba(100, 216, 255, .75);
}

.judgment.show {
    animation: judgment-burst 440ms ease-out both;
}

.judgment.great strong { color: #2f7cff; }
.judgment.good strong { color: #9ebeff; }

@keyframes judgment-burst {
    0% { opacity: 0; transform: translateY(4px) scale(.98); }
    22% { opacity: .9; transform: translateY(0) scale(1.01); }
    68% { opacity: .82; transform: translateY(0) scale(1); }
    100% { opacity: 0; transform: translateY(-5px) scale(1); }
}
