/* ============================================================================
   mobile.css — Mobile-only overrides (html.mobile-ui scope).

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

/* ============================================================================
   MOBILE-ONLY UI (mobile.css + mobile.js)
   ----------------------------------------------------------------------------
   An app-style interface used ONLY on phones - both the mobile-browser site
   and the installed "Add to Home Screen" PWA (they share these exact styles;
   the only PWA-specific parts are the env(safe-area-inset-*) paddings, which
   are 0 in a normal browser tab).

   HOW IT ACTIVATES: mobile.js watches matchMedia("(max-width: 820px)") and
   toggles the `mobile-ui` class on <html>. EVERY layout-changing rule in this
   file is scoped under `html.mobile-ui`, so desktop never sees any of it, and
   resizing a desktop window across the breakpoint cleanly switches both ways.
   The injected chrome elements (tab bar, view switcher, quick bar, page
   title) stay in the DOM when mobile-ui turns off - they're display:none by
   default and only shown under html.mobile-ui, so no teardown is needed.

   DESIGN INTENT: this is the same product identity as desktop (dark panels,
   gold accents, the hero-blue → villain-red gradient as the brand thread) -
   not a new theme. The gradient that paints the desktop brand title is
   reused as the active-tab treatment in the bottom bar, which is the one
   deliberate "signature" of the mobile UI. Everything else stays quiet:
   bigger tap targets, one-column flow, bottom-sheet modals.
   ========================================================================= */

/* Injected chrome is inert unless the mobile UI is active. */
.m-tabbar, .m-viewswitch, .m-quickbar, .m-page-title { display: none; }
html:not(.mobile-ui) .m-only { display: none !important; }

/* ---------------------------------------------------------------- base --- */
html.mobile-ui body {
  font-size: 14.5px;
  /* Clear the fixed bottom tab bar (+ home indicator on notched phones). */
  padding-bottom: calc(66px + env(safe-area-inset-bottom));
}
/* Build editor also has the floating quick bar above the tab bar. */
html.mobile-ui.m-page-build body {
  padding-bottom: calc(122px + env(safe-area-inset-bottom));
}

/* -------------------------------------------------------------- header --- */
/* The header stops being sticky on mobile - persistent navigation moves to
   the bottom tab bar instead, and content gets the full screen back while
   scrolling (the optimizer's Setup/Results switcher is the one thing that
   stays pinned, below). */
html.mobile-ui header.top {
  position: static;
  padding: 9px 12px;
  padding-top: calc(9px + env(safe-area-inset-top));
  gap: 8px;
}
html.mobile-ui header.top h1 { font-size: 14px; }
html.mobile-ui header.top .sub { display: none; }
/* On mobile the desktop nav links and the page-name label are hidden; the header
   Sign in / account button takes the top-right slot instead (it toggles between
   "Sign in" and the user's display name via auth.js). display:contents keeps the
   .top-nav box out of the header flex row so its button child joins the header;
   it auto-reverts to the normal desktop nav when the mobile-ui class comes off. */
html.mobile-ui .top-nav { display: contents; }
html.mobile-ui .top-nav a { display: none; }
html.mobile-ui .m-page-title { display: none; }
html.mobile-ui .auth-nav-btn { margin-left: auto; }

/* ------------------------------------------------------ bottom tab bar --- */
html.mobile-ui .m-tabbar {
  display: flex;
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 150;
  background: rgba(17, 21, 28, .96);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
  border-top: 1px solid var(--border);
  padding: 4px max(8px, env(safe-area-inset-right)) calc(4px + env(safe-area-inset-bottom)) max(8px, env(safe-area-inset-left));
}
html.mobile-ui .m-tab {
  flex: 1;
  min-width: 0; /* equal widths regardless of label length (flex items default to
                   min-width:auto, which would let wider labels squeeze others) */
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 5px 2px 3px;
  text-decoration: none;
  color: var(--text-dim);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .02em;
  border-radius: 10px;
  position: relative;
  -webkit-tap-highlight-color: transparent;
}
html.mobile-ui .m-tab .m-tab-icon { font-size: 18px; line-height: 1; }
html.mobile-ui .m-tab .m-tab-label {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
html.mobile-ui .m-tab:active { background: var(--panel-2); }
/* The signature: the active tab wears the same hero→villain gradient as the
   brand title, plus a thin gradient indicator above it. */
html.mobile-ui .m-tab[aria-current="page"] .m-tab-label {
  background: linear-gradient(90deg, var(--hero), var(--villain));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
  font-weight: 800;
}
html.mobile-ui .m-tab[aria-current="page"]::before {
  content: "";
  position: absolute;
  top: -7px; left: 22%; right: 22%;
  height: 3px;
  border-radius: 0 0 3px 3px;
  background: linear-gradient(90deg, var(--hero), var(--villain));
}

/* ------------------------------------- optimizer: Setup / Results flow --- */
/* The desktop sidebar+results two-pane becomes two full screens on a phone,
   switched by a pinned segmented control. Same DOM, same handlers - the
   switcher only toggles which pane is visible. */
html.mobile-ui .m-viewswitch {
  display: flex;
  position: sticky;
  top: 0;
  z-index: 60;
  gap: 6px;
  margin: 0;
  padding: 7px 10px;
  /* The safe-area inset is NOT applied here unconditionally: at the top of the
     page the static header above already clears the status bar/notch, so
     adding the inset here too would double the gap (visible only in the
     installed PWA, where the inset is non-zero). mobile.js toggles .is-stuck
     via a sentinel + IntersectionObserver; the inset is added only once the
     switcher is actually pinned to the top (after the header scrolls away). */
  background: rgba(14, 17, 22, .94);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  border-bottom: 1px solid var(--border);
}
html.mobile-ui .m-viewswitch.is-stuck {
  padding-top: calc(7px + env(safe-area-inset-top));
}
html.mobile-ui .m-stick-sentinel { height: 1px; margin: 0; padding: 0; }
html.mobile-ui .m-viewswitch button {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text-dim);
  font-size: 13px;
  font-weight: 700;
  padding: 9px 8px;
  border-radius: 10px;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
html.mobile-ui .m-viewswitch button[aria-pressed="true"] {
  background: linear-gradient(90deg, var(--hero), var(--villain));
  border-color: transparent;
  color: #fff;
}
html.mobile-ui .m-badge {
  min-width: 19px;
  padding: 1px 6px;
  border-radius: 10px;
  background: #241f12;
  border: 1px solid var(--gold);
  color: var(--gold);
  font-size: 10.5px;
  font-weight: 800;
  text-align: center;
}
html.mobile-ui .m-viewswitch button[aria-pressed="true"] .m-badge {
  background: rgba(0, 0, 0, .35);
  border-color: rgba(255, 255, 255, .55);
  color: #fff;
}
@keyframes m-badge-pop {
  0% { transform: scale(1); }
  40% { transform: scale(1.35); }
  100% { transform: scale(1); }
}
html.mobile-ui .m-badge.m-badge-pulse { animation: m-badge-pop .5s ease; }

/* Pane switching (index page only). */
html.mobile-ui.m-page-index[data-mview="setup"] .layout .main { display: none; }
html.mobile-ui.m-page-index[data-mview="results"] .layout .sidebar { display: none; }

/* ------------------------------------------------------ layout / panels --- (RDH) */
html.mobile-ui .layout { padding: 10px 10px 4px; gap: 10px; }
html.mobile-ui .build-layout { padding: 10px 10px 4px; gap: 4px; }
html.mobile-ui .panel { padding: 12px; border-radius: 12px; }
html.mobile-ui .panel + .panel { margin-top: 10px; }
html.mobile-ui .panel h2 { font-size: 13px; }
html.mobile-ui .footer-note { padding: 18px 14px 8px; }

/* Collapsible setup sections (optimizer sidebar): the section heading is the
   whole tap target, with a chevron that flips when collapsed. mobile.js adds
   .m-acc to the sidebar panels and toggles .m-collapsed on heading taps. */
html.mobile-ui .m-acc > h2 {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  cursor: pointer;
  user-select: none;
  -webkit-user-select: none;
  margin: -12px;
  /* No extra bottom margin when expanded: the heading's own 12px padding-bottom
     already gives a clean gap to the content below. The previous 8px here stacked
     on top of that padding into a ~20px band that felt too loose on mobile.
     (Collapsed state overrides this to -12px to pull the box edge-to-edge.) */
  margin-bottom: 0;
  padding: 12px;
  -webkit-tap-highlight-color: transparent;
}
html.mobile-ui .m-acc > h2::after {
  content: "⌄";
  font-size: 15px;
  color: var(--text-dim);
  transition: transform .18s ease;
  transform: rotate(0deg);
}
html.mobile-ui .m-acc.m-collapsed > h2 { margin-bottom: -12px; }
html.mobile-ui .m-acc.m-collapsed > h2::after { transform: rotate(-90deg); }
html.mobile-ui .m-acc.m-collapsed > *:not(h2) { display: none !important; }

/* ------------------------------------------------------------- results --- */
html.mobile-ui .results-head { margin: 8px 2px 10px; }
html.mobile-ui .results-head h2 { font-size: 14.5px; }
html.mobile-ui .results-grid {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px;
}
html.mobile-ui .costume-card .imgwrap { height: 120px; }
html.mobile-ui .costume-card .body { padding: 7px 9px 9px; gap: 3px; }
html.mobile-ui .costume-card .cname { font-size: 12px; }
html.mobile-ui .costume-card:hover { transform: none; } /* no hover-lift on touch */
html.mobile-ui .costume-card:active { border-color: var(--gold); }

/* Larger phones / small tablets in the mobile range get a third results
   column so cards don't feel oversized on wider screens. */
@media (min-width: 560px) and (max-width: 820px) {
  html.mobile-ui .results-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  html.mobile-ui .builds-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* ------------------------------------------------- bottom-sheet modals --- */
html.mobile-ui .modal-overlay { padding: 0; align-items: flex-end; }
html.mobile-ui .modal {
  max-width: 100%;
  width: 100%;
  max-height: 90vh;
  max-height: 90dvh;
  border-radius: 18px 18px 0 0;
  border-bottom: none;
  padding-bottom: calc(10px + env(safe-area-inset-bottom));
  animation: m-sheet-up .22s ease-out;
}
html.mobile-ui .modal::before {
  content: "";
  display: block;
  width: 44px;
  height: 4px;
  border-radius: 2px;
  background: var(--border);
  margin: 10px auto 0;
}
@keyframes m-sheet-up {
  from { transform: translateY(24px); opacity: .6; }
  to { transform: translateY(0); opacity: 1; }
}
html.mobile-ui .modal-close { width: 40px; height: 40px; font-size: 19px; }
html.mobile-ui .modal-top { padding: 12px 16px 16px; }
html.mobile-ui .modal-section { padding: 14px 16px; }

/* -------------------------------------------------- inputs / tap targets --- */
html.mobile-ui select,
html.mobile-ui input[type="text"] { padding: 12px 12px; border-radius: 10px; }
html.mobile-ui input[type="checkbox"] { width: 18px; height: 18px; }
html.mobile-ui .skill-row { padding: 10px 11px; }
html.mobile-ui .skill-list { max-height: 300px; }
html.mobile-ui .chip { padding: 6px 11px; font-size: 12.5px; }
html.mobile-ui .fs-option, html.mobile-ui .cs-option { padding: 12px 12px; font-size: 14px; }
html.mobile-ui .face-select-list, html.mobile-ui .char-select-list {
  max-height: 46vh;
  /* Mobile scroll hardening (2026-07-15) — RDH. Symptom: scrolling the special-
     tuning list would work for a few seconds then lock up completely, in both ST1
     and ST2. Cause: this list is a nested scroll region living inside the RELOCATED
     special-tuning bar; when momentum scrolling hit the list's top/bottom the touch
     was handed to an ancestor that can't scroll, orphaning subsequent touches and
     freezing the list. These three properties keep the scroll owned by the list:
     - overscroll-behavior: contain  → the boundary bounce never leaks to the page
     - -webkit-overflow-scrolling: touch → proper momentum scrolling on iOS
     - touch-action: pan-y → the list claims vertical drags outright */
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y;
}
/* The options wrapper is the actual scrolled content; make sure vertical panning is
   never intercepted by a parent gesture handler. The sticky search box above it can
   otherwise cause iOS to lose the scroll target after a repaint. */
html.mobile-ui .fs-options {
  touch-action: pan-y;
  overscroll-behavior: contain;
}
/* On iOS a position:sticky child inside a -webkit-overflow-scrolling:touch region
   can drop the scroll target mid-momentum (the exact "freezes after a few seconds"
   report). The search field doesn't need to be sticky on mobile — the list is short
   and the ☰ opener already gives a no-keyboard path — so pin it static here. */
html.mobile-ui .fs-search { position: static; }
html.mobile-ui .face-select-btn, html.mobile-ui .char-display-btn { padding: 12px 12px; border-radius: 10px; }
html.mobile-ui .costume-picker-grid { grid-template-columns: repeat(auto-fill, minmax(86px, 1fr)); max-height: 300px; }
html.mobile-ui .create-build-btn, html.mobile-ui .publish-btn {
  padding: 12px 16px;
  font-size: 14px;
  border-radius: 11px;
}
html.mobile-ui .build-save-row { gap: 10px; }
html.mobile-ui .build-save-row .create-build-btn,
html.mobile-ui .build-save-row .publish-btn { flex: 1 1 46%; }

/* ------------------------------------------- My Builds / Community pages --- */
html.mobile-ui .sort-tabs {
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  padding-bottom: 4px;
  margin-right: -12px;
  padding-right: 12px;
}
html.mobile-ui .sort-tabs::-webkit-scrollbar { display: none; }
html.mobile-ui .sort-tab { white-space: nowrap; padding: 9px 14px; font-size: 13px; flex-shrink: 0; }
html.mobile-ui .build-search-input { padding: 12px 14px; border-radius: 11px; }
html.mobile-ui .builds-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; margin-top: 12px; }
html.mobile-ui .build-card { padding: 0; border-radius: 13px; }
html.mobile-ui .bc-banner { height: 118px; }
html.mobile-ui .build-card .bc-info { padding: 10px 11px 11px; }
html.mobile-ui .build-card .bc-name { font-size: 13px; }
html.mobile-ui .build-card button { font-size: 12px; padding: 7px 9px; border-radius: 7px; }
html.mobile-ui .tag-chip { padding: 8px 13px; font-size: 13px; }
html.mobile-ui .preview-banner { font-size: 12px; padding: 10px 12px; border-radius: 11px; }

/* -------------------------------------------------------- build editor --- (RDH) */
html.mobile-ui .undo-btn { padding: 8px 10px; font-size: 12px; border-radius: 8px; }
html.mobile-ui .presets-panel button { padding: 9px 11px; font-size: 13px; }
html.mobile-ui .build-slot-select { padding: 10px 9px; border-radius: 9px; font-size: 13.5px; }
html.mobile-ui .build-face-select .face-select-btn { padding: 10px 9px; }
/* Mobile split trigger: reveal the ☰ end-cap, which opens the list WITHOUT the
   keyboard. The main (left) part of the same rectangle still opens the list with
   the search field focused, for anyone who wants to type. The ▾ chevron is hidden
   because the ☰ is now the affordance. (RDH) */
html.mobile-ui .fs-menu-btn { display: flex; }
html.mobile-ui .build-face-select .face-select-btn::after { display: none; }

/* Build editor panel: tighter header row on small screens */
html.mobile-ui .build-editor-panel > div:first-child { flex-wrap: wrap; gap: 8px; }
html.mobile-ui .build-editor-panel > div:first-child > div { flex-wrap: wrap; gap: 6px; }

/* Slot grid: 1 column (LEFT then RIGHT stacked) on narrow phones */
html.mobile-ui .build-slot-grid {
  grid-template-columns: 1fr;
  gap: 16px;
}

/* Save & Share panel: stack buttons vertically, full width */
html.mobile-ui .build-save-row {
  flex-direction: column;
  gap: 8px;
}
html.mobile-ui .build-save-row .create-build-btn,
html.mobile-ui .build-save-row .publish-btn {
  flex: none;
  width: 100%;
}
html.mobile-ui .create-build-btn, html.mobile-ui .publish-btn {
  padding: 12px 14px;
  font-size: 14px;
  border-radius: 11px;
}

/* Build card panel: bleed to screen edges so the card fills the full width */
html.mobile-ui .build-card-panel {
  margin-left: -10px;
  margin-right: -10px;
  padding-left: 6px;
  padding-right: 6px;
  border-left: none;
  border-right: none;
  border-radius: 0;
}

/* Build costume head: tighter on mobile */
html.mobile-ui .build-costume-panel { padding: 10px 12px; }

/* Build hint text: slightly smaller */
html.mobile-ui .build-hint { font-size: 12.5px; line-height: 1.5; margin-bottom: 10px; }

/* Tag picker chips */
html.mobile-ui .tag-chip { padding: 7px 11px; font-size: 12.5px; }

/* Build name input */
html.mobile-ui #buildNameInput { font-size: 15px; padding: 11px 12px; }

/* Floating quick actions on the Build Editor - shortcuts that just click the
   real Save / Totals buttons, pinned above the tab bar. */
html.mobile-ui .m-quickbar {
  display: flex;
  position: fixed;
  left: 12px; right: 12px;
  bottom: calc(64px + env(safe-area-inset-bottom));
  z-index: 140;
  gap: 10px;
}
html.mobile-ui .m-quickbar button {
  flex: 1;
  border: 1px solid var(--gold);
  background: rgba(22, 27, 34, .96);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  color: var(--gold);
  font-size: 13.5px;
  font-weight: 700;
  padding: 12px 10px;
  border-radius: 12px;
  cursor: pointer;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .45);
  -webkit-tap-highlight-color: transparent;
}
html.mobile-ui .m-quickbar button:active { background: #241f12; }

/* ------------------------------------------------ tuning-totals combos --- */
/* Bigger + buttons for thumbs; everything else about the combo feature is
   shared with desktop in style.css. */
html.mobile-ui .tt-combo-btn { width: 32px; height: 32px; font-size: 17px; }
html.mobile-ui .tt-combo-spacer { width: 32px; }

/* --------------------------------------------------------------- motion --- */
@media (prefers-reduced-motion: reduce) {
  html.mobile-ui .modal { animation: none; }
  html.mobile-ui .m-badge.m-badge-pulse { animation: none; }
  html.mobile-ui .m-acc > h2::after { transition: none; }
}

/* ---- Effect priority chips (mobile) ----  (RDH)
   The ⠿ grip is the only drag target, so give it a proper thumb-sized tap area
   and keep touch-action:none confined to it - touching the chip body (or the
   rest of the page) must still scroll normally. */
/* Effect priority list on mobile: thumb-sized targets. The list is vertical, so
   rows are full width and easy to hit. touch-action:none stays scoped to the ⠿
   grip alone, so touching the rest of a row still scrolls the page. (RDH) */
/* Priority rows on mobile: taller so they are easy to grab and read. The whole
   row is the drag handle (touch-action:none lives on .prio-item in style.css),
   so there is no small target to hit. The ▲▼ buttons are gone - they squeezed the
   effect name into an ellipsis. (RDH) */
html.mobile-ui .prio-item { padding: 12px 11px; font-size: 13.5px; gap: 10px; }
html.mobile-ui .prio-rank { min-width: 21px; height: 21px; font-size: 11px; }
html.mobile-ui .prio-grip { font-size: 17px; }
html.mobile-ui .prio-remove { padding: 6px 4px; font-size: 19px; }
html.mobile-ui .prio-hint { font-size: 11.5px; }
