/* kept off wiki.css, nothing else uses it.
   panels are LIGHTER than the page. yes really, case #10 */
.fx-wrap{max-width:min(1880px,96vw);margin:0 auto;padding:0 26px 80px;}
.fx-main{display:grid;grid-template-columns:minmax(280px,340px) minmax(0,1fr);gap:24px;align-items:start;}
@media (max-width:900px){.fx-main{grid-template-columns:minmax(0,1fr);}}
.fx-box{background:var(--bg-2);border:1px solid var(--line);border-radius:16px;}

/* inventory, laid out like the one in game */
.fx-inv{overflow:hidden;position:sticky;top:16px;background:#0b0b0f;}
.fx-inv .fx-bar{background:#050507;}
.fx-inv-head{padding:15px 18px 12px;display:flex;align-items:baseline;justify-content:space-between;gap:10px;}
.fx-inv-head b{font-size:.7rem;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;color:var(--muted);}
.fx-weight{font-size:.92rem;font-variant-numeric:tabular-nums;color:var(--white);font-weight:600;}
.fx-weight i{font-style:normal;color:var(--muted);font-weight:400;font-size:.8rem;}
.fx-weight.over{color:#ff8a7e;}
.fx-bar{height:4px;background:var(--bg);margin:0 18px;border-radius:999px;overflow:hidden;}
.fx-bar span{display:block;height:100%;background:var(--red);transition:width .2s ease;border-radius:999px;}
.fx-bar span.over{background:#ff8a7e;}
/* deep enough to reach the bottom of the attachment rail on the other side, so the two columns
   finish together and the list is not scrolling while there is empty panel next to it. case #125 */
.fx-list{list-style:none;margin:12px 0 0;padding:0;max-height:min(74vh,760px);
  overflow:auto;overscroll-behavior:contain;}

.fx-row{position:relative;}
.fx-row + .fx-row{border-top:1px solid var(--line);}
.fx-rowmain{display:flex;align-items:stretch;}
.fx-slotline{display:flex;align-items:center;gap:10px;flex:1;min-width:0;background:none;border:0;
  color:var(--text);text-align:left;padding:12px 6px 12px 18px;cursor:pointer;font:inherit;font-size:.92rem;}
.fx-row:hover .fx-rowmain,.fx-row.on .fx-rowmain{background:var(--panel);}
/* left bar does double duty, selection + colour code */
.fx-row.on:before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;
  background:var(--red);}
/* colour coded: the whole card carries it, so the inventory and the command bar read as the
   same thing. the wash is kept light enough that the text on top stays legible */
.fx-row--col{background:color-mix(in srgb, var(--swatch) 22%, transparent);
  box-shadow:inset 3px 0 0 var(--swatch);}
.fx-row--col:hover .fx-rowmain,.fx-row--col.on .fx-rowmain{background:color-mix(in srgb, var(--swatch) 12%, transparent);}
.fx-row--col.on:before{background:var(--swatch);}
.fx-row--col .fx-nm{color:#fff;}
.fx-row--col .fx-idx{color:var(--swatch);filter:brightness(1.5);}
/* armour and attachments are not equipped, so they read as kit rather than a numbered slot */
.fx-row--kit .fx-nm{color:var(--muted);font-weight:500;}
.fx-idx{color:var(--muted);font-variant-numeric:tabular-nums;font-size:.76rem;min-width:16px;font-weight:700;}
.fx-row.on .fx-idx{color:var(--swatch,var(--red-2));}
.fx-nm{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:600;}
.fx-meta{display:flex;align-items:center;gap:10px;padding-right:4px;}
.fx-wt{color:var(--muted);font-size:.76rem;font-variant-numeric:tabular-nums;}
/* one pip per slot, lit when filled */
.fx-pips{display:flex;gap:3px;}
.fx-pip{width:5px;height:5px;border-radius:50%;background:rgba(255,255,255,.16);}
.fx-pip.on{background:#39d98a;}
.fx-x{background:none;border:0;color:var(--muted);cursor:pointer;font-size:1.2rem;line-height:1;
  padding:0 15px;opacity:0;transition:opacity .12s ease,color .12s ease;font-family:inherit;}
.fx-row:hover .fx-x,.fx-x:focus-visible{opacity:1;}
.fx-x:hover{color:var(--red-2);}
.fx-subs{list-style:none;margin:0;padding:0 18px 10px 44px;}
.fx-sub{display:flex;gap:10px;font-size:.79rem;color:var(--muted);padding:2px 0;align-items:baseline;}
.fx-sub em{font-style:normal;min-width:56px;font-size:.68rem;letter-spacing:.6px;text-transform:uppercase;}
.fx-sub b{font-weight:500;color:var(--text);}
.fx-empty{padding:32px 20px;text-align:center;color:var(--muted);font-size:.88rem;line-height:1.55;}
.fx-add{display:block;width:100%;padding:14px;background:none;border:0;border-top:1px solid var(--line);
  color:var(--red-2);font:inherit;font-weight:700;font-size:.88rem;cursor:pointer;letter-spacing:.3px;}
.fx-add:hover{background:var(--panel);}
.fx-tabs{display:flex;border-top:1px solid var(--line);background:var(--bg);}
.fx-tab{flex:1;padding:11px 4px;background:none;border:0;color:var(--muted);font:inherit;
  font-size:.7rem;font-weight:800;letter-spacing:.9px;cursor:pointer;transition:color .15s ease;}
.fx-tab:hover{color:var(--text);}
.fx-tab.on{color:#ff8a7e;box-shadow:0 -2px 0 var(--red) inset;}

/* command bar. it's an input because it reads both ways.
   don't restyle the field, wiki.css already does it. case #11 */
.fx-cmd{display:flex;gap:10px;align-items:stretch;margin-bottom:16px;}
.fx-cmdwrap{position:relative;flex:1;min-width:0;display:flex;}
/* pills sit on a layer behind the field, lined up character for character. the input keeps its
   own text and paints it transparent, so typing and the caret still work normally while the
   layer underneath is the thing people actually read */
.fx-cmd input{flex:1;min-width:0;font-family:ui-monospace,Menlo,Consolas,monospace;
  font-size:.88rem;padding:12px 15px;background-color:var(--bg);}
/* only the loadout bar hides its own text, because only that one has a pill layer sitting
   behind it. scoped to .fx-cmdwrap so the bot bar, which is a plain field in the same .fx-cmd
   row, keeps its text visible. case #54 */
.fx-cmdwrap input{position:relative;z-index:1;
  background-color:transparent;color:transparent;caret-color:var(--text);}
.fx-cmdwrap input::selection{background:rgba(223,24,0,.35);color:transparent;}
.fx-cmdhl{position:absolute;inset:0;padding:12px 15px;border:1px solid transparent;
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.88rem;line-height:normal;
  white-space:pre;overflow:hidden;color:var(--text);pointer-events:none;border-radius:10px;
  background:var(--bg);}
.fx-pill{border-radius:999px;padding:2px 7px;margin:0 -1px;
  background:color-mix(in srgb, var(--swatch) 26%, transparent);
  box-shadow:inset 0 0 0 1px color-mix(in srgb, var(--swatch) 70%, transparent);
  color:#fff;}
.fx-cmd input.bad{border-color:rgba(255,199,56,.6);}
.fx-btn{background:var(--bg-2);border:1px solid var(--line);border-radius:999px;color:var(--text);
  padding:9px 16px;font:inherit;font-size:.84rem;font-weight:600;cursor:pointer;white-space:nowrap;
  transition:background .15s ease,border-color .15s ease,color .15s ease;}
.fx-btn:hover{border-color:rgba(255,255,255,.2);background:var(--panel);}
.fx-btn.on{background:rgba(223,24,0,.16);border-color:rgba(223,24,0,.5);color:#ff8a7e;}
/* notes were a run of loose yellow lines, which reads as a warning about something going wrong
   rather than a thing worth knowing. cards on a quiet amber, one to a line, with a mark down the
   side so several of them still scan as a list. case #141 */
.fx-notes{display:flex;flex-direction:column;gap:6px;margin:-2px 0 16px;}
.fx-notes:empty{display:none;}
.fx-notes p{position:relative;margin:0;padding:9px 34px 9px 34px;
  background:rgba(255,199,56,.07);border:1px solid rgba(255,199,56,.22);
  border-left-width:3px;border-radius:10px;
  color:var(--text);font-size:.83rem;line-height:1.5;}
.fx-notes p:before{content:"i";position:absolute;left:12px;top:10px;
  width:14px;height:14px;border-radius:50%;background:rgba(255,199,56,.85);
  color:#241a00;font-size:.6rem;font-weight:800;line-height:14px;text-align:center;
  font-family:"Gin",sans-serif;}
/* how people put one away. quiet until they go near it, it's not the point of the note */
.fx-note-x{position:absolute;top:6px;right:7px;width:20px;height:20px;border-radius:50%;
  background:none;border:none;color:var(--muted);cursor:pointer;font-size:1rem;line-height:1;
  padding:0;opacity:0;transition:opacity .15s ease,color .15s ease,background .15s ease;}
.fx-notes p:hover .fx-note-x,.fx-note-x:focus-visible{opacity:1;}
.fx-note-x:hover{background:rgba(255,199,56,.18);color:var(--white);}

/* ---- the gun, with a cross on every slot it has ---- */
.fx-stage{padding:20px 22px;margin-bottom:18px;}
/* keep max-width. ratio + min-height means css works the WIDTH out backwards. 480px inside a
   282px box. whole page went sideways on a phone. case #180 */
.fx-shot{position:relative;aspect-ratio:16/6;min-height:180px;max-width:100%;display:flex;
  align-items:center;justify-content:center;background:var(--bg);border:1px solid var(--line);
  border-radius:12px;}
/* the weapon's own picture, faded out at the edges so it sits in the panel rather than in a
   hard rectangle. the mask is what does the fade, on all four sides */
.fx-art{position:absolute;inset:10px;border-radius:26px;overflow:hidden;}
.fx-art img,.fx-art .thumb{width:100%;height:100%;object-fit:contain;display:block;
  -webkit-mask-image:radial-gradient(ellipse 78% 78% at 50% 50%, #000 52%, transparent 92%);
  mask-image:radial-gradient(ellipse 78% 78% at 50% 50%, #000 52%, transparent 92%);}
.fx-art .thumb--none{background:var(--panel-2);opacity:.4;}
.fx-cross{position:absolute;transform:translate(-50%,-50%);width:30px;height:30px;border:0;
  background:none;cursor:pointer;padding:0;border-radius:50%;transition:background .15s ease;}
.fx-cross:before,.fx-cross:after{content:"";position:absolute;left:50%;top:50%;background:var(--red-2);
  transform:translate(-50%,-50%);border-radius:1px;}
.fx-cross:before{width:15px;height:2px;} .fx-cross:after{width:2px;height:15px;}
.fx-cross:hover{background:rgba(223,24,0,.2);}
.fx-cross.filled:before,.fx-cross.filled:after{background:#39d98a;}
.fx-cross.filled{background:rgba(57,217,138,.16);}
.fx-cross .lbl{position:absolute;left:50%;top:calc(100% + 5px);transform:translateX(-50%);
  font-size:.66rem;color:var(--muted);white-space:nowrap;letter-spacing:.5px;}
.fx-cross.filled .lbl{color:#7fe6b0;}
.fx-noneyet{color:var(--muted);font-size:.92rem;text-align:center;padding:40px 10px;}

/* stats. same tile as .dsh-stat so the dashboards match */
.fx-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(215px,1fr));gap:8px 24px;
  padding-top:18px;margin-top:16px;border-top:1px solid var(--line);}
.fx-st{display:flex;justify-content:space-between;gap:12px;font-size:.88rem;padding:4px 0;align-items:baseline;}
.fx-st .k{color:var(--muted);}
.fx-st .v{font-variant-numeric:tabular-nums;color:var(--white);}
.fx-st .was{color:var(--muted);text-decoration:line-through;margin-right:7px;font-size:.79rem;font-weight:400;}
.fx-up{color:#7fe6b0;} .fx-down{color:#ff8a7e;}
.fx-group{grid-column:1/-1;font-size:.68rem;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;
  color:var(--muted);margin-top:12px;padding-top:12px;border-top:1px solid var(--line);}
.fx-group:first-child{margin-top:0;border-top:0;padding-top:0;}

/* ---- pickers, also used for the browse section at the bottom ---- */
.fx-pick{position:fixed;inset:0;background:rgba(0,0,0,.7);z-index:60;display:flex;
  align-items:center;justify-content:center;padding:20px;}
.fx-pick[hidden]{display:none;}
/* freeze the page behind or people close the picker and land somewhere else. case #182 */
html.fx-modal,html.fx-modal body{overflow:hidden;}
/* dvh. vh counts the bit the address bar is sitting on. thanks safari */
.fx-panel{overscroll-behavior:contain;background:var(--bg-2);border:1px solid var(--line);border-radius:18px;
  width:min(920px,100%);max-height:86vh;max-height:86dvh;display:flex;flex-direction:column;
  overflow:hidden;box-shadow:0 20px 60px rgba(0,0,0,.55);}
.fx-panel-head{padding:16px 20px;border-bottom:1px solid var(--line);display:flex;gap:12px;align-items:center;}
.fx-panel-head h3{margin:0;font-size:1.05rem;color:var(--white);flex:1;}
.fx-search{width:min(260px,42vw);background-color:var(--bg);}
/* the filters are two questions, so they are two labelled lines rather than one wrap of chips.
   a quieter strip than the panel, so the answers below stay the loudest thing. case #138 */
.fx-filters{padding:10px 20px 12px;border-bottom:1px solid var(--line);
  background:rgba(0,0,0,.16);}
/* the panel is also used for a help note and for one item's stats, which have nothing to filter.
   without this the empty strip reads as a bar that failed to load. case #160 */
.fx-filters:empty{display:none;}
.fx-frow{display:flex;align-items:baseline;gap:12px;padding:4px 0;}
.fx-frow + .fx-frow{border-top:1px solid rgba(255,255,255,.05);padding-top:9px;margin-top:5px;}
/* wide enough for the longest of these labels on one line. at 104 "How you get it" wrapped */
.fx-frow-k{flex:0 0 118px;font-size:.62rem;font-weight:800;letter-spacing:1.1px;
  text-transform:uppercase;color:var(--muted);padding-top:5px;}
.fx-frow-c{flex:1;display:flex;gap:6px;flex-wrap:wrap;min-width:0;}
@media (max-width:620px){
  .fx-frow{flex-direction:column;gap:5px;}
  .fx-frow-k{flex:none;padding-top:0;}
  /* 26 chips wrapped is taller than the panel, so the list people came for starts below the
     screen. one line each, scrolls sideways. case #183

     align-self:stretch is load bearing. the row above is still align-items:baseline, which
     sizes to content, and 660px of nowrap chips stretched the page instead of scrolling */
  .fx-frow-c{flex-wrap:nowrap;align-self:stretch;overflow-x:auto;overscroll-behavior-x:contain;
    scrollbar-width:none;padding-bottom:2px;}
  .fx-frow-c::-webkit-scrollbar{display:none;}
}
/* title + search + Close will not share a line on a phone. heading went to three lines */
@media (max-width:520px){
  .fx-pick{padding:10px;}
  .fx-panel-head{flex-wrap:wrap;padding:13px 15px;}
  .fx-panel-head h3{flex:1 1 auto;font-size:1rem;}
  .fx-search{order:3;flex:1 0 100%;width:100%;}
}
.fx-chip{background:var(--bg);border:1px solid var(--line);border-radius:999px;color:var(--muted);
  padding:5px 12px;font:inherit;font-size:.76rem;font-weight:600;cursor:pointer;
  white-space:nowrap;
  transition:background .15s ease,border-color .15s ease,color .15s ease;}
.fx-chip:hover{color:var(--text);border-color:rgba(255,255,255,.2);}
.fx-chip.on{background:rgba(223,24,0,.16);border-color:rgba(223,24,0,.5);color:#ff8a7e;}
/* grid-auto-rows:max-content is doing real work here. the panel is a flex column so this grid
   has a definite height, and a <button> reports almost no intrinsic height, so auto rows just
   split the container between them: five cards came out 222px tall and a hundred came out 3px.
   Sizing rows to their content instead makes them scroll like they should. case #62 */
.fx-opts{overflow:auto;overscroll-behavior:contain;padding:14px;display:grid;gap:12px;
  grid-template-columns:repeat(auto-fill,minmax(210px,1fr));
  grid-auto-rows:max-content;align-content:start;}
/* display:block, not flex. a <button> wraps its children in an anonymous box, so making the
   button itself the flex container does not pass the children's height back up: the grid sized
   every row to 2px while the contents measured 140. case #62 */
.fx-opt{background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:0;
  cursor:pointer;text-align:left;font:inherit;color:var(--text);display:block;width:100%;
  overflow:hidden;transition:border-color .15s ease,background .15s ease;}
/* a fixed height rather than aspect-ratio, and flex:none on both children. inside a <button>
   set to flex column, an aspect-ratio box has no intrinsic height to shrink from, so it
   collapsed to 1px and took the whole card down to 2px with it. case #62 */
.fx-opt-pic{position:relative;display:block;height:116px;background:#0b0a12;
  border-bottom:1px solid var(--line);overflow:hidden;}
.fx-opt-pic img,.fx-opt-pic .thumb{position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;display:block;}
.fx-opt-pic .thumb--none{background:var(--panel-2);}
.fx-opt-kind{position:absolute;top:7px;left:7px;background:rgba(0,0,0,.68);border-radius:999px;
  padding:2px 8px;font-size:.62rem;font-weight:700;letter-spacing:.5px;text-transform:uppercase;
  color:var(--red-2);}
.fx-opt-body{display:flex;flex-direction:column;gap:6px;padding:11px 13px 13px;}
.fx-opt:hover{border-color:var(--red);background:var(--panel);}
.fx-opt-t{font-weight:700;font-size:.92rem;display:flex;justify-content:space-between;gap:9px;align-items:baseline;}
.fx-opt-w{color:var(--muted);font-weight:400;font-size:.76rem;white-space:nowrap;}
.fx-opt-s{display:flex;flex-wrap:wrap;gap:4px 10px;font-size:.76rem;color:var(--muted);}
.fx-opt-s b{font-weight:600;color:var(--text);}
/* clamped so one wordy effect line does not make its whole row twice the height of the
   others. the full text is on the item's own page */
.fx-opt-e{font-size:.76rem;color:var(--muted);font-style:italic;line-height:1.4;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
.fx-opt-s{max-height:3.4em;overflow:hidden;}
/* same shape as .proj-state */
.fx-tagm{color:#ffc738;font-size:.66rem;font-weight:700;background:rgba(255,199,56,.14);
  border:1px solid rgba(255,199,56,.4);border-radius:999px;padding:2px 8px;letter-spacing:.5px;}
/* the rest of a long list, on a button. sits across the grid like the empty state does */
.fx-moreopts{grid-column:1/-1;justify-self:center;margin:4px 0 2px;}
.fx-none{grid-column:1/-1;display:flex;flex-direction:column;align-items:center;gap:9px;
  padding:52px 24px;text-align:center;color:var(--muted);font-size:.88rem;
  background:var(--bg-2);border:1px solid var(--line);border-radius:16px;}
.fx-none b{color:var(--white);font-size:1.15rem;font-weight:700;}
.fx-none span{max-width:420px;line-height:1.55;}

/* the shelf. cards behave like .wiki-card, just denser */
.fx-browse{margin-top:40px;border-top:1px solid var(--line);padding-top:30px;}
/* on its own page it is the page, so it has nothing above to be ruled off from */
.fx-browse--own{margin-top:0;border-top:0;padding-top:0;}
.fx-browse h2{margin:0 0 6px;font-size:1.3rem;color:var(--white);}
.fx-browse .hint{margin:0 0 6px;color:var(--muted);font-size:.95rem;max-width:680px;}
/* the filters sit in a panel of their own rather than as two tinted bands running edge to edge.
   stacked, full bleed and untinted they read as one flat grey slab across the page. panels are
   lighter than the page here, which is the whole depth model. case #176 */
.fx-filterbox{background:var(--bg-2);border:1px solid var(--line);border-radius:16px;
  padding:4px 18px;margin:0 0 22px;}
.fx-browse .fx-filterbox .fx-filters{background:none;border-bottom:0;padding:11px 0;}
.fx-browse .fx-filterbox .fx-filters + .fx-filters{border-top:1px solid rgba(255,255,255,.05);}
.fx-bcards{display:grid;gap:20px;grid-template-columns:repeat(auto-fill,minmax(225px,1fr));margin-top:4px;}
.fx-bcard{background:var(--bg-2);border:1px solid var(--line);border-radius:18px;overflow:hidden;
  cursor:pointer;text-align:left;font:inherit;color:var(--text);padding:0;display:block;
  transition:transform .25s ease,border-color .25s ease,box-shadow .25s ease;}
.fx-bcard:hover{transform:translateY(-6px);border-color:var(--red);box-shadow:0 12px 30px rgba(0,0,0,.4);}
.fx-bthumb{position:relative;aspect-ratio:16/9;background:#0b0a12;overflow:hidden;display:block;
  border-bottom:1px solid var(--line);}
.fx-bthumb img,.fx-bthumb .thumb{position:absolute;inset:0;width:100%;height:100%;
  object-fit:cover;display:block;}
/* stops cards with no picture collapsing */
.fx-bthumb .thumb--none{background:var(--panel-2);}
/* name on the picture, not under it. reads way better in bulk */
.fx-bname{position:absolute;left:0;right:0;bottom:0;padding:26px 14px 11px;font-weight:700;
  font-size:.92rem;line-height:1.25;
  background:linear-gradient(to top,rgba(0,0,0,.9),rgba(0,0,0,.55) 55%,transparent);color:var(--white);}
.fx-bsub{position:absolute;top:9px;left:9px;background:rgba(0,0,0,.68);border-radius:999px;
  padding:3px 9px;font-size:.66rem;font-weight:700;letter-spacing:.6px;text-transform:uppercase;
  color:var(--red-2);}

/* the buttons squashed the command to about 5 characters on a phone.
   the field isn't a child of .fx-cmd, it's inside .fx-cmdwrap, so the old fix aimed at nothing
   and nobody noticed for months. bot builder's is styled by ID because of course it is, so it's
   named here heavy enough to beat it. case #184 */
@media (max-width:640px){
  .fx-wrap{padding:0 16px 60px;}
  .fx-cmd{flex-wrap:wrap;}
  .fx-cmd input,.fx-cmd .fx-cmdwrap,.fx-cmd #bb-cmd{flex:1 0 100%;}
  .fx-btn{flex:1;padding:10px 8px;text-align:center;}
}

/* the stat sheet is the wiki's own, not a copy. wiki.css scopes every stat rule to .infobox so
   the wrapper is the whole trick. without it, bare unstyled rows. case #40 */
.fx-statwrap{margin-top:2px;}
.fx-statwrap .infobox{margin-bottom:0;}
/* two columns on a wide panel, because one long column of thirty rows is all scrolling */
@media (min-width:900px){
  .fx-statwrap .infobox{column-count:2;column-gap:26px;}
  .fx-statwrap .ib-group{break-inside:avoid;}
}
/* what the attachments moved, pinned onto the row rather than replacing the wiki layout */
.fx-delta{margin-left:8px;font-size:.72rem;font-weight:700;border-radius:999px;padding:1px 7px;
  vertical-align:middle;}
.fx-delta.fx-up{background:rgba(57,217,138,.16);color:#7fe6b0;}
.fx-delta.fx-down{background:rgba(255,138,126,.14);color:#ff8a7e;}

/* browse */
.fx-bhead{margin-bottom:4px;}
.fx-bsearch{width:min(420px,100%);}
.fx-filters--types{border-bottom:0;padding-top:0;}
.fx-filters--types[hidden]{display:none;}
/* the extra row for one kind, on the way in. an animation rather than a transition, so a browser
   that never runs it leaves the row at its normal styles instead of at nothing. case #116 */
.fx-drop{animation:fx-drop .18s ease;}
@keyframes fx-drop{from{opacity:0;transform:translateY(-5px);}}
@media (prefers-reduced-motion: reduce){ .fx-drop{animation:none;} }
.fx-sep{width:10px;}
.fx-sublabel{font-size:.68rem;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;
  color:var(--muted);align-self:center;margin-right:2px;}
.fx-rar{font-size:.7rem;font-weight:700;color:var(--muted);letter-spacing:.6px;
  text-transform:uppercase;margin-left:6px;}

/* the detail panel behind a card */
.fx-detail{grid-column:1/-1;display:grid;grid-template-columns:minmax(0,260px) minmax(0,1fr);gap:20px;}
@media (max-width:640px){.fx-detail{grid-template-columns:minmax(0,1fr);}}
.fx-dthumb{position:relative;aspect-ratio:16/9;background:#0b0a12;border:1px solid var(--line);
  border-radius:12px;overflow:hidden;}
.fx-dthumb img,.fx-dthumb .thumb{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block;}
.fx-dthumb .thumb--none{background:var(--panel-2);}
.fx-dsum{margin:0 0 10px;color:var(--muted);font-size:.9rem;line-height:1.5;}
.fx-dacts{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px;}
.fx-dacts a{display:flex;align-items:center;text-decoration:none;}

/* the tool tab bar moved to wiki.css. it is the nav for three sections now, and the keybind
   finder needs it without pulling this whole file in for one row of pills. case #159 */

/* bot builder: pictures down the left, the bot in the middle, answers on the right */
.bb-body{display:grid;grid-template-columns:minmax(200px,240px) minmax(0,1fr) minmax(230px,300px);
  gap:22px;padding:22px;align-items:start;}
@media (max-width:1100px){.bb-body{grid-template-columns:minmax(0,1fr) minmax(0,1fr);}
  .bb-mid{grid-column:1/-1;order:-1;}}
@media (max-width:700px){.bb-body{grid-template-columns:minmax(0,1fr);}}
.bb-left,.bb-right{display:flex;flex-direction:column;gap:14px;}

/* click to fill, then it shows what went in */
.bb-slot{position:relative;background:var(--bg);border:1px dashed var(--line);border-radius:14px;
  padding:12px;cursor:pointer;font:inherit;color:var(--text);text-align:left;
  display:flex;flex-direction:column;gap:8px;transition:border-color .15s ease,background .15s ease;}
.bb-slot:hover{border-color:var(--red);background:var(--panel);}
.bb-slot.filled{border-style:solid;}
.bb-slot-k{font-size:.66rem;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;color:var(--muted);}
.bb-slot-art{position:relative;aspect-ratio:16/10;border-radius:10px;overflow:hidden;
  background:#0b0a12;display:flex;align-items:center;justify-content:center;}
.bb-slot-art img,.bb-slot-art .thumb{position:absolute;inset:0;width:100%;height:100%;
  object-fit:contain;display:block;}
.bb-slot-art .thumb--none{background:var(--panel-2);}
.bb-plus{font-size:1.8rem;color:var(--muted);line-height:1;}
.bb-slot-v{font-size:.86rem;font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.bb-clear{position:absolute;top:8px;right:10px;color:var(--muted);font-size:1.1rem;line-height:1;
  padding:2px 6px;border-radius:6px;}
.bb-clear:hover{color:var(--red-2);background:rgba(223,24,0,.14);}

/* the attachment tabs that appear once a gun is in the box */
.bb-atts{display:flex;flex-direction:column;gap:6px;margin:-6px 0 0;}
.bb-att{display:flex;justify-content:space-between;gap:10px;align-items:baseline;
  background:var(--bg);border:1px solid var(--line);border-radius:9px;padding:7px 11px;
  font:inherit;font-size:.78rem;cursor:pointer;color:var(--text);text-align:left;}
.bb-att:hover{border-color:var(--red);}
.bb-att.on{border-color:rgba(57,217,138,.45);background:rgba(57,217,138,.08);}
.bb-att-k{color:var(--muted);font-size:.66rem;letter-spacing:.6px;text-transform:uppercase;}
.bb-att-v{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;}
.bb-att.on .bb-att-v{color:#7fe6b0;}

/* the bot itself */
.bb-mid{display:flex;flex-direction:column;align-items:center;gap:12px;}
.bb-art{position:relative;width:100%;aspect-ratio:4/3;max-height:300px;border-radius:26px;overflow:hidden;}
.bb-art img,.bb-art .thumb{width:100%;height:100%;object-fit:contain;display:block;
  -webkit-mask-image:radial-gradient(ellipse 78% 78% at 50% 50%, #000 52%, transparent 92%);
  mask-image:radial-gradient(ellipse 78% 78% at 50% 50%, #000 52%, transparent 92%);}
.bb-art .thumb--none{background:var(--panel-2);opacity:.4;}
.bb-art{border:0;padding:0;cursor:pointer;background:none;}
.bb-art{border:1px solid var(--line);border-radius:26px;transition:border-color .15s ease;}
.bb-art:hover{border-color:var(--red);}
/* a real button under the portrait. the picture is clickable too, but nobody discovers that on
   their own, so the visible control is the one that matters */
.bb-change{background:var(--bg-2);border:1px solid var(--line);border-radius:999px;
  color:var(--text);padding:9px 18px;font:inherit;font-size:.85rem;font-weight:600;
  cursor:pointer;display:flex;align-items:center;gap:8px;
  transition:background .15s ease,border-color .15s ease,color .15s ease;}
.bb-change:before{content:"↻";font-size:1.05rem;line-height:1;}
.bb-change:hover{background:rgba(223,24,0,.16);border-color:rgba(223,24,0,.5);color:#ff8a7e;}
.bb-name{font-family:"Gin",sans-serif;font-size:1.5rem;color:var(--white);display:flex;
  align-items:baseline;gap:10px;}
.bb-fam{font-size:.66rem;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;
  color:#ff8a7e;background:rgba(223,24,0,.16);border:1px solid rgba(223,24,0,.5);
  border-radius:999px;padding:2px 9px;font-family:inherit;}
.bb-page{font-size:.8rem;color:var(--red-2);}
.bb-warn{color:#ffc738;opacity:.85;}
.bb-typenote{margin:0;font-size:.76rem;color:var(--muted);text-align:center;max-width:340px;}
.bb-custom{width:min(240px,100%);text-align:center;}

/* the answers */
.bb-q{background:var(--bg);border:1px solid var(--line);border-radius:12px;padding:12px 14px;}
.bb-q-k{font-size:.66rem;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;
  color:var(--muted);margin-bottom:9px;display:flex;flex-direction:column;gap:2px;}
.bb-q-note{font-size:.66rem;font-weight:500;letter-spacing:0;text-transform:none;opacity:.75;}
.bb-q-a{display:flex;gap:6px;flex-wrap:wrap;}
.bb-opt{background:var(--bg-2);border:1px solid var(--line);border-radius:999px;color:var(--muted);
  padding:6px 13px;font:inherit;font-size:.8rem;cursor:pointer;}
.bb-opt:hover{color:var(--text);border-color:rgba(255,255,255,.2);}
.bb-opt.on{background:rgba(223,24,0,.16);border-color:rgba(223,24,0,.5);color:#ff8a7e;}
.bb-opt--off.on{background:var(--panel);border-color:var(--line);color:var(--muted);}
.bb-teams .bb-opt{min-width:38px;text-align:center;}
#bb-cmd{flex:1;min-width:0;font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.88rem;
  padding:12px 15px;background-color:var(--bg);}

/* the attachment boxes on the loadout side. same object as the bot builder's, laid out as a rail
   above the picture rather than a grid beside it. case #110 */
/* a fixed number of columns rather than auto-fit, so a gun with one slot gets a box the same
   size as a gun with five instead of one stretched across the whole rail. the empty columns
   just sit there. case #118 */
.fx-slots{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:10px;
  margin:16px 0 4px;justify-items:stretch;}
.fx-slots:empty{display:none;}
@media (max-width:1180px){ .fx-slots{grid-template-columns:repeat(4,minmax(0,1fr));} }
@media (max-width:900px){ .fx-slots{grid-template-columns:repeat(3,minmax(0,1fr));} }
@media (max-width:620px){ .fx-slots{grid-template-columns:repeat(2,minmax(0,1fr));} }
.fx-slotx{position:absolute;top:8px;right:8px;width:22px;height:22px;border-radius:50%;
  display:flex;align-items:center;justify-content:center;font-size:.9rem;line-height:1;
  background:rgba(0,0,0,.62);color:#fff;opacity:0;transition:opacity .15s ease;}
.bb-slot:hover .fx-slotx{opacity:1;}
.fx-slotx:hover{background:var(--red);}
@media (max-width:700px){
  .fx-slots{grid-template-columns:repeat(auto-fit,minmax(104px,1fr));gap:8px;}
}

/* skeletons. the shapes that are about to be there, so the panel has its size from the first
   paint and nothing jumps when the real thing arrives. case #120 */
.fx-skel{position:relative;overflow:hidden;background:var(--panel-2,rgba(255,255,255,.05));
  border:1px solid var(--line);border-radius:14px;}
.fx-skel:after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.07),transparent);
  animation:fx-sweep 1.25s infinite;}
@keyframes fx-sweep{to{transform:translateX(100%);}}
.fx-skel--card{aspect-ratio:4/3;}
.fx-skel--row{height:58px;margin-bottom:8px;border-radius:12px;}
.fx-skel--slot{aspect-ratio:1/1.35;border-style:dashed;}
.fx-skel--body{height:340px;}
@media (prefers-reduced-motion: reduce){ .fx-skel:after{animation:none;} }

/* the picker's pictures. the shimmer sits in the frame and the photo covers it once it has
   arrived, using the thumb-ready class wiki.js already puts on a loaded image. the animation
   stops at the same moment, so a modal of forty options is not running forty of them behind
   opaque pictures. case #122 */
.fx-opt-pic{position:relative;overflow:hidden;
  background:var(--panel-2,rgba(255,255,255,.05));}
.fx-opt-pic:after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.07),transparent);
  animation:fx-sweep 1.25s infinite;pointer-events:none;}
.fx-opt-pic:has(.thumb-ready):after,
.fx-opt-pic:has(.thumb--none):after{animation:none;opacity:0;}
.fx-opt-pic .thumb{opacity:0;transition:opacity .25s ease;}
.fx-opt-pic .thumb-ready,.fx-opt-pic .thumb--none{opacity:1;}
@media (prefers-reduced-motion: reduce){
  .fx-opt-pic:after{animation:none;}
  .fx-opt-pic .thumb{transition:none;}
}

/* three columns, because head, torso and limb only mean anything next to each other. case #126 */
.fx-hit{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px;padding:10px 0 4px;}
.fx-hitcol{display:flex;flex-direction:column;gap:2px;background:var(--bg);
  border:1px solid var(--line);border-radius:12px;padding:12px 14px;}
.fx-hit-k{font-size:.66rem;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;
  color:var(--muted);}
.fx-hit-n{font-family:"Gin",sans-serif;font-weight:400;font-size:1.5rem;line-height:1;
  color:var(--white);font-variant-numeric:tabular-nums;}
.fx-hit-s{font-size:.68rem;color:var(--muted);margin-bottom:6px;}
.fx-hit-r{font-size:.76rem;color:var(--muted);}
.fx-hit-r b{color:var(--red-2);font-weight:700;}
@media (max-width:560px){ .fx-hit{grid-template-columns:repeat(3,minmax(0,1fr));gap:6px;}
  .fx-hitcol{padding:10px;} .fx-hit-n{font-size:1.2rem;} }

/* through cover. a table because three parts against three situations is a grid, and reading it
   across is the whole point. case #128 */
.fx-cv-arm{display:flex;align-items:center;gap:6px;flex-wrap:wrap;padding:8px 0 12px;}
.fx-cv-arm>span{font-size:.7rem;font-weight:800;letter-spacing:1px;text-transform:uppercase;
  color:var(--muted);margin-right:4px;}
.fx-cv-b{cursor:pointer;background:var(--bg);border:1px solid var(--line);color:var(--muted);
  font-family:inherit;font-size:.76rem;font-weight:700;padding:5px 11px;border-radius:999px;}
.fx-cv-b:hover{border-color:var(--red);color:#fff;}
.fx-cv-b.on{background:rgba(223,24,0,.16);border-color:rgba(223,24,0,.5);color:#ff8a7e;}
.fx-cv{width:100%;border-collapse:collapse;font-size:.84rem;}
.fx-cv th,.fx-cv td{text-align:left;padding:7px 10px;border-top:1px solid var(--line);}
.fx-cv thead th{border-top:none;font-size:.66rem;font-weight:800;letter-spacing:1px;
  text-transform:uppercase;color:var(--muted);}
.fx-cv tbody th{color:var(--white);font-weight:700;width:64px;}
.fx-cv td b{color:var(--white);font-weight:700;font-variant-numeric:tabular-nums;}
.fx-cv td em{font-style:normal;color:var(--red-2);font-weight:700;margin-left:5px;}
.fx-cv-no{color:var(--muted);opacity:.7;}
.fx-cv-note{color:var(--muted);font-size:.76rem;line-height:1.55;margin:10px 0 0;}

/* melee can have four columns where a gun has three */
.fx-hit--melee{grid-template-columns:repeat(auto-fit,minmax(0,1fr));}

/* what a bot already carries. a list not boxes, because nobody sets these, they're just what
   is there already. case #130 */
.bb-kit{background:var(--bg);border:1px solid var(--line);border-radius:14px;
  padding:14px 16px;margin:0 0 14px;min-width:0;overflow:hidden;}
.bb-kit-h{font-size:.66rem;font-weight:800;letter-spacing:1.1px;text-transform:uppercase;
  color:var(--muted);margin-bottom:10px;}
.bb-kit-g{display:flex;align-items:center;gap:7px;flex-wrap:wrap;margin-bottom:12px;min-width:0;}
/* the label owns its own line. it used to hold a fixed column, so the moment the chips wrapped
   the second row started under the label and lined up with nothing. case #131 */
.bb-kit-k{font-size:.66rem;font-weight:800;letter-spacing:1px;text-transform:uppercase;
  color:var(--muted);flex:1 0 100%;margin-bottom:1px;}
.bb-kit-i{display:inline-flex;align-items:center;gap:6px;background:var(--panel);
  border:1px solid var(--line);border-radius:999px;padding:3px 11px 3px 3px;
  font-size:.8rem;color:var(--text);text-decoration:none;}
.bb-kit-i:hover{border-color:var(--red);color:#fff;text-decoration:none;}
.bb-kit-i--nopage{opacity:.62;border-style:dashed;cursor:help;}

/* the gun and what is bolted to it, drawn as one run so it reads as an assembled weapon rather
   than four things that happen to be listed together. the plus is the same one the command uses.
   case #132 */
/* max-width is the fix: an inline-flex with no width takes its content's size, so on a narrow
   column it grew past its parent instead of wrapping inside it. and once it does wrap it is two
   lines rather than a pill, so the 999px radius has to go or the corners cut the second row.
   case #139 */
.bb-rig{display:flex;align-items:center;flex-wrap:wrap;gap:4px 5px;max-width:100%;min-width:0;
  background:var(--bg-2);border:1px solid var(--line);border-radius:14px;padding:5px 10px;
  row-gap:5px;}
.bb-rig .bb-kit-i{max-width:100%;min-width:0;}
.bb-rig .bb-kit-t{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}
.bb-rig-plus{color:var(--muted);font-size:.78rem;font-weight:700;padding:0 1px;opacity:.75;}
/* the gun leads, so it keeps the weight. the attachments sit back a step */
.bb-kit-i--gun{background:var(--panel-2);border-color:rgba(255,255,255,.16);font-weight:600;}
.bb-kit-i--att{background:none;border-color:transparent;padding-left:2px;font-size:.76rem;
  color:var(--muted);}
.bb-kit-i--att .bb-kit-pic{width:19px;height:19px;flex:0 0 19px;}
.bb-kit-i--att:hover{color:#fff;border-color:transparent;}
.bb-kit-pic{width:24px;height:24px;border-radius:50%;overflow:hidden;flex:0 0 24px;
  background:var(--panel-2);}
.bb-kit-pic .thumb{width:100%;height:100%;object-fit:cover;}
.bb-kit-none{display:block;width:100%;height:100%;}
.bb-kit-n{color:var(--muted);font-size:.74rem;line-height:1.55;margin:10px 0 0;}

/* ---- gun builder ------------------------------------------------------------------------- */
/* wiki's own infobox inside .fx-statwrap, same pair as the loadout builder, so all that's left
   here is turning a value into something typeable. nothing restyles a row. i tried that once
   under a ge- prefix that was already the gallery builder's and every row came out in a box.
   case #136 */
.ge-pick{display:flex;align-items:center;gap:22px;padding:18px 20px;margin:0 0 20px;flex-wrap:wrap;}
.ge-art{display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;
  column-gap:16px;align-items:center;cursor:pointer;background:none;border:none;padding:0;
  text-align:left;font-family:inherit;}
.ge-art-pic{grid-row:1 / span 2;width:150px;height:150px;border-radius:16px;overflow:hidden;
  background:var(--panel-2);border:1px solid var(--line);display:flex;align-items:center;
  justify-content:center;transition:border-color .18s ease;}
.ge-art:hover .ge-art-pic{border-color:var(--red);}
.ge-art-pic .thumb{width:100%;height:100%;object-fit:cover;}
.ge-plus{font-size:2rem;color:var(--muted);}
.ge-art-k{align-self:end;font-size:.66rem;font-weight:800;letter-spacing:1.2px;
  text-transform:uppercase;color:var(--muted);}
.ge-art-v{align-self:start;font-family:"Gin",sans-serif;font-weight:400;font-size:1.9rem;
  line-height:1.1;color:var(--white);}
.ge-art-swap{grid-column:2;font-size:.74rem;color:var(--red-2);}
.ge-pick-say{flex:1 1 260px;}
.ge-pick-say b{color:var(--white);}

.ge-fields{column-count:3;column-gap:16px;}
@media (max-width:1200px){ .ge-fields{column-count:2;} }
@media (max-width:760px){ .ge-fields{column-count:1;} }
/* two sheets side by side rather than flowing, so the short one sits beside the long one instead
   of being stranded under it. the numbers get the wider half. case #137 */
.ge-fields--pair{column-count:auto;display:grid;grid-template-columns:minmax(0,3fr) minmax(0,2fr);
  gap:16px;align-items:start;}
@media (max-width:880px){ .ge-fields--pair{grid-template-columns:minmax(0,1fr);} }
.ge-card{break-inside:avoid;margin:0 0 16px;display:inline-block;width:100%;}

/* the small round one beside a label. the wiki page's own description is behind it */
.ge-help{width:15px;height:15px;flex:0 0 15px;margin-left:6px;border-radius:50%;
  background:none;border:1px solid var(--line);color:var(--muted);cursor:pointer;
  font-family:inherit;font-size:.62rem;font-weight:800;line-height:1;padding:0;
  vertical-align:middle;}
.ge-help:hover{border-color:var(--red);color:#fff;}
.ge-helpbox{padding:4px 2px;}
.ge-helpbox code{display:inline-block;background:var(--bg);border:1px solid var(--line);
  border-radius:8px;padding:6px 11px;margin-bottom:12px;
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.84rem;color:var(--red-2);}
.ge-helpbox p{color:var(--text);font-size:.95rem;line-height:1.65;margin:0 0 10px;}
.ge-helpbox .ge-help-n{color:var(--muted);font-size:.86rem;}
.ge-helpbox b{color:var(--white);}

/* reads as a stat until someone goes near it */
.ge-row .v{display:flex;align-items:center;justify-content:flex-end;gap:5px;min-width:0;}
.ge-in{width:72px;box-sizing:border-box;background:none;border:1px solid transparent;
  border-radius:8px;padding:2px 7px;text-align:right;
  font-family:inherit;font-size:.95rem;font-weight:700;color:var(--white);
  transition:background .15s ease,border-color .15s ease;}
.ge-in--wide{width:132px;font-weight:600;font-size:.86rem;}
.ge-in::placeholder{color:var(--white);opacity:.45;font-weight:700;}
.ge-in:hover{background:var(--bg);border-color:var(--line);}
.ge-in:focus{outline:none;background:var(--bg);border-color:var(--red-2);
  box-shadow:0 0 0 3px rgba(223,24,0,.16);}
/* a changed value goes red, so ten of them stand out among sixty rows */
.ge-row.is-set .ge-in,.ge-row.is-set .k{color:#ff8a7e;}

.ge-seg{display:flex;gap:3px;flex-wrap:wrap;justify-content:flex-end;}
.ge-segb,.ge-anim,.ge-x{cursor:pointer;background:var(--bg);border:1px solid var(--line);
  color:var(--muted);font-family:inherit;font-size:.72rem;font-weight:700;padding:3px 8px;
  border-radius:7px;}
.ge-segb:hover,.ge-anim:hover,.ge-x:hover{border-color:var(--red);color:#fff;}
.ge-segb.on,.ge-anim.on{background:rgba(223,24,0,.16);border-color:rgba(223,24,0,.5);color:#ff8a7e;}
.ge-segb--off.on{background:var(--panel);border-color:var(--line);color:var(--muted);}
.ge-x{padding:3px 7px;}
/* the animation list, in the picker rather than a browser dropdown */
.ge-anims{display:grid;grid-template-columns:repeat(auto-fill,minmax(132px,1fr));gap:7px;}
.ge-anim-o{cursor:pointer;background:var(--bg);border:1px solid var(--line);color:var(--text);
  font-family:inherit;font-size:.84rem;padding:9px 11px;border-radius:10px;text-align:left;}
.ge-anim-o:hover{border-color:var(--red);color:#fff;}

/* the commands sit above the sheets and stick, because they are the thing being made */
.ge-out{position:sticky;top:12px;z-index:5;background:var(--bg-2);border:1px solid var(--line-red);
  border-radius:16px;padding:14px 16px;margin:0 0 20px;}
.ge-out-h{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:12px;}
.ge-out-h b{color:var(--white);font-size:.9rem;}
.ge-out-h span{color:var(--muted);font-size:.82rem;}
.ge-out-h .spacer{flex:1;}
.ge-msg{display:flex;align-items:center;gap:10px;padding:8px 0;border-top:1px solid var(--line);}
.ge-msg:first-of-type{border-top:none;}
.ge-msg-n{flex:0 0 20px;color:var(--muted);font-size:.76rem;font-weight:700;}
.ge-msg-t{flex:1;min-width:0;overflow-x:auto;white-space:nowrap;background:var(--bg);
  border:1px solid var(--line);border-radius:9px;padding:7px 11px;
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.8rem;color:var(--text);}
.ge-msg-c{flex:0 0 auto;color:var(--muted);font-size:.72rem;font-variant-numeric:tabular-nums;}
.ge-msg-b{flex:0 0 auto;}
.ge-out-n{color:var(--muted);font-size:.78rem;line-height:1.55;margin:10px 0 0;}

/* ---- comparison ---------------------------------------------------------------------------- */
/* cp-, checked against every prefix in use first. gb- was the gallery builder's and putting the
   gun builder under it cost a rebuild. case #136 */
/* one item to a column, or a whole loadout to a column */
.cp-mode{display:flex;gap:8px;margin:0 0 14px;flex-wrap:wrap;}
/* a loadout's column is its command, with what the command resolved to underneath it */
.cp-lo{gap:8px;}
.cp-lo-in{width:100%;background-color:var(--bg);
  font-family:ui-monospace,Menlo,Consolas,monospace;font-size:.78rem;padding:8px 10px;}
.cp-lo-items{display:flex;flex-wrap:wrap;gap:4px;}
.cp-lo-items i{color:var(--muted);font-size:.76rem;font-style:italic;}
.cp-lo-chip{background:var(--bg);border:1px solid var(--line);border-radius:999px;
  padding:2px 8px;font-size:.68rem;color:var(--muted);max-width:100%;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;}
.cp-bar{display:flex;align-items:center;gap:10px;margin:0 0 14px;flex-wrap:wrap;}
.cp-bar[hidden]{display:none;}
.cp-bar .spacer{flex:1;}
.cp-count{color:var(--muted);font-size:.8rem;font-variant-numeric:tabular-nums;}

.cp-empty{padding:46px 30px;text-align:center;}
.cp-empty h2{margin:0 0 8px;font-size:1.5rem;color:var(--white);}
.cp-empty p{margin:0 auto 20px;color:var(--muted);max-width:540px;line-height:1.6;}

/* the table is wider than a phone, so it scrolls sideways in its own box and the row labels are
   held on the left while it does */
.cp-scroll{overflow-x:auto;overscroll-behavior-x:contain;}
/* widths live here, not in js. an inline min-width was quietly overruling the phone rules
   below, so a phone got one column of a four column table. brilliant. case #181 */
.cp{--cp-label:196px;--cp-col:174px;
  width:100%;table-layout:fixed;border-collapse:separate;border-spacing:0;font-size:.88rem;
  min-width:calc(var(--cp-label) + var(--cp-col) * var(--cp-n,1));}
.cp th,.cp td{text-align:left;vertical-align:top;}
.cp-k,.cp-corner{position:sticky;left:0;background:var(--bg-2);
  width:var(--cp-label);min-width:var(--cp-label);}
.cp-corner{z-index:2;}
.cp-k{z-index:1;padding:11px 15px;color:var(--muted);font-weight:600;
  border-top:1px solid var(--line);}
.cp-col{min-width:var(--cp-col);padding:16px 14px 14px;border-left:1px solid var(--line);}

.cp-card{position:relative;display:flex;flex-direction:column;align-items:flex-start;gap:6px;}
.cp-cardpic{width:100%;height:94px;border-radius:12px;overflow:hidden;background:#0b0a12;
  border:1px solid var(--line);cursor:pointer;padding:0;display:flex;align-items:center;
  justify-content:center;transition:border-color .15s ease;}
.cp-cardpic:hover{border-color:var(--red);}
.cp-cardpic img,.cp-cardpic .thumb{width:100%;height:100%;object-fit:contain;display:block;}
.cp-cardpic .thumb--none{background:var(--panel-2);}
.cp-cardn{font-weight:700;font-size:.95rem;line-height:1.25;color:var(--white);text-decoration:none;}
.cp-cardk{font-size:.62rem;font-weight:800;letter-spacing:.9px;text-transform:uppercase;
  color:var(--muted);}
/* quiet until someone goes near the column, same as the inventory delete */
.cp-cardx{position:absolute;top:6px;right:6px;z-index:2;width:22px;height:22px;border-radius:50%;
  background:rgba(0,0,0,.62);border:0;color:#fff;cursor:pointer;font-size:.95rem;line-height:1;
  padding:0;opacity:0;transition:opacity .15s ease,background .15s ease;}
.cp-col:hover .cp-cardx,.cp-cardx:focus-visible{opacity:1;}
.cp-cardx:hover{background:var(--red);}
.cp-plus{font-size:1.6rem;color:var(--muted);line-height:1;}
.cp-addcol{width:100%;min-height:94px;border:1px dashed var(--line);border-radius:12px;
  background:var(--bg);color:var(--muted);cursor:pointer;font-family:inherit;font-size:.82rem;
  font-weight:600;display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:2px;transition:border-color .15s ease,color .15s ease;}
.cp-addcol:hover{border-color:var(--red);color:#fff;}

/* same title as a stat sheet's group, because that is what these are. the band drops back to the
   page colour so it reads as a divider, and the name inside is held on the left while the table
   scrolls sideways */
.cp-grow th{padding:0;background:var(--bg);border-top:1px solid var(--line);}
.cp-grow span{position:sticky;left:0;display:block;padding:16px 15px 6px;
  font-size:.68rem;letter-spacing:1.4px;text-transform:uppercase;
  color:var(--red-2);font-weight:800;width:max-content;}
/* deliberately not held on the left: it is wider than a phone, and pinning it would put half of
   it past the edge with no way to reach it. scroll back to the labels and it is there */
.cp-ctlrow td{padding:8px 15px 12px;}
.cp-ctl-n{color:var(--muted);font-size:.76rem;line-height:1.55;margin:9px 0 0;max-width:820px;}
.cp-ctl-k{font-size:.62rem;font-weight:800;letter-spacing:1px;text-transform:uppercase;
  color:var(--muted);margin-right:7px;}
.cp-ctl-k + .fx-cv-b{margin-left:0;}
.cp-ctlrow .fx-cv-b{margin-right:4px;}
.cp-ctlrow .cp-ctl-k:not(:first-child){margin-left:16px;}

.cp-v{padding:10px 14px;border-top:1px solid var(--line);border-left:1px solid var(--line);}
/* the number on the left, how far off the best it is on the right, so the margins line up down
   the column and can be read on their own */
.cp-top{display:flex;align-items:baseline;justify-content:space-between;gap:8px;min-width:0;}
.cp-gap{flex:0 0 auto;font-size:.7rem;font-weight:700;font-variant-numeric:tabular-nums;
  color:var(--muted);}
.cp-v.is-up .cp-gap{color:#7fe6b0;}
.cp-v.is-down .cp-gap{color:#ff8a7e;}
.cp-n{display:block;min-width:0;font-variant-numeric:tabular-nums;font-weight:700;
  color:var(--white);font-size:.98rem;}
/* a dot on the rows the score is worked out from, so which ones those are is not a guess */
.cp-k.is-scored:after{content:"";display:inline-block;width:4px;height:4px;border-radius:50%;
  background:var(--red-2);opacity:.6;margin-left:6px;vertical-align:middle;}
.cp-n i{font-style:normal;font-weight:500;font-size:.72rem;color:var(--muted);margin-left:4px;}
.cp-n--soft{font-weight:600;font-size:.82rem;color:var(--muted);line-height:1.45;}
.cp-sub{display:block;font-size:.72rem;color:var(--muted);margin-top:1px;}
/* length is how good the number is, not how big it is: half these rows are better the lower they
   go, so a bar drawn from the value would put the longest one on the worst gun */
.cp-meter{display:block;height:3px;border-radius:999px;background:rgba(255,255,255,.07);
  margin-top:8px;overflow:hidden;}
.cp-meter i{display:block;height:100%;background:rgba(255,255,255,.26);border-radius:999px;}
.cp-r:hover .cp-k,.cp-r:hover .cp-v:not(.is-up):not(.is-down){background:var(--panel);}
/* the shared value is left alone. only what is above or below it is marked. case #169 */
.cp-v.is-up{background:rgba(57,217,138,.09);}
.cp-v.is-up .cp-n{color:#7fe6b0;}
.cp-v.is-up .cp-meter i{background:#39d98a;}
.cp-v.is-down{background:rgba(255,138,126,.07);}
.cp-v.is-down .cp-n{color:#ff8a7e;}
.cp-v.is-down .cp-meter i{background:#ff8a7e;}
.cp-nodiff{padding:28px 14px;color:var(--muted);text-align:center;}
.cp-legend{color:var(--muted);font-size:.78rem;line-height:1.6;margin:12px 2px 0;max-width:780px;}
.cp-legend[hidden]{display:none;}
/* the verdict is the thing worth reading here, so it leads and the rest is the small print */
.cp-legend b{display:block;color:var(--text);font-size:.92rem;font-weight:600;margin-bottom:6px;}
/* two columns on screen at once or the whole table is pointless */
@media (max-width:640px){
  .cp{--cp-label:100px;--cp-col:110px;}
  .cp-k{padding:10px 9px;font-size:.78rem;}
  .cp-v{padding:9px;}
  .cp-col{padding:13px 9px 11px;}
  .cp-n{font-size:.92rem;}
  .cp-gap{font-size:.66rem;}
  .cp-cardpic{height:76px;}
  .cp-cardn{font-size:.86rem;}
  /* snap to a column. the margin is the sticky labels, which otherwise sit on top of it */
  .cp-scroll{scroll-snap-type:x proximity;}
  .cp-col{scroll-snap-align:start;scroll-margin-left:var(--cp-label);}
}

/* The pictures in the media library are megabytes each, so on a grid of a hundred cards the
   browser is still fetching long after the layout has settled and the space just sits empty.
   The same shimmer the picker uses, so an empty frame reads as one that has not arrived rather
   than one with nothing in it. Stops the moment the picture lands. case #145 */
.fx-bthumb{position:relative;overflow:hidden;background:var(--panel-2,rgba(255,255,255,.05));}
.fx-bthumb:after{content:"";position:absolute;inset:0;transform:translateX(-100%);
  background:linear-gradient(90deg,transparent,rgba(255,255,255,.06),transparent);
  animation:fx-sweep 1.25s infinite;pointer-events:none;z-index:0;}
.fx-bthumb:has(.thumb-ready):after,.fx-bthumb:has(.thumb--none):after{animation:none;opacity:0;}
.fx-bthumb .thumb{opacity:0;transition:opacity .3s ease;}
.fx-bthumb .thumb-ready,.fx-bthumb .thumb--none{opacity:1;}
/* z-index only. these are already positioned, and setting position again here put them back in
   the flow, so the name rendered inline across the top of the card instead of along the bottom
   and a two word name wrapped out of the card entirely. case #162 */
.fx-bthumb .fx-bsub,.fx-bthumb .fx-bname{z-index:1;}
@media (prefers-reduced-motion: reduce){
  .fx-bthumb:after{animation:none;} .fx-bthumb .thumb{transition:none;}
}
