/* ============================================================================
   style.css — Core styles: layout, panels, results, modal, priority chips, footer.

   MHUR Tuning Optimizer — fan-made tool for My Hero Ultra Rumble.
   Author: RDH
   ============================================================================ */

:root {
  --bg: #0e1116;
  --panel: #161b22;
  --panel-2: #1c222b;
  --border: #2a313c;
  --text: #e7eaee;
  --text-dim: #93a0b0;
  --hero: #3aa0ff;
  --hero-dim: #1c3a55;
  --villain: #ff4d5e;
  --villain-dim: #4a1d22;
  --gold: #e8b84b;
  --assault: #ff8a4c;
  --rapid: #3ad6c4;
  --support: #9d7bff;
  --strike: #ff5c7a;
  --fixer: #b478ff;
  --technical: #5ad1ff;
  --radius: 10px;
  --cat-real-assault: #f7d046;
  --cat-real-rapid: #4da6ff;
  --cat-real-technical: #b15cff;
  --cat-real-support: #3ddc84;
  --cat-real-strike: #ff5252;
  /* In-game health/guard bar colors, used by the Tuning Totals stat-combo
     lines (HP bar = green, GP bar = blue - confirmed via ultrarumble.com's
     gameplay guide). Exact hex approximated from the in-game HUD; if a
     side-by-side with a real screenshot shows drift, correct it HERE only -
     everything reads these two vars. */
  --hpbar: #58e14e;
  --gpbar: #4db5ff;
  font-family:
    -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
    sans-serif;
}

* {
  box-sizing: border-box;
}
html,
body {
  margin: 0;
  padding: 0;
  background: var(--bg);
  color: var(--text);
  min-height: 100vh;
}
body {
  font-size: 15px;
  line-height: 1.4;
}

header.top {
  display: flex;
  align-items: center;
  gap: 14px;
  flex-wrap: wrap;
  padding: 18px 24px;
  border-bottom: 1px solid var(--border);
  background: linear-gradient(180deg, #11151c, #0e1116);
  position: sticky;
  top: 0;
  z-index: 50;
  /* When launched as an installed PWA ("Add to Home Screen"), iOS/Android
     draw the app full-screen with no browser chrome at all - just this
     sticky header up against the very top of the display, right under the
     status bar/clock/battery icons and (on notched phones) the camera
     cutout. In a normal browser tab this isn't an issue since the browser's
     own address bar already pushes page content down, which is why "fine on
     the website, blocked on the home-screen app" was the exact symptom.
     env(safe-area-inset-top) is the standard way to ask the OS how much
     extra top padding is needed to clear that area - it's 0 in a normal
     browser tab (so this is a no-op there) and becomes the actual notch/
     status-bar height in standalone PWA mode. Requires viewport-fit=cover
     in the <meta name="viewport"> tag (already present in every page) for
     env() to report a real, non-zero value at all. */
  padding-top: calc(18px + env(safe-area-inset-top));
}
header.top h1 {
  font-size: 19px;
  margin: 0;
  font-weight: 800;
  letter-spacing: 0.3px;
  background: linear-gradient(90deg, var(--hero), var(--villain));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}
header.top h1 a {
  color: inherit;
  text-decoration: none;
}
header.top .sub {
  color: var(--text-dim);
  font-size: 12.5px;
}
.top-nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 16px;
  flex-shrink: 0;
  flex-wrap: wrap;
}
.top-nav a {
  color: var(--text-dim);
  text-decoration: none;
  font-size: 13px;
}
.top-nav a:hover {
  color: var(--hero);
}
/* Marks whichever nav link matches the current page. Same gradient
   treatment as the "MHUR TUNING OPTIMIZER" brand title in header.top h1,
   just reused here instead of swapping the title out for a page name -
   see "Top nav now always shows the brand title" in PROJECT_KNOWLEDGE.md. */
.top-nav a.active {
  background: linear-gradient(90deg, var(--hero), var(--villain));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 700;
}

.layout {
  display: grid;
  grid-template-columns: 380px 1fr;
  gap: 20px;
  padding: 20px 24px;
  max-width: 1500px;
  margin: 0 auto;
}
/* Grid items default to min-width:auto (sized to their CONTENT's intrinsic
   width, not the space actually available) - without this override, if
   anything inside .sidebar or .main has a wide enough min-content size,
   the whole grid column (and therefore the page) can render wider than the
   viewport on a narrow phone, even though every individual rule elsewhere
   looks correctly responsive in isolation. This is the standard fix for
   "overflows on mobile, especially after a relayout like rotating the
   device forces browsers to re-measure intrinsic content widths." */
.sidebar,
.main {
  min-width: 0;
}
@media (max-width: 980px) {
  .layout {
    grid-template-columns: 1fr;
  }
}

.panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  padding: 16px;
}
.panel + .panel {
  margin-top: 16px;
}
.panel h2 {
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--text-dim);
  margin: 0 0 12px;
  font-weight: 700;
}

select,
input[type="text"] {
  width: 100%;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 9px 10px;
  font-size: 14px;
  outline: none;
}
select:focus,
input[type="text"]:focus {
  border-color: var(--hero);
}

.class-badge {
  font-size: 10px;
  font-weight: 700;
  padding: 2px 6px;
  border-radius: 5px;
  letter-spacing: 0.04em;
}
.class-badge.HERO {
  background: var(--hero-dim);
  color: var(--hero);
}
.class-badge.VILLAIN {
  background: var(--villain-dim);
  color: var(--villain);
}

.skill-search {
  margin-bottom: 10px;
}
.skill-list {
  max-height: 260px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding-right: 4px;
}
.skill-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 7px 9px;
  border-radius: 7px;
  background: var(--panel-2);
  border: 1px solid transparent;
  cursor: pointer;
  transition: 0.12s;
}
.skill-row:hover {
  border-color: var(--border);
}
.skill-row.selected {
  border-color: var(--gold);
  background: #241f12;
}
.skill-row input {
  accent-color: var(--gold);
}
.skill-row .name {
  font-weight: 600;
  font-size: 13.5px;
  flex: 1;
}
.skill-row .cat-tag {
  font-size: 10px;
  padding: 2px 6px;
  border-radius: 5px;
  font-weight: 700;
  letter-spacing: 0.03em;
}
.cat-text-ASSAULT {
  color: var(--cat-real-assault);
  font-weight: 700;
}
.cat-text-RAPID {
  color: var(--cat-real-rapid);
  font-weight: 700;
}
.cat-text-TECHNICAL {
  color: var(--cat-real-technical);
  font-weight: 700;
}
.cat-text-SUPPORT {
  color: var(--cat-real-support);
  font-weight: 700;
}
.cat-text-STRIKE {
  color: var(--cat-real-strike);
  font-weight: 700;
}
.cat-real-ASSAULT {
  background: #3a2f10;
  color: var(--cat-real-assault);
}
.cat-real-RAPID {
  background: #142a3a;
  color: var(--cat-real-rapid);
}
.cat-real-TECHNICAL {
  background: #2a1c3a;
  color: var(--cat-real-technical);
}
.cat-real-SUPPORT {
  background: #123a26;
  color: var(--cat-real-support);
}
.cat-real-STRIKE {
  background: #3a1414;
  color: var(--cat-real-strike);
}
.skill-row .desc {
  font-size: 11.5px;
  color: var(--text-dim);
  display: block;
  width: 100%;
  margin-top: 2px;
}

/* chosen-bar is now a column: the "Prioritize effects" toggle sits above the
   chip row, and the chips themselves are the drag-reorderable priority list. */
.chosen-bar {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin-top: 10px;
}
.chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.chip {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--panel-2);
  border: 1px solid var(--gold);
  color: var(--gold);
  font-size: 12px;
  font-weight: 600;
  padding: 4px 8px;
  border-radius: 20px;
}
.chip button {
  background: none;
  border: none;
  color: var(--gold);
  cursor: pointer;
  font-size: 13px;
  line-height: 1;
  padding: 0;
}

/* ---------------- Effect priority list ---------------- (RDH)
   With priority ON the selected effects become a VERTICAL ranked list. Vertical is
   deliberate: a horizontal wrapping chip row is a poor drag surface (rows reflow
   mid-drag, targets are tiny on a phone). Every row is full width and drag is a
   single axis. Each row also carries ▲▼ buttons, which always work even if the
   drag gesture is fiddly. */
.prio-head {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.prio-toggle {
  display: flex;
  align-items: center;
  gap: 6px;
  cursor: pointer;
  font-size: 12.5px;
  color: var(--text);
  user-select: none;
}
.prio-toggle input {
  cursor: pointer;
}
.prio-hint {
  font-size: 11px;
  color: var(--text-dim);
  line-height: 1.35;
}

.prio-list {
  display: flex;
  flex-direction: column;
  gap: 5px;
}

/* The WHOLE row is the drag handle - nothing small to aim at. touch-action:none
   is therefore on the row itself: dragging a row must not scroll the page. The
   list is only a few rows tall, so the rest of the page still scrolls fine.
   The transform transition is what makes the OTHER rows glide aside to open a
   gap; the dragged row disables it (below) so it tracks the finger exactly. (RDH) */
.prio-item {
  display: flex;
  align-items: center;
  gap: 9px;
  background: var(--panel-2);
  border: 1px solid var(--gold);
  border-radius: 8px;
  padding: 8px 10px;
  color: var(--gold);
  font-size: 12.5px;
  font-weight: 600;
  cursor: grab;
  touch-action: none;
  user-select: none;
  transition: transform 0.16s ease;
}
.prio-item:active {
  cursor: grabbing;
}
/* The name gets the full remaining width now that the ▲▼ buttons are gone. */
.prio-item .prio-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.prio-rank {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  border-radius: 50%;
  background: var(--gold);
  color: #1a1408;
  font-size: 10px;
  font-weight: 700;
  flex-shrink: 0;
}

/* Purely a visual affordance now ("this row is draggable") - the whole row is
   the handle, so the grip is not itself a target. */
.prio-grip {
  color: var(--text-dim);
  font-size: 14px;
  line-height: 1;
  flex-shrink: 0;
  pointer-events: none;
}

.prio-remove {
  background: none;
  border: none;
  color: var(--gold);
  cursor: pointer;
  font-size: 16px;
  line-height: 1;
  padding: 2px 3px;
  flex-shrink: 0;
}

/* The row being dragged: lifted off the list and following the finger. No
   transition, or it would lag behind the pointer. Slightly scaled + shadowed so
   it reads as "picked up", exactly like dragging an app icon. (RDH) */
.prio-item.dragging {
  transition: none;
  cursor: grabbing;
  position: relative;
  z-index: 5;
  background: #241f12;
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.5);
  scale: 1.02;
}

.special-tuning-bar {
  margin-bottom: 18px;
}
.special-tuning-row {
  display: flex;
  align-items: flex-end;
  gap: 14px;
  flex-wrap: wrap;
}
.st-group {
  display: flex;
  flex-direction: column;
  gap: 5px;
  min-width: 180px;
  flex: 1;
}
.st-label {
  font-size: 11.5px;
  color: var(--text-dim);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.st-col-hint {
  color: var(--gold);
  font-weight: 700;
}

.fixer-toggle-row {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  cursor: pointer;
  font-size: 13px;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--panel-2);
  border: 1px solid var(--border);
}
.fixer-toggle-row input {
  margin-top: 2px;
  accent-color: var(--gold);
}
.fixer-toggle-row small {
  color: var(--text-dim);
  font-size: 10.5px;
  font-weight: 400;
}

.require-columns-row {
  display: flex;
  align-items: center;
  gap: 7px;
  cursor: pointer;
  font-size: 12.5px;
  padding: 6px 10px;
  border-radius: 8px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  white-space: nowrap;
}
.require-columns-row input {
  accent-color: var(--gold);
}

.disabled-group {
  opacity: 0.4;
  pointer-events: none;
}

.fixer-toggle-note {
  font-size: 11.5px;
  color: var(--text-dim);
  margin: 10px 0 0;
}
.fixer-badge {
  position: absolute;
  top: 8px;
  right: 8px;
  background: #241f12;
  color: var(--gold);
  border: 1px solid var(--gold);
  font-size: 10.5px;
  font-weight: 700;
  padding: 2px 7px;
  border-radius: 6px;
}
.slot-item.fixer-slot {
  border-color: var(--gold);
  background: #1c180e;
}
.fixer-slot-note {
  color: var(--gold);
  font-size: 11.5px;
  font-weight: 600;
  margin: 4px 0 2px;
  line-height: 1.35;
}
.match-line {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 3px;
}
.match-extra {
  display: contents;
}
.match-extra[hidden] {
  display: none;
}
.match-toggle {
  background: none;
  border: none;
  padding: 0;
  margin-top: 2px;
  color: var(--text-dim);
  font-size: 11px;
  cursor: pointer;
  text-decoration: underline;
}
.match-toggle:hover {
  color: var(--text);
}
.face-icon-sm {
  width: 20px;
  height: 20px;
  border-radius: 5px;
  object-fit: cover;
  vertical-align: middle;
  flex-shrink: 0;
}

.char-select {
  position: relative;
}
#characterSearchInput {
  cursor: pointer;
}
#characterSearchInput:not([readonly]) {
  cursor: text;
}
.char-display-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 9px 10px;
  font-size: 14px;
  cursor: pointer;
  text-align: left;
}
.cdb-name {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.cdb-badges {
  display: flex;
  gap: 6px;
  flex-shrink: 0;
}
.char-select-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 60;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  max-height: 280px;
  overflow-y: auto;
  box-shadow: 0 8px 24px #000a;
}
.cs-option {
  padding: 8px 10px;
  font-size: 13.5px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.cs-option-none {
  color: var(--text-dim);
  font-style: italic;
}
.cs-option:last-child {
  border-bottom: none;
}
.cs-option:hover {
  background: #222a35;
}
.cs-option-disabled {
  color: var(--text-dim);
  cursor: not-allowed;
  opacity: 0.5;
}
.cs-option-disabled:hover {
  background: none;
}
.cs-empty {
  padding: 10px;
  font-size: 12.5px;
  color: var(--text-dim);
}

.face-select {
  position: relative;
}
.face-select-btn {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  padding: 9px 10px;
  font-size: 13.5px;
  cursor: pointer;
  text-align: left;
}
.face-select-btn::after {
  content: "▾";
  color: var(--text-dim);
  font-size: 11px;
  margin-left: 6px;
}
.face-select.disabled-group .face-select-btn {
  cursor: not-allowed;
}
.fs-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}
.fs-faces {
  display: flex;
  gap: 3px;
  flex-shrink: 0;
}
.face-select-list {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 60;
  background: var(--panel-2);
  border: 1px solid var(--border);
  border-radius: 8px;
  max-height: 320px;
  overflow-y: auto;
  box-shadow: 0 8px 24px #000a;
}
.fs-search {
  width: 100%;
  border: none;
  border-bottom: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text);
  padding: 9px 10px;
  font-size: 13px;
  outline: none;
  position: sticky;
  top: 0;
}
.fs-options {
}
.fs-option {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 8px 10px;
  font-size: 13px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
}
.fs-option:last-child {
  border-bottom: none;
}
.fs-option:hover:not(.disabled) {
  background: #222a35;
}
.fs-option.active {
  background: #241f12;
  color: var(--gold);
}
.fs-option.disabled {
  opacity: 0.35;
  cursor: not-allowed;
}
.fs-name {
  display: flex;
  align-items: center;
  gap: 6px;
  flex: 1;
  min-width: 0;
}

.results-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
}
.results-head h2 {
  margin: 0;
  font-size: 16px;
}
.results-head-top {
  display: flex;
  align-items: baseline;
  gap: 14px;
  flex-wrap: wrap;
}
.only-3star-toggle {
  display: flex;
  align-items: baseline;
  gap: 6px;
  cursor: pointer;
  font-size: 12.5px;
  color: var(--text-dim);
}
.only-3star-toggle input {
  accent-color: var(--gold);
}
.only-3star-toggle:hover {
  color: var(--text);
}
.results-count {
  color: var(--text-dim);
  font-size: 12.5px;
}

.results-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(230px, 1fr));
  gap: 14px;
  min-width: 0;
}

.costume-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  cursor: pointer;
  transition:
    transform 0.12s,
    border-color 0.12s;
  display: flex;
  flex-direction: column;
}
.costume-card:hover {
  transform: translateY(-3px);
  border-color: var(--gold);
}
.costume-card .rank {
  position: absolute;
  top: 8px;
  left: 8px;
  background: #000a;
  color: var(--gold);
  font-weight: 800;
  font-size: 12px;
  border-radius: 6px;
  padding: 2px 7px;
}
.costume-card .imgwrap {
  position: relative;
  background: radial-gradient(circle at 50% 20%, #1d2330, #0c0f14);
  display: flex;
  align-items: center;
  justify-content: center;
  height: 190px;
}
.costume-card img {
  max-width: 90%;
  max-height: 100%;
  object-fit: contain;
}
.costume-card .body {
  padding: 10px 12px 12px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.costume-card .cname {
  font-weight: 700;
  font-size: 13.5px;
}
.costume-card .cname-character {
  font-size: 11px;
  color: var(--text-dim);
  margin-top: 1px;
}
.costume-card .meta {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11.5px;
  color: var(--text-dim);
}
.score-pill {
  background: var(--hero-dim);
  color: var(--hero);
  font-weight: 800;
  border-radius: 6px;
  padding: 2px 8px;
  font-size: 12.5px;
}

.costume-picker-toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  cursor: pointer;
  user-select: none;
}
.costume-picker-toggle input {
  accent-color: var(--gold);
  width: 15px;
  height: 15px;
  cursor: pointer;
}
.costume-picker-head {
  display: flex;
  gap: 8px;
  margin: 10px 0;
  flex-wrap: wrap;
}
.costume-picker-reset-btn {
  background: var(--panel);
  border: 1px solid var(--border);
  color: var(--text-dim);
  border-radius: 6px;
  padding: 5px 10px;
  font-size: 12px;
  cursor: pointer;
  white-space: nowrap;
}
.costume-picker-reset-btn:hover {
  color: var(--text);
  border-color: var(--gold);
}
.costume-picker-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(90px, 1fr));
  gap: 8px;
  max-height: 340px;
  overflow-y: auto;
}
.costume-pick-tile {
  background: var(--panel);
  border: 1.5px solid var(--gold);
  border-radius: 8px;
  cursor: pointer;
  padding: 6px;
  text-align: center;
  transition:
    opacity 0.12s,
    border-color 0.12s;
}
.costume-pick-tile img {
  width: 100%;
  height: 60px;
  object-fit: contain;
  background: #0c0f14;
  border-radius: 4px;
}
.costume-pick-tile .cpt-label {
  font-size: 10.5px;
  font-weight: 600;
  margin-top: 4px;
  line-height: 1.25;
}
.costume-pick-tile .cpt-count {
  font-size: 9.5px;
  color: var(--text-dim);
}
.costume-pick-tile.deselected {
  opacity: 0.35;
  border-color: var(--border);
}
.costume-pick-tile.deselected .cpt-label {
  color: var(--text-dim);
}
.stars {
  color: var(--gold);
  font-size: 12px;
  letter-spacing: 1px;
}

.empty-state {
  color: var(--text-dim);
  text-align: center;
  padding: 60px 20px;
  font-size: 14px;
  grid-column: 1/-1;
  width: 100%;
}

/* Modal */
.modal-overlay {
  position: fixed;
  inset: 0;
  background: #000c;
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 200;
  padding: 20px;
}
.modal-overlay.open {
  display: flex;
}
.modal {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 14px;
  max-width: 680px;
  width: 100%;
  max-height: 88vh;
  overflow-y: auto;
}
.modal-top {
  display: flex;
  gap: 16px;
  padding: 20px;
  border-bottom: 1px solid var(--border);
}
.modal-top img {
  width: 140px;
  height: auto;
  border-radius: 8px;
  background: #0c0f14;
}
.modal-top .info {
  flex: 1;
}
.modal-top h3 {
  margin: 0 0 6px;
  font-size: 18px;
}
.modal-close {
  position: sticky;
  float: right;
  top: 10px;
  right: 10px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  color: var(--text);
  border-radius: 8px;
  width: 30px;
  height: 30px;
  cursor: pointer;
  font-size: 16px;
  margin: 10px;
}
.modal-section {
  padding: 16px 20px;
  border-bottom: 1px solid var(--border);
}
.modal-section h4 {
  margin: 0 0 10px;
  font-size: 12.5px;
  text-transform: uppercase;
  color: var(--text-dim);
  letter-spacing: 0.06em;
}
.modal-section-breakdown details summary {
  list-style: none;
  cursor: pointer;
  user-select: none;
  display: flex;
  align-items: center;
  gap: 6px;
}
.modal-section-breakdown details summary::-webkit-details-marker {
  display: none;
}
.modal-section-breakdown details summary h4 {
  margin: 0;
  transition: color 0.15s;
}
.modal-section-breakdown details summary::before {
  content: "▶";
  font-size: 9px;
  color: var(--text-dim);
  transition:
    transform 0.15s,
    color 0.15s;
  flex-shrink: 0;
}
.modal-section-breakdown details[open] summary::before {
  transform: rotate(90deg);
  color: var(--hero);
}
.modal-section-breakdown details[open] summary h4 {
  color: var(--text);
}
.modal-section-breakdown .breakdown-body {
  margin-top: 10px;
}
.slot-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
}
.slot-grid .slot-col {
  min-width: 0;
}
.slot-col h5 {
  margin: 0 0 8px;
  font-size: 11.5px;
  color: var(--text-dim);
  text-transform: uppercase;
}
.slot-item {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 8px;
  border-radius: 7px;
  background: var(--panel-2);
  border: 1px solid var(--border);
  margin-bottom: 6px;
}
.slot-item.matched {
  border-color: var(--gold);
}
.slot-item .slot-type-line {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 11.5px;
}
.slot-item .fill {
  font-size: 12px;
  color: var(--text);
}
.slot-item .fill.none {
  color: var(--text-dim);
  font-style: italic;
}
.restriction-tag {
  font-size: 9.5px;
  padding: 1px 5px;
  border-radius: 4px;
  font-weight: 700;
}
.restriction-HERO_ONLY {
  background: var(--hero-dim);
  color: var(--hero);
}
.restriction-VILLAIN_ONLY {
  background: var(--villain-dim);
  color: var(--villain);
}
.restriction-NONE {
  background: #262c35;
  color: var(--text-dim);
}
.alignment-PLAIN {
  background: #262c35;
  color: var(--text-dim);
}
.alignment-HERO {
  background: var(--hero-dim);
  color: var(--hero);
}
.alignment-VILLAIN {
  background: var(--villain-dim);
  color: var(--villain);
}

.create-build-btn {
  background: linear-gradient(90deg, var(--hero), #2a7fd6);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 9px 16px;
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
  transition:
    transform 0.12s,
    box-shadow 0.12s;
}
.create-build-btn:hover {
  transform: translateY(-1px);
  box-shadow: 0 4px 14px #3aa0ff55;
}

::-webkit-scrollbar {
  width: 8px;
}
::-webkit-scrollbar-thumb {
  background: #2a313c;
  border-radius: 8px;
}

.footer-note {
  padding: 30px;
  text-align: center;
  color: var(--text-dim);
  font-size: 11.5px;
  position: sticky;
  top: 100vh;
}

/* ===================== Tuning Totals: stat combo lines ===================== */
/* The rows wrapper is the positioning context for the SVG bracket lines that  (RDH)
   connect two combined stats in the right-hand gutter. The gutter width is
   set dynamically (padding-right) by drawTuningCombos() in faces.js based on
   how many combo "lanes" are needed - zero combos means zero gutter. */
.tt-rows {
  position: relative;
}
.tt-row {
  display: flex;
  align-items: center;
  gap: 8px;
}
.tt-row .bcard-row-skill {
  min-width: 0;
}
.tt-val {
  font-weight: 700;
  white-space: nowrap;
}
.tt-combo-svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  overflow: visible;
}
.tt-combo-svg .tt-combo-label {
  pointer-events: auto;
  cursor: pointer;
}
.tt-combo-btn {
  width: 26px;
  height: 26px;
  flex-shrink: 0;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--panel-2);
  color: var(--text-dim);
  font-size: 15px;
  font-weight: 700;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0;
  transition:
    border-color 0.12s,
    color 0.12s,
    transform 0.12s,
    opacity 0.12s;
}
.tt-combo-btn:hover {
  border-color: var(--gold);
  color: var(--gold);
}
.tt-combo-btn.tt-pending {
  border-color: var(--gold);
  background: #241f12;
  color: var(--gold);
  transform: scale(1.08);
}
.tt-combo-btn.tt-partner {
  border-color: var(--gold);
  color: var(--gold);
  animation: tt-partner-pulse 1.1s ease-in-out infinite;
}
.tt-combo-btn.tt-dim {
  opacity: 0.22;
  cursor: not-allowed;
}
.tt-combo-spacer {
  width: 26px;
  flex-shrink: 0;
}
@keyframes tt-partner-pulse {
  0%,
  100% {
    box-shadow: 0 0 0 0 rgba(232, 184, 75, 0);
  }
  50% {
    box-shadow: 0 0 0 4px rgba(232, 184, 75, 0.25);
  }
}
@media (prefers-reduced-motion: reduce) {
  .tt-combo-btn.tt-partner {
    animation: none;
  }
}
.tt-combo-hint {
  font-size: 11.5px;
  color: var(--text-dim);
  line-height: 1.5;
  border: 1px dashed var(--border);
  border-radius: 8px;
  padding: 7px 10px;
  margin-bottom: 12px;
}
.tt-combo-hint em {
  color: var(--text);
  font-style: normal;
  font-weight: 600;
}
.tt-rows.tt-picking .tt-row {
  transition: opacity 0.12s;
}

/* ===================== Mobile / touch responsiveness ===================== */
/* Prevent any stray fixed-width element from ever creating horizontal scroll. */
html,
body {
  overflow-x: hidden;
}

/* iOS Safari auto-zooms the page on focusing any input/select/textarea with a
   computed font-size under 16px - this forces every text entry point in the
   app to be at least 16px so typing on a phone never triggers that zoom. */
@media (max-width: 768px) {
  select,
  input[type="text"],
  .face-select-btn,
  .fs-search,
  .build-slot-select,
  .char-select input[type="text"] {
    font-size: 16px;
  }
}

@media (max-width: 900px) {
  /* Tablets/large phones: tighten outer spacing so more content fits without
     feeling cramped against the edges. */
  .layout {
    padding: 14px 16px;
    gap: 16px;
  }
  .panel {
    padding: 14px;
  }
  header.top {
    padding: 14px 16px;
    padding-top: calc(14px + env(safe-area-inset-top));
  }

  /* The optimizer's "slot-by-slot" modal columns and the build editor's
     LEFT/RIGHT columns are too narrow to read two-up once the viewport gets
     this tight - stack them instead. (build.css has the matching rule for
     .build-slot-grid at the same 700px point below; this one's slightly wider
     since the modal has its own internal padding eating more space.) */
  .modal-section .slot-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

@media (max-width: 700px) {
  /* Header: keep the title together, let the nav wrap to its own
     full-width row underneath instead of squeezing/overflowing. */
  header.top h1 {
    font-size: 16px;
  }
  header.top .sub {
    display: none;
  }
  .top-nav {
    width: 100%;
    justify-content: flex-start;
    margin-left: 0;
    gap: 18px;
  }

  /* Modal: side-by-side image+info gets too cramped to read on a phone -
     stack the image above the info block and center everything. */
  .modal-overlay {
    padding: 0;
    align-items: flex-end;
  }
  .modal {
    max-width: 100%;
    width: 100%;
    max-height: 92vh;
    border-radius: 14px 14px 0 0;
  }
  .modal-top {
    flex-direction: column;
    align-items: center;
    text-align: center;
  }
  .modal-top img {
    width: 120px;
  }
  .modal-top .info {
    width: 100%;
  }

  /* Bigger, easier-to-hit tap targets for icon-only / small controls.
     float:none is important here: a floated close button shrinks the
     adjacent .modal-top flex column (BFC shrink-to-avoid-float), which
     pushed the centered image/title/pill visibly left of center. Dropping
     the float lets .modal-top span the full width so align-items:center
     truly centers. margin-left:auto keeps the X pinned to the right, and
     it stays sticky (visible while scrolling the sheet). */
  .modal-close {
    width: 38px;
    height: 38px;
    font-size: 18px;
    float: none;
    display: block;
    margin: 10px 10px 0 auto;
  }
  .fs-option,
  .cs-option {
    padding: 11px 10px;
  }

  /* Special-tuning bar controls already wrap via flex-wrap, but give them
     room to breathe full-width instead of forcing a min-width that can
     overflow a narrow screen. */
  .st-group {
    min-width: 0;
    flex-basis: 100%;
  }
  .require-columns-row {
    white-space: normal;
  }
}

@media (max-width: 480px) {
  .results-grid {
    grid-template-columns: 1fr;
  }
  .layout {
    padding: 10px 12px;
  }
  .panel {
    padding: 12px;
  }
  .costume-card .imgwrap {
    height: 160px;
  }
  .modal-top img {
    width: 100px;
  }
}

/* ===================== Rendering performance ===================== */
/* The results grid can hold 1500+ cards in all-characters mode; letting the
   browser skip layout/paint for offscreen cards is the single biggest
   rendering win on low-end phones. `auto <h>px` is only a pre-first-render
   estimate - after a card has rendered once the browser remembers its real
   size, so scrollbar jumping is minimal. Browsers without content-visibility
   simply ignore both lines. */
.costume-card {
  content-visibility: auto;
  contain-intrinsic-size: auto 250px;
}

/* ===================== Auth modal ===================== (RDH) */
.auth-modal-overlay {
  display: none;
  position: fixed;
  inset: 0;
  z-index: 1000;
  background: rgba(0, 0, 0, 0.7);
  backdrop-filter: blur(3px);
  align-items: center;
  justify-content: center;
  padding: 16px;
}
.auth-modal-overlay.open {
  display: flex;
}
.auth-modal-box {
  background: #1a1f2e;
  border: 1px solid #2e3650;
  border-radius: 12px;
  padding: 28px 28px 24px;
  width: 100%;
  max-width: 400px;
  position: relative;
  max-height: 90vh;
  overflow-y: auto;
}
.auth-modal-close {
  position: absolute;
  top: 12px;
  right: 14px;
  background: none;
  border: none;
  color: #8899bb;
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
  padding: 4px 8px;
}
.auth-modal-close:hover {
  color: #e2e8f7;
}
.auth-modal-title {
  margin: 0 0 20px;
  font-size: 1.2rem;
  color: #e2e8f7;
  font-weight: 600;
}
.auth-tabs {
  display: flex;
  gap: 8px;
  margin-bottom: 18px;
}
.auth-tab {
  flex: 1;
  padding: 8px;
  border: 1px solid #2e3650;
  border-radius: 6px;
  background: none;
  color: #8899bb;
  cursor: pointer;
  font-size: 0.9rem;
  transition: all 0.15s;
}
.auth-tab.active {
  background: #2563eb;
  border-color: #2563eb;
  color: #fff;
}
.auth-field {
  display: flex;
  flex-direction: column;
  gap: 5px;
  margin-bottom: 14px;
}
.auth-field label {
  font-size: 0.82rem;
  color: #8899bb;
  font-weight: 500;
}
.auth-field input {
  background: #11151c;
  border: 1px solid #2e3650;
  border-radius: 7px;
  color: #e2e8f7;
  padding: 9px 12px;
  font-size: 0.95rem;
  transition: border-color 0.15s;
}
.auth-field input:focus {
  outline: none;
  border-color: #4a7cf6;
}
.auth-field-hint {
  font-size: 0.76rem;
  color: #5a6a8a;
  margin-top: 2px;
}
.auth-checkbox-row {
  display: flex;
  align-items: flex-start;
  gap: 9px;
  margin-bottom: 16px;
  font-size: 0.87rem;
  color: #c4cfde;
  cursor: pointer;
  line-height: 1.4;
}
.auth-checkbox-row input[type="checkbox"] {
  width: 15px;
  height: 15px;
  margin-top: 2px;
  accent-color: #4a7cf6;
  flex-shrink: 0;
}
.auth-error {
  background: #3a1515;
  border: 1px solid #7c2020;
  border-radius: 6px;
  color: #f87171;
  padding: 9px 12px;
  font-size: 0.87rem;
  margin-bottom: 12px;
}
.auth-info {
  background: #132a1f;
  border: 1px solid #1a5c35;
  border-radius: 6px;
  color: #6ee7b7;
  padding: 9px 12px;
  font-size: 0.87rem;
  margin-bottom: 12px;
}
.auth-btn-primary {
  width: 100%;
  padding: 10px;
  border-radius: 8px;
  border: none;
  background: #2563eb;
  color: #fff;
  font-size: 0.97rem;
  font-weight: 600;
  cursor: pointer;
  transition: background 0.15s;
  margin-bottom: 4px;
}
.auth-btn-primary:hover:not(:disabled) {
  background: #1d4ed8;
}
.auth-btn-primary:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.auth-btn-secondary {
  width: 100%;
  padding: 9px;
  border-radius: 8px;
  border: 1px solid #2e3650;
  background: none;
  color: #8899bb;
  font-size: 0.92rem;
  cursor: pointer;
  transition: border-color 0.15s;
  margin-top: 8px;
}
.auth-btn-secondary:hover {
  border-color: #4a5a7a;
  color: #c4cfde;
}
.auth-btn-danger {
  width: 100%;
  padding: 9px;
  border-radius: 8px;
  border: 1px solid #7c2020;
  background: #3a1515;
  color: #f87171;
  font-size: 0.92rem;
  cursor: pointer;
  transition: background 0.15s;
  margin-top: 8px;
}
.auth-btn-danger:hover:not(:disabled) {
  background: #4a1818;
}
.auth-btn-danger:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}
.auth-switch {
  text-align: center;
  margin: 14px 0 0;
  font-size: 0.87rem;
  color: #6a7a9a;
}
.auth-link {
  background: none;
  border: none;
  color: #4a7cf6;
  cursor: pointer;
  font-size: 0.87rem;
  text-decoration: underline;
  padding: 0;
}
.auth-link:hover {
  color: #7aa4ff;
}
.auth-body-text {
  color: #c4cfde;
  font-size: 0.9rem;
  margin: 0 0 12px;
  line-height: 1.5;
}
.auth-danger-zone {
  margin-top: 20px;
  padding-top: 16px;
  border-top: 1px solid #2e3650;
}

/* ===================== Auth nav button ===================== */
.auth-nav-btn {
  padding: 5px 13px;
  border-radius: 8px;
  border: 1px solid #2e3650;
  background: none;
  color: #c4cfde;
  font-size: 13px;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  transition:
    border-color 0.15s,
    color 0.15s;
  max-width: 140px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.auth-nav-btn:hover {
  border-color: #4a7cf6;
  color: #e2e8f7;
}
.auth-hint-ok {
  color: #6ee7b7;
}
.auth-hint-bad {
  color: #f87171;
}

/* Pending-publish banner (offline / retry queue surfacing) - faces.js injects it
   at the top of #myBuildsContent when builds are queued to publish. */
.pending-banner {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin: 0 0 14px;
  padding: 10px 14px;
  border-radius: 10px;
  background: rgba(240, 180, 60, 0.1);
  border: 1px solid rgba(240, 180, 60, 0.45);
  color: var(--text);
  font-size: 13.5px;
}
.pending-banner-text {
  flex: 1;
  min-width: 180px;
}
.pending-banner-btn {
  font-size: 13px;
  font-weight: 600;
  padding: 6px 14px;
  border-radius: 7px;
  cursor: pointer;
  background: var(--gold);
  border: 1px solid var(--gold);
  color: #161b22;
}
.pending-banner-btn:hover {
  filter: brightness(1.08);
}
.pending-banner-btn:disabled {
  opacity: 0.6;
  cursor: default;
}
