/* Sized to the table rather than to the card: at full size the far Active runs off the top and
   loses its name. Both sides take the same size so the halves stay mirrored. */
.battle-screen .card-face--battle {
  --blokemon-card-scale: 0.215;

  @media (max-width: 720px) {
    --blokemon-card-scale: 0.128;
  }
}

/*
  A hold must not raise the browser's selection or callout, and a drag must still scroll. Nor may
  it wash the card in Android's tap colour: that is painted over the whole of whatever was pressed
  and stays for as long as the press does, so a card being held to be read was being held under a
  blue sheet. The card answers a press by coming up, which is the only answer it needs.
*/
.field-card-button,
.hand-card,
.tray-card,
.card-press-surface {
  padding: 0;
  border: 0;
  color: inherit;
  background: transparent;
  touch-action: pan-x pan-y;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/*
  A hold answers from the first frame. The card starts coming up the moment it is pressed, so the
  wait before the viewer is the card being lifted rather than nothing happening, and the viewer
  arrives as the end of a movement already under way.

  Weighted to the end of the hold: a tap is over long before the card has visibly moved, so the
  gesture a player makes most often still looks like a tap and not like a card that flinched.
  Only scale and translate, which compose with the fan each card is already turned by and cost
  the compositor nothing to run.
*/
.card-press-surface.is-holding,
.attached-card.is-holding {
  animation: card-holding 400ms cubic-bezier(0.55, 0, 0.9, 0.35) both;
}

.card-press-surface,
.attached-card {
  transition: scale 0.16s ease-out, translate 0.16s ease-out;
}

.field-card-button {
  position: relative;
  z-index: 1;
  border-radius: 10px;
  transition: filter 0.2s;
}

/* The press surface is one control and cannot be two, so each readable card - the host and every
   attachment - gets its own, shown only once the card is engaged. */
.card-press {
  position: relative;
}

/* The press surface keeps the card's own box, so nothing about the card's place has moved. */
.card-press-surface {
  display: block;
  border-radius: inherit;
}

/* An engaged card comes forward, so its reading controls are not painted over by its neighbours. */
.card-press:hover,
.card-press:focus-within {
  z-index: 90;
}

.card-reading {
  position: absolute;
  z-index: 90;
  top: calc(100% + 4px);
  left: 50%;
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
  /* Measured by its contents, not by the card: card names are wider than the card. */
  width: max-content;
  max-width: 240px;
  opacity: 0;
  pointer-events: none;
  transform: translateX(-50%);
}

.card-press:hover > .card-reading,
.card-press:focus-within > .card-reading {
  opacity: 1;
  pointer-events: auto;
}

.card-read {
  display: flex;
  align-items: center;
  gap: 4px;
  min-height: 22px;
  padding: 3px 8px 3px 6px;
  border: 1px solid #6f7a55;
  border-radius: 100px;
  color: #f2f5e6;
  background: #10130ef2;
  box-shadow: 0 4px 12px #000a;
  cursor: pointer;
  white-space: nowrap;
  font: 700 10px "Jost", sans-serif;
}

.card-read:hover {
  border-color: var(--gold);
}

/* A lens, drawn rather than written, so the control shows what it does without saying it. */
.card-read-glyph {
  position: relative;
  flex: 0 0 auto;
  width: 9px;
  height: 9px;
  border: 1.5px solid currentcolor;
  border-radius: 50%;
}

.card-read-glyph::after {
  content: "";
  position: absolute;
  top: 5px;
  left: 5px;
  width: 4px;
  height: 1.5px;
  border-radius: 1px;
  background: currentcolor;
  transform: rotate(45deg);
  transform-origin: left center;
}

/* The aura IS the instruction: actionable cards breathe, the chosen one holds and lifts, and
   the places it can go glow for it. Nothing flashes or steps. A card outside the aura is
   darkened, never seen through: it stays a solid card, only not one in play right now. */
.battlefield.is-choosing .field-card-button:not(.is-aura, .is-target) {
  filter: brightness(0.46) saturate(0.6);
}

.is-aura,
.is-target {
  z-index: 20;
  cursor: pointer;
}

.field-card-button.is-aura-selected .battle-card-shell {
  transform: translateY(-6px) scale(1.05);
}

/* The target the pointer is on comes up to meet the card, the way the chosen card comes up. */
.field-card-button.is-target:hover .battle-card-shell,
.field-card-button.is-target[data-drop-over] .battle-card-shell {
  transform: translateY(-6px) scale(1.05);
}

/*
  A card being carried. It is moved by a translate the browser writes, on top of whatever the fan
  or the table already turned it by, and nothing here may ease that: a card that eased after the
  pointer would trail it. It rises over everything in its own zone, and is not itself a place
  anything can land on - the pointer is always over it.
*/
.card-press[data-dragging],
.card-press[data-springing] {
  z-index: 95;
}

.card-press-surface[data-dragging] {
  cursor: grabbing;
  transition: none;
}

/* A card that can be carried is not a card to scroll with: the table fits the screen it has, so
   there is nothing for a finger on one to scroll. */
.card-press[data-drag],
.card-press[data-drag] > .card-press-surface {
  touch-action: none;
}

.aura-counter {
  position: absolute;
  z-index: 12;
  top: -9px;
  left: -9px;
  min-width: 26px;
  height: 26px;
  display: grid;
  place-items: center;
  padding: 0 5px;
  border: 2px solid #dff0ff;
  border-radius: 100px;
  color: #10130e;
  background: white;
  box-shadow: 0 3px 10px #0009;
  font: 700 12px "Jost", sans-serif;
}

/* The row never clips: a benched card's corona has to read whole, the same as anywhere else. */
.bench-row {
  position: relative;
  z-index: 4;
  grid-column: 2;
  display: flex;
  align-items: end;
  justify-content: center;
  max-width: 100%;
  gap: 8px;
  padding: 8px;
  overflow: visible;

  /* Five fixed positions, always all five - no scrolling. */
  @media (max-width: 720px) {
    grid-column: 1;
    display: grid;
    grid-template-columns: repeat(5, 50px);
    justify-content: center;
    justify-items: center;
    gap: 2px;
    padding: 3px 10px;
    overflow: visible;
  }
}

.bench-slot {
  flex: 0 0 98px;
  width: 98px;
  height: 137px;
  border: 1px dashed rgb(156 164 128 / 23%);
  border-radius: 7px;

  @media (max-width: 720px) {
    flex: none;
    width: 50px;
    height: 70px;
  }
}

/* An empty Bench position only becomes a control while it is a legal destination. */
button.bench-slot {
  display: grid;
  place-items: center;
  padding: 0;
  color: #10130e;
  background: rgb(255 255 255 / 12%);
  cursor: pointer;
}

/* An empty position glows the way a target card does: the same rim, the same revolving corona,
   in the table's gold, and it brightens under the card being carried to it. */
button.bench-slot.is-target,
button.empty-slot.is-target,
button.local-slot-empty.is-target {
  position: relative;
  border: 2px solid rgb(246 221 160 / 90%);
  box-shadow:
    0 0 4px rgb(244 189 63 / 55%),
    0 0 10px rgb(244 189 63 / 28%) inset;
}

button.bench-slot.is-target[data-drop-over],
button.bench-slot.is-target:hover,
button.empty-slot.is-target[data-drop-over],
button.empty-slot.is-target:hover,
.local-slot.is-target[data-drop-over] button.local-slot-empty,
button.local-slot-empty.is-target:hover {
  border-color: rgb(255 244 214 / 100%);
  box-shadow:
    0 0 6px rgb(244 189 63 / 85%),
    0 0 14px rgb(244 189 63 / 45%) inset;
}

button.bench-slot span {
  color: white;
  font: 700 10px "Jost", sans-serif;
  text-transform: uppercase;
  letter-spacing: 0.14em;
}

.battle-card-shell {
  position: relative;
  width: max-content;
  /* REQUIRED by the fan's z-index: -1 below. Without a stacking context here that negative order
     is measured against the page and puts the fan behind the table entirely. */
  isolation: isolate;
  transition: transform 0.18s, filter 0.18s;
}

.battle-card-shell.is-selected {
  filter: drop-shadow(0 0 10px rgb(244 189 63 / 70%));
  transform: translateY(-3px);
}

.damage-badge {
  position: absolute;
  z-index: 10;
  top: 13px;
  right: -16px;
  width: 50px;
  height: 50px;
  display: grid;
  place-items: center;
  border: 3px solid #f6d9c9;
  border-radius: 50%;
  color: white;
  background: var(--danger);
  box-shadow: 0 6px 16px #0008;
  font: 700 16px "Jost", sans-serif;

  @media (max-width: 720px) {
    top: 8px;
    right: -11px;
    width: 38px;
    height: 38px;
    border-width: 2px;
    font-size: 12px;
  }
}

.hp-badge,
.energy-badge {
  position: absolute;
  z-index: 10;
  bottom: -8px;
  padding: 4px 7px;
  border: 1px solid #696349;
  border-radius: 100px;
  color: var(--ink);
  background: #0b0d09ed;
  font-size: 10px;
  white-space: nowrap;
}

.hp-badge {
  right: 3px;

  @media (max-width: 720px) {
    right: -3px;
    font-size: 8px;
  }
}

/* The fan says which Energy; this says how much, which is what decides affordability. */
.energy-badge {
  left: 3px;

  @media (max-width: 720px) {
    left: -3px;
    font-size: 8px;
  }
}

.is-compact .damage-badge {
  top: 2px;
  right: -7px;
  width: 28px;
  height: 28px;
  border-width: 2px;
  font-size: 9px;

  /* A benched card is small enough that its damage counter has to be smaller too. */
  @media (max-width: 720px) {
    top: 2px;
    right: -6px;
    width: 24px;
    height: 24px;
    font-size: 9px;
  }
}

.is-compact .hp-badge {
  display: none;
}

/* Kept on the Bench where the HP pill is dropped: the fan is at its smallest here, so this is
   the only place the count can be read. */
.is-compact .energy-badge {
  left: 0;
  bottom: -6px;
  padding: 2px 5px;
  font-size: 8px;

  /* 50px of card: give up the padding, never the number. */
  @media (max-width: 720px) {
    left: -4px;
    bottom: -5px;
    padding: 1px 4px;
    font-size: 7px;
  }
}

/* Pressed through the host's surface, so they need the same callout and selection guards. */
.attached-card {
  flex: 0 0 auto;
  touch-action: pan-x pan-y;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}

/*
  The Energy fan: each face steps left and back by a FRACTION of a face, so every one shows an
  edge - stepped by a whole face the fan shows only its front card.

  The reach is fixed and the spacing gives, so the fan stops widening at four faces and compresses
  after that rather than crossing the table. A compact card restates only the spacing.
*/
.attached-energy {
  /* The printed face is 750 wide, so a face in this fan is that times the scale it is drawn at.
     Declared here because the tuck is measured against it and the scale lives on the child. */
  --energy-fan-card: calc(750px * 0.055);
  --energy-fan-spread: 16px;
  /* Three steps, so the fan is at its widest at four faces and everything after that closes the
     spacing up rather than reaching further across the table. */
  --energy-fan-reach: calc(var(--energy-fan-spread) * 3);
  --energy-fan-step: min(
    var(--energy-fan-spread),
    var(--energy-fan-reach) / max(1, var(--energy-fan-count, 1) - 1)
  );
  /* Derived, not fixed: the first gap has to be one step like every other, or the leading face
     shows about twice what the ones behind it do. */
  --energy-fan-tuck: calc(var(--energy-fan-card) - var(--energy-fan-step));
  position: absolute;
  z-index: -1;
  right: calc(100% - var(--energy-fan-tuck));
  bottom: 16px;
  height: 0;

  /* The same fan against a card roughly half the size. */
  @media (max-width: 720px) {
    --energy-fan-step: 12px;
    --energy-fan-tuck: 12px;
    bottom: 10px;
  }
}

/* Back to front, so the face nearest the host paints last and lies over the rest. */
.attached-energy .attached-card {
  position: absolute;
  right: calc(var(--fan-depth, 0) * var(--energy-fan-step));
  bottom: 0;
  filter: drop-shadow(0 4px 5px rgb(0 0 0 / 65%));
}

.is-compact .attached-energy {
  --energy-fan-card: calc(750px * 0.035);
  --energy-fan-spread: 9px;
  bottom: 11px;

  @media (max-width: 720px) {
    --energy-fan-step: 6px;
    --energy-fan-tuck: 5px;
    bottom: 6px;
  }
}

.is-compact .attached-energy .card-face-host {
  --blokemon-card-scale: 0.035;

  @media (max-width: 720px) {
    --blokemon-card-scale: 0.026;
  }
}

.attached-tools {
  position: absolute;
  z-index: 9;
  right: -22px;
  bottom: 18px;
  display: flex;
}

.attached-tools .card-face-host {
  filter: drop-shadow(0 4px 6px rgb(0 0 0 / 75%));
}

.is-compact .attached-tools {
  right: -12px;
  bottom: 5px;
}

.is-compact .attached-tools .card-face-host {
  --blokemon-card-scale: 0.035;
}

.condition-row {
  position: absolute;
  z-index: 12;
  top: -7px;
  left: 50%;
  display: flex;
  gap: 3px;
  transform: translateX(-50%);
}

.condition-row span {
  padding: 3px 6px;
  border: 1px solid #a65f7b;
  border-radius: 100px;
  color: #ffd6e5;
  background: #351a26;
  font-size: 8px;
  white-space: nowrap;
}
