/* =====================================================================
   NineGames — Portal Stylesheet
   Design system derived from G9 (SKIN_DEFAULT).
   Structure: 1) Tokens  2) Reset  3) Base  4) Layout  5) Components
   ===================================================================== */

/* ---------- 1) DESIGN TOKENS ---------------------------------------- */
:root {
    /* Colors */
    --color-bg:             #020617;
    --color-surface:        rgba(15, 23, 42, 0.80);
    --color-surface-hover:  rgba(30, 41, 59, 0.90);
    --color-surface-muted:  rgba(15, 23, 42, 0.40);

    --color-primary:        #3b82f6;
    --color-primary-glow:   rgba(59, 130, 246, 0.45);

    --color-text:           #ffffff;
    --color-text-secondary: #94a3b8;
    --color-text-muted:     #64748b;

    --color-border:         #475569;
    --color-border-subtle:  #1e293b;

    /* Grid cell colors (l→r, top→bottom) — functional identity, fixed across skins */
    --g1: #f43f5e;  --g2: #ec4899;  --g3: #d946ef;
    --g4: #a855f7;  --g5: #6366f1;  --g6: #3b82f6;
    --g7: #06b6d4;  --g8: #10b981;  --g9: #14b8a6;

    /* Grid cell shape — fixed across skins so the 9 buttons never change form */
    --cell-radius: clamp(6px, 2vw, 14px);
    --grid-gap:    clamp(0.5rem, 2.5vw, 1rem);

    /* Typography */
    --font-display:  'Rajdhani', system-ui, sans-serif;
    --font-headline: 'Space Grotesk', var(--font-display);

    /* Fluid spacing */
    --space-page: clamp(1rem, 4vmin, 2rem);
}

/* ---------- 2) RESET ------------------------------------------------ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }

img, svg { display: block; max-width: 100%; }

/* ---------- 3) BASE ------------------------------------------------- */
html { -webkit-text-size-adjust: 100%; }

body {
    height: 100vh;   /* fallback: browsers without dvh (e.g. iOS < 15.4) */
    height: 100dvh;  /* dynamic viewport: accounts for mobile address bar */
    overflow: hidden;
    background: var(--color-bg);
    color: var(--color-text);
    font-family: var(--font-display);
    -webkit-font-smoothing: antialiased;
    /* Notch / safe-area aware for app mode */
    padding:
        env(safe-area-inset-top)
        env(safe-area-inset-right)
        env(safe-area-inset-bottom)
        env(safe-area-inset-left);
}

/* App shell: fills the viewport exactly, no scrolling */
.app {
    height: 100%;
    display: flex;
    flex-direction: column;
}

:focus-visible {
    outline: 2px solid var(--color-primary);
    outline-offset: 3px;
}

@media (prefers-reduced-motion: reduce) {
    * { transition: none !important; animation: none !important; }
}

/* ---------- 4) LAYOUT ----------------------------------------------- */
.site-main {
    flex: 1 1 auto;
    min-height: 0;
    width: 100%;
    max-width: 920px;
    margin-inline: auto;
    padding: clamp(1.5rem, 7vw, 3rem) clamp(1.75rem, 9vw, 3rem);
    display: flex;
    align-items: center;
    justify-content: center;
    overflow: hidden;
}

/* The grid stage is the single fixed anchor: the 3×3 grid sits here at a
   constant size/position in EVERY view. Everything else (NINE/GAMES, a
   sub-menu heading, the back button) is positioned absolutely above/below
   so it can never shift the grid when navigating. */
.grid-stage {
    --logo-w: min(74vw, 56vh, 340px);
    --stage-gap: clamp(0.8rem, 3.5vh, 2rem);
    position: relative;
    width: var(--logo-w);
}

.stage-top {
    position: absolute;
    bottom: 100%;
    left: 0;
    width: 100%;
    margin-bottom: var(--stage-gap);
}
.stage-bottom {
    position: absolute;
    top: 100%;
    left: 0;
    width: 100%;
    margin-top: var(--stage-gap);
}

/* Letters spread to the full logo width, matching the grid below/above */
.brand-text {
    display: flex;
    justify-content: space-between;
    width: var(--logo-w);
    font-family: var(--font-headline);
    font-weight: 900;
    color: var(--color-text);
}
.brand-text--nine  { font-size: clamp(1.5rem, 8vw, 3rem); }
.brand-text--games { font-size: clamp(1.2rem, 6.5vw, 2.4rem); }


/* ---------- 5) COMPONENTS ------------------------------------------- */

/* 5.1 Brand grid — the 9 squares double as the game buttons.
   Shares --logo-w with the NINE/GAMES text rows so both line up
   edge-to-edge, while still scaling independently from text size —
   that's what lets the whole stack fill a tall phone screen instead
   of being locked to a square aspect ratio. */
.cell-grid {
    width: var(--logo-w);
    aspect-ratio: 1;
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    grid-template-rows: repeat(3, 1fr);
    gap: var(--grid-gap);
}

.cell {
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--cell-radius);
    transition: opacity 0.18s ease, filter 0.18s ease, transform 0.18s ease;
}

/* Cells that are <button> need the chrome stripped to match <a>/<span> cells */
button.cell {
    border: none;
    appearance: none;
    -webkit-appearance: none;
    font: inherit;
    color: inherit;
}

[data-view="home"] .cell:nth-child(1) { background: var(--g1); }
[data-view="home"] .cell:nth-child(2) { background: var(--g2); }
[data-view="home"] .cell:nth-child(3) { background: var(--g3); }
[data-view="home"] .cell:nth-child(4) { background: var(--g4); }
[data-view="home"] .cell:nth-child(5) { background: var(--g5); }
[data-view="home"] .cell:nth-child(6) { background: var(--g6); }
[data-view="home"] .cell:nth-child(7) { background: var(--g7); }
[data-view="home"] .cell:nth-child(8) { background: var(--g8); }
[data-view="home"] .cell:nth-child(9) { background: var(--g9); }

.cell svg {
    width: 52% !important;
    height: 52% !important;
    color: rgba(255, 255, 255, 0.85);
    stroke: rgba(255, 255, 255, 0.85);
    display: block;
    flex-shrink: 0;
}

/* Soon: desaturated, inert, decorative only */
.cell--soon {
    opacity: 0.22;
    filter: grayscale(60%);
}

/* Active: full color, real link, interactive */
.cell--active {
    cursor: pointer;
    outline-offset: 4px;
}
.cell--active:hover,
.cell--active:focus-visible {
    filter: brightness(1.2);
    transform: scale(1.06);
}

/* Game cells keep their identity color (Rosé/Pink/Magenta); the logo is a
   transparent mark sitting directly on the colored tile (tuned for contrast). */
.cell-logo {
    width: 100%;
    height: 100%;
    display: block;
    pointer-events: none;
}

/* Toggle cell (heart / skin switch) — reset button chrome, make it clearly tappable */
.cell--toggle {
    cursor: pointer;
    border: none;
    appearance: none;
    -webkit-appearance: none;
    opacity: 0.5;
    filter: grayscale(30%);
    transition: opacity 0.18s ease, filter 0.18s ease, transform 0.18s ease;
}
.cell--toggle:hover,
.cell--toggle:focus-visible { opacity: 1; filter: none; transform: scale(1.06); }
.cell--toggle[aria-pressed="true"] { opacity: 1; filter: none; }

/* 5.2 Views — the grid layout is reused for every sub-menu */
.view { width: 100%; display: flex; justify-content: center; }
.view[hidden] { display: none; }

/* 5.3 Leaderboard — same 3×3 grid, cells re-assigned. The single heading is
   the ONLY text outside the grid; each cell carries its own timeframe label,
   its game identity comes from the row color. */
.lb-heading {
    font-family: var(--font-headline);
    font-weight: 900;
    font-size: clamp(1.5rem, 8vw, 3rem);
    text-align: center;
    color: var(--color-text);
}

/* Leaderboard cells reuse .cell geometry; here only the label + row color. */
.lb-cell {
    cursor: pointer;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: clamp(0.72rem, 3.4vw, 1.05rem);
    color: rgba(255, 255, 255, 0.92);
    transition: filter 0.18s ease, transform 0.18s ease;
}
.lb-cell:hover,
.lb-cell:focus-visible { filter: brightness(1.12); transform: scale(1.06); }

.lb-cell--gravity { background: var(--g1); }
.lb-cell--merge   { background: var(--g2); }
.lb-cell--deflect { background: var(--g3); }

/* Back button — uniform across sub-menus, slightly smaller than a cell,
   centered under the middle column. Absolute, so it never shifts the grid. */
.back-btn {
    left: 50%;
    width: calc(var(--logo-w) / 4);
    aspect-ratio: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    border: 0.5px solid var(--color-border);
    appearance: none;
    -webkit-appearance: none;
    border-radius: var(--cell-radius);
    background: var(--color-surface);
    color: var(--color-text);
    cursor: pointer;
    transform: translateX(-50%);
    transition: transform 0.18s ease, background 0.18s ease;
}
.back-btn:hover,
.back-btn:focus-visible { background: var(--color-surface-hover); transform: translateX(-50%) scale(1.06); }
.back-btn svg { width: 44%; height: 44%; }

/* 5.4 Ranking list — a thin colored frame at exactly grid size, holding a
   simple positions list. --frame-color is set per game on the list view. */
.lb-frame {
    width: 100%;
    aspect-ratio: 1;
    border: 1.5px solid var(--frame-color, var(--color-border));
    border-radius: var(--cell-radius);
    padding: clamp(0.5rem, 2.5vw, 0.9rem);
    display: flex;
    flex-direction: column;
    overflow: hidden;
}

.rank-list {
    list-style: none;
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
}

.rank-row,
.rank-self {
    display: grid;
    grid-template-columns: 2.2em 1fr auto;
    align-items: center;
    gap: 0.6em;
    padding: 0.34em 0.2em;
    font-family: var(--font-display);
    font-size: clamp(0.78rem, 3.4vw, 1rem);
    color: var(--color-text);
}
.rank-row + .rank-row { border-top: 0.5px solid var(--color-border-subtle); }

.rank-pos   { color: var(--color-text-secondary); font-weight: 700; text-align: right; }
.rank-name  { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rank-score { font-weight: 700; font-variant-numeric: tabular-nums; }

/* Own row — always visible, pinned below the list, set off by the frame color */
.rank-self {
    margin-top: 0.4em;
    border-top: 1.5px solid var(--frame-color, var(--color-border));
    font-weight: 700;
}
.rank-self .rank-pos { color: var(--color-text); }

/* ---------- 6) SKINS ------------------------------------------------ */
/* A skin is just a re-themed token set toggled on <body>. Components read
   tokens only, so they restyle automatically. The 9 grid colors stay fixed
   (brand identity) — a skin changes only everything *around* them.
   Games are never affected by portal skins. */

/* Support skin — "Vapor" (80s vaporwave) */
.skin-vapor {
    --color-bg:             #0c1f24;
    --color-surface:        rgba(15, 50, 50, 0.80);
    --color-primary:        #2fd4d0;
    --color-primary-glow:   rgba(47, 212, 208, 0.50);
    --color-text:           #ecfeff;
    --color-text-secondary: #99f6e4;

    /* NB: the 9 grid colors (--g1..--g9) are intentionally NOT overridden here.
       They are functional identity tokens — each cell's color themes its target
       sub-menu — and must stay distinct & recognizable across every skin. */

    /* Deep petrol gradient + soft cyan horizon glow */
    background:
        radial-gradient(125% 75% at 50% 118%, #2fd4d0 0%, rgba(47, 212, 208, 0) 46%),
        linear-gradient(180deg, #081519 0%, #0c2f30 55%, #134e4a 100%) fixed;
}

/* Neon brand glow, gently pulsing (the "animation" token of the package) */
.skin-vapor .brand-text {
    color: var(--color-text);
    animation: vaporPulse 3.5s ease-in-out infinite;
}

@keyframes vaporPulse {
    0%, 100% { text-shadow: 0 0 8px var(--color-primary-glow), 0 0 22px var(--color-primary-glow); }
    50%      { text-shadow: 0 0 14px var(--color-primary-glow), 0 0 34px var(--color-primary); }
}

/* Grid form stays fixed across skins (see --cell-radius); only add a hover glow */
.skin-vapor .cell--active:hover {
    box-shadow: 0 0 16px var(--color-primary-glow);
}
