High-fidelity HTML/CSS/JS design references for the tactical-CRPG direction — title, character creation, character sheet, inventory, world map, quest log, shop, pause/settings, dialogue, combat HUD, main exploration window. README is the handoff spec (visual system, per-screen state models, Godot translation notes). Not production code — the source of truth for the game's look + systems. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
293 lines
19 KiB
HTML
293 lines
19 KiB
HTML
<!DOCTYPE html>
|
||
<html>
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||
<script src="./support.js"></script>
|
||
</head>
|
||
<body>
|
||
<x-dc>
|
||
<helmet data-dc-atomics>
|
||
<link href="https://fonts.googleapis.com/css2?family=Architects+Daughter&display=swap" rel="stylesheet">
|
||
<style>
|
||
body{margin:0;background:#0f0d0b;font-family:system-ui,sans-serif}
|
||
a{color:#8f3a34}a:hover{color:#6f2b26}
|
||
</style>
|
||
</helmet>
|
||
<div style="width:1920px;height:1080px;position:relative;display:flex">
|
||
|
||
<!-- ============ LEFT: PAPER DOLL ============ -->
|
||
<div style="width:620px;height:1080px;position:relative;overflow:hidden;background:repeating-linear-gradient(135deg,#26221c 0 16px,#221e18 16px 32px);display:flex;flex-direction:column">
|
||
<div style="position:absolute;inset:0;background:radial-gradient(120% 70% at 50% 40%,rgba(0,0,0,0) 35%,rgba(0,0,0,.6) 100%)"></div>
|
||
<!-- header -->
|
||
<div style="position:relative;padding:28px 34px 0">
|
||
<div style="font:13px ui-monospace,monospace;letter-spacing:.18em;color:#8a7f6c">EQUIPMENT</div>
|
||
<div style="font:600 30px 'Architects Daughter',cursive;color:#e8d9b6;margin-top:4px">Vexcca the Nameless</div>
|
||
<div style="font:13px ui-monospace,monospace;letter-spacing:.12em;color:#a9843f;margin-top:2px">HUMAN · SELLSWORD · LVL 4</div>
|
||
</div>
|
||
<!-- paper doll -->
|
||
<div style="position:relative;flex:1;display:flex;align-items:center;justify-content:center">
|
||
<div style="position:relative;width:620px;height:430px">
|
||
<!-- model -->
|
||
<div style="position:absolute;left:50%;top:60px;transform:translateX(-50%);width:150px;height:310px;border:1px dashed #5a5348;border-radius:14px;background:repeating-linear-gradient(135deg,#2c2620 0 14px,#282219 14px 28px);display:flex;align-items:center;justify-content:center;text-align:center;color:#6b6152;font:11px ui-monospace,monospace;letter-spacing:.1em;padding:0 14px">PAPER<br>DOLL</div>
|
||
<!-- equipment slots -->
|
||
<sc-for list="{{ equip }}" as="s" hint-placeholder-count="12">
|
||
<div style="position:absolute;{{ s.posStyle }}">
|
||
<div onClick="{{ s.onSelect }}" style="width:62px;height:62px;border-radius:10px;border:1px solid #4a4238;background:rgba(18,15,11,.72);position:relative;display:flex;align-items:center;justify-content:center;cursor:pointer" style-hover="border-color:#a9843f">
|
||
<sc-if value="{{ s.filled }}" hint-placeholder-val="{{ true }}">
|
||
<span style="font:600 11px ui-monospace,monospace;color:#c9bda3">{{ s.glyph }}</span>
|
||
<div style="position:absolute;left:6px;right:6px;bottom:5px;height:3px;border-radius:2px;background:{{ s.rarityColor }}"></div>
|
||
</sc-if>
|
||
<sc-if value="{{ s.empty }}" hint-placeholder-val="{{ false }}">
|
||
<span style="font:8px ui-monospace,monospace;letter-spacing:.08em;color:#5a5348">{{ s.label }}</span>
|
||
</sc-if>
|
||
<sc-if value="{{ s.sel }}" hint-placeholder-val="{{ false }}">
|
||
<div style="position:absolute;inset:-2px;border:2.5px solid #a9843f;border-radius:11px;pointer-events:none"></div>
|
||
</sc-if>
|
||
</div>
|
||
</div>
|
||
</sc-for>
|
||
</div>
|
||
</div>
|
||
<!-- derived stats -->
|
||
<div style="position:relative;display:flex;gap:10px;padding:0 34px 34px">
|
||
<div style="flex:1;background:rgba(18,15,11,.7);border:1px solid #3a352e;border-radius:10px;padding:11px 12px"><div style="font:10px ui-monospace,monospace;letter-spacing:.1em;color:#8a7f6c">ARMOR</div><div style="font:600 22px 'Architects Daughter',cursive;color:#e8d9b6">14</div></div>
|
||
<div style="flex:1;background:rgba(18,15,11,.7);border:1px solid #3a352e;border-radius:10px;padding:11px 12px"><div style="font:10px ui-monospace,monospace;letter-spacing:.1em;color:#8a7f6c">DAMAGE</div><div style="font:600 22px 'Architects Daughter',cursive;color:#e8d9b6">12–17</div></div>
|
||
<div style="flex:1;background:rgba(18,15,11,.7);border:1px solid #3a352e;border-radius:10px;padding:11px 12px"><div style="font:10px ui-monospace,monospace;letter-spacing:.1em;color:#caa39c">HP</div><div style="font:600 22px 'Architects Daughter',cursive;color:#e8d9b6">42/60</div></div>
|
||
<div style="flex:1;background:rgba(18,15,11,.7);border:1px solid #3a352e;border-radius:10px;padding:11px 12px"><div style="font:10px ui-monospace,monospace;letter-spacing:.1em;color:#9caccb">MP</div><div style="font:600 22px 'Architects Daughter',cursive;color:#e8d9b6">18/30</div></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- ============ RIGHT: SATCHEL ============ -->
|
||
<div style="width:1300px;height:1080px;background:linear-gradient(180deg,#ece2ca,#e4d8bd);border-left:4px solid #1a1512;box-sizing:border-box;padding:30px 40px;display:flex;flex-direction:column;gap:18px">
|
||
<!-- header -->
|
||
<div style="display:flex;align-items:flex-end;justify-content:space-between;border-bottom:2px solid #bfa878;padding-bottom:14px">
|
||
<div>
|
||
<div style="font:600 30px 'Architects Daughter',cursive;letter-spacing:.04em;color:#5a4326">The Satchel</div>
|
||
<div style="font:12px ui-monospace,monospace;color:#8a7748;letter-spacing:.08em;margin-top:2px">EVERYTHING YOU'VE STOLEN, LOOTED OR REFUSED TO DROP</div>
|
||
</div>
|
||
<div style="display:flex;align-items:flex-end;gap:22px">
|
||
<div style="text-align:right"><div style="font:10px ui-monospace,monospace;letter-spacing:.1em;color:#8a7748">GOLD</div><div style="font:600 22px ui-monospace,monospace;color:#8f6a2a">◈ 1,240</div></div>
|
||
<div style="text-align:right;width:200px">
|
||
<div style="display:flex;justify-content:space-between;font:10px ui-monospace,monospace;letter-spacing:.08em;color:#8a7748"><span>ENCUMBRANCE</span><span style="color:{{ weightColor }}">{{ weightText }}</span></div>
|
||
<div style="height:9px;border-radius:5px;background:#d3c39a;border:1px solid #bfa878;overflow:hidden;margin-top:4px"><div style="width:{{ weightPct }};height:100%;background:{{ weightColor }}"></div></div>
|
||
</div>
|
||
<div style="font:11px ui-monospace,monospace;color:#a99464;border:1px solid #cbb684;border-radius:6px;padding:6px 10px;cursor:pointer" style-hover="background:#e6d9b8">ESC ✕</div>
|
||
</div>
|
||
</div>
|
||
<!-- tabs -->
|
||
<div style="display:flex;gap:8px">
|
||
<sc-for list="{{ tabs }}" as="t" hint-placeholder-count="5">
|
||
<div onClick="{{ t.onSelect }}" style="font:12px ui-monospace,monospace;letter-spacing:.08em;padding:7px 14px;border-radius:7px;border:1px solid {{ t.border }};background:{{ t.bg }};color:{{ t.fg }};cursor:pointer">{{ t.label }}</div>
|
||
</sc-for>
|
||
</div>
|
||
<!-- grid -->
|
||
<div style="display:grid;grid-template-columns:repeat(12,1fr);gap:8px">
|
||
<sc-for list="{{ cells }}" as="c" hint-placeholder-count="60">
|
||
<div onClick="{{ c.onSelect }}" style="aspect-ratio:1;border-radius:8px;border:1px solid #cbb684;background:{{ c.bg }};position:relative;cursor:pointer;display:flex;align-items:center;justify-content:center" style-hover="border-color:#8f7a4a">
|
||
<sc-if value="{{ c.filled }}" hint-placeholder-val="{{ false }}">
|
||
<span style="font:600 12px ui-monospace,monospace;color:#5a4326">{{ c.glyph }}</span>
|
||
<div style="position:absolute;left:5px;right:5px;bottom:4px;height:3px;border-radius:2px;background:{{ c.rarityColor }}"></div>
|
||
<span style="position:absolute;top:3px;right:5px;font:9px ui-monospace,monospace;color:#8a7748">{{ c.qtyLabel }}</span>
|
||
</sc-if>
|
||
<sc-if value="{{ c.sel }}" hint-placeholder-val="{{ false }}">
|
||
<div style="position:absolute;inset:-2px;border:2.5px solid #8f3a34;border-radius:9px;pointer-events:none"></div>
|
||
</sc-if>
|
||
</div>
|
||
</sc-for>
|
||
</div>
|
||
<!-- detail -->
|
||
<div style="margin-top:auto;min-height:196px;background:#f1e8d2;border:1px solid #bfa878;border-radius:12px;padding:20px 24px">
|
||
<sc-if value="{{ hasSel }}" hint-placeholder-val="{{ true }}">
|
||
<div style="display:flex;gap:22px;height:100%">
|
||
<!-- icon -->
|
||
<div style="width:96px;height:96px;border-radius:12px;border:2px solid {{ selRarityColor }};background:#e6d9b8;position:relative;display:flex;align-items:center;justify-content:center;flex:none">
|
||
<span style="font:600 16px ui-monospace,monospace;color:#5a4326">{{ selGlyph }}</span>
|
||
<div style="position:absolute;left:8px;right:8px;bottom:7px;height:4px;border-radius:2px;background:{{ selRarityColor }}"></div>
|
||
</div>
|
||
<!-- body -->
|
||
<div style="flex:1;min-width:0">
|
||
<div style="font:600 24px 'Architects Daughter',cursive;color:{{ selRarityColor }};line-height:1.1">{{ selName }}</div>
|
||
<div style="font:11px ui-monospace,monospace;letter-spacing:.1em;color:#8a7748;margin-top:3px">{{ selType }}</div>
|
||
<div style="margin-top:12px;display:flex;flex-wrap:wrap;gap:5px 18px">
|
||
<sc-for list="{{ selStats }}" as="line" hint-placeholder-count="2">
|
||
<div style="font:14px system-ui;color:#3a2f1c">▸ {{ line }}</div>
|
||
</sc-for>
|
||
</div>
|
||
<div style="margin-top:12px;font:14px/1.5 Georgia,serif;font-style:italic;color:#7a684a">"{{ selFlavor }}"</div>
|
||
</div>
|
||
<!-- side: value + actions -->
|
||
<div style="width:180px;flex:none;display:flex;flex-direction:column;gap:8px;border-left:1px solid #cbb684;padding-left:20px">
|
||
<div style="display:flex;justify-content:space-between;font:12px ui-monospace,monospace;color:#8a7748"><span>WEIGHT</span><span style="color:#5a4326">{{ selWeight }}</span></div>
|
||
<div style="display:flex;justify-content:space-between;font:12px ui-monospace,monospace;color:#8a7748"><span>VALUE</span><span style="color:#8f6a2a">◈ {{ selValue }}</span></div>
|
||
<div style="margin-top:auto;display:flex;flex-direction:column;gap:7px">
|
||
<sc-if value="{{ selCanEquip }}" hint-placeholder-val="{{ false }}">
|
||
<div style="text-align:center;padding:9px 0;border:1.5px solid #8f3a34;border-radius:8px;background:linear-gradient(180deg,#a5423a,#7a2f29);color:#f4e6cf;font:600 13px system-ui;letter-spacing:.04em;cursor:pointer" style-hover="background:#b8524a">EQUIP</div>
|
||
</sc-if>
|
||
<sc-if value="{{ selCanUse }}" hint-placeholder-val="{{ false }}">
|
||
<div style="text-align:center;padding:9px 0;border:1.5px solid #8f3a34;border-radius:8px;background:linear-gradient(180deg,#a5423a,#7a2f29);color:#f4e6cf;font:600 13px system-ui;letter-spacing:.04em;cursor:pointer" style-hover="background:#b8524a">USE</div>
|
||
</sc-if>
|
||
<div style="text-align:center;padding:9px 0;border:1px solid #a99464;border-radius:8px;background:#e6d9b8;color:#5a4326;font:600 13px system-ui;letter-spacing:.04em;cursor:pointer" style-hover="background:#d9c9a2">DROP</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</sc-if>
|
||
<sc-if value="{{ noSel }}" hint-placeholder-val="{{ false }}">
|
||
<div style="height:100%;display:flex;align-items:center;justify-content:center;font:15px 'Architects Daughter',cursive;color:#a99464">Select something. Turn it over in your hands.</div>
|
||
</sc-if>
|
||
</div>
|
||
</div>
|
||
|
||
</div>
|
||
</x-dc>
|
||
<script type="text/x-dc" data-dc-script data-props="{"$preview":{"width":1920,"height":1080}}">
|
||
class Component extends DCLogic {
|
||
RARITY = { common: '#8a8378', uncommon: '#5f8a4f', rare: '#4f7ab8', epic: '#8a5fb8', legendary: '#c8963f' };
|
||
COLS = 12; ROWS = 5;
|
||
MAXW = 60;
|
||
|
||
items() {
|
||
return {
|
||
// equipped
|
||
falchion: { name: 'Notched Falchion', cat: 'weapon', slot: 'mainhand', rarity: 'uncommon', glyph: 'FAL', weight: 4.5, value: 85, qty: 1, stats: ['12–17 slashing', '+1 to hit vs. unarmored'], flavor: 'The nicks in the edge are from bone, not practice.' },
|
||
buckler: { name: 'Dwarf-iron Buckler', cat: 'armor', slot: 'offhand', rarity: 'uncommon', glyph: 'BKL', weight: 5, value: 70, qty: 1, stats: ['+4 block', 'Shield bash: 1d4'], flavor: 'Dented inward. Whatever hit it came off worse.' },
|
||
hood: { name: "Cutpurse's Hood", cat: 'armor', slot: 'head', rarity: 'uncommon', glyph: 'HD', weight: 1, value: 55, qty: 1, stats: ['+2 armor', '+1 DEX'], flavor: 'Keeps the rain and the witnesses off.' },
|
||
jerkin: { name: 'Boiled Leather Jerkin', cat: 'armor', slot: 'chest', rarity: 'common', glyph: 'JRK', weight: 8, value: 40, qty: 1, stats: ['+3 armor', '−1 to sneak'], flavor: 'Stinks of the tanner who died in it.' },
|
||
amulet: { name: 'Amulet of the Ninth Saint', cat: 'misc', slot: 'amulet', rarity: 'rare', glyph: 'AMU', weight: 0.2, value: 320, qty: 1, stats: ['+2 FTH', 'Once a day: reroll a death save'], flavor: 'The saint was hanged. The amulet remembers.' },
|
||
ringdrowned: { name: 'Ring of the Drowned', cat: 'misc', slot: 'ring1', rarity: 'rare', glyph: 'RNG', weight: 0.1, value: 280, qty: 1, stats: ['+1 MAG', 'Breathe water, briefly'], flavor: 'Cold, always. It has not dried in years.' },
|
||
boots: { name: 'Split Marching Boots', cat: 'armor', slot: 'boots', rarity: 'common', glyph: 'BT', weight: 2, value: 15, qty: 1, stats: ['+1 armor'], flavor: 'One sole flaps. You walk quiet anyway.' },
|
||
// backpack
|
||
shiv: { name: 'Rusted Shiv', cat: 'weapon', slot: 'mainhand', rarity: 'common', glyph: 'SHV', weight: 2, value: 5, qty: 1, stats: ['4–7 slashing', 'Snaps on a natural 1'], flavor: 'A door hinge with ambitions.' },
|
||
cap: { name: 'Padded Cap', cat: 'armor', slot: 'head', rarity: 'common', glyph: 'CAP', weight: 1, value: 8, qty: 1, stats: ['+1 armor'], flavor: 'Sweat-stiff. Previous owner not consulted.' },
|
||
salve: { name: 'Fevergrass Salve', cat: 'consumable', rarity: 'common', glyph: 'SLV', weight: 0.3, value: 20, qty: 3, stats: ['Clears Infection (1)', 'Heals 2d4 over time'], flavor: 'Tastes of pond. Works anyway.' },
|
||
bile: { name: 'Vial of Black Bile', cat: 'consumable', rarity: 'uncommon', glyph: 'BILE', weight: 0.4, value: 45, qty: 2, stats: ['Throw: 2d6 acid', 'Fouls the ground it hits'], flavor: 'Do not uncork it near your face.' },
|
||
ration: { name: 'Stale Ration', cat: 'consumable', rarity: 'common', glyph: 'RTN', weight: 0.5, value: 2, qty: 4, stats: ['Removes Hungry', 'Small chance of the runs'], flavor: 'Hard enough to break a tooth. Some have.' },
|
||
picks: { name: "Tinker's Lockpicks", cat: 'tool', rarity: 'uncommon', glyph: 'PICK', weight: 0.2, value: 60, qty: 1, stats: ['+2 to pick locks', 'Breaks on a fumble'], flavor: 'Six left. There were twelve.' },
|
||
bones: { name: 'Human Finger-bones', cat: 'misc', rarity: 'common', glyph: 'BNE', weight: 0.1, value: 0, qty: 9, stats: ["Someone's tally"], flavor: 'Not yours. You keep counting them anyway.' },
|
||
signet: { name: 'Cracked Signet', cat: 'misc', rarity: 'uncommon', glyph: 'SIG', weight: 0.1, value: 120, qty: 1, stats: ['Quest item'], flavor: 'A noble house that no longer pays its debts.' },
|
||
};
|
||
}
|
||
|
||
slotList() {
|
||
return [
|
||
{ key: 'head', label: 'HEAD', pos: 'left:30px;top:12px' },
|
||
{ key: 'amulet', label: 'NECK', pos: 'left:30px;top:80px' },
|
||
{ key: 'chest', label: 'CHEST', pos: 'left:30px;top:148px' },
|
||
{ key: 'cloak', label: 'CLOAK', pos: 'left:30px;top:216px' },
|
||
{ key: 'gloves', label: 'HANDS', pos: 'left:30px;top:284px' },
|
||
{ key: 'belt', label: 'BELT', pos: 'left:30px;top:352px' },
|
||
{ key: 'mainhand', label: 'MAIN', pos: 'left:528px;top:12px' },
|
||
{ key: 'offhand', label: 'OFF', pos: 'left:528px;top:80px' },
|
||
{ key: 'ring1', label: 'RING', pos: 'left:528px;top:148px' },
|
||
{ key: 'ring2', label: 'RING', pos: 'left:528px;top:216px' },
|
||
{ key: 'legs', label: 'LEGS', pos: 'left:528px;top:284px' },
|
||
{ key: 'boots', label: 'FEET', pos: 'left:528px;top:352px' },
|
||
];
|
||
}
|
||
equipped() {
|
||
return { head: 'hood', amulet: 'amulet', chest: 'jerkin', cloak: null, gloves: null, belt: null, mainhand: 'falchion', offhand: 'buckler', ring1: 'ringdrowned', ring2: null, legs: null, boots: 'boots' };
|
||
}
|
||
backpack() { return ['shiv', 'cap', 'salve', 'bile', 'ration', 'picks', 'bones', 'signet']; }
|
||
|
||
state = { sel: 'falchion', tab: 'all' };
|
||
|
||
tabDefs() {
|
||
return [
|
||
{ id: 'all', label: 'ALL', test: () => true },
|
||
{ id: 'weapon', label: 'WEAPONS', test: (it) => it.cat === 'weapon' },
|
||
{ id: 'armor', label: 'ARMOR', test: (it) => it.cat === 'armor' },
|
||
{ id: 'consumable', label: 'CONSUMABLES', test: (it) => it.cat === 'consumable' },
|
||
{ id: 'misc', label: 'MISC', test: (it) => it.cat === 'misc' || it.cat === 'tool' },
|
||
];
|
||
}
|
||
|
||
rc(r) { return this.RARITY[r] || '#8a8378'; }
|
||
|
||
renderVals() {
|
||
const ITEMS = this.items();
|
||
const eq = this.equipped();
|
||
const sel = this.state.sel;
|
||
|
||
// equipment slots
|
||
const equip = this.slotList().map(s => {
|
||
const id = eq[s.key];
|
||
const it = id ? ITEMS[id] : null;
|
||
return {
|
||
key: s.key, label: s.label, posStyle: s.pos,
|
||
filled: !!it, empty: !it,
|
||
glyph: it ? it.glyph : '',
|
||
rarityColor: it ? this.rc(it.rarity) : '#4a4238',
|
||
sel: !!id && id === sel,
|
||
onSelect: () => { if (id) this.setState({ sel: id }); },
|
||
};
|
||
});
|
||
|
||
// tabs
|
||
const tab = this.state.tab;
|
||
const tabs = this.tabDefs().map(t => ({
|
||
label: t.label,
|
||
onSelect: () => this.setState({ tab: t.id }),
|
||
bg: t.id === tab ? '#8f3a34' : '#efe6cf',
|
||
fg: t.id === tab ? '#f1e8d2' : '#6a5a3a',
|
||
border: t.id === tab ? '#8f3a34' : '#cbb684',
|
||
}));
|
||
const activeTest = this.tabDefs().find(t => t.id === tab).test;
|
||
|
||
// grid cells
|
||
const visible = this.backpack().filter(id => activeTest(ITEMS[id]));
|
||
const total = this.COLS * this.ROWS;
|
||
const cells = [];
|
||
for (let i = 0; i < total; i++) {
|
||
const id = visible[i];
|
||
const it = id ? ITEMS[id] : null;
|
||
cells.push({
|
||
filled: !!it,
|
||
glyph: it ? it.glyph : '',
|
||
qtyLabel: it && it.qty > 1 ? ('×' + it.qty) : '',
|
||
rarityColor: it ? this.rc(it.rarity) : '#cbb684',
|
||
bg: it ? '#f4ecd6' : '#e4d6b6',
|
||
sel: !!id && id === sel,
|
||
onSelect: () => { if (id) this.setState({ sel: id }); },
|
||
});
|
||
}
|
||
|
||
// encumbrance
|
||
let w = 0;
|
||
Object.values(eq).forEach(id => { if (id) w += ITEMS[id].weight; });
|
||
this.backpack().forEach(id => { const it = ITEMS[id]; w += it.weight * it.qty; });
|
||
w = Math.round(w * 10) / 10;
|
||
const pct = Math.min(100, Math.round((w / this.MAXW) * 100));
|
||
|
||
// detail
|
||
const it = ITEMS[sel];
|
||
const typeLabel = it ? this.typeOf(it) : '';
|
||
return {
|
||
equip, tabs, cells,
|
||
weightText: w + ' / ' + this.MAXW,
|
||
weightPct: pct + '%',
|
||
weightColor: pct > 90 ? '#8f3a34' : (pct > 70 ? '#a5772a' : '#5f8a4f'),
|
||
hasSel: !!it, noSel: !it,
|
||
selName: it ? it.name : '',
|
||
selType: typeLabel,
|
||
selGlyph: it ? it.glyph : '',
|
||
selRarityColor: it ? this.rc(it.rarity) : '#5a4326',
|
||
selStats: it ? it.stats : [],
|
||
selFlavor: it ? it.flavor : '',
|
||
selWeight: it ? it.weight : '',
|
||
selValue: it ? it.value : '',
|
||
selCanEquip: !!(it && it.slot),
|
||
selCanUse: !!(it && it.cat === 'consumable'),
|
||
};
|
||
}
|
||
|
||
typeOf(it) {
|
||
const capt = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
||
const cat = it.cat === 'tool' ? 'Tool' : (it.cat === 'misc' ? 'Trinket' : capt(it.cat));
|
||
if (it.slot) return cat + ' · ' + capt(it.slot);
|
||
return cat;
|
||
}
|
||
}
|
||
</script>
|
||
</body>
|
||
</html>
|