/* Positioning for the combat overlay, and nothing else. Every look here comes from another
   sheet: the plate from hud.css's world layer, .gs-bar--target, .gs-bar--thin and .gs-damage from
   gs.css. The rules below only say where a thing sits, which is what neither of them owns.
   These elements live in .hud-plates, which is never HUD-scaled: main.ts places them at raw
   toScreen() pixels. */

.cb-plate,
.cb-float {
  position: absolute;
  pointer-events: none;
}

.cb-plate { transform: translate(-50%, -100%); }
/* The death clip ends on an empty frame, so a corpse has no body left to label. The plate goes
   with it - the M03 UI section says a plate is hidden when its body dies. */
.cb-plate.cb-dead { display: none; }
/* Health, under the name. It moves when a blow lands and not otherwise, so the transition is the
   whole of the drain animation - the number itself arrives in one step from the server.

   ONE width for every body in the fight, and centred under whatever width the name happens to
   need. The plates themselves are `width: auto` (see .hud-plates .gs-plate in hud.css) so a long
   name never wraps - but letting the bar inherit that made a health bar a readout of name length:
   a Noisy Cactus wore a wider bar than a Rogue Bear, and a full bar on one body was a different
   number of pixels from a full bar on the next. 92px is .gs-plate's own declared width, which is
   what the plate would be if long names had not forced auto onto it.

   A boss is the exception, and it is a flag on the wire (Fighter.boss), never a guess from the
   name or the scale: it wears a wider bar, which is most of what makes it read as a boss at a
   glance rather than as one more body in the rank. Wider, but still FIXED - 1.5x the standard.
   Leaving a boss on auto would have kept the one thing this rule exists to remove: a bar whose
   length is a fact about its name. No fighter's bar follows its name, boss included. */
.cb-plate .cb-hp { margin-top: 2px; width: 92px; margin-inline: auto; }
.cb-plate.cb-boss .cb-hp { width: 138px; }
.cb-plate .cb-hp .gs-bar__fill { transition: width 180ms ease-out; }
/* A phone's fight stands further back (main.ts PHONE_VIEW_H) and its bodies are half their desktop
   height, but this layer is raw screen px and is never scaled: a 92px bar was wider than two bodies
   side by side. Same one-width rule, a phone's width. `.gs-bar` in the height selector because
   hud.css's `.gs-plate .gs-bar` loads after this sheet. */
@media (hover: none) and (pointer: coarse) {
  .cb-plate .cb-hp { width: 52px; }
  .cb-plate.cb-boss .cb-hp { width: 78px; }
  .cb-plate .gs-bar.cb-hp { height: 4px; }
}

/* The status tickers, under the health bar. Over a BODY, not in a panel - and that is the whole
   difference from the HUD buff strip.
   THE CELLS THEMSELVES ARE DRESSED IN hud.css, beside the strip's, because that file owns the
   `.hud .gs-slot` rules these have to beat and a mark means the same thing in both places. What
   is here is what only a plate has: the row, and its distance from the health bar.

   Wrapping is deliberate: the buff store holds at most one status per category, so the longest row
   is the number of categories, and a second line beats a clipped one. No height until an icon is
   in it, so a body wearing nothing costs the plate nothing. */
.hud .cb-plate .cb-status { display: flex; flex-wrap: wrap; justify-content: center; gap: 3px 4px; }
.hud .cb-plate .cb-status:not(:empty) { margin-top: 4px; }

.hud-plates.cb-swap { opacity: 0; transition: opacity 120ms linear; }

/* The result, modal over everything. It is the click trap as much as the readout: while it is up
   the only thing a click can reach is this, so nothing behind it can be walked to, targeted or
   engaged by a click meant for the banner. */
.cb-veil {
  position: absolute;
  inset: 0;
  pointer-events: auto;
  background: var(--gs-scrim);
  animation: cb-veil-in 200ms linear;
}
/* A defeat is the one result that colours its own veil: a soft red falling top to bottom, dark
   enough at the bottom that the banner still reads over it. */
.cb-veil--loss {
  background: rgba(143, 42, 30, 0.6);
}
@keyframes cb-veil-in { from { opacity: 0; } to { opacity: 1; } }
/* a floating number starts over the plate; the rise is the animation's, not ours */
.cb-float { transform: translate(-50%, 0); }

/* The crit burst sits ON the body rather than over its head, so combat.ts hands it the body's
   projected middle instead of the plate's anchor: `left`/`top` ARE the impact point, and the
   element is a 0x0 point that its spikes radiate out of - nothing here has to centre anything.
   It is prepended to the layer, which is what keeps it behind every number and plate without
   anyone declaring a z-index. Look: .gs-crit-burst in gs.css. */
.cb-crit {
  position: absolute;
  pointer-events: none;
}

/* ------------------------------------------------- M04 SKILL PANEL (S10) */
/* Positioning and the atlas sprite only - the window itself is Stonebevel. */
.sp { position: fixed; left: 50%; top: 12%; transform: translateX(-50%); width: 440px; }
.sp[hidden], .sp-card[hidden] { display: none; }
.sp-grid { position: relative; padding: 8px; display: flex; flex-wrap: wrap; gap: 4px; }
.sp-grid .gs-row { flex: 0 0 calc(50% - 2px); cursor: var(--cur-grab, grab); }
.sp-grid .gs-slot { width: 32px; height: 32px; }
.sp-card { position: fixed; z-index: 90; pointer-events: none; }
/* The opener pin: a row-end toggle, so a skill is marked without leaving the list. Layout only.
   The pinned state is gs.css's own .gs-btn.is-active, which the pin already asked for by name
   before the rule existed - the glyph (filled star vs hollow) now says it twice, which is what
   a toggle wants when it is 20px wide. */
.sp-grid .gs-row { position: relative; }
/* Height and shading come from gs-btn--sm; this is placement and the tighter cap only. */
.sp-pin { position: absolute; right: 4px; top: 50%; transform: translateY(-50%); padding: 0 5px; }

/* --------------------------------------------- M10 BELIEF (TALENTS) TAB (S08) */
/* The two branch boxes only. Everything inside them is Stonebevel already. */
/* .gs-body sets a display, which beats the [hidden] attribute on its own. */
.sp .gs-body[hidden] { display: none; }
.sp--wide { width: 620px; }
.sp-tree { display: flex; gap: 8px; align-items: stretch; }
.sp-branch { flex: 1 1 250px; gap: 6px; }
/* Three lanes, one row per opening gate: a pair sits on the shoulders and a lone node on the
   spine, so the tier ladder reads without drawing a single connector. */
.sp-branch__list { max-height: 440px; display: grid;
  grid-template-columns: repeat(3, 1fr); justify-items: center; align-content: start;
  row-gap: 14px; column-gap: 4px; padding: 6px 2px; }
.sp-node { position: relative; cursor: var(--cur-hand, pointer); display: flex; flex-direction: column;
  align-items: center; gap: 3px; width: 100%; }
.sp-node__name { font-family: var(--gs-face-mono); font-size: var(--gs-size-bar); line-height: 1.2;
  text-align: center; max-width: 76px; color: var(--gs-text-mute); }
.sp-node:hover .sp-node__name { color: var(--gs-gold-head); }
/* An unlearned node steps back: grey art (gs.css) and a muted label, so a glance down the tree
   reads what you own without counting the numbers. */
.sp-node--locked .sp-node__name { color: var(--gs-text-mute); }
/* The rank counter sits in the slot's corner, the way the original stamps it, and carries the
   node's state in its colour: green while there is room to grow, gold once it is capped. */
.sp-node__rank { position: absolute; right: 0; bottom: 0; min-width: 13px; box-sizing: border-box;
  padding: 0 2px; border: 0; border-radius: 0; background: none;
  font-family: var(--gs-face-display); font-size: var(--gs-size-bar); line-height: 1;
  text-align: center; color: var(--gs-gold-bright); box-shadow: none;
  text-shadow:
    1px 1px 0 var(--gs-stamp-outline), -1px 1px 0 var(--gs-stamp-outline),
    1px -1px 0 var(--gs-stamp-outline), -1px -1px 0 var(--gs-stamp-outline); }
.sp-node--locked .sp-node__rank { color: var(--gs-text-mute); }
.sp-node--ready .sp-node__rank { color: var(--moss-300); }
/* No frame in the tree. A skill icon is a full plate with its own rounded edge and its own
   field, so the slot's border, well and bevel drew a second border on top of the picture. The
   art IS the tile here. Nothing is lost: an unlearned node is still greyed (gs.css greys what a
   locked slot HOLDS), the rank counter still carries the colour, and the + still appears only on
   a node the server would actually accept a point for. */
.sp-tree .gs-slot { position: relative; width: 32px; height: 32px;
  border: 0; background: none; box-shadow: none; }
.sp-tree .gs-slot__inner { background: none; }
/* And no rules anywhere else in the tree either: the branch box, the line under its heading and
   the + button all drop their border. The tree is art and labels on the panel, nothing drawn
   around anything. The branch still reads as a group from its own tint and its heading. */
.sp-tree .gs-sub { border: 0; box-shadow: none; }
.sp-tree .gs-section { border-bottom: 0; }
.sp-tree .sp-node__add { border: 0; box-shadow: none; }
/* A plus is an action, not another state colour. It exists only on a server-valid next rank and
   sits outside the icon corner so it never covers the art or the rank counter. */
.sp-node__add {
  appearance: none;
  position: absolute;
  right: -7px;
  top: -7px;
  z-index: 2;
  width: 18px;
  height: 18px;
  padding: 0 0 1px;
  border: var(--gs-border-width) solid var(--gs-border-hard);
  border-radius: 0;
  cursor: var(--cur-hand, pointer);
  display: grid;
  place-items: center;
  background: var(--moss-600);
  box-shadow: var(--gs-raised-thin);
  color: var(--stone-50);
  font: 700 var(--gs-size-label)/1 var(--gs-face-display);
}
/* Hover lightens one stop; press flips the bevel and shifts. Focus is the global inset ring. */
.sp-node__add:hover { background: var(--moss-500); }
.sp-node__add:active { box-shadow: var(--gs-sunken-thin); transform: translate(1px, 1px); }

@media (max-width: 760px) {
  .sp {
    left: max(6px, env(safe-area-inset-left));
    right: max(6px, env(safe-area-inset-right));
    top: max(6px, env(safe-area-inset-top));
    width: auto;
    max-width: none;
    max-height: calc(100dvh - 12px);
    transform: none;
    overflow-x: hidden;
    overflow-y: auto;
    overscroll-behavior: contain;
  }
  .sp--wide { width: auto; }
  .sp-grid .gs-row { flex-basis: 100%; }
  .sp-tree { flex-direction: column; }
  .sp-branch__list { max-height: 42dvh; }
  .sp-card { max-width: calc(100vw - 12px); }
}

