/*  ═══════════════════════════════════════════════════════════════════
    play/lib/object-selector.css
    ──────────────────────────────────────────────────────────────────
    Common-library styles for the bottom-left "object selector" UI —
    a.k.a. the combo tracker. Pairs with play/lib/object-selector.js.

    Class prefix `os-` keeps everything namespaced so it doesn't clash
    with any existing per-game tracker styles (in particular WYN's
    `#wyn-combo-tracker` + `.wyn-ct-*` + `.tracker-*` rules in
    play/css/style.css remain untouched — WYN's bespoke implementation
    keeps working alongside the lib).

    Architecture notes:
      • DOM is `<div id="os-tracker">` with three cell siblings
        (.os-cell-1, .os-plus-cell, .os-cell-2). Each cell is a flex
        column with the slot on top + label below, both centered.
      • Tracker is anchored to the BOTTOM-LEFT of the visible canvas
        (#game-container, the 5:3 ratio inside #game-wrapper) — not
        the viewport — so it stays inside the canvas on wide-screen
        phones in fullscreen.
      • Four-state class system on #os-tracker (set by JS):
            os-default                — always present
            os-mob-win                — mobile + windowed
            os-mob-fs                 — mobile + fullscreen
            os-desk-fs                — desktop + fullscreen
            (none of mob/desk-*)      — desktop + windowed → default only

    See play/lib/OBJECT_SELECTOR.md for usage + AS hooks per game.
    ═══════════════════════════════════════════════════════════════════ */


/* ────────────────────────────────────────────────────────────────────
   1. Base tracker container — windowed mode is the default look.
      The os-default class is statically applied by JS at boot and never
      removed. Three circumstantial classes layer on top to override
      position/scale per device + fullscreen state (see fullscreen rules
      further down).
   ──────────────────────────────────────────────────────────────────── */
#os-tracker {
    position: absolute;
    display: flex;
    align-items: flex-end;
    gap: -8px;
    z-index: 25;
    transition: opacity 0.25s;
    /* Windowed defaults (overridden by os-mob-fs / os-desk-fs in FS) */
    bottom: 10px;
    left: 12px;
    transform: scale(0.7);
    transform-origin: bottom left;
}


/* ────────────────────────────────────────────────────────────────────
   2. Cell architecture — slot on top, label at bottom, flex column.
      Cell width MIN-tracks the slot (100 px) and grows to fit a longer
      label. Long names like "100 PROOF WHISKY" / "BAG OF NAILS" /
      "FIRE EXTINGUISHER" used to be truncated by play/lib/label-
      abbreviate.js to fit the 100 px box; with min-width + auto, the
      cell expands and the label renders in full. The slot inside stays
      100 × 100 (centred via align-items: center), so only the parent
      cell container grows — the icon itself never scales.
      Trade-off: when one cell's label is much wider than its
      neighbour's, the blood-splat overlap (driven by margin-left:-8px
      between siblings, see §2 below) loses its visual tightness for
      that pair. Acceptable cost for full readable names — labels were
      previously being clipped to 9 chars + "..." which looked worse.
   ──────────────────────────────────────────────────────────────────── */
.os-cell {
    display: flex;
    flex-direction: column;
    align-items: center;        /* horizontal-center slot + label */
    justify-content: flex-end;  /* anchor children to cell bottom */
    gap: 4px;
    min-width: 100px;           /* slot floor */
    width: auto;                /* grow with label */
}

/* Plus-cell mirrors a regular cell's shape so its plus icon vertically
   aligns with the slot centers in the adjacent cells. The plus-area is
   100px tall (matches slot height) with the 22×22 plus centered inside;
   the invisible label below provides bottom-padding parity. */
.os-plus-cell {
    width: 22px;
}
.os-plus-area {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 100px;
}
.os-plus-cell .os-label {
    visibility: hidden;
}

/* Negative-gap fallback — pulls each non-first sibling left so blood
   backgrounds overlap and the plus nestles tight against both slots.
   2026-04-30 — Tightened from -8px to -18px (10px more negative) per
   user request "reduce the gap between each object and each plus sign
   by 10px". For cells at the slot floor (100 px) this means the plus
   icon overlaps slot edges by 18 px instead of 8 — visually plus icon
   nestles deeper into both slots. For grown cells (e.g. Game Console
   145 px wide), the previously-visible 14.5 px gap between slot edge
   and plus icon now shrinks to 4.5 px. */
#os-tracker > *:not(:first-child) { margin-left: -40px; }

/* Children opt out of pointer events except the close button */
#os-tracker .os-slot,
#os-tracker .os-plus { pointer-events: none; }


/* ────────────────────────────────────────────────────────────────────
   2c. Slot alignment — centred in the cell (default `align-items:center`
        from .os-cell). This intentionally reverts the earlier per-cell
        edge-anchoring (cell-1 slot →right, cell-3 slot →left) because
        when the cell grew to fit a long label like "GAME CONSOLE", the
        slot was visually offset to one side of the cell while the label
        stayed centred — slot and label no longer aligned.

        With slot centred (align-self: center) the slot sits directly
        above the label's centre, regardless of cell width. Cells grow
        to fit their labels (min-width: 100px, width: auto) and the slot
        floats in the centre; gaps between slot/plus/slot are managed
        by the negative margin above (§2 -18px).
   ──────────────────────────────────────────────────────────────────── */


/* ────────────────────────────────────────────────────────────────────
   3. Slot — fixed 100×100 with absolute-positioned blood + icon + qmark.
      Blood fills the slot (object-fit:contain), icon centers at 60%,
      qmark centers at 50%. Icon + qmark visibility toggled via opacity.
   ──────────────────────────────────────────────────────────────────── */
.os-slot {
    position: relative;
    width: 100px;
    height: 100px;
    transform-origin: center center;
    transition: transform 0.4s ease-in;
}
.os-slot .os-blood {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    object-fit: contain;
}
.os-slot .os-icon {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 60%; height: 60%;
    object-fit: contain;
    transition: opacity 0.25s;
}
.os-slot .os-qmark {
    position: absolute;
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
    width: 50%; height: 50%;
    object-fit: contain;
    transition: opacity 0.25s;
}


/* ────────────────────────────────────────────────────────────────────
   4. Plus icon — 22×22 between cells.
   ──────────────────────────────────────────────────────────────────── */
.os-plus {
    width: 22px;
    height: 22px;
    object-fit: contain;
    transition: transform 0.4s ease-in;
}


/* ────────────────────────────────────────────────────────────────────
   5. Label (the black pill below each slot).
      transform: scale() composed in fullscreen rules to shrink labels
      relative to slots without affecting layout flow.
   ──────────────────────────────────────────────────────────────────── */
.os-label {
    background: #1a1a1a;
    color: #fff;
    padding: 6px 12px;
    border-radius: 8px;
    font-family: 'White wood', 'Woodbone', sans-serif;
    font-size: 11pt;
    letter-spacing: 1px;
    white-space: nowrap;
    text-align: center;
    text-transform: uppercase;
    pointer-events: none;
    transform-origin: center center;
}
/* Zero-width-space keeps line-box height consistent even on empty
   labels — without this, an empty label collapses to just its padding
   and shifts adjacent slots out of alignment. */
.os-label::before {
    content: "\200B";
}


/* ────────────────────────────────────────────────────────────────────
   6. Visibility helpers — JS toggles these to drive the state machine.
        os-hidden / os-visible      — whole tracker fade in/out
        os-single                   — collapse plus + cell-2 (single mode)
        os-cell-hidden              — display:none on a cell
        os-slot-hidden              — visibility:hidden on a slot
        os-label-hidden             — visibility:hidden on a label
   ──────────────────────────────────────────────────────────────────── */
.os-cell.os-cell-hidden     { display: none !important; }
.os-slot.os-slot-hidden     { visibility: hidden; }
.os-label.os-label-hidden   { visibility: hidden; }

#os-tracker.os-hidden {
    opacity: 0;
    visibility: hidden;
}
/* Force cells to scale(0) while the tracker is hidden. Belt-and-braces
   against any frame-timing race during _hideTracker() (skip-kill etc.):
   if the os-popping animation class is stripped while os-hidden is being
   added, the cells would otherwise snap from animation-end scale(0) to
   their natural scale(1) for one frame before opacity finishes fading.
   This rule pins them at scale(0) the whole time the tracker is hidden,
   matching the end of the pop-OUT keyframe seamlessly. */
#os-tracker.os-hidden .os-cell {
    transform: scale(0);
    transform-origin: center bottom;
}
#os-tracker.os-visible {
    opacity: 1;
    visibility: visible;
}

#os-tracker.os-single .os-plus-cell,
#os-tracker.os-single .os-cell-2,
#os-tracker.os-single .os-cell-3 { display: none; }


/* ────────────────────────────────────────────────────────────────────
   6b. 3-item combo support (WTB Rug+Chandelier+Bowling Ball etc.).
        Cell-3 + plus-cell-2 are present in the DOM at all times so the
        pop-in keyframe references stay valid, but they're hidden by
        default. JS adds `.os-3item` to #os-tracker for any kill whose
        WhackItConfig.killList items.length === 3, which reveals the
        third cell + the second plus separator.
        Close (X) button: in 2-item mode it sits on cell-2 (the partner
        cell). In 3-item mode it must be on cell-3 (the LAST cell) only —
        cell-2 is no longer the cancel target. The rules below collapse
        cell-3/plus-2 by default, expand them in 3-item mode, and toggle
        which cell shows the close button.
   ──────────────────────────────────────────────────────────────────── */
.os-cell-3,
.os-plus-cell-2 {
    display: none;
}
#os-tracker.os-3item .os-cell-3,
#os-tracker.os-3item .os-plus-cell-2 {
    display: flex;
}
/* In 3-item mode, hide cell-2's close button so only cell-3 (last) shows it */
#os-tracker.os-3item .os-cell-2 .os-close { display: none; }
/* In 2-item mode (default), cell-3's close button is hidden along with
   cell-3 itself via display:none on the parent, so no extra rule needed. */


/* ────────────────────────────────────────────────────────────────────
   7. Pop animation — slot+label cells scale to 110% then collapse to 0
      over 0.4s. Plus-cell rides along (it's also an .os-cell).
   ──────────────────────────────────────────────────────────────────── */
@keyframes os-pop {
    0%   { transform: scale(1); }
    35%  { transform: scale(1.10); }
    100% { transform: scale(0); }
}
#os-tracker.os-popping .os-cell {
    animation: os-pop 0.4s ease-in forwards;
    transform-origin: center bottom;
}

/* ────────────────────────────────────────────────────────────────────
   7b. Pop-IN animation — inverse of os-pop. Applied per-cell (not to
       the whole tracker) so cells can pop in SEQUENTIALLY. On combo
       grab the first item pops first, the plus + ?-cell follow after
       a short stagger; on combo reveal the cell-2 ICON ONLY pops in
       (the blood background stays put while the qmark fades out fast).

       Three classes drive the system:
         .os-popping-in (on .os-cell)   — whole-cell scale 0 → 110% → 100%
         .os-prepop     (on .os-cell)   — cell parked at scale 0 waiting
                                          its turn in the stagger
         .os-popping-in (on .os-icon)   — icon-only pop, composes with
                                          the icon's translate centering
                                          (used for combo reveal only)
   ──────────────────────────────────────────────────────────────────── */
@keyframes os-pop-in {
    0%   { transform: scale(0); }
    65%  { transform: scale(1.10); }
    100% { transform: scale(1); }
}
.os-cell.os-popping-in {
    animation: os-pop-in 0.4s ease-out forwards;
    transform-origin: center bottom;
}
.os-cell.os-prepop {
    transform: scale(0);
    transform-origin: center bottom;
}
@keyframes os-icon-pop-in {
    0%   { transform: translate(-50%, -50%) scale(0); }
    65%  { transform: translate(-50%, -50%) scale(1.10); }
    100% { transform: translate(-50%, -50%) scale(1); }
}
.os-slot .os-icon.os-popping-in {
    animation: os-icon-pop-in 0.4s ease-out forwards;
}


/* ────────────────────────────────────────────────────────────────────
   8. Close button — top-right of slot-2, swap default/hover artwork.
   ──────────────────────────────────────────────────────────────────── */
.os-close {
    position: absolute;
    top: -6px;
    right: -35px;
    width: 40px;
    height: 40px;
    padding: 0;
    border: none;
    background: transparent;
    cursor: pointer;
    z-index: 2;
    pointer-events: auto;
}
.os-close img {
    position: absolute;
    top: 0; left: 0;
    width: 100%; height: 100%;
    object-fit: contain;
    transition: opacity 0.15s;
}
.os-close .os-close-hover { opacity: 0; }
.os-close:hover .os-close-default { opacity: 0; }
.os-close:hover .os-close-hover   { opacity: 1; }


/* ────────────────────────────────────────────────────────────────────
   9. Windowed-mode label tweak — slightly smaller pill + lifted up so
      it sits cleanly under the slot without touching the slot's
      bottom edge. Applies in any windowed game (not fullscreen).
   ──────────────────────────────────────────────────────────────────── */
#game-wrapper:not(:fullscreen) #os-tracker .os-label {
    transform: scale(0.9);
    font-size: 16pt;
    position: relative;
    top: -15px;
}


/* ────────────────────────────────────────────────────────────────────
   10. Desktop fullscreen — anchor tracker to the canvas's bottom-left
       (canvas is centred in the wrapper at 5:3) and scale by canvas
       width. The /963 divisor matches WYN's tuned look; override
       per-game via WhackItConfig.objectSelector.fullscreenScaleDivisor.
   ──────────────────────────────────────────────────────────────────── */
#game-wrapper:fullscreen #os-tracker.os-desk-fs,
#game-wrapper:-webkit-full-screen #os-tracker.os-desk-fs {
    left:   calc((100vw - min(100vw, 100vh * 5 / 3)) / 2 + 24px);
    bottom: -25px;
    transform: scale(calc(min(80vw, 100vh * 5 / 3) / 963px));
    transform-origin: bottom left;
}

/* Fullscreen labels — smaller pill (composed with tracker scale) */
#game-wrapper:fullscreen #os-tracker .os-label,
#game-wrapper:-webkit-full-screen #os-tracker .os-label {
    transform: scale(0.6);
    position: relative;
    top: -25px;
    font-size: 16pt;
}


/* ────────────────────────────────────────────────────────────────────
   11. Mobile fullscreen — pinned 10 px from the canvas bottom-left so
       it never falls off-canvas on wide-screen phones. Slightly larger
       tracker scale than desktop (mobile screens are smaller — the
       canvas-relative scale would otherwise leave the icons unreadable).
       2026-04-30 — bumped from 0.9 → 1.05. First attempt at "40 %
       larger" used scale(1.26) (40 % linear from 0.9), which gave a
       96 % AREA increase — visibly nearly-double-sized. User reported
       it as "clearly over 100 % increase, probably more". Rolled back
       to scale(1.05): 17 % linear from 0.9, ~36 % area increase ≈
       what the eye perceives as a 40 % bump. transform-origin stays
       at bottom left so the tracker grows up + right from its 10 px-
       from-corner anchor (no risk of clipping the canvas edge).
   ──────────────────────────────────────────────────────────────────── */
#game-wrapper:fullscreen #os-tracker.os-mob-fs,
#game-wrapper:-webkit-full-screen #os-tracker.os-mob-fs {
    /* 2026-05-02 — Nudge container 10 px down + 10 px left from the
       canvas-relative anchor (was -10/+10 → now -20/+0). Applies to
       every game that uses the common library — WTB, WTC, WYN, and any
       future game inheriting #os-tracker.os-mob-fs. */
    bottom: calc((100vh - min(100vh, 100vw * 3 / 5)) / 2 - 20px);
    left:   calc((100vw - min(100vw, 100vh * 5 / 3)) / 2 + 0px);
    transform: scale(1.05);
    transform-origin: bottom left;
}
/* 2026-05-02 — Mobile fullscreen label sizing.
   ───────────────────────────────────────────────────────────────
   THIRD ATTEMPT, this one keeping the natural slot-above-label
   flex column. Iteration history:
     1. Original: `transform: scale(0.6)` shrunk the label visually
        only — the layout box stayed at the natural width
        (font-size 11pt + letter-spacing 1px + padding 6/12px), so
        the cell still grew to ~140 px for "CHANDELIER" and adjacent
        slots ended up far apart.
     2. Earlier 2026-05-02: pulled labels out of flex flow
        (`position: absolute`) and capped cell `max-width: 50px`.
        Cells stayed tight but labels overflowed into neighbouring
        cells AND off the canvas on a 2- or 3-item combo — user
        reported "labels overlap, on a double combo they break and
        come off the actual game canvas".
     3. NOW: keep the natural flex column (slot on top, label
        beneath, both centered as a unit — the way every other
        screen-state is laid out) but shrink the LABEL'S OWN
        LAYOUT BOX so the cell only grows modestly for long
        labels. Same visual size as the previous scale(0.6) look:
          font-size:    11pt × 0.6 ≈ 7pt
          padding:      6/12 × 0.6 ≈ 4/7 px
          letter-sp:    1   × 0.6 = 0.6 px
        Result: "CHANDELIER" cell ≈ 88 px (was ~140 px in attempt 1
        and 50 px / overflowing in attempt 2). Slot stays centred
        above the label both visually and geometrically; the -15 px
        sibling overlap (defined further down) handles the
        "minimal gap between object + plus + label" requirement.
        3-cell-combo tracker width ≈ 184 px at scale(1.05) — well
        inside the canvas on any phone landscape.

   The 9 px gap below preserves the user's earlier "lift slot 5 px
   above the label" request (4 px default + 5 px = 9 px).
   Per-game-agnostic — applies across WTB, WTC, WYN, every future
   game inheriting `#os-tracker.os-mob-fs`. */
#os-tracker.os-mob-fs .os-cell {
    gap: 9px;
}
#os-tracker.os-mob-fs .os-label {
    font-size: 7pt;
    padding: 4px 7px;
    letter-spacing: 0.6px;
}
/* 2026-05-02 — Close button is 40×40 px by default — that's
   80 % of the 50 px slot on mobile fullscreen, visually
   ridiculous (user reported "the close button is ridiculously
   big" with a screenshot). Shrink to 22×22 px on mobile fs
   (~44 % of the slot) and re-anchor to the slot's top-right
   corner with proportional offsets. The 22-px size matches the
   plus-icon size for a coherent control language. */
#os-tracker.os-mob-fs .os-close {
    width: 22px;
    height: 22px;
    top: -4px;
    right: -18px;
}
/* 2026-04-30 — User asked to reduce the mobile-fullscreen tracker
   by ~50 px in both dimensions and tighten spacing so no more than
   15 px sits between any slot and plus-icon. The base values
   (.os-slot 100×100, .os-cell min-width 100, plus cell height 100,
   sibling margin-left -40) produce a tracker ~149 px wide × 137 px
   tall in 2-cell mode and 193 px × 137 px in 3-cell mode. Cutting
   ~50 px off both with even spacing means halving the slot to 50×50
   and pulling sibling margin from -40 to -15:
     • Slot 100→50  (-50 px width AND -50 px height)
     • Cell min-width 100→50  (slot floor matches)
     • Plus cell height 100→50  (vertical alignment with adjacent slots)
     • Sibling overlap -40→-15  (max 15 px overlap between slot and plus)
   Result at the existing scale(1.05):
     2-cell:  (50+22+50−15×2) × 1.05 ≈ 100 px wide × 74 px tall
     3-cell:  (50+22+50+22+50−15×4) × 1.05 ≈ 140 px wide × 74 px tall
   Even spacing on both sides of every plus icon (the 15 px applies
   symmetrically because plus is centred in its 22 px cell + the
   -15 margin pulls each non-first sibling left by the same amount).
   Mobile-fullscreen-only — `.os-mob-fs` scope keeps windowed and
   desktop-fullscreen sizes untouched. */
#os-tracker.os-mob-fs .os-slot {
    width: 50px !important;
    height: 50px !important;
}
.os-mob-fs.os-mob-fs .os-cell {
    min-width: 50px;
}
#os-tracker.os-mob-fs .os-plus-cell,
#os-tracker.os-mob-fs .os-plus-area {
    height: 50px;
}
#os-tracker.os-mob-fs > *:not(:first-child) {
    margin-left: -15px;
}


/* ────────────────────────────────────────────────────────────────────
   12. Mobile windowed — currently inherits the base #os-tracker
       windowed look. Reserved for per-device tweaks via os-mob-win
       class hook if mobile portrait/landscape needs a different size.
   ──────────────────────────────────────────────────────────────────── */
/* (No overrides yet — placeholder for future mobile-windowed tuning) */
