diff --git a/docs/DESIGN_SYSTEM.md b/docs/DESIGN_SYSTEM.md index ff8dc01..296cd51 100644 --- a/docs/DESIGN_SYSTEM.md +++ b/docs/DESIGN_SYSTEM.md @@ -1371,3 +1371,24 @@ a dedicated column to the right of the graphic. Clamp display values to `0–100`, use orange only for the filled measure, and keep the unfilled track neutral. Stack meter labels and tracks on narrow cards rather than shrinking them below a reliably readable width. + +Talent registry cards treat the two tier descriptions as their primary +content; never replace them with configured/missing summary facts. Render Tier +I and Tier II as distinct structured data blocks, then place optional cooldown +metadata below both descriptions. Do not use the serif, quote-like prose +treatment for tier effects. Use compact fixed tier labels, sans-serif effect +text, and engineered borders. Tier I is the neutral baseline; Tier II uses the +orange rail, label, and subtly elevated surface to communicate that it is the +improved version. Duration and stack limits may remain compact badges. The +top-right header status uses the applicable Backpack or Body Armor icon for +gear talents and the SMG icon as the generic Weapon Talent symbol. Weapon +Talent headers pair that icon with an explicit `1 · TOP` or `2 · BOTTOM` +status badge; never rely on the slot number alone. + +When a public registry needs only one small bounded filter vocabulary, use the +compact facet-panel form: one full-width group with all options visible in a +single row on wide screens. Talent slot filtering uses Backpack, Body Armor, +Weapon 1 · Top, and Weapon 2 · Bottom. Always include the Top/Bottom context +when presenting numbered Weapon Talent slots to users. The filter remains +additive within the group and wraps to two columns on narrow screens; do not +introduce search or dropdown controls for this four-option set. diff --git a/src/app.css b/src/app.css index 2adf185..9c4a944 100644 --- a/src/app.css +++ b/src/app.css @@ -201,15 +201,18 @@ .database-category-page{padding-top:34px}.database-category-command{display:flex;justify-content:space-between;align-items:end;gap:28px;padding:22px;border:1px solid var(--shd-border);border-top:2px solid var(--shd-orange);background:linear-gradient(115deg,#15191a,#0d1011)}.database-category-command h1{margin:8px 0 7px;font-size:clamp(30px,4vw,52px);line-height:.95}.database-category-command>div:first-child>p:last-child{max-width:720px;margin:0;color:#8d9597;font:12px/1.55 Georgia,serif}.database-category-command>div:last-child{min-width:150px;display:grid;justify-items:end;gap:3px}.database-category-command>div:last-child strong{color:var(--shd-orange);font-size:32px;line-height:1}.database-category-command>div:last-child span{color:#687073;font-size:6px;letter-spacing:1px}.database-category-command>div:last-child a{margin-top:8px;color:var(--shd-orange);font-size:7px;font-weight:900;letter-spacing:.8px} .database-category-nav{display:grid;grid-template-columns:repeat(8,minmax(0,1fr));margin:10px 0;border:1px solid var(--shd-border);background:#0d1011}.database-category-nav>a{min-height:55px;display:grid;grid-template-columns:auto 1fr auto;align-items:center;gap:7px;padding:9px;border-left:1px solid var(--shd-border);color:#8e9698}.database-category-nav>a:first-child{border-left:0}.database-category-nav>a small{color:#525a5c;font-size:5px;letter-spacing:.6px}.database-category-nav>a span{font-size:7px;font-weight:900;letter-spacing:.35px}.database-category-nav>a b{color:#4f5759}.database-category-nav>a:hover,.database-category-nav>a:focus-visible{background:#171b1c;color:var(--shd-text)}.database-category-nav>a.active{box-shadow:inset 0 2px var(--shd-orange);background:#191814;color:var(--shd-orange)}.database-category-nav>a:active{filter:brightness(.85)} .database-facet-panel{margin:10px 0;border:1px solid var(--shd-border);border-left:2px solid var(--shd-orange);background:#0d1011}.database-facet-panel>header{height:auto;min-height:43px;display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 11px;border-bottom:1px solid var(--shd-border);background:#15191a}.database-facet-panel>header>div{display:grid;gap:3px}.database-facet-panel>header small{color:var(--shd-orange);font-size:6px;font-weight:900;letter-spacing:.9px}.database-facet-panel>header strong{color:#727a7c;font-size:5px;letter-spacing:.7px}.database-facet-panel>header button{min-height:30px;padding:0 10px;border:1px solid #5d4324;background:#1c160d;color:var(--shd-orange);font-size:6px;font-weight:900;letter-spacing:.7px;cursor:pointer}.database-facet-panel>header button:hover,.database-facet-panel>header button:focus-visible{border-color:var(--shd-orange);background:#261c0d}.database-facet-panel>header button:active{transform:translateY(1px);filter:brightness(.8)}.database-facet-groups{display:grid;grid-template-columns:1.2fr 1fr 1fr;gap:8px;padding:9px}.database-facet-group{min-width:0;margin:0;padding:7px;border:1px solid var(--shd-border);background:#111415}.database-facet-group legend{display:flex;align-items:center;gap:7px;padding:0 4px;color:#a7adaf;font-size:6px;font-weight:900;letter-spacing:.7px}.database-facet-group legend span{color:var(--shd-orange);font-size:5px}.database-facet-group>div{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:4px}.database-facet-group>div>button{min-width:0;min-height:46px;display:flex;align-items:center;justify-content:center;gap:5px;padding:5px;border:1px solid #353b3c;background:#0d1011;color:#7f8789;cursor:pointer}.database-facet-group>div>button :is(.game-icon,img){width:28px;height:28px;flex:0 0 28px;object-fit:contain}.database-facet-group>div>button span{overflow:hidden;font-size:6px;font-weight:900;letter-spacing:.3px;text-overflow:ellipsis;white-space:nowrap}.database-facet-group>div>button:hover,.database-facet-group>div>button:focus-visible{border-color:#6a4c26;background:#18150f;color:#d0d3d1}.database-facet-group>div>button.selected{border-color:var(--shd-orange);box-shadow:inset 0 2px var(--shd-orange);background:#21190e;color:var(--shd-orange)}.database-facet-group>div>button:active{transform:translateY(1px);filter:brightness(.82)}.database-facet-group.searchable>div{max-height:150px;display:grid;grid-template-columns:1fr;overflow:auto}.database-facet-group.searchable>div>button{min-height:36px;justify-content:flex-start}.database-facet-group.searchable>div>button :is(img,.game-icon){width:25px;height:25px;flex-basis:25px}.database-facet-search{display:block;margin-bottom:5px}.database-facet-search input{width:100%;height:32px;margin:0;padding:0 8px;border:1px solid #3b4243;background:#0a0d0e;color:var(--shd-text);font-size:7px}.database-facet-search input:focus{border-color:var(--shd-orange);outline:1px solid color-mix(in srgb,var(--shd-orange) 45%,transparent);outline-offset:1px} +.database-facet-groups.compact{grid-template-columns:1fr}.database-facet-groups.compact .database-facet-group>div{grid-template-columns:repeat(4,minmax(0,1fr))} .database-category-page>.registry-pagination{margin:10px 0}.database-item-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:9px}.database-item-card{min-width:0;display:flex;flex-direction:column;border:1px solid var(--shd-border);border-top:2px solid #404748;background:#111415}.database-item-card>header{height:auto;min-height:78px;display:grid;grid-template-columns:58px minmax(0,1fr);align-items:center;gap:12px;padding:11px 13px;border-bottom:1px solid var(--shd-border)}.database-item-icon{width:58px;height:58px;display:grid;place-items:center;border:1px solid #343a3b;background:#0c0f10}.database-item-icon :is(img,.game-icon){width:52px;height:52px;object-fit:contain}.database-item-card>header small{display:block;margin-bottom:5px;color:#697174;font-size:6px;font-weight:900;letter-spacing:.8px;text-transform:uppercase}.database-item-card h2{overflow-wrap:anywhere;margin:0;font-size:14px;line-height:1.1}.database-item-badges{display:flex;flex-wrap:wrap;gap:5px;padding:8px 12px 0}.database-item-badges span{padding:5px 7px;border:1px solid #424849;background:#171b1c;color:#a5acae;font-size:6px;font-weight:900;letter-spacing:.6px;text-transform:uppercase}.database-item-badges .exotic{border-color:#74552a;background:#1a160d;color:var(--quality-high-end)}.database-item-badges :is(.standard,.specialized,.superior,.highend){border-left-width:2px}.database-item-badges .standard{border-left-color:var(--quality-standard)}.database-item-badges .specialized{border-left-color:var(--quality-specialized)}.database-item-badges .superior{border-left-color:var(--quality-superior)}.database-item-badges .highend{border-left-color:var(--quality-high-end)}.database-item-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(90px,1fr));margin:9px 12px 0;border:1px solid var(--shd-border)}.database-item-facts>div{min-width:0;display:grid;align-content:center;gap:4px;min-height:53px;padding:7px;border-left:1px solid var(--shd-border)}.database-item-facts>div:first-child{border-left:0}.database-item-facts span,.database-item-lines span{color:#626a6c;font-size:5px;font-weight:900;letter-spacing:.65px}.database-item-facts b{overflow-wrap:anywhere;color:#d2d6d3;font-size:8px;line-height:1.35}.database-item-lines{display:grid;gap:1px;margin:7px 12px 0;border-top:1px solid var(--shd-border)}.database-item-lines>div{display:grid;grid-template-columns:110px 1fr;gap:9px;padding:8px 0;border-bottom:1px solid var(--shd-border)}.database-item-lines b{overflow-wrap:anywhere;font-size:7px;line-height:1.4}.database-item-card>p{margin:9px 12px 0;padding:9px;border-left:2px solid var(--shd-orange);background:#0d1011;color:#a2a8aa;font:10px/1.55 Georgia,serif}.database-item-card>p.secondary-description{margin-top:5px;border-left-color:#5c6466}.database-item-card>:last-child{margin-bottom:12px}.database-empty{grid-column:1/-1;display:grid;justify-items:center;gap:9px;padding:70px 24px;border:1px solid var(--shd-border);background:#101314;text-align:center}.database-empty>span{color:var(--shd-orange);font-size:30px}.database-empty strong{font-size:10px;letter-spacing:1px}.database-empty p{margin:0;color:#7e8688;font:11px/1.5 Georgia,serif} .database-item-facts.stacked{grid-template-columns:1fr}.database-item-facts.stacked>div{grid-template-columns:82px minmax(0,1fr);align-items:center;min-height:43px;border-left:0;border-top:1px solid var(--shd-border)}.database-item-facts.stacked>div:first-child{border-top:0}.database-item-facts.stacked b{color:var(--shd-orange)} .database-item-facts.stacked>div.primary{min-height:66px;grid-template-columns:minmax(130px,.7fr) minmax(0,1fr);border-left:3px solid var(--shd-orange);background:linear-gradient(90deg,#21190e,#101314)}.database-item-facts.stacked>div.primary span{padding-left:5px;color:#c89138;font-size:6px}.database-item-facts.stacked>div.primary b{font-size:20px;letter-spacing:.7px} +.database-item-facts:empty{display:none}.database-item-lines.after-description{margin-top:6px}.database-item-lines.after-description>div{padding:7px 2px}.database-item-lines.after-description b{color:#9da4a6} +.database-item-card>p.data-description{position:relative;margin-top:6px;padding:10px 11px 10px 58px;border:1px solid var(--shd-border);border-left:2px solid #4b5355;background:#0e1112;color:#9ca3a5;font:8px/1.55 Arial,sans-serif}.database-item-card>p.data-description::before{position:absolute;top:10px;left:10px;color:#858d8f;font:700 6px/1 Arial,sans-serif;letter-spacing:.7px}.database-item-card>p.data-description:first-of-type::before{content:"TIER I"}.database-item-card>p.data-description.secondary-description{margin-top:4px;border-color:#57462c;border-left-color:var(--shd-orange);background:#12130f;color:#bcc1bf}.database-item-card>p.data-description.secondary-description::before{content:"TIER II";color:var(--shd-orange)} .database-item-card>header{position:relative}.database-item-identity{min-width:0;padding-right:52px}.database-item-identity>small{margin:0}.database-header-status{position:absolute;top:10px;right:12px;display:flex;align-items:center;gap:6px}.database-header-status>.game-icon{width:19px;height:19px;object-fit:contain}.database-header-badge{flex:none;padding:3px 5px;border:1px solid #765426;background:#21180d;color:var(--shd-orange);font-size:6px;font-weight:900;letter-spacing:.7px}.database-fact-value{min-width:0;display:flex;align-items:center;gap:8px}.database-fact-value .game-icon{flex:none;width:27px;height:27px;object-fit:contain}.database-fact-value small{color:#707779;font-size:5px;font-weight:900;letter-spacing:.7px}.database-item-facts.stacked>div.primary>span{font-size:8px;letter-spacing:.9px}.database-item-facts.stacked>div.primary .database-fact-value small{align-self:flex-end;margin-bottom:3px;color:#777d7e}.database-stat-meters{grid-column:2;min-width:0;display:grid;gap:7px}.database-stat-meters>div{display:grid;grid-template-columns:58px minmax(0,1fr) 25px;align-items:center;gap:8px}.database-stat-meters i{color:#737b7d;font-style:normal;font-size:5px;font-weight:900;letter-spacing:.6px}.database-stat-meters output{color:#c7ccca;font-size:7px;font-weight:900;text-align:right}.database-stat-meters progress{display:block;width:100%;min-width:40px;height:7px;border:0;background:#252a2b;accent-color:var(--shd-orange)}.database-stat-meters progress::-webkit-progress-bar{background:#252a2b}.database-stat-meters progress::-webkit-progress-value{background:linear-gradient(90deg,#86531b,var(--shd-orange))}.database-stat-meters progress::-moz-progress-bar{background:linear-gradient(90deg,#86531b,var(--shd-orange))} .database-item-actions{display:flex;flex-wrap:wrap;gap:6px;margin:10px 12px 12px;padding-top:9px;border-top:1px solid var(--shd-border)}.database-item-actions>a{min-height:34px;display:inline-flex;align-items:center;justify-content:center;padding:0 11px;border:1px solid #74552a;background:#1b150c;color:var(--shd-orange);font-size:6px;font-weight:900;letter-spacing:.65px}.database-item-actions>a:hover,.database-item-actions>a:focus-visible{border-color:var(--shd-orange);background:#261b0b;color:#ffd19b}.database-item-actions>a:active{transform:translateY(1px);filter:brightness(.82)} .database-facet-group>div>button i{width:6px;height:6px;border:1px solid #596164;background:#171b1c;transform:rotate(45deg)}.database-facet-group>div>button.selected i{border-color:var(--shd-orange);background:var(--shd-orange);box-shadow:0 0 6px color-mix(in srgb,var(--shd-orange) 65%,transparent)} .database-facet-group.searchable>div{max-height:220px}.database-facet-group.searchable>div>button:has(span small){min-height:58px;align-items:flex-start}.database-facet-group.searchable>div>button>span{display:grid;gap:3px;white-space:normal;text-align:left}.database-facet-group.searchable>div>button>span>small{display:-webkit-box;overflow:hidden;color:#747c7e;font:8px/1.35 Georgia,serif;-webkit-box-orient:vertical;-webkit-line-clamp:2}.database-facet-group.searchable>div>button>span>small>b{margin-right:5px;color:var(--shd-orange);font:5px/1 monospace;letter-spacing:.5px} .database-category-page{overflow-x:clip}.database-category-command{width:100%;height:auto;min-height:132px}.database-category-command>*{min-width:0}.database-category-command h1{overflow-wrap:anywhere}.database-category-nav{min-width:0}.database-category-nav>a{min-width:0;grid-template-columns:auto minmax(0,1fr) auto}.community-index-hero{height:auto} .database-item-icon-groups{display:grid;gap:8px;margin:8px 12px 0}.database-item-icon-groups>div{display:grid;grid-template-columns:110px minmax(0,1fr);align-items:center;gap:9px;padding-top:8px;border-top:1px solid var(--shd-border)}.database-item-icon-groups>div>span{color:#626a6c;font-size:5px;font-weight:900;letter-spacing:.65px}.item-icon-rail{min-width:0;display:flex;flex-wrap:wrap;gap:5px}.item-icon-rail>button{width:34px;height:34px;display:grid;place-items:center;padding:0;border:1px solid #394041;background:#0d1011;cursor:pointer}.item-icon-rail>button:hover,.item-icon-rail>button:focus-visible{border-color:var(--shd-orange);background:#211a0e}.item-icon-rail>button:active{transform:translateY(1px);filter:brightness(.82)}.item-icon-rail img{width:30px;height:30px;object-fit:contain}.item-icon-rail small{color:#687073;font-size:6px;font-weight:900;letter-spacing:.55px}.database-preview-backdrop{position:fixed;z-index:1200;inset:0;display:grid;place-items:center;padding:20px;background:rgba(3,5,5,.82);backdrop-filter:blur(3px)}.database-preview-dialog{width:min(520px,100%);max-height:calc(100vh - 40px);overflow:auto;border:1px solid #4b5254;border-top:2px solid var(--shd-orange);background:#0b0e0f;box-shadow:0 18px 60px #000}.database-preview-dialog>header{height:auto;display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid var(--shd-border);background:#15191a}.database-preview-dialog>header>div{display:grid;gap:3px}.database-preview-dialog>header small{color:#697174;font-size:5px;letter-spacing:.8px}.database-preview-dialog>header strong{font-size:10px;letter-spacing:.45px}.database-preview-dialog>header button{width:32px;height:32px;padding:0;border:1px solid #434a4c;background:#101314;color:#aab0b2;font-size:20px;line-height:1;cursor:pointer}.database-preview-dialog>header button:hover,.database-preview-dialog>header button:focus-visible{border-color:var(--shd-orange);color:var(--shd-orange)}.database-preview-dialog>.database-item-card{margin:10px;border-top-color:#404748} -@media(max-width:1200px){.database-category-nav{grid-template-columns:repeat(4,1fr)}.database-category-nav>a:nth-child(5){border-left:0}.database-category-nav>a:nth-child(n+5){border-top:1px solid var(--shd-border)}.database-facet-groups{grid-template-columns:1fr 1fr}.database-facet-group:first-child{grid-column:1/-1}.database-item-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:700px){.database-category-command{align-items:stretch;flex-direction:column}.database-category-command>div:last-child{justify-items:start}.database-category-nav{grid-template-columns:repeat(2,1fr)}.database-category-nav>a:nth-child(odd){border-left:0}.database-category-nav>a:nth-child(n+3){border-top:1px solid var(--shd-border)}.database-facet-panel>header{align-items:flex-start;flex-direction:column}.database-facet-groups{grid-template-columns:1fr}.database-facet-group:first-child{grid-column:auto}.database-facet-group>div{grid-template-columns:repeat(2,minmax(0,1fr))}.database-item-grid{grid-template-columns:1fr}.database-item-card>header{grid-template-columns:52px minmax(0,1fr)}.database-item-icon{width:52px;height:52px}.database-item-icon :is(img,.game-icon){width:46px;height:46px}}@media(prefers-reduced-motion:reduce){.database-registry-grid>a{transition:none}} +@media(max-width:1200px){.database-category-nav{grid-template-columns:repeat(4,1fr)}.database-category-nav>a:nth-child(5){border-left:0}.database-category-nav>a:nth-child(n+5){border-top:1px solid var(--shd-border)}.database-facet-groups{grid-template-columns:1fr 1fr}.database-facet-group:first-child{grid-column:1/-1}.database-item-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(max-width:700px){.database-category-command{align-items:stretch;flex-direction:column}.database-category-command>div:last-child{justify-items:start}.database-category-nav{grid-template-columns:repeat(2,1fr)}.database-category-nav>a:nth-child(odd){border-left:0}.database-category-nav>a:nth-child(n+3){border-top:1px solid var(--shd-border)}.database-facet-panel>header{align-items:flex-start;flex-direction:column}.database-facet-groups{grid-template-columns:1fr}.database-facet-group:first-child{grid-column:auto}.database-facet-group>div,.database-facet-groups.compact .database-facet-group>div{grid-template-columns:repeat(2,minmax(0,1fr))}.database-item-grid{grid-template-columns:1fr}.database-item-card>header{grid-template-columns:52px minmax(0,1fr)}.database-item-icon{width:52px;height:52px}.database-item-icon :is(img,.game-icon){width:46px;height:46px}}@media(prefers-reduced-motion:reduce){.database-registry-grid>a{transition:none}} .community-metrics{gap:38px}.community-metrics strong{color:var(--shd-orange);font-size:15px;letter-spacing:1px}.community-preview .gear-node{width:98px;color:var(--shd-text)}.community-preview .gear-node:hover,.community-preview .gear-node:focus-visible{border-color:var(--shd-orange);background:#211a0e}.community-preview .gear-node:active{transform:translateY(1px);filter:brightness(.86)}.community-preview .gear-node b{font-size:7px;letter-spacing:.55px}.community-channels{padding:58px max(24px,5vw) 70px;border-top:1px solid var(--shd-border);background:#0c0f10}.community-channels>.section-heading{max-width:1240px}.community-channels>.section-heading>p{max-width:310px;margin:0;color:var(--shd-text-muted);font:12px/1.5 Georgia,serif;text-align:right}.community-channel-grid{max-width:1240px;display:grid;grid-template-columns:repeat(4,1fr);margin:auto;border:1px solid var(--shd-border)}.community-channel-grid>a{min-height:205px;display:flex;flex-direction:column;padding:20px;border-left:1px solid var(--shd-border);background:#111415;color:var(--shd-text)}.community-channel-grid>a:first-child{border-left:0}.community-channel-grid>a:hover,.community-channel-grid>a:focus-visible{background:#171b1c;box-shadow:inset 0 2px var(--shd-orange)}.community-channel-grid>a:active{filter:brightness(.84)}.community-channel-grid small{color:#626a6c;font-size:6px;letter-spacing:1px}.community-channel-grid strong{margin:18px 0 9px;font-size:14px;letter-spacing:.6px}.community-channel-grid span{color:#858d8f;font:11px/1.55 Georgia,serif}.community-channel-grid b{margin-top:auto;padding-top:17px;color:var(--shd-orange);font-size:7px;letter-spacing:.8px}.community-index-page{padding-top:34px}.community-index-hero{margin-bottom:12px}.community-database-intro{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px}.community-database-intro>div{display:grid;grid-template-columns:150px 1fr 1.4fr;align-items:center;gap:12px;min-height:65px;padding:10px 13px;border:1px solid var(--shd-border);background:#101314}.community-database-intro span{color:#666e70;font-size:6px;letter-spacing:1px}.community-database-intro strong{color:var(--shd-orange);font-size:8px;letter-spacing:.7px}.community-database-intro small{color:#7f8789;font:10px/1.45 Georgia,serif}.database-registry-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:9px}.database-registry-grid article{min-height:180px;display:flex;flex-direction:column;padding:17px;border:1px solid var(--shd-border);border-top:2px solid #43494a;background:#111415}.database-registry-grid article:hover{border-top-color:var(--shd-orange);background:#15191a}.database-registry-grid header{height:auto;display:flex;justify-content:space-between}.database-registry-grid header small{color:#596164;font-size:6px;letter-spacing:.8px}.database-registry-grid header b{color:var(--shd-orange);font-size:20px}.database-registry-grid h2{margin:18px 0 8px;font-size:16px}.database-registry-grid p{color:#858d8f;font:11px/1.55 Georgia,serif}.database-registry-grid>article>span{margin-top:auto;color:#687073;font-size:6px;font-weight:900;letter-spacing:.8px}.news-channel-grid{display:grid;grid-template-columns:minmax(0,1fr) 330px;gap:10px}.news-primary{min-height:390px;padding:30px;border:1px solid var(--shd-border);border-top:2px solid var(--shd-orange);background:linear-gradient(135deg,#151819,#0d1011)}.news-primary>div:first-child{display:flex;justify-content:space-between;padding-bottom:13px;margin-bottom:30px;border-bottom:1px solid var(--shd-border);color:#626a6c;font-size:6px;letter-spacing:1px}.news-primary>div:first-child b{color:var(--shd-orange)}.news-primary h2{max-width:720px;margin:19px 0;font-size:clamp(30px,4vw,52px);line-height:.95}.news-primary>p:not(.eyebrow){max-width:760px;color:#969d9f;font:14px/1.7 Georgia,serif}.news-primary footer{display:flex;gap:7px;margin-top:35px}.news-primary footer span{display:grid;padding:8px 10px;border:1px solid var(--shd-border);color:#626a6c;font-size:6px;letter-spacing:.8px}.news-primary footer b{margin-top:4px;color:#d5d8d5;font-size:8px}.news-channel-grid>aside{padding:19px;border:1px solid var(--shd-border);background:#111415}.news-channel-grid>aside>div{min-height:58px;display:grid;grid-template-columns:30px 1fr auto;align-items:center;border-top:1px solid var(--shd-border)}.news-channel-grid>aside small{color:#596164;font-size:7px}.news-channel-grid>aside span{font-size:8px;letter-spacing:.7px}.news-channel-grid>aside b{color:#6e7678;font-size:6px}@media(max-width:1100px){.community-channel-grid{grid-template-columns:1fr 1fr}.community-channel-grid>a:nth-child(3){border-left:0;border-top:1px solid var(--shd-border)}.community-channel-grid>a:nth-child(4){border-top:1px solid var(--shd-border)}.community-database-intro{grid-template-columns:1fr}.database-registry-grid{grid-template-columns:1fr 1fr}}@media(max-width:750px){.community-channels>.section-heading>p{display:none}.community-channel-grid,.database-registry-grid,.news-channel-grid{grid-template-columns:1fr}.community-channel-grid>a{min-height:155px;border-left:0;border-top:1px solid var(--shd-border)}.community-channel-grid>a:first-child{border-top:0}.community-database-intro>div{grid-template-columns:1fr}.news-primary{padding:22px}.news-primary footer{flex-wrap:wrap}}@media(max-width:430px){.site-header .brand-name small{display:block;font-size:4px;letter-spacing:.7px}} diff --git a/src/lib/components/DatabaseFacetFilters.svelte b/src/lib/components/DatabaseFacetFilters.svelte index 2b746b0..faee18a 100644 --- a/src/lib/components/DatabaseFacetFilters.svelte +++ b/src/lib/components/DatabaseFacetFilters.svelte @@ -36,7 +36,7 @@
TACTICAL FILTER MATRIXMATCH ANY WITHIN A GROUP · MATCH EVERY ACTIVE GROUP
{#if selectedCount}{/if}
-
+
{#each groups as group}
{group.label}{group.selected.length ? `${group.selected.length} ACTIVE` : 'ANY'} diff --git a/src/lib/components/DatabaseItemCard.svelte b/src/lib/components/DatabaseItemCard.svelte index 12d39f2..0da81de 100644 --- a/src/lib/components/DatabaseItemCard.svelte +++ b/src/lib/components/DatabaseItemCard.svelte @@ -41,8 +41,11 @@ {/each}
{/if} - {#if item.description}

{item.description}

{/if} - {#if item.secondaryDescription}

{item.secondaryDescription}

{/if} + {#if item.description}

{item.description}

{/if} + {#if item.secondaryDescription}

{item.secondaryDescription}

{/if} + {#if item.afterLines?.length} +
{#each item.afterLines as line}
{line.label}{line.value}
{/each}
+ {/if} {#if item.actions?.length} {/if} diff --git a/src/lib/components/ItemIconRail.svelte b/src/lib/components/ItemIconRail.svelte index d078028..770db18 100644 --- a/src/lib/components/ItemIconRail.svelte +++ b/src/lib/components/ItemIconRail.svelte @@ -41,8 +41,9 @@ {#if selected.preview.badges?.length}
{#each selected.preview.badges as badge}{badge.label}{/each}
{/if} {#if selected.preview.lines?.length}
{#each selected.preview.lines as line}
{line.label}{line.value}
{/each}
{/if} - {#if selected.preview.description}

{selected.preview.description}

{/if} - {#if selected.preview.secondaryDescription}

{selected.preview.secondaryDescription}

{/if} + {#if selected.preview.description}

{selected.preview.description}

{/if} + {#if selected.preview.secondaryDescription}

{selected.preview.secondaryDescription}

{/if} + {#if selected.preview.afterLines?.length}
{#each selected.preview.afterLines as line}
{line.label}{line.value}
{/each}
{/if} {#if selected.preview.actions?.length}{/if}
diff --git a/src/lib/database/items.ts b/src/lib/database/items.ts index 381bc27..a352cf4 100644 --- a/src/lib/database/items.ts +++ b/src/lib/database/items.ts @@ -24,9 +24,11 @@ export type DatabaseItem = { factLayout?: 'grid' | 'stack'; actions?: Array<{ label: string; href: string }>; lines?: DatabaseFact[]; + afterLines?: DatabaseFact[]; iconGroups?: DatabaseIconGroup[]; description?: string; secondaryDescription?: string; + descriptionStyle?: 'prose' | 'data'; }; export type DatabaseRelatedItem = { diff --git a/src/routes/database/[category]/+page.server.ts b/src/routes/database/[category]/+page.server.ts index bb3162b..45af0fa 100644 --- a/src/routes/database/[category]/+page.server.ts +++ b/src/routes/database/[category]/+page.server.ts @@ -207,8 +207,35 @@ export const load: PageServerLoad = async ({ params, url }) => { WHERE item.active=1${searchClause} ORDER BY item.quality,item.primary_attribute_type,item.name COLLATE NOCASE LIMIT ? OFFSET ?`; break; - case 'talents': - countSql = `SELECT COUNT(*) AS total FROM talents item WHERE item.active=1${searchClause}`; + case 'talents': { + const talentSlots = [ + { value: 'Backpack', label: 'Backpack', gameIcon: 'backpack' as const }, + { value: 'Body Armor', label: 'Body Armor', gameIcon: 'body_armor' as const }, + { value: 'Weapon 1', label: 'Weapon 1 · Top', gameIcon: 'smg' as const }, + { value: 'Weapon 2', label: 'Weapon 2 · Bottom', gameIcon: 'smg' as const } + ]; + const selectedTalentSlots = url.searchParams.getAll('talentSlot') + .filter((value) => talentSlots.some((slot) => slot.value === value)); + const conditions = ['item.active=1']; + queryArgs = []; + if (search) { + conditions.push("item.name LIKE ? ESCAPE '\\' COLLATE NOCASE"); + queryArgs.push(pattern); + } + if (selectedTalentSlots.length) { + const slotConditions = selectedTalentSlots.map((slot) => { + if (slot === 'Backpack') return "item.category='Backpack'"; + if (slot === 'Body Armor') return "item.category IN ('Body Armor','Vest')"; + queryArgs.push(slot === 'Weapon 1' ? 1 : 2); + return `item.category='Weapon' AND EXISTS ( + SELECT 1 FROM weapon_talent_slots filter_slots + WHERE filter_slots.talent_id=item.id AND filter_slots.slot=? + )`; + }); + conditions.push(`(${slotConditions.map((condition) => `(${condition})`).join(' OR ')})`); + } + const where = conditions.join(' AND '); + countSql = `SELECT COUNT(*) AS total FROM talents item WHERE ${where}`; rowsSql = `SELECT item.*, (SELECT description FROM talent_tiers tiers WHERE tiers.talent_id=item.id AND tiers.tier='I') AS tier_i, (SELECT description FROM talent_tiers tiers WHERE tiers.talent_id=item.id AND tiers.tier='II') AS tier_ii, @@ -217,9 +244,17 @@ export const load: PageServerLoad = async ({ params, url }) => { icons.updated_at AS icon_updated_at FROM talents item LEFT JOIN game_data_icons icons ON icons.entity_type='talent' AND icons.entity_id=item.id - WHERE item.active=1${searchClause} + WHERE ${where} ORDER BY item.category,item.name COLLATE NOCASE LIMIT ? OFFSET ?`; + filters = [{ + key: 'talentSlot', + label: 'TALENT SLOT', + kind: 'segmented', + selected: selectedTalentSlots, + options: talentSlots + }]; break; + } case 'brands': countSql = `SELECT COUNT(*) AS total FROM brand_sets item WHERE item.active=1${searchClause}`; rowsSql = `SELECT item.*,icons.updated_at AS icon_updated_at @@ -449,23 +484,30 @@ export const load: PageServerLoad = async ({ params, url }) => { ], lines: [{ label: 'UNIQUE TALENT', value: list(row.talent_name,'NOT CONFIGURED') }] }; - case 'talents': + case 'talents': { + const talentCategory = String(row.category); + const isWeaponTalent = talentCategory === 'Weapon'; + const normalizedCategory = talentCategory === 'Vest' ? 'Body Armor' : talentCategory; + const slotLabel = isWeaponTalent && row.weapon_slot ? `WEAPON ${row.weapon_slot}` : normalizedCategory.toUpperCase(); return { - id: String(row.id), name: String(row.name), kicker: `${row.category}${row.weapon_slot ? ` // SLOT ${row.weapon_slot}` : ''}`, + id: String(row.id), name: String(row.name), kicker: `${slotLabel} TALENT`, iconUrl: iconUrl('talent',row.id,row.icon_updated_at), + headerMetaIcon: isWeaponTalent ? 'smg' : gearIcon(normalizedCategory), + headerBadge: isWeaponTalent && row.weapon_slot + ? `${row.weapon_slot} · ${Number(row.weapon_slot) === 1 ? 'TOP' : 'BOTTOM'}` + : undefined, badges: [ ...(row.weapon_scope === 'Exotic' ? [{ label: 'EXOTIC', tone: 'exotic' }] : []), - ...(row.cooldown_seconds ? [{ label: `${number(row.cooldown_seconds)}s COOLDOWN` }] : []), ...(row.duration_seconds ? [{ label: `${number(row.duration_seconds)}s DURATION` }] : []), ...(row.max_stacks ? [{ label: `${row.max_stacks} STACKS` }] : []) ], - facts: [ - { label: 'TIER I', value: row.tier_i ? 'CONFIGURED' : 'MISSING' }, - { label: 'TIER II', value: row.tier_ii ? 'CONFIGURED' : 'MISSING' } - ], - description: row.tier_i ? `TIER I · ${row.tier_i}` : 'Tier I description is not configured.', - secondaryDescription: row.tier_ii ? `TIER II · ${row.tier_ii}` : 'Tier II description is not configured.' + facts: [], + description: row.tier_i ? String(row.tier_i) : 'Description is not available.', + secondaryDescription: row.tier_ii ? String(row.tier_ii) : 'Description is not available.', + descriptionStyle: 'data' as const, + afterLines: row.cooldown_seconds ? [{ label: 'TALENT COOLDOWN', value: `${number(row.cooldown_seconds)} SECONDS` }] : [] }; + } case 'brands': { const effects = brandEffects.filter((effect) => effect.brand_set_id === row.id); return {