/* texturePackPicker.css - styles for shared/texturePackPicker.js and the
   texture modal it opens (client/game/ui/textureBrowser.js). Reads the
   game's --surface-* variables when present (in-game settings) and falls
   back to the same literal values so the profile page renders identically.

   One deliberate visual device: every sprite preview sits on a checkerboard
   (the standard transparency backing of texture editors), so translucent
   art reads correctly and previews are recognizable as game assets at a
   glance. Selection state is the game's gold accent, nothing else.

   Layout model: a fixed toolbar (search + bulk actions) and a fixed
   Apply-All footer bracket a single scrolling list in the middle, so
   neither ever scrolls out of reach while browsing 40+ tile slots. */

.hidden { display: none; }
.texturePackPicker {
  font-size: 13px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  /* Bounded so the toolbar and Apply-All footer below stay fixed in place
     while only the list/grid between them scrolls. A dedicated host
     context (the Textures tab, ui/settingsPanel.js) can raise this via its
     own rule; this is the sane default everywhere else, including the
     profile page's standalone picker. */
  max-height: 460px;
}

/* Checkerboard transparency backing shared by every sprite preview. */
.tppThumb, .tppOption img {
  --tpp-check-a: var(--surface-1, #363b44);
  --tpp-check-b: var(--surface-2, #40464f);
  background: repeating-conic-gradient(var(--tpp-check-b) 0% 25%, var(--tpp-check-a) 0% 50%) 0 0 / 12px 12px;
  border: 1px solid var(--border, #4e555f);
  border-radius: 3px;
  image-rendering: pixelated;
}

/* ---- toolbar: search + "change all to one theme" ------------------------ */
.tppToolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  flex: none;
}
/* Inside the horizontal toolbar (search + "change all"), the search box
   grows to fill the row instead of the modal's full-width column default. */
.tppToolbar .tppSearch { flex: 1; width: auto; }

.tppSearch {
  flex: none;
  width: 100%;
  min-width: 120px;
  padding: 7px 10px 7px 28px;
  box-sizing: border-box;
  background: var(--surface-2, #40464f) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20' width='13' height='13' fill='none' stroke='%23a4aab3' stroke-width='1.6'%3E%3Ccircle cx='8.5' cy='8.5' r='6'/%3E%3Cpath d='M13 13l5 5' stroke-linecap='round'/%3E%3C/svg%3E") no-repeat 8px center;
  color: var(--text, #e2e4e8);
  border: 1px solid var(--border, #4e555f);
  border-radius: 4px;
  font: inherit;
}
.tppSearch::placeholder { color: var(--text-faint, #7d838c); }
.tppSearch:focus { outline: none; border-color: var(--accent, #c9a24e); }
/* Native clear-button (webkit) recolored to match the dark field instead of
   inheriting a light system default. */
.tppSearch::-webkit-search-cancel-button { filter: grayscale(1) opacity(0.6); cursor: pointer; }

.tppTileRow {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px;
  border-radius: 4px;
}
.tppTileRow:hover { background: var(--surface-1, #363b44); }

.tppThumb {
  width: 44px;
  height: 44px;
  flex: none;
  object-fit: contain;
  transition: transform 0.12s ease;
}

.tppTileName {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
}

/* Small status pill ("Set by host", "custom", "default") - state as a
   label, not a parenthetical. */
.tppBadge {
  flex: none;
  font-size: 10px;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  padding: 3px 6px;
  border-radius: 999px;
  color: var(--accent, #c9a24e);
  border: 1px solid var(--accent-dim, #4a4230);
  background: var(--accent-dim, #4a4230);
}

/* :not(.tppIconBtn) throughout - the Lock/Edit icon buttons (Global
   Textures, Cell Texture, Personal picker rows) keep their own fixed
   square sizing (.tppIconBtn below); .tppTileRow button would otherwise
   outrank that single-class rule (one more selector = higher specificity)
   and stretch them back into text-button proportions. */
.tppTileRow button:not(.tppIconBtn),
.tppChangeAll button {
  padding: 4px 10px;
  cursor: pointer;
  background: var(--surface-2, #40464f);
  color: var(--text, #e2e4e8);
  border: 1px solid var(--border, #4e555f);
  border-radius: 4px;
  font-size: 12px;
}
.tppTileRow button:not(.tppIconBtn):hover:not(:disabled),
.tppChangeAll button:hover:not(:disabled) {
  background: var(--surface-3, #4b525c);
}
.tppTileRow button:not(.tppIconBtn):disabled,
.tppChangeAll button:disabled {
  opacity: 0.4;
  cursor: default;
}
.tppTileRow button:not(.tppIconBtn).active {
  border-color: var(--accent, #c9a24e);
  color: var(--accent, #c9a24e);
}

.tppTileList {
  flex: 1;
  min-height: 120px;
  overflow-y: auto;
  scrollbar-width: thin;
}

/* Group section heading ("Flags", "Boosts", ...) - sticky within the
   scrolling list so it's always clear which category is currently in view,
   the same affordance a long alphabetized settings list badly needed. */
.tppGroupHeader {
  position: sticky;
  top: 0;
  z-index: 1;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 8px;
  padding: 5px 6px;
  margin-top: 4px;
  background: var(--surface-0, #2c3038);
  color: var(--text-dim, #a4aab3);
  font-size: 10px;
  font-weight: bold;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border-bottom: 1px solid var(--border, #4e555f);
}
.tppGroupHeader:first-child { margin-top: 0; }
.tppGroupCount {
  font-weight: normal;
  color: var(--text-faint, #7d838c);
  letter-spacing: normal;
  text-transform: none;
}

.tppEmpty {
  padding: 24px 8px;
  text-align: center;
  color: var(--text-faint, #7d838c);
  font-size: 12px;
}

.tppNotice {
  font-size: 12px;
  color: var(--text-dim, #a4aab3);
  margin: 0;
}

/* ---- the shared texture-picker modal (textureBrowser.js) ----------------
   One instance, built once, reused by all three pickers: click a slot ->
   this opens over everything -> click an option -> it applies and this
   closes. No footer, no "confirm" step - the grid IS the whole modal. */
.tppModalBackdrop {
  position: fixed;
  inset: 0;
  /* Above #menu's z-index:100 (local/index.html) - this modal (and its
     sibling changeAllConfirm modal, same class) always opens ON TOP of
     the Esc menu that hosts the picker, not behind it. Was 50, which put
     it visibly behind the menu - clicking a tile "did nothing" because
     the modal WAS opening, just invisibly. */
  z-index: 200;
  background: rgba(0, 0, 0, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  box-sizing: border-box;
}
.tppModalBackdrop.hidden { display: none; }

.tppModal {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: min(560px, 100%);
  max-height: min(600px, 100%);
  background: var(--surface-0, #2c3038);
  color: var(--text, #e2e4e8);
  border: 1px solid var(--border, #4e555f);
  border-radius: 8px;
  padding: 14px;
  box-sizing: border-box;
  box-shadow: 0 12px 48px rgba(0, 0, 0, 0.6);
}

.tppModalHeader {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex: none;
}
.tppModalTitle { font-weight: bold; font-size: 15px; }
.tppModalHeader .tppIconBtn { width: 24px; height: 24px; font-size: 16px; }

.tppGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(100px, max-content));
  gap: 8px;
  flex: 1;
  min-height: 80px;
  overflow-y: auto;
  scrollbar-width: thin;
  align-content: start;
}

.tppOption {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 5px;
  padding: 8px 4px 6px;
  background: var(--surface-1, #363b44);
  border: 2px solid transparent;
  border-radius: 5px;
  cursor: pointer;
  color: inherit;
  transition: background 0.12s ease, border-color 0.12s ease;
}
.tppOption:hover { background: var(--surface-2, #40464f); }
.tppOption:hover img { transform: scale(1.12); }
.tppOption.active {
  border-color: var(--accent, #c9a24e);
  background: var(--accent-dim, #4a4230);
}
.tppOption:focus-visible {
  outline: 2px solid var(--accent, #c9a24e);
  outline-offset: 1px;
}

/* Change All confirm step - a plain preview grid, not a picker, so its
   cells keep the pointer cursor (they're still clickable, to exclude) but
   drop the hover-zoom feedback .tppOption implies for an actual pick. */
.tppOption.tppOptionStatic:hover img { transform: none; }

/* Clicked to exclude from this "change all" - grayed out, stays this way
   until clicked again. Click still works while excluded (toggle, not a
   one-way disable), so no pointer-events:none. */
.tppOption.tppOptionExcluded { opacity: 0.35; }
.tppOption.tppOptionExcluded:hover { background: var(--surface-1, #363b44); }

/* A group header inside a CSS grid (the Change All confirm list) needs an
   explicit span - unlike .tppTileList's flex column, a grid item defaults
   to one cell and would sit squeezed into the thumbnail grid otherwise. */
.tppGrid .tppGroupHeader { grid-column: 1 / -1; }

.tppOption img {
  width: 56px;
  height: 56px;
  object-fit: contain;
  transition: transform 0.12s ease;
}

.tppOption span {
  font-size: 10px;
  text-align: center;
  word-break: break-word;
  color: var(--text-dim, #a4aab3);
}
.tppOption.active span { color: var(--text, #e2e4e8); }

/* "Change all to one theme" row (toolbar, logged-in only) */
.tppChangeAll {
  display: flex;
  gap: 6px;
  align-items: center;
  flex: none;
}
.tppChangeAll select {
  min-width: 0;
  padding: 4px;
  background: var(--surface-2, #40464f);
  color: var(--text, #e2e4e8);
  border: 1px solid var(--border, #4e555f);
  border-radius: 4px;
}

/* Slot currently forced by the room host ("Set by host") */

/* Icon-only Lock/Edit buttons (Global Textures list) */
.tppIconBtn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 4px;
  color: var(--text-dim, #a4aab3);
  flex: none;
}
.tppIconBtn:hover:not(:disabled) { color: var(--text, #e2e4e8); background: var(--surface-2, #40464f); }
.tppIconBtn:disabled { opacity: 0.35; cursor: default; }
.tppIconBtn.active { color: var(--accent, #c9a24e); background: var(--accent-dim, #4a4230); }

/* Clickable thumbnail = opens the picker, same as the pencil button */
.tppThumbClickable { cursor: pointer; }
.tppThumbClickable:hover { outline: 2px solid var(--accent, #c9a24e); outline-offset: 1px; transform: scale(1.06); }

/* A tile with an unapplied staged change - the row itself flags it, not
   just the badge, since the change hasn't reached the room yet. */
.tppTileRow.tppPending { background: var(--accent-dim, #4a4230); }
.tppBadge.tppBadgePending { color: #1d2025; background: var(--accent, #c9a24e); border-color: var(--accent, #c9a24e); }

/* ---- Apply All / Discard All footer -------------------------------------
   Sits below the scrolling list as a fixed footer (flex: none, the list is
   the only flex: 1 region) so it's always reachable without hunting for it
   at the bottom of a long scroll. */
.tppApplyRow {
  display: flex;
  gap: 8px;
  flex: none;
  padding-top: 8px;
  border-top: 1px solid var(--border, #4e555f);
}
.tppApplyBtn {
  flex: 1;
  font-weight: bold;
  color: var(--accent, #c9a24e) !important;
  border-color: var(--accent-dim, #4a4230) !important;
}
.tppApplyBtn:not(:disabled):hover { background: var(--accent-dim, #4a4230) !important; }

/* ---- drag-and-drop upload zone ------------------------------------------
   Replaces a bare file input with a full click/drop target, so uploading a
   custom texture doesn't require hunting for the native "Choose File"
   button. The label/file/button row inside stays for keyboard users and as
   the explicit "commit the upload" action. */
.tppDropzone {
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex: none;
  padding: 10px;
  border: 1px dashed var(--border, #4e555f);
  border-radius: 5px;
  background: var(--surface-1, #363b44);
  cursor: pointer;
  transition: border-color 0.12s ease, background 0.12s ease;
}
.tppDropzone:hover { border-color: var(--text-dim, #a4aab3); }
.tppDropzone.tppDropActive { border-color: var(--accent, #c9a24e); background: var(--accent-dim, #4a4230); }
.tppDropzoneHint {
  font-size: 11px;
  color: var(--text-dim, #a4aab3);
  text-align: center;
  pointer-events: none;
}
.tppDropzone input[type="text"] {
  padding: 5px 8px;
  background: var(--surface-2, #40464f);
  color: var(--text, #e2e4e8);
  border: 1px solid var(--border, #4e555f);
  border-radius: 4px;
  font: inherit;
}
.tppFileInput { font-size: 11px; color: var(--text-dim, #a4aab3); }


/* ---- pack view: the sprites themselves, nothing around them ------------ */

.tppPackView { display: flex; flex-direction: column; gap: 10px; min-height: 0; }
.tppPackActions { display: flex; gap: 8px; align-items: center; flex: none; }

/* The wall sheet on the left at full size, the 40x40 tiles packed beside
   it - the same arrangement the contact sheet uses, for the same reason:
   walls is a 480x440 auto-tile grid and only means anything whole. */
.tppPackBody {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  overflow: auto;
  min-height: 0;
  padding: 8px;
  background: repeating-conic-gradient(var(--surface-2, #40464f) 0% 25%, var(--surface-1, #363b44) 0% 50%) 0 0 / 16px 16px;
  border: 1px solid var(--border, #4e555f);
  border-radius: 6px;
}

.tppWallsColumn { flex: none; }

/* No gap: the sprites butt together the way they do in the game, instead of
   floating in a grid of cards. */
.tppTiles {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  align-content: flex-start;
  gap: 0;
  min-width: 320px;
}

/* Nothing but the sprite. No border, background, padding or label - the
   only visible state is the hover/selection outline, drawn inside the
   sprite's own bounds so picking one never shifts the others. */
.tppTile {
  padding: 0;
  border: 0;
  background: none;
  line-height: 0;
  cursor: pointer;
  outline-offset: -2px;
}
.tppTile:hover:not(:disabled) { outline: 2px solid var(--accent, #c9a24e); }
.tppTile:disabled { cursor: default; }

/* Deliberately unsized: the image renders at its intrinsic pixel size, so a
   40x40 tile is 40x40 and marsBall is 80x80. Any width/height here would be
   a resize, which is exactly what this view must not do. */
.tppTile img {
  display: block;
  image-rendering: pixelated;
}
.tppTileEmpty { width: 40px; height: 40px; }

/* Still used by the gallery's preview pane. */
.tppPackSheet {
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding: 10px;
  background: repeating-conic-gradient(var(--surface-2, #40464f) 0% 25%, var(--surface-1, #363b44) 0% 50%) 0 0 / 16px 16px;
  border: 1px solid var(--border, #4e555f);
  border-radius: 6px;
  min-height: 0;
  overflow: auto;
}
/* No max-width: scaling the preview down is what made it unreadable. It
   scrolls inside its pane instead. */
.tppPackSheet img { image-rendering: pixelated; display: block; }

.tppPackBtn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 14px;
  background: var(--surface-2, #40464f);
  color: var(--text, #e2e4e8);
  border: 1px solid var(--border, #4e555f);
  border-radius: 4px;
  font: inherit;
  cursor: pointer;
}
.tppPackBtn:hover:not(:disabled) { background: var(--surface-3, #4b525c); }
.tppPackBtn:disabled { opacity: 0.5; cursor: not-allowed; }
.tppPackBtn.primary {
  background: var(--accent-dim, #4a4230);
  border-color: var(--accent, #c9a24e);
  color: var(--accent, #c9a24e);
}

/* ---- back row (gallery) ------------------------------------------ */

.tppBackRow { display: flex; align-items: center; gap: 8px; flex: none; }
.tppBackBtn {
  padding: 4px 10px;
  background: var(--surface-2, #40464f);
  color: var(--text, #e2e4e8);
  border: 1px solid var(--border, #4e555f);
  border-radius: 4px;
  font: inherit;
  cursor: pointer;
}
.tppBackBtn:hover { background: var(--surface-3, #4b525c); }
.tppBackTitle { font-weight: 600; }

/* ---- gallery: swatch grid beside a full-size preview -------------------- */

.tppGalleryView { display: flex; flex-direction: column; gap: 8px; min-height: 0; }

/* Two panes: a scrolling grid of swatches to scan, and a preview pane that
   stays put while you scan. Collapses to one column when there isn't room
   for both (the profile page's narrower container). */
.tppGalleryBody {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 260px);
  gap: 12px;
  min-height: 0;
}
@media (max-width: 720px) {
  .tppGalleryBody { grid-template-columns: minmax(0, 1fr); }
}

.tppGalleryGrid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(84px, 1fr));
  gap: 8px;
  overflow-y: auto;
  min-height: 0;
  align-content: start;
}
.tppGalleryCell {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 6px;
  background: var(--surface-1, #363b44);
  border: 1px solid var(--border, #4e555f);
  border-radius: 5px;
  color: var(--text-dim, #a4aab3);
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.tppGalleryCell:hover { background: var(--surface-2, #40464f); }
.tppGalleryCell.selected {
  border-color: var(--accent, #c9a24e);
  background: var(--accent-dim, #4a4230);
  color: var(--accent, #c9a24e);
}
/* Native size, like everything else here: the swatch is generated at 92x92
   (assets/themePreviewBuilder.js) and squeezing it to 56 was a downscale
   for no reason. */
.tppGalleryCell img {
  image-rendering: pixelated;
  display: block;
}
.tppGalleryCell span {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.tppGalleryPreview {
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-height: 0;
  overflow: auto;
}
.tppGalleryPreviewName { font-weight: 600; }

/* ---- source tabs (texture modal): which tile's sprites you're browsing --- */

/* One row, horizontally scrollable - there are ~48 source tiles and they
   must not wrap into a wall of buttons above the grid. */
.tppSourceTabs {
  display: flex;
  gap: 4px;
  overflow-x: auto;
  padding-bottom: 4px;
  flex: none;
}
.tppSourceTab {
  padding: 4px 9px;
  white-space: nowrap;
  background: var(--surface-1, #363b44);
  color: var(--text-dim, #a4aab3);
  border: 1px solid var(--border, #4e555f);
  border-radius: 999px;
  font: inherit;
  font-size: 11px;
  cursor: pointer;
}
.tppSourceTab:hover { background: var(--surface-2, #40464f); }
.tppSourceTab.active {
  background: var(--accent-dim, #4a4230);
  border-color: var(--accent, #c9a24e);
  color: var(--accent, #c9a24e);
}
