diff --git a/crates/benilla-app/assets/ui/CharacterFrame.xml b/crates/benilla-app/assets/ui/CharacterFrame.xml
deleted file mode 100644
index 41583285..00000000
--- a/crates/benilla-app/assets/ui/CharacterFrame.xml
+++ /dev/null
@@ -1,2027 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- self:EnableMouse(true)
-
- if self.tooltip then
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(self.tooltip)
- GameTooltip:AddLine(self.tooltipSubtext, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
- GameTooltip:Show()
- end
-
- GameTooltip:Hide()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- self:SetFrameLevel(self:GetFrameLevel() + 1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -- A plain Frame isn't mouse-enabled by construction (this file's
- -- header comment) — needed THIS phase (1b) so the pane hit-tests
- -- as an OnMouseUp/OnReceiveDrag drop target (ref l.226-231).
- self:EnableMouse(true)
- self.setFacing = BenillaPaperDollModel_SetFacing
- BenillaPaperDollModel_OnLoad(self)
- BenillaSetBoothTexture(getglobal(self:GetName() .. "Texture"), "paperdoll")
-
-
- BenillaPaperDollModel_OnUpdate(self, arg1)
- BenillaPaperDollModel_OnMouseUp(self, arg1)
- AutoEquipCursorItem()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("player", "STRENGTH")
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("player", "AGILITY")
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("player", "STAMINA")
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("player", "INTELLECT")
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("player", "SPIRIT")
- GameTooltip:Hide()
-
-
-
-
-
-
- self:EnableMouse(true)
-
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(self.tooltip)
- GameTooltip:AddLine(self.tooltipSubtext, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
-
- self:EnableMouse(true)
-
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(ATTACK_TOOLTIP)
- GameTooltip:AddLine(ATTACK_TOOLTIP_SUBTEXT, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
-
- self:EnableMouse(true); self:SetWidth(99)
-
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(self.tooltip)
- GameTooltip:AddLine(self.tooltipSubtext, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
-
- self:EnableMouse(true); self:SetWidth(99)
- CharacterDamageFrame_OnEnter()
- GameTooltip:Hide()
-
-
-
-
-
-
- self:EnableMouse(true)
-
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(RANGED_ATTACK_TOOLTIP)
- GameTooltip:AddLine(ATTACK_TOOLTIP_SUBTEXT, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
-
- self:EnableMouse(true); self:SetWidth(99)
-
- if self.tooltip then
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(self.tooltip)
- GameTooltip:AddLine(self.tooltipSubtext, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
- GameTooltip:Show()
- end
-
- GameTooltip:Hide()
-
-
-
-
-
-
- self:EnableMouse(true); self:SetWidth(99)
- CharacterRangedDamageFrame_OnEnter()
- GameTooltip:Hide()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PaperDollFrame_OnLoad()
- PaperDollFrame_OnEvent(event, arg1)
- PaperDollFrame_OnShow()
-
-
-
-
- CharacterFrame_OnLoad()
- CharacterFrame_OnShow()
- CharacterFrame_OnHide()
-
-
-
diff --git a/crates/benilla-app/assets/ui/InspectFrame.xml b/crates/benilla-app/assets/ui/InspectFrame.xml
index d367391a..c53bc062 100644
--- a/crates/benilla-app/assets/ui/InspectFrame.xml
+++ b/crates/benilla-app/assets/ui/InspectFrame.xml
@@ -459,11 +459,18 @@
PlaySound("igInventoryRotateCharacter")
end
- -- The character window's twin (CharacterFrame.xml's BenillaPaperDollModel_OnUpdate — the
- -- same ref Model_OnUpdate, UIParent.lua:1444-1462, that EVERY 1.12 model pane wires:
- -- PaperDollFrame l.222-224, DressUpFrame.xml:202-204, TabardFrame.xml:406-408). Held button
+ -- The ref's own Model_OnUpdate (UIParent.lua:1444-1462), which EVERY 1.12 model pane wires:
+ -- PaperDollFrame l.222-224, DressUpFrame.xml:202-204, TabardFrame.xml:406-408. Held button
-- = half a turn per second; the 0.03 click above is the tap. The ref's held-vs-click sign
-- flip is quoted, not corrected.
+ --
+ -- **This quartet retires with this window.** The character sheet's twin of it is gone: the
+ -- migrated paper doll is a real `` driven by the reference's own
+ -- `Model_OnLoad`/`Model_Rotate*`/`Model_OnUpdate` (UIParent.xml), because `` panes
+ -- draw their booth now and carry their own facing (decision 1810). This pane is still a
+ -- booth-texture Frame, so it still needs the `frame.facing` + `*_SetFacing` shape — until
+ -- the inspect window is the reference's own, which it cannot be while 1.12 ships it as a
+ -- LoadOnDemand addon packed as `.pub`.
function BenillaInspectModel_OnUpdate(frame, elapsed)
local step = elapsed * 2 * PI * ROTATIONS_PER_SECOND
if getglobal(frame:GetName() .. "RotateLeftButton"):GetButtonState() == "PUSHED" then
diff --git a/crates/benilla-app/assets/ui/ItemSlotButtonTemplates.xml b/crates/benilla-app/assets/ui/ItemSlotButtonTemplates.xml
deleted file mode 100644
index fa8c45b1..00000000
--- a/crates/benilla-app/assets/ui/ItemSlotButtonTemplates.xml
+++ /dev/null
@@ -1,76 +0,0 @@
-
-
-
-
-
-
-
diff --git a/crates/benilla-app/assets/ui/MicroMenu.xml b/crates/benilla-app/assets/ui/MicroMenu.xml
index 7a42ab9f..97666eae 100644
--- a/crates/benilla-app/assets/ui/MicroMenu.xml
+++ b/crates/benilla-app/assets/ui/MicroMenu.xml
@@ -136,6 +136,33 @@
button:RegisterForClicks("LeftButtonUp", "RightButtonUp")
end
+ -- ref MicroButtonTooltipText (MainMenuBarMicroButtons.lua l.11-18), VERBATIM — the
+ -- reference's own two-argument form: a label and a binding ACTION name, returning the
+ -- label with the bound key in NORMAL_FONT_COLOR parentheses, or the bare label when the
+ -- action is unbound.
+ --
+ -- It lives here because this file is our `MainMenuBarMicroButtons.xml`, which is where the
+ -- reference declares it. It is not the micro bar's own helper: the stock `CharacterFrame`
+ -- tab row calls it at all five `` sites
+ -- (`MicroButtonTooltipText(TEXT(CHARACTER_INFO), "TOGGLECHARACTER0")` and its four
+ -- siblings), so migrating that window onto the chain (decision 1751) needs this name to
+ -- answer or every character-tab hover raises. `SpellBookFrame.xml` already guards on it
+ -- with `if MicroButtonTooltipText then`; that guard is now always true.
+ --
+ -- Ours below is the BUTTON-shaped variant, kept because our own micro buttons carry the
+ -- action in `button.binding` and the label in `button.label`, and because it renders the
+ -- key through the Key Bindings window's display law. The reference's version prints
+ -- `GetBindingKey`'s raw token, which is what the real client shows, so the two are not
+ -- folded together: this one is the reference's text, the other is ours.
+ function MicroButtonTooltipText(text, action)
+ if GetBindingKey(action) then
+ return text .. " " .. NORMAL_FONT_COLOR_CODE .. "(" .. GetBindingKey(action) .. ")"
+ .. FONT_COLOR_CODE_CLOSE
+ else
+ return text
+ end
+ end
+
-- ref MicroButtonTooltipText (l.11-18), the LIVE contract since 0997: `button.binding`
-- is the binding ACTION name and the key resolves through GetBindingKey at hover time
-- (rendered through the Key Bindings window's display law when it is loaded — the
diff --git a/crates/benilla-app/assets/ui/PetPaperDollFrame.xml b/crates/benilla-app/assets/ui/PetPaperDollFrame.xml
deleted file mode 100644
index 95975ae7..00000000
--- a/crates/benilla-app/assets/ui/PetPaperDollFrame.xml
+++ /dev/null
@@ -1,773 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PetExpBar_Update()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- self.setFacing = BenillaPetPaperDollModel_SetFacing
- BenillaPaperDollModel_OnLoad(self)
- BenillaSetBoothTexture(getglobal(self:GetName() .. "Texture"), "petdoll")
-
- BenillaPaperDollModel_OnUpdate(self, arg1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- self:EnableMouse(true)
-
- -- ref l.267-270, unguarded now that both halves exist (decision 1062):
- -- `GetPetFoodTypes` is a real binding and `BuildListString` is the ref's
- -- own UIParent.lua joiner, re-expressed in UIParent.xml.
- --
- -- `BuildListString()` returns NIL on an empty list and `format`'s "%s"
- -- would error on it, so the pairing matters. Two things keep it safe, and
- -- both are the reference's: this frame is shown for HUNTER pets only (the
- -- `canGainXP` block above), and in the shipped `CreatureFamily.dbc` every
- -- family with a ZERO food mask is a warlock minion or "Remote Control" —
- -- every hunter-tameable family has a real diet. `GetPetFoodTypes` is
- -- itself hunter-gated in the binary too (`0x6116e0`), so all three agree.
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(format(PET_DIET_TEMPLATE, BuildListString(GetPetFoodTypes())))
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("pet", "STRENGTH")
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("pet", "AGILITY")
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("pet", "STAMINA")
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("pet", "INTELLECT")
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
- PaperDollStatTooltip("pet", "SPIRIT")
- GameTooltip:Hide()
-
-
-
-
-
-
- self:EnableMouse(true)
-
-
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(ATTACK_TOOLTIP, 1.0, 1.0, 1.0)
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
-
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(self.tooltip)
- GameTooltip:AddLine(self.tooltipSubtext, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
-
- CharacterDamageFrame_OnEnter()
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
-
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(DEFENSE_TOOLTIP, 1.0, 1.0, 1.0)
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
- self:EnableMouse(true)
-
- GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
- GameTooltip:SetText(self.tooltip)
- GameTooltip:AddLine(self.tooltipSubtext, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, 1)
- GameTooltip:Show()
-
- GameTooltip:Hide()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- PetPaperDollFrame_OnLoad()
- PetPaperDollFrame_OnEvent()
- PetPaperDollFrame_OnShow()
- PetPaperDollFrame_OnHide()
-
-
-
diff --git a/crates/benilla-app/assets/ui/PetStable.xml b/crates/benilla-app/assets/ui/PetStable.xml
index 8629999a..6c492640 100644
--- a/crates/benilla-app/assets/ui/PetStable.xml
+++ b/crates/benilla-app/assets/ui/PetStable.xml
@@ -23,20 +23,22 @@
Named deferrals / deviations, each re-cited at its own site below:
- - **The model pane is a booth-texture stand-in, not a live ``** — the same
- 0208 §5 decision the character and pet paper dolls already ship under. The reference
- declares `` (xml l.182-280); ours is a plain
- `` whose one texture samples an app-side bake, so the widget's own script trio
- goes with the widget: `Model_OnLoad`/`Model_OnUpdate` (xml l.194-203) and the
- `DISPLAY_SIZE_CHANGED` → `this:RefreshUnit()` pair (xml l.196-200) have no analogue
- here, exactly as `PetPaperDollFrame.xml` records for its own pane. `Model_RotateLeft`/
- `Model_RotateRight` (xml l.222/241) become `BenillaPaperDollModel_RotateLeft`/`_Right`,
- the shared helpers `CharacterFrame.xml` defines.
- - The pane's booth is the `"stable"` slot in `crates/benilla-app/src/portrait`, and its yaw
- binding is `BenillaStableModel_SetFacing`, the fourth beside the paperdoll/petdoll/
- inspect three. The app resolves `GetSelectedStablePet()`'s slot into either the live
- pet's entity or — for a stabled or dismissed pet, which has no world object at all —
- the creature query's `CreatureDisplayInfo` id, and the booth mirrors whichever it got.
+ - **The model pane is the reference's own ``**
+ (xml l.182-280), and so are the four scripts on it: `Model_OnLoad`, `Model_OnUpdate`
+ and the two `Model_Rotate*` the buttons call (UIParent.xml). It was a plain ``
+ sampling a booth bake through `BenillaSetBoothTexture`, with the rotate quartet borrowed
+ from our CharacterFrame.xml — both went when the character window migrated (decision
+ 1751): the widget draws its own booth now, and the yaw the app mirrors is the pane's
+ own `SetRotation` state.
+ One thing the reference's pane does that ours still does not: `DISPLAY_SIZE_CHANGED` →
+ `this:RefreshUnit()` (xml l.196-200) is a no-op here, because the pane holds the unit
+ TOKEN and the app re-resolves it every frame — there is no cached appearance to
+ invalidate (`script/modelframe.rs`'s `RefreshUnit`).
+ - The pane's booth is the `"stable"` slot in `crates/benilla-app/src/portrait`, joined to
+ the pane by name in that module's `MODEL_PANE_BOOTHS`. The app resolves
+ `GetSelectedStablePet()`'s slot into either the live pet's entity or — for a stabled or
+ dismissed pet, which has no world object at all — the creature query's
+ `CreatureDisplayInfo` id, and the booth mirrors whichever it got.
- **`GetPetIcon()` does not exist in this client** (reference/1.12-globals.tsv has it as
an engine global; benilla has never needed it). `PetStable_Update` calls it at lua l.51
and l.161-162 and it is transcribed verbatim rather than guarded: the window's current
@@ -84,16 +86,6 @@
-- iterate 1..NUM_PET_STABLE_SLOTS and handle 0 on its own.
NUM_PET_STABLE_SLOTS = 2
- -- ── The model pane's yaw ─────────────────────────────────────────────────────────────────
- -- Every booth pane names its own engine yaw binding in `frame.setFacing`
- -- (`BenillaPaperDollModel_SetFacing`, `BenillaPetPaperDollModel_SetFacing`,
- -- `BenillaInspectModel_SetFacing`); this pane's is `BenillaStableModel_SetFacing`. The
- -- named forwarder stays because `frame.setFacing` wants a plain function value and this
- -- file's OnLoad is where the pane's own name for it belongs.
- function BenillaPetStableModel_SetFacing(radians)
- BenillaStableModel_SetFacing(radians)
- end
-
-- ── The window ──────────────────────────────────────────────────────────────────────────
-- lua l.3-9, verbatim. UNIT_PET is here because a pet summoned or dismissed while the
-- window is open changes slot 0 without the server sending a stable list.
@@ -525,40 +517,29 @@
-
+ `SetPetStablePaperdoll` at four sites, an addon may too, and the app now joins the
+ booth to the pane by that name. -->
+
-
-
-
-
-
-
-
-
-
+ TOPLEFT and the right one chained off its TOPRIGHT, calling the
+ reference's own `Model_RotateLeft`/`Model_RotateRight` (UIParent.xml). -->
-
- this.setFacing = BenillaPetStableModel_SetFacing
- BenillaPaperDollModel_OnLoad(this)
- BenillaSetBoothTexture(getglobal(this:GetName() .. "Texture"), "stable")
-
- BenillaPaperDollModel_OnUpdate(this, arg1)
+
+ Model_OnLoad()
+ Model_OnUpdate(arg1, this)
-
+
+ CHARACTERFRAME_SUBFRAMES. -->
diff --git a/crates/benilla-app/assets/ui/benilla.toc b/crates/benilla-app/assets/ui/benilla.toc
index cff4963b..ec8df4ee 100644
--- a/crates/benilla-app/assets/ui/benilla.toc
+++ b/crates/benilla-app/assets/ui/benilla.toc
@@ -74,26 +74,6 @@ Interface\FrameXML\Localization.xml
# words with `GetText("FACTION_STANDING_LABEL"..id, gender)` — and fourteen more call sites across
# FriendsFrame, StaticPopup and the quest windows are waiting behind it.
Interface\FrameXML\LocaleProperties.lua
-# ── A reference file sourced ABOVE ours, so OUR bodies win every collision ─────────────────────
-# This one is not a migrated window: it is here for one family of frame-agnostic globals that
-# addons call by name, while the window that file also drives is still ours. So it loads first and
-# our later files overwrite the names we own. (A migrated window is the other case, and sits at its
-# window's own position — `Interface\FrameXML\ContainerFrame.xml` below is the first of them.)
-#
-# PaperDollFrame.lua earns its place for ONE family: `PaperDollItemSlotButton_OnLoad`/`_OnEvent`/
-# `_OnClick`/`_Update`/`_UpdateLock`/`_OnEnter`/`_OnUpdate` — frame-agnostic in the same sense,
-# acting on `this`/`this:GetID()` through live APIs and never on a named reference window.
-# `PaperDollItemSlotButtonTemplate` and `BagSlotButtonTemplate` are declared over them
-# (ItemSlotButtonTemplates.xml), and pfUI builds its bag bar from the latter.
-#
-# Its top level is four constants (NUM_RESISTANCE_TYPES, NUM_STATS, NUM_SHOPPING_TOOLTIPS,
-# ATTACK_POWER_MAGIC_NUMBER) — nothing touches a frame at load, so sourcing it cannot raise. 18 of
-# its 29 functions collide with ours (the PaperDollFrame_Set* stat family, the two damage-frame
-# hovers, PaperDollFormatStat, PaperDollStatTooltip) and this position settles all of them the
-# documented way: CharacterFrame.xml loads far below and its bodies win. Not one of the seven
-# names we are here for is in that overlap, and our own doll slots keep calling
-# `BenillaPaperDollSlot_*`, untouched.
-Interface\FrameXML\PaperDollFrame.lua
# The reference's own second file, in its own position: TEXT/message/_ERRORMESSAGE, the
# ScriptErrors dialog, and the DialogBoxFrame + DialogButton*Texture kit it is built from.
# Straight after Fonts.xml because those are the only things it needs (GameFontRedLarge,
@@ -559,18 +539,52 @@ Interface\FrameXML\RaidWarning.xml
# (Cooldown.xml), `UIPanelCloseButton` (UIPanelTemplates.xml) — plus `parent="UIParent"`. It
# cannot load "first" the way a Lua-only sourcing had to.
Interface\FrameXML\ContainerFrame.xml
-# The reference's item-SLOT button base, `PaperDollItemSlotButtonTemplate` — published for addons
-# (pfUI builds its bag bar from what inherits it) and, since window 3, a LOAD-TIME dependency of the
-# entry directly below: stock `MainMenuBarBagButtons.xml` inherits it on all five bag buttons, and
-# an `inherits=` is resolved at load. That requirement is what moved this file up from below
-# CharacterFrame.xml, where it sat only because the chain crossed the old BagFrame -> CharacterFrame
-# the wrong way. It needs ItemButtonTemplate.xml above it for the base and Cooldown.xml for the
-# $parentCooldown the doll template carries — both far above.
+# ══ THE CHARACTER WINDOW — the reference's own, off the player's chain (decision 1751) ══
+# `CharacterFrame` + its five-tab row and portrait/name header (CharacterFrame.xml), the paper doll
+# itself — model pane, 19 equipment slots, the ammo slot, the five attributes, the melee and ranged
+# stat blocks, the five resistances (PaperDollFrame.xml) — and the pet page over the same templates
+# (PetPaperDollFrame.xml). Our `CharacterFrame.xml` (2027 lines) and `PetPaperDollFrame.xml` (773)
+# stood here and are deleted.
#
-# `BagSlotButtonTemplate` used to be declared here too, transcribed from MainMenuBarBagButtons.xml
-# because that file could not be sourced. It is sourced now, one entry down, so the reference's own
-# declaration is the live one and the copy is deleted — the whole point of the migration.
-ItemSlotButtonTemplates.xml
+# THREE FILES IN THE REFERENCE'S OWN ORDER, and every edge between them is resolved at LOAD:
+# - CharacterFrame.xml declares `CharacterFrame`, which the other two name in `parent=` (1734).
+# - PaperDollFrame.xml declares `StatFrameTemplate`, `AttributeFrameTemplate` and
+# `MagicResistanceFrameTemplate`, which PetPaperDollFrame.xml inherits on 11 frames.
+# - PaperDollFrame.xml also declares `PaperDollItemSlotButtonTemplate`, which stock
+# `MainMenuBarBagButtons.xml` below inherits on all five bag buttons.
+#
+# THAT LAST EDGE IS WHY THE BLOCK SITS HERE rather than below the bag bar where ours did.
+# `ItemSlotButtonTemplates.xml` held a transcribed copy of that template for exactly one reason:
+# our CharacterFrame.xml loaded after the bag bar and could not declare it in time. The reference's
+# own toc has no such problem (CharacterFrame 53, PaperDollFrame 54, MainMenuBarBagButtons 59), so
+# the copy is deleted and the reference's declaration is the live one — the same retirement
+# `BagSlotButtonTemplate` took one window earlier.
+#
+# `PaperDollFrame.lua` used to be a manifest line of its own, sourced far above everything so that
+# our bodies would win its 18 collisions. It arrives through PaperDollFrame.xml's own
+# `