/* base.css — deep slate table, layout grid, global chrome */

:root {
  --table-1: #2a3442;
  --table-2: #1a222e;
  --table-3: #0e131b;
  --gold: #c9a86a;
  --ink: #e8e0cd;
  --line: rgba(201, 168, 106, 0.22);
  --panel: rgba(10, 15, 22, 0.55);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

html,
body {
  height: 100%;
  overflow: hidden;
  overscroll-behavior: none;
}

body {
  font-family: Georgia, 'Times New Roman', serif;
  background: #0e131b;
  color: var(--ink);
  user-select: none;
  -webkit-user-select: none;
}

/* ---------- table layout ---------- */

#table {
  /* absolute, not fixed: a fixed element is its own stacking context, which
     would trap #opp-hand's z-index (and #initiative-bar's) below #card-layer —
     docked arcanes could then never lose the paint race to the hand. The page
     never scrolls (html/body overflow hidden), so absolute is identical. */
  position: absolute;
  inset: 0;
  display: grid;
  /* Both player strips are the same height (130px): the bottom row's hand
     keeps its full-size cards and rides up over the battleground, exactly the
     way the opponent's fan rides in its header. */
  grid-template-rows: 46px 130px 1fr 130px;
  background: radial-gradient(
    ellipse 120% 90% at 50% 30%,
    var(--table-1) 0%,
    var(--table-2) 55%,
    var(--table-3) 100%
  );
  box-shadow: inset 0 0 180px rgba(0, 0, 0, 0.55);
}

#opp-row {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 28px;
  border-bottom: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.14);
}

#opp-hand {
  flex: 1;
  height: 100%;
  display: flex;
  align-items: center;
  /* Anchor the face-down fan at the LIFE-side (left) edge instead of
     centering it in the zone — the player's hand is a left-anchored spring
     fan, so centering let the opponent's fan drift right and open a gap
     beside their life. flex-start parks the cluster next to the life total
     (the row's padding + a small gutter read between them), exactly the
     way the player's hand sits beside their own arcane dock. When the pile
     tray opens and narrows the zone the fan simply stays left-anchored. */
  justify-content: flex-start;
  padding-left: 10px;
  /* The dock is out of the flow (see #opp-arcane-dock) — this margin restores
     its flow slot so the hand zone keeps its exact rest width and the fan
     stays centered where it has always been. When the pile tray opens, the
     tray's growth narrows the hand zone and the fan yields left — the same
     room-making the player's hand does. */
  margin-right: 620px;
  /* The hand ALWAYS paints over the dock: docked arcanes are CardViews in
     #card-layer (z 10), so any peel or overflow that reaches the header
     loses to the hand — the same rule HandView's z >= 130 floor enforces on
     the player's side. Still below #initiative-bar (z 20). */
  position: relative;
  z-index: 15;
}
#opp-hand .card {
  width: 103px;
  height: 145px;
  flex: none;
  pointer-events: none;
}
#opp-hand .card + .card {
  margin-left: -72px;
}

/* The DRAGGED card is the topmost thing on the table (never regress — the
   reported "dragged cards render under the opponent's hand backs" bug):
   #opp-hand sits at z 15, ABOVE #card-layer (z 10), because docked arcanes
   and peeled tucked copies must always lose the paint race to the hand —
   but the card YOU are dragging is also a #card-layer child, so its local
   z (1000) could never beat its own parent layer and it slid beneath the
   opponent's face-down backs on its way up the table. While a drag is
   live (body.is-dragging — stamped by DragController on gesture start and
   removed on finish/cancel), the opponent hand drops to z 9, one step BELOW
   the card layer: the dragged card glides over everything static. The
   initiative bar (20), prompt bar (400) and drag guides (1100) keep their
   places, and the resting table is untouched — the rule only exists
   mid-gesture. */
body.is-dragging #opp-hand {
  z-index: 9;
}

/* ---------- arcane docks (tucked duplicate stacks next to each hand) ------ */

#arcane-dock {
  position: relative;
  align-self: stretch;
  width: 620px;    /* tucked stacks + their used peel-outs, beside the hand.
                      Wide enough that 5 distinct groups (or 4 all-used
                      singles) fit with real felt — the row must never rely
                      on overlap to fit (see Animator._layoutArcaneDock). */
  flex-shrink: 0;
}

#opp-arcane-dock {
  /* OUT OF THE FLOW, right-anchored. In-flow, the dock sat between the flex
     hand and the pile tray — and an in-flow item between a flex remainder
     (the hand, flex-basis 0) and a growing item ALWAYS translates: opening
     the tray dragged the whole box, every docked arcane with it, ~198px left
     regardless of how few arcanes there are (the reported "violently shifts
     left" bug). The shrink phase can never route the growth into the dock
     (the hand's basis-0 slack never creates a base deficit), so the only
     escape is out of the flow. Right-anchoring makes that position
     viewport-independent: the offset is the row's padding (28) plus the
     piles' CLOSED footprint (padding 8 + deck 90 + gap 20 + tray 126 +
     padding 8) — all documented constants — so the dock's right edge lands
     exactly on the piles' closed left edge and its LEFT edge (where the
     arcane row anchors: Animator._layoutArcaneDock walks right from D.left)
     never moves, at any window size. The tray's growth now narrows the hand
     zone instead (the opponent's fan yields, same as the player's), and the
     pile cluster slides left over the dock's EMPTY tail; _layoutArcaneDock
     reserves that tail while the piles intrude (BattlegroundView.dockReserve,
     wired in main.js) so no arcane ever sits under the slid-out piles. */
  position: absolute;
  top: 0;
  bottom: 0;
  right: calc(28px + 8px + 90px + 20px + 126px + 8px);
  width: 620px;    /* same width as #arcane-dock — symmetric queue spacing */
}

#mid-row {
  display: grid;
  grid-template-rows: 48% 52%;
}

#opp-battleground {
  position: relative;
  border-bottom: 1px dashed rgba(201, 168, 106, 0.16);
}

#battleground {
  position: relative;
  transition: box-shadow 0.15s ease, background-color 0.15s ease;
}

/* ---------- battleground horizontal pan (overflow only) ----------
   Permanents never cover each other, so when a no-overlap row outgrows the
   zone the content slides sideways instead of compressing. The chevrons and
   edge fades only exist while .bf-pannable is set (content wider than the
   zone); the fade on a clipped edge reads "more board this way", and the
   active-edge chevron pans a page (snapped to whole card slots). */
#opp-battleground { overflow: hidden; }
#battleground { overflow: hidden; }

.bf-fade {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 46px;
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.2s ease;
  z-index: 6;
}
.bf-fade--left  { left: 0;  background: linear-gradient(90deg, rgba(8, 10, 14, 0.55), transparent); }
.bf-fade--right { right: 0; background: linear-gradient(270deg, rgba(8, 10, 14, 0.55), transparent); }
.bf-pannable:not(.bf-at-left) .bf-fade--left  { opacity: 1; }
.bf-pannable:not(.bf-at-right) .bf-fade--right { opacity: 1; }

.bf-pan {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 26px;
  height: 52px;
  display: none;
  align-items: center;
  justify-content: center;
  font-size: 22px;
  line-height: 1;
  color: #efe6c8;
  background: linear-gradient(180deg, rgba(42, 36, 24, 0.92), rgba(22, 17, 10, 0.92));
  border: 1px solid rgba(201, 168, 106, 0.5);
  border-radius: 9px;
  cursor: pointer;
  z-index: 7;
  padding: 0;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
}
.bf-pan:hover { filter: brightness(1.25); border-color: rgba(255, 224, 150, 0.85); }
.bf-pan:active { transform: translateY(-50%) scale(0.94); }
.bf-pan--left  { left: 6px; }
.bf-pan--right { right: 6px; }
.bf-pannable:not(.bf-at-left) .bf-pan--left   { display: flex; }
.bf-pannable:not(.bf-at-right) .bf-pan--right { display: flex; }

#player-row {
  position: relative;
  display: flex;
  align-items: stretch;
  padding: 0 20px;
  border-top: 1px solid var(--line);
  background: rgba(0, 0, 0, 0.16);
}

#hand-zone {
  position: relative;
  flex: 1;
  border-radius: 12px;
  transition: box-shadow 0.15s ease, background-color 0.15s ease;
}

#piles {
  display: flex;
  align-items: center;
  gap: 20px;
  padding: 0 10px;
}

/* ---------- card layer ---------- */

/* Every interactive card lives here, in viewport coordinates, so dragging
   across zones never reparents DOM and never triggers layout. The layer
   itself is click-through; cards opt back in. */
#card-layer {
  position: fixed;
  inset: 0;
  z-index: 10;
  pointer-events: none;
}
#card-layer .card {
  pointer-events: auto;
}

/* ---------- labels, hints, misc ---------- */

.zone-label {
  position: absolute;
  top: 6px;
  left: 12px;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  opacity: 0.32;
  pointer-events: none;
}

body.is-dragging,
body.is-dragging .card {
  cursor: grabbing;
}
