/**
 * Mulligan Phase CSS Styles
 * Styles for the pre-game card selection overlay
 */

/* Mulligan Overlay - covers the game view during mulligan phase */
#mulligan-overlay {
    --mulligan-unit: 1vmin;
    position: fixed;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    /* Above every transient battlefield layer, including enlarged board cards
       (9500) and spell announcements (9600), but below tutorial guidance and
       blocking/system overlays. Locked by mulliganLayering.test.js. */
    z-index: 9700;
    display: none;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    background: rgba(8, 12, 18, 0.42);
    -webkit-backdrop-filter: blur(2px);
    backdrop-filter: blur(2px);
    animation: mulliganFadeIn 0.5s ease-out;
    overflow: visible;
}

#mulligan-overlay.active {
    display: flex;
}

/* Connected, final-size staging for the initial hand; JS drops this class once
   every face settles (capped at 1500ms).

   Only what depends on the settled hand waits. The veil and header need no
   assets, and presenting them at once is what covers the raw battlefield a
   mulligan entry deliberately walks into — socket-handler skips the battle
   veil here on the promise that the overlay fades itself in, a promise the old
   whole-overlay `visibility: hidden` broke by spending `mulliganFadeIn` off
   screen and then cutting the finished overlay in hard.

   The wait uses `visibility`, so every card stays measurable, the row keeps its
   final height, and nothing reflows when the hand arrives. And staging must NOT
   set `pointer-events: none`: that was safe while the overlay was invisible,
   but a veil the player can SEE has to block, or the battlefield stays
   clickable through something that looks like a modal.
   Contract: tests/unit/styles/mulliganEntrySequence.test.js. */
#mulligan-overlay.mulligan-raster-staging #mulligan-cards,
#mulligan-overlay.mulligan-raster-staging .mulligan-status,
#mulligan-overlay.mulligan-raster-staging .mulligan-buttons,
#mulligan-overlay.mulligan-raster-staging .mulligan-timer {
    visibility: hidden;
}

/* The hand deals in (UI.FX.staggerChildren), then the controls arrive a beat
   behind it — the moment the player is actually being asked to choose.
   Declared on the released state so it starts exactly when staging lifts; a
   gate-free show has no staging class and starts it with .active, which is the
   same beat. Opacity only: the controls sit beside the cards and a transform
   here would resample their raster mid-entrance. The countdown is deliberately
   left out — a staging-scoped `animation` on .mulligan-timer would out-specify
   its own warning/critical pulse. */
#mulligan-overlay.active:not(.mulligan-raster-staging) .mulligan-status,
#mulligan-overlay.active:not(.mulligan-raster-staging) .mulligan-buttons {
    animation: mulliganControlsIn 300ms ease-out 240ms backwards;
}

@keyframes mulliganControlsIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

/* Explicit raster-gate failure. Rather than reveal a partial/half-rendered
   hand, JS clears the cards and appends this actionable panel. JS drops the
   staging class first, so the panel and its recovery button are released and
   interactive on the overlay's own default `pointer-events`. */

.mulligan-raster-failure {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1.25rem;
    max-width: min(88vw, 34rem);
    margin: auto;
    padding: 1.75rem 2rem;
    text-align: center;
    background: rgba(14, 18, 28, 0.92);
    border: 1px solid rgba(148, 120, 220, 0.45);
    border-radius: 14px;
    box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
}

.mulligan-raster-alert {
    margin: 0;
    color: #f3ecff;
    font-size: clamp(0.95rem, 2.4vmin, 1.15rem);
    line-height: 1.5;
}

.mulligan-raster-return {
    min-height: 44px;
    padding: 0.6rem 1.6rem;
    font: inherit;
    font-weight: 700;
    color: #1a1330;
    background: linear-gradient(180deg, #f4d98b, #e0b452);
    border: none;
    border-radius: 10px;
    cursor: pointer;
    transition: transform 0.12s ease, filter 0.12s ease;
}

.mulligan-raster-return:hover {
    filter: brightness(1.06);
    transform: translateY(-1px);
}

.mulligan-raster-return:active {
    transform: translateY(0);
}

/* Graceful dissolve on Keep Hand — fades out to reveal the battlefield behind
   (replaces the old mistimed black battle veil). .active keeps it laid out
   during the fade; JS drops both classes when it finishes. */
#mulligan-overlay.mulligan-leaving {
    animation: mulliganFadeOut 0.38s ease-in forwards;
    pointer-events: none;
}

@keyframes mulliganFadeIn {
    from {
        opacity: 0;
    }

    to {
        opacity: 1;
    }
}

@keyframes mulliganFadeOut {
    from {
        opacity: 1;
    }

    to {
        opacity: 0;
    }
}

/* Mulligan Header */
.mulligan-header {
    text-align: center;
    /* 4 units left the two tutorial CLICK pills sitting on the subtitle's second
       line: 2.6px of ink over the descenders at 1400x640, 4.7px at 1920x1080,
       3.5px at 1366x768. The pills are anchored above the cards, so widening the
       gap under the header moves them down while the text stays put. Measured,
       the overlap is 0.41-0.46 of a unit at every desktop size — it scales with
       the unit, so the clearance is a unit too, not a pixel.
       NOT sufficient at a landscape phone page box, where the subtitle wraps to
       three lines and the pill is drawn 42px ABOVE the card, landing inside the
       header: 10-12px of overlap remains there, in both WebKit and Chromium.
       That needs the cue layer to clamp against text, not a larger gap. */
    margin-bottom: calc(4.75 * var(--mulligan-unit));
}

.mulligan-header h2 {
    font-size: calc(5 * var(--mulligan-unit));
    color: #e2b714;
    text-shadow:
        0 0 calc(2.5 * var(--mulligan-unit)) rgba(226, 183, 20, 0.5),
        0 calc(0.25 * var(--mulligan-unit)) calc(0.5 * var(--mulligan-unit)) rgba(0, 0, 0, 0.5);
    margin-bottom: var(--mulligan-unit);
    font-family: 'Cinzel', 'Georgia', serif;
    letter-spacing: calc(0.3 * var(--mulligan-unit));
    text-transform: uppercase;
    background: linear-gradient(180deg, #ffd700 0%, #e2b714 50%, #c9a012 100%);
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    background-clip: text;
}

.mulligan-header p {
    font-size: calc(2.2 * var(--mulligan-unit));
    color: rgba(255, 255, 255, 0.8);
    max-width: calc(62.5 * var(--mulligan-unit));
    line-height: 1.5;
    margin: 0 auto;
    text-align: center;
}

/* Cards Container — overflow stays visible for the resting fan and selection glow.
   One formula owns the visible gutter: 4.5 * unit - 20px reproduces the
   established desktop spacing (the old column-gap + wrapper margins + the
   hand-fan card margin this row used to inherit), and the 12px floor keeps
   phone cards from touching as vmin shrinks. */
.mulligan-cards {
    display: flex;
    row-gap: calc(4 * var(--mulligan-unit));
    column-gap: max(calc(4.5 * var(--mulligan-unit) - 20px), 12px);
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
    padding: calc(2 * var(--mulligan-unit));
    max-width: 90vw;
    overflow: visible;
}

/* The hand fan's bare `.card { margin: 0 -10px }` (game-board.css) must not
   collapse the mulligan gutter; the row's column-gap is the only spacer. */
.mulligan-card-wrapper > .card {
    margin: 0;
}

/* Card frames intentionally contain transparent pixels. Give both the resting
   selection card and the body-level hover popup the same opaque physical
   backing so battlefield slots can never bleed through those pixels. This is
   paint-only: card dimensions and fitted text stay intact. */
#mulligan-cards .mulligan-card-wrapper > .card-front,
#mulligan-card-hover-preview.mulligan-hover-preview > .card-front {
    background-color: rgb(4, 6, 9);
}

/* The wrapper is only the stable source hit target. The original card moves
   into a body-level, physically sized popup for inspection, so no browser ever
   stretches the resting Mulligan raster. */
.mulligan-card-wrapper {
    position: relative;
    flex: 0 0 auto;
    margin-inline: 0;
    cursor: pointer;
    transition: filter 0.3s ease;
    z-index: 1;
}

/* The active source remains stationary while its card is in the popup. */
.mulligan-card-wrapper.hover-enlarged {
    z-index: 6000;
    transition: filter 0.3s ease;
}

/* Every engine moves the original card into this body-level popup and assigns
   its final physical dimensions before reveal. */
#mulligan-card-hover-preview.mulligan-hover-preview {
    position: fixed;
    /* Body-level popup: above its 9700 mulligan overlay, below the
       tutorial cue layer (9998) and blocking/system overlays. */
    z-index: 9800 !important;
    transform: none;
    pointer-events: auto;
    cursor: pointer;
    -webkit-filter: none;
    filter: none;
    -webkit-user-select: none;
    user-select: none;
}

#mulligan-card-hover-preview.mulligan-hover-preview .card {
    margin: 0;
    pointer-events: none;
    transition: none;
}

/* Keep hovered wrapper above siblings even before the delay fires */
.mulligan-card-wrapper:hover {
    z-index: 5999;
}

/* Subtle card surface effects during hover */
.mulligan-card-wrapper .card.hover-active {
    transition: box-shadow 0.2s ease;
}


/* Disabled cards in tutorial mode stay physically opaque. Muting uses filters
   only; ancestor opacity would blend the entire card with battlefield layers. */
.mulligan-card-wrapper.tutorial-disabled {
    cursor: default;
    pointer-events: none;
    filter: grayscale(60%) brightness(0.7);
}

.mulligan-card-wrapper.tutorial-disabled:hover {
    transform: none;
}

/* Forced select card in tutorial — moonlight-gold breathing glow.
   No transform pulses: scaling cards reads as jank, the glow breathes
   instead (same language as the tutorial cue rings). Only while the card
   is still unselected — once selected the red ✕ styling takes over. */
.mulligan-card-wrapper.tutorial-forced-select:not(.selected)::before {
    border-color: rgba(255, 219, 140, 0.95) !important;
    animation: mulligan-forced-glow 1.8s ease-in-out infinite;
}

@keyframes mulligan-forced-glow {

    0%,
    100% {
        box-shadow:
            0 0 1.2vmin 0.25vmin rgba(255, 215, 130, 0.4),
            0 0 3vmin 0.6vmin rgba(124, 90, 255, 0.22);
    }

    50% {
        box-shadow:
            0 0 2vmin 0.5vmin rgba(255, 220, 140, 0.75),
            0 0 4.6vmin 1vmin rgba(124, 90, 255, 0.42);
    }
}

@media (prefers-reduced-motion: reduce) {
    .mulligan-card-wrapper.tutorial-forced-select:not(.selected)::before {
        animation: none;
        box-shadow:
            0 0 2vmin 0.5vmin rgba(255, 220, 140, 0.75),
            0 0 4.6vmin 1vmin rgba(124, 90, 255, 0.42) !important;
    }
}

.mulligan-card-wrapper.selected {
    filter: brightness(0.6);
}

.mulligan-selection-mark {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: calc(8 * var(--mulligan-unit));
    font-weight: 800;
    line-height: 1;
    color: #ff4444;
    text-shadow: 0 0 calc(1.25 * var(--mulligan-unit)) rgba(255, 0, 0, 0.8);
    pointer-events: none;
    z-index: 10000;
    visibility: hidden;
    opacity: 0;
}

.mulligan-card-wrapper.selected .mulligan-selection-mark {
    visibility: visible;
    opacity: 1;
}

/* Selection indicator */
.mulligan-card-wrapper::before {
    content: '';
    position: absolute;
    top: calc(-0.6 * var(--mulligan-unit));
    left: calc(-0.6 * var(--mulligan-unit));
    right: calc(-0.6 * var(--mulligan-unit));
    bottom: calc(-0.6 * var(--mulligan-unit));
    border-radius: calc(1.5 * var(--mulligan-unit));
    background: transparent;
    border: calc(0.3 * var(--mulligan-unit)) solid transparent;
    transition: border-color 0.3s ease, box-shadow 0.3s ease;
    pointer-events: none;
    z-index: 5;
}

.mulligan-card-wrapper:not(.selected):hover::before {
    border-color: rgba(226, 183, 20, 0.5);
    box-shadow: 0 0 calc(1.9 * var(--mulligan-unit)) rgba(226, 183, 20, 0.3);
}

.mulligan-card-wrapper.selected::before {
    border-color: #ff4444;
    box-shadow: 0 0 calc(1.9 * var(--mulligan-unit)) rgba(255, 68, 68, 0.5);
}

/* Status Section */
.mulligan-status {
    margin-top: calc(3 * var(--mulligan-unit));
    text-align: center;
}

.mulligan-status .opponent-status {
    font-size: calc(2 * var(--mulligan-unit));
    color: rgba(255, 255, 255, 0.7);
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--mulligan-unit);
}

.mulligan-status .opponent-status.ready {
    color: #44ff44;
}

.mulligan-status .opponent-status .spinner {
    width: calc(2 * var(--mulligan-unit));
    height: calc(2 * var(--mulligan-unit));
    border: calc(0.25 * var(--mulligan-unit)) solid rgba(255, 255, 255, 0.3);
    border-top-color: #e2b714;
    border-radius: 50%;
    animation: mulliganSpin 1s linear infinite;
}

@keyframes mulliganSpin {
    to {
        transform: rotate(360deg);
    }
}

/* Buttons Container */
.mulligan-buttons {
    display: flex;
    gap: calc(3 * var(--mulligan-unit));
    margin-top: calc(4 * var(--mulligan-unit));
}

/* Enlarged cards physically overlap this control at short desktop heights.
   Suppress only its paint while the card grows and shrinks; visibility keeps
   the flex geometry fixed, so hover never moves the control or its siblings. */
#mulligan-overlay.mulligan-card-inspection-active .mulligan-buttons {
    visibility: hidden;
    pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
    #mulligan-overlay.mulligan-leaving {
        animation: none;
        opacity: 0;
    }

    /* The controls still arrive with the hand; they just stop being sequenced. */
    #mulligan-overlay.active:not(.mulligan-raster-staging) .mulligan-status,
    #mulligan-overlay.active:not(.mulligan-raster-staging) .mulligan-buttons {
        animation: none;
    }

    .mulligan-card-wrapper,
    .mulligan-card-wrapper.hover-enlarged {
        transition: none;
    }
}

/* The source wrapper keeps the row stable while its exact card node is inspected. */

.mulligan-btn {
    /* Floors, not raw vmin. `--mulligan-unit` is 1vmin, so on a 288pt landscape
       page box 2.2 units is 6.3px — a primary action the player cannot read.
       vmin still drives the growth on a big screen; the floor only decides what
       happens when there is no height to scale from. */
    padding: max(10px, calc(2 * var(--mulligan-unit))) max(16px, calc(5 * var(--mulligan-unit)));
    font-size: max(14px, calc(2.2 * var(--mulligan-unit)));
    min-height: var(--mf-touch, 44px);
    font-weight: 600;
    border: none;
    border-radius: var(--mulligan-unit);
    cursor: pointer;
    transition: all 0.3s ease;
    font-family: 'Cinzel', 'Georgia', serif;
    text-transform: uppercase;
    letter-spacing: calc(0.125 * var(--mulligan-unit));
}

.mulligan-btn.confirm {
    background: linear-gradient(135deg, #e2b714 0%, #c9a012 50%, #a8850f 100%);
    color: #1a1a2e;
    box-shadow:
        0 4px 15px rgba(226, 183, 20, 0.4),
        inset 0 1px 0 rgba(255, 255, 255, 0.3);
    border: 1px solid rgba(255, 215, 0, 0.3);
    position: relative;
    overflow: hidden;
}

.mulligan-btn.confirm::before {
    content: '';
    position: absolute;
    top: -50%;
    left: -50%;
    width: 200%;
    height: 200%;
    background: linear-gradient(45deg,
            transparent 30%,
            rgba(255, 255, 255, 0.1) 50%,
            transparent 70%);
    animation: shimmer 3s infinite;
}

@keyframes shimmer {
    0% {
        transform: translateX(-100%) rotate(45deg);
    }

    100% {
        transform: translateX(100%) rotate(45deg);
    }
}

.mulligan-btn.confirm:hover {
    background: linear-gradient(135deg, #f0c520 0%, #d9b015 100%);
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(226, 183, 20, 0.6);
}

/* Timer Display */
/* THE SAME COUNTDOWN AS THE TURN TIMER, IN THE SAME SEAT.

   This was bare text — `color: rgba(255,255,255,0.7)`, monospace, nothing else
   — parked in the screen's top-right corner under the chrome menu, where it
   was attached to nothing and read as a debug readout. The owner asked for it
   "slightly more stylish" and in "a slighly lesss awkward place", taking its
   cue from the turn timer, and for the two to be "more unifromized in
   style/look/location".

   SO IT TAKES THE TURN TIMER'S SEAT LITERALLY. `#turn-timer` rides directly
   above End Turn at `--end-turn-right`; this reads the same two variables, so
   a match has exactly ONE place that means "time left" and the countdown does
   not jump across the screen when the mulligan ends and the first turn begins.
   `--turn-timer-anchor-top` is published on the document element by
   audio-settings.js whenever it moves End Turn off its CSS seat, so this
   follows that too, for free.

   THE TWO CANNOT COLLIDE. `#turn-timer` reveals only inside the last 15s of a
   turn (REVEAL_MS in turn-timer.js) and the mulligan resolves before turn one
   exists, so they are never on screen together — proven rather than assumed in
   tests/e2e-playwright/timer-uniformity.spec.js, which drives a real mulligan
   and asserts the turn timer is hidden throughout.

   `margin-right` mirrors the generic `button` margin in main.css for the same
   reason #turn-timer does: End Turn is a real button at the same `right`, and
   its own margin is the whole reason two elements pinned to one edge disagree
   about their centre. */
.mulligan-timer {
    position: absolute;
    right: var(--end-turn-right, 9.26vmin);
    margin-right: clamp(4px, 0.58vmin, 10px);
    top: var(--turn-timer-anchor-top, calc(50% - 4.6vmin));
    transform: translateY(-100%);
    min-width: var(--end-turn-width);
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 0.5vmin;
    padding: 0.7vmin 1.4vmin 0.9vmin;
    border-radius: var(--mf-timer-radius);
    border: 0.19vmin solid var(--mf-timer-border);
    background: var(--mf-timer-bg);
    color: var(--mf-timer-ink);
    font-family: inherit;
    font-variant-numeric: tabular-nums;
    font-size: 2.2vmin;
    font-weight: 700;
    letter-spacing: 0.08vmin;
    line-height: 1.15;
    pointer-events: none;
    text-shadow: 0 0 0.5vmin rgba(0, 0, 0, 0.9);
}

.mulligan-timer-value {
    display: block;
}

/* Depleting bar. --mulligan-timer-progress is 1 at a full budget, 0 at zero —
   the same contract as --turn-timer-progress, set by mulligan.js on the tick. */
.mulligan-timer-bar {
    display: block;
    width: 100%;
    height: 0.5vmin;
    min-height: 3px;
    border-radius: 999px;
    background: var(--mf-timer-track);
    overflow: hidden;
}

.mulligan-timer-bar::after {
    content: '';
    display: block;
    height: 100%;
    width: calc(var(--mulligan-timer-progress, 1) * 100%);
    border-radius: inherit;
    background: var(--mf-timer-fill);
    transition: width 240ms linear;
}

/* Urgency. `warning` and `critical` are the class names mulligan.js already
   sets at 10s and 5s; only their palette moves to the shared tokens, so the
   two countdowns stop signalling the same thing in two different oranges. */
.mulligan-timer.warning {
    border-color: var(--mf-timer-urgent-border);
    color: var(--mf-timer-urgent-ink);
}

.mulligan-timer.warning .mulligan-timer-bar::after {
    background: var(--mf-timer-urgent-fill);
}

.mulligan-timer.critical {
    border-color: var(--mf-timer-critical-border);
    color: var(--mf-timer-critical-ink);
    animation: mulligan-timer-critical 1s ease-in-out infinite;
}

.mulligan-timer.critical .mulligan-timer-bar::after {
    background: var(--mf-timer-critical-fill);
}

@keyframes mulligan-timer-critical {
    0%, 100% { box-shadow: 0 0 0 rgba(255, 120, 120, 0); }
    50% { box-shadow: 0 0 1.6vmin rgba(255, 120, 120, 0.5); }
}

/* Responsive adjustments */
@media (max-width: 768px) {
    .mulligan-header h2 {
        font-size: 1.8rem;
    }

    .mulligan-header p {
        font-size: 0.95rem;
        padding: 0 1rem;
    }

    .mulligan-buttons {
        flex-direction: column;
        gap: 1rem;
    }

    .mulligan-btn {
        padding: 0.8rem 2rem;
        font-size: 1rem;
    }
}

/* Phone-landscape battle: the mulligan must fit a 390px-class height —
   compact header, card row driven by the --card-unit floor, 48px confirm. */
@media (pointer: coarse) and (orientation: landscape) and (max-height: 520px) {
    .mulligan-header h2 {
        font-size: clamp(16px, 4.5vmin, 24px);
    }

    .mulligan-header p {
        font-size: clamp(12px, 3vmin, 15px);
    }

    #mulligan-confirm-btn {
        min-height: 48px;
        padding: 10px 22px;
        padding-bottom: max(10px, env(safe-area-inset-bottom, 0px));
        /* "Redraw button text in mulligan is too small. Rename to just Redraw
           and make text and possibly button bigger." The box already met the
           tap floor; the LABEL inside it was still at the body size it
           inherited, which is what made the control read as small. */
        font-size: clamp(15px, 4vmin, 19px);
        font-weight: 700;
        letter-spacing: 0.04em;
        min-width: min(200px, 46vw);
    }
}

/* Coarse pointers (touch): no backdrop blur over the live board. The mulligan
   veil covers the entire animated battlefield, so its blur repaints the whole
   viewport every frame — the biggest GPU paint cost on phones. Swap to a
   visually-matched darker veil instead (0.42 + blur(2px) → 0.6 solid).
   Contract: tests/unit/styles/coarseBackdropSwap.test.js. */
@media (pointer: coarse) {
    #mulligan-overlay {
        background: rgba(8, 12, 18, 0.6);
        -webkit-backdrop-filter: none;
        backdrop-filter: none;
    }
}

/* The mulligan card used to pick up `z-index: 5` from an UNSCOPED `.card` rule
   in game-board.css. Scoping that rule to the battle view (where it belongs)
   exposed the dependency: without it the card no longer stacked above the
   tutorial battlefield behind the overlay. Declare it here, where the mulligan
   surface owns its own layering, instead of inheriting a battle-board accident.
   Locked by guest-tutorial.spec.js "mulligan cards remain fully opaque over the
   tutorial battlefield". */
#mulligan-overlay .card {
    position: relative;
    z-index: 5;
}



/* "In mulligan the opponent-is-ready text is too small" — same coarse phone
   tier as the rest of the mulligan chrome; big text or no text. */
@media (pointer: coarse) and (orientation: landscape) and (max-height: 520px) {
  .mulligan-status,
  .mulligan-status .opponent-status {
    font-size: clamp(14px, 3.6vmin, 17px);
    line-height: 1.25;
  }
}
