/* ====================================================================
   FIRE ARCADE & OBERON VANGUARD - CURSOR LAYER  (single source of truth)
   --------------------------------------------------------------------
   Goal: the player NEVER sees an OS cursor (arrow / hand / I-beam) in game.

   Files that make up the cursor system (keep them together):
     css/cursors.css          <- this file (tokens + rules)
     js/cursors.js            <- maps JS `el.style.cursor = 'pointer'` -> tokens
     media/cursors/*.png      <- 32px (1x) and 64px (2x) artwork

   Rules of the road for everyone else:
     - In CSS write  cursor: var(--cursor-pointer);   (never the raw keyword)
     - In JS  write  el.style.cursor = 'pointer';     (cursors.js converts it)
     - Inline HTML   style="cursor:pointer"           (caught in section 4)

   Layout of this file:
     1. Tokens        - one variable per cursor, 1x/2x image-set + hotspot
     2. Base          - html owns the default; everything else inherits it
     3. Interactive   - hand cursor for anything clickable / draggable
     4. Inline-style  - catch-all for cursor:keyword written inside style=""
     5. Text          - I-beam for typing fields
     6. Special states- grab / grabbing / crosshair / wait / progress
     7. Disabled      - ALWAYS LAST so it beats every rule above
   ==================================================================== */

/* ---------- 1. TOKENS ------------------------------------------------
   Syntax: image-set(1x, 2x) hotspotX hotspotY, 1x-fallback hotspot, keyword

   !! GOTCHA: a relative url() inside a CSS variable is resolved against the
   page/stylesheet that USES the variable, not this file. Used from style.css,
   injected <style> tags or inline styles, these relative paths 404 and the
   browser silently shows the OS cursor. js/cursors.js therefore re-publishes
   every token below with ABSOLUTE urls inline on <html> (inline beats :root).
   The relative values here are only the no-JS fallback. Keep hotspots in sync
   with SPECS in js/cursors.js. */
:root {
    --cursor-default:     -webkit-image-set(url('../media/cursors/default_32.png') 1x, url('../media/cursors/default_64.png') 2x) 1 1, url('../media/cursors/default_32.png') 1 1, default;
    --cursor-pointer:     -webkit-image-set(url('../media/cursors/pointer_32.png') 1x, url('../media/cursors/pointer_64.png') 2x) 4 1, url('../media/cursors/pointer_32.png') 4 1, pointer;
    --cursor-grab:        -webkit-image-set(url('../media/cursors/grab_32.png') 1x, url('../media/cursors/grab_64.png') 2x) 16 16, url('../media/cursors/grab_32.png') 16 16, grab;
    --cursor-grabbing:    -webkit-image-set(url('../media/cursors/grabbing_32.png') 1x, url('../media/cursors/grabbing_64.png') 2x) 16 16, url('../media/cursors/grabbing_32.png') 16 16, grabbing;
    --cursor-crosshair:   -webkit-image-set(url('../media/cursors/crosshair_32.png') 1x, url('../media/cursors/crosshair_64.png') 2x) 16 16, url('../media/cursors/crosshair_32.png') 16 16, crosshair;
    --cursor-text:        -webkit-image-set(url('../media/cursors/text_32.png') 1x, url('../media/cursors/text_64.png') 2x) 16 16, url('../media/cursors/text_32.png') 16 16, text;
    --cursor-not-allowed: -webkit-image-set(url('../media/cursors/not_allowed_32.png') 1x, url('../media/cursors/not_allowed_64.png') 2x) 16 16, url('../media/cursors/not_allowed_32.png') 16 16, not-allowed;
    --cursor-wait:        -webkit-image-set(url('../media/cursors/wait_32.png') 1x, url('../media/cursors/wait_64.png') 2x) 16 16, url('../media/cursors/wait_32.png') 16 16, wait;
    --cursor-progress:    -webkit-image-set(url('../media/cursors/progress_32.png') 1x, url('../media/cursors/progress_64.png') 2x) 1 1, url('../media/cursors/progress_32.png') 1 1, progress;
}

/* ---------- 2. BASE --------------------------------------------------
   `cursor` is an inherited property: set it once on <html>. Every child
   (canvases, HUD, text, overlays) inherits the custom arrow, and children
   of a clickable element inherit the hand. No `*` rule on purpose - a `*`
   rule would stomp that inheritance and break the hand on child spans/icons. */
html {
    cursor: var(--cursor-default);
}

/* ---------- 3. INTERACTIVE (hand) ------------------------------------ */
a, a[href], button, summary, label[for], select, option, optgroup,
input[type="button"], input[type="submit"], input[type="reset"], input[type="file"],
input[type="checkbox"], input[type="radio"], input[type="range"], input[type="color"],
[role="button"], [role="tab"], [role="slider"], [role="option"], [role="combobox"], [onclick], [data-action],
a *, button *, [role="button"] *,

/* Ability Hotbar & HUD Slots (Q, E, R, F) */
.ability-slot:not(.empty-slot),
.ability-slot:not(.empty-slot) *,
.ability-slot:not(.empty-slot):hover,
.ability-slot:not(.empty-slot):hover *,
.ability-img,
.ability-icon,
.keybind-pill,
.heat-radial-ring,
.heat-pct-badge,
.cooldown-radial,

/* In-DOM Cyberpunk Custom Dropdowns (Trigger & All Options) */
.cyber-select-wrapper,
.cyber-select-wrapper *,
.cyber-select-trigger,
.cyber-select-trigger *,
.cyber-select-options,
.cyber-select-option,
.cyber-select-option *,

/* Project specific clickable components */
.btn, .btn *, .pill-btn, .nav-tab, .tab-btn, .settings-tab-btn, .menu-item, .social-icon,
.modal-close-btn, .close-btn, .close-drawer-btn,
.game-card, .game-card *, .play-game-trigger,
.profile-summary, .profile-summary *, .profile-avatar-large, .avatar, .badge-item, .badge-item *,
.music-player, .music-player *, .volume-slider-container, .volume-slider-container *,
.track-select, .tactical-select, .tactical-btn, .tactical-btn-cancel, .tactical-btn-submit,
.oberon-menu-btn, .oberon-armory-btn, .keybind-btn,
.lobby-header-btn, .lobby-mode-btn, .lobby-network-btn, .lobby-toggle-btn, .lobby-tab, .lobby-tab *,
.lobby-btn, .lobby-btn *, .lobby-ship-card, .lobby-skin-card, .lobby-slot-remove-btn,
.lobby-player-slot, .lobby-player-slot *, .lobby-slot-empty-inner, .lobby-slot-empty-inner *,
.upgrade-card, .upgrade-card *, .telemetry-row, .telemetry-row *,
.stage-floating-cloud-pill, .stage-floating-cloud-pill *,
#btn-prev-eng, #btn-next-eng, #fx-minus, #fx-plus, #fy-minus, #fy-plus {
    cursor: var(--cursor-pointer) !important;
}

/* Empty socket fallback to default cursor */
.ability-slot.empty-slot,
.ability-slot.empty-slot * {
    cursor: var(--cursor-default) !important;
}

/* Range slider internals (Chromium/Electron paint thumb + track as pseudo-elements).
   KEEP THIS RULE SEPARATE: if a browser doesn't know one selector in a list, it
   throws away the WHOLE rule. Never mix vendor pseudo-elements into other lists,
   and never add ::-moz-* here - Chromium rejects them. */
input[type="range"]::-webkit-slider-thumb,
input[type="range"]::-webkit-slider-runnable-track {
    cursor: var(--cursor-pointer) !important;
}

/* ---------- 4. INLINE-STYLE CATCH-ALL --------------------------------
   HTML strings built in JS (innerHTML / template literals) often contain
   style="cursor:pointer". Inline keywords bypass the tokens, so map them. */
[style*="cursor: pointer"], [style*="cursor:pointer"] {
    cursor: var(--cursor-pointer) !important;
}
[style*="cursor: default"], [style*="cursor:default"] {
    cursor: var(--cursor-default) !important;
}
[style*="cursor: grab;"], [style*="cursor:grab;"] {
    cursor: var(--cursor-grab) !important;
}
[style*="cursor: grabbing"], [style*="cursor:grabbing"] {
    cursor: var(--cursor-grabbing) !important;
}
[style*="cursor: crosshair"], [style*="cursor:crosshair"] {
    cursor: var(--cursor-crosshair) !important;
}
[style*="cursor: text"], [style*="cursor:text"] {
    cursor: var(--cursor-text) !important;
}

/* ---------- 5. TEXT FIELDS (I-beam) ---------------------------------- */
input:not([type]), input[type="text"], input[type="search"], input[type="password"],
input[type="email"], input[type="number"], input[type="url"], input[type="tel"],
textarea, .tactical-textarea, [contenteditable="true"] {
    cursor: var(--cursor-text) !important;
}

/* ---------- 6. SPECIAL STATES ---------------------------------------- */

/* Draggable Fire Arcade cloud pill: grasping -> latched carrying.
   body.* variants keep the cursor stable when the mouse outruns the pill. */
.stage-floating-cloud-pill.is-pressing,
body.cloud-pressing,
body.cloud-pressing * {
    cursor: var(--cursor-grab) !important;
}

.stage-floating-cloud-pill.is-carrying,
body.cloud-carrying-active,
body.cloud-carrying-active *,
#stage-cloud-pill-shield {
    cursor: var(--cursor-grabbing) !important;
}

/* Combat reticle */
.combat-crosshair-active, #combat-reticle-layer {
    cursor: var(--cursor-crosshair) !important;
}

/* Loading overlays */
.loading, .is-loading, .quantum-waiting, .game-loading, .startup-loader-overlay {
    cursor: var(--cursor-wait) !important;
}

.in-progress {
    cursor: var(--cursor-progress) !important;
}


/* Decoupled HUD Comms Terminal: custom grab hand -> grabbing hand */
.comms-tabs-bar,
#hud-comms-drag-handle,
#hud-comms-terminal.is-minimized,
.comms-resize-grip {
    cursor: var(--cursor-grab) !important;
}

.comms-tabs-bar:active,
#hud-comms-drag-handle:active,
#hud-comms-terminal.is-dragging,
#hud-comms-terminal.is-dragging *,
.comms-resize-grip:active,
#hud-comms-terminal.is-resizing,
#hud-comms-terminal.is-resizing *,
body.hud-comms-dragging,
body.hud-comms-dragging * {
    cursor: var(--cursor-grabbing) !important;
}

/* ---------- 7. DISABLED / LOCKED (must stay last) ---------------------
   `html body` prefix raises specificity so this beats the hand rules above,
   including their `button *` style descendants. */
html body :is(button, select, input, textarea, a, .btn, [role="button"]):is(:disabled, [disabled], .disabled, .locked),
html body :is(button, select, input, textarea, a, .btn, [role="button"]):is(:disabled, [disabled], .disabled, .locked) *,
html body [disabled], html body .locked, html body .disabled,
html body .cyber-select-wrapper.is-disabled,
html body .cyber-select-wrapper.is-disabled *,
html body [style*="cursor: not-allowed"], html body [style*="cursor:not-allowed"] {
    cursor: var(--cursor-not-allowed) !important;
}
