/*
 * WynnSolver — desktop/wide stylesheet.
 * Loaded on solver/index.html alongside the shared wynnstyles / sq2bs sheets.
 */

/* ── Combo row inputs ────────────────────────────────────────────────────── */

/*
 * sq2bs.css sets .form-control { width: 95% !important } which breaks the
 * flex-row layout of combo rows.  Use this class instead — same visuals,
 * no fixed width so the flex container controls sizing.
 */
.combo-row-input {
    padding: 0.25rem 0.5rem;
    font-size: 0.875rem;
    line-height: 1.5;
    color: #fff;
    background-color: #212529;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 0.25rem;
    box-shadow: none;
    outline: none;
    /* width intentionally omitted — set by flex or inline style per element */
}

.combo-row-input:disabled {
    color: hsl(0, 0%, 45%);
    background-color: hsl(0, 0%, 12%);
    border-color: hsl(0, 0%, 22%);
    cursor: not-allowed;
}

.combo-row-input:focus {
    border-color: rgba(255, 255, 255, 0.4);
    outline: 0;
    box-shadow: 0 0 0 0.15rem rgba(255, 255, 255, 0.1);
}

/* ── Combo button tweaks ─────────────────────────────────────────────────── */

/* Remove box-shadow from all buttons on the solver page (cards/panels keep theirs). */
.btn:focus,
.btn:focus-visible,
.button-boost,
.button,
.btn {
    box-shadow: none !important;
    outline: none !important;
}

/*
 * Text / Selection mode buttons — dark when inactive, light-grey when active.
 * Mirrors the dark→light-grey pattern of the stat tabs.
 * .combo-row-boost-toggle (individual boosts inside the popup) intentionally
 * excluded — those keep the default green toggleOn from sq2bs.css.
 */
#combo-mode-text,
#combo-mode-selection {
    background-color: hsl(0, 0%, 15%) !important;
    border-color: hsl(0, 0%, 28%) !important;
    color: hsl(0, 0%, 65%) !important;
}

.combo-boost-menu-btn.toggleOn,
.combo-timing-menu-btn.toggleOn,
#combo-adv-btn.toggleOn,
#combo-downtime-btn.toggleOn,
#solver-advanced-btn.toggleOn,
#combo-mode-text.toggleOn,
#combo-mode-selection.toggleOn {
    background-color: hsl(0, 0%, 50%) !important;
    border-color: hsl(0, 0%, 62%) !important;
    color: #fff !important;
}

/* ── Combo row layout ────────────────────────────────────────────────────── */

/*
 * Flex children default to min-width:auto which prevents shrinking below
 * content size.  min-width:0 lets the row compress to fit its container at
 * narrow viewports instead of overflowing the right edge.
 *
 * NOTE: Do NOT add overflow:hidden here — it clips the absolutely-positioned
 * per-spell damage popup (.combo-dmg-popup) that extends above/below the row.
 */
.combo-row {
    min-width: 0;
    flex-wrap: wrap;
}

/*
 * Spell select grows to fill available space; inline width in JS is omitted.
 * min-width keeps it readable when the panel is narrow.
 */
.combo-row-spell {
    flex: 999 1 0;
    min-width: 8em;
}

/* Warning border for rows where HP < cost or mana < cost without Blood Pact */
.combo-row-spell.combo-row-warning {
    border-color: orange !important;
}

/* Boosts wrapper and button stay at natural (content) width. */
.combo-boost-btn-wrap {
    flex-shrink: 0;
}

/*
 * Damage/heal spans form fixed-width columns so numbers line up vertically
 * across all rows.  Heal sits to the left of damage so the more common
 * damage column stays flush-right at the row edge.
 */
.combo-row-heal {
    display: inline-block;
    text-align: right;
    flex-shrink: 0;
}

.combo-row-damage {
    display: inline-block;
    text-align: right;
    flex-shrink: 0;
}

/* ── Mana hover tooltip ──────────────────────────────────────────────────── */

.combo-mana-tooltip {
    display: none;
    bottom: calc(100% + 6px);
    left: 0;
    min-width: 14em;
    z-index: 1050;
    pointer-events: none;
    white-space: nowrap;
}

.combo-mana-wrapper:hover .combo-mana-tooltip,
.combo-mana-wrapper.popup-locked .combo-mana-tooltip {
    display: block;
}

.combo-mana-wrapper.popup-locked .combo-mana-tooltip {
    pointer-events: auto;
}


/* ── Roll-group popup ────────────────────────────────────────────────────── */

.roll-group-popup {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    right: 0;
    min-width: 160px;
    background: #1a1d21;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 4px;
    padding: 6px 8px;
    z-index: 1050;
    font-size: 0.8125rem;
}

.roll-group-row {
    display: flex;
    align-items: center;
    gap: 0.35rem;
    padding: 2px 0;
}

.roll-group-label {
    flex: 1 0 0;
    color: #adb5bd;
    font-size: 0.8125rem;
    white-space: nowrap;
}

.roll-group-input {
    width: 3.5em;
    text-align: center;
    padding: 1px 4px;
    font-size: 0.8125rem;
    color: #fff;
    background-color: #212529;
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 0.25rem;
    outline: none;
}

.roll-group-input:focus {
    border-color: rgba(255, 255, 255, 0.4);
}

/* Hide number input spin buttons */
.roll-group-input::-webkit-inner-spin-button,
.roll-group-input::-webkit-outer-spin-button {
    -webkit-appearance: none;
    margin: 0;
}

.roll-group-input {
    -moz-appearance: textfield;
}

.roll-group-suffix {
    color: #6c757d;
    font-size: 0.8125rem;
}

.roll-group-divider {
    margin: 4px 0;
    border-color: rgba(255, 255, 255, 0.12);
}

/* ── Roll-mode select ────────────────────────────────────────────────────── */

select.solver-select {
    background-color: hsl(0, 0%, 21%) !important;
    color: #fff !important;
    border-color: rgba(33, 37, 41, 1) !important;
    font-weight: bold;
    /* remove the default browser arrow tint that can clash with dark bg */
    background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill='none' stroke='%23aaaaaa' stroke-linecap='round' stroke-linejoin='round' stroke-width='2' d='m2 5 6 6 6-6'/%3e%3c/svg%3e");
}

select.solver-select option {
    background-color: hsl(0, 0%, 21%);
    color: #fff;
}

select.solver-select:focus {
    border-color: hsl(0, 0%, 30%) !important;
    box-shadow: none !important;
}

/* ── Tomes / Ability Tree / Aspects tab highlight ────────────────────────── */

/*
 * The Tomes/AT/Aspects tabs use the same fake-button + selected-btn pattern as
 * the Detailed/Summary stat tabs.  The base sq2bs rule lifts brightness from 9%
 * to 14% when selected; that's subtle on a dark card, so we bump it further here
 * and add a thin bottom accent to make the active tab unambiguous.
 */
#adjust-id .fake-button {
    padding: 0.35rem 0.5rem;
}

#adjust-id .fake-button.selected-btn {
    background-color: hsl(0, 0%, 20%) !important;
    border-bottom-color: rgba(255, 255, 255, 0.25) !important;
}

/* ── Ability tree sizing ─────────────────────────────────────────────────── */

/*
 * Give the tree canvas a capped height and allow scrolling in both axes.
 * This contains any absolutely-positioned tooltips within the tree panel,
 * preventing scroll stutter from atree hover-tooltips extending below viewport.
 * overflow-x: auto lets the tree scroll horizontally when the panel is narrower
 * than the rendered tree width (avoids left/right clipping).
 */
#atree-ui {
    max-height: 75vh;
    overflow-y: auto;
    overflow-x: auto;
}

/* ── Fixed footer ────────────────────────────────────────────────────────── */

.solver-footer {
    position: fixed;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 500;
    padding-top: 4px;
    padding-bottom: 4px;
}

/* Push page content up so fixed footer doesn't overlap.
 * min-width prevents the layout from squishing below 400px — users scroll
 * horizontally instead of the app trying to scale into an unusable state. */
body {
    padding-bottom: 40px;
    min-width: 400px;
}

/* ── Tome grid & label column ──────────────────────────────────────────── */

/* Kill Bootstrap's negative-margin gutter on the inner tome rows. */
.tome-grid .row {
    margin-left: 0;
    margin-right: 0;
}

/* Horizontal gap between the two tome columns on wide screens only.
 * Columns sized with calc() so the gap doesn't push them to wrap. */
@media (min-width: 1200px) {
    .tome-grid {
        column-gap: 1rem;
    }

    .tome-grid>.col {
        flex: 0 0 calc(50% - 0.5rem);
        max-width: calc(50% - 0.5rem);
    }
}

/* Fixed width so all tome labels ("Weapon", "Mysticism", etc.) align.
 * Sized to fit the widest label ("Mysticism") without extra space. */
.tome-label-col {
    width: 5.5em;
    flex: 0 0 auto;
}

/* Kill Bootstrap's negative-margin gutter on the inner aspect rows. */
#aspects-dropdown .row {
    margin-left: 0;
    margin-right: 0;
}

/* Switch aspect grid to two columns only on very wide screens. */
@media (min-width: 1800px) {
    .aspect-grid>.col {
        flex: 0 0 50%;
        max-width: 50%;
    }
}

/* ── Item slot lock toggle ──────────────────────────────────────────────── */

/*
 * Per-slot lock/unlock toggle icon.  Visible only when the slot has an item.
 * Clicking it flips the slot between locked (solver skips) and free (solver
 * searches).  The {eq}-lock div is the first child of {eq}-dropdown.
 */
.solver-lock-col {
    width: 18px;
    min-width: 18px;
    cursor: pointer;
    opacity: 0.65;
    transition: opacity 0.15s;
    color: hsl(145, 60%, 45%);
}

.solver-lock-col:hover {
    opacity: 1;
}

.solver-lock-col.solver-lock-free {
    color: hsl(0, 0%, 50%);
}

/* ── Item slot lock indicator ────────────────────────────────────────────── */

/*
 * .slot-locked  — user-set item; solver will NOT search this slot.
 * .slot-solver  — solver-filled item; solver WILL re-search this slot.
 * .slot-unlocked — empty slot; solver WILL search this slot.
 *
 * Applied to the `{eq}-dropdown` wrapper row by SolverItemDisplayNode.
 */

.slot-locked {
    border-left: 3px solid hsl(145, 60%, 40%) !important;
    cursor: pointer;
}

.slot-solver {
    border-left: 3px solid hsl(0, 0%, 30%) !important;
    cursor: pointer;
}

.slot-unlocked {
    border-left: 3px solid hsl(0, 0%, 30%) !important;
}

/* Visual feedback: brighten the slot row when hovering a clickable slot.
   Gated behind (hover: hover) to prevent sticky :hover on touch devices. */
@media (hover: hover) {
    .slot-locked:hover {
        background-color: hsla(145, 60%, 40%, 0.18) !important;
    }

    .slot-solver:hover {
        background-color: hsla(0, 0%, 60%, 0.14) !important;
    }
}

/* Persist highlight when the item tooltip is currently visible. */
.slot-selected {
    background-color: hsla(145, 60%, 40%, 0.18) !important;
}

/* ── Item tooltips ───────────────────────────────────────────────────────── */

/*
 * The tooltip divs live in #masonry-container. They are hidden by default
 * (display: none in HTML) and toggled by toggleItemTooltip().
 *
 * Flexbox wrapping replicates the builder's Macy masonry without the library:
 * each tooltip is capped at 340 px wide; when multiple are visible they sit
 * side-by-side and wrap onto additional rows.
 */

#masonry-container {
    display: flex;
    flex-wrap: wrap;
    align-items: flex-start;
    gap: 16px;
}

/*
 * sq2bs.css sets .float-tooltip { position: absolute } which causes all
 * tooltips to stack on top of each other (they're taken out of flow).
 * Override here so they participate in the masonry-container flex layout.
 */
.float-tooltip {
    position: static;
    /* override position: absolute from sq2bs.css */
    flex: 0 1 340px;
    max-width: 340px;
    /* prevent flavor text from expanding the box */
    min-width: 240px;
    /* gap handles spacing — no individual margin needed */
}

/* ── Calculate Mana button ──────────────────────────────────────────────────── */

/*
 * Mirrors Bootstrap btn-outline-* pattern using the same mana-blue as the
 * per-spell mana toggles.  Off = blue border + text, on/hover = blue fill +
 * white text.
 */
.btn-outline-mana {
    --mana-blue: hsl(213, 90%, 62%);
    color: var(--mana-blue) !important;
    border-color: var(--mana-blue) !important;
    background-color: transparent !important;
}

.btn-outline-mana:hover,
.btn-outline-mana:focus-visible {
    color: #fff !important;
    background-color: var(--mana-blue) !important;
    border-color: var(--mana-blue) !important;
}

.btn-outline-mana.toggleOn {
    color: #fff !important;
    background-color: var(--mana-blue) !important;
    border-color: var(--mana-blue) !important;
}

.btn-outline-mana.toggleOn:hover,
.btn-outline-mana.toggleOn:focus-visible {
    background-color: hsl(213, 90%, 55%) !important;
    border-color: hsl(213, 90%, 55%) !important;
}

/* ── Per-spell mana inclusion toggle ────────────────────────────────────────── */

/*
 * Thin bar to the right of the Boosts button in each selection-mode combo row.
 * Blue (filled) when the spell is included in the mana calculation (default).
 * Transparent (border only) when excluded.
 */
.combo-mana-toggle {
    width: 8px;
    min-width: 8px;
    height: 1.75em;
    padding: 0;
    border: 2px solid hsl(213, 90%, 62%);
    background-color: hsl(213, 90%, 62%);
    border-radius: 3px;
    flex-shrink: 0;
    cursor: pointer;
}

.combo-mana-toggle.mana-excluded {
    background-color: transparent;
}

.combo-mana-toggle:hover {
    opacity: 0.75;
}

/* ── Per-spell damage inclusion toggle ──────────────────────────────────────── */

/*
 * Thin bar next to the mana toggle.
 * Red (filled) when the spell is included in the damage total (default).
 * Transparent (border only) when excluded.
 */
.combo-dmg-toggle {
    width: 8px;
    min-width: 8px;
    height: 1.75em;
    padding: 0;
    border: 2px solid hsl(0, 80%, 58%);
    background-color: hsl(0, 80%, 58%);
    border-radius: 3px;
    flex-shrink: 0;
    cursor: pointer;
}

.combo-dmg-toggle.dmg-excluded {
    background-color: transparent;
}

.combo-dmg-toggle:hover {
    opacity: 0.75;
}

/* Smooth fade-in when tooltip becomes visible */
.float-tooltip[style*="display: flex"] {
    animation: tooltip-fade-in 0.12s ease-in;
}

@keyframes tooltip-fade-in {
    from {
        opacity: 0;
        transform: translateY(-4px);
    }

    to {
        opacity: 1;
        transform: translateY(0);
    }
}

/* ── Level / Roll / Reset + action buttons grid ──────────────────────────────── */
/*
 * Container-query driven layout with explicit grid-template-areas for
 * reliable placement.  Three tiers:
 *
 * Narrow (default, <240px): 3-col, 4-row — reset spans rows 1-2, buttons below.
 *   Row 1: [Level] [input] [Reset]
 *   Row 2: [Roll]  [input] [Reset]
 *   Row 3: [Copy URL ────────────]
 *   Row 4: [Export to Builder ───]
 *
 * Medium (≥240px, also mobile/tablet): 3-col, 3-row — buttons inline, reset below.
 *   Row 1: [Level] [input] [Copy URL]
 *   Row 2: [Roll]  [input] [Export to Builder]
 *   Row 3: [Reset ──────────────────────────]
 *
 * Wide (≥295px, desktop XL only): 4-col, 2-row — everything inline.
 *   Row 1: [Level] [input] [Copy URL]         [Reset]
 *   Row 2: [Roll]  [input] [Export to Builder] [Reset]
 */

.solver-lrg-wrap {
    container-type: inline-size;
}

/* Assign grid areas to each child by DOM position */
.solver-level-roll-grid> :nth-child(1) {
    grid-area: lvl-lbl;
}

.solver-level-roll-grid> :nth-child(2) {
    grid-area: lvl-in;
}

.solver-level-roll-grid> :nth-child(3) {
    grid-area: copy;
}

.solver-level-roll-grid> :nth-child(4) {
    grid-area: reset;
}

.solver-level-roll-grid> :nth-child(5) {
    grid-area: roll-lbl;
}

.solver-level-roll-grid> :nth-child(6) {
    grid-area: roll-in;
}

.solver-level-roll-grid> :nth-child(7) {
    grid-area: export;
}

/* Default: narrowest — 3-column, 4-row */
.solver-level-roll-grid {
    display: grid;
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
        "lvl-lbl  lvl-in  reset"
        "roll-lbl roll-in reset"
        "copy     copy    copy"
        "export   export  export";
    gap: 0.25rem 0.5rem;
    align-items: center;
}

.solver-lrg-label {
    font-size: 0.8em;
    white-space: nowrap;
}

#level-choice,
#roll-mode-input {
    min-width: 3em;
}

.solver-reset-btn {
    align-self: stretch;
    white-space: nowrap;
}

.solver-action-btn {
    text-align: center;
    white-space: nowrap;
}

/* Medium: buttons inline, reset drops to full-width row below (3 rows) */
@container (min-width: 240px) {
    .solver-level-roll-grid {
        grid-template-columns: auto 1fr max-content;
        grid-template-areas:
            "lvl-lbl  lvl-in  copy"
            "roll-lbl roll-in export"
            "reset    reset   reset";
    }

    .solver-action-btn {
        text-align: center;
    }
}

/* Wide: everything inline — desktop XL only (mobile/tablet stay at medium) */
@container (min-width: 295px) {
    @media (min-width: 1200px) {
        .solver-level-roll-grid {
            grid-template-columns: auto 1fr max-content auto;
            grid-template-areas:
                "lvl-lbl  lvl-in  copy   reset"
                "roll-lbl roll-in export reset";
        }
    }
}

/* ── Ability-tree active list scroll ─────────────────────────────────────────── */

/*
 * Without a height cap the spell-description panel can push the atree section
 * to an extreme length.  Mirror WynnBuilder's overflow-y scroll behaviour.
 */
#atree-active {
    overflow-y: auto;
}

/* ── Stat box padding & row-margin fix ────────────────────────────────────── */

#summary-stats,
#detailed-stats {
    padding: 0 0.5rem 0.35rem;
}

/*
 * Bootstrap's .row applies negative margin-left/right to cancel out its col
 * children's gutter padding.  Inside the narrow stat card and atree active-list
 * this removes the perceived left/right padding.  Zeroing the margin only inside
 * those specific containers preserves the correct behaviour everywhere else.
 */
#summary-stats .row,
#detailed-stats .row,
#atree-active .row {
    margin-left: 0 !important;
    margin-right: 0 !important;
}

/* Strip the outer gutter from the first/last col so only the container padding
 * provides the edge inset, while the inner gutter between columns is kept. */
#summary-stats .row> :first-child,
#detailed-stats .row> :first-child {
    padding-left: 0;
}

#summary-stats .row> :last-child,
#detailed-stats .row> :last-child {
    padding-right: 0;
}

/* ── Attack selection button border ──────────────────────────────────────────── */

/*
 * Bootstrap's form-select adds a bright white focus ring that stands out too
 * strongly in the dark combo rows.  Tone it down to match other inputs.
 */
.combo-row-spell {
    border-color: rgba(255, 255, 255, 0.15) !important;
}

.combo-row-spell:focus {
    border-color: rgba(255, 255, 255, 0.3) !important;
    box-shadow: none !important;
}

/* ── Combo boost popup ───────────────────────────────────────────────────────── */

/*
 * Default absolute positioning for the boost popup.
 * JS (combo_toggle_boost_popup) may override to position:fixed + explicit width
 * to span the full combo column; clearing those inline styles reverts to this.
 */
.boost-popup {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    min-width: 280px;
    max-height: 70vh;
    overflow-y: auto;
    z-index: 1050;
}

.timing-popup {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    width: max-content;
    z-index: 1050;
}

/* ── Per-spell damage breakdown popup ────────────────────────────────────────── */

/*
 * The dmg-wrap is a thin wrapper around the per-row damage span so we can
 * position the breakdown popup relative to it.
 * Hover → popup appears temporarily; click (popup-locked) → stays visible.
 */
.combo-row-damage-wrap {
    position: relative;
    display: inline-flex;
    align-items: center;
    flex-shrink: 0;
}

.combo-dmg-popup {
    display: none;
    position: absolute;
    bottom: calc(100% + 4px);
    right: 0;
    background: #1a1d21;
    border: 1px solid rgba(255, 255, 255, 0.2);
    border-radius: 4px;
    padding: 6px 10px;
    z-index: 1060;
    font-size: 0.8em;
    white-space: normal;
    /* allow element range lines to wrap */
    pointer-events: none;
    min-width: 200px;
    max-width: 300px;
    max-height: 60vh;
    overflow-y: auto;
}

.combo-row-damage-wrap.has-popup:hover .combo-dmg-popup,
.combo-row-damage-wrap.popup-locked .combo-dmg-popup {
    display: block;
}

/* Show popup below the row instead of above when near the viewport top. */
.combo-row-damage-wrap.popup-below .combo-dmg-popup {
    bottom: auto;
    top: calc(100% + 4px);
}

/* Allow scrolling/selecting text in the popup when it is click-locked. */
.combo-row-damage-wrap.popup-locked .combo-dmg-popup {
    pointer-events: auto;
}

.combo-row-damage {
    cursor: default;
}

/*
 * Wrapper around mana toggle, damage toggle, and damage display.
 * Keeps these three elements together as a single flex item so they always
 * wrap to line 2 as a group instead of splitting across lines.
 */
.combo-row-toggles-wrap {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    flex-shrink: 0;
    flex-grow: 1;
}

.combo-row-toggles-wrap .combo-row-damage-wrap {
    margin-left: auto;
}

/*
 * Combo total row: always allow wrapping so the Time/Downtime section can
 * drop to line 2 when the panel is narrow — not only at ≤576px.
 */
.combo-total-row {
    flex-wrap: wrap;
}

/* ── Combo row drag-and-drop ─────────────────────────────────────────────────── */

.combo-row[draggable="true"] {
    cursor: grab;
}

.combo-row.dragging {
    opacity: 0.35;
}

.combo-row.drag-over-top {
    box-shadow: 0 -2px 0 rgba(255, 255, 255, 0.45);
}

/* ── Loop bracket rows ──────────────────────────────────────────────────────── */

.combo-loop-start,
.combo-loop-end {
    font-size: 0.8125rem;
    color: #adb5bd;
    padding: 0;
    min-height: 0;
}

.combo-loop-start .combo-loop-label,
.combo-loop-end .combo-loop-label {
    font-weight: 600;
    color: #7eb8da;
}

.combo-loop-start .combo-loop-condition {
    color: #adb5bd;
    font-size: 0.75rem;
}

.combo-loop-start .combo-loop-result {
    color: #6cc070;
    font-size: 0.75rem;
    margin-left: auto;
}

/* Loop condition select: match combo-row-input border */
.combo-loop-cond-type {
    flex: 999 1 0;
    min-width: 8em;
    border-color: rgba(255, 255, 255, 0.15) !important;
}

.combo-loop-cond-type:focus {
    border-color: rgba(255, 255, 255, 0.3) !important;
    box-shadow: none !important;
}

/* Loop count input: match boosts button width */
.combo-loop-count {
    width: 5.5em !important;
}

/* Loop label: same width and spacing as combo-row-qty */
.combo-loop-label {
    display: inline-block;
    width: 42px;
    text-align: center;
    box-sizing: content-box;
}

.combo-loop-result {
    margin-left: 39px !important;
}

/* Indent body rows between matched loop brackets */
.loop-body {
    border-left: 2px solid rgba(126, 184, 218, 0.35);
    padding-left: 0.5em;
}

/* ── Solver result rows ──────────────────────────────────────────────────────── */

.solver-result-row {
    display: flex;
    align-items: baseline;
    gap: 0.5rem;
    padding: 0.2rem 0.4rem;
    border-radius: 0.25rem;
    cursor: pointer;
    font-size: 0.8125rem;
    border: 1px solid rgba(255, 255, 255, 0.08);
    margin-bottom: 0.2rem;
    overflow: hidden;
    white-space: nowrap;
}

.solver-result-row:hover {
    background-color: rgba(255, 255, 255, 0.12);
}

.solver-result-rank {
    font-weight: bold;
    min-width: 1.8rem;
    flex-shrink: 0;
    color: #adb5bd;
}

.solver-result-score {
    font-weight: bold;
    color: #ffd700;
    flex-shrink: 0;
    min-width: 5rem;
}

.solver-result-items {
    color: #adb5bd;
    overflow: hidden;
    text-overflow: ellipsis;
    flex: 1;
}

.solver-result-newtab {
    flex-shrink: 0;
    color: #6ea8fe;
    text-decoration: none;
    padding: 0 0.25rem;
    opacity: 0.6;
    font-size: 0.85em;
}

.solver-result-newtab:hover {
    opacity: 1;
    color: #9ec5fe;
}

.solver-expand-toggle {
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    text-align: center;
    padding: 0 0.4rem;
    border-radius: 0.25rem;
    border: 1px solid rgba(255, 255, 255, 0.08);
    margin-bottom: 0.2rem;
    user-select: none;
    color: #adb5bd;
}

.solver-expand-toggle:hover {
    background-color: rgba(255, 255, 255, 0.12);
}

/* ═══════════════════════════════════════════════════════════════════════════════
 * Mobile / narrow viewport support
 *
 * Breakpoints:  576px (phone)  |  768px (tablet)
 * Bootstrap already stacks the 3-column layout below 1200px (xl breakpoint).
 * These rules fix individual components that overflow on narrow screens.
 * All rules use plain CSS — no Bootstrap utility classes added.
 *
 * NOTE: sq2bs.css scales fonts/icons down for landscape-and-<1200px and for
 * >=1200px, but portrait phones (<1200px, portrait) get the giant 2.5rem
 * defaults (the builder works around this via viewport initial-scale=.45).
 * Since the solver uses initial-scale=1 for proper mobile support, we must
 * apply the scale-down ourselves for narrow portrait viewports.
 * ═══════════════════════════════════════════════════════════════════════════════ */

/* ── Portrait phone/tablet: scale down fonts and icons ─────────────────────── */
/*
 * Mirrors the values from sq2bs.css's landscape-and-<1200px media query.
 * Uses max-width:1199px + portrait to catch exactly the gap sq2bs.css misses.
 */

@media screen and (orientation: portrait) and (max-width: 1199px) {
    :root {
        --scaled-fontsize: max(1rem, 16px);
    }

    .scaled-font {
        font-size: max(1rem, 16px);
    }

    .box-title {
        font-size: 1rem;
    }

    .item-title {
        font-size: 1.2rem;
    }

    .big-title {
        font-size: 1.5rem;
    }

    .skp-tooltip {
        font-size: 1rem;
    }

    .spellcost-tooltip b {
        font-size: .625rem !important;
    }

    .scaled-item-icon {
        width: 3.2rem;
    }

    .scaled-item-icon img {
        width: 2.8rem;
    }

    .scaled-bckgrd {
        width: 4rem;
        height: 4rem;
    }

    .scaled-bckgrd img {
        width: 2.8rem;
    }

    .warning {
        font-size: .7rem;
    }

    .spell-display b {
        font-size: 1rem;
    }
}

/* ── Remove Items/AT tab switcher ──────────────────────────────────────────── */
/*
 * On the solver, the ability tree lives in a tabbed panel (Tomes/AT/Aspects)
 * that is always visible below the item grid.  The builder's mobile tab
 * switcher that toggles between Items and AT sections is not needed.
 */

#solver-mobile-tab-selector {
    display: none !important;
}

/* ── Stacked layout: weapon ordering ───────────────────────────────────────── */
/*
 * Below the xl breakpoint Bootstrap stacks the equipment grid into one column.
 * The interleaved order-0/order-1 groups armor first, then accessories.
 * Push the weapon row after accessories, with level/roll controls last.
 */

@media (max-width: 1199px) {
    .col:has(#weapon-dropdown) {
        order: 2 !important;
    }

    .col:has(#level-choice) {
        order: 3 !important;
    }

    /* Ring1 has my-0 (needed on xl to avoid extra top margin on the first row).
     * On stacked layout ring1 follows boots, so restore its gutter margin. */
    .col:has(#ring1-dropdown) {
        margin-top: var(--bs-gutter-y) !important;
    }

}

/* ── Tablet: atree touch scroll ────────────────────────────────────────────── */

@media (max-width: 768px) {
    #atree-ui {
        -webkit-overflow-scrolling: touch;
        overscroll-behavior-x: contain;
        /* prevent back-nav gesture hijack */
    }
}

/* ── Item level min hint ───────────────────────────────────────────────────── */

#restr-lvl-min:placeholder-shown {
    border-color: rgba(240, 173, 78, 0.5);
}

/* ── Build direction buttons ───────────────────────────────────────────────── */

.dir-btn.toggleOn {
    background-color: #198754 !important;
    border-color: #198754 !important;
    color: #fff !important;
}

.dir-btn:not(.toggleOn) {
    opacity: 0.55;
}

/* ── Restriction / blacklist rows ─────────────────────────────────────────── */
/*
 * Restriction rows reuse the .combo-row class but should NOT wrap.
 * Override the combo-row flex-wrap and constrain the stat input.
 */

[id^="restr-row-"] {
    flex-wrap: nowrap;
}

.restr-stat-input {
    flex: 1 1 0 !important;
    /* shrink instead of overflowing */
    min-width: 5em;
}

/* Only add top margin to blacklist-rows when it has children */
#blacklist-rows:not(:empty) {
    margin-top: 0.5rem;
}

/* ── Restriction stat autocomplete dropdown ───────────────────────────────── */

ul.search-box {
    max-height: 40vh;
    overflow-y: auto;
}

/* ── Phone: all component fixes ────────────────────────────────────────────── */

@media (max-width: 576px) {

    /* ── Item tooltips: constrain to viewport ── */

    .float-tooltip {
        min-width: 0;
        max-width: 100%;
        flex-basis: 100%;
        /* one tooltip per row on phones */
    }

    #masonry-container {
        gap: 8px;
    }

    /* ── Skill points: compact for phones ── */

    .skp-tooltip {
        font-size: 0.8rem;
    }

    /* ── Combo rows: tweak for phone ── */
    /*
     * flex-wrap is always on (see global .combo-row rule).
     * Shrink the boost button and widen the spell select on narrow screens.
     */

    .combo-row-spell {
        flex: 1 1 45%;
        min-width: 7em;
    }

    .combo-boost-btn-wrap {
        flex-shrink: 1;
    }

    /* ── Mana / damage toggle bars: larger touch targets ── */

    .combo-mana-toggle,
    .combo-dmg-toggle {
        width: 14px;
        min-width: 14px;
    }

    /* ── Boost popup: bottom-sheet on phones ── */
    /*
     * CSS !important overrides the inline styles set by JS in
     * combo_toggle_boost_popup(), converting the popup to a viewport-anchored
     * bottom sheet above the fixed footer.
     */

    .boost-popup {
        position: fixed !important;
        left: 4px !important;
        right: 4px !important;
        width: auto !important;
        max-width: none !important;
        min-width: 0;
        top: auto !important;
        bottom: 50px !important;
        /* above fixed footer */
        max-height: 60vh;
    }

    .timing-popup {
        position: fixed !important;
        left: 4px !important;
        right: 4px !important;
        width: auto !important;
        min-width: 0;
        top: auto !important;
        bottom: 50px !important;
        max-height: 60vh;
    }

    /* ── Damage popup: prevent right-edge clipping ── */

    .combo-dmg-popup {
        min-width: 0;
        max-width: calc(100vw - 32px);
    }

    /* ── Footer: extra clearance for wrapping text ── */

    body {
        padding-bottom: 56px;
    }

    .solver-footer {
        padding-top: 6px;
        padding-bottom: 6px;
    }

    /* ── Restriction autocomplete: constrain to viewport ── */

    ul.search-box {
        max-width: calc(100vw - 32px);
    }
}

/* ── Encoding-limit validation feedback ───────────────────────────────────── */

.encoding-capped {
    border-color: #f0ad4e !important;
    box-shadow: 0 0 0 1px rgba(240, 173, 78, 0.4);
}

.restr-contradictory {
    border-color: #d9534f !important;
    box-shadow: 0 0 0 1px rgba(217, 83, 79, 0.5);
}

.encoding-limit-msg {
    animation: fade-out-msg 3s ease-in forwards;
}

@keyframes fade-out-msg {

    0%,
    70% {
        opacity: 1;
    }

    100% {
        opacity: 0;
    }
}

/* ── Advanced panel ───────────────────────────────────────────────────────── */

.adv-weight-row {
    display: flex;
    justify-content: space-between;
    padding: 0 0.5em;
}

.adv-weight-label {
    color: #ccc;
    font-size: 0.8em;
}

.adv-weight-val {
    color: #fff;
    font-size: 0.8em;
    font-family: monospace;
}

.adv-sp-row {
    display: flex;
    gap: 1em;
    padding: 0 0.5em;
    flex-wrap: wrap;
}

.adv-sp-entry {
    color: #ccc;
    font-size: 0.8em;
    font-family: monospace;
}

/* ── Thin scrollbar (override styles.css chunky scrollbar) ─────────────── */
::-webkit-scrollbar {
    width: 6px !important;
    height: 6px !important;
}

::-webkit-scrollbar-track {
    background: transparent !important;
    box-shadow: none !important;
    border: none !important;
}

::-webkit-scrollbar-thumb {
    background: rgba(180, 180, 180, 0.5) !important;
    border-radius: 3px !important;
}

::-webkit-scrollbar-thumb:hover {
    background: rgba(180, 180, 180, 0.7) !important;
}

::-webkit-scrollbar-corner {
    background: transparent !important;
}

/* Firefox */
* {
    scrollbar-width: thin;
    scrollbar-color: rgba(180, 180, 180, 0.5) transparent;
}

/* ── Info overlay ──────────────────────────────────────────────────────── */
.solver-info-highlight {
    position: relative !important;
    z-index: 10000 !important;
    box-shadow: 0 0 0 2px rgba(100, 180, 255, 0.7), 0 0 12px 2px rgba(100, 180, 255, 0.3) !important;
    border-radius: 0.25rem;
}

.solver-info-badge {
    position: absolute;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: rgba(100, 180, 255, 0.9);
    color: #000;
    font-size: 11px;
    font-weight: bold;
    display: flex;
    align-items: center;
    justify-content: center;
    pointer-events: none;
    z-index: 10001;
    line-height: 1;
}

/* >= 1200px: fixed bottom-left panel */
.solver-info-legend {
    position: fixed;
    bottom: 1rem;
    left: 1rem;
    max-width: 600px;
    width: 40%;
    max-height: 45vh;
    overflow-y: auto;
    background: rgba(25, 25, 35, 0.95);
    border: 1px solid rgba(255, 255, 255, 0.15);
    border-radius: 0.5rem;
    padding: 0.75rem 1rem;
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 0.3rem 1.5rem;
    z-index: 10001;
    cursor: default;
    font-size: 0.82rem;
    color: #ccc;
    line-height: 1.4;
}

/* < 1200px: inline section that scrolls with the page */
@media (max-width: 1199.98px) {
    .solver-info-legend {
        position: relative;
        bottom: auto;
        left: auto;
        max-width: none;
        width: 100%;
        max-height: none;
        grid-template-columns: 1fr;
        border-radius: 0.5rem;
        margin-top: 1rem;
    }
}

.solver-info-legend-entry {
    display: flex;
    align-items: baseline;
    gap: 0.4rem;
    cursor: pointer;
    user-select: none;
}

.solver-info-legend-summary {
    font-weight: 500;
}

.solver-info-legend-detail {
    display: none;
    color: #aaa;
    font-size: 0.78rem;
    margin-top: 0.15rem;
    padding-left: 0.4rem;
}

.solver-info-legend-entry.expanded .solver-info-legend-detail {
    display: block;
}

.solver-info-legend-hidden-note {
    color: #888;
    font-style: italic;
    font-size: 0.78rem;
}

#solver-info-btn.btn-outline-info {
    color: #7aaccc;
    border-color: #7aaccc;
}

#solver-info-btn.btn-outline-info:hover,
#solver-info-btn.btn-outline-info:focus {
    background-color: rgba(122, 172, 204, 0.15);
    color: #9dc4dc;
    border-color: #9dc4dc;
}

.solver-info-badge-inline {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 18px;
    height: 18px;
    border-radius: 50%;
    background: rgba(100, 180, 255, 0.9);
    color: #000;
    font-size: 10px;
    font-weight: bold;
    flex-shrink: 0;
    line-height: 1;
}