/* ---------------------------------------------------------------------------
   Spacetime V2
   A single stylesheet: layout, board, overlays and leaderboards.
   Tiles are painted from the data-tile attribute so the markup stays boring.
   --------------------------------------------------------------------------- */

:root
{
    --bg: #05070d;
    --panel: rgba(6, 18, 14, 0.72);
    --panel-solid: #0a1511;
    --ink: #d9ffe6;
    --dim: #8aa79a;
    --green: #4dff9f;
    --green-soft: rgba(77, 255, 159, 0.16);
    --red: #ff5a6e;
    --gold: #ffd166;
    --silver: #c7d2d0;
    --bronze: #d6a06a;
    --line: rgba(77, 255, 159, 0.2);
    --line-strong: rgba(77, 255, 159, 0.34);
    --radius: 16px;
    --shadow: 0 18px 45px rgba(0, 0, 0, 0.55);
    /* Mina stays for the display type; body copy switches to a cleaner sans so
       the HUD, tables and dialogs read better at small sizes. */
    --font: "Mina", "Segoe UI", system-ui, -apple-system, sans-serif;
    --font-body: "Segoe UI", system-ui, -apple-system, sans-serif;
    /* One fade-out-and-in of the ship on a purple teleport; matches
       TELEPORT_BLINK_MS in assets/js/game.js. */
    --teleport-blink: 500ms;
}

*,
*::before,
*::after
{
    box-sizing: border-box;
}

html
{
    color-scheme: dark;
}

body
{
    margin: 0;
    min-height: 100vh;
    color: var(--ink);
    font-family: var(--font-body);
    line-height: 1.5;
    background-color: var(--bg);
    /* index.php sets --page-background to a random file from
       assets/img/backgrounds/. The gradients sit on top of the photo so the
       page reads as one dark, vignetted backdrop rather than a flat image. */
    background-image:
        radial-gradient(1100px 560px at 50% -8%, rgba(77, 255, 159, 0.12), transparent 60%),
        radial-gradient(820px 480px at 88% 108%, rgba(77, 255, 159, 0.08), transparent 55%),
        linear-gradient(180deg, rgba(5, 7, 13, 0.24) 0%, rgba(5, 7, 13, 0.42) 55%, rgba(5, 7, 13, 0.72) 100%),
        var(--page-background, url("../img/backgrounds/space16.jpg"));
    background-size: cover;
    background-attachment: fixed;
    background-position: center top;
}

a
{
    color: var(--green);
}

:focus-visible
{
    outline: 2px solid var(--green);
    outline-offset: 2px;
}

kbd
{
    display: inline-block;
    padding: 0 0.35em;
    border: 1px solid var(--line);
    border-bottom-width: 2px;
    border-radius: 5px;
    background: rgba(0, 0, 0, 0.45);
    font-family: inherit;
    font-size: 0.85em;
}

.skip-link
{
    position: absolute;
    left: -9999px;
    top: 0;
    padding: 0.6rem 1rem;
    background: var(--green);
    color: #04120b;
    z-index: 50;
}

.skip-link:focus
{
    left: 0.5rem;
    top: 0.5rem;
}

.page
{
    width: min(1120px, 94vw);
    margin: 0 auto;
    padding-bottom: 3rem;
}

/* The page header is now the shared JAWNLogic navigation bar (nav/navbar.php). */

/* --- layout -------------------------------------------------------------- */

.layout
{
    display: grid;
    grid-template-columns: minmax(0, 1fr) 348px;
    gap: 2.2rem;
    align-items: start;
    padding-top: 2rem;
}

.stage
{
    min-width: 0;
}

.stage__heading
{
    text-align: center;
    padding: 0.25rem 0 0.35rem;
}

.stage h1
{
    margin: 0;
    font-family: var(--font);
    font-size: clamp(1.6rem, 4.5vw, 2.7rem);
    font-weight: 700;
    letter-spacing: 0.16em;
    color: #fff;
    text-shadow:
        0 0 12px rgba(77, 255, 159, 0.5),
        0 0 34px rgba(77, 255, 159, 0.26),
        0 0 70px rgba(77, 255, 159, 0.14);
}

.stage__version
{
    font-size: 0.45em;
    letter-spacing: 0.08em;
    color: var(--green);
    vertical-align: super;
}

.stage__tagline
{
    margin: 0.35rem 0 0;
    color: var(--dim);
    font-size: 0.95rem;
    letter-spacing: 0.04em;
}

/* A short gradient rule under the title keeps the header from floating; the
   boards and panels below share the same green accent. */
.stage__heading::after
{
    content: "";
    display: block;
    width: 72px;
    height: 2px;
    margin: 0.85rem auto 0;
    border-radius: 2px;
    background: linear-gradient(90deg, transparent, var(--green), transparent);
}

.stage__hint
{
    width: fit-content;
    margin: 1rem auto 0;
    padding: 0.55rem 1.1rem;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: rgba(4, 10, 8, 0.45);
    color: var(--ink);
    font-size: 0.85rem;
    text-align: center;
}

/* Shown only when a returning, signed-in player skips the start screen: the
   board is live but the countdown is waiting for the first move. */
.hint-line
{
    margin: 0.75rem 0 0;
    text-align: center;
    color: var(--gold);
    font-size: 0.78rem;
}

.stage__notice
{
    text-align: center;
}

.link-button
{
    padding: 0;
    border: 0;
    background: none;
    color: var(--green);
    font: inherit;
    text-decoration: underline;
    cursor: pointer;
}

.notice
{
    display: flex;
    flex-direction: column;
    gap: 0.15rem;
    margin: 0 auto 1.1rem;
    max-width: 560px;
    padding: 0.75rem 1rem;
    border: 1px solid rgba(255, 209, 102, 0.4);
    border-left: 3px solid var(--gold);
    border-radius: 12px;
    background: rgba(60, 45, 0, 0.28);
    color: #ffe6ae;
    font-size: 0.85rem;
}

.notice--error
{
    border-color: rgba(255, 90, 110, 0.5);
    background: rgba(60, 0, 10, 0.35);
    color: #ffb3bd;
}

/* --- level manager (levels.php) ------------------------------------------ */

.manager
{
    display: grid;
    gap: 1rem;
    max-width: 920px;
    margin: 0 auto;
    padding: 1.2rem 1rem 2rem;
}

.manager .notice
{
    margin: 0;
    max-width: none;
}

.manager__hint
{
    margin: 0 0 0.9rem;
    color: var(--dim);
    font-size: 0.82rem;
}

.manager__table th,
.manager__table td
{
    padding: 0.35rem 0.55rem;
    text-align: left;
    white-space: nowrap;
}

.manager__actions
{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
}

.manager__actions form
{
    margin: 0;
}

.notice strong
{
    color: var(--gold);
}

.notice span
{
    display: block;
}

/* --- HUD ----------------------------------------------------------------- */

.hud
{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 0.5rem;
    margin: 0 auto 1.1rem;
    padding: 0.55rem 0.7rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: rgba(4, 10, 8, 0.5);
    backdrop-filter: blur(8px);
    box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.04);
}

.hud__chip
{
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.3rem 0.8rem;
    border: 1px solid rgba(77, 255, 159, 0.16);
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.35);
    font-size: 0.72rem;
    letter-spacing: 0.07em;
    text-transform: uppercase;
    color: var(--dim);
}

.hud__chip strong
{
    color: #fff;
    font-size: 1.05rem;
    letter-spacing: 0;
    line-height: 1;
    font-variant-numeric: tabular-nums;
}

.hud__chip strong.is-low
{
    color: var(--red);
    text-shadow: 0 0 10px rgba(255, 90, 110, 0.55);
}

/* display: flex on the chip would otherwise override the [hidden] attribute. */
.hud__chip[hidden]
{
    display: none;
}

.hud__heart
{
    color: var(--red);
    font-size: 0.95rem;
    line-height: 1;
}

.hud__star
{
    color: var(--gold);
    font-size: 0.9rem;
    line-height: 1;
}

.hud__of
{
    color: var(--dim);
    font-size: 0.72rem;
}

.hud__name
{
    display: flex;
    align-items: center;
    gap: 0.35rem;
    max-width: 12rem;
    padding: 0.3rem 0.8rem;
    border: 1px solid rgba(77, 255, 159, 0.26);
    border-radius: 999px;
    background: var(--green-soft);
    color: var(--green);
    font-size: 0.8rem;
}

/* The name itself truncates; the verified check must stay whole. */
.hud__name > span:first-child
{
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.hud__verified
{
    display: inline-flex;
    flex: none;
    align-items: center;
    justify-content: center;
    width: 1rem;
    height: 1rem;
    border-radius: 50%;
    background: var(--green);
    color: var(--bg);
    font-size: 0.7rem;
    line-height: 1;
}

/* --- board --------------------------------------------------------------- */

.board-frame
{
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: min(92vw, 470px);
    aspect-ratio: 1;
    margin: 0 auto;
}

.board
{
    display: grid;
    /* Board.fitToTiles() replaces the track counts inline and sets --cols /
       --rows, which size the board below; these are the pre-load fallbacks. */
    grid-template-columns: repeat(15, 1fr);
    grid-template-rows: repeat(15, 1fr);
    /* A narrow block gets a narrow board, which keeps the cells square. */
    width: min(100%, calc(100% * var(--cols, 15) / var(--rows, 15)));
    aspect-ratio: var(--cols, 15) / var(--rows, 15);
    gap: 2px;
    padding: 9px;
    border: 1px solid rgba(77, 255, 159, 0.16);
    border-radius: var(--radius);
    background: rgba(0, 0, 0, 0.5);
    box-shadow: var(--shadow), inset 0 0 40px rgba(0, 0, 0, 0.6);
    touch-action: none;
    user-select: none;
}

.cell
{
    position: relative;
    border-radius: 3px;
    background-color: rgba(255, 255, 255, 0.03);
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
    transition: background-color 120ms ease;
}

/* Outside the level's block of tiles there is nothing to draw: those cells are
   empty space, not part of the map. They stay in the DOM (and in the cells map)
   so coordinates and the rules are unchanged. */
.cell.is-outside
{
    display: none;
}

.cell[data-tile="b"]
{
    background-image: url("../img/blue3.png");
}

.cell[data-tile="g"]
{
    background-image: url("../img/green3.png");
}

.cell[data-tile="c"]
{
    background-image: url("../img/cyan3.png");
}

.cell[data-tile="r"]
{
    background-image: url("../img/red3.png");
}

.cell[data-tile="d"]
{
    background-image: url("../img/darkRed3.png");
}

.cell[data-tile="p"]
{
    background-image: url("../img/purple3.png");
}

.cell[data-tile="o"]
{
    background-image: url("../img/orange3.png");
}

.cell[data-tile="y"]
{
    background-image: url("../img/yellow3.png");
}

.cell[data-tile="u"]
{
    background-image: url("../img/yellowOutline3.png");
}

/* Ice: translucent, so the board shows through. The cracked version also has a
   crack overlay; both are pass-through and never stop a move. */
.cell[data-tile="i"]
{
    background-image: url("../img/ice.svg");
}

.cell[data-tile="s"]
{
    background-image: url("../img/iceCracked.svg");
}

.cell[data-tile="i"],
.cell[data-tile="s"]
{
    box-shadow: inset 0 0 0 1px rgba(190, 235, 255, 0.22);
}

.cell .token
{
    position: absolute;
    inset: 1px;
    display: none;
    background-image: url("../img/spaceship.png");
    background-position: center;
    background-repeat: no-repeat;
    background-size: contain;
    filter: drop-shadow(0 0 4px rgba(77, 255, 159, 0.85));
    animation: token-pop 160ms ease-out;
}

.cell.has-token .token
{
    display: block;
}

/* A slide is walked cell by cell (see SLIDE_MS_PER_CELL in game.js). Each hop
   is short, so the pop is trimmed to match, and the ship glows while it
   travels so the trip across the ice reads as one movement. */
.board.is-sliding .cell .token
{
    filter: drop-shadow(0 0 8px rgba(77, 255, 159, 1));
    animation-duration: 70ms;
}

/* Purple teleport: the ship fades out and in three times where it stands and
   twice where it lands (see teleport() in game.js). The period here and
   TELEPORT_BLINK_MS there have to match, so the fade always finishes on a
   fully visible frame. */
.cell .token.is-blinking
{
    animation: token-blink var(--teleport-blink) ease-in-out infinite;
}

.cell.is-life
{
    box-shadow: inset 0 0 0 2px #fff, 0 0 12px rgba(255, 255, 255, 0.75);
    animation: life-pulse 900ms ease-in-out infinite;
}

.cell.is-start::after
{
    content: "X";
    position: absolute;
    inset: 0;
    display: grid;
    place-items: center;
    color: #fff;
    font-size: clamp(0.5rem, 1.6vw, 0.85rem);
    font-weight: 700;
    text-shadow: 0 0 6px #000;
}

.cell.is-teleporting
{
    animation: teleport 260ms ease-out;
}

/* The legacy editTable.png was drawn for the old table's 3px spacing and cannot
   align with this grid. The per-cell outlines below are the editor lines. */
.board.is-editing
{
    background-color: rgba(0, 0, 0, 0.62);
}

.board.is-editing .cell
{
    cursor: crosshair;
    outline: 1px dashed rgba(255, 255, 255, 0.28);
    outline-offset: -1px;
}

.edit-overlay
{
    position: absolute;
    top: 0.6rem;
    left: 0.8rem;
    z-index: 3;
    padding: 0.2rem 0.55rem;
    border-radius: 999px;
    background: rgba(0, 0, 0, 0.75);
    color: var(--gold);
    font-size: 0.72rem;
    pointer-events: none;
}

/* --- overlays ------------------------------------------------------------ */

.overlay
{
    position: absolute;
    inset: 0;
    z-index: 5;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 0.55rem;
    padding: 1.4rem;
    overflow-y: auto;
    border-radius: var(--radius);
    background: rgba(2, 8, 6, 0.88);
    backdrop-filter: blur(3px);
    text-align: center;
}

.overlay[hidden]
{
    display: none;
}

.overlay__title
{
    margin: 0;
    font-family: var(--font);
    font-size: clamp(1.2rem, 4vw, 1.7rem);
    letter-spacing: 0.12em;
    color: #fff;
    text-shadow: 0 0 14px rgba(77, 255, 159, 0.6);
}

.overlay__title--danger
{
    color: #ffd7dc;
    text-shadow: 0 0 16px rgba(255, 90, 110, 0.75);
}

.overlay__text
{
    max-width: 26ch;
    margin: 0;
    color: var(--dim);
    font-size: 0.88rem;
}

/* Small credit line on the level-complete card. */
.overlay__credit
{
    margin: 0;
    color: var(--dim);
    font-size: 0.72rem;
    opacity: 0.75;
}

.overlay__big
{
    margin: 0;
    color: var(--green);
    font-size: 2rem;
    font-weight: 700;
}

.overlay__warning
{
    min-height: 1.2rem;
    margin: 0;
    color: var(--red);
    font-size: 0.78rem;
}

.overlay__form
{
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5rem;
    width: 100%;
}

.field
{
    display: flex;
    flex-direction: column;
    gap: 0.25rem;
    width: min(240px, 100%);
    text-align: left;
    font-size: 0.78rem;
    color: var(--dim);
}

.field input
{
    padding: 0.45rem 0.6rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.45);
    color: var(--ink);
    font: inherit;
}

/* A name that Authelia filled in cannot be edited; the chip next to the label
   says why. */
.field__label
{
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.4rem;
}

.field input[readonly]
{
    border-color: rgba(77, 255, 159, 0.4);
    background: rgba(77, 255, 159, 0.08);
    color: var(--green);
    cursor: default;
}

.verified
{
    display: inline-flex;
    align-items: center;
    gap: 0.25rem;
    padding: 0.05rem 0.45rem;
    border: 1px solid rgba(77, 255, 159, 0.4);
    border-radius: 999px;
    background: var(--green-soft);
    color: var(--green);
    font-size: 0.65rem;
    letter-spacing: 0.08em;
    line-height: 1.5;
    text-transform: uppercase;
}

.verified__check
{
    font-size: 0.8rem;
    line-height: 1;
}

/* The check on a leaderboard row: the run was saved while signed in, so the
   name is the verified username. */
.leaderboard__verified
{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 0.9rem;
    height: 0.9rem;
    margin-left: 0.3rem;
    border-radius: 50%;
    background: var(--green);
    color: var(--bg);
    font-size: 0.62rem;
    line-height: 1;
    vertical-align: middle;
}

.form-status
{
    min-height: 1.1rem;
    margin: 0;
    color: var(--gold);
    font-size: 0.75rem;
}

/* --- buttons ------------------------------------------------------------- */

.button
{
    padding: 0.5rem 1.1rem;
    border: 1px solid transparent;
    border-radius: 999px;
    font: inherit;
    font-size: 0.9rem;
    letter-spacing: 0.04em;
    cursor: pointer;
    transition: transform 120ms ease, background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}

.button:hover
{
    transform: translateY(-1px);
}

.button:active
{
    transform: translateY(0);
}

.button:focus-visible
{
    outline: none;
    box-shadow: 0 0 0 3px rgba(77, 255, 159, 0.35);
}

.button--primary
{
    background: linear-gradient(180deg, #63ffb1, #2fd27f);
    color: #032013;
    font-weight: 700;
    box-shadow: 0 6px 18px rgba(47, 210, 127, 0.28);
}

.button--primary:hover
{
    box-shadow: 0 8px 22px rgba(47, 210, 127, 0.4);
}

.button--ghost
{
    border-color: var(--line);
    background: rgba(0, 0, 0, 0.35);
    color: var(--ink);
}

.button--ghost:hover
{
    border-color: var(--line-strong);
    background: rgba(77, 255, 159, 0.08);
}

.button--small
{
    padding: 0.25rem 0.7rem;
    font-size: 0.78rem;
}

/* --- side panels --------------------------------------------------------- */

.side
{
    display: flex;
    flex-direction: column;
    gap: 1.15rem;
}

.panel
{
    padding: 1rem 1.05rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--panel);
    backdrop-filter: blur(8px);
    box-shadow: var(--shadow);
}

.panel__title
{
    display: flex;
    align-items: center;
    gap: 0.5rem;
    margin: 0 0 0.65rem;
    color: var(--green);
    font-family: var(--font);
    font-size: 0.82rem;
    font-weight: 700;
    letter-spacing: 0.16em;
    text-transform: uppercase;
}

/* A small accent tick in front of each panel title ties the two columns
   together with the rest of the page's green highlights. */
.panel__title::before
{
    content: "";
    flex: none;
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--green);
    box-shadow: 0 0 8px rgba(77, 255, 159, 0.7);
}

.panel__scroll
{
    max-height: 380px;
    overflow-y: auto;
    scrollbar-color: rgba(77, 255, 159, 0.35) transparent;
    scrollbar-width: thin;
}

.table
{
    width: 100%;
    border-collapse: collapse;
    font-size: 0.82rem;
}

.table th
{
    padding: 0.3rem 0.35rem;
    color: var(--dim);
    font-size: 0.68rem;
    font-weight: 400;
    letter-spacing: 0.1em;
    text-align: left;
    text-transform: uppercase;
}

/* The header stays visible while the column scrolls (scoreboard and levels). */
.table thead th
{
    position: sticky;
    top: 0;
    z-index: 1;
    background: var(--panel-solid);
}

.table td
{
    padding: 0.36rem 0.35rem;
    border-top: 1px solid rgba(77, 255, 159, 0.08);
}

.table tbody tr:hover td
{
    background: rgba(77, 255, 159, 0.07);
}

.table tbody tr:nth-child(odd) td
{
    background: rgba(77, 255, 159, 0.04);
}

/* The leaderboard podium reads gold, silver and bronze without extra markup.
   Scoped to #scoreboard so the level manager's own tables stay neutral. */
#scoreboard tbody tr:nth-child(1) td
{
    background: rgba(255, 209, 102, 0.08);
}

#scoreboard tbody tr:nth-child(2) td
{
    background: rgba(199, 210, 208, 0.06);
}

#scoreboard tbody tr:nth-child(3) td
{
    background: rgba(214, 160, 106, 0.07);
}

.table td:first-child
{
    width: 2rem;
    color: var(--dim);
    font-variant-numeric: tabular-nums;
}

.table td:nth-child(2)
{
    max-width: 8rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.table td:last-child,
.table th:last-child
{
    text-align: right;
}

.table__empty
{
    margin: 0.4rem 0;
    color: var(--dim);
    font-size: 0.8rem;
    text-align: center;
}

.timeboards
{
    display: flex;
    flex-direction: column;
    gap: 0.8rem;
}

.timeboard__title
{
    margin: 0 0 0.35rem;
    color: var(--dim);
    font-family: var(--font);
    font-size: 0.72rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.timeboard__list
{
    margin: 0;
    padding: 0;
    list-style: none;
    font-size: 0.82rem;
}

.timeboard__row
{
    display: grid;
    grid-template-columns: 1.7rem minmax(0, 1fr) auto;
    gap: 0.45rem;
    align-items: center;
    padding: 0.24rem 0.1rem;
    border-top: 1px solid rgba(77, 255, 159, 0.08);
}

.timeboard__row:hover
{
    background: rgba(77, 255, 159, 0.06);
}

.timeboard__row:first-child
{
    border-top: 0;
}

.timeboard__rank
{
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 1.5rem;
    height: 1.5rem;
    padding: 0 0.3rem;
    border-radius: 7px;
    background: rgba(255, 255, 255, 0.05);
    color: var(--dim);
    font-size: 0.72rem;
    font-variant-numeric: tabular-nums;
}

/* Gold, silver and bronze medals for the fastest three runs. */
.timeboard__list li:nth-child(1) .timeboard__rank
{
    background: rgba(255, 209, 102, 0.14);
    color: var(--gold);
}

.timeboard__list li:nth-child(2) .timeboard__rank
{
    background: rgba(199, 210, 208, 0.12);
    color: var(--silver);
}

.timeboard__list li:nth-child(3) .timeboard__rank
{
    background: rgba(214, 160, 106, 0.14);
    color: var(--bronze);
}

.timeboard__name
{
    display: flex;
    align-items: center;
    min-width: 0;
    overflow: hidden;
}

/* Only the name itself truncates; the verified check stays whole. */
.timeboard__name-text
{
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.timeboard__time
{
    color: var(--green);
    font-variant-numeric: tabular-nums;
}

/* --- level editor -------------------------------------------------------- */

.creator
{
    width: min(760px, 94vw);
    margin: 2rem auto 0;
    padding: 1.15rem 1.35rem 1.4rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--panel);
    backdrop-filter: blur(8px);
    box-shadow: var(--shadow);
}

.creator[hidden]
{
    display: none;
}

.creator__head
{
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 1rem;
}

.creator__head h2
{
    margin: 0;
    color: var(--green);
    font-family: var(--font);
    font-size: 1rem;
    letter-spacing: 0.12em;
    text-transform: uppercase;
}

.creator__hint
{
    margin: 0.5rem 0 0.8rem;
    color: var(--dim);
    font-size: 0.8rem;
}

.creator__form
{
    display: flex;
    flex-wrap: wrap;
    align-items: flex-end;
    gap: 0.8rem;
    margin-top: 1rem;
}

.palette
{
    display: flex;
    flex-wrap: wrap;
    gap: 0.4rem;
}

.palette__button
{
    display: flex;
    align-items: center;
    gap: 0.4rem;
    padding: 0.3rem 0.55rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.4);
    color: var(--ink);
    font: inherit;
    font-size: 0.76rem;
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease;
}

.palette__button:hover
{
    border-color: var(--line-strong);
    background: rgba(77, 255, 159, 0.08);
}

.palette__button.is-active
{
    border-color: var(--green);
    background: var(--green-soft);
}

.swatch
{
    display: inline-block;
    width: 1.35rem;
    height: 1.35rem;
    border-radius: 3px;
    background-color: rgba(255, 255, 255, 0.05);
    background-position: center;
    background-repeat: no-repeat;
    background-size: cover;
}

.swatch[data-tile="b"]
{
    background-image: url("../img/blue3.png");
}

.swatch[data-tile="g"]
{
    background-image: url("../img/green3.png");
}

.swatch[data-tile="c"]
{
    background-image: url("../img/cyan3.png");
}

.swatch[data-tile="r"]
{
    background-image: url("../img/red3.png");
}

.swatch[data-tile="d"]
{
    background-image: url("../img/darkRed3.png");
}

.swatch[data-tile="p"]
{
    background-image: url("../img/purple3.png");
}

.swatch[data-tile="o"]
{
    background-image: url("../img/orange3.png");
}

.swatch[data-tile="y"]
{
    background-image: url("../img/yellow3.png");
}

.swatch[data-tile="u"]
{
    background-image: url("../img/yellowOutline3.png");
}

.swatch[data-tile="i"]
{
    background-image: url("../img/ice.svg");
}

.swatch[data-tile="s"]
{
    background-image: url("../img/iceCracked.svg");
}

.swatch[data-tile="X"]
{
    background: rgba(0, 0, 0, 0.6);
    color: #fff;
    font-size: 0.8rem;
    font-weight: 700;
    text-align: center;
    line-height: 1.35rem;
}

/* --- help dialog --------------------------------------------------------- */

.dialog
{
    width: min(560px, 92vw);
    padding: 1.4rem 1.5rem;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    background: var(--panel-solid);
    color: var(--ink);
    box-shadow: var(--shadow);
}

.dialog::backdrop
{
    background: rgba(0, 0, 0, 0.72);
    backdrop-filter: blur(2px);
}

.dialog__title
{
    margin: 0 0 0.7rem;
    font-family: var(--font);
    color: var(--green);
    font-size: 1.1rem;
    letter-spacing: 0.1em;
    text-transform: uppercase;
}

.rules
{
    margin: 0 0 1rem;
    padding-left: 1.1rem;
    font-size: 0.88rem;
}

.rules li + li
{
    margin-top: 0.35rem;
}

.legend
{
    width: 100%;
    margin-bottom: 1rem;
    border-collapse: collapse;
    font-size: 0.82rem;
}

.legend td
{
    padding: 0.18rem 0.3rem;
    border-top: 1px solid rgba(77, 255, 159, 0.08);
}

.legend td:first-child
{
    width: 2rem;
}

.dialog__note
{
    color: var(--dim);
    font-size: 0.8rem;
}

/* Level picker: a grid of numbers, so a jump is one click instead of a prompt. */
.level-grid
{
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(2.6rem, 1fr));
    gap: 0.4rem;
    max-height: min(50vh, 320px);
    margin: 0.9rem 0;
    padding-right: 0.2rem;
    overflow-y: auto;
}

.level-grid__button
{
    padding: 0.45rem 0.2rem;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: rgba(0, 0, 0, 0.45);
    color: var(--ink);
    font: inherit;
    font-size: 0.85rem;
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease, color 120ms ease;
}

.level-grid__button:hover,
.level-grid__button:focus-visible
{
    border-color: var(--green);
    background: var(--green-soft);
    color: var(--green);
}

.level-grid__button.is-current
{
    border-color: var(--green);
    color: var(--green);
}

/* Level tools sit under the board and only exist for the allowed groups. */
.toolbar
{
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    gap: 0.5rem;
    margin-top: 0.85rem;
}

/* --- touch controls ------------------------------------------------------ */

.mobile-pad
{
    display: none;
    grid-template-columns: repeat(3, 3.2rem);
    grid-template-rows: repeat(2, 3.2rem);
    justify-content: center;
    gap: 0.35rem;
    margin-top: 1rem;
}

.mobile-pad__key
{
    border: 1px solid var(--line);
    border-radius: 12px;
    background: rgba(0, 0, 0, 0.45);
    color: var(--ink);
    font-size: 1.2rem;
    cursor: pointer;
    touch-action: manipulation;
    transition: background-color 120ms ease, border-color 120ms ease;
}

.mobile-pad__key:hover
{
    border-color: var(--line-strong);
}

.mobile-pad__key:active
{
    background: var(--green-soft);
}

.mobile-pad__key[data-direction="up"]
{
    grid-column: 2;
    grid-row: 1;
}

.mobile-pad__key[data-direction="left"]
{
    grid-column: 1;
    grid-row: 2;
}

.mobile-pad__key[data-direction="down"]
{
    grid-column: 2;
    grid-row: 2;
}

.mobile-pad__key[data-direction="right"]
{
    grid-column: 3;
    grid-row: 2;
}

/* --- footer -------------------------------------------------------------- */

.footer
{
    margin-top: 2.75rem;
    padding-top: 1.1rem;
    border-top: 1px solid var(--line);
    color: var(--dim);
    font-size: 0.78rem;
    text-align: center;
}

.footer p
{
    margin: 0;
}

.footer a
{
    color: var(--green);
    text-decoration: none;
}

.footer a:hover
{
    text-decoration: underline;
}

/* --- animation ----------------------------------------------------------- */

@keyframes token-pop
{
    from
    {
        transform: scale(0.6);
        opacity: 0.4;
    }

    to
    {
        transform: scale(1);
        opacity: 1;
    }
}

/* One fade out and in. Applied once per cycle by teleport(), so the ship
   disappears and reappears twice before the jump and once after it. */
@keyframes token-blink
{
    0%,
    100%
    {
        opacity: 1;
    }

    50%
    {
        opacity: 0;
    }
}

@keyframes life-pulse
{
    0%,
    100%
    {
        opacity: 1;
    }

    50%
    {
        opacity: 0.55;
    }
}

@keyframes teleport
{
    from
    {
        transform: scale(0.4) rotate(-90deg);
    }

    to
    {
        transform: scale(1) rotate(0);
    }
}

/* --- responsive ---------------------------------------------------------- */

@media (max-width: 980px)
{
    .layout
    {
        grid-template-columns: minmax(0, 1fr);
    }

    .side
    {
        flex-direction: row;
        flex-wrap: wrap;
    }

    .side .panel
    {
        flex: 1 1 280px;
    }
}

@media (max-width: 620px)
{
    .page
    {
        width: 96vw;
    }

    .board-frame
    {
        width: 94vw;
    }

    .side
    {
        flex-direction: column;
    }

    .hud
    {
        gap: 0.35rem;
        padding: 0.45rem 0.5rem;
    }

    .hud__chip
    {
        padding: 0.28rem 0.6rem;
    }
}

@media (hover: none), (pointer: coarse)
{
    .mobile-pad
    {
        display: grid;
    }

    .stage__hint
    {
        display: none;
    }
}

@media (prefers-reduced-motion: reduce)
{
    *,
    *::before,
    *::after
    {
        animation-duration: 0.001ms !important;
        animation-iteration-count: 1 !important;
        transition-duration: 0.001ms !important;
    }
}
