game/2d/ui/gridpanel.razor.scss
root {
    width: 100%;
    height: 100%;
    position: absolute;
}

.outer {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;  
    background-color: #0d0820;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-right: 0px;
    pointer-events: none;
    transition: background-color 2s ease;
    overflow: hidden;
}

.grid-wrap {
    display: flex;
    flex-direction: column;
    gap: 6px;
    pointer-events: none;
    position: relative;  /* ← sits above particles */
    z-index: 2;
}
.grid-row {
    display: flex;
    flex-direction: row;
    gap: 6px;
    pointer-events: none;
}

.cell {
    width: 100px; height: 100px;
    border-radius: 14px;
    border: 2px solid rgba(255,255,255,0.07);
    background-color: rgba(255,255,255,0.03);
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    position: relative;
    pointer-events: all;
    transition: transform 0.1s, background-color 0.15s, border-color 0.15s;
}
.cell:hover {
    background-color: rgba(167,139,250,0.08);
    transform: scale(1.05);
}

/* Bomb chest */

.cell.chest {
    background-color: rgba(114,126,143,0.10);
    border-color: rgba(148,163,184,0.45);
}

.cell.bomb {
    background-color: rgba(109,40,217,0.32);
    border-color: rgba(167,139,250,0.75);
}

.cell.bomb:hover {
    background-color: rgba(109,40,217,0.48);
}

/* Chest cell */
.cell.chest-spawn {
    background-color: rgba(114,126,143,0.10);
    border-color: rgba(148,163,184,0.45);
    animation: chest-spawn 0.45s cubic-bezier(0.22,1,0.36,1) both;
}

/* Danger column — chest one step from game over */
.cell.danger-col {
    border-color: rgba(251,191,36,0.35);
    animation: danger-col-pulse 0.8s ease-in-out infinite alternate;
}

.cell.chest.danger {
    border-color: rgba(251,191,36,0.80);
    background-color: rgba(251,191,36,0.12);
    animation: danger-col-pulse 0.8s ease-in-out infinite alternate;
}

@keyframes danger-col-pulse {
    0%   { border-color: rgba(251,191,36,0.30); box-shadow: none; }
    100% { border-color: rgba(251,191,36,0.90); box-shadow: 0 0 8px rgba(251,191,36,0.25); }
}

/* Chest spawn animations */

@keyframes chest-spawn {
    0%   { opacity: 0; transform: scale(0.5) translateY(-8px); }
    60%  { opacity: 1; transform: scale(1.08) translateY(0px); }
    80%  { transform: scale(0.96); }
    100% { opacity: 1; transform: scale(1.0); }
}

@keyframes chest-spawn-gem {
    0%   { opacity: 0; transform: scale(0.4) translateY(-10px); }
    50%  { opacity: 1; transform: scale(1.15) translateY(0px); }
    75%  { transform: scale(0.94); }
    100% { opacity: 1; transform: scale(1.0); }
}

@keyframes chest-spawn-boss {
    0%   { opacity: 0; transform: scale(0.3) rotate(-5deg); }
    50%  { opacity: 1; transform: scale(1.20) rotate(2deg); }
    75%  { transform: scale(0.95) rotate(-1deg); }
    100% { opacity: 1; transform: scale(1.0) rotate(0deg); }
}

/* Destroyed chest — scorched dark remains */
.cell.cell-scorched {
    background-color: rgba(100, 11, 11, 0.589);
    border-color: rgba(163, 163, 163, 0.801);
    opacity: 0.55;
    transition: background-color 0.3s ease, opacity 0.3s ease;
}

/* Fired bomb cell — slightly darkened blast mark */
.cell.cell-fired {
    background-color: rgba(100, 11, 11, 0.589);
    border-color: rgba(255, 255, 255, 0.616);
    opacity: 0.45;
    transition: background-color 0.3s ease, opacity 0.3s ease;
}

/* Secret Chest cell */

.cell.secret {
    background-color: rgba(244,114,182,0.12);
    border-color: rgba(244,114,182,0.55);
    animation: secret-pulse 2s ease-in-out infinite;
}

@keyframes secret-pulse {
    0%   { border-color: rgba(244,114,182,0.40); }
    50%  { border-color: rgba(244,114,182,0.85); }
    100% { border-color: rgba(244,114,182,0.40); }
}

.cell.empty:hover {
    background-color: rgba(255,255,255,0.07);
}

.cell.pblast.p0 { border-color: rgba(96,165,250,0.65);  background-color: rgba(59,130,246,0.12); }
.cell.pblast.p1 { border-color: rgba(52,211,153,0.65);  background-color: rgba(16,185,129,0.12); }
.cell.pblast.p2 { border-color: rgba(251,146,60,0.65);  background-color: rgba(234,88,12,0.12); }

.cell.phit.p0 { border-color: rgba(96,165,250,0.95);  background-color: rgba(59,130,246,0.25); }
.cell.phit.p1 { border-color: rgba(52,211,153,0.95);  background-color: rgba(16,185,129,0.25); }
.cell.phit.p2 { border-color: rgba(251,146,60,0.95);  background-color: rgba(234,88,12,0.25); }

.cell.phit-survive {
    border-color: rgba(251,191,36,0.90);
    background-color: rgba(251,191,36,0.22);
}

.cell.pdestroy {
    border-color: rgba(248,113,113,0.95);
    background-color: rgba(239,68,68,0.28);
}

/* ── Preview hit — will destroy ── */
.cell.chest.pdestroy,
.cell.locked.pdestroy,
.cell.cursed.pdestroy,
.cell.void.pdestroy,
.cell.secret.pdestroy,
.cell.boss.pdestroy  {
    border-color: rgba(248,113,113,0.95);
    background-color: rgba(239,68,68,0.28);
}

/* ── Preview hit — will survive (not enough hits) ── */
.cell.chest.phit-survive,
.cell.locked.phit-survive,
.cell.cursed.phit-survive,
.cell.void.phit-survive,
.cell.secret.phit-survive,
.cell.boss.phit-survive {
    border-color: rgba(251,191,36,0.90);
    background-color: rgba(251,191,36,0.22);
}

.cell.pchain {
    border-color: rgba(196,181,253,0.65);
    background-color: rgba(139,92,246,0.15);
}

/* Hover preview highlight on chests */
@keyframes phit-hover-pulse {
    0%   { border-color: rgba(248,113,113,0.40); background-color: rgba(239,68,68,0.08); }
    100% { border-color: rgba(248,113,113,0.80); background-color: rgba(239,68,68,0.20); }
}

/* ── Hover preview highlight — all chest types ── */
.cell.chest.phit-hover,
.cell.locked.phit-hover,
.cell.cursed.phit-hover,
.cell.void.phit-hover,
.cell.secret.phit-hover,
.cell.boss.phit-hover {
    border-color: rgba(248,113,113,0.70);
    background-color: rgba(239,68,68,0.14);
    animation: phit-hover-pulse 0.3s ease-in-out infinite alternate;
}

/* Hover origin cell */
/* ── Hover preview highlight — all chest types ── */
.cell.cell-hover-origin.p0 { background-color: rgba(59,130,246,0.25);  border-color: rgba(96,165,250,0.80);  border-width: 2px; }
.cell.cell-hover-origin.p1 { background-color: rgba(16,185,129,0.25);  border-color: rgba(52,211,153,0.80);  border-width: 2px; }
.cell.cell-hover-origin.p2 { background-color: rgba(234,88,12,0.25);   border-color: rgba(251,146,60,0.80);  border-width: 2px; }

/* pointer-events none on cell children to prevent hover flicker */
.icon {
    font-size: 48px;
    pointer-events: none;
    background-color: transparent;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
    height: 100%;
}
.badge {
    position: absolute; top: 4px; right: 6px;
    font-size: 14px; font-weight: 700;
    color: rgba(80,220,140,0.95);
    background-color: rgba(29,158,117,0.35);
    border-radius: 4px; padding: 0 4px;
    pointer-events: none;
}
.hits {
    position: absolute; bottom: 10px; right: 6px;
    font-size: 15px; font-weight: 700;
    color: rgba(251,191,36,0.9);
    pointer-events: none;
}
.cell-flash {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    border-radius: 12px;
    pointer-events: none;
    z-index: 3;
}

.cell-flash.flash-direct       { animation: flash-origin-direct 0.6s ease-out forwards; }
.cell-flash.flash-chain        { animation: flash-origin-chain  0.6s ease-out forwards; }
.cell-flash.flash-blast-direct { animation: flash-blast-direct  0.5s ease-out forwards; }
.cell-flash.flash-blast-chain  { animation: flash-blast-chain   0.5s ease-out forwards; }

@keyframes flash-origin-direct {
    0%   { background-color: rgba(251,191,36,0.9);  border: 3px solid #fbbf24; transform: scale(1.12); }
    40%  { background-color: rgba(251,191,36,0.5);  transform: scale(1.04); }
    100% { background-color: transparent; border-color: transparent; transform: scale(1.0); }
}
@keyframes flash-origin-chain {
    0%   { background-color: rgba(196,181,253,0.9); border: 3px solid #c4b5fd; transform: scale(1.12); }
    40%  { background-color: rgba(196,181,253,0.5); transform: scale(1.04); }
    100% { background-color: transparent; border-color: transparent; transform: scale(1.0); }
}
@keyframes flash-blast-direct {
    0%   { background-color: rgba(251,191,36,0.3); border: 1px solid rgba(251,191,36,0.5); }
    100% { background-color: transparent; border-color: transparent; }
}
@keyframes flash-blast-chain {
    0%   { background-color: rgba(196,181,253,0.3); border: 1px solid rgba(196,181,253,0.5); }
    100% { background-color: transparent; border-color: transparent; }
}

@keyframes cell-appear {
    0%   { opacity: 0; transform: scale(0.85); }
    100% { opacity: 1; transform: scale(1.0); }
}

/* CHEST ICONS */

/* normal chest */
.cell-chest-sprite {
    position: relative;
    width: 128px;
    height: 128px;
    image-rendering: pixelated;
    pointer-events: none;
    margin-left: -16px;
}

.chest-boss {
    width: 140px;
    height: 140px;
    margin-left: -21.5px;
    margin-bottom: 15px;
}

/* when mystery wave */
.cell-mystery-icon {
    font-size: 32px;
    pointer-events: none;
}
.cell.mystery {
    background-color: rgba(20, 10, 40, 0.95);
    border-color: rgba(167, 139, 250, 0.3);
}
/* ------------------ */

.chest-secret {
    width: 140px;
    height: 140px;
    margin-left: -21.5px;
    margin-bottom: 2px;
}

.chest-gem {
    width: 140px;
    height: 140px;
}

/* Background Particles in game*/
.grid-particles {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    pointer-events: none;
    overflow: hidden;
    z-index: 0;  /* ← behind grid */
}

.grid-particle {
    position: absolute;
    bottom: -10px;
    opacity: 0;
    animation-name: grid-particle-rise;
    animation-timing-function: ease-in;
    animation-iteration-count: infinite;
}

@keyframes grid-particle-rise {
    0%   { opacity: 0;   transform: translateY(0px); }
    15%  { opacity: 1; }
    80%  { opacity: 0.8; transform: translateY(-60vh); }
    100% { opacity: 0;   transform: translateY(-100vh); }
}

.cell.boss {
    position: relative;
    overflow: visible;
    background-color: rgba(251,191,36,0.25);
    border-color: rgba(251,191,36,0.80);
    border-width: 3px;
   //animation: boss-pulse 1.2s ease-in-out infinite alternate; /* ← add this back */
}

/* Boss chest cell */
.cell.boss.chest-spawn {
    position: relative;
    overflow: visible;
    background-color: rgba(251,191,36,0.25);
    border-color: rgba(251,191,36,0.80);
    border-width: 3px;
    animation: boss-spawn-enter 0.5s cubic-bezier(0.22,1,0.36,1) both,
               boss-pulse 1.2s ease-in-out 0.5s infinite alternate;
}

@keyframes boss-spawn-enter {
    0%   { opacity: 0; transform: scale(0.3) rotate(-5deg); background-color: rgba(251,191,36,0.05); }
    60%  { opacity: 1; transform: scale(1.15) rotate(2deg); }
    100% { opacity: 1; transform: scale(1.0) rotate(0deg); }
}

/* HP bar sits at bottom of cell */
.boss-hp-bar {
    position: absolute;
    bottom: 8px; 
    left: 8px;
    right: 8px;
    height: 5px;
    background-color: rgba(255,255,255,0.10);
    border-radius: 3px;
    overflow: hidden;
}

.boss-hp-fill {
    height: 100%;
    border-radius: 3px;
    transition: width 0.3s ease, background-color 0.4s ease;
    background-color: rgba(52,211,153,0.90); /* green at full */
}

.boss-suppress-icon {
    position: absolute;
    top: 4px;
    left: 16px;
    font-size: 24px;
    pointer-events: none;
    opacity: 0.80;
    line-height: 10;
    background-color: transparent; 
}

/* These get applied via inline style instead — easier to drive from C# */


/* ---------------------- SCREEN SHAKE ----------------------- */
/* Add these: */
.grid-shake-wrap {
    position: absolute;
    top: 0; left: 0; right: 0; bottom: 0;
    pointer-events: none;
    background-color: transparent;
}

.grid-shake-wrap.shake-small  { animation: shake-small  0.25s ease-out; }
.grid-shake-wrap.shake-medium { animation: shake-medium 0.35s ease-out; }
.grid-shake-wrap.shake-strong { animation: shake-strong 0.45s ease-out; }
.grid-shake-wrap.shake-insane { animation: shake-insane 0.55s ease-out; }

@keyframes shake-small {
    0%,100% { transform: translate(0,0); }
    25%     { transform: translate(-2px, 1px); }
    50%     { transform: translate(2px, -1px); }
    75%     { transform: translate(-1px, 2px); }
}
@keyframes shake-medium {
    0%,100% { transform: translate(0,0); }
    20%     { transform: translate(-4px, 2px) rotate(-0.3deg); }
    40%     { transform: translate(4px,-3px) rotate(0.3deg); }
    60%     { transform: translate(-3px, 3px) rotate(-0.2deg); }
    80%     { transform: translate(3px,-2px) rotate(0.2deg); }
}
@keyframes shake-strong {
    0%,100% { transform: translate(0,0); }
    15%     { transform: translate(-6px, 3px) rotate(-0.5deg); }
    30%     { transform: translate(6px,-4px) rotate(0.5deg); }
    45%     { transform: translate(-5px, 5px) rotate(-0.4deg); }
    60%     { transform: translate(5px,-4px) rotate(0.4deg); }
    75%     { transform: translate(-3px, 2px); }
    90%     { transform: translate(2px,-2px); }
}
@keyframes shake-insane {
    0%,100% { transform: translate(0,0); }
    10%     { transform: translate(-9px, 5px) rotate(-0.7deg); }
    20%     { transform: translate(9px,-6px) rotate(0.7deg); }
    30%     { transform: translate(-8px, 7px) rotate(-0.6deg); }
    40%     { transform: translate(8px,-6px) rotate(0.6deg); }
    50%     { transform: translate(-6px, 5px) rotate(-0.4deg); }
    60%     { transform: translate(6px,-5px) rotate(0.4deg); }
    70%     { transform: translate(-4px, 3px); }
    80%     { transform: translate(3px,-3px); }
    90%     { transform: translate(-1px, 1px); }
}

/* ---------------- SCREEN SHAKE ------------------- */
.mini-hand.shake-small  { animation: shake-small  0.25s ease-out; }
.mini-hand.shake-medium { animation: shake-medium 0.35s ease-out; }
.mini-hand.shake-strong { animation: shake-strong 0.45s ease-out; }
.mini-hand.shake-insane { animation: shake-insane 0.55s ease-out; }

/* ---------------- TUTORIAL FOR BOMB PLACEMENT STEP 3 (turn cell targeted red if it doesn't blast a bomb ------------------- */
.cell.tut-invalid {
    opacity: 0.35;
    cursor: not-allowed;
}

.cell.tut-invalid:hover {
    background-color: rgba(255,0,0,0.08);
    border-color: rgba(255,0,0,0.20);
    transform: none;  /* no scale on invalid */
}


/* ---------------------------------------------------------------------------------- */
/* -------------------------------- REVEAL CONSUMABLE ------------------------------- */
/* ---------------------------------------------------------------------------------- */

/* Reveal ghost cells — shows next wave chest positions */
.cell.cell-reveal {
    background-color: rgba(251,191,36,0.15);
    border-color: rgba(251,191,36,0.50);
    animation: reveal-pulse 0.8s ease-in-out infinite alternate;
}

.cell.cell-reveal-gem {
    background-color: rgba(52,211,153,0.15);
    border-color: rgba(52,211,153,0.50);
    animation: reveal-pulse 0.8s ease-in-out infinite alternate;
}

.cell.cell-reveal-bomb {
    background-color: rgba(167,139,250,0.15);
    border-color: rgba(167,139,250,0.50);
    animation: reveal-pulse 0.8s ease-in-out infinite alternate;
}

@keyframes reveal-pulse {
    0%   { opacity: 0.4; }
    100% { opacity: 1.0; }
}

/* ---------------------------------------------------------------------------------- */
/* ------------------------------------- OTHER CHESTS ------------------------------- */
/* ---------------------------------------------------------------------------------- */

/* ── Locked chest — steel grey, heavy feel ── */
.cell.locked {
    background-color: rgba(148,163,184,0.25);
    border-color: rgba(148,163,184,0.60);
}

/* ── Cursed chest — blood red ── */
.cell.cursed {
    background-color: rgba(185,28,28,0.25);
    border-color: rgba(239,68,68,0.60);
    animation: cursed-pulse 1.5s ease-in-out infinite alternate;
}

@keyframes cursed-pulse {
    0%   { border-color: rgba(239,68,68,0.40); }
    100% { border-color: rgba(239,68,68,0.90); }
}

/* ── Void chest — deep dark purple ── */
.cell.void {
    background-color: rgba(88,28,135,0.35);
    border-color: rgba(139,92,246,0.70);
    animation: void-pulse 2s ease-in-out infinite alternate;
}

@keyframes void-pulse {
    0%   { background-color: rgba(88,28,135,0.20); }
    100% { background-color: rgba(88,28,135,0.50); }
}

/* Reveal is for when we use a reveal consumable to reveal futur chests positions on next wave */
.cell.cell-reveal-locked {
    background-color: rgba(148,163,184,0.12);
    border-color: rgba(148,163,184,0.40);
    animation: reveal-pulse 0.8s ease-in-out infinite alternate;
}

.cell.cell-reveal-cursed {
    background-color: rgba(185,28,28,0.12);
    border-color: rgba(239,68,68,0.40);
    animation: reveal-pulse 0.8s ease-in-out infinite alternate;
}

.cell.cell-reveal-void {
    background-color: rgba(88,28,135,0.15);
    border-color: rgba(139,92,246,0.40);
    animation: reveal-pulse 0.8s ease-in-out infinite alternate;
}