/* ═══════════════════════════════════════════════════════════════════════════════
   MYTHARA - Presentation Utilities

   Every rule in this file used to be an inline `style` attribute, and it is here
   because that attribute needed style-src 'unsafe-inline' to have any effect.
   The values that CHANGE per render moved to data-style-* declarations read by
   js/styleApply.js; the values that never change are these, because a class
   costs no attribute, no observer work and no allowlist entry.

   WHY THIS SHEET IS LINKED LAST, AND WHY SOME SELECTORS REPEAT THEIR CLASS.
   An inline style attribute sits above every author stylesheet in the cascade,
   so the declarations below used to win against anything, at any specificity,
   in any file. A class does not get that for free. Two things restore it:

     1. index.html links this sheet after all the others, so a tie on
        specificity resolves here.
     2. `.u-hidden.u-hidden` is the same class named twice. It matches exactly
        what `.u-hidden` matches and raises the specificity to (0,2,0), which
        is what the component rules these utilities have to beat actually use -
        `.detail-portrait .detail-symbol { display: flex }`, `.nav-btn
        .nav-badge`, `.skill-node:hover { transform: translateY(-2px) }`.

   It stops there deliberately. (0,2,0) still loses to an inline style, which is
   what keeps `el.style.display = 'flex'` and every other CSSOM write in the
   client working exactly as it did - those are how each of these elements is
   revealed, and they are NOT affected by the CSP (style-src does not gate the
   CSSOM). No rule here is !important for the same reason.
   ═══════════════════════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════════════════════
   UTILITIES
   ═══════════════════════════════════════════════════════════════════════════════ */

/* The starting state of everything that is revealed later: notification pips,
   the god-symbol spans js/imageFallbacks.js swaps in when a portrait 404s, the
   panels their screens open on demand. A class rather than a data-style-display
   declaration on purpose - a class is applied by the parser, so the element is
   never painted visible for a frame first, and it cannot race the other
   MutationObserver on the page (imageFallbacks.js reveals these). */
.u-hidden.u-hidden {
  display: none;
}

/* #intro-cutscene is the one element .u-hidden cannot hide: mobile.css gives it
   `#intro-cutscene { display: flex }`, and an ID beats any number of classes.
   App.playIntroCutscene() sets display:flex inline to play it and
   App.endCutscene() sets display:none again. */
#intro-cutscene {
  display: none;
}

/* Portraits that fade in once they have actually loaded. The opacity is raised
   to 1 by js/imageFallbacks.js from the element's own data-onload-opacity, and
   an image that never loads is hidden instead by its data-fallback. */
.u-fade-in.u-fade-in {
  opacity: 0;
  transition: opacity 0.3s;
}

/* A staggered entrance for a short list rendered all at once. These have to
   out-specify the `animation` SHORTHAND on the component rule
   (`.level-up-rewards .reward-item`), which resets animation-delay to 0s. */
.u-delay-1.u-delay-1 {
  animation-delay: 0.1s;
}

.u-delay-2.u-delay-2 {
  animation-delay: 0.2s;
}

.u-delay-3.u-delay-3 {
  animation-delay: 0.3s;
}

.u-delay-4.u-delay-4 {
  animation-delay: 0.4s;
}

/* Load-bearing, not decoration: characterSheetUI.css positions every
   .skill-node with `transform: translate(-50%, -50%)` for a layout the skill
   tree does not use, which painted each tile half its own width left and half
   its height up from the box reserved for it. skillTreeUI.js:renderNode carries
   the whole story. */
.u-no-transform.u-no-transform {
  transform: none;
}

/* A progress bar in a leaderboard row, which is as wide as the row without it. */
.u-max-w-180.u-max-w-180 {
  max-width: 180px;
}

/* ═══════════════════════════════════════════════════════════════════════════════
   HUD RESOURCE BARS (index.html)

   The starting widths the markup used to declare. Every one of these is
   overwritten inline by UI.updateHeader() / UI.updateResourceBars() as soon as
   a character is loaded; they exist so the bars are not full before it is.
   ═══════════════════════════════════════════════════════════════════════════════ */

#xp-fill {
  width: 0;
}

#health-fill,
#mana-fill,
#energy-fill {
  width: 100%;
}

/* No `.resource-bar.energy .bar-fill` rule exists in the sheets that own the
   HP and Mana bars, so the amber gradient that keeps energy visually
   consistent with them lives here. */
#energy-fill {
  background: linear-gradient(90deg, #b8860b, #ffd700);
}

/* ═══════════════════════════════════════════════════════════════════════════════
   COMPONENTS THAT HAD NO CLASS
   ═══════════════════════════════════════════════════════════════════════════════ */

/* The unread-DM pip in the collapsed chat bar. It is NOT .nav-badge or
   .notification-badge: both of those are position:absolute and this one sits in
   the bar's flex row. UI.loadNotificationBadges() only toggles `display`. */
.chat-dms-badge {
  display: none;
  flex-shrink: 0;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  margin: 0 8px;
  padding: 0 5px;
  border-radius: 9px;
  background: linear-gradient(135deg, #e74c3c, #c0392b);
  color: #fff;
  font-size: 0.7rem;
  font-weight: bold;
}

/* The starting-ability card in the god-selection preview.

   The row layout this card was written for (screens.css) is undone by two later
   stylesheets that reach it by class alone: components.css restyles every
   .ability-card as a centred column at opacity .5 - which put the icon alone on
   its own row with the text crammed underneath, greyed out - and skillTreeUI.css
   makes every .ability-info a flex row, so name, description and costs landed on
   one line. Scoping to .starting-ability is what wins both without touching any
   other ability card on the page. */
.starting-ability .ability-card {
  display: flex;
  flex-direction: row;
  align-items: flex-start;
  gap: 12px;
  text-align: left;
  opacity: 1;
}

.starting-ability .ability-icon {
  flex: 0 0 auto;
  margin-bottom: 0;
}

.starting-ability .ability-info {
  display: block;
  flex: 1 1 auto;
  min-width: 0;
}

.starting-ability .ability-info > strong {
  display: block;
}

/* The god portrait in a leaderboard row, filling the round avatar slot. */
.lb-god-portrait {
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
}

/* A four-character tag beside a full-width alliance name. */
#alliance-tag {
  width: 80px;
  text-transform: uppercase;
}

/* The quieter of the two tutorial continue buttons: the step already tells the
   player to click the highlighted element, and this is the way past it. */
.tutorial-continue-btn.tutorial-continue-alt {
  margin-top: 10px;
  opacity: 0.7;
}

/* A stacking context for the skill tree's tiers, so a node's hover tooltip is
   painted over the tier below it rather than under it. */
.node-tiers {
  position: relative;
  z-index: 0;
}
