OOKNET                             [ /  search the index  ]  
──────────────────────────────────────────────────────────────────────────────────────
══════════════════════════════════════════════════════════════════════════════════════
OOKNET   [ /  search  ]  
────────────────────────────────────────────────
════════════════════════════════════════════════
 
HASH      d76ccaeefab2
DATE      2026-05-02
SUBJECT   web: add ItemTooltip component
FILES     5 CHANGED
HASH      d76ccaeefab2
DATE      2026-05-02
SUBJECT   web: add ItemTooltip component
FILES     5 CHANGED
 

diff --git a/web/src/components/ItemTooltip/ItemTooltip.astro b/web/src/components
/ItemTooltip/ItemTooltip.astro
new file mode 100644
index 0000000..31867e6
--- /dev/null
+++ b/web/src/components/ItemTooltip/ItemTooltip.astro
@@ -0,0 +1,24 @@
+---
+import "./ItemTooltip.scss";
+---
+
+<div id="item-tooltip" class="item-tooltip" style="display:none">
+  <div class="tooltip-header">
+    <span class="tooltip-item-name"></span>
+  </div>
+  <div class="tooltip-ilvl"></div>
+  <div class="tooltip-slot-armor"></div>
+  <div class="tooltip-stats"></div>
+  <div class="tooltip-gems"></div>
+  <div class="tooltip-enchant"></div>
+  <div class="tooltip-effect"></div>
+  <div class="tooltip-set"></div>
+</div>
+
+<script>
+  import { initItemTooltip } from "./ItemTooltip.ts";
+  // run on initial load
+  initItemTooltip();
+  // also handle View Transitions if enabled
+  document.addEventListener("astro:page-load", initItemTooltip);
+</script>

diff --git a/web/src/components/ItemTooltip/
ItemTooltip.astro b/web/src/components/ItemT
ooltip/ItemTooltip.astro
new file mode 100644
index 0000000..31867e6
--- /dev/null
+++ b/web/src/components/ItemTooltip/ItemToo
ltip.astro
@@ -0,0 +1,24 @@
+---
+import "./ItemTooltip.scss";
+---
+
+<div id="item-tooltip" class="item-tooltip"
 style="display:none">
+  <div class="tooltip-header">
+    <span class="tooltip-item-name"></span>
+  </div>
+  <div class="tooltip-ilvl"></div>
+  <div class="tooltip-slot-armor"></div>
+  <div class="tooltip-stats"></div>
+  <div class="tooltip-gems"></div>
+  <div class="tooltip-enchant"></div>
+  <div class="tooltip-effect"></div>
+  <div class="tooltip-set"></div>
+</div>
+
+<script>
+  import { initItemTooltip } from "./ItemTo
oltip.ts";
+  // run on initial load
+  initItemTooltip();
+  // also handle View Transitions if enable
d
+  document.addEventListener("astro:page-loa
d", initItemTooltip);
+</script>
 

diff --git a/web/src/components/ItemTooltip/ItemTooltip.scss b/web/src/components/
ItemTooltip/ItemTooltip.scss
new file mode 100644
index 0000000..c362719
--- /dev/null
+++ b/web/src/components/ItemTooltip/ItemTooltip.scss
@@ -0,0 +1,94 @@
+.item-tooltip {
+  position: fixed;
+  z-index: 9999;
+  pointer-events: none;
+  min-width: 200px;
+  max-width: 320px;
+  padding: 10px 14px;
+  background: #1a1a1a;
+  border: 1px solid #4d4947;
+  border-radius: 4px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6);
+  font-size: 13px;
+  line-height: 1.5;
+  color: #e6e6e6;
+}
+
+.tooltip-item-name {
+  display: block;
+  font-size: 15px;
+  font-weight: 600;
+  margin-bottom: 2px;
+
+  &.quality-poor { color: var(--quality-poor); }
+  &.quality-common { color: var(--quality-common); }
+  &.quality-uncommon { color: var(--quality-uncommon); }
+  &.quality-rare { color: var(--quality-rare); }
+  &.quality-epic { color: var(--quality-epic); }
+  &.quality-legendary { color: var(--quality-legendary); }
+  &.quality-artifact { color: var(--quality-artifact); }
+  &.quality-heirloom { color: var(--quality-heirloom); }
+}
+
+.tooltip-ilvl {
+  color: var(--quality-heirloom);
+  margin-bottom: 4px;
+}
+
+.tooltip-slot-armor {
+  color: #e6e6e6;
+  margin-bottom: 4px;
+}
+
+.tooltip-stats {
+  margin-bottom: 4px;
+}
+
+.tooltip-stat-line {
+  color: #fff;
+}
+
+.tooltip-gems {
+  margin-bottom: 4px;
+}
+
+.tooltip-gem-line {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  color: #fff;
+}
+
+.tooltip-gem-icon {
+  width: 14px;
+  height: 14px;
+  border-radius: 2px;
+  flex-shrink: 0;
+}
+
+.tooltip-enchant {
+  margin-bottom: 4px;
+}
+
+.tooltip-enchant-line {
+  color: var(--quality-uncommon);
+}
+
+.tooltip-effect {
+  margin-top: 6px;
+  padding-top: 6px;
+  border-top: 1px solid #333;
+}
+
+.tooltip-effect:empty {
+  display: none;
+}
+
+.tooltip-effect-line {
+  color: #00ff00; // Blizzard tooltip green
+}
+
+.tooltip-set {
+  color: var(--quality-uncommon);
+  margin-top: 4px;
+}

diff --git a/web/src/components/ItemTooltip/
ItemTooltip.scss b/web/src/components/ItemTo
oltip/ItemTooltip.scss
new file mode 100644
index 0000000..c362719
--- /dev/null
+++ b/web/src/components/ItemTooltip/ItemToo
ltip.scss
@@ -0,0 +1,94 @@
+.item-tooltip {
+  position: fixed;
+  z-index: 9999;
+  pointer-events: none;
+  min-width: 200px;
+  max-width: 320px;
+  padding: 10px 14px;
+  background: #1a1a1a;
+  border: 1px solid #4d4947;
+  border-radius: 4px;
+  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.6)
;
+  font-size: 13px;
+  line-height: 1.5;
+  color: #e6e6e6;
+}
+
+.tooltip-item-name {
+  display: block;
+  font-size: 15px;
+  font-weight: 600;
+  margin-bottom: 2px;
+
+  &.quality-poor { color: var(--quality-poo
r); }
+  &.quality-common { color: var(--quality-c
ommon); }
+  &.quality-uncommon { color: var(--quality
-uncommon); }
+  &.quality-rare { color: var(--quality-rar
e); }
+  &.quality-epic { color: var(--quality-epi
c); }
+  &.quality-legendary { color: var(--qualit
y-legendary); }
+  &.quality-artifact { color: var(--quality
-artifact); }
+  &.quality-heirloom { color: var(--quality
-heirloom); }
+}
+
+.tooltip-ilvl {
+  color: var(--quality-heirloom);
+  margin-bottom: 4px;
+}
+
+.tooltip-slot-armor {
+  color: #e6e6e6;
+  margin-bottom: 4px;
+}
+
+.tooltip-stats {
+  margin-bottom: 4px;
+}
+
+.tooltip-stat-line {
+  color: #fff;
+}
+
+.tooltip-gems {
+  margin-bottom: 4px;
+}
+
+.tooltip-gem-line {
+  display: flex;
+  align-items: center;
+  gap: 4px;
+  color: #fff;
+}
+
+.tooltip-gem-icon {
+  width: 14px;
+  height: 14px;
+  border-radius: 2px;
+  flex-shrink: 0;
+}
+
+.tooltip-enchant {
+  margin-bottom: 4px;
+}
+
+.tooltip-enchant-line {
+  color: var(--quality-uncommon);
+}
+
+.tooltip-effect {
+  margin-top: 6px;
+  padding-top: 6px;
+  border-top: 1px solid #333;
+}
+
+.tooltip-effect:empty {
+  display: none;
+}
+
+.tooltip-effect-line {
+  color: #00ff00; // Blizzard tooltip green
+}
+
+.tooltip-set {
+  color: var(--quality-uncommon);
+  margin-top: 4px;
+}
 

diff --git a/web/src/components/ItemTooltip/ItemTooltip.ts b/web/src/components/It
emTooltip/ItemTooltip.ts
new file mode 100644
index 0000000..111646a
--- /dev/null
+++ b/web/src/components/ItemTooltip/ItemTooltip.ts
@@ -0,0 +1,183 @@
+import type { Enchantment, ScalingOption } from "../../lib/types";
+
+const STAT_NAMES: Record<string, string> = {
+  "0": "Strength",
+  "1": "Agility",
+  "2": "Stamina",
+  "3": "Intellect",
+  "4": "Spirit",
+  "5": "Hit",
+  "6": "Crit",
+  "7": "Haste",
+  "8": "Expertise",
+  "9": "Dodge",
+  "10": "Parry",
+  "11": "Mastery",
+};
+
+function getScaling(scalingOptions: Record<string, ScalingOption>): ScalingOption
 | null {
+  return scalingOptions["0"] ?? null;
+}
+
+function populateTooltip(
+  tooltip: HTMLElement,
+  scalingOptions: Record<string, ScalingOption>,
+  itemName: string,
+  quality: string,
+  enchants: Enchantment[],
+  spellDescription: string | null,
+) {
+  const nameEl = tooltip.querySelector<HTMLElement>(".tooltip-item-name");
+  const ilvlEl = tooltip.querySelector<HTMLElement>(".tooltip-ilvl");
+  const slotArmorEl = tooltip.querySelector<HTMLElement>(".tooltip-slot-armor");
+  const statsEl = tooltip.querySelector<HTMLElement>(".tooltip-stats");
+  const gemsEl = tooltip.querySelector<HTMLElement>(".tooltip-gems");
+  const enchantEl = tooltip.querySelector<HTMLElement>(".tooltip-enchant");
+  const effectEl = tooltip.querySelector<HTMLElement>(".tooltip-effect");
+  const setEl = tooltip.querySelector<HTMLElement>(".tooltip-set");
+
+  if (nameEl) {
+    nameEl.textContent = itemName;
+    nameEl.className = `tooltip-item-name quality-${quality.toLowerCase()}`;
+  }
+
+  const scaling = getScaling(scalingOptions);
+
+  if (ilvlEl) {
+    ilvlEl.textContent = scaling?.ilvl ? `Item Level ${scaling.ilvl}` : "";
+  }
+
+  if (slotArmorEl) {
+    const parts: string[] = [];
+    if (scaling?.stats?.["17"]) {
+      parts.push(`${scaling.stats["17"].toLocaleString()} Armor`);
+    }
+    slotArmorEl.textContent = parts.join(" - ");
+  }
+
+  // stats (skip armor key 17)
+  if (statsEl) {
+    statsEl.innerHTML = "";
+    if (scaling?.stats) {
+      for (const [key, value] of Object.entries(scaling.stats)) {
+        if (key === "17") continue;
+        const name = STAT_NAMES[key] || `Stat ${key}`;
+        const div = document.createElement("div");
+        div.className = "tooltip-stat-line";
+        div.textContent = `+${value.toLocaleString()} ${name}`;
+        statsEl.appendChild(div);
+      }
+    }
+  }
+
+  // gems (slot_id 2-5, no slot_type)
+  if (gemsEl) {
+    gemsEl.innerHTML = "";
+    const gems = enchants.filter(
+      (e) => e.slot_id >= 2 && e.slot_id <= 5 && !e.slot_type,
+    );
+    for (const gem of gems) {
+      const div = document.createElement("div");
+      div.className = "tooltip-gem-line";
+      if (gem.gem_icon_slug) {
+        const img = document.createElement("img");
+        img.src = `https://wow.zamimg.com/images/wow/icons/small/${gem.gem_icon_s
lug}.jpg`;
+        img.className = "tooltip-gem-icon";
+        img.alt = "";
+        div.appendChild(img);
+      }
+      const span = document.createElement("span");
+      span.textContent = gem.display_string;
+      div.appendChild(span);
+      gemsEl.appendChild(div);
+    }
+  }
+
+  // enchant (slot_type === "PERMANENT")
+  if (enchantEl) {
+    enchantEl.innerHTML = "";
+    const permanent = enchants.filter((e) => e.slot_type === "PERMANENT");
+    for (const ench of permanent) {
+      const div = document.createElement("div");
+      div.className = "tooltip-enchant-line";
+      div.textContent = ench.display_string;
+      enchantEl.appendChild(div);
+    }
+  }
+
+  // spell description from Blizzard API
+  if (effectEl) {
+    effectEl.innerHTML = "";
+    if (spellDescription) {
+      // handle multiple descriptions (separated by newlines)
+      const descriptions = spellDescription.split("\n");
+      for (const desc of descriptions) {
+        if (desc.trim()) {
+          const div = document.createElement("div");
+          div.className = "tooltip-effect-line";
+          div.textContent = desc;
+          effectEl.appendChild(div);
+        }
+      }
+    }
+  }
+
+  if (setEl) {
+    setEl.textContent = "";
+    setEl.style.display = "none";
+  }
+}
+
+function positionTooltip(tooltip: HTMLElement, anchor: HTMLElement) {
+  const rect = anchor.getBoundingClientRect();
+  const tooltipRect = tooltip.getBoundingClientRect();
+  const padding = 8;
+
+  let left = rect.right + padding;
+  let top = rect.top;
+
+  if (left + tooltipRect.width > window.innerWidth) {
+    left = rect.left - tooltipRect.width - padding;
+  }
+  if (top + tooltipRect.height > window.innerHeight) {
+    top = window.innerHeight - tooltipRect.height - padding;
+  }
+  if (top < padding) top = padding;
+
+  tooltip.style.left = `${left}px`;
+  tooltip.style.top = `${top}px`;
+}
+
+export function initItemTooltip() {
+  const tooltip = document.getElementById("item-tooltip");
+  if (!tooltip) return;
+
+  const icons = document.querySelectorAll<HTMLElement>(".equip-icon-wrap[data-ite
m-id]");
+
+  for (const icon of icons) {
+    icon.addEventListener("mouseenter", () => {
+      const itemName = icon.dataset.itemName || "Unknown";
+      const quality = icon.dataset.quality || "COMMON";
+
+      let enchants: Enchantment[] = [];
+      try {
+        enchants = JSON.parse(icon.dataset.enchants || "[]");
+      } catch { /* ignore */ }
+
+      let scalingOptions: Record<string, ScalingOption> = {};
+      try {
+        scalingOptions = JSON.parse(icon.dataset.scaling || "{}");
+      } catch { /* ignore */ }
+
+      const spellDescription = icon.dataset.spellDescription || null;
+
+      populateTooltip(tooltip, scalingOptions, itemName, quality, enchants, spell
Description);
+      tooltip.style.display = "block";
+      positionTooltip(tooltip, icon);
+    });
+
+    icon.addEventListener("mouseleave", () => {
+      tooltip.style.display = "none";
+    });
+  }
+}

diff --git a/web/src/components/ItemTooltip/
ItemTooltip.ts b/web/src/components/ItemTool
tip/ItemTooltip.ts
new file mode 100644
index 0000000..111646a
--- /dev/null
+++ b/web/src/components/ItemTooltip/ItemToo
ltip.ts
@@ -0,0 +1,183 @@
+import type { Enchantment, ScalingOption } 
from "../../lib/types";
+
+const STAT_NAMES: Record<string, string> = 
{
+  "0": "Strength",
+  "1": "Agility",
+  "2": "Stamina",
+  "3": "Intellect",
+  "4": "Spirit",
+  "5": "Hit",
+  "6": "Crit",
+  "7": "Haste",
+  "8": "Expertise",
+  "9": "Dodge",
+  "10": "Parry",
+  "11": "Mastery",
+};
+
+function getScaling(scalingOptions: Record<
string, ScalingOption>): ScalingOption | nul
l {
+  return scalingOptions["0"] ?? null;
+}
+
+function populateTooltip(
+  tooltip: HTMLElement,
+  scalingOptions: Record<string, ScalingOpt
ion>,
+  itemName: string,
+  quality: string,
+  enchants: Enchantment[],
+  spellDescription: string | null,
+) {
+  const nameEl = tooltip.querySelector<HTML
Element>(".tooltip-item-name");
+  const ilvlEl = tooltip.querySelector<HTML
Element>(".tooltip-ilvl");
+  const slotArmorEl = tooltip.querySelector
<HTMLElement>(".tooltip-slot-armor");
+  const statsEl = tooltip.querySelector<HTM
LElement>(".tooltip-stats");
+  const gemsEl = tooltip.querySelector<HTML
Element>(".tooltip-gems");
+  const enchantEl = tooltip.querySelector<H
TMLElement>(".tooltip-enchant");
+  const effectEl = tooltip.querySelector<HT
MLElement>(".tooltip-effect");
+  const setEl = tooltip.querySelector<HTMLE
lement>(".tooltip-set");
+
+  if (nameEl) {
+    nameEl.textContent = itemName;
+    nameEl.className = `tooltip-item-name q
uality-${quality.toLowerCase()}`;
+  }
+
+  const scaling = getScaling(scalingOptions
);
+
+  if (ilvlEl) {
+    ilvlEl.textContent = scaling?.ilvl ? `I
tem Level ${scaling.ilvl}` : "";
+  }
+
+  if (slotArmorEl) {
+    const parts: string[] = [];
+    if (scaling?.stats?.["17"]) {
+      parts.push(`${scaling.stats["17"].toL
ocaleString()} Armor`);
+    }
+    slotArmorEl.textContent = parts.join(" 
- ");
+  }
+
+  // stats (skip armor key 17)
+  if (statsEl) {
+    statsEl.innerHTML = "";
+    if (scaling?.stats) {
+      for (const [key, value] of Object.ent
ries(scaling.stats)) {
+        if (key === "17") continue;
+        const name = STAT_NAMES[key] || `St
at ${key}`;
+        const div = document.createElement(
"div");
+        div.className = "tooltip-stat-line"
;
+        div.textContent = `+${value.toLocal
eString()} ${name}`;
+        statsEl.appendChild(div);
+      }
+    }
+  }
+
+  // gems (slot_id 2-5, no slot_type)
+  if (gemsEl) {
+    gemsEl.innerHTML = "";
+    const gems = enchants.filter(
+      (e) => e.slot_id >= 2 && e.slot_id <=
 5 && !e.slot_type,
+    );
+    for (const gem of gems) {
+      const div = document.createElement("d
iv");
+      div.className = "tooltip-gem-line";
+      if (gem.gem_icon_slug) {
+        const img = document.createElement(
"img");
+        img.src = `https://wow.zamimg.com/i
mages/wow/icons/small/${gem.gem_icon_slug}.j
pg`;
+        img.className = "tooltip-gem-icon";
+        img.alt = "";
+        div.appendChild(img);
+      }
+      const span = document.createElement("
span");
+      span.textContent = gem.display_string
;
+      div.appendChild(span);
+      gemsEl.appendChild(div);
+    }
+  }
+
+  // enchant (slot_type === "PERMANENT")
+  if (enchantEl) {
+    enchantEl.innerHTML = "";
+    const permanent = enchants.filter((e) =
> e.slot_type === "PERMANENT");
+    for (const ench of permanent) {
+      const div = document.createElement("d
iv");
+      div.className = "tooltip-enchant-line
";
+      div.textContent = ench.display_string
;
+      enchantEl.appendChild(div);
+    }
+  }
+
+  // spell description from Blizzard API
+  if (effectEl) {
+    effectEl.innerHTML = "";
+    if (spellDescription) {
+      // handle multiple descriptions (sepa
rated by newlines)
+      const descriptions = spellDescription
.split("\n");
+      for (const desc of descriptions) {
+        if (desc.trim()) {
+          const div = document.createElemen
t("div");
+          div.className = "tooltip-effect-l
ine";
+          div.textContent = desc;
+          effectEl.appendChild(div);
+        }
+      }
+    }
+  }
+
+  if (setEl) {
+    setEl.textContent = "";
+    setEl.style.display = "none";
+  }
+}
+
+function positionTooltip(tooltip: HTMLEleme
nt, anchor: HTMLElement) {
+  const rect = anchor.getBoundingClientRect
();
+  const tooltipRect = tooltip.getBoundingCl
ientRect();
+  const padding = 8;
+
+  let left = rect.right + padding;
+  let top = rect.top;
+
+  if (left + tooltipRect.width > window.inn
erWidth) {
+    left = rect.left - tooltipRect.width - 
padding;
+  }
+  if (top + tooltipRect.height > window.inn
erHeight) {
+    top = window.innerHeight - tooltipRect.
height - padding;
+  }
+  if (top < padding) top = padding;
+
+  tooltip.style.left = `${left}px`;
+  tooltip.style.top = `${top}px`;
+}
+
+export function initItemTooltip() {
+  const tooltip = document.getElementById("
item-tooltip");
+  if (!tooltip) return;
+
+  const icons = document.querySelectorAll<H
TMLElement>(".equip-icon-wrap[data-item-id]"
);
+
+  for (const icon of icons) {
+    icon.addEventListener("mouseenter", () 
=> {
+      const itemName = icon.dataset.itemNam
e || "Unknown";
+      const quality = icon.dataset.quality 
|| "COMMON";
+
+      let enchants: Enchantment[] = [];
+      try {
+        enchants = JSON.parse(icon.dataset.
enchants || "[]");
+      } catch { /* ignore */ }
+
+      let scalingOptions: Record<string, Sc
alingOption> = {};
+      try {
+        scalingOptions = JSON.parse(icon.da
taset.scaling || "{}");
+      } catch { /* ignore */ }
+
+      const spellDescription = icon.dataset
.spellDescription || null;
+
+      populateTooltip(tooltip, scalingOptio
ns, itemName, quality, enchants, spellDescri
ption);
+      tooltip.style.display = "block";
+      positionTooltip(tooltip, icon);
+    });
+
+    icon.addEventListener("mouseleave", () 
=> {
+      tooltip.style.display = "none";
+    });
+  }
+}
 

diff --git a/web/src/components/PlayerProfile/PlayerEquipment/PlayerEquipment.astr
o b/web/src/components/PlayerProfile/PlayerEquipment/PlayerEquipment.astro
index 23e627a..d52ef95 100644
--- a/web/src/components/PlayerProfile/PlayerEquipment/PlayerEquipment.astro
+++ b/web/src/components/PlayerProfile/PlayerEquipment/PlayerEquipment.astro
@@ -6,6 +6,7 @@ import {
   getZamimgIconUrl,
   getWowheadUrl,
 } from "../../../lib/equipment-utils";
+import ItemTooltip from "../../ItemTooltip/ItemTooltip.astro";
 import "./PlayerEquipment.scss";
 
 interface Props {
@@ -63,9 +64,14 @@ if (equipment && Object.keys(equipment).length > 0) {
                 <a
                   href={href}
                   class={`equip-icon-wrap ${qualityClass}`}
-                  title={title}
                   target="_blank"
                   rel="noopener noreferrer"
+                  data-item-id={itemId}
+                  data-item-name={title}
+                  data-quality={item.quality || "COMMON"}
+                  data-enchants={JSON.stringify(item.enchantments || [])}
+                  data-scaling={JSON.stringify(item.scaling_options || {})}
+                  data-spell-description={item.spell_description || undefined}
                 >
                   <div class="equip-icon-inner">
                     {iconUrl ? (
@@ -105,4 +111,5 @@ if (equipment && Object.keys(equipment).length > 0) {
       )
     }
   </div>
+  <ItemTooltip />
 </div>

diff --git a/web/src/components/PlayerProfil
e/PlayerEquipment/PlayerEquipment.astro b/we
b/src/components/PlayerProfile/PlayerEquipme
nt/PlayerEquipment.astro
index 23e627a..d52ef95 100644
--- a/web/src/components/PlayerProfile/Playe
rEquipment/PlayerEquipment.astro
+++ b/web/src/components/PlayerProfile/Playe
rEquipment/PlayerEquipment.astro
@@ -6,6 +6,7 @@ import {
   getZamimgIconUrl,
   getWowheadUrl,
 } from "../../../lib/equipment-utils";
+import ItemTooltip from "../../ItemTooltip/
ItemTooltip.astro";
 import "./PlayerEquipment.scss";
 
 interface Props {
@@ -63,9 +64,14 @@ if (equipment && Object.k
eys(equipment).length > 0) {
                 <a
                   href={href}
                   class={`equip-icon-wrap $
{qualityClass}`}
-                  title={title}
                   target="_blank"
                   rel="noopener noreferrer"
+                  data-item-id={itemId}
+                  data-item-name={title}
+                  data-quality={item.qualit
y || "COMMON"}
+                  data-enchants={JSON.strin
gify(item.enchantments || [])}
+                  data-scaling={JSON.string
ify(item.scaling_options || {})}
+                  data-spell-description={i
tem.spell_description || undefined}
                 >
                   <div class="equip-icon-in
ner">
                     {iconUrl ? (
@@ -105,4 +111,5 @@ if (equipment && Object.
keys(equipment).length > 0) {
       )
     }
   </div>
+  <ItemTooltip />
 </div>
 

diff --git a/web/src/lib/types.ts b/web/src/lib/types.ts
index 15ed8d5..7dabde9 100644
--- a/web/src/lib/types.ts
+++ b/web/src/lib/types.ts
@@ -75,6 +75,13 @@ export interface Equipment {
   [slot: string]: EquipmentItem;
 }
 
+export interface ScalingOption {
+  stats?: Record<string, number>;
+  ilvl?: number;
+  weaponDamageMin?: number;
+  weaponDamageMax?: number;
+}
+
 export interface EquipmentItem {
   id: number;
   slot_type: string;
@@ -83,6 +90,7 @@ export interface EquipmentItem {
   quality: string;
   item_icon_slug?: string;
   enchantments?: Enchantment[];
+  scaling_options?: Record<string, ScalingOption>;
 }
 
 export interface Enchantment {

diff --git a/web/src/lib/types.ts b/web/src/
lib/types.ts
index 15ed8d5..7dabde9 100644
--- a/web/src/lib/types.ts
+++ b/web/src/lib/types.ts
@@ -75,6 +75,13 @@ export interface Equipmen
t {
   [slot: string]: EquipmentItem;
 }
 
+export interface ScalingOption {
+  stats?: Record<string, number>;
+  ilvl?: number;
+  weaponDamageMin?: number;
+  weaponDamageMax?: number;
+}
+
 export interface EquipmentItem {
   id: number;
   slot_type: string;
@@ -83,6 +90,7 @@ export interface Equipment
Item {
   quality: string;
   item_icon_slug?: string;
   enchantments?: Enchantment[];
+  scaling_options?: Record<string, ScalingO
ption>;
 }
 
 export interface Enchantment {
 
[ BACK TO LOG ]
──────────────────────────────────────────────────────────────────────────────────────
OOKNET
────────────────────────────────────────────────
OOKNET