/* Loot Tracker page (render_loot_tracker in app/pages/). The chart, "By NPC"
   row and item panel all scope to the selected range (see the app/loot.py module
   docstring). */

/* Bar chart */
.loot-chart-card {
  /* panel-translucent like every top-level card; opaque panel-2 is reserved for
     the boxes inside it. */
  background: var(--panel-translucent); border: 1px solid var(--border);
  padding: 18px 22px 14px; margin-bottom: 18px;
}
.loot-chart-header { position: relative; display: flex; justify-content: space-between; align-items: center; margin-bottom: 22px; }
.loot-chart-stats { display: flex; align-items: baseline; gap: 8px; }
.loot-chart-total { font-size: 13px; color: var(--gold); font-variant-numeric: tabular-nums; }
.loot-chart-kills { font-size: 12px; color: var(--text-faint); letter-spacing: 0.03em; font-variant-numeric: tabular-nums; }
/* Selected NPC name or "ALL NPCs" (renderBarChart), absolutely centered since
   the range control and stats differ in width. Uppercased in JS, not CSS, which
   would turn "ALL NPCs" into "ALL NPCS". */
.loot-chart-title {
  position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%);
  font-size: 15px; color: var(--text-dim); letter-spacing: 0.03em;
  white-space: nowrap; max-width: 40%; overflow: hidden; text-overflow: ellipsis;
}

/* Range button (presets + CUSTOM date pair) and its dropdown. */
.loot-chart-range { position: relative; z-index: 2; display: flex; align-items: center; gap: 6px; }
/* 25px is the site-wide button height; pinned so it cannot drift from the other
   buttons sharing it. */
.loot-range-btn {
  display: flex; align-items: center; justify-content: center; gap: 5px;
  height: 25px;
  padding: 0 10px;
  font-size: 11px; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-dim);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer; white-space: nowrap;
}
.loot-range-btn:hover { border-color: var(--gold-dim); color: var(--text); }
/* On while the menu is open (see closeRangeMenu). */
.loot-range-btn.active { border-color: var(--gold); color: var(--gold); }
.loot-range-caret { font-size: 9px; color: var(--text-faint); }
/* More specific than .loot-range-btn.active, so the caret keeps its own color. */
.loot-range-btn.active .loot-range-caret { color: var(--gold); }
.loot-range-menu {
  position: absolute; top: calc(100% + 4px); left: 0;
  display: flex; flex-direction: column; gap: 2px;
  min-width: 132px; padding: 6px;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
}
.loot-range-option {
  padding: 6px 8px;
  font-size: 11px; letter-spacing: 0.03em; text-transform: uppercase; text-align: left;
  color: var(--text-dim);
  background: transparent; border: 1px solid transparent; border-radius: var(--radius);
  cursor: pointer;
}
.loot-range-option:hover { color: var(--text); background: var(--panel); }
.loot-range-option.active { color: var(--gold); border-color: var(--gold-dim); }
.loot-range-custom {
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 4px; padding-top: 8px; border-top: 1px solid var(--border);
}
.loot-range-custom-field {
  display: flex; flex-direction: column; gap: 3px;
  font-size: 10px; letter-spacing: 0.03em; text-transform: uppercase; color: var(--text-faint);
}
.loot-range-custom-field input[type="text"] {
  padding: 5px 6px; font-size: 12px; color: var(--text);
  background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius);
  color-scheme: dark;
}
/* Set by applyCustomRange for a typed value that is not a real YYYY-MM-DD date. */
.loot-range-custom-field input[type="text"].invalid { border-color: var(--red); }
.loot-range-apply {
  padding: 6px 8px;
  font-size: 11px; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--gold);
  background: var(--panel); border: 1px solid var(--gold-dim); border-radius: var(--radius);
  cursor: pointer;
}
.loot-range-apply:hover { border-color: var(--gold); }

/* Export icon next to the "Loot Tracker" .page-title and its floating popup.
   .loot-share-wrap is the position: relative anchor of .loot-share-card.
   No transform on the wrap: it would create a stacking context that walls
   .loot-share-card's z-index: 5 off from the root context, letting later content
   (.loot-chart-title, position: absolute, z-index: auto) paint over the popup. */
.loot-share-wrap {
  position: relative; display: inline-block; vertical-align: middle; margin-left: 8px;
}
.loot-share-icon-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  margin: 0;
  cursor: pointer;
  line-height: 1;
  color: var(--text-faint);
  transition: color 0.15s ease;
  /* Nudged up 2px: the SVG glyph sits low against the title text. */
  position: relative;
  top: -2px;
}
.loot-share-icon-btn:hover { color: var(--text-dim); }
.loot-share-icon-btn.open { color: var(--gold); }

/* Floats under its trigger; closes on re-click or outside click (see
   lootShareIconBtn in app/pages/). Opaque --panel since it floats over
   content; box-shadow matches .loot-range-menu.
   top: 32px, not icon height + gap: the wrap sits inside .page-title and
   inherits its 22px font-size/1.5 line-height, so its ~33px line box is taller
   than the 14px icon and its top sits above the icon's. 32px (measured) lands
   ~10px below the icon. */
.loot-share-card {
  position: absolute; top: 32px; left: 50%; transform: translateX(-50%); z-index: 5;
  display: flex;
  flex-direction: column;
  gap: 6px;
  width: 280px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 5px 6px;
  box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
}
/* Author `display` outranks the UA [hidden] rule; same fix as
   .public-profile-card[hidden] in character-overview.css. */
.loot-share-card[hidden] { display: none; }

/* Only thing visible until clicked (see lootShareGenerateBtn); opening the card
   generates nothing. font-size: 15px matches Character Overview's public-profile
   buttons. */
.loot-share-generate-btn {
  height: 28px;
  padding: 0 10px;
  font-size: 15px; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-dim);
  /* --panel-2, lighter than the --panel card, so the button reads as raised. */
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer;
}
.loot-share-generate-btn:hover { border-color: var(--gold-dim); color: var(--text); }
.loot-share-generate-btn:disabled { cursor: default; opacity: 0.6; }
.loot-share-generate-btn.action-failed { border-color: var(--red); color: var(--red); }

/* Replaces lootShareGenerateBtn once a link exists; clicking copies and flashes
   "COPIED". Sized like it so the layout is stable; overflow/ellipsis is a safety
   net for long URLs. */
.loot-share-link-btn {
  height: 28px;
  padding: 0 10px;
  font-size: 15px;
  font-family: inherit;
  color: var(--text-dim);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.loot-share-link-btn:hover { border-color: var(--gold-dim); color: var(--text); }

/* margin: 0 overrides the default <p> margins, which would stack on the card's
   gap. */
.loot-share-popup-hint { margin: 0; font-size: 13px; color: var(--text-faint); text-align: center; }

/* The y-axis label gutter is a 10px inset on the gridlines/bars themselves
   (padding on .loot-bar-plot would not affect absolutely-positioned children). */
.loot-bar-plot { position: relative; height: 150px; }
.loot-bar-gridlines { position: absolute; inset: 0 0 0 10px; }
.loot-bar-gridline { position: absolute; left: 0; right: 0; border-top: 1px solid var(--border); }
.loot-bar-gridline-label {
  position: absolute; top: 0; left: -34px; width: 30px; text-align: right;
  transform: translateY(-50%); font-size: 10px; color: var(--text-faint);
}
.loot-bar-bars { position: absolute; inset: 0 0 0 10px; display: flex; align-items: flex-end; gap: 3px; }

/* Each column layers a full-height outline at the bucket's total (visible only
   with .active) behind a solid fill for the displayed amount (renderBarChart);
   both are absolute so their heights can differ. */
.loot-bar-col { flex: 1 1 0; height: 100%; position: relative; }
.loot-bar-outline {
  position: absolute; left: 0; right: 0; bottom: 0; box-sizing: border-box;
  border: 1px solid transparent;
  transition: height 0.5s ease, border-color 0.5s ease;
}
.loot-bar-outline.active { border-color: var(--gold-dim); }
/* Hides the outline's bottom border (see outlineHideBottomBorder) for a bucket
   the selection had no part in, so no flat line sits under an empty bar. Two
   classes beat .active's border-color shorthand. */
.loot-bar-outline.active.no-bottom-border { border-bottom-color: transparent; }
.loot-bar-fill {
  position: absolute; left: 0; right: 0; bottom: 0; background: var(--gold-dim);
  transition: height 0.5s ease, background-color 0.5s ease, opacity 0.12s ease;
}
.loot-bar-fill.has-value { background: var(--gold); }
/* The click/cursor hit area is the outline and fill, not the empty column above
   a short bar. */
.loot-bar-outline, .loot-bar-fill { cursor: pointer; }
/* Hover fades the fill, only over the outline or fill themselves. The outline is
   hovered first since it is the taller piece when an NPC is selected, and ~
   reaches the fill. :not(.selected) avoids a specificity tie with the selected
   dim below. Clicking a bar re-scopes the panels (see the loot-bar-col click
   handler). */
.loot-bar-col:not(.selected) .loot-bar-outline:hover ~ .loot-bar-fill,
.loot-bar-col:not(.selected) .loot-bar-fill:hover { opacity: 0.7; }
/* Selected bar: dimmer than the hover fade so it looks the same with or without
   the pointer on it. */
.loot-bar-col.selected .loot-bar-fill { opacity: 0.4; }
.loot-bar-x-labels { display: flex; gap: 3px; padding-left: 10px; margin-top: 6px; }
/* min-width: 0 overrides min-width: auto. Labels line up with their bars only if
   both rows shrink evenly; a label with text (see labelStep) would otherwise
   keep its min-content width and drag later labels ("NOW") off their bars at
   narrow widths. An overflowing label spills past its column, still centered on
   it. */
.loot-bar-x-label { flex: 1 1 0; min-width: 0; text-align: center; font-size: 9px; color: var(--text-faint); white-space: nowrap; }
.loot-bar-x-label.now { text-align: center; }

.loot-column-empty { color: var(--text-faint); font-size: 13px; margin: 0 0 10px; }

/* "By NPC" row (renderNpcRow): styled after Purchase Goals' .tracker-icon-btn
   row (copied). Identity is icon + tooltip only. */
/* gap matches .loot-item-list's. */
.loot-npc-row { display: flex; flex-wrap: wrap; gap: 8px; }
/* Fixed size: a quarter of the row minus the three 8px gaps, no grow/shrink, so
   a short row ends early.
   Height is two item boxes plus the 8px gap so the panels' rows line up (4 NPC
   boxes vs 6 item boxes per row). An item box is (panelWidth - 40px) / 6 square;
   cqw resolves against .loot-panel's container-type: inline-size. aspect-ratio
   is the fallback where container queries are unsupported. */
/* Wrapper holding the NPC box and its eye button as siblings (a <button> cannot
   nest in a <button>; as .pm-row-wrap in possessions.css). Carries the sizing;
   position: relative anchors .loot-eye-btn. */
.loot-npc-box-wrap { flex: 0 0 calc((100% - 24px) / 4); min-width: 0; box-sizing: border-box; position: relative; }
@supports not (container-type: inline-size) {
  .loot-npc-box-wrap { aspect-ratio: 3 / 4; }
}
@supports (container-type: inline-size) {
  .loot-npc-box-wrap { height: calc((100cqw - 40px) / 3 + 8px); }
}
.loot-npc-box {
  width: 100%; height: 100%; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 6px;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 10px 8px; cursor: pointer;
  min-width: 0; overflow: hidden;
}
/* Hidden entries (see npcEffectiveHidden) shown via "show hidden" are dimmed.
   Dims the box, not the wrap, so the sibling eye button stays at full opacity. */
.loot-npc-box-wrap.hidden-entry .loot-npc-box { opacity: 0.45; }
/* Hover lightens the background (rgb(51,51,54) is ~1.35x panel-2) rather than
   filter: brightness, which would also brighten the icon and text. */
.loot-npc-box:hover { background-color: rgb(51, 51, 54); }
.loot-npc-box.active { border-color: var(--gold); }
/* Scales with the box instead of a fixed 56px: at narrow desktop widths a
   quarter of the row is narrower than 56px + padding, which pushed the tile past
   its slot. */
.loot-npc-box-icon { width: min(56px, 80%); height: auto; aspect-ratio: 1 / 1; object-fit: contain; image-rendering: pixelated; }
/* Detail-render tiles: wiki "detail" images or portraits that look oversized at
   the shared 56px are drawn at 70%. transform: scale, not a smaller
   width/height: .loot-npc-box centers the icon+kc+value stack, so shrinking the
   icon would pull the text up, while a transform leaves the 56x56 slot
   untouched. Plain portraits that read large (crawling hand, implings, spider,
   death spawn, goblin) need no _NPC_DISPLAY_OVERRIDES entry in app/loot.py. */
.loot-npc-box-icon-casket,
/* Intricate pouch. */
.loot-npc-box-icon-pouch,
.loot-npc-box-icon-crawling-hand,
.loot-npc-box-icon-impling,
/* Seed pack / bird nest sources: detail render here only; the item panel shows
   the plain icon. */
.loot-npc-box-icon-seedpack,
.loot-npc-box-icon-birdnest,
/* Sailing salvage tiers. */
.loot-npc-box-icon-salvage,
.loot-npc-box-icon-spider,
.loot-npc-box-icon-death-spawn,
.loot-npc-box-icon-goblin,
.loot-npc-box-icon-rockslug,
.loot-npc-box-icon-hellhound,
.loot-npc-box-icon-araxyte,
.loot-npc-box-icon-scion,
.loot-npc-box-icon-juvenile-custodian-stalker,
.loot-npc-box-icon-turoth,
.loot-npc-box-icon-spawn,
.loot-npc-box-icon-imp,
.loot-npc-box-icon-ram,
.loot-npc-box-icon-calf,
.loot-npc-box-icon-chicken,
/* Dossier, Unsired, Forgotten lockbox and Cache of runes: detail renders in _NPC_DISPLAY_OVERRIDES (app/loot.py). */
.loot-npc-box-icon-dossier,
.loot-npc-box-icon-unsired,
.loot-npc-box-icon-forgotten-lockbox,
.loot-npc-box-icon-cache-of-runes {
  transform: scale(0.7);
}
/* Tarnished items (nine NPCs in one tile): padding shrinks the picture inside
   the 56x56 slot so it is drawn once at final size; a scale transform re-samples
   and comes out soft. Smooth render, so pixelated is off. */
.loot-npc-box-icon-tarnished {
  padding: 14%;
  image-rendering: auto;
}
.loot-npc-box-kc {
  font-size: 11px; color: var(--text-dim); text-align: center; line-height: 1.15;
  font-variant-numeric: tabular-nums;
}
@supports (container-type: inline-size) {
  .loot-npc-box-kc { font-size: clamp(9px, 2.8cqw, 11px); }
  .loot-npc-box-value { font-size: clamp(8.5px, 2.7cqw, 10.5px); }
}
.loot-npc-box.active .loot-npc-box-kc { color: var(--text); }
.loot-npc-box-value { font-size: 10.5px; color: var(--gold-dim); font-variant-numeric: tabular-nums; }
.loot-npc-box.active .loot-npc-box-value { color: var(--gold); }
/* Shift-click multi-select (2+ NPCs): blue outline instead of .active's gold
   border, never both; matches .gear-slot.multi-selected (purchase-goals.css). */
.loot-npc-box.multi-selected { outline: 2px solid var(--blue); outline-offset: -2px; }

/* Two columns below the chart (NPC panel, item panel); stacks when the
   search/sort row would get cramped. */
.loot-panels { display: flex; gap: 18px; align-items: flex-start; }
/* container-type: inline-size makes this a query container so .loot-npc-box can
   size its height from the panel width (cqw); min-width: 0 keeps width
   independent of content, as containment requires. Card styling matches
   .loot-chart-card; border-box keeps the panels equal width. */
.loot-panel {
  flex: 1 1 0; min-width: 0; container-type: inline-size; box-sizing: border-box;
  background: var(--panel-translucent); border: 1px solid var(--border);
  padding: 16px 18px;
}

/* Search box and sort tabs each take a full-width row (side by side they cramp;
   see _sort_tabs in app/pages/). */
.loot-panel-controls { display: flex; flex-direction: column; gap: 8px; margin-bottom: 10px; }
.loot-search { width: 100%; height: 34px; padding: 0 10px; font-size: 13px; }
/* Wrapper so the CLEAR button can overlay the input's right edge (as
   .pm-search-group in possessions.css); the input's right padding keeps text
   clear of it. */
.loot-search-group { position: relative; }
.loot-search-group .loot-search { padding-right: 46px; }
.loot-search-clear {
  position: absolute; top: 50%; right: 10px; transform: translateY(-50%);
  background: none; border: none; padding: 0; margin: 0;
  font-size: 10.5px; letter-spacing: 0.03em; text-transform: uppercase;
  color: var(--text-faint); cursor: pointer;
}
.loot-search-clear:hover { color: var(--text); }

/* Equal-width toggle buttons, one active at a time, mirroring Purchase Goals'
   .sort-btn (copied). Each tab toggles ascending/descending in place via
   .loot-sort-arrow (see _sort_tabs, updateSortTabs). */
.loot-sort-tabs { display: flex; gap: 5px; }
/* 25px is the site-wide button height shared by all buttons and segmented
   controls. */
.loot-sort-tab {
  flex: 1;
  height: 25px;
  display: flex; align-items: center; justify-content: center;
  padding: 0 3px;
  font-size: 10px; letter-spacing: 0.02em; text-transform: uppercase;
  color: var(--text-dim);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer;
  text-align: center;
}
.loot-sort-tab:hover { border-color: var(--gold-dim); color: var(--text); }
.loot-sort-tab.active { border-color: var(--gold); color: var(--gold); }
/* RuneScapePlain11 (myscape.css) has no arrow glyphs; the system-font fallback
   has a taller line box that sits the arrow low, so it is nudged up. */
.loot-sort-arrow { position: relative; top: -1px; }

/* "Show hidden" eye toggle: same box as .loot-sort-tab, icon-only and fixed
   width. .active reuses its gold. The icon is always the open eye, unlike the
   per-tile .loot-eye-btn. */
.loot-hide-toggle {
  flex: 0 0 26px;
  height: 25px;
  display: flex; align-items: center; justify-content: center;
  padding: 0;
  color: var(--text-dim);
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  cursor: pointer;
}
.loot-hide-toggle svg { display: block; }
.loot-hide-toggle:hover { border-color: var(--gold-dim); color: var(--text); }
.loot-hide-toggle.active { border-color: var(--gold); color: var(--gold); }

@media (max-width: 640px) {
  .loot-panels { flex-direction: column; }
}

/* Item panel: the same small-box grid as the NPC panel (name on hover). Data
   from windowItems/npcItems in build_loot_state (app/loot.py). */
.loot-item-list { display: flex; flex-wrap: wrap; gap: 8px; }
/* Fixed size: a sixth of the row minus the five 8px gaps, no grow/shrink;
   aspect-ratio: 1/1 keeps it square. */
/* Sibling wrap as .loot-npc-box-wrap: an <a> cannot contain a <button>. Carries
   the sizing. */
.loot-item-box-wrap { flex: 0 0 calc((100% - 40px) / 6); min-width: 0; aspect-ratio: 1 / 1; box-sizing: border-box; position: relative; }
.loot-item-box {
  width: 100%; height: 100%; box-sizing: border-box;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px;
  background: var(--panel-2); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 4px; min-width: 0; overflow: hidden;
  /* An <a> to the item's wiki page (see wikiItemUrl): default link styling is
     reset. */
  color: inherit; text-decoration: none; cursor: pointer;
}
.loot-item-box-wrap.hidden-entry .loot-item-box { opacity: 0.45; }
.loot-item-box:hover {
  background-color: rgb(51, 51, 54);
  /* myscape.css's a:hover underline ties the base reset on specificity and would
     underline the qty/gp text; class + :hover beats it. */
  text-decoration: none;
}
/* RuneLite's item-icon CDN (item_icon_url in app/purchase_goals.py) draws items
   on a fixed 36x32 canvas with room on the right for the stack-count badge, so
   the art sits left of center (measured over ~30 icons: about -5.5% of width,
   +1% of height). object-fit: contain cannot know that, so this translate shifts
   CDN item icons right/up by the average offset. NPC portraits and bundled icons
   are not drawn this way. */
.loot-item-box-icon {
  width: min(28px, 70%); height: auto; aspect-ratio: 1 / 1; object-fit: contain; image-rendering: pixelated;
  transform: translate(5.5%, -1%);
}
.loot-item-box-qty { font-size: 9px; color: var(--text-dim); text-align: center; line-height: 1; font-variant-numeric: tabular-nums; }
.loot-item-box-value { font-size: 8px; color: var(--gold-dim); line-height: 1; font-variant-numeric: tabular-nums; }
/* Tiles stay six per row at every desktop width and their contents scale with
   the tile (28px icon in a ~59px tile), capped at full size; fixed-size contents
   spilled out of ~40px tiles. The phone layout is separate. */
@media (min-width: 701px) {
  @supports (container-type: inline-size) {
    .loot-item-box { padding: min(4px, calc((100cqw - 40px) * 0.0113)); gap: min(2px, calc((100cqw - 40px) * 0.0057)); }
    .loot-item-box-icon { width: min(28px, calc((100cqw - 40px) * 0.0792)); height: auto; aspect-ratio: 1 / 1; }
    .loot-item-box-qty { font-size: min(9px, calc((100cqw - 40px) * 0.0253)); }
    .loot-item-box-value { font-size: min(8px, calc((100cqw - 40px) * 0.0225)); }
  }
}

/* Per-tile hide/unhide eye in the top-right of each wrap: open eye hides,
   crossed-out unhides (EYE_GLYPH/EYE_OFF_GLYPH). Gray, gold on hover, as
   .pm-pin-btn (possessions.css), but shown only while the wrap is hovered. */
.loot-eye-btn {
  position: absolute; top: 4px; right: 4px;
  width: 18px; height: 18px; padding: 0; margin: 0;
  display: flex; align-items: center; justify-content: center;
  background: none; border: none; border-radius: var(--radius);
  cursor: pointer;
  color: var(--text-dim);
  opacity: 0; pointer-events: none;
  transition: opacity 0.12s, color 0.12s;
}
.loot-eye-btn svg { display: block; }
.loot-npc-box-wrap:hover .loot-eye-btn,
.loot-item-box-wrap:hover .loot-eye-btn { opacity: 1; pointer-events: auto; }
.loot-eye-btn:hover { color: var(--gold); }

/* Landing page preview (render_landing_loot_preview in app/pages/): the real
   page reused; only these rules are preview-specific. */

/* Fits the panel in one landing scroll-snap slide (.landing-anchor has
   min-height: 100vh and no max). 80px is its top+bottom padding; svh follows vh
   for the mobile address bar.
   Clipped, not scrolled, so no independent scrollbar appears; the ::after
   feather fades the cut edge and position: relative anchors it. */
.landing-loot-preview {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
  /* A fixed height, not a max-height: filtering to a row or two would otherwise
     shrink the container and make the bottom feather blink out. */
  height: calc(100vh - 80px);
  height: calc(100svh - 80px);
  overflow: hidden;
  position: relative;
}
/* Fades the last ~15% of the height to --bg (the .landing-anchor background).
   pointer-events: none so clicks reach tiles beneath it. Always painted: the
   fixed height leaves no short-content case to gate it. */
.landing-loot-preview::after {
  content: '';
  position: absolute;
  left: 0; right: 0; bottom: 0;
  height: 15%;
  background: linear-gradient(to bottom, transparent, var(--bg));
  pointer-events: none;
}

/* The range selector is non-interactive in the preview (fixed one-day snapshot):
   no caret, default cursor. It keeps .loot-range-btn:hover since
   border-color/color are untouched. */
.loot-range-btn--static { cursor: default; }
.loot-range-btn--static .loot-range-caret { display: none; }

/* Two-line title row on a share page (myscape.io/s/<code>,
   render_loot_tracker_share in app/pages/): the date range on a .subtitle line
   (this rule adds centering/spacing), then "Shared by <name>" carrying
   .page-title, so there is one title-sized heading. */
.loot-share-range { text-align: center; margin: 0 0 4px; }

/* Landing-preview hero row: character + tagline replacing the heading (see
   hero_markup in render_landing_loot_preview). Scoped to .landing-loot-preview. */

/* Hidden rather than removed so _loot_tracker_panel_markup stays unchanged. */
.landing-loot-preview .page-title { display: none; }

/* Flex row, align-items: flex-end: the row is as tall as the character and its
   bottom edge is the chart card's top border, so the character ends flush on it
   with no overlap or gap. */
.loot-preview-hero {
  display: flex;
  align-items: flex-end;
}
/* Stretches to the row's height (overriding flex-end) so its flex-centered text
   centers beside .loot-preview-char. */
.loot-preview-tagline-wrap {
  flex: 1 1 auto;
  align-self: stretch;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0; /* lets the row below actually shrink instead of overflowing the card */
}
.loot-preview-tagline {
  margin: 0;
  max-width: 100%;
  min-width: 0; /* flex items default to their content's width as a floor -- without this, the truncation below can never actually kick in */
  text-align: center;
  font-size: 30px;
  line-height: 1.25;
  font-weight: 400; /* unbolded -- was 600 */
  white-space: nowrap;
  /* Engages only on a viewport too narrow for the full line: centered text
     overflowing a box spills evenly, and with overflow: hidden would lose both
     ends, so it reads off both edges instead. */
  overflow: hidden;
  text-overflow: ellipsis;
}
.loot-preview-tagline-gold { color: var(--gold); }
.loot-preview-tagline-white { color: var(--text); }

/* Downscaled from the 340x410 source (already cropped to its upper half). Fixed
   height, not width, as .purchase-preview-char (purchase-goals.css) so both
   characters match despite different aspect ratios; width follows. 157px is the
   old 130px width at 410/340; .purchase-preview-char matches it. */
.loot-preview-char {
  flex: 0 0 auto;
  height: 157px;
  line-height: 0;
}
/* Two classes beat myscape.css's .landing-anchor picture img (width: min(700px,
   82vw)), which would otherwise blow this character up. */
.landing-loot-preview .loot-preview-char img {
  display: block;
  height: 100%;
  max-height: none;
  width: auto;
  max-width: none;
}
/* Mirrors the character so he faces the tagline; applied to the img only, so
   layout is not mirrored. */
.landing-loot-preview .loot-preview-char--flipped img {
  transform: scaleX(-1);
}


/* Phone layout. 700px is the site-wide phone breakpoint (see
   character-overview.css). Scoped to body:not(.phone-off) so the homepage
   preview is unaffected.
   The .loot-panels column rule at 640px above leaves align-items: flex-start,
   which in a column shrinks each panel to its content width; container-type:
   inline-size makes that zero, collapsing panels to a ~36px sliver. Stretching
   fixes it. */
@media (max-width: 700px) {
  body:not(.phone-off) .loot-panels {
    flex-direction: column;
    align-items: stretch;
  }
  body:not(.phone-off) .loot-panel {
    width: 100%;
    flex: none;
    padding: 14px 12px;
  }
  body:not(.phone-off) .loot-chart-card {
    padding: 14px 12px 12px;
  }

  /* Sections at most 320px wide, centered, leaving plain page strips to scroll
     with a thumb (as the Character Overview phone page). */
  body:not(.phone-off) .loot-chart-card,
  body:not(.phone-off) .loot-panels {
    max-width: 320px;
    margin-left: auto;
    margin-right: auto;
    box-sizing: border-box;
  }

  /* Title on its own centered row (absolute centering got squeezed between the
     range button and totals). */
  body:not(.phone-off) .loot-chart-header {
    flex-wrap: wrap;
    row-gap: 12px;
  }
  body:not(.phone-off) .loot-chart-title {
    position: static;
    transform: none;
    order: 3;
    flex: 0 0 100%;
    max-width: 100%;
    text-align: center;
    white-space: normal;
  }

  /* Finger-sized controls; inputs at 16px, since smaller makes iOS Safari zoom
     in on focus. */
  body:not(.phone-off) .loot-sort-tab,
  body:not(.phone-off) .loot-hide-toggle {
    height: 36px;
    font-size: 12px;
  }
  body:not(.phone-off) .loot-hide-toggle {
    flex: 0 0 40px;
  }
  body:not(.phone-off) .loot-search {
    height: 40px;
    font-size: 16px;
  }
  body:not(.phone-off) .loot-range-custom-field input[type="text"] {
    font-size: 16px;
    padding: 8px 6px;
  }
  body:not(.phone-off) .loot-range-option,
  body:not(.phone-off) .loot-range-apply {
    padding: 10px 8px;
    font-size: 12px;
  }

  /* Share popup anchored to the title row, centered and no wider than the page:
     the fixed 280px popup under the small icon ran off the right edge. */
  body:not(.phone-off) .page-title:has(.loot-share-wrap) {
    position: relative;
  }
  body:not(.phone-off) .loot-share-wrap {
    position: static;
  }
  body:not(.phone-off) .loot-share-card {
    top: calc(100% + 6px);
    width: min(280px, 100%);
    box-sizing: border-box;
  }

  body:not(.phone-off) .loot-bar-x-label {
    font-size: 10px;
  }
  body:not(.phone-off) .loot-bar-gridline-label {
    font-size: 11px;
  }

  /* Four item tiles per row (six were ~48px with 8-9px text); NPC tiles stay
     four with slightly larger text. */
  body:not(.phone-off) .loot-item-box-wrap {
    flex: 0 0 calc((100% - 24px) / 4);
  }
  body:not(.phone-off) .loot-item-box-icon {
    width: 30px;
    height: 30px;
  }
  body:not(.phone-off) .loot-item-box-qty {
    font-size: 12px;
  }
  body:not(.phone-off) .loot-item-box-value {
    font-size: 11px;
  }
  /* The 56px icon plus padding is wider than a quarter of a ~320px row and flex
     items do not shrink below content, so only three tiles fit; the tile and
     icon scale with the row. */
  body:not(.phone-off) .loot-npc-box-wrap,
  body:not(.phone-off) .loot-npc-box {
    min-width: 0;
  }
  body:not(.phone-off) .loot-npc-box {
    padding-left: 2px;
    padding-right: 2px;
  }
  body:not(.phone-off) .loot-npc-box-icon {
    width: min(52px, 64%);
    height: auto;
    aspect-ratio: 1 / 1;
  }
  body:not(.phone-off) .loot-npc-box-icon-tarnished {
    padding: 15%;
  }
  body:not(.phone-off) .loot-npc-box-kc {
    font-size: 12px;
  }
  body:not(.phone-off) .loot-npc-box-value {
    font-size: 11px;
  }
}

/* Touch screens cannot hover to reveal the per-tile eye, so the eyes show only
   while the panel's eye toggle is on, dimmed with a bigger tap area. */
@media (hover: none) {
  body:not(.phone-off) .loot-eye-btn,
  body:not(.phone-off) .loot-npc-box-wrap:hover .loot-eye-btn,
  body:not(.phone-off) .loot-item-box-wrap:hover .loot-eye-btn {
    opacity: 0;
    pointer-events: none;
    width: 26px;
    height: 26px;
    top: 2px;
    right: 2px;
  }
  body:not(.phone-off) .loot-panel:has(.loot-hide-toggle.active) .loot-eye-btn,
  body:not(.phone-off) .loot-panel:has(.loot-hide-toggle.active) .loot-npc-box-wrap:hover .loot-eye-btn,
  body:not(.phone-off) .loot-panel:has(.loot-hide-toggle.active) .loot-item-box-wrap:hover .loot-eye-btn {
    opacity: 0.65;
    pointer-events: auto;
  }
}
