/* matte.css — the restraint layer.
 *
 * Two things live here, and they arrived together because they are the same decision.
 *
 * The first is a palette retune, applied as a token override rather than as several hundred edits
 * at the call sites. Every surface on the site already reads its colour from one of these
 * variables, so repointing them here moves the whole product at once and leaves one place to look
 * when somebody asks why a panel is the colour it is.
 *
 * The second is the small set of controls that replaced the explanatory copy stripped out of the
 * game components: the info hint, the quick-action chips, and the referral dashboard's rows. They
 * belong beside the palette because they exist for the same reason — a screen that says less has
 * to show more, and what it shows has to be legible without a caption.
 *
 * Loaded last, so the token block below wins on cascade order at equal specificity.
 */

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   MATTE OBSIDIAN
   ══════════════════════════════════════════════════════════════════════════════════════════════

   Three things change, and nothing else.

     1. The grounds go flatter and slightly cooler. The old obsidian carried a green cast that
        showed up as a tint wherever two panels overlapped.
     2. Gold loses saturation. The bright stop was #ffd700 at full chroma on the loudest surfaces,
        which on an OLED panel in a dark room is genuinely uncomfortable to sit in front of — and
        a colour that loud everywhere cannot also mean "this is the active thing", because
        everything is already wearing it. The range is now #ffaa00 down to #d4a303, and the bright
        end is reserved for one state at a time.
     3. Body text comes off pure white onto an off-white. Pure white on near-black is the highest
        contrast a screen can produce, and this needs less than that.
*/
:root {
  --bg:       #0a0a0c;
  --bg2:      #0e0e11;
  --panel:    #121216;
  --panel2:   #16161b;
  --panel3:   #1c1c22;
  --line:     #24242b;
  --line2:    #2f2f38;

  /* The bright stop is no longer a different colour from the body — it is the same metal catching
     light — so an active state reads as emphasis instead of as a second hue. */
  --gold-bright: #ffd700;
  --gold-body:   #ffaa00;
  --gold-deep:   #d4a303;
  --gold-ink:    #221802;

  --amber:    #ffaa00;
  --amber2:   #d98800;
  /* Information and loss keep their hues but come down off full saturation, so they sit on a
     matte ground without haloing against it. */
  --cyan:     #ffd700;
  --cyan2:    #d4a303;
  --crimson:  #c0392b;

  --text:     #d1d5db;
  --muted:    #9096a0;
  --faint:    #757b85;

  --win-lo:   #221802;
  --green-lo: #221802;

  /* Bevels come down with everything else. At the old alphas a card edge read as a light source
     rather than as an edge. */
  --bev-hi: rgba(255, 255, 255, .06);
  --bev-lo: rgba(0, 0, 0, .55);
}

.inspect__dropval { color: var(--cyan); }
.inspect__dropodds { color: var(--gold-deep); }

/* The invite badge in the nav pulsed its glow on a 2.8s infinite loop, on every page, forever.
   That is the one animation on the site that a player cannot get away from, and a permanently
   breathing element in the chrome is exactly what "no excessive glow animations" is about. The
   badge keeps its gold; it simply stops moving. */
.tabs .navref { animation: none; }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   INFO HINT
   ══════════════════════════════════════════════════════════════════════════════════════════════

   The replacement for every explanatory paragraph that used to sit inside a game component.

   The rule it enforces: a mechanic that genuinely needs a sentence gets exactly one sentence, and
   that sentence is not on screen until somebody asks for it. What stays visible is the number the
   player is actually reading.

   Hover OR keyboard focus opens it, because a control that only answers to a mouse is one a
   keyboard user cannot ask at all. The bubble is clamped to the viewport on small screens rather
   than being allowed to push the page sideways.
*/
.ihint {
  display: inline-grid; place-items: center; position: relative;
  width: 15px; height: 15px; padding: 0; margin-left: 7px;
  vertical-align: middle;
  border: 1px solid var(--gold-deep); border-radius: 50%;
  background: transparent; color: var(--gold-deep);
  font: italic 700 9px/1 var(--body); cursor: help;
  transition: color .14s, border-color .14s, background-color .14s;
}
.ihint::before { content: "i"; }
.ihint:hover, .ihint:focus-visible {
  color: var(--gold-bright); border-color: var(--gold-bright);
  background: rgba(255, 170, 0, .09); outline: none;
}
.ihint::after {
  content: attr(data-tip);
  position: absolute; bottom: calc(100% + 8px); left: 50%;
  transform: translateX(-50%) translateY(3px);
  width: max-content; max-width: min(268px, 72vw);
  padding: 7px 10px;
  border: 1px solid var(--line2); border-radius: 4px;
  background: var(--tip-bg); color: var(--tip-txt);
  font: 400 .7rem/1.45 var(--body); font-style: normal;
  letter-spacing: 0; text-align: left; text-transform: none; white-space: normal;
  opacity: 0; pointer-events: none; z-index: 60;
  transition: opacity .14s, transform .14s;
}
.ihint:hover::after, .ihint:focus-visible::after {
  opacity: 1; transform: translateX(-50%) translateY(0);
}
/* Against the left edge of the column a centred bubble would clip off-screen, so a hint in a page
   heading anchors to its own left instead. */
.phead .ihint::after { left: 0; transform: translateX(-8px) translateY(3px); }
.phead .ihint:hover::after, .phead .ihint:focus-visible::after {
  transform: translateX(-8px) translateY(0);
}

/* Touch screens. The CSS bubble cannot open there (no hover, and a tap is not focus-visible), so a
   tap opens .tipfloat from ui.js instead, and the pseudo bubble is switched off so iOS's sticky
   hover cannot show a second, unclamped copy.

   The circle stays 15px; the box around it grows to 29px, because a 15px target is a third of a
   fingertip. The ring moves into a gradient so it can stay small inside the bigger box, and the
   negative margins hand the extra 7px back so nothing in the heading moves. */
@media (hover: none) {
  .ihint {
    --ring: var(--gold-deep);
    width: 29px; height: 29px;
    margin: -7px -7px -7px 0;
  }
  /* Restated for :hover because the rule above uses the `background` shorthand there, which would
     wipe the ring the moment iOS applies its sticky hover after a tap. */
  .ihint, .ihint:hover, .ihint:focus-visible {
    border-color: transparent;
    background: radial-gradient(circle, transparent 6.5px, var(--ring) 6.5px 7.5px, transparent 7.5px);
  }
  .ihint::after { display: none; }
  .ihint[aria-expanded="true"] { --ring: var(--gold-bright); color: var(--gold-bright); }
}

.tipfloat {
  position: fixed; z-index: var(--z-portal);
  width: max-content; max-width: min(300px, calc(100vw - 24px));
  padding: 9px 12px;
  border: 1px solid var(--line2); border-radius: 6px;
  background: var(--tip-bg); color: var(--tip-txt);
  box-shadow: 0 10px 28px rgba(0, 0, 0, .55);
  font: 400 .8125rem/1.45 var(--body);
  text-align: left;
  pointer-events: none;
  animation: tipfloat-in .14s ease-out;
}
/* The notch points at the icon, wherever the clamp left the bubble. */
.tipfloat::before {
  content: "";
  position: absolute; left: var(--tip-arrow, 50%);
  width: 8px; height: 8px; margin-left: -4px;
  background: var(--tip-bg);
  border: 1px solid var(--line2);
  transform: rotate(45deg);
}
.tipfloat[data-side="below"]::before { top: -5px; border-right: 0; border-bottom: 0; }
.tipfloat[data-side="above"]::before { bottom: -5px; border-left: 0; border-top: 0; }
@keyframes tipfloat-in { from { opacity: 0; transform: translateY(3px); } }
@media (prefers-reduced-motion: reduce) { .tipfloat { animation: none; } }

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   QUICK-ACTION CHIPS
   ══════════════════════════════════════════════════════════════════════════════════════════════

   What replaced the "type 1m, 250k, or 1000000" hint under every amount box. That instruction was
   there because the field accepted a shorthand nobody could guess. Buttons that apply the amounts
   directly make the shorthand optional rather than something to be taught: the field still parses
   everything it always did, so an exact figure is still typed, but the common amounts are one
   press and the row itself is the documentation.
*/
.qchips { display: flex; flex-wrap: wrap; gap: 4px; width: 100%; margin-top: 8px; }
.qchip {
  flex: 1 1 auto; min-width: 52px;
  padding: 6px 8px;
  border: 1px solid var(--line); border-radius: var(--r-s);
  background: var(--panel2); color: var(--muted);
  font: 600 .68rem/1 var(--mono); letter-spacing: .02em;
  white-space: nowrap; cursor: pointer;
  transition: color .14s, border-color .14s, background-color .14s, transform .08s;
}
.qchip:hover:not(:disabled) {
  color: var(--text); border-color: var(--line2); background: var(--panel3);
}
.qchip:active:not(:disabled) { transform: translateY(1px); }
.qchip:focus-visible { outline: 1px solid var(--gold-deep); outline-offset: 1px; }
.qchip:disabled { opacity: .4; cursor: default; }
/* The one that commits the whole balance carries the accent, because it is the one worth a second
   look before pressing. */
.qchip--max { color: var(--gold-deep); border-color: rgba(212, 163, 3, .38); }
.qchip--max:hover:not(:disabled) {
  color: var(--gold-bright); border-color: var(--gold-bright); background: rgba(255, 170, 0, .08);
}

@media (prefers-reduced-motion: reduce) {

}
@media (max-width: 560px) {

}

/* ══════════════════════════════════════════════════════════════════════════════════════════════
   HOSTS FOR THE NEW ICONS
   ══════════════════════════════════════════════════════════════════════════════════════════════

   Three places where an info hint now sits beside something that was laid out assuming it would
   be alone. Kept here with the icon rather than scattered across the files it lands in, so the
   whole restraint pass reverts as one change.
*/

/* A page heading and its icon share a baseline. The heading is display type at a much larger
   size, so the icon needs to stop stretching to the line box. */
.phead h1 { display: flex; align-items: center; flex-wrap: wrap; }
.phead h1 .ihint { align-self: center; }

/* The card heading keeps its right-hand meta span, so the icon goes in as a third item rather
   than pushing that span out of position. */
.card__h .ihint { align-self: center; }

/* The community-crate price head is a label-and-figure pair on one row; the icon joins the label
   end of it rather than the figure. */
.build__pricehead { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.build__pricehead .build__price { margin-left: auto; }
