/* ---- team builder ---- */

/* Name field + Save/Save as new/Load, all in one line, New team pushed to
   the far right in the same red "danger" treatment as reset-sort-btn/
   remove-group-btn (a full reset of the current draft, so it gets the same
   affordance as those). No separate confirm dialog for Save -- clicking it
   saves the name that's already sitting in the field, immediately. */
.team-controls { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; flex-wrap: wrap; }
.team-name-input {
  flex: 1; min-width: 140px; padding: 8px 12px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--bg-panel); color: var(--text); font-size: 0.85rem;
}
.team-controls button {
  padding: 7px 12px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--bg-panel); color: var(--text); font-size: 0.82rem; cursor: pointer; white-space: nowrap;
}
.team-controls button:hover { border-color: var(--accent); }
.team-new-btn {
  margin-left: auto;
  width: 72px;
  border-color: var(--tier-4x) !important;
  background: var(--tier-4x) !important;
  color: #fff !important;
  font-weight: 700;
}
.team-new-btn:hover { filter: brightness(1.15); }

.team-load-wrap { position: relative; }
.team-load-dropdown {
  position: absolute; top: 100%; right: 0; margin-top: 4px; z-index: 15;
  width: 260px; max-height: 320px; overflow-y: auto;
  background: var(--bg-panel-alt); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.4); padding: 4px;
}
.team-load-empty { padding: 10px; font-size: 0.8rem; color: var(--text-dim); font-style: italic; }
.team-load-row { display: flex; align-items: center; gap: 6px; border-radius: 6px; }
.team-load-row.active { background: color-mix(in srgb, var(--accent) 12%, transparent); }
.team-load-row-main { flex: 1; min-width: 0; padding: 7px 8px; cursor: pointer; border-radius: 6px; }
.team-load-row-main:hover { background: var(--bg-panel); }
.team-load-name { font-size: 0.85rem; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.team-load-meta { font-size: 0.68rem; color: var(--text-dim); margin-top: 2px; }
.team-load-delete {
  flex-shrink: 0; margin-right: 6px; cursor: pointer; color: var(--text-dim);
  background: none; border: none; font-size: 1rem; padding: 4px 6px; border-radius: 4px;
}
.team-load-delete:hover { color: #fff; background: var(--tier-4x); }

/* Stage selector -- same button+dropdown shape as Load above, mirrored to
   the left side of .team-controls (see renderControls' markup order),
   which is what shrinks .team-name-input (flex:1) to make room for it. */
.team-stage-wrap { position: relative; }
#team-stage-btn {
  padding: 7px 12px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--bg-panel); color: var(--text); font-size: 0.82rem; cursor: pointer; white-space: nowrap;
}
#team-stage-btn:hover { border-color: var(--accent); }
.team-stage-dropdown {
  position: absolute; top: 100%; left: 0; margin-top: 4px; z-index: 15;
  width: 220px; max-height: 320px; overflow-y: auto;
  background: var(--bg-panel-alt); border: 1px solid var(--border); border-radius: 8px;
  box-shadow: 0 6px 18px rgba(0,0,0,0.4); padding: 4px;
}
.team-stage-row { padding: 7px 8px; font-size: 0.82rem; cursor: pointer; border-radius: 6px; }
.team-stage-row:hover { background: var(--bg-panel); }
.team-stage-row.active { background: color-mix(in srgb, var(--accent) 12%, transparent); font-weight: 600; }

/* "!" stage-conflict marker (see team.js's effectiveLevelForMember) --
   deliberately just a small flag, never blocking anything, on any card's
   corner alongside the existing form/BST badges. */
.team-stage-conflict {
  display: inline-flex; align-items: center; justify-content: center;
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--tier-4x); color: #fff; font-size: 0.65rem; font-weight: 700;
  line-height: 1; cursor: default;
}

/* Top bar: either the roster search picker (a normal flex row -- its width
   doesn't need to line up with anything below it), or (once 6 Pokemon are
   picked, or the toggle button is used manually) a panel-styled strip of
   per-member shiny toggles -- see team.js's renderTopbar(). The toggle
   button itself is a fixed width matching .team-new-btn above it so the two
   line up regardless of which mode is showing. */
/* Shared by the search input and the shiny bar (below) so they're
   guaranteed the same height by construction, rather than by trying to
   independently match padding/border/line-height math across two elements
   with very different font sizes (the input's 16px inherited body font vs.
   the toggle row's own sizing) -- that's what left the shiny bar very
   slightly shorter than the search input despite both starting at the
   same top edge. */
.team-topbar { margin-bottom: 16px; --team-topbar-field-h: 39px; }
.team-topbar-row { display: flex; align-items: flex-start; gap: 8px; }
.team-topbar-toggle-btn {
  /* height: var(--team-topbar-field-h), not vertical padding -- the same
     fix the search input and shiny bar already use (see the comment
     above), applied to the one element in this row that was still missing
     it. Without an explicit height, this button's own height came out of
     its padding + font line-height instead, which landed a couple px
     short of the other two -- close enough to look right at a glance, but
     not an exact match, which is what made it read as "the bars are
     slightly taller than the button" rather than all three being equal. */
  flex-shrink: 0; width: 72px; height: var(--team-topbar-field-h); box-sizing: border-box;
  display: flex; align-items: center; justify-content: center;
  border-radius: 8px; border: 1px solid var(--border);
  background: var(--bg-panel); color: var(--text); font-size: 0.82rem; cursor: pointer;
}
.team-topbar-toggle-btn:hover { border-color: var(--accent); }

.team-picker { position: relative; flex: 1; min-width: 0; }
.team-picker input {
  width: 100%; height: var(--team-topbar-field-h); box-sizing: border-box;
  padding: 0 12px; border-radius: 8px; border: 1px solid var(--border);
  background: var(--bg-panel); color: var(--text);
}
.team-picker-results {
  position: absolute; top: 100%; left: 0; right: 0; z-index: 5;
  background: var(--bg-panel); border: 1px solid var(--border); border-radius: 8px;
  max-height: 300px; overflow-y: auto; margin-top: 4px;
}
.team-picker-result { display: flex; align-items: center; gap: 8px; padding: 6px 10px; cursor: pointer; }
.team-picker-result:hover { background: var(--bg-panel-alt); }
.team-picker-result img { width: 32px; height: 32px; image-rendering: pixelated; }

/* Same "dark red, can't-not-danger" disabled look as .team-aux-up-disabled
   (see there) -- shown when the roster is already full, so a search result
   that can't actually be added doesn't look identical to one that can. */
.team-picker-result.team-picker-result-disabled {
  cursor: not-allowed; opacity: 0.55; background: #2a1414;
}
.team-picker-result.team-picker-result-disabled:hover { background: #2a1414; }

/* Two independent layers, not one panel wearing two hats:

   .team-shiny-backdrop is the visible rounded box, sized to exactly match
   the search bar's own width (100% minus the button's 72px and its 8px
   gap -- the identical math the search-mode flex row below already does),
   so the bar reads as "just as long as the search bar" rather than
   stretching edge to edge.

   .team-shiny-bar is a separate, unstyled overlay sized to the FULL
   container width, using the exact same grid-template-columns/gap as
   .team-board below it -- that's what keeps the 6 toggles pixel-aligned
   above their own slots regardless of how wide the visible backdrop is.
   A single element couldn't satisfy both "as short as the search bar" and
   "aligned with a full-width 6-column board" at once, which is exactly
   the conflict a single panel-with-inset-button ran into before.

   The toggle button sits at top:0/right:0 -- flush, no inset -- so it
   lands in exactly the position the search-mode flex row already puts its
   own button in (a flex child with no extra margin, flush against the
   row's own right edge). Any nonzero top/right here was guessing at that
   position instead of just matching it exactly. */
.team-shiny-panel { position: relative; }
.team-shiny-backdrop {
  position: absolute; top: 0; left: 0; height: var(--team-topbar-field-h);
  width: calc(100% - 80px); /* 72px button + 8px gap */
}
.team-topbar-toggle-corner { position: absolute; top: 0; right: 0; }
.team-shiny-bar {
  /* Explicit height (not the old padding: 6px 0, which only approximated
     the search input's own height rather than matching it exactly) --
     see --team-topbar-field-h above. align-items: center still handles
     vertically centering each toggle within it. */
  height: var(--team-topbar-field-h); box-sizing: border-box;
  display: grid; grid-template-columns: repeat(6, 1fr); gap: 10px; align-items: center;
}
.team-shiny-cell { display: flex; align-items: center; justify-content: center; padding: 0 4px; }

/* Roster (6 slots) + the merged coverage panel, all one grid. Column gap
   (10px) is what also separates the roster slots from each other, so it
   stays small; row gap is bumped to 16px -- matching the spacing between
   every other stacked block on this page (team-topbar, team-board's own
   margin-bottom, the gap between the Benched and Favorites panels) -- so
   the row break between the roster and the coverage panel below it (the 6
   slots fill exactly one implicit grid row, the panel wraps to the next)
   doesn't read as roughly half that spacing the way the old uniform 10px
   `gap` shorthand did. */
.team-board { display: grid; grid-template-columns: repeat(6, 1fr); column-gap: 10px; row-gap: 16px; margin-bottom: 16px; }
/* Defensive and offensive used to be two separate 3-column panels sitting
   side by side, with the grid's own 10px column gap reading as the visual
   gap between them. They always collapsed/reopened together in practice,
   so they're now one panel spanning the full 6 columns; the same 10px gap
   is recreated *inside* it (see .team-coverage-headings/.team-coverage-tables
   below) so the two halves still line up exactly as they did before --
   same widths, same gap, just one shared backdrop instead of two. */
.team-coverage-panel { grid-column: 1 / -1; position: relative; align-self: start; }
/* Sits in the panel's own top-right corner, replacing the two separate
   per-half collapse buttons that used to live inline with each heading.
   Sized to match the roster card's own small corner buttons (see
   .team-slot-bench) rather than the old, much larger 28px/1.1rem button --
   see the shared .team-panel-collapse-btn rule below. */
.team-coverage-panel .team-coverage-collapse-btn { position: absolute; top: 16px; right: 16px; }
.team-coverage-headings {
  display: grid; grid-template-columns: repeat(6, 1fr); column-gap: 10px;
}
/* Centered over each half's own table below it, not left-aligned -- and no
   padding-right carve-out for the collapse button (an earlier attempt):
   that shrank this row to a different width than .team-coverage-tables
   below it, which threw off centering relative to the actual tables. The
   button is small enough now (20px) to just float over the corner without
   needing the headings row to make room for it. */
.team-coverage-heading { grid-column: span 3; margin: 0 0 12px; font-size: 1.05rem; text-align: center; }
.team-coverage-tables { display: grid; grid-template-columns: repeat(6, 1fr); column-gap: 10px; }
.team-coverage-tables > div { grid-column: span 3; }
/* Author-level `display: grid` above always wins over the browser's own
   default `[hidden] { display: none }` UA-stylesheet rule (author styles
   beat user-agent styles regardless of selector specificity) -- so setting
   the `hidden` attribute via JS was doing nothing visually: the element's
   `hidden` property read true, but it stayed on screen, laid out as a
   grid, exactly as if nothing had been collapsed. This is what actually
   broke the collapse behavior after the merge (not a JS bug -- the JS was
   already toggling the attribute correctly). Restated explicitly here so
   our own rule doesn't outrank the browser's hidden behavior. */
.team-coverage-tables[hidden] { display: none; }
/* Collapsed: the headings stay visible (they're the merged panel's own
   title row now), only the tables hide -- same reasoning as the old
   .panel-collapsed > .team-panel-header rule, just retargeted at this
   panel's own heading row instead. */
.team-coverage-panel.panel-collapsed .team-coverage-heading { margin-bottom: 0; }

.team-slot {
  background: var(--bg-panel);
  border: 1px dashed var(--border);
  border-radius: 10px;
  min-height: 120px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 8px;
  position: relative;
}
.team-slot.filled {
  border: 1px solid var(--border);
  align-items: stretch;
  justify-content: flex-start;
  text-align: center;
  padding: 10px;
  min-height: 0;
}
.team-slot .add-label { color: var(--text-dim); font-size: 0.8rem; }

/* Red "X", same danger treatment as reset-sort-btn -- now sits where the
   Matrix card's BST used to (top-right), since BST moved down into the
   corner stack below to make room for it. Flex-centered rather than relying
   on line-height to vertically center the glyph -- line-height's centering
   is only approximate (depends on the font's own internal metrics), which
   is why the &times; glyph was visibly sitting low in the box; flex
   alignment centers the actual glyph box exactly regardless of font. */
/* Flexbox-centering the button's content box (tried previously) still left
   the X looking off-center, because the actual problem was never the box,
   it was the &times; glyph -- most fonts don't draw that character
   perfectly centered within its own line box, so no amount of centering
   the box fixes it. Drawn as two rotated bars instead, positioned at
   top/left: 50% + translate(-50%, -50%), which is exact regardless of
   font/rendering: it's plain geometry, not glyph metrics. The &times; text
   itself is kept in the markup (see team.js) for screen readers, just
   made invisible here. */
.team-slot-remove {
  position: absolute; top: 8px; right: 8px; z-index: 2; cursor: pointer;
  width: 20px; height: 20px; padding: 0;
  border-radius: 6px; border: 1px solid var(--tier-4x); background: var(--tier-4x);
  color: transparent; font-size: 0.85rem; font-weight: 700; line-height: 1;
}
.team-slot-remove::before, .team-slot-remove::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 10px; height: 2px; border-radius: 1px; background: #fff;
}
.team-slot-remove::before { transform: translate(-50%, -50%) rotate(45deg); }
.team-slot-remove::after { transform: translate(-50%, -50%) rotate(-45deg); }
.team-slot-remove:hover { filter: brightness(1.15); }

/* Sits directly under the remove X, same footprint -- the down arrow glyph
   itself renders centered fine (unlike &times; above), so no pseudo-element
   redraw is needed here. */
.team-slot-bench {
  position: absolute; top: 32px; right: 8px; z-index: 2; cursor: pointer;
  width: 20px; height: 20px; padding: 0;
  border-radius: 6px; border: 1px solid var(--border); background: var(--bg-panel);
  color: var(--text-dim); font-size: 0.65rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.team-slot-bench:hover { color: var(--text); border-color: var(--accent); }

/* Third and last spot in the stack, same 24px step below Bench that Bench
   itself sits below Remove -- only rendered once the roster IS a saved
   team (see team.js's rosterIsSavedTeam), so this button doesn't always
   occupy the slot. */
.team-slot-rename {
  position: absolute; top: 56px; right: 8px; z-index: 2; cursor: pointer;
  width: 20px; height: 20px; padding: 0;
  border-radius: 6px; border: 1px solid var(--border); background: var(--bg-panel);
  color: var(--text-dim);
  display: flex; align-items: center; justify-content: center;
}
.team-slot-rename svg { width: 12px; height: 12px; }
.team-slot-rename:hover { color: var(--text); border-color: var(--accent); }

.team-slot-corner {
  display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  position: absolute; top: 8px; left: 10px;
}
/* line-height: 1 on both -- without it, each span's own font leading (the
   few extra px of whitespace line-height reserves above/below the glyph
   itself, on top of the flex column's fixed gap) reads as a bigger visual
   gap between ID and BST than between BST and the form badge (which has
   much less internal leading at its own smaller font-size), even though
   the actual gap value is identical between every pair. Stripping the
   leading out of these two makes all the gaps read as the same size. */
.team-slot-num { font-size: 0.68rem; color: var(--text-dim); line-height: 1; }
.team-slot-bst { font-size: 0.68rem; color: var(--text); font-weight: 700; line-height: 1; }
/* line-height: 1 alone wasn't quite enough -- the form badge's own tight
   padding still reads visually closer to BST than BST reads to ID above
   it. This small extra nudge closes that remaining gap so all the pairs
   in the stack read as evenly spaced. */
.team-slot-corner .form-badge { margin-top: 2px; }
/* The "!" stage-conflict marker (see team-stage-conflict below) is a small
   solid circle with no internal leading at all, unlike the text/badge pairs
   above it -- without its own nudge it reads noticeably closer to the form
   badge above it than every other pair in this stack. */
.team-slot-corner .team-stage-conflict { margin-top: 4px; }

.team-slot-sprite-area { cursor: pointer; padding-top: 14px; }
/* 77px (70 + 10%) -- the roster card has more spare room than the compact
   Benched/Favorites cards, which keep the dex's own 70px footprint (see
   ROSTER_SPRITE_PX vs TEAM_SPRITE_PX in team.js). Both the clipping box
   and the image itself need the override -- .sprite-ground-box's own base
   rule elsewhere in this file is a plain 70px shared by every other sprite
   context (dex cards, Benched/Favorites cards), so left alone it would
   still clip this bigger image back down to 70px. */
.team-slot-sprite-area .sprite-ground-box { width: 77px; height: 77px; }
.team-slot-sprite-area img { width: 77px; height: 77px; image-rendering: pixelated; color: transparent; }
.team-slot-sprite-area .slot-name { font-size: 0.82rem; font-weight: 600; margin-top: 4px; }
.team-slot-sprite-area .dex-types { display: flex; gap: 3px; justify-content: center; margin-top: 4px; }
.team-slot-sprite-area .dex-types .type-badge { padding: 2px 6px; font-size: 0.62rem; letter-spacing: 0.01em; }

/* Reuses the dex Matrix card's own 2x3 stat grid (.dex-card-stats), just
   with a second divider added below it (mirroring the one .dex-card-stats
   already draws above itself) so the stats read as their own separated
   block sitting between the name/types and the move fields, not fused to
   either. */
/* The team card is much wider than the dex Matrix card, so a fixed-px
   divider width (an earlier attempt) doesn't track the few pixels the
   actual stats content shifts by depending on digit count (65 vs 150 vs
   100 all render at slightly different widths). Instead of guessing a
   width, this makes .dex-card-stats itself size to its own real content
   (width: fit-content instead of the block-level default of filling its
   parent) and centers that content-sized box with margin auto -- both
   borders then sit directly on that box, so they always exactly bracket
   whatever the stats actually rendered at, on every Pokemon, with nothing
   to keep in sync by hand. This only overrides the team page's own
   instance; the dex Matrix card's .dex-card-stats (base rule, elsewhere in
   this file) is untouched and still spans its card edge-to-edge as before. */
.team-slot-stats { margin-bottom: 2px; }
.team-slot-stats .dex-card-stats {
  /* Safe to size to its own real content here (unlike the base rule above)
     since the team card is always wide enough for the 3 packs to fit --
     this is what makes the divider hug the actual stat text width instead
     of spanning the whole (much wider) card edge to edge. */
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
  /* Explicit rather than inherited: the base rule's own gap (3px 0) relies
     on justify-content: space-between distributing leftover width, which
     doesn't exist once this box is sized to its own content -- without
     this, the packs here would render with a 0px column-gap. */
  gap: 3px 14px;
  border-bottom: 1px solid #8d9199;
  padding-bottom: 8px;
}

.team-slot-fields { display: flex; flex-direction: column; gap: 6px; margin-top: 10px; }
.team-move-field, .team-ability-field { width: 100%; }
/* A move field is now a row: the reorder arrows (fixed-width, stacked)
   plus the searchable-select combobox taking the rest -- min-width: 0 is
   what actually lets a flex item shrink below its content's natural width
   instead of overflowing the card. */
.team-move-field { display: flex; align-items: center; gap: 5px; }
.team-move-field .searchable-select { flex: 1; min-width: 0; }
.team-move-reorder { display: flex; flex-direction: column; gap: 2px; flex-shrink: 0; }
.team-move-reorder-btn {
  width: 15px; height: 12px; padding: 0; border-radius: 3px; border: 1px solid var(--border);
  background: var(--bg-panel); color: var(--text-dim); font-size: 0.5rem; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.team-move-reorder-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--accent); }
.team-move-reorder-btn:disabled { opacity: 0.25; cursor: not-allowed; }
.team-slot-fields .searchable-select { display: block; width: 100%; }
.team-slot-fields .searchable-input { width: 100%; box-sizing: border-box; font-size: 0.78rem; padding: 6px 8px; }
.team-slot-fields .searchable-dropdown { left: 0; right: 0; width: auto; min-width: 0; }
/* #8d9199, not var(--border) -- matches the other dividers on this card
   (the stats block's own border-top/border-bottom, just above this field)
   instead of the much darker default border color, which read as an odd
   one out next to them. */
.team-ability-field { padding-top: 4px; border-top: 1px solid #8d9199; }
/* Matches .team-slot-fields .searchable-input's own look (same padding/
   font-size/border/radius/colors) so swapping the ability field from a
   searchable combobox to a plain <select> -- there are at most 3 abilities
   to choose from, nowhere near the "hundreds of options" the searchable
   pattern exists for -- doesn't read as a visually different kind of field
   from the move fields above it. */
.team-ability-select {
  width: 100%; box-sizing: border-box; font-size: 0.78rem; padding: 6px 8px;
  border-radius: 6px; border: 1px solid var(--border);
  background: var(--bg); color: var(--text); cursor: pointer;
}
.team-ability-select:focus { outline: none; border-color: var(--accent); }
/* Only rendered when the selected ability is actually swapped under
   Restricted/Hardcore mode (see renderFilledSlot's abilitySwapNoteHtml) --
   kept to a single small line deliberately, since an earlier always-on
   note here was found to push the card grid's row heights around when it
   wrapped (see that function's own comment). */
.team-ability-swap-note { font-size: 0.7rem; margin-top: 3px; }

/* ---- benched / favorites panels ----
   Cards reuse .dex-card and its children wholesale (see auxCardHtml in
   team.js) so these read as the same visual language as the Pokedex's own
   Matrix view rather than a bespoke look. Only the parts that don't apply
   here get overridden: the whole card isn't a single click target (only
   the sprite navigates), so the base .dex-card hover/cursor treatment is
   turned off and moved onto just the sprite area. There's no bottom
   actions row anymore -- the buttons live in the top-right corner instead
   (see .team-aux-remove/.team-aux-up below), the same corner the roster
   card's own remove/bench buttons occupy, so a card with no moves/ability
   fields to show doesn't need a divider bar it has nothing to separate. */
/* .team-board already ends with its own margin-bottom (16px), matching the
   gap between every other stacked block on this page -- the Benched panel
   needs the same, since it's followed directly by the Favorites panel with
   nothing else supplying that spacing. */
#team-benched-panel { margin-bottom: 16px; }

/* Wraps the Favorites panel's own "Favorites" heading together with its
   ID/Name/Type sort buttons, on one row, so the buttons sit level with the
   heading rather than pushed onto their own line below it. */
.team-favorites-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 10px;
}
.team-favorites-header h2 { margin: 0; }
/* Reuses the dex sort bar's own .sort-btn styling (see .sort-btn above) for
   visual consistency with the rest of the app, rather than introducing a
   second button style for what is functionally the same control. */
.team-aux-sort {
  display: flex;
  gap: 6px;
}

.team-aux-grid {
  display: grid;
  /* 165px, not 150px -- 10% wider than the dex Matrix card's own column,
     giving the sprite (still the same size as the dex's own) more empty
     breathing room around it instead of crowding the card's edges. */
  grid-template-columns: repeat(auto-fill, minmax(165px, 1fr));
  gap: 10px;
}
/* Own favorite-status star, separate from the top-right action button(s)
   -- shown on both Benched and Favorite cards so favorite status can be
   toggled from either panel, not just the detail page. Lives as the 4th
   item in the corner stack (ID -> BST -> form -> star, see auxCardHtml in
   team.js), sized down to fit alongside the rest of that stack rather than
   the much larger default .favorite-star size meant for standalone use. */
.team-aux-favorite-star { font-size: 0.85rem; line-height: 1; }
/* Spans every column instead of landing in the grid's first ~150px track
   like a normal card would -- without this the empty-state message wraps
   after every couple words (reading as one tall, narrow ragged column)
   and inflates the whole panel's height for no reason. */
.team-aux-empty { grid-column: 1 / -1; color: var(--text-dim); font-size: 0.85rem; margin: 4px 0 0; }
.team-aux-card { cursor: default; }
.team-aux-card:hover { transform: none; border-color: var(--border); }
.team-aux-card-sprite-area { cursor: pointer; padding-top: 14px; }

/* Same red-X-via-pseudo-elements trick as .team-slot-remove (see there for
   why: the &times; glyph itself isn't centered within its own text box in
   most fonts, pseudo-element bars drawn at exact 50%/50% are). Delete
   (top) and return-to-team (below it) mirror the roster card's own
   remove/bench stack exactly, just on a card with no move/ability fields
   below to make room for. */
.team-aux-remove, .team-aux-up {
  position: absolute; right: 8px; z-index: 2; cursor: pointer;
  width: 20px; height: 20px; padding: 0; border-radius: 6px;
}
.team-aux-remove {
  top: 8px; border: 1px solid var(--tier-4x); background: var(--tier-4x);
  color: transparent; font-size: 0.85rem; font-weight: 700; line-height: 1;
}
.team-aux-remove::before, .team-aux-remove::after {
  content: ""; position: absolute; top: 50%; left: 50%;
  width: 10px; height: 2px; border-radius: 1px; background: #fff;
}
.team-aux-remove::before { transform: translate(-50%, -50%) rotate(45deg); }
.team-aux-remove::after { transform: translate(-50%, -50%) rotate(-45deg); }
.team-aux-remove:hover { filter: brightness(1.15); }

.team-aux-up {
  top: 32px; border: 1px solid var(--border); background: var(--bg-panel);
  color: var(--text-dim); font-size: 0.65rem; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
.team-aux-up:hover { color: var(--text); border-color: var(--accent); }
/* Favorites only ever get the up-arrow, with no delete button above it --
   sits in the top slot instead of waiting under a button that isn't there. */
.team-aux-up.team-aux-up-only { top: 8px; }

/* Dark red "unavailable" look once the roster is full -- both
   unbenchMember and addFavoriteToTeam already no-op silently in that
   case (see team.js), so this makes that state visible up front instead
   of a button that looks clickable but quietly does nothing. A dark,
   desaturated red rather than the bright .team-aux-remove red, so it
   doesn't read as another delete action -- this is "can't", not
   "danger." The real `disabled` attribute (see team.js) backs this up
   at the DOM level too, not just visually. */
.team-aux-up.team-aux-up-disabled {
  background: #4a1414; border-color: #4a1414; color: rgba(255, 255, 255, 0.55);
  cursor: not-allowed;
}
.team-aux-up.team-aux-up-disabled:hover { color: rgba(255, 255, 255, 0.55); border-color: #4a1414; }

/* ---- defensive/offensive matrices ----
   table-layout: fixed (rather than the default auto, which sizes each
   column to whatever its widest cell wants) is what makes these actually
   fit inside a 3-slot-wide panel without a horizontal scrollbar -- auto
   layout let 6 Pokemon name columns each claim as much width as their own
   longest name needed, which is exactly what was overflowing.

   Type and the two conclusion columns are back to an explicit width
   (an equal 9-way split, tried previously, still wasn't wide enough for
   "Fighting"/"Electric" once the Pokemon-name columns had claimed their
   even share).

   The Type column's actual bottleneck turned out not to be the column
   width at all, but the type badge inside it: .type-badge's base rule
   (used everywhere else at full size, e.g. a Pokemon's own type pills on
   its card) is 0.72rem text plus 9px of horizontal padding on each side,
   which alone ate most of any reasonable column width before a single
   letter was drawn. It needed the same compact treatment already used
   for badges in other tight spots (.dex-card .dex-types .type-badge,
   .team-slot-sprite-area .dex-types .type-badge) -- smaller font, smaller
   padding -- rather than a wider column trying to out-grow an oversized
   badge.

   Conclusion headers are now abbreviated to single letters/initials --
   W/R (from Weak/Resist) and NVE/SE (from Not Very/Super) -- specifically
   so their column can shrink further still, freeing more width for
   --matrix-side-col, which is the one that actually needs it (full
   English type names). --matrix-side-col and --matrix-total-col are kept
   as two separate custom properties since they're sized for different
   content (the longest type name vs. the longest of W/R/NVE/SE, which is
   NVE at 3 characters) and only need to be internally consistent within
   their own group, not with each other. Whatever's left after both
   splits evenly across the Pokemon columns, which is also what keeps
   both tables' columns matching each other -- same column count and
   same two side-column widths on both. */
.matrix-table-wrap {
  overflow-x: hidden;
  --matrix-side-col: 88px;
  --matrix-total-col: 34px;
}
.matrix-table { width: 100%; table-layout: fixed; border-collapse: collapse; font-size: 0.72rem; }
.matrix-table th, .matrix-table td {
  padding: 4px 4px; text-align: center; border: 1px solid var(--border);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.matrix-table th { color: var(--text-dim); font-weight: 600; font-size: 0.64rem; text-transform: uppercase; }
.matrix-row-label { text-align: left; width: var(--matrix-side-col); }
.matrix-row-label .type-badge {
  display: block; width: 100%; box-sizing: border-box; text-align: center;
  overflow: hidden; text-overflow: ellipsis;
  font-size: 0.62rem; padding: 2px 6px; letter-spacing: 0.01em;
}
.matrix-cell-weak { color: var(--tier-4x); font-weight: 700; }
.matrix-cell-resist { color: var(--tier-half); font-weight: 700; }
.matrix-cell-null { color: var(--text-dim); font-style: italic; font-size: 0.6rem; }
.matrix-cell-super { color: var(--tier-half); font-weight: 700; }
/* Offensive table only: a checkmark/cross built off a team member's full
   learnable movepool rather than moves actually picked yet (see team.js's
   teamDamagingMoveTypes/isDefaultMoveset) -- greyed out and de-emphasized
   so it visually reads as "estimate, not a real answer" rather than
   carrying the same weight as a confirmed super/not-very-effective result.
   Declared AFTER .matrix-cell-weak/-super above so its color wins over
   theirs when both classes land on the same cell (plain CSS cascade by
   source order, same specificity -- no !important needed). */
.matrix-cell-fallback { color: var(--text-dim); opacity: 0.55; font-weight: 400; }
/* The two "conclusion" columns -- background intensity (how red/green) is
   set inline per-row in team.js, scaled to how many team members landed in
   that bucket, rather than a flat on/off threshold. */
.matrix-total { font-weight: 700; width: var(--matrix-total-col); }
.matrix-total-head-weak { color: var(--tier-4x) !important; }
.matrix-total-head-resist { color: var(--tier-half) !important; }

/* Row banding (Excel-style alternating stripes) so a row can be followed
   across a wide table by eye without losing track of which one you were
   on. Three alternating shades, each a plain lighten of --bg-panel rather
   than a new color -- this is purely a reading aid, not new information,
   so it shouldn't compete for attention with the weak/resist tint colors.
   Applied per `td`/`th`, not the `tr` itself: the weak/resist conclusion
   columns and the row-label's own type badge already carry their own
   inline `style="background:..."` (see intensityStyle()/typeBadge()
   above), and an inline style always wins the cascade over these class
   rules automatically -- so the banding only ever shows through on cells
   that don't already have a color of their own to show. */
.matrix-table tbody tr:nth-child(3n+1) td,
.matrix-table tbody tr:nth-child(3n+1) th.matrix-row-label { background: rgba(255,255,255,0.02); }
.matrix-table tbody tr:nth-child(3n+2) td,
.matrix-table tbody tr:nth-child(3n+2) th.matrix-row-label { background: rgba(255,255,255,0.045); }
.matrix-table tbody tr:nth-child(3n+3) td,
.matrix-table tbody tr:nth-child(3n+3) th.matrix-row-label { background: rgba(255,255,255,0.07); }

/* Row highlight on hover, tinted with that row's own type color -- same
   idea as the floating Type Chart's row/column highlight (see
   .typechart-hover-row in this file), but pure CSS here since there's no
   "column" concept worth highlighting in these tables (the columns are
   team members, not types) and no need to pin one -- team.js just sets
   `--row-color` inline on each <tr> (see rowTintStyle/renderOffensiveTable)
   to that row's type color, and plain `tr:hover` picks it up. Unlike the
   Type Chart, this is deliberately wired to the whole row rather than
   just the row label, so hovering anywhere in the row -- any cell, not
   only the type badge -- lights it up. */
.matrix-table tbody tr:hover td {
  box-shadow: inset 0 0 0 999px color-mix(in srgb, var(--row-color) 25%, transparent);
}

.suggestion-list { display: flex; flex-direction: column; gap: 6px; }
.suggestion-row { display: flex; align-items: center; gap: 10px; padding: 6px; border-radius: 8px; background: var(--bg-panel-alt); cursor: pointer; }
.suggestion-row:hover { background: var(--bg-panel); }
.suggestion-row img { width: 40px; height: 40px; image-rendering: pixelated; }
.suggestion-row .why { font-size: 0.76rem; color: var(--text-dim); }

