/* Gem Garden — the game front. Self-contained styling that reuses the shared
   design tokens (tokens.css) so the disguise sits on the same visual system as
   the rest of the site without pulling in any messaging CSS. */

.gg {
    /* A self-contained dark-purple theme: overriding the shared colour tokens on
       this root recolours the whole game (card, HUD, board track, buttons, text)
       without touching the rest of the site. The gems use their own vivid oklch
       hues, so they pop against the dark board. */
    --bg: #150826;
    --surface: #251047;
    --ink: #f3edff;
    --muted: #a493c4;
    --muted-strong: #d4c8ef;
    --hairline: rgba(255, 255, 255, 0.1);
    --segment-track: #1c0d38;
    --shadow-card: 0 16px 54px rgba(0, 0, 0, 0.55);
    --danger-text: #ff8080;

    min-height: 100dvh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: max(14px, 2.5vh) 14px;
    background: var(--bg);
    color: var(--ink);
    font-family: var(--font-sans);
}

/* The card (and thus the square board inside it) grows to the largest size that
   fits the display: full width on a phone, height-bounded on a wide screen, with
   a sane ceiling on huge monitors. */
.gg-card {
    width: min(94vw, 82vh, 820px);
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
    padding: clamp(14px, 2.4vw, 22px);
    display: flex;
    flex-direction: column;
    gap: clamp(12px, 2vh, 18px);
}

.gg-title {
    margin: 0;
    text-align: center;
    font-family: var(--font-serif);
    font-size: var(--fs-app-title);
    font-weight: 600;
    letter-spacing: 0.2px;
}

/* --- Inputs & buttons (shared: level-code dialog, game over) --- */

.gg-input {
    width: 100%;
    box-sizing: border-box;
    padding: 12px 14px;
    font-size: var(--fs-editor);
    font-family: var(--font-sans);
    color: var(--ink);
    background: var(--bg);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-input);
}

.gg-input:focus {
    outline: none;
    border-color: var(--accent);
}

.gg-error {
    margin: 0;
    font-size: 15px;
    color: var(--danger-text);
}

.gg-btn {
    padding: 12px 16px;
    font-size: var(--fs-editor);
    font-family: var(--font-sans);
    font-weight: 600;
    border: none;
    border-radius: var(--radius-input);
    cursor: pointer;
}

.gg-btn--primary {
    background: var(--accent);
    color: var(--accent-contrast);
}

.gg-btn--primary:disabled {
    opacity: 0.6;
    cursor: default;
}

/* --- Play + board --- */

.gg-play {
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.gg-hud {
    display: flex;
    justify-content: space-between;
    align-items: center;
    font-size: var(--fs-label);
    color: var(--muted-strong);
    font-variant-numeric: tabular-nums;
}

.gg-hud__stat {
    font-weight: 600;
    flex: 1 1 0;
}

.gg-hud__stat:last-child {
    text-align: right;
}

/* The centre column stacks the running total over the combo badge; a fixed
   min-height reserves the badge's row so the score never shifts as it appears. */
.gg-hud__center {
    display: flex;
    flex-direction: column;
    align-items: center;
    flex: 0 0 auto;
}

.gg-hud__score {
    font-family: var(--font-serif);
    font-size: 26px;
    font-weight: 600;
    line-height: 1.1;
    color: var(--ink);
}

/* --- Countdown bar --- */

.gg-timerbar {
    height: 6px;
    border-radius: 999px;
    background: var(--segment-track);
    overflow: hidden;
}

.gg-timerbar__fill {
    height: 100%;
    border-radius: 999px;
    background: var(--accent);
    /* Eases the width change so the drain looks continuous between frames. */
    transition: width 120ms linear, background-color 300ms ease;
}

.gg-timerbar__fill--low {
    background: var(--danger-text);
}

/* The combo tag pulses beneath the score while a cascade is running; its slot is
   always reserved (min-height) so the score above it never shifts. */
.gg-hud__combo {
    min-height: 1.1em;
    font-size: var(--fs-label);
    font-weight: 700;
    color: var(--accent);
    font-variant-numeric: tabular-nums;
    animation: gg-combo 220ms ease;
}

.gg-hud__combo--off {
    animation: none;
}

@keyframes gg-combo {
    from {
        transform: scale(0.6);
        opacity: 0;
    }

    60% {
        transform: scale(1.15);
        opacity: 1;
    }

    to {
        transform: scale(1);
    }
}

/* The board is a square, positioned stage; gems are placed on it by percentage
   so a change of slot animates as a slide (see .gg-gem). overflow:hidden clips
   fresh gems as they drop in from just above the top edge. */
.gg-board {
    position: relative;
    width: 100%;
    aspect-ratio: 1 / 1;
    background: var(--segment-track);
    border-radius: var(--radius-image);
    overflow: hidden;
    /* Own the touch gesture: without this the browser treats a drag as a scroll
       and never delivers the pointermove stream. user-select keeps a drag from
       selecting the page. */
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
}

/* A gem cell: a full-slot, transparent click target. Its position is set inline
   (left/top); a slot change transitions as a fall, weighted to accelerate like
   gravity. transform/opacity carry the select and pop states; a freshly minted
   node plays gg-enter, dropping in from above. */
.gg-gem {
    position: absolute;
    cursor: pointer;
    /* All pieces share one rounded-square silhouette; kinds are told apart by hue. */
    --gem-shape: inset(6% round 30%);
    transition:
        top 250ms cubic-bezier(0.35, 0, 0.7, 1),
        left 170ms ease,
        transform 130ms ease,
        opacity 170ms ease;
    animation: gg-enter 300ms cubic-bezier(0.35, 0, 0.7, 1);
    /* No will-change: promoting all 64 gems to their own compositor layer costs
       more than it saves and, during a big clear (many gems animating at once),
       can make the board flash black on mobile GPUs. */
}

/* The visible token, inset from the slot to leave a gap between pieces. The
   shared rounded-square clip-path (--gem-shape) gives every piece the same
   silhouette; the ::before is a soft top-lit fill (a flat matte token, not a cut
   jewel), the ::after adds a gentle top sheen. Both are clipped to that shape. */
.gg-gem::before,
.gg-gem::after {
    content: "";
    position: absolute;
    inset: 8%;
    clip-path: var(--gem-shape);
    pointer-events: none;
}

.gg-gem::before {
    /* A per-kind engraved glyph (colour-blind aid) over the soft top-lit fill, so
       pieces are told apart by mark as well as hue. */
    background:
        var(--gem-glyph, none) center / 60% no-repeat,
        radial-gradient(72% 62% at 50% 26%, var(--gem-hi) 0%, var(--gem) 54%, var(--gem-lo) 100%);
}

.gg-gem::after {
    background: radial-gradient(46% 26% at 50% 15%, rgba(255, 255, 255, 0.55), rgba(255, 255, 255, 0) 70%);
}

.gg-gem--sel {
    /* Picked-up gem: shrink a touch, brighten, glow, and sit above its rank. */
    transform: scale(0.86);
    filter: brightness(1.18) drop-shadow(0 0 3px rgba(0, 0, 0, 0.4));
    z-index: 2;
}

.gg-gem--pop {
    /* Matched gem detonating: a hard white flash then it shatters IN PLACE —
       spinning and dissolving into blur without growing past its own cell, so a
       big clear reads as many small explosions, not gems ballooning over the
       board. Sits above neighbours. */
    z-index: 3;
    animation: gg-pop 200ms ease-out forwards;
}

@keyframes gg-pop {
    0% {
        transform: scale(1) rotate(0);
        filter: brightness(1);
        opacity: 1;
    }

    22% {
        transform: scale(1.04);
        filter: brightness(3.2) saturate(1.8);
        opacity: 1;
    }

    100% {
        transform: scale(0.35) rotate(24deg);
        filter: brightness(2) blur(2px);
        opacity: 0;
    }
}

/* --- Bonus pieces --- */

/* A Line piece (4-match): bright diagonal stripes over the gem, with a white
   glow so it reads as "charged". ::after (normally the sheen) becomes the
   stripes, still clipped to the gem's silhouette. */
.gg-gem--line {
    filter: brightness(1.12) drop-shadow(0 0 5px rgba(255, 255, 255, 0.95));
}

.gg-gem--line::after {
    /* Thin white pin-stripes (with a fine dark edge) over mostly-open gaps, so the
       gem's own colour stays the dominant read while it's clearly marked. */
    background: repeating-linear-gradient(
        -45deg,
        rgba(255, 255, 255, 0.95) 0,
        rgba(255, 255, 255, 0.95) 2px,
        rgba(0, 0, 0, 0.3) 2px,
        rgba(0, 0, 0, 0.3) 3px,
        rgba(255, 255, 255, 0) 3px,
        rgba(255, 255, 255, 0) 11px
    );
}

/* A Bomb piece (5+-match): a small bright core + halo and a strong glow, kept
   small so most of the gem shows its colour. */
.gg-gem--bomb {
    filter: brightness(1.12) drop-shadow(0 0 6px rgba(255, 255, 255, 0.95));
}

.gg-gem--bomb::after {
    background: radial-gradient(
        circle at 50% 45%,
        #ffffff 0,
        #ffffff 11%,
        rgba(255, 255, 255, 0.45) 17%,
        rgba(255, 255, 255, 0) 30%
    );
}

/* Fresh gems start just above the board's top edge regardless of which row they
   land in: the start offset lifts them by (row + 1.3) cell-heights, so every new
   gem in a column begins above the top and falls the full distance to its slot —
   a pour, not a pop. --row defaults to 0 for the opening board fill. */
@keyframes gg-enter {
    from {
        transform: translateY(calc(-100% * (var(--row, 0) + 1.3)));
        opacity: 0;
    }

    55% {
        opacity: 1;
    }

    to {
        transform: translateY(0);
        opacity: 1;
    }
}

/* Five pieces, one rounded-square silhouette (set on .gg-gem), told apart by hue
   AND an engraved glyph (colour-blind aid): green ● disc, purple ▲ triangle,
   yellow ◆ diamond, red ○ ring, blue ▬ bar. Each carries a hue triad (highlight /
   body / shadow). */
.gem-0 {
    --gem: oklch(0.64 0.15 152);
    --gem-hi: oklch(0.8 0.14 158);
    --gem-lo: oklch(0.5 0.13 146);
    --gem-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='8' fill='black' opacity='.72'/%3E%3C/svg%3E");
}

.gem-1 {
    --gem: oklch(0.7 0.14 305);
    --gem-hi: oklch(0.84 0.1 308);
    --gem-lo: oklch(0.56 0.15 300);
    --gem-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3.5 L20.5 19 L3.5 19 Z' fill='black' opacity='.72'/%3E%3C/svg%3E");
}

.gem-2 {
    --gem: oklch(0.83 0.15 98);
    --gem-hi: oklch(0.93 0.1 105);
    --gem-lo: oklch(0.7 0.15 92);
    --gem-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 3 L21 12 L12 21 L3 12 Z' fill='black' opacity='.72'/%3E%3C/svg%3E");
}

.gem-3 {
    --gem: oklch(0.6 0.21 22);
    --gem-hi: oklch(0.78 0.16 28);
    --gem-lo: oklch(0.45 0.17 18);
    --gem-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Ccircle cx='12' cy='12' r='8' fill='none' stroke='black' stroke-width='3.4' opacity='.75'/%3E%3C/svg%3E");
}

.gem-4 {
    --gem: oklch(0.6 0.16 262);
    --gem-hi: oklch(0.76 0.13 268);
    --gem-lo: oklch(0.46 0.15 258);
    --gem-glyph: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Crect x='2.5' y='9' width='19' height='6' rx='3' fill='black' opacity='.72'/%3E%3C/svg%3E");
}

/* --- Game over --- */

.gg-over {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    padding: 12px 0;
}

.gg-over__title {
    margin: 0;
    font-size: var(--fs-label);
    letter-spacing: var(--ls-section);
    text-transform: uppercase;
    color: var(--muted);
}

.gg-over__score {
    margin: 0;
    font-family: var(--font-serif);
    font-size: 44px;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

/* --- Level-code dialog (disguised login) --- */

/* A full-viewport scrim + centred card. It renders inside .gg, so it inherits
   the game's dark-purple token overrides. */
.gg-modal__scrim {
    position: fixed;
    inset: 0;
    z-index: 10;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
    background: rgba(0, 0, 0, 0.6);
}

.gg-modal {
    position: relative;
    box-sizing: border-box;
    width: min(92vw, 340px);
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding: 24px 22px 22px;
    background: var(--surface);
    border: 1px solid var(--hairline);
    border-radius: var(--radius-card);
    box-shadow: var(--shadow-card);
}

.gg-modal__x {
    position: absolute;
    top: 8px;
    right: 10px;
    width: 32px;
    height: 32px;
    padding: 0;
    font-size: 22px;
    line-height: 1;
    color: var(--muted-strong);
    background: transparent;
    border: none;
    border-radius: var(--radius-input);
    cursor: pointer;
}

.gg-modal__x:hover {
    color: var(--ink);
}

.gg-modal__label {
    margin: 0;
    font-size: 18px;
    color: var(--muted-strong);
}
