/* ==========================================================================
   ASURA NEXUS — SHARED UI SYSTEM

   What this file is
   -----------------
   The design language the newest pages already speak. Groups, achievements,
   quests, friends, the dashboard and the leaderboards all reached the same
   answers — an accent-railed hero, a stat pill row, a flat dark card, a hover
   row, an uppercase micro-heading, an outline button that fills on hover — and
   then each kept a private copy of it under its own prefix: `.grp-head`,
   `.ach-hero`, `.frn-hero`, `.dash-hero`. Six names, one component.

   This file is the single copy, named `nx-`. A page that needs one of these
   uses the class; it does not redeclare it.

   Rules
   -----
   * A component used on more than one page lives HERE, never in a template.
   * A page keeps a <style> block only for what is genuinely unique to it —
     a race track, a roulette strip, a 3D viewport.
   * Loaded from base.html after Bootstrap and before the page's own <style>,
     so it beats Bootstrap and loses to a page that really needs to override.
     Nothing here uses !important; if a rule is not applying, a page is fighting
     it and that is the bug to fix.
   * nexus-theme.css is gone. Despite its "UNIFIED CSS FRAMEWORK" header it was
     linked by index.html alone and reached no page behind the login — which is
     why every feature page grew its own card. Its shared colour tokens moved
     into section 1 here; the landing page's own body and scrollbar rules moved
     into page-index.css; the rest of it was used by nothing at all.
   ========================================================================== */


/* --------------------------------------------------------------------------
   1. TOKENS
   The accent palette, previously redeclared in base.html, the Dino Lab, the
   inventory card partial and the Patreon page — four copies that had already
   begun to differ.
   -------------------------------------------------------------------------- */
:root {
    --nexus-orange: #eb6105;
    --nexus-green:  #2ecc71;
    --nexus-blue:   #2390c1;
    --nexus-teal:   #1abc9c;
    --nexus-gold:   #f1c40f;
    --nexus-red:    #e74c3c;
    --nexus-purple: #9b59b6;

    /* Surfaces and the item-card palette (section 10), previously a second
       :root block further down base.html. --card-bg is the flat panel every
       card in the app sits on. */
    --card-bg:      #1a1b1e;
    --card-orange:  #22c4ff;
    --card-gold:    #ffd700;
    --card-grey:    #6c757d;
    --card-green:   #2ecc71;
    --card-red:     #e74c3c;
    --text-muted:   #8e9297;

    /* Ink */
    --nx-ink:       #ffffff;
    --nx-ink-soft:  #d8dbde;
    --nx-ink-mute:  #9aa0a6;
    --nx-ink-faint: #8e9297;

    /* Lines and fills, as the newest pages use them. */
    --nx-line:      rgba(255, 255, 255, 0.08);
    --nx-line-soft: rgba(255, 255, 255, 0.05);
    --nx-line-hard: rgba(255, 255, 255, 0.18);
    --nx-fill:      rgba(255, 255, 255, 0.02);
    --nx-fill-hover:rgba(255, 255, 255, 0.045);
    --nx-well:      rgba(0, 0, 0, 0.30);

    --nx-radius:    12px;
    --nx-radius-sm: 8px;

    /* Every nx- component tints itself from this. A page or a wrapper sets it
       once (`.nx-scope { --nx-accent: #9b59b6 }`) and the hero rail, the active
       tab, the progress fill and the primary button all follow. */
    --nx-accent:     var(--nexus-teal);
    --nx-accent-ink: #14151a;

    /* Inherited from the retired nexus-theme.css. These were only ever defined
       there, and that file was linked by the landing page alone — so the skin
       shop's supporter badge and its modal referenced --rgb-purple and
       --border-light against nothing and silently fell back. Defining them here
       is what makes those rules resolve on every page.

       The --rgb-* set is stored as bare triplets, not hex, so a use site picks
       its own alpha with rgba(var(--rgb-x), 0.3) instead of needing a second
       variable. */
    --bg-main:       #0a0a0c;
    --bg-card:       rgba(20, 22, 25, 0.65);
    --bg-card-hover: rgba(30, 32, 36, 0.9);
    --border-light:  rgba(255, 255, 255, 0.08);
    --border-hover:  rgba(255, 255, 255, 0.2);
    --text-main:     #e0e0e0;

    --rgb-primary: 52, 152, 219;   /* #3498db blue */
    --rgb-info:    13, 202, 240;   /* #0dcaf0 cyan */
    --rgb-success: 46, 204, 113;   /* #2ecc71 green */
    --rgb-warning: 255, 193, 7;    /* #ffc107 gold */
    --rgb-danger:  231, 76, 60;    /* #e74c3c red */
    --rgb-purple:  155, 89, 182;   /* #9b59b6 purple */
    --rgb-muted:   108, 117, 125;  /* #6c757d grey */
}


/* --------------------------------------------------------------------------
   2. HERO
   The block at the top of a feature page: title, one line of explanation, and
   usually a row of stat pills. The accent rail down the left edge is what makes
   one page recognisably different from the next without inventing a new layout.
   -------------------------------------------------------------------------- */
.nx-hero {
    display: flex;
    align-items: flex-start;
    gap: 18px;
    flex-wrap: wrap;
    background: linear-gradient(135deg, rgba(255, 255, 255, 0.04), rgba(26, 27, 30, 0));
    border: 1px solid var(--nx-line);
    border-left: 3px solid var(--nx-accent);
    border-radius: 14px;
    padding: 20px 22px;
    margin-bottom: 20px;
}

.nx-hero-body { flex: 1; min-width: 260px; }
.nx-hero-side { display: flex; flex-direction: column; align-items: flex-end; gap: 10px; }

.nx-hero-title {
    font-family: 'Impact', 'Arial Black', sans-serif;
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 1.9rem;
    color: var(--nx-ink);
    margin: 0;
}

.nx-hero-sub {
    color: var(--nx-ink-mute);
    font-size: 0.88rem;
    margin: 8px 0 0;
    max-width: 70ch;
}
.nx-hero-sub strong { color: var(--nx-ink-soft); font-weight: 600; }

/* Small uppercase line above a title. */
.nx-kicker {
    display: flex;
    align-items: center;
    gap: 9px;
    margin-bottom: 10px;
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 2.4px;
    text-transform: uppercase;
    color: var(--nx-ink-faint);
}


/* --------------------------------------------------------------------------
   3. STATS
   The pill row under a hero. Two shapes: a bordered tile with a label above a
   number (.nx-stat), and a compact inline pill (.nx-pill) for counts and state.
   -------------------------------------------------------------------------- */
.nx-stats { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 18px; }

.nx-stat {
    flex: 1 1 150px;
    min-width: 140px;
    padding: 10px 14px;
    background: var(--nx-well);
    border: 1px solid rgba(255, 255, 255, 0.06);
    border-left: 3px solid var(--nx-accent);
    border-radius: var(--nx-radius-sm);
}
.nx-stat-label {
    font-size: 0.62rem;
    font-weight: 800;
    letter-spacing: 1.2px;
    text-transform: uppercase;
    color: var(--nx-ink-faint);
}
.nx-stat-value { font-size: 1.25rem; font-weight: 800; color: var(--nx-ink); line-height: 1.25; }

.nx-stat.is-green  { border-left-color: var(--nexus-green); }
.nx-stat.is-gold   { border-left-color: var(--nexus-gold); }
.nx-stat.is-blue   { border-left-color: var(--nexus-blue); }
.nx-stat.is-red    { border-left-color: var(--nexus-red); }
.nx-stat.is-purple { border-left-color: var(--nexus-purple); }

.nx-pill {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    border-radius: 50px;
    padding: 5px 12px;
    background: rgba(255, 255, 255, 0.05);
    color: var(--nx-ink-mute);
    border: 1px solid var(--nx-line);
}
.nx-pill-on      { background: rgba(46, 204, 113, 0.12); color: var(--nexus-green);  border-color: rgba(46, 204, 113, 0.35); }
.nx-pill-warn    { background: rgba(241, 196, 15, 0.12); color: var(--nexus-gold);   border-color: rgba(241, 196, 15, 0.35); }
.nx-pill-danger  { background: rgba(231, 76, 60, 0.12);  color: var(--nexus-red);    border-color: rgba(231, 76, 60, 0.35); }
.nx-pill-info    { background: rgba(35, 144, 193, 0.12); color: var(--nexus-blue);   border-color: rgba(35, 144, 193, 0.35); }
.nx-pill-special { background: rgba(155, 89, 182, 0.12); color: var(--nexus-purple); border-color: rgba(155, 89, 182, 0.35); }


/* --------------------------------------------------------------------------
   4. SECTIONS AND CARDS
   -------------------------------------------------------------------------- */

/* The uppercase micro-heading that titles a list. Its count pill sits inside. */
.nx-section {
    display: flex;
    align-items: center;
    gap: 10px;
    margin: 0 0 14px;
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    color: var(--nx-ink-faint);
}
.nx-section-count {
    background: rgba(255, 255, 255, 0.06);
    border-radius: 50px;
    padding: 2px 9px;
    font-size: 0.66rem;
    color: var(--nx-ink-mute);
}

.nx-card {
    background: var(--card-bg);
    border: 1px solid var(--nx-line);
    border-radius: var(--nx-radius);
    padding: 18px;
    margin-bottom: 16px;
}
.nx-card > h2 {
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    color: var(--nx-ink-faint);
    margin: 0 0 14px;
    display: flex;
    align-items: center;
    gap: 8px;
}

/* A row inside a card: avatar, name, meta, actions pushed to the right. The
   left rail is optional and carries state — online, pending, outgoing. */
.nx-row {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 10px 14px;
    border-radius: 9px;
    background: var(--nx-fill);
    border: 1px solid var(--nx-line-soft);
    border-left: 3px solid var(--nx-rail, transparent);
    margin-bottom: 8px;
    transition: background 0.18s ease;
}
.nx-row:hover { background: var(--nx-fill-hover); }
.nx-row:last-child { margin-bottom: 0; }

.nx-row.is-online   { --nx-rail: var(--nexus-green); }
.nx-row.is-pending  { --nx-rail: var(--nexus-gold); }
.nx-row.is-outgoing { --nx-rail: #6c757d; }
.nx-row.is-incoming { --nx-rail: var(--nexus-gold); }

.nx-row-user   { flex: 0 0 210px; min-width: 0; display: flex; align-items: center; gap: 10px; }
.nx-row-name   { color: var(--nx-ink); text-decoration: none; font-size: 0.9rem; font-weight: 600; }
.nx-row-name:hover { color: var(--nx-accent); }
.nx-row-meta   { flex: 1; min-width: 150px; font-size: 0.8rem; color: var(--nx-ink-mute); }
.nx-row-actions{ display: flex; gap: 6px; flex-wrap: wrap; margin-left: auto; }

img.nx-avatar, .nx-avatar {
    width: 38px; height: 38px; border-radius: 50%; flex-shrink: 0;
    border: 2px solid rgba(255, 255, 255, 0.10);
    transition: border-color 0.18s ease;
}
.nx-row:hover .nx-avatar { border-color: var(--nx-accent); }

/* Nothing to show. Dashed, never a bare sentence — an empty list has to look
   deliberate rather than broken. */
.nx-empty {
    border: 1px dashed rgba(255, 255, 255, 0.12);
    border-radius: 10px;
    padding: 30px 22px;
    text-align: center;
    color: var(--nx-ink-faint);
    font-size: 0.86rem;
}
.nx-empty strong { color: var(--nx-ink); display: block; margin-bottom: 4px; }


/* --------------------------------------------------------------------------
   5. TABS
   -------------------------------------------------------------------------- */
.nx-tabs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 16px; }
.nx-tab {
    display: inline-flex;
    align-items: center;
    text-decoration: none;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.10);
    color: var(--nx-ink-mute);
    border-radius: var(--nx-radius-sm);
    padding: 8px 16px;
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    transition: all 0.18s ease;
}
.nx-tab:hover { color: var(--nx-ink); border-color: rgba(255, 255, 255, 0.25); }
.nx-tab.is-active {
    color: var(--nx-accent-ink);
    background: var(--nx-accent);
    border-color: transparent;
}
.nx-tab-badge {
    background: var(--nexus-red); color: #fff; border-radius: 50px;
    padding: 1px 7px; font-size: 0.62rem; margin-left: 6px;
}


/* --------------------------------------------------------------------------
   6. BUTTONS
   Outline by default, filling with its own colour on hover. The colour comes
   from `currentColor`, so a variant sets one property.
   -------------------------------------------------------------------------- */
.nx-btn {
    border: 1px solid currentColor;
    background: transparent;
    border-radius: 7px;
    font-size: 0.68rem;
    font-weight: 800;
    letter-spacing: 0.5px;
    text-transform: uppercase;
    padding: 6px 12px;
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
    text-decoration: none;
    cursor: pointer;
    transition: all 0.2s ease;
}
.nx-btn:disabled, .nx-btn.is-disabled { opacity: 0.45; cursor: not-allowed; }

/* One variant sets the outline colour; its hover fills with the same colour and
   drops to the dark ink. Spelled out per variant rather than with currentColor,
   because a filled button also has to change its text colour and currentColor
   cannot do both at once. */
.nx-btn-primary { color: var(--nx-accent); }
.nx-btn-accept  { color: var(--nexus-green); }
.nx-btn-danger  { color: var(--nexus-red); }
.nx-btn-gold    { color: var(--nexus-gold); }
.nx-btn-info    { color: var(--nexus-blue); }
.nx-btn-muted   { color: #adb5bd; }

.nx-btn-primary:not(:disabled):hover { background: var(--nx-accent);   color: var(--nx-accent-ink); border-color: transparent; }
.nx-btn-accept:not(:disabled):hover  { background: var(--nexus-green); color: var(--nx-accent-ink); border-color: transparent; }
.nx-btn-danger:not(:disabled):hover  { background: var(--nexus-red);   color: var(--nx-accent-ink); border-color: transparent; }
.nx-btn-gold:not(:disabled):hover    { background: var(--nexus-gold);  color: var(--nx-accent-ink); border-color: transparent; }
.nx-btn-info:not(:disabled):hover    { background: var(--nexus-blue);  color: var(--nx-accent-ink); border-color: transparent; }
.nx-btn-muted:not(:disabled):hover   { background: #adb5bd;            color: var(--nx-accent-ink); border-color: transparent; }

/* A filled variant that stays filled to mark an active state. */
.nx-btn-gold.is-on { background: var(--nexus-gold); color: var(--nx-accent-ink); border-color: transparent; }


/* --------------------------------------------------------------------------
   7. SELECT

   A native <select> is two separate surfaces and only one of them is really
   ours. The closed control can be styled freely, but the open list is drawn by
   the operating system: `color-scheme: dark` is what makes it render dark
   instead of the light grey Windows default, and the `option` colours are the
   fallback for a browser that ignores it. Neither can be fully designed — a
   custom-looking dropdown list means replacing the element with JS, which is
   not worth it for the handful of selects in the app.

   `color-scheme` is set on the bare element rather than on the class, because
   the point is to catch every select in the app — including the Bootstrap
   `form-select` ones the HUD, the map, the Lab and the inventory use — without
   touching thirty templates. It changes nothing about how the closed control
   looks; a select with its own background keeps it.
   -------------------------------------------------------------------------- */
select { color-scheme: dark; }
select option { background-color: #1a1b1e; color: #fff; }

/* `.rl-field select` rides along rather than getting a copy: the game lobbies
   are the one place that styles a select by position instead of by class, and
   two rules that have to agree is how the chevron ends up on top of the text. */
.nx-select,
.rl-field select {
    width: 100%;
    /* background-color and background-image separately: the shorthand would
       wipe the chevron the next time somebody sets `background`. */
    background-color: rgba(0, 0, 0, 0.35);
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5 6 6.5 11 1.5' fill='none' stroke='%238e9297' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
    background-repeat: no-repeat;
    background-position: right 11px center;
    background-size: 11px 8px;
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: var(--nx-radius-sm);
    color: var(--nx-ink);
    /* The right padding is what keeps a long option off the chevron. */
    padding: 9px 32px 9px 11px;
    font-size: 0.88rem;
    line-height: 1.3;
    cursor: pointer;
    appearance: none;
    -webkit-appearance: none;
}
.nx-select:focus,
.rl-field select:focus {
    outline: none;
    border-color: var(--nx-accent);
}
.nx-select:disabled { opacity: 0.5; cursor: not-allowed; }

/* Bootstrap draws .form-select's chevron in near-black (`stroke='%23343a40'`),
   which every one of them in this app sits on top of `bg-dark` — an arrow
   nobody can see. 5.3 exposes it as a variable, so this is a redefinition
   rather than a fight: no !important, and a future Bootstrap that renames the
   variable simply falls back to its own default. */
.form-select {
    --bs-form-select-bg-img: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='%238e9297' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3E%3C/svg%3E");
}


/* --------------------------------------------------------------------------
   8. PROGRESS
   -------------------------------------------------------------------------- */
.nx-track {
    height: 8px;
    background: rgba(0, 0, 0, 0.45);
    border-radius: 50px;
    overflow: hidden;
    border: 1px solid var(--nx-line-soft);
}
.nx-fill {
    height: 100%;
    border-radius: 50px;
    background: var(--nx-accent);
    transition: width 0.4s ease;
}


/* --------------------------------------------------------------------------
   9. STATE DOTS
   -------------------------------------------------------------------------- */
.nx-dot { width: 8px; height: 8px; border-radius: 50%; display: inline-block; margin-right: 6px; }
.nx-dot-on  { background: var(--nexus-green); box-shadow: 0 0 7px rgba(46, 204, 113, 0.8); }
.nx-dot-off { background: rgba(255, 255, 255, 0.18); }


/* ==========================================================================
   10. ITEM CARD
   The card every wall in the app is built from — skins, dinosaurs, storage,
   inventory, the marketplace. It lived inside base.html's <style> block and was
   then partially redeclared by four other templates, which is how .skin-name
   ended up with two font stacks and .price-val with two definitions.

   Moved here VERBATIM from base.html. Do not "tidy" the values: every card wall
   in the app is measured against them.
   ========================================================================== */
.skin-card {
    background-color: var(--card-bg);
    border: 2px solid rgba(255, 255, 255, 0.05);
    border-radius: 12px;
    overflow: hidden;
    position: relative;
    transition: transform 0.3s, box-shadow 0.3s, border-color 0.3s;
    height: 100%;
    display: flex;
    flex-direction: column;
}
.skin-card:hover {
    transform: translateY(-5px);
    box-shadow: 0 10px 20px rgba(0,0,0,0.3);
    border-color: rgba(255, 255, 255, 0.2);
}

/* --- RIBBONS --- */
.ribbon {
    position: absolute; top: 20px; right: -35px; width: 150px;
    text-align: center; font-weight: 800; font-size: 0.75rem;
    text-transform: uppercase; transform: rotate(45deg); z-index: 20;
    box-shadow: 0 2px 10px rgba(0,0,0,0.5); padding: 5px 0; letter-spacing: 1px;
}
.ribbon-owned { background: linear-gradient(45deg, #ffd700, #ffecb3); color: #000; text-shadow: 0 0 2px rgba(255, 255, 255, 0.5); }
.ribbon-sale { background: var(--card-red); color: #fff; }

/* --- STATUS BORDERS --- */
.status-locked { border-color: rgba(231, 76, 60, 0.3); opacity: 0.85; }
.status-owned { border-color: rgba(255, 215, 0, 0.3); }

/* --- HEADER --- */
.card-header-custom {
    display: flex; justify-content: space-between; align-items: center;
    padding: 12px 15px; background: rgba(255,255,255,0.02);
    border-bottom: 1px solid rgba(255,255,255,0.05);
}
.skin-name {
    font-family: 'Impact', 'Arial Black', sans-serif; text-transform: uppercase;
    font-size: 1.1rem; color: #fff; margin: 0; letter-spacing: 0.5px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.tier-badge {
    padding: 3px 8px; font-size: 0.65rem; font-weight: bold; text-transform: uppercase;
    transform: skewX(-15deg); border-radius: 2px; background: #333; color: #aaa;
    border: 1px solid rgba(255,255,255,0.1);
}
.tier-badge span { display: inline-block; transform: skewX(15deg); }

/* --- BODY / IMAGE --- */
.card-body-custom {
    padding: 0; flex-grow: 1; display: flex; flex-direction: column; position: relative;
}
.skin-bottom-container {
    position: relative;
    display: flex;
    flex-direction: column;
    flex-grow: 1;
}

.skin-img-wrapper {
    width: 100%; height: 240px; overflow: hidden; position: relative;
    display: flex; align-items: center; justify-content: center;
    background: radial-gradient(circle at center, rgba(255,255,255,0.05) 0%, rgba(0,0,0,0) 70%);
    background-color: var(--card-bg);
}

/* Gallery cross-fade, done in CSS alone. */
.gallery-img {
    position: absolute; top: 0; left: 0; width: 100%; height: 100%;
    object-fit: cover;

    /* Inactive state. */
    opacity: 0;
    z-index: 1;

    /* The outgoing image does not fade: it waits out the incoming one's 1.5 s
       fade (delay) and then vanishes instantly (duration 0s). That keeps it
       visible *underneath* the new one, so the crossfade never shows the
       background through both. */
    transition: opacity 0s linear 1.5s;
}

/* Active state. */
.gallery-img.active {
    opacity: 1;
    z-index: 2;

    transition: opacity 1.5s ease-in-out;
}

/* Covers a locked card. Full-bleed on purpose — the card-level overlay in the
   skin shop anchors to the bottom instead and overrides this. */
.lock-overlay {
    position: absolute; top: 0; left: 0; right: 0; bottom: 0;
    background: rgba(0,0,0,0.7); display: flex; flex-direction: column;
    align-items: center; justify-content: center; z-index: 5;
    backdrop-filter: blur(3px);
}

/* --- INFO & PRICES --- */
.skin-info { padding: 15px; }
.author-text { font-size: 0.75rem; color: #6c757d; font-family: monospace; display: flex; align-items: center; justify-content: flex-end; }
.price-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-size: 0.85rem; padding-bottom: 4px; border-bottom: 1px dashed rgba(255,255,255,0.05); }
.price-row:last-child { border-bottom: none; margin-bottom: 0; }
.price-label { color: #aaa; text-transform: uppercase; font-size: 0.7rem; font-weight: 600; letter-spacing: 0.5px; }
.price-val { color: #fff; font-weight: 700; font-family: monospace; font-size: 0.9rem;}
.price-val.discounted { color: var(--card-orange); }
.old-price { text-decoration: line-through; color: #555; font-size: 0.7rem; margin-right: 8px; }

/* --- FOOTER ---
   .card-footer-custom, .btn-give, .btn-single and .btn-reusable were dropped:
   they belonged to an earlier card footer, and every wall in the app now uses
   .card-actions with .btn-action-custom / .btn-give-style from nexus-cards.css.
   Nothing referenced them in a template, a script or a route. */
.btn-buy { flex: 8; border: 1px solid transparent; border-radius: 4px; padding: 8px 0; text-transform: uppercase; font-weight: 700; font-size: 0.75rem; transition: all 0.2s; color: white; cursor: pointer; }
.btn-disabled { opacity: 0.5; background: #222; border-color: #333; color: #555; cursor: not-allowed; }

/* --- PALETTE --- */
.skin-palette {
    position: absolute; bottom: 8px; right: 8px; display: flex; align-items: center; gap: 4px;
    background: rgba(0, 0, 0, 0.7); padding: 4px 6px; border-radius: 6px; z-index: 10;
    backdrop-filter: blur(4px); border: 1px solid rgba(255,255,255,0.1); box-shadow: 0 2px 10px rgba(0,0,0,0.5);
}
.color-swatch {
    width: 12px; height: 12px; border-radius: 2px; border: 1px solid rgba(255,255,255,0.2);
    box-shadow: 0 1px 2px black; cursor: help; transition: transform 0.2s;
}
.color-swatch:hover { transform: scale(1.5); z-index: 15; border-color: white; }


/* ==========================================================================
   11. GAME LOBBY
   One lobby, six games. Blackjack, bomb, crash and dice carried byte-identical
   copies of this block; roulette and poker had drifted by a rule or two. The
   deltas that were real (poker's seat list) stay in poker's own template.
   ========================================================================== */
.rl-wrap { max-width: 1100px; margin: 0 auto; padding: 24px 16px 60px; }

.rl-head { display: flex; align-items: center; gap: 14px; margin-bottom: 22px; flex-wrap: wrap; }
.rl-head a.back { color: var(--nx-ink-faint); text-decoration: none; font-size: 0.8rem; }
.rl-head a.back:hover { color: var(--nx-ink); }
.rl-head h1 {
    font-family: 'Impact', 'Arial Black', sans-serif;
    text-transform: uppercase;
    letter-spacing: 1px;
    font-size: 1.7rem;
    color: var(--nx-ink);
    margin: 0;
}
.rl-head h1 i { color: var(--nexus-gold); margin-right: 8px; }

.rl-grid { display: grid; grid-template-columns: 320px 1fr; gap: 18px; align-items: start; }
@media (max-width: 860px) { .rl-grid { grid-template-columns: 1fr; } }

.rl-card {
    background: var(--card-bg);
    border: 1px solid var(--nx-line);
    border-radius: var(--nx-radius);
    padding: 18px;
}
.rl-card h2 {
    font-size: 0.72rem;
    font-weight: 800;
    letter-spacing: 1.4px;
    text-transform: uppercase;
    color: var(--nx-ink-faint);
    margin: 0 0 14px;
}

.rl-field { margin-bottom: 12px; }
.rl-field label {
    display: block;
    font-size: 0.66rem;
    font-weight: 800;
    letter-spacing: 0.8px;
    text-transform: uppercase;
    color: var(--nx-ink-faint);
    margin-bottom: 5px;
}
/* A lobby's <select> is styled in section 7 alongside .nx-select, so the box
   and the chevron stay one rule rather than two that have to agree. The
   poker lobby's original was `.pk-field input, .pk-field select`, and dropping
   the second half when this moved out of the template left its two dropdowns
   rendering as bare Windows controls in the middle of a dark card. */
.rl-field input {
    width: 100%;
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: var(--nx-radius-sm);
    color: var(--nx-ink);
    padding: 9px 11px;
    font-size: 0.88rem;
}
.rl-field input:focus { outline: none; border-color: var(--nx-accent); }

.rl-toggle { display: flex; gap: 6px; }
.rl-toggle button {
    flex: 1;
    background: transparent;
    border: 1px solid rgba(255, 255, 255, 0.10);
    color: var(--nx-ink-mute);
    border-radius: var(--nx-radius-sm);
    padding: 8px;
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    cursor: pointer;
}
.rl-toggle button.active { background: var(--nexus-gold); border-color: transparent; color: #14151a; }

.rl-btn {
    width: 100%;
    margin-top: 6px;
    background: transparent;
    border: 1px solid var(--nexus-green);
    color: var(--nexus-green);
    border-radius: var(--nx-radius-sm);
    padding: 10px;
    font-size: 0.75rem;
    font-weight: 800;
    letter-spacing: 0.6px;
    text-transform: uppercase;
    cursor: pointer;
    transition: all 0.2s ease;
}
.rl-btn:hover { background: var(--nexus-green); color: #14151a; }

.rl-room {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 12px 14px;
    border-radius: var(--nx-radius-sm);
    background: var(--nx-fill);
    border: 1px solid var(--nx-line-soft);
    margin-bottom: 8px;
}
.rl-room .r-name { color: var(--nx-ink); font-weight: 700; font-size: 0.92rem; }
.rl-room .r-meta { color: var(--nx-ink-mute); font-size: 0.76rem; margin-left: auto; }
.rl-room .r-join {
    background: transparent;
    border: 1px solid var(--nexus-blue);
    color: var(--nexus-blue);
    border-radius: 7px;
    padding: 6px 14px;
    font-size: 0.68rem;
    font-weight: 800;
    text-transform: uppercase;
    cursor: pointer;
    text-decoration: none;
}
.rl-room .r-join:hover { background: var(--nexus-blue); color: #fff; }

.rl-empty {
    border: 1px dashed rgba(255, 255, 255, 0.12);
    border-radius: 10px;
    padding: 26px;
    text-align: center;
    color: var(--nx-ink-faint);
    font-size: 0.85rem;
}

.rl-join-code { display: flex; gap: 8px; margin-top: 10px; }
.rl-join-code input {
    flex: 1;
    background: rgba(0, 0, 0, 0.35);
    border: 1px solid rgba(255, 255, 255, 0.10);
    border-radius: var(--nx-radius-sm);
    color: var(--nx-ink);
    padding: 9px 11px;
    font-family: monospace;
    text-transform: uppercase;
}
.rl-join-code button {
    background: transparent;
    border: 1px solid var(--nexus-gold);
    color: var(--nexus-gold);
    border-radius: var(--nx-radius-sm);
    padding: 0 16px;
    font-size: 0.7rem;
    font-weight: 800;
    text-transform: uppercase;
    cursor: pointer;
}
.rl-join-code button:hover { background: var(--nexus-gold); color: #14151a; }

.rl-rules { color: var(--nx-ink-mute); font-size: 0.8rem; line-height: 1.6; }
.rl-rules b { color: var(--nx-ink-soft); }
