/* locker.css - inventory locker, melt ladder, Milestone claims.
   Its own file because app.css is at its structure budget. Reuses the app's
   existing custom properties so it inherits the shell's theme. */

/* The grid, its cards, the ×N badge and the toolbar are public/css/locker-grid.css.
   This file is the drawer, the copy rows and the melt ladder. */

/* ---- The two-column locker ------------------------------------------------
   What you own on the left, what you picked on the right.

   It used to be one column: grid, then the details drawer, then the recolour
   row, then Titles. In a panel that cannot scroll (docs/ui-rules.xml) that made
   every block below the drawer hostage to it. Measured at 1280x800 with a
   nine-copy stack open: #ownedGrid was allocated 0px of height, and the Titles
   chips ended 33px past the panel's clipped edge. So the locker showed no skins
   and no titles, and "I still cannot equip a title" was the symptom.

   Side by side, each column's height is its own problem. The grid pages against
   .locker-main and the copy list against the panel, so neither can take room
   from the other. */
.locker-body {
  flex: 1 1 auto; min-height: 0; width: 100%;
  display: grid; grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
  gap: 16px;
}
/* `align-items: stretch`, deliberately not `start`. A content-sized column is a
   circular floor for the pager inside it: it measures down to the bottom of what
   is already there, concludes that exactly that much fits, and settles on one
   row of skins with the rest of the panel empty beneath it. Stretched, both
   columns are the height of the panel and both pagers measure something real. */
.locker-col { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.locker-main { gap: 12px; }

/* Below ~860px there is not enough width for two useful columns: the cards drop
   under 92px and the copy rows lose their date column. One column then, in
   reading order, and the pager turns whatever does not fit into pages the same
   way it does everywhere else. */
@media (max-width: 860px) {
  /* BOTH tracks are bounded, and that is the whole fix. The drawer's row used to
     be plain `auto`, so it took its content height FIRST and handed the grid
     whatever was left. With the nine-copy stack open that was nothing: measured
     at 390x844 #ownedGrid was allocated 0px, at 320x568 0px, at 740x360 0px, and
     because a grid does not clip, its cards painted straight down over the
     drawer's own heading. Opening a skin you own several copies of deleted the
     Locker.
     fit-content(56%) says the drawer is as tall as it needs and never more than
     a bit over half the body. The grid keeps a real 1fr floor at every size, and
     the copy list now pages against a height the LAYOUT decided instead of one
     it decided for itself, which is what made the old floor circular. */
  .locker-body {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) fit-content(56%);
    gap: 12px;
  }
}

/* A landscape phone is 740x360: two tall blocks stacked into 290px of body is
   what makes both of them useless, while 400px of width sits doing nothing. So
   the SHORT screens take the side-by-side layout back under the 860px
   breakpoint, and the copy rows compact the way they already do below 520px
   (the shared rule near the bottom of this file). Measured at 740x360: stacked
   gave the grid 0px and the copy list one row of nine; side by side gives the
   grid its cards and the list three rows a page. */
@media (max-width: 860px) and (max-height: 560px) {
  .locker-body {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr);
    grid-template-rows: minmax(0, 1fr);
    gap: 10px;
  }
}

/* A short portrait phone, where the arithmetic simply does not close.
   320x568 leaves 300px of body once the tab head is paid for, and ONE card row
   (120) plus its page bar (42) plus the drawer's head (48), one copy row (57)
   and its own page bar (42) is 321 before anything optional is drawn. Neither
   pager can page below one row, so no amount of paging fixes a 21px deficit:
   something has to get smaller. What goes is the chrome, in the order it is
   least missed.
   It used to be the stats block that went first, on the argument that every
   figure in it is somewhere else too. The tabs took that job instead: stats and
   copies share one height here rather than one of them being deleted. What still
   goes is the copy column labels, because a date, a gem count and a button marked
   Melt do not need a header explaining that they are a date, a gem count and a
   button, and the cards take the compact shape landscape already gives them,
   which also fits three across instead of two. Measured at 320x568 after the
   rebuild: 90px cards, 132px of grid track, 156px of drawer column, and nothing
   past the panel's edge on either tab. */
@media (max-width: 860px) and (max-height: 700px) and (orientation: portrait) {
  .locker-body { gap: 8px; grid-template-rows: minmax(0, 1fr) fit-content(50%); }
  /* Scoped through .locker-drawer only to outrank the base rules further down
     this file. A media query adds no specificity, so a bare `.ld-copyhead` here
     loses to the rule written after it.
     The stats block used to be hidden here too, and that is the line the tabs
     below replaced. Deleting it saved 90px by removing the numbers this screen
     exists to show, on the two shapes most people play on. The column labels are
     a fair cut in a way the figures are not: a date, a gem count and a button
     marked Melt do not need a header explaining that they are a date, a gem
     count and a button. */
  .locker-drawer .ld-copyhead { display: none; }
  #ownedGrid { grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); gap: 6px; }
  #ownedGrid .skin-card { padding: 17px 5px 7px; gap: 2px; }
  #ownedGrid .swatch { width: 30px; height: 30px; }
  #ownedGrid .skin-card-name { font-size: 10.5px; }
  #ownedGrid .skin-card-sub { font-size: 9.5px; }
  #ownedGrid .skin-card-kind { font-size: 6.5px; padding: 1.5px 5px; }
  /* Below the pill here too, and for the same reason: a 74px card has even less
     room for a rarity pill and a count on one line. */
  .locker-count { top: 19px; right: 3px; font-size: .66rem; padding: 0 5px; }
}

/* ---- Details drawer ---- */
.locker-drawer[hidden] { display: none; }
.locker-drawer {
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 12px;
  background: rgba(255,255,255,.035);
  overflow: hidden;
}

/* ---- Titles: equip one, or take it off with "None" ----
   This is the whole reason the layout moved. It is a permanent block in the left
   column now rather than the last thing in a stack, so it is on screen whenever
   the Locker is, whatever is open beside it. */
#titlesSection[hidden] { display: none; }
#titlesSection {
  border-top: 1px solid rgba(255,255,255,.08); padding-top: 11px;
}
.titles-head { font-weight: 700; font-size: .95rem; margin-bottom: 8px; }
.titles-head span { font-weight: 500; font-size: .78rem; opacity: .55; margin-left: 6px; }
.titles-row { display: flex; flex-wrap: wrap; gap: 8px; }
.title-chip {
  padding: 9px 15px; min-height: 44px; font: inherit; font-size: .82rem; font-weight: 700;
  cursor: pointer; color: #d9d3ff; background: rgba(150,110,255,.08);
  border: 1px solid rgba(178,150,255,.25); border-radius: 999px;
  transition: transform .1s ease, border-color .15s ease, background .15s ease;
}
.title-chip:hover { transform: translateY(-1px); border-color: rgba(184,150,255,.55); }
.title-chip.on { color: #1a1330; background: linear-gradient(100deg, #ffd75e, #d78bff); border-color: transparent; }
.ld-head {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  border-bottom: 1px solid rgba(255,255,255,.08);
}
.ld-name { font-weight: 700; }
.ld-rar { font-weight: 600; font-size: .85rem; }
.ld-close {
  margin-left: auto; background: none; border: 0;
  color: inherit; opacity: .6; cursor: pointer; font-size: 1rem;
}
.ld-close:hover { opacity: 1; }

/* ---- Stats and copies: both at once on a wide screen, two tabs on a narrow one ----
   Stacking them below 860px costs more height than those screens have, and what
   used to give was the stats block, deleted outright at 320x568 and in landscape.
   One height, one half of it at a time, and the figures keep their size. */
.ld-tabs { display: none; gap: 6px; padding: 7px 8px; border-bottom: 1px solid rgba(255,255,255,.08); }
.ld-tab {
  flex: 1 1 0; min-height: 44px; border-radius: 9px;
  border: 1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.04);
  color: inherit; font: inherit; font-size: .82rem; font-weight: 700; cursor: pointer;
  transition: background var(--t-quick) var(--e-standard), border-color var(--t-quick) var(--e-standard);
}
.ld-tab b { font-variant-numeric: tabular-nums; opacity: .7; margin-left: 3px; }
.ld-tab[aria-pressed="true"] { background: rgba(255,255,255,.14); border-color: rgba(255,255,255,.34); }
.ld-tab:active { transform: scale(.965); transition-duration: var(--t-instant); }
@media (max-width: 860px) {
  .ld-tabs { display: flex; }
  /* The strip and the head pay for themselves out of their own padding on short
     screens. The tabs stay 44px, because they are what a thumb aims at; the space
     around them is what the screen cannot afford. */
  @media (max-height: 700px) {
    .ld-tabs { padding: 3px 6px; gap: 5px; }
    .ld-head { padding: 6px 11px; }
  }
  /* The notes warn about what melting costs, so they travel with the melt buttons
     rather than with the figures. */
  .locker-drawer.ld-t-stats .locker-copies,
  .locker-drawer.ld-t-stats .ld-copyhead,
  .locker-drawer.ld-t-stats .ld-note { display: none; }
  .locker-drawer.ld-t-copies .locker-stats { display: none; }
}

/* A phone that is narrow AND short, on the copies tab, is the one place the
   arithmetic will not close: the head (50), the tab strip (50), one copy row (52)
   and its page bar (46) is 198 into a 156px column, and none of those four can be
   made smaller without dropping a 44px target below the floor. So the HEAD goes,
   on that tab only. Measured at 320x568: 36px past the panel before, nothing past
   it after.
   It is the safe one to lose. The name and the rarity are still on the card above,
   which is outlined as the open one, and they are on the Stats tab a tap away. The
   moment that actually matters already names the skin itself: the melt dialog asks
   "Melt Werewolf?" and the receipt lists what it destroyed (js/melt.js). Equip
   lives on the Stats tab here, which is where you go to read about a skin anyway. */
@media (max-width: 620px) and (max-height: 700px) {
  .locker-drawer.ld-t-copies .ld-head { display: none; }
}

.locker-stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px; padding: 12px 14px;
}
.locker-stats > div { display: flex; flex-direction: column; gap: 2px; }
.locker-stats span { font-size: .72rem; opacity: .6; text-transform: uppercase; letter-spacing: .04em; }
/* The figures are the reason this panel gets opened, and they used to inherit the
   body size, which left them smaller than the copy rows underneath them. The LABEL
   is the part that can afford to be quiet. */
.locker-stats b { font-variant-numeric: tabular-nums; font-size: 1.05rem; line-height: 1.2; }

.ld-copyhead, .copy-row {
  display: grid;
  grid-template-columns: 26px 1fr 1fr auto auto auto;
  gap: 10px; align-items: center;
  padding: 8px 14px;
}
.ld-copyhead {
  font-size: .7rem; text-transform: uppercase; letter-spacing: .04em; opacity: .5;
  border-top: 1px solid rgba(255,255,255,.08);
  border-bottom: 1px solid rgba(255,255,255,.08);
}
/* 52px, not the 34px this used to be. The row is itself a tap target (it toggles the
   tick) and it carries the Melt button, and both sat under the 44px floor. */
.copy-row {
  border-bottom: 1px solid rgba(255,255,255,.05); cursor: pointer; font-size: .85rem;
  padding: 4px 14px; min-height: 52px; }
.copy-row:last-child { border-bottom: 0; }
.copy-row:hover { background: rgba(255,255,255,.04); }
.copy-row.inert { cursor: default; }
.copy-row.inert:hover { background: none; }
.copy-row.picked { background: rgba(245,179,1,.12); }
.copy-src { opacity: .65; text-transform: capitalize; }
.copy-paid, .copy-melt, .copy-when { font-variant-numeric: tabular-nums; }
.copy-melt { font-weight: 600; }
.copy-melt.none { opacity: .4; }

/* Sticky action bar - only appears once something is ticked.
   The [hidden] rule is NOT redundant: `display:flex` below outranks the browser's
   default `[hidden] { display:none }`, so without it the bar stayed on screen
   showing a stale "2 selected / 16,150" over an emptied locker. */
.melt-bar[hidden] { display: none; }
.melt-bar {
  position: sticky; bottom: 0;
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px; margin-top: 10px;
  border-radius: 12px;
  background: rgba(20,24,48,.94);
  border: 1px solid rgba(255,255,255,.12);
}
.melt-bar-count { flex: 1; }
.melt-bar-gems { font-weight: 700; font-variant-numeric: tabular-nums; }
.melt-bar-btn, .melt-bar-clear, .melt-go, .melt-cancel, .ms-claim, .ms-claim-all {
  border: 0; border-radius: 8px; padding: 8px 14px;
  font: inherit; font-weight: 600; cursor: pointer;
}
/* 44px floor. These four commit or cancel the destruction of an owned skin, so
   they are the last controls in the game that should be hard to hit. */
.melt-bar-btn, .melt-bar-clear, .melt-go, .melt-cancel { min-height: 44px; padding: 10px 16px; }
.melt-bar-clear, .melt-cancel { background: rgba(255,255,255,.12); color: inherit; }
.melt-bar-btn, .melt-go { background: #f5b301; color: #1b1500; }
/* Rarity colours the commit button, so the stakes are visible before the dialog. */
.melt-bar-btn.r-purple, .melt-modal.r-purple .melt-go { background: #a64dff; color: #fff; }
.melt-bar-btn.r-gold,   .melt-modal.r-gold .melt-go   { background: #f5b301; color: #1b1500; }
.melt-bar-btn.r-green,  .melt-modal.r-green .melt-go  { background: #2ec26b; color: #04160c; }
.melt-go:disabled { opacity: .45; cursor: not-allowed; }

/* ---- Milestone claims ---- */
.ms-claims {
  border: 1px solid rgba(245,179,1,.35);
  background: rgba(245,179,1,.08);
  border-radius: 12px; padding: 14px; margin-bottom: 14px;
}
.ms-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin-bottom: 10px; }
.ms-title { font-weight: 700; }
.ms-sub { font-variant-numeric: tabular-nums; opacity: .85; }
.ms-row {
  display: flex; align-items: center; gap: 10px;
  padding: 8px 0; border-top: 1px solid rgba(255,255,255,.08);
}
.ms-what { flex: 1; font-size: .9rem; }
.ms-gems { font-variant-numeric: tabular-nums; font-weight: 600; }
.ms-claim { background: #f5b301; color: #1b1500; padding: 6px 12px; }
.ms-claim-all { width: 100%; margin-top: 12px; background: #f5b301; color: #1b1500; }

/* Four columns instead of six: the tick, when you got it, what it melts for, and
   the button that melts it. Source and price go, because both are on the card
   and neither decides which copy you destroy.
   The second query is the landscape two-column layout above: the drawer is about
   340px wide there, which is the same squeeze a 520px phone puts on it. Without
   it the six-column row ran 148px past a drawer that sets overflow: hidden, so
   the Melt button was cut in half. */
@media (max-width: 520px), (max-width: 860px) and (max-height: 560px) {
  .ld-copyhead, .copy-row { grid-template-columns: 26px 1fr auto auto; }
  .ld-copyhead span:nth-child(3), .ld-copyhead span:nth-child(4),
  .copy-src, .copy-paid { display: none; }
}

/* Selected card: the stats bar below is showing this one. */
.skin-card.locker-open { outline: 2px solid rgba(255,255,255,.45); outline-offset: -2px; }
.ld-equip {
  margin-left: auto; border: 0; border-radius: 8px; padding: 6px 14px;
  font: inherit; font-weight: 600; cursor: pointer;
  background: #f5b301; color: #1b1500;
}
.ld-equipped { margin-left: auto; font-weight: 600; color: #7adca0; font-size: .9rem; }
/* grey is the entry tier: it reads like the default white blob on purpose. */
.skin-card.rar-grey { border-color: rgba(154,163,178,.30); background: rgba(154,163,178,.07); }
.skin-card.rar-grey:hover { border-color: rgba(184,193,208,.5); }
.skin-card-kind.rk-grey {
  color: #cfd6e2; background: rgba(154,163,178,.16); border-color: rgba(154,163,178,.34);
}

/* Per-copy Melt. Still quiet at rest so a stack of them does not read as a wall of
   destructive buttons, but quiet through COLOUR now rather than opacity: it used to
   rest at opacity .35, which composited its label to about 2.6:1 and left the only
   destroy control on screen unreadable until you hovered it, and hover is the one
   state a keyboard player never reaches. It also measured 48x24 against the 44x44
   floor, on a button that permanently destroys an owned skin. */
.copy-melt-btn {
  min-height: 44px; min-width: 62px; border-radius: 9px; padding: 3px 12px;
  border: 1px solid rgba(224,120,120,.38); background: rgba(224,64,90,.10); color: #ffb4b4;
  font: inherit; font-size: .78rem; font-weight: 700; cursor: pointer;
  transition: background var(--t-quick) var(--e-standard),
              border-color var(--t-quick) var(--e-standard), color var(--t-quick) var(--e-standard);
}
.copy-row:hover .copy-melt-btn, .copy-melt-btn:hover, .copy-melt-btn:focus-visible {
  background: rgba(224,64,90,.30); border-color: rgba(255,150,150,.75); color: #fff;
}
.copy-melt-btn:active { transform: scale(.96); }

/* What sits where the Melt button would be on a gift skin. Deliberately NOT a
   button: there is no action here, and a disabled-looking button reads as "this
   is broken" rather than "this one is yours to keep". A tag states a fact, so it
   is styled as one - no hover, no press, no min tap size to earn. */
.copy-tag {
  justify-self: start;
  padding: 4px 10px; border-radius: 999px;
  border: 1px solid rgba(160,132,255,.42); background: rgba(107,70,201,.16);
  color: #d9ccff; font-size: .72rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .04em; white-space: nowrap;
}

/* Prestige: stated, not shouted. The rarity ladder still decides the friction. */
.ld-note, .melt-note {
  margin: 0; padding: 8px 14px;
  font-size: .82rem; color: #ffc9c9;
  background: rgba(224,64,90,.10);
  border-top: 1px solid rgba(224,120,120,.25);
}
.melt-note { border: 0; border-radius: 8px; margin-bottom: 10px; }
/* The other notes warn about something you are about to lose, so they are red.
   This one says you cannot lose it, and red would read as a problem. */
.ld-note.keep {
  color: #d9ccff;
  background: rgba(107,70,201,.14);
  border-top-color: rgba(160,132,255,.28);
}

/* Account stats moved to public/css/account.css, which is their own screen. */

/* "Melted": the same visual language as Sold Out, because it means the same thing to
   the player - this is not obtainable - but it is their own doing, so it names the
   reason rather than pretending the shelf is empty. The dimming used to sit on the
   whole card, taking "Cannot be re-earned" to about 2.8:1 and the stamp to 2.3:1: the
   one line explaining that something is permanently gone was the least legible thing
   on it. Dim the ART instead and leave every word at full strength. */
.skin-card.melted { cursor: not-allowed; position: relative; }
.skin-card.melted .swatch { opacity: .45; filter: grayscale(.85); }
.skin-card.melted .skin-card-name { opacity: .8; }
.melted-stamp {
  position: absolute; top: 42%; left: 50%;
  transform: translate(-50%, -50%) rotate(-15deg);
  font-weight: 900; font-size: 15px; letter-spacing: 2px; color: #ff3b4e;
  border: 3px solid #ff3b4e; border-radius: 6px; padding: 2px 9px;
  background: rgba(20,6,10,.55); text-shadow: 0 1px 2px rgba(0,0,0,.6);
  pointer-events: none; white-space: nowrap; text-transform: uppercase;
}

/* Stated once at the top of a wall whose whole promise is "earn this again". */
.tab-warn {
  margin-top: 6px; font-size: .85rem; color: #ffc9c9;
  background: rgba(224,64,90,.10);
  border-left: 3px solid rgba(224,120,120,.5);
  border-radius: 0 8px 8px 0; padding: 8px 12px;
  display: inline-block;
}

/* ---- The drawer on a small screen ------------------------------------------
   Moved here from fit.css section 8b, which was the one single-screen section in
   a file organised by viewport shape. The rules did not change; the argument
   above them did, because the drawer is TABBED below 860px now and no longer
   pays for the phone by deleting its own stats.

   The drawer takes its natural height and the GRID gives way, at every size.
   Both are flex children of #skinsPanel, so flex was shrinking both, and a shrunk
   drawer clips (it sets overflow: hidden) while a shrunk grid does not, because
   the grid is paged and shrinking it just means fewer cards per page. Letting the
   thing that CAN page absorb the difference is the whole point of having a pager.
   Without this the drawer's own pager measures room down to the stage floor, sees
   space, and keeps rows that flex has already squeezed away. */
#lockerDrawer { flex: 0 0 auto; }
#ownedGrid { flex: 0 1 auto; min-height: 0; }

/* Neither block below sets a margin on .locker-drawer any more. That dates from
   when the drawer sat UNDER the grid in one flex column and needed separating
   from it; they are grid columns now and .locker-body's own gap does that job.
   Kept, it was 8px of content inside a track sized without it, which is exactly
   the 8px the drawer hung past the panel by at 320x568. */
@media (max-width: 620px), (max-height: 640px) {
  .locker-stats { grid-template-columns: repeat(2, 1fr); gap: 4px 10px; padding: 7px 12px; }
  .locker-stats span { font-size: .64rem; }
  .ld-head { padding: 7px 12px; }
  .ld-copyhead, .copy-row { padding: 6px 12px; gap: 7px; }
  .ld-note { font-size: 11px; padding: 0 12px; }
}

/* The four market figures go on ONE shape only: a phone that is both narrow and
   short, where the stats tab gets a single row of two and there is no arithmetic
   that makes six of them fit. It used to go on `max-height: 640px` alone, which
   caught every landscape phone as well, and those have the width for all six.
   What survives is what decides an action: how many you hold, and what a copy
   melts for. The other four are the market, and the market can wait for a
   bigger screen. */
@media (max-width: 620px) and (max-height: 700px) {
  .locker-stats > div:nth-child(-n+4) { display: none; } /* circulation, minted, destroyed, released */
}
