<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://deadlock.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=~2026-PurpleDynamoLeap628</id>
	<title>The Deadlock Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://deadlock.wiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=~2026-PurpleDynamoLeap628"/>
	<link rel="alternate" type="text/html" href="https://deadlock.wiki/Special:Contributions/~2026-PurpleDynamoLeap628"/>
	<updated>2026-09-01T14:26:15Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.46.0</generator>
	<entry>
		<id>https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91978</id>
		<title>Template:AbilitySection/styles.css</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91978"/>
		<updated>2026-07-12T14:44:44Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Add .ability-section-main flex rule so card + hint rail group together (gap matches existing spacing) (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Make ability name match in-game look and align with the card */&lt;br /&gt;
.ability-section-wrapper .ability-name {&lt;br /&gt;
  margin-left: 20px;&lt;br /&gt;
  font-size: 1.5rem;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  font-family: &amp;quot;Valve Occult&amp;quot;,&amp;quot;Retail Demo&amp;quot;,&amp;quot;Open Sans&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* a dirty-ish hack to recreate yellow text color on Icon next to ability name */&lt;br /&gt;
.ability-section-wrapper .ability-name img {&lt;br /&gt;
	filter: brightness(0) saturate(100%) invert(87%) sepia(17%) saturate(354%) hue-rotate(335deg) brightness(107%) contrast(104%);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Outer two-column flex wrapper */&lt;br /&gt;
.ability-section {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: row;&lt;br /&gt;
	flex-wrap: wrap;&lt;br /&gt;
	gap: 12px;&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Left column: the ability card */&lt;br /&gt;
.ability-section-card {&lt;br /&gt;
	flex: 0 1 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Card + hint rail grouped so the rail wraps together with the card and never&lt;br /&gt;
   lands on the notes&#039; line. Only rendered when hints are present.&lt;br /&gt;
   gap matches the old section gap so card/rail spacing is unchanged. */&lt;br /&gt;
.ability-section-main {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: row;&lt;br /&gt;
	flex-wrap: wrap;&lt;br /&gt;
	gap: 12px;&lt;br /&gt;
	flex: 0 1 auto;&lt;br /&gt;
	align-items: flex-start;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Right column: tabbed details panel */&lt;br /&gt;
.ability-section-details {&lt;br /&gt;
	flex: 1 1 280px;&lt;br /&gt;
	min-width: 280px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tabs {&lt;br /&gt;
	background: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tab {&lt;br /&gt;
	flex: 0;&lt;br /&gt;
	padding: 8px 32px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* make underline for active section thinner&lt;br /&gt;
   todo: can&#039;t use var for color because TemplateStyles. */ &lt;br /&gt;
.ability-section-details .tabber__tab[aria-selected=&amp;quot;true&amp;quot;] {&lt;br /&gt;
	box-shadow: inset #92e3b2 0 -1px 0 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* If there&#039;s only one section make it look less like a tab since there are no other section tabs to move to */&lt;br /&gt;
.ability-section-details .single-tabbed .tabber__tab {&lt;br /&gt;
	box-shadow: unset;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Constrain the first tab panel with a scrollbar if content overflows.&lt;br /&gt;
   Value is chosen to approximate the average ability card height — adjust if card&lt;br /&gt;
   sizes change significantly. */&lt;br /&gt;
.ability-section-details .tabber__panel:first-child {&lt;br /&gt;
	max-height: 400px;&lt;br /&gt;
	overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Section header inside Show All tab */&lt;br /&gt;
.ability-details-section-header {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 0.8rem;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.05em;&lt;br /&gt;
	color: #aaa;&lt;br /&gt;
	padding: 8px 4px 2px;&lt;br /&gt;
	border-bottom: 1px solid #444;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-details-section-header:first-child {&lt;br /&gt;
	padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Content block inside each Show All section — matches individual tab panel padding */&lt;br /&gt;
.ability-details-section-content {&lt;br /&gt;
	display: block;&lt;br /&gt;
	padding: 0 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ABILITY CARD V2 Overrides &lt;br /&gt;
Write styles here only if they are custom to AbililtySection. &lt;br /&gt;
If you want to change AbililtyCard styles everywhere go to &lt;br /&gt;
https://deadlock.wiki/Template:Ability_card_v2/Card/styles.css&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/* Hide Ability Title, it&#039;s written above as heading */&lt;br /&gt;
.ability-section .ac-title {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* move charge indicators to be on the same height as other indicators */&lt;br /&gt;
.ability-section .ac-header-right {&lt;br /&gt;
	flex-direction: row&lt;br /&gt;
}&lt;br /&gt;
.ability-section .ac-charge-row {&lt;br /&gt;
	margin-bottom: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* add some margin since title that was providing it is gone */&lt;br /&gt;
.ability-section .ac-header {&lt;br /&gt;
	margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ABILITY HINTS */&lt;br /&gt;
.ability-section-hints {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: column;&lt;br /&gt;
	gap: 6px;&lt;br /&gt;
	flex: 0 0 auto;&lt;br /&gt;
	justify-content: flex-start;&lt;br /&gt;
	padding: 3px 0;&lt;br /&gt;
	margin-left: -8px;&lt;br /&gt;
	margin-right: 8px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	display: inline-flex;&lt;br /&gt;
	align-items: center;&lt;br /&gt;
	justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint img {&lt;br /&gt;
	border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint .ability-hint-tip {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: 50%;&lt;br /&gt;
	bottom: 130%;&lt;br /&gt;
	transform: translateX(-50%);&lt;br /&gt;
	background: #1c1a1d;&lt;br /&gt;
	color: #FFEFD7;&lt;br /&gt;
	border: 1px solid #45414a;&lt;br /&gt;
	border-radius: 5px;&lt;br /&gt;
	padding: 5px 9px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	line-height: 1.3;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	opacity: 0;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
	transition: opacity .12s;&lt;br /&gt;
	z-index: 20;&lt;br /&gt;
	box-shadow: 0 4px 14px rgba(0,0,0,.5);&lt;br /&gt;
}&lt;br /&gt;
.ability-hint:hover .ability-hint-tip {&lt;br /&gt;
	opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* On narrow screens the rail wraps under the card; lay the icons out in a row&lt;br /&gt;
   there instead of a column. */&lt;br /&gt;
@media (max-width: 560px) {&lt;br /&gt;
	.ability-section-hints {&lt;br /&gt;
		flex-direction: row;&lt;br /&gt;
		flex-wrap: wrap;&lt;br /&gt;
		margin: -6px 0 0 0;&lt;br /&gt;
		padding: 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MISC */&lt;br /&gt;
&lt;br /&gt;
/* The only ability in the game with not top indicators (range/duration/cd) at all. Custom hack to cut empty space. */&lt;br /&gt;
#hero_atlas\:citadel_ability_passive_beefy .ac-header-wrapper,&lt;br /&gt;
#hero_viper\:ability_viper_snakedash .ac-header-wrapper {&lt;br /&gt;
	height: 10px;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:AbilitySection?diff=91977</id>
		<title>Module:AbilitySection</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:AbilitySection?diff=91977"/>
		<updated>2026-07-12T14:43:09Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Group card and hint rail in .ability-section-main (only when hints present) so the rail wraps with the card and never lands beside the notes (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- see /doc for docs&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
local utils           = require &amp;quot;Module:Abilities/utils&amp;quot;&lt;br /&gt;
local lang            = require &amp;quot;Module:Lang&amp;quot;&lt;br /&gt;
local icon_module     = require &amp;quot;Module:Icon&amp;quot;&lt;br /&gt;
local AbilityHints    = require &amp;quot;Module:AbilityHints&amp;quot;&lt;br /&gt;
local resource_lookup = mw.loadJsonData(&amp;quot;Data:ResourceLookup.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
-- Tab definitions — order here determines display order.&lt;br /&gt;
local TABS = {&lt;br /&gt;
	{ key = &#039;notes&#039;, label = &#039;Notes&#039; },&lt;br /&gt;
	{ key = &#039;tips&#039;,  label = &#039;Tips&#039;  },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function get_hero_key(hero_name)&lt;br /&gt;
	if hero_name == nil or hero_name == &#039;&#039; then return nil end&lt;br /&gt;
	if string.sub(hero_name, 1, 5) == &amp;quot;hero_&amp;quot; then return hero_name end&lt;br /&gt;
	local entry = resource_lookup[hero_name:lower()]&lt;br /&gt;
	if entry == nil then return nil end&lt;br /&gt;
	return entry.key&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function trim(s)&lt;br /&gt;
	return s:match(&#039;^%s*(.-)%s*$&#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function build_tabber(wikitext_map)&lt;br /&gt;
	local filled = {}&lt;br /&gt;
	for _, tab in ipairs(TABS) do&lt;br /&gt;
		if wikitext_map[tab.key] ~= &#039;&#039; then&lt;br /&gt;
			table.insert(filled, { key = tab.key, label = tab.label, wikitext = wikitext_map[tab.key] })&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	if #filled == 0 then&lt;br /&gt;
		return &#039;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local tabs = {}&lt;br /&gt;
	for _, section in ipairs(filled) do&lt;br /&gt;
		table.insert(tabs, {&lt;br /&gt;
			label   = section.label,&lt;br /&gt;
			content = &#039;&amp;lt;div class=&amp;quot;ability-details-panel&amp;quot;&amp;gt;\n&#039; .. section.wikitext .. &#039;\n&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- &amp;quot;Show All&amp;quot; tab wraps each section&#039;s wikitext in a &amp;lt;div&amp;gt; to give the parser&lt;br /&gt;
	-- a fresh block context per section, preventing html mangling.&lt;br /&gt;
	if #filled &amp;gt;= 2 then&lt;br /&gt;
		local all_parts = {}&lt;br /&gt;
		for _, section in ipairs(filled) do&lt;br /&gt;
			table.insert(all_parts,&lt;br /&gt;
				&#039;&amp;lt;div class=&amp;quot;ability-details-section-header&amp;quot;&amp;gt;&#039; .. section.label .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
				.. &#039;&amp;lt;div class=&amp;quot;ability-details-section-content&amp;quot;&amp;gt;\n&#039; .. section.wikitext .. &#039;\n&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
			)&lt;br /&gt;
		end&lt;br /&gt;
		table.insert(tabs, {&lt;br /&gt;
			label   = &#039;Show All&#039;,&lt;br /&gt;
			content = &#039;&amp;lt;div class=&amp;quot;ability-details-panel&amp;quot;&amp;gt;&#039; .. table.concat(all_parts) .. &#039;&amp;lt;/div&amp;gt;&#039;,&lt;br /&gt;
		})&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local rendered = mw.ext.tabber.render(tabs)&lt;br /&gt;
	if #filled == 1 then&lt;br /&gt;
		return &#039;&amp;lt;div class=&amp;quot;single-tabbed&amp;quot;&amp;gt;&#039; .. rendered .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
	return rendered&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Entry point. Called via {{#invoke:AbilitySection|render}}.&lt;br /&gt;
function p.render(frame)&lt;br /&gt;
	local args        = frame.args&lt;br /&gt;
	local hero_name   = trim(args.hero_name or &#039;&#039;)&lt;br /&gt;
	local ability_num = trim(args.ability_num or &#039;&#039;)&lt;br /&gt;
	local notes       = trim(args.notes or &#039;&#039;)&lt;br /&gt;
	local tips        = trim(args.tips or &#039;&#039;)&lt;br /&gt;
	local hints       = trim(args.hints or &#039;&#039;)&lt;br /&gt;
&lt;br /&gt;
	local hero_key    = get_hero_key(hero_name)&lt;br /&gt;
	local heading     = &#039;&#039;&lt;br /&gt;
	local ability_key = nil&lt;br /&gt;
	if hero_key ~= nil then&lt;br /&gt;
		local ability = utils.get_ability_card_data(hero_key, ability_num)&lt;br /&gt;
		if ability ~= nil then&lt;br /&gt;
			ability_key = ability.Key&lt;br /&gt;
			local ability_name = lang.get_string(ability.Key)&lt;br /&gt;
			-- Use the English ability key for icon render; icon module indexes by English name&lt;br /&gt;
			local ability_name_en = lang.get_string(ability.Key, &#039;en&#039;, ability.Key)&lt;br /&gt;
			local icon_html = icon_module._render(ability_name_en, { size = &#039;30px&#039;, [&#039;icon-only&#039;] = &#039;true&#039;, [&#039;no-link&#039;] = &#039;true&#039; })&lt;br /&gt;
			heading = &#039;&amp;lt;h3 class=&amp;quot;ability-name&amp;quot;&amp;gt;&#039; .. icon_html .. &#039; &#039; .. ability_name .. &#039;&amp;lt;/h3&amp;gt;&#039;&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local card = frame:expandTemplate{&lt;br /&gt;
		title = &#039;Ability card v2&#039;,&lt;br /&gt;
		args  = { hero_name = hero_name, ability_num = ability_num, link_name = &#039;false&#039; }&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	-- Ability interaction hints. Gated for staged rollout:&lt;br /&gt;
	-- delete the `hints ~= &#039;&#039;` guard to enable on all hero pages.&lt;br /&gt;
	local hints_col = &#039;&#039;&lt;br /&gt;
	if hints ~= &#039;&#039; and ability_key ~= nil then&lt;br /&gt;
		hints_col = AbilityHints.get_icons(ability_key, ability_num)&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local wikitext_map = {&lt;br /&gt;
		notes = notes,&lt;br /&gt;
		tips  = tips,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local tabber = build_tabber(wikitext_map)&lt;br /&gt;
	local details_col = &#039;&#039;&lt;br /&gt;
	if tabber ~= &#039;&#039; then&lt;br /&gt;
		details_col = &#039;&amp;lt;div class=&amp;quot;ability-section-details&amp;quot;&amp;gt;&#039; .. tabber .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	-- When hints are present, group the card and the hint rail together so the&lt;br /&gt;
	-- rail wraps together with the card (and never onto the notes&#039; line).&lt;br /&gt;
	-- Without hints the structure stays flat, so real pages are unchanged.&lt;br /&gt;
	local card_block = &#039;&amp;lt;div class=&amp;quot;ability-section-card&amp;quot;&amp;gt;&#039; .. card .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	local left_col&lt;br /&gt;
	if hints_col ~= &#039;&#039; then&lt;br /&gt;
		left_col = &#039;&amp;lt;div class=&amp;quot;ability-section-main&amp;quot;&amp;gt;&#039; .. card_block .. hints_col .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
	else&lt;br /&gt;
		left_col = card_block&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local ability_section = &#039;&amp;lt;div class=&amp;quot;ability-section&amp;quot;&amp;gt;&#039;&lt;br /&gt;
		.. left_col&lt;br /&gt;
		.. details_col&lt;br /&gt;
		.. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
	return &#039;&amp;lt;div class=&amp;quot;ability-section-wrapper&amp;quot;&amp;gt;&#039;&lt;br /&gt;
		.. heading&lt;br /&gt;
		.. ability_section&lt;br /&gt;
		.. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91973</id>
		<title>Template:AbilitySection/styles.css</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91973"/>
		<updated>2026-07-12T14:20:43Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Mobile: hints rail becomes a horizontal row on narrow screens (viewport media query; TemplateStyles lacks container queries) (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Make ability name match in-game look and align with the card */&lt;br /&gt;
.ability-section-wrapper .ability-name {&lt;br /&gt;
  margin-left: 20px;&lt;br /&gt;
  font-size: 1.5rem;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  font-family: &amp;quot;Valve Occult&amp;quot;,&amp;quot;Retail Demo&amp;quot;,&amp;quot;Open Sans&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* a dirty-ish hack to recreate yellow text color on Icon next to ability name */&lt;br /&gt;
.ability-section-wrapper .ability-name img {&lt;br /&gt;
	filter: brightness(0) saturate(100%) invert(87%) sepia(17%) saturate(354%) hue-rotate(335deg) brightness(107%) contrast(104%);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Outer two-column flex wrapper */&lt;br /&gt;
.ability-section {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: row;&lt;br /&gt;
	flex-wrap: wrap;&lt;br /&gt;
	gap: 12px;&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Left column: the ability card */&lt;br /&gt;
.ability-section-card {&lt;br /&gt;
	flex: 0 1 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Right column: tabbed details panel */&lt;br /&gt;
.ability-section-details {&lt;br /&gt;
	flex: 1 1 280px;&lt;br /&gt;
	min-width: 280px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tabs {&lt;br /&gt;
	background: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tab {&lt;br /&gt;
	flex: 0;&lt;br /&gt;
	padding: 8px 32px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* make underline for active section thinner&lt;br /&gt;
   todo: can&#039;t use var for color because TemplateStyles. */ &lt;br /&gt;
.ability-section-details .tabber__tab[aria-selected=&amp;quot;true&amp;quot;] {&lt;br /&gt;
	box-shadow: inset #92e3b2 0 -1px 0 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* If there&#039;s only one section make it look less like a tab since there are no other section tabs to move to */&lt;br /&gt;
.ability-section-details .single-tabbed .tabber__tab {&lt;br /&gt;
	box-shadow: unset;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Constrain the first tab panel with a scrollbar if content overflows.&lt;br /&gt;
   Value is chosen to approximate the average ability card height — adjust if card&lt;br /&gt;
   sizes change significantly. */&lt;br /&gt;
.ability-section-details .tabber__panel:first-child {&lt;br /&gt;
	max-height: 400px;&lt;br /&gt;
	overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Section header inside Show All tab */&lt;br /&gt;
.ability-details-section-header {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 0.8rem;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.05em;&lt;br /&gt;
	color: #aaa;&lt;br /&gt;
	padding: 8px 4px 2px;&lt;br /&gt;
	border-bottom: 1px solid #444;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-details-section-header:first-child {&lt;br /&gt;
	padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Content block inside each Show All section — matches individual tab panel padding */&lt;br /&gt;
.ability-details-section-content {&lt;br /&gt;
	display: block;&lt;br /&gt;
	padding: 0 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ABILITY CARD V2 Overrides &lt;br /&gt;
Write styles here only if they are custom to AbililtySection. &lt;br /&gt;
If you want to change AbililtyCard styles everywhere go to &lt;br /&gt;
https://deadlock.wiki/Template:Ability_card_v2/Card/styles.css&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/* Hide Ability Title, it&#039;s written above as heading */&lt;br /&gt;
.ability-section .ac-title {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* move charge indicators to be on the same height as other indicators */&lt;br /&gt;
.ability-section .ac-header-right {&lt;br /&gt;
	flex-direction: row&lt;br /&gt;
}&lt;br /&gt;
.ability-section .ac-charge-row {&lt;br /&gt;
	margin-bottom: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* add some margin since title that was providing it is gone */&lt;br /&gt;
.ability-section .ac-header {&lt;br /&gt;
	margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ABILITY HINTS */&lt;br /&gt;
.ability-section-hints {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: column;&lt;br /&gt;
	gap: 6px;&lt;br /&gt;
	flex: 0 0 auto;&lt;br /&gt;
	justify-content: flex-start;&lt;br /&gt;
	padding: 3px 0;&lt;br /&gt;
	margin-left: -6px;&lt;br /&gt;
	margin-right: 6px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	display: inline-flex;&lt;br /&gt;
	align-items: center;&lt;br /&gt;
	justify-content: center;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint img {&lt;br /&gt;
	border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint .ability-hint-tip {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: 50%;&lt;br /&gt;
	bottom: 130%;&lt;br /&gt;
	transform: translateX(-50%);&lt;br /&gt;
	background: #1c1a1d;&lt;br /&gt;
	color: #FFEFD7;&lt;br /&gt;
	border: 1px solid #45414a;&lt;br /&gt;
	border-radius: 5px;&lt;br /&gt;
	padding: 5px 9px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	line-height: 1.3;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	opacity: 0;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
	transition: opacity .12s;&lt;br /&gt;
	z-index: 20;&lt;br /&gt;
	box-shadow: 0 4px 14px rgba(0,0,0,.5);&lt;br /&gt;
}&lt;br /&gt;
.ability-hint:hover .ability-hint-tip {&lt;br /&gt;
	opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* On narrow screens the rail wraps under the card; lay the icons out in a row&lt;br /&gt;
   there instead of a column. (TemplateStyles has no container queries, so this&lt;br /&gt;
   keys off viewport width — tune the breakpoint if needed.) */&lt;br /&gt;
@media (max-width: 560px) {&lt;br /&gt;
	.ability-section-hints {&lt;br /&gt;
		flex-direction: row;&lt;br /&gt;
		flex-wrap: wrap;&lt;br /&gt;
		margin-left: 0;&lt;br /&gt;
		margin-right: 0;&lt;br /&gt;
		padding: 4px 0 0;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MISC */&lt;br /&gt;
&lt;br /&gt;
/* The only ability in the game with not top indicators (range/duration/cd) at all. Custom hack to cut empty space. */&lt;br /&gt;
#hero_atlas\:citadel_ability_passive_beefy .ac-header-wrapper,&lt;br /&gt;
#hero_viper\:ability_viper_snakedash .ac-header-wrapper {&lt;br /&gt;
	height: 10px;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:AbilityHints?diff=91971</id>
		<title>Module:AbilityHints</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:AbilityHints?diff=91971"/>
		<updated>2026-07-12T14:10:09Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Revert groups/combinations: reactivebarrier and indomitable are plain separate icons again (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Ability interaction hints: small item icons on ability cards showing how an&lt;br /&gt;
-- ability interacts with items (dispellable, reduced, blocked, etc.).&lt;br /&gt;
-- Membership is decided by Module:AbilityTable.is_member so these icons always&lt;br /&gt;
-- agree with the dynamic ability-interaction tables.&lt;br /&gt;
&lt;br /&gt;
local AbilityTable = require(&amp;quot;Module:AbilityTable&amp;quot;)&lt;br /&gt;
local icon_module  = require(&amp;quot;Module:Icon&amp;quot;)&lt;br /&gt;
local ability_data = mw.loadJsonData(&amp;quot;Data:AbilityData.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Display order. Each entry: { list = &amp;quot;...&amp;quot;, item = &amp;quot;...&amp;quot;, tip = &amp;quot;...&amp;quot; }&lt;br /&gt;
-- The icon is shown when the ability is a member of `list`.&lt;br /&gt;
local CONFIG = {&lt;br /&gt;
    { list = &amp;quot;melee&amp;quot;,           item = &amp;quot;Melee Lifesteal&amp;quot;,  tip = &amp;quot;Benefits from melee items&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;movementbased&amp;quot;,   item = &amp;quot;Slowing Hex&amp;quot;,      tip = &amp;quot;Disabled by Slowing Hex&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;debuffresist&amp;quot;,    item = &amp;quot;Debuff Reducer&amp;quot;,   tip = &amp;quot;Duration reduced by Debuff Resist&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;heal&amp;quot;,            item = &amp;quot;Healing Booster&amp;quot;,  tip = &amp;quot;Healing amplified by Healing Booster and affected by healing reduction&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;reactivebarrier&amp;quot;, item = &amp;quot;Reactive Barrier&amp;quot;, tip = &amp;quot;Triggers Reactive Barrier&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;dispelmagic&amp;quot;,     item = &amp;quot;Dispel Magic&amp;quot;,     tip = &amp;quot;Effect can be dispelled&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;indomitable&amp;quot;,     item = &amp;quot;Indomitable&amp;quot;,      tip = &amp;quot;Effect blocked by Indomitable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;unstoppable&amp;quot;,     item = &amp;quot;Unstoppable&amp;quot;,      tip = &amp;quot;Disable prevented by Unstoppable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;platedarmor&amp;quot;,     item = &amp;quot;Plated Armor&amp;quot;,     tip = &amp;quot;On-shot effect prevented by Plated Armor&amp;quot; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Renders one item icon as a title-less external link (so Page Previews / Popups&lt;br /&gt;
-- ignores it) wrapping just the image.&lt;br /&gt;
local function icon_img(item)&lt;br /&gt;
    local url = tostring(mw.uri.canonicalUrl(item))&lt;br /&gt;
    return icon_module._render(item, { size = &#039;24px&#039;, [&#039;icon-only&#039;] = &#039;true&#039;, link = url })&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- One full-size hint icon with a tooltip.&lt;br /&gt;
local function hint_icon(item, tip)&lt;br /&gt;
    return &#039;&amp;lt;span class=&amp;quot;ability-hint&amp;quot;&amp;gt;&#039; .. icon_img(item)&lt;br /&gt;
        .. &#039;&amp;lt;span class=&amp;quot;ability-hint-tip&amp;quot;&amp;gt;&#039; .. tip .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Renders the interaction icon rail for one ability.&lt;br /&gt;
--   ability_key  the ability&#039;s internal key (AbilityCards .Key)&lt;br /&gt;
--   ability_num  the ability&#039;s slot (1-4); coerced to number&lt;br /&gt;
-- Returns rail HTML, or &#039;&#039; when the ability has no interactions.&lt;br /&gt;
function p.get_icons(ability_key, ability_num)&lt;br /&gt;
    local record = ability_data[ability_key]&lt;br /&gt;
    if record == nil then return &#039;&#039; end&lt;br /&gt;
    local num = tonumber(ability_num)&lt;br /&gt;
&lt;br /&gt;
    local icons = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        if AbilityTable.is_member(def.list, record, num) then&lt;br /&gt;
            table.insert(icons, hint_icon(def.item, def.tip))&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #icons == 0 then return &#039;&#039; end&lt;br /&gt;
    return &#039;&amp;lt;div class=&amp;quot;ability-section-hints&amp;quot;&amp;gt;&#039; .. table.concat(icons) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:AbilityHints?diff=91969</id>
		<title>Module:AbilityHints</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:AbilityHints?diff=91969"/>
		<updated>2026-07-12T13:34:12Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Replace the reactive/indomitable split icon with a grouped single icon whose image and tooltip depend on which of the two lists match (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Ability interaction hints: small item icons on ability cards showing how an&lt;br /&gt;
-- ability interacts with items (dispellable, reduced, blocked, etc.).&lt;br /&gt;
-- Membership is decided by Module:AbilityTable.is_member so these icons always&lt;br /&gt;
-- agree with the dynamic ability-interaction tables.&lt;br /&gt;
&lt;br /&gt;
local AbilityTable = require(&amp;quot;Module:AbilityTable&amp;quot;)&lt;br /&gt;
local icon_module  = require(&amp;quot;Module:Icon&amp;quot;)&lt;br /&gt;
local ability_data = mw.loadJsonData(&amp;quot;Data:AbilityData.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Display order. Each entry is either:&lt;br /&gt;
--   { list = &amp;quot;...&amp;quot;, item = &amp;quot;...&amp;quot;, tip = &amp;quot;...&amp;quot; }   a single icon shown when the ability is in `list`&lt;br /&gt;
--   { group = &amp;quot;...&amp;quot; }                             a grouped relationship (see GROUPS)&lt;br /&gt;
local CONFIG = {&lt;br /&gt;
    { list = &amp;quot;melee&amp;quot;,           item = &amp;quot;Melee Lifesteal&amp;quot;,  tip = &amp;quot;Benefits from melee items&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;movementbased&amp;quot;,   item = &amp;quot;Slowing Hex&amp;quot;,      tip = &amp;quot;Disabled by Slowing Hex&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;debuffresist&amp;quot;,    item = &amp;quot;Debuff Reducer&amp;quot;,   tip = &amp;quot;Duration reduced by Debuff Resist&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;heal&amp;quot;,            item = &amp;quot;Healing Booster&amp;quot;,  tip = &amp;quot;Healing amplified by Healing Booster and affected by healing reduction&amp;quot; },&lt;br /&gt;
    { group = &amp;quot;reactive_indomitable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;dispelmagic&amp;quot;,     item = &amp;quot;Dispel Magic&amp;quot;,     tip = &amp;quot;Effect can be dispelled&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;unstoppable&amp;quot;,     item = &amp;quot;Unstoppable&amp;quot;,      tip = &amp;quot;Disable prevented by Unstoppable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;platedarmor&amp;quot;,     item = &amp;quot;Plated Armor&amp;quot;,     tip = &amp;quot;On-shot effect prevented by Plated Armor&amp;quot; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Grouped relationships: two related lists collapse into ONE full-size icon&lt;br /&gt;
-- whose item and tooltip depend on which of the two the ability matches.&lt;br /&gt;
local GROUPS = {&lt;br /&gt;
    reactive_indomitable = {&lt;br /&gt;
        a = &amp;quot;reactivebarrier&amp;quot;,&lt;br /&gt;
        b = &amp;quot;indomitable&amp;quot;,&lt;br /&gt;
        a_only = { item = &amp;quot;Reactive Barrier&amp;quot;, tip = &amp;quot;Triggers Reactive Barrier&amp;lt;br&amp;gt;does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; trigger Indomitable&amp;quot; },&lt;br /&gt;
        b_only = { item = &amp;quot;Indomitable&amp;quot;,      tip = &amp;quot;Blocked by Indomitable&amp;lt;br&amp;gt;does &amp;lt;b&amp;gt;not&amp;lt;/b&amp;gt; trigger Reactive Barrier&amp;quot; },&lt;br /&gt;
        both   = { item = &amp;quot;Reactive Barrier&amp;quot;, tip = &amp;quot;Triggers Reactive Barrier&amp;lt;br&amp;gt;Blocked by Indomitable&amp;quot; },&lt;br /&gt;
    },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Renders one item icon as a title-less external link (so Page Previews / Popups&lt;br /&gt;
-- ignores it) wrapping just the image.&lt;br /&gt;
local function icon_img(item)&lt;br /&gt;
    local url = tostring(mw.uri.canonicalUrl(item))&lt;br /&gt;
    return icon_module._render(item, { size = &#039;24px&#039;, [&#039;icon-only&#039;] = &#039;true&#039;, link = url })&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- One full-size hint icon with a tooltip.&lt;br /&gt;
local function hint_icon(item, tip)&lt;br /&gt;
    return &#039;&amp;lt;span class=&amp;quot;ability-hint&amp;quot;&amp;gt;&#039; .. icon_img(item)&lt;br /&gt;
        .. &#039;&amp;lt;span class=&amp;quot;ability-hint-tip&amp;quot;&amp;gt;&#039; .. tip .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Renders the interaction icon rail for one ability.&lt;br /&gt;
--   ability_key  the ability&#039;s internal key (AbilityCards .Key)&lt;br /&gt;
--   ability_num  the ability&#039;s slot (1-4); coerced to number&lt;br /&gt;
-- Returns rail HTML, or &#039;&#039; when the ability has no interactions.&lt;br /&gt;
function p.get_icons(ability_key, ability_num)&lt;br /&gt;
    local record = ability_data[ability_key]&lt;br /&gt;
    if record == nil then return &#039;&#039; end&lt;br /&gt;
    local num = tonumber(ability_num)&lt;br /&gt;
&lt;br /&gt;
    -- Membership for every list referenced by CONFIG or GROUPS.&lt;br /&gt;
    local member = {}&lt;br /&gt;
    local function check(list)&lt;br /&gt;
        if list ~= nil and member[list] == nil then&lt;br /&gt;
            member[list] = AbilityTable.is_member(list, record, num)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        if def.list then&lt;br /&gt;
            check(def.list)&lt;br /&gt;
        elseif def.group then&lt;br /&gt;
            local g = GROUPS[def.group]&lt;br /&gt;
            check(g.a)&lt;br /&gt;
            check(g.b)&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local icons = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        if def.group then&lt;br /&gt;
            local g = GROUPS[def.group]&lt;br /&gt;
            local ma, mb = member[g.a], member[g.b]&lt;br /&gt;
            local case&lt;br /&gt;
            if ma and mb then&lt;br /&gt;
                case = g.both&lt;br /&gt;
            elseif ma then&lt;br /&gt;
                case = g.a_only&lt;br /&gt;
            elseif mb then&lt;br /&gt;
                case = g.b_only&lt;br /&gt;
            end&lt;br /&gt;
            if case then&lt;br /&gt;
                table.insert(icons, hint_icon(case.item, case.tip))&lt;br /&gt;
            end&lt;br /&gt;
        elseif def.list and member[def.list] then&lt;br /&gt;
            table.insert(icons, hint_icon(def.item, def.tip))&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #icons == 0 then return &#039;&#039; end&lt;br /&gt;
    return &#039;&amp;lt;div class=&amp;quot;ability-section-hints&amp;quot;&amp;gt;&#039; .. table.concat(icons) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91966</id>
		<title>Template:AbilitySection/styles.css</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91966"/>
		<updated>2026-07-12T13:15:16Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Add CSS for diagonally-split combined hint icons (clip-path triangles) (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Make ability name match in-game look and align with the card */&lt;br /&gt;
.ability-section-wrapper .ability-name {&lt;br /&gt;
  margin-left: 20px;&lt;br /&gt;
  font-size: 1.5rem;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  font-family: &amp;quot;Valve Occult&amp;quot;,&amp;quot;Retail Demo&amp;quot;,&amp;quot;Open Sans&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* a dirty-ish hack to recreate yellow text color on Icon next to ability name */&lt;br /&gt;
.ability-section-wrapper .ability-name img {&lt;br /&gt;
	filter: brightness(0) saturate(100%) invert(87%) sepia(17%) saturate(354%) hue-rotate(335deg) brightness(107%) contrast(104%);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Outer two-column flex wrapper */&lt;br /&gt;
.ability-section {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: row;&lt;br /&gt;
	flex-wrap: wrap;&lt;br /&gt;
	gap: 12px;&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Left column: the ability card */&lt;br /&gt;
.ability-section-card {&lt;br /&gt;
	flex: 0 1 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Right column: tabbed details panel */&lt;br /&gt;
.ability-section-details {&lt;br /&gt;
	flex: 1 1 280px;&lt;br /&gt;
	min-width: 280px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tabs {&lt;br /&gt;
	background: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tab {&lt;br /&gt;
	flex: 0;&lt;br /&gt;
	padding: 8px 32px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* make underline for active section thinner&lt;br /&gt;
   todo: can&#039;t use var for color because TemplateStyles. */ &lt;br /&gt;
.ability-section-details .tabber__tab[aria-selected=&amp;quot;true&amp;quot;] {&lt;br /&gt;
	box-shadow: inset #92e3b2 0 -1px 0 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* If there&#039;s only one section make it look less like a tab since there are no other section tabs to move to */&lt;br /&gt;
.ability-section-details .single-tabbed .tabber__tab {&lt;br /&gt;
	box-shadow: unset;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Constrain the first tab panel with a scrollbar if content overflows.&lt;br /&gt;
   Value is chosen to approximate the average ability card height — adjust if card&lt;br /&gt;
   sizes change significantly. */&lt;br /&gt;
.ability-section-details .tabber__panel:first-child {&lt;br /&gt;
	max-height: 400px;&lt;br /&gt;
	overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Section header inside Show All tab */&lt;br /&gt;
.ability-details-section-header {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 0.8rem;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.05em;&lt;br /&gt;
	color: #aaa;&lt;br /&gt;
	padding: 8px 4px 2px;&lt;br /&gt;
	border-bottom: 1px solid #444;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-details-section-header:first-child {&lt;br /&gt;
	padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Content block inside each Show All section — matches individual tab panel padding */&lt;br /&gt;
.ability-details-section-content {&lt;br /&gt;
	display: block;&lt;br /&gt;
	padding: 0 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ABILITY CARD V2 Overrides &lt;br /&gt;
Write styles here only if they are custom to AbililtySection. &lt;br /&gt;
If you want to change AbililtyCard styles everywhere go to &lt;br /&gt;
https://deadlock.wiki/Template:Ability_card_v2/Card/styles.css&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/* Hide Ability Title, it&#039;s written above as heading */&lt;br /&gt;
.ability-section .ac-title {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* move charge indicators to be on the same height as other indicators */&lt;br /&gt;
.ability-section .ac-header-right {&lt;br /&gt;
	flex-direction: row&lt;br /&gt;
}&lt;br /&gt;
.ability-section .ac-charge-row {&lt;br /&gt;
	margin-bottom: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* add some margin since title that was providing it is gone */&lt;br /&gt;
.ability-section .ac-header {&lt;br /&gt;
	margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ABILITY HINTS */&lt;br /&gt;
.ability-section-hints {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: column;&lt;br /&gt;
	gap: 6px;&lt;br /&gt;
	flex: 0 0 auto;&lt;br /&gt;
	justify-content: flex-start;&lt;br /&gt;
	padding: 3px 0;&lt;br /&gt;
	margin-left: -6px;&lt;br /&gt;
	margin-right: 6px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	display: inline-flex;&lt;br /&gt;
	align-items: center;&lt;br /&gt;
	justify-content: center;&lt;br /&gt;
	cursor: help;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint img {&lt;br /&gt;
	border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint .ability-hint-tip {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: 50%;&lt;br /&gt;
	bottom: 130%;&lt;br /&gt;
	transform: translateX(-50%);&lt;br /&gt;
	background: #1c1a1d;&lt;br /&gt;
	color: #FFEFD7;&lt;br /&gt;
	border: 1px solid #45414a;&lt;br /&gt;
	border-radius: 5px;&lt;br /&gt;
	padding: 5px 9px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	line-height: 1.3;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	opacity: 0;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
	transition: opacity .12s;&lt;br /&gt;
	z-index: 20;&lt;br /&gt;
	box-shadow: 0 4px 14px rgba(0,0,0,.5);&lt;br /&gt;
}&lt;br /&gt;
.ability-hint:hover .ability-hint-tip {&lt;br /&gt;
	opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Combined diagonally-split hint icon (two items sharing one 24px box) */&lt;br /&gt;
.ability-hint--split {&lt;br /&gt;
	width: 24px;&lt;br /&gt;
	height: 24px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint--split .ability-hint-half {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	top: 0;&lt;br /&gt;
	left: 0;&lt;br /&gt;
	width: 24px;&lt;br /&gt;
	height: 24px;&lt;br /&gt;
	line-height: 0;&lt;br /&gt;
}&lt;br /&gt;
/* neutralise Module:Icon&#039;s inline bottom:2px nudge so the clip aligns to the box */&lt;br /&gt;
.ability-hint--split .ability-hint-half &amp;gt; span {&lt;br /&gt;
	position: static !important;&lt;br /&gt;
	bottom: auto !important;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint-half--tl {&lt;br /&gt;
	clip-path: polygon(0 0, 100% 0, 0 100%);&lt;br /&gt;
}&lt;br /&gt;
.ability-hint-half--br {&lt;br /&gt;
	clip-path: polygon(100% 0, 100% 100%, 0 100%);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MISC */&lt;br /&gt;
&lt;br /&gt;
/* The only ability in the game with not top indicators (range/duration/cd) at all. Custom hack to cut empty space. */&lt;br /&gt;
#hero_atlas\:citadel_ability_passive_beefy .ac-header-wrapper,&lt;br /&gt;
#hero_viper\:ability_viper_snakedash .ac-header-wrapper {&lt;br /&gt;
	height: 10px;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:AbilityHints?diff=91965</id>
		<title>Module:AbilityHints</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:AbilityHints?diff=91965"/>
		<updated>2026-07-12T13:14:06Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Replace reactivebarrier/indomitable suppression with a diagonally-split combined icon (clip-path); tooltip shows both notes (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Ability interaction hints: small item icons on ability cards showing how an&lt;br /&gt;
-- ability interacts with items (dispellable, reduced, blocked, etc.).&lt;br /&gt;
-- Membership is decided by Module:AbilityTable.is_member so these icons always&lt;br /&gt;
-- agree with the dynamic ability-interaction tables.&lt;br /&gt;
&lt;br /&gt;
local AbilityTable = require(&amp;quot;Module:AbilityTable&amp;quot;)&lt;br /&gt;
local icon_module  = require(&amp;quot;Module:Icon&amp;quot;)&lt;br /&gt;
local ability_data = mw.loadJsonData(&amp;quot;Data:AbilityData.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Display order. Each entry:&lt;br /&gt;
--   list           AbilityTable list name (Module:AbilityTable/Lists)&lt;br /&gt;
--   item           item whose icon represents the interaction&lt;br /&gt;
--   tip            short hover text&lt;br /&gt;
--   suppressed_by  optional: hide this icon when the named list is also a member&lt;br /&gt;
local CONFIG = {&lt;br /&gt;
    { list = &amp;quot;melee&amp;quot;,           item = &amp;quot;Melee Lifesteal&amp;quot;,  tip = &amp;quot;Benefits from melee items&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;reactivebarrier&amp;quot;, item = &amp;quot;Reactive Barrier&amp;quot;, tip = &amp;quot;Triggers Reactive Barrier&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;debuffresist&amp;quot;,    item = &amp;quot;Debuff Reducer&amp;quot;,   tip = &amp;quot;Duration reduced by Debuff Resist&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;movementbased&amp;quot;,   item = &amp;quot;Slowing Hex&amp;quot;,      tip = &amp;quot;Disabled by Slowing Hex&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;heal&amp;quot;,            item = &amp;quot;Healing Booster&amp;quot;,  tip = &amp;quot;Healing amplified by Healing Booster and affected by healing reduction&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;dispelmagic&amp;quot;,     item = &amp;quot;Dispel Magic&amp;quot;,     tip = &amp;quot;Effect can be dispelled&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;indomitable&amp;quot;,     item = &amp;quot;Indomitable&amp;quot;,      tip = &amp;quot;Effect blocked by Indomitable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;unstoppable&amp;quot;,     item = &amp;quot;Unstoppable&amp;quot;,      tip = &amp;quot;Disable prevented by Unstoppable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;platedarmor&amp;quot;,     item = &amp;quot;Plated Armor&amp;quot;,     tip = &amp;quot;Bullet effect prevented by Plated Armor&amp;quot; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Pairs that merge into ONE diagonally-split icon when BOTH match the ability:&lt;br /&gt;
-- the first list fills the upper-left triangle, the second the lower-right.&lt;br /&gt;
-- (Replaces suppressed_by for these pairs.)&lt;br /&gt;
local COMBINE = {&lt;br /&gt;
    { &amp;quot;reactivebarrier&amp;quot;, &amp;quot;indomitable&amp;quot; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local DEF_BY_LIST = {}&lt;br /&gt;
for _, def in ipairs(CONFIG) do&lt;br /&gt;
    DEF_BY_LIST[def.list] = def&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Renders one item icon as a title-less external link (so Page Previews / Popups&lt;br /&gt;
-- ignores it) wrapping just the image.&lt;br /&gt;
local function icon_img(item)&lt;br /&gt;
    local url = tostring(mw.uri.canonicalUrl(item))&lt;br /&gt;
    return icon_module._render(item, { size = &#039;24px&#039;, [&#039;icon-only&#039;] = &#039;true&#039;, link = url })&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- A normal single hint icon.&lt;br /&gt;
local function single_icon(def)&lt;br /&gt;
    return &#039;&amp;lt;span class=&amp;quot;ability-hint&amp;quot;&amp;gt;&#039; .. icon_img(def.item)&lt;br /&gt;
        .. &#039;&amp;lt;span class=&amp;quot;ability-hint-tip&amp;quot;&amp;gt;&#039; .. def.tip .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- A combined icon split along the diagonal: tl = upper-left, br = lower-right.&lt;br /&gt;
-- Each half links to its own item; the tooltip lists both notes.&lt;br /&gt;
local function split_icon(tl, br)&lt;br /&gt;
    return &#039;&amp;lt;span class=&amp;quot;ability-hint ability-hint--split&amp;quot;&amp;gt;&#039;&lt;br /&gt;
        .. &#039;&amp;lt;span class=&amp;quot;ability-hint-half ability-hint-half--tl&amp;quot;&amp;gt;&#039; .. icon_img(tl.item) .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        .. &#039;&amp;lt;span class=&amp;quot;ability-hint-half ability-hint-half--br&amp;quot;&amp;gt;&#039; .. icon_img(br.item) .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        .. &#039;&amp;lt;span class=&amp;quot;ability-hint-tip&amp;quot;&amp;gt;&#039; .. tl.tip .. &#039;&amp;lt;br&amp;gt;&#039; .. br.tip .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
        .. &#039;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
-- Renders the interaction icon rail for one ability.&lt;br /&gt;
--   ability_key  the ability&#039;s internal key (AbilityCards .Key)&lt;br /&gt;
--   ability_num  the ability&#039;s slot (1-4); coerced to number&lt;br /&gt;
-- Returns rail HTML, or &#039;&#039; when the ability has no interactions.&lt;br /&gt;
function p.get_icons(ability_key, ability_num)&lt;br /&gt;
    local record = ability_data[ability_key]&lt;br /&gt;
    if record == nil then return &#039;&#039; end&lt;br /&gt;
    local num = tonumber(ability_num)&lt;br /&gt;
&lt;br /&gt;
    local member = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        member[def.list] = AbilityTable.is_member(def.list, record, num)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    -- Resolve combos: when both lists match, the second is consumed and drawn as&lt;br /&gt;
    -- the lower-right half of the first list&#039;s icon.&lt;br /&gt;
    local split_with = {}&lt;br /&gt;
    local consumed = {}&lt;br /&gt;
    for _, c in ipairs(COMBINE) do&lt;br /&gt;
        local tl, br = c[1], c[2]&lt;br /&gt;
        if member[tl] and member[br] then&lt;br /&gt;
            split_with[tl] = br&lt;br /&gt;
            consumed[br] = true&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local icons = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        if member[def.list] and not consumed[def.list]&lt;br /&gt;
           and not (def.suppressed_by and member[def.suppressed_by]) then&lt;br /&gt;
            if split_with[def.list] then&lt;br /&gt;
                table.insert(icons, split_icon(def, DEF_BY_LIST[split_with[def.list]]))&lt;br /&gt;
            else&lt;br /&gt;
                table.insert(icons, single_icon(def))&lt;br /&gt;
            end&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #icons == 0 then return &#039;&#039; end&lt;br /&gt;
    return &#039;&amp;lt;div class=&amp;quot;ability-section-hints&amp;quot;&amp;gt;&#039; .. table.concat(icons) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:AbilityHints?diff=91949</id>
		<title>Module:AbilityHints</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:AbilityHints?diff=91949"/>
		<updated>2026-07-12T12:22:55Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Test: link hint icons via full URL so the anchor has no title attribute, which Page Previews (Popups) requires to fire — keeps click-through without the preview popup (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Ability interaction hints: small item icons on ability cards showing how an&lt;br /&gt;
-- ability interacts with items (dispellable, reduced, blocked, etc.).&lt;br /&gt;
-- Membership is decided by Module:AbilityTable.is_member so these icons always&lt;br /&gt;
-- agree with the dynamic ability-interaction tables.&lt;br /&gt;
&lt;br /&gt;
local AbilityTable = require(&amp;quot;Module:AbilityTable&amp;quot;)&lt;br /&gt;
local icon_module  = require(&amp;quot;Module:Icon&amp;quot;)&lt;br /&gt;
local ability_data = mw.loadJsonData(&amp;quot;Data:AbilityData.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Display order. Each entry:&lt;br /&gt;
--   list           AbilityTable list name (Module:AbilityTable/Lists)&lt;br /&gt;
--   item           item whose icon represents the interaction&lt;br /&gt;
--   tip            short hover text&lt;br /&gt;
--   suppressed_by  optional: hide this icon when the named list is also a member&lt;br /&gt;
local CONFIG = {&lt;br /&gt;
    { list = &amp;quot;melee&amp;quot;,           item = &amp;quot;Melee Lifesteal&amp;quot;,  tip = &amp;quot;Benefits from Melee Damage&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;reactivebarrier&amp;quot;, item = &amp;quot;Reactive Barrier&amp;quot;, tip = &amp;quot;Blocked by Reactive Barrier&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;debuffresist&amp;quot;,    item = &amp;quot;Debuff Reducer&amp;quot;,   tip = &amp;quot;Duration reduced by Debuff Reducer&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;movementbased&amp;quot;,   item = &amp;quot;Slowing Hex&amp;quot;,      tip = &amp;quot;Disabled by Slowing Hex&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;heal&amp;quot;,            item = &amp;quot;Healing Booster&amp;quot;,  tip = &amp;quot;Amplified by Healing Booster&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;dispelmagic&amp;quot;,     item = &amp;quot;Dispel Magic&amp;quot;,     tip = &amp;quot;Effect can be dispelled by Dispel Magic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;charges&amp;quot;,         item = &amp;quot;Rapid Recharge&amp;quot;,   tip = &amp;quot;Charged ability&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;divinebarrier&amp;quot;,   item = &amp;quot;Divine Barrier&amp;quot;,   tip = &amp;quot;Effect can be dispelled by Divine Barrier&amp;quot;, suppressed_by = &amp;quot;dispelmagic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;indomitable&amp;quot;,     item = &amp;quot;Indomitable&amp;quot;,      tip = &amp;quot;Duration reduced by Indomitable&amp;quot;, suppressed_by = &amp;quot;reactivebarrier&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;unstoppable&amp;quot;,     item = &amp;quot;Unstoppable&amp;quot;,      tip = &amp;quot;Prevented by Unstoppable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;cursedrelic&amp;quot;,     item = &amp;quot;Cursed Relic&amp;quot;,     tip = &amp;quot;Interrupted by Cursed Relic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;platedarmor&amp;quot;,     item = &amp;quot;Plated Armor&amp;quot;,     tip = &amp;quot;Prevented by Plated Armor&amp;quot; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Renders the interaction icon rail for one ability.&lt;br /&gt;
--   ability_key  the ability&#039;s internal key (AbilityCards .Key)&lt;br /&gt;
--   ability_num  the ability&#039;s slot (1-4); coerced to number&lt;br /&gt;
-- Returns rail HTML, or &#039;&#039; when the ability has no interactions.&lt;br /&gt;
function p.get_icons(ability_key, ability_num)&lt;br /&gt;
    local record = ability_data[ability_key]&lt;br /&gt;
    if record == nil then return &#039;&#039; end&lt;br /&gt;
    local num = tonumber(ability_num)&lt;br /&gt;
&lt;br /&gt;
    local member = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        member[def.list] = AbilityTable.is_member(def.list, record, num)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local icons = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        if member[def.list] and not (def.suppressed_by and member[def.suppressed_by]) then&lt;br /&gt;
            -- Link via a full URL so the anchor has NO title attribute — that&#039;s&lt;br /&gt;
            -- what Page Previews (Popups) keys off of — while staying clickable.&lt;br /&gt;
            local url = tostring(mw.uri.canonicalUrl(def.item))&lt;br /&gt;
            local img = icon_module._render(def.item, { size = &#039;24px&#039;, [&#039;icon-only&#039;] = &#039;true&#039;, link = url })&lt;br /&gt;
            table.insert(icons,&lt;br /&gt;
                &#039;&amp;lt;span class=&amp;quot;ability-hint&amp;quot;&amp;gt;&#039; .. img&lt;br /&gt;
                .. &#039;&amp;lt;span class=&amp;quot;ability-hint-tip&amp;quot;&amp;gt;&#039; .. def.tip .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #icons == 0 then return &#039;&#039; end&lt;br /&gt;
    return &#039;&amp;lt;div class=&amp;quot;ability-section-hints&amp;quot;&amp;gt;&#039; .. table.concat(icons) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91937</id>
		<title>Template:AbilitySection/styles.css</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91937"/>
		<updated>2026-07-12T12:16:35Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Remove dead anchor-only styles from .ability-hint now that icons are spans again (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Make ability name match in-game look and align with the card */&lt;br /&gt;
.ability-section-wrapper .ability-name {&lt;br /&gt;
  margin-left: 20px;&lt;br /&gt;
  font-size: 1.5rem;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  font-family: &amp;quot;Valve Occult&amp;quot;,&amp;quot;Retail Demo&amp;quot;,&amp;quot;Open Sans&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* a dirty-ish hack to recreate yellow text color on Icon next to ability name */&lt;br /&gt;
.ability-section-wrapper .ability-name img {&lt;br /&gt;
	filter: brightness(0) saturate(100%) invert(87%) sepia(17%) saturate(354%) hue-rotate(335deg) brightness(107%) contrast(104%);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Outer two-column flex wrapper */&lt;br /&gt;
.ability-section {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: row;&lt;br /&gt;
	flex-wrap: wrap;&lt;br /&gt;
	gap: 12px;&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Left column: the ability card */&lt;br /&gt;
.ability-section-card {&lt;br /&gt;
	flex: 0 1 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Right column: tabbed details panel */&lt;br /&gt;
.ability-section-details {&lt;br /&gt;
	flex: 1 1 280px;&lt;br /&gt;
	min-width: 280px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tabs {&lt;br /&gt;
	background: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tab {&lt;br /&gt;
	flex: 0;&lt;br /&gt;
	padding: 8px 32px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* make underline for active section thinner&lt;br /&gt;
   todo: can&#039;t use var for color because TemplateStyles. */ &lt;br /&gt;
.ability-section-details .tabber__tab[aria-selected=&amp;quot;true&amp;quot;] {&lt;br /&gt;
	box-shadow: inset #92e3b2 0 -1px 0 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* If there&#039;s only one section make it look less like a tab since there are no other section tabs to move to */&lt;br /&gt;
.ability-section-details .single-tabbed .tabber__tab {&lt;br /&gt;
	box-shadow: unset;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Constrain the first tab panel with a scrollbar if content overflows.&lt;br /&gt;
   Value is chosen to approximate the average ability card height — adjust if card&lt;br /&gt;
   sizes change significantly. */&lt;br /&gt;
.ability-section-details .tabber__panel:first-child {&lt;br /&gt;
	max-height: 400px;&lt;br /&gt;
	overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Section header inside Show All tab */&lt;br /&gt;
.ability-details-section-header {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 0.8rem;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.05em;&lt;br /&gt;
	color: #aaa;&lt;br /&gt;
	padding: 8px 4px 2px;&lt;br /&gt;
	border-bottom: 1px solid #444;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-details-section-header:first-child {&lt;br /&gt;
	padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Content block inside each Show All section — matches individual tab panel padding */&lt;br /&gt;
.ability-details-section-content {&lt;br /&gt;
	display: block;&lt;br /&gt;
	padding: 0 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ABILITY CARD V2 Overrides &lt;br /&gt;
Write styles here only if they are custom to AbililtySection. &lt;br /&gt;
If you want to change AbililtyCard styles everywhere go to &lt;br /&gt;
https://deadlock.wiki/Template:Ability_card_v2/Card/styles.css&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/* Hide Ability Title, it&#039;s written above as heading */&lt;br /&gt;
.ability-section .ac-title {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* move charge indicators to be on the same height as other indicators */&lt;br /&gt;
.ability-section .ac-header-right {&lt;br /&gt;
	flex-direction: row&lt;br /&gt;
}&lt;br /&gt;
.ability-section .ac-charge-row {&lt;br /&gt;
	margin-bottom: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* add some margin since title that was providing it is gone */&lt;br /&gt;
.ability-section .ac-header {&lt;br /&gt;
	margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ABILITY HINTS */&lt;br /&gt;
.ability-section-hints {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: column;&lt;br /&gt;
	gap: 6px;&lt;br /&gt;
	flex: 0 0 auto;&lt;br /&gt;
	justify-content: flex-start;&lt;br /&gt;
	padding: 3px 0;&lt;br /&gt;
	margin-left: -6px;&lt;br /&gt;
	margin-right: 6px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	display: inline-flex;&lt;br /&gt;
	align-items: center;&lt;br /&gt;
	justify-content: center;&lt;br /&gt;
	cursor: help;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint img {&lt;br /&gt;
	border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint .ability-hint-tip {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: 50%;&lt;br /&gt;
	bottom: 130%;&lt;br /&gt;
	transform: translateX(-50%);&lt;br /&gt;
	background: #1c1a1d;&lt;br /&gt;
	color: #FFEFD7;&lt;br /&gt;
	border: 1px solid #45414a;&lt;br /&gt;
	border-radius: 5px;&lt;br /&gt;
	padding: 5px 9px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	line-height: 1.3;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	opacity: 0;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
	transition: opacity .12s;&lt;br /&gt;
	z-index: 20;&lt;br /&gt;
	box-shadow: 0 4px 14px rgba(0,0,0,.5);&lt;br /&gt;
}&lt;br /&gt;
.ability-hint:hover .ability-hint-tip {&lt;br /&gt;
	opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MISC */&lt;br /&gt;
&lt;br /&gt;
/* The only ability in the game with not top indicators (range/duration/cd) at all. Custom hack to cut empty space. */&lt;br /&gt;
#hero_atlas\:citadel_ability_passive_beefy .ac-header-wrapper,&lt;br /&gt;
#hero_viper\:ability_viper_snakedash .ac-header-wrapper {&lt;br /&gt;
	height: 10px;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:AbilityHints?diff=91928</id>
		<title>Module:AbilityHints</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:AbilityHints?diff=91928"/>
		<updated>2026-07-12T11:54:39Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Revert to span-wrapped icons: MediaWiki escapes raw anchor tags in module output, so the custom-link approach renders as broken text. Back to the working no-link version (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Ability interaction hints: small item icons on ability cards showing how an&lt;br /&gt;
-- ability interacts with items (dispellable, reduced, blocked, etc.).&lt;br /&gt;
-- Membership is decided by Module:AbilityTable.is_member so these icons always&lt;br /&gt;
-- agree with the dynamic ability-interaction tables.&lt;br /&gt;
&lt;br /&gt;
local AbilityTable = require(&amp;quot;Module:AbilityTable&amp;quot;)&lt;br /&gt;
local icon_module  = require(&amp;quot;Module:Icon&amp;quot;)&lt;br /&gt;
local ability_data = mw.loadJsonData(&amp;quot;Data:AbilityData.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Display order. Each entry:&lt;br /&gt;
--   list           AbilityTable list name (Module:AbilityTable/Lists)&lt;br /&gt;
--   item           item whose icon represents the interaction&lt;br /&gt;
--   tip            short hover text&lt;br /&gt;
--   suppressed_by  optional: hide this icon when the named list is also a member&lt;br /&gt;
local CONFIG = {&lt;br /&gt;
    { list = &amp;quot;melee&amp;quot;,           item = &amp;quot;Melee Lifesteal&amp;quot;,  tip = &amp;quot;Benefits from Melee Damage&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;reactivebarrier&amp;quot;, item = &amp;quot;Reactive Barrier&amp;quot;, tip = &amp;quot;Blocked by Reactive Barrier&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;debuffresist&amp;quot;,    item = &amp;quot;Debuff Reducer&amp;quot;,   tip = &amp;quot;Duration reduced by Debuff Reducer&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;movementbased&amp;quot;,   item = &amp;quot;Slowing Hex&amp;quot;,      tip = &amp;quot;Disabled by Slowing Hex&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;heal&amp;quot;,            item = &amp;quot;Healing Booster&amp;quot;,  tip = &amp;quot;Amplified by Healing Booster&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;dispelmagic&amp;quot;,     item = &amp;quot;Dispel Magic&amp;quot;,     tip = &amp;quot;Effect can be dispelled by Dispel Magic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;charges&amp;quot;,         item = &amp;quot;Rapid Recharge&amp;quot;,   tip = &amp;quot;Charged ability&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;divinebarrier&amp;quot;,   item = &amp;quot;Divine Barrier&amp;quot;,   tip = &amp;quot;Effect can be dispelled by Divine Barrier&amp;quot;, suppressed_by = &amp;quot;dispelmagic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;indomitable&amp;quot;,     item = &amp;quot;Indomitable&amp;quot;,      tip = &amp;quot;Duration reduced by Indomitable&amp;quot;, suppressed_by = &amp;quot;reactivebarrier&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;unstoppable&amp;quot;,     item = &amp;quot;Unstoppable&amp;quot;,      tip = &amp;quot;Prevented by Unstoppable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;cursedrelic&amp;quot;,     item = &amp;quot;Cursed Relic&amp;quot;,     tip = &amp;quot;Interrupted by Cursed Relic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;platedarmor&amp;quot;,     item = &amp;quot;Plated Armor&amp;quot;,     tip = &amp;quot;Prevented by Plated Armor&amp;quot; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Renders the interaction icon rail for one ability.&lt;br /&gt;
--   ability_key  the ability&#039;s internal key (AbilityCards .Key)&lt;br /&gt;
--   ability_num  the ability&#039;s slot (1-4); coerced to number&lt;br /&gt;
-- Returns rail HTML, or &#039;&#039; when the ability has no interactions.&lt;br /&gt;
function p.get_icons(ability_key, ability_num)&lt;br /&gt;
    local record = ability_data[ability_key]&lt;br /&gt;
    if record == nil then return &#039;&#039; end&lt;br /&gt;
    local num = tonumber(ability_num)&lt;br /&gt;
&lt;br /&gt;
    local member = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        member[def.list] = AbilityTable.is_member(def.list, record, num)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local icons = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        if member[def.list] and not (def.suppressed_by and member[def.suppressed_by]) then&lt;br /&gt;
            local img = icon_module._render(def.item, { size = &#039;24px&#039;, [&#039;icon-only&#039;] = &#039;true&#039;, [&#039;no-link&#039;] = &#039;true&#039; })&lt;br /&gt;
            table.insert(icons,&lt;br /&gt;
                &#039;&amp;lt;span class=&amp;quot;ability-hint&amp;quot;&amp;gt;&#039; .. img&lt;br /&gt;
                .. &#039;&amp;lt;span class=&amp;quot;ability-hint-tip&amp;quot;&amp;gt;&#039; .. def.tip .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/span&amp;gt;&#039;&lt;br /&gt;
            )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #icons == 0 then return &#039;&#039; end&lt;br /&gt;
    return &#039;&amp;lt;div class=&amp;quot;ability-section-hints&amp;quot;&amp;gt;&#039; .. table.concat(icons) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91927</id>
		<title>Template:AbilitySection/styles.css</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Template:AbilitySection/styles.css?diff=91927"/>
		<updated>2026-07-12T11:51:14Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Reset link styling on hint icons now that they wrap in an anchor (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;/* Make ability name match in-game look and align with the card */&lt;br /&gt;
.ability-section-wrapper .ability-name {&lt;br /&gt;
  margin-left: 20px;&lt;br /&gt;
  font-size: 1.5rem;&lt;br /&gt;
  font-weight: normal;&lt;br /&gt;
  font-family: &amp;quot;Valve Occult&amp;quot;,&amp;quot;Retail Demo&amp;quot;,&amp;quot;Open Sans&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* a dirty-ish hack to recreate yellow text color on Icon next to ability name */&lt;br /&gt;
.ability-section-wrapper .ability-name img {&lt;br /&gt;
	filter: brightness(0) saturate(100%) invert(87%) sepia(17%) saturate(354%) hue-rotate(335deg) brightness(107%) contrast(104%);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Outer two-column flex wrapper */&lt;br /&gt;
.ability-section {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: row;&lt;br /&gt;
	flex-wrap: wrap;&lt;br /&gt;
	gap: 12px;&lt;br /&gt;
	margin-top: 4px;&lt;br /&gt;
	margin-bottom: 8px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Left column: the ability card */&lt;br /&gt;
.ability-section-card {&lt;br /&gt;
	flex: 0 1 auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Right column: tabbed details panel */&lt;br /&gt;
.ability-section-details {&lt;br /&gt;
	flex: 1 1 280px;&lt;br /&gt;
	min-width: 280px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber {&lt;br /&gt;
	margin: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tabs {&lt;br /&gt;
	background: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-section-details .tabber .tabber__tab {&lt;br /&gt;
	flex: 0;&lt;br /&gt;
	padding: 8px 32px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* make underline for active section thinner&lt;br /&gt;
   todo: can&#039;t use var for color because TemplateStyles. */ &lt;br /&gt;
.ability-section-details .tabber__tab[aria-selected=&amp;quot;true&amp;quot;] {&lt;br /&gt;
	box-shadow: inset #92e3b2 0 -1px 0 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* If there&#039;s only one section make it look less like a tab since there are no other section tabs to move to */&lt;br /&gt;
.ability-section-details .single-tabbed .tabber__tab {&lt;br /&gt;
	box-shadow: unset;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Constrain the first tab panel with a scrollbar if content overflows.&lt;br /&gt;
   Value is chosen to approximate the average ability card height — adjust if card&lt;br /&gt;
   sizes change significantly. */&lt;br /&gt;
.ability-section-details .tabber__panel:first-child {&lt;br /&gt;
	max-height: 400px;&lt;br /&gt;
	overflow-y: auto;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Section header inside Show All tab */&lt;br /&gt;
.ability-details-section-header {&lt;br /&gt;
	font-weight: bold;&lt;br /&gt;
	font-size: 0.8rem;&lt;br /&gt;
	text-transform: uppercase;&lt;br /&gt;
	letter-spacing: 0.05em;&lt;br /&gt;
	color: #aaa;&lt;br /&gt;
	padding: 8px 4px 2px;&lt;br /&gt;
	border-bottom: 1px solid #444;&lt;br /&gt;
	margin-bottom: 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
.ability-details-section-header:first-child {&lt;br /&gt;
	padding-top: 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Content block inside each Show All section — matches individual tab panel padding */&lt;br /&gt;
.ability-details-section-content {&lt;br /&gt;
	display: block;&lt;br /&gt;
	padding: 0 4px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ABILITY CARD V2 Overrides &lt;br /&gt;
Write styles here only if they are custom to AbililtySection. &lt;br /&gt;
If you want to change AbililtyCard styles everywhere go to &lt;br /&gt;
https://deadlock.wiki/Template:Ability_card_v2/Card/styles.css&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/* Hide Ability Title, it&#039;s written above as heading */&lt;br /&gt;
.ability-section .ac-title {&lt;br /&gt;
	display: none;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* move charge indicators to be on the same height as other indicators */&lt;br /&gt;
.ability-section .ac-header-right {&lt;br /&gt;
	flex-direction: row&lt;br /&gt;
}&lt;br /&gt;
.ability-section .ac-charge-row {&lt;br /&gt;
	margin-bottom: unset;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* add some margin since title that was providing it is gone */&lt;br /&gt;
.ability-section .ac-header {&lt;br /&gt;
	margin-top: 20px;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ABILITY HINTS */&lt;br /&gt;
.ability-section-hints {&lt;br /&gt;
	display: flex;&lt;br /&gt;
	flex-direction: column;&lt;br /&gt;
	gap: 6px;&lt;br /&gt;
	flex: 0 0 auto;&lt;br /&gt;
	justify-content: flex-start;&lt;br /&gt;
	padding: 3px 0;&lt;br /&gt;
	margin-left: -6px;&lt;br /&gt;
	margin-right: 6px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint {&lt;br /&gt;
	position: relative;&lt;br /&gt;
	display: inline-flex;&lt;br /&gt;
	align-items: center;&lt;br /&gt;
	justify-content: center;&lt;br /&gt;
	cursor: help;&lt;br /&gt;
	text-decoration: none;&lt;br /&gt;
	color: inherit;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint img {&lt;br /&gt;
	border-radius: 2px;&lt;br /&gt;
}&lt;br /&gt;
.ability-hint .ability-hint-tip {&lt;br /&gt;
	position: absolute;&lt;br /&gt;
	left: 50%;&lt;br /&gt;
	bottom: 130%;&lt;br /&gt;
	transform: translateX(-50%);&lt;br /&gt;
	background: #1c1a1d;&lt;br /&gt;
	color: #FFEFD7;&lt;br /&gt;
	border: 1px solid #45414a;&lt;br /&gt;
	border-radius: 5px;&lt;br /&gt;
	padding: 5px 9px;&lt;br /&gt;
	font-size: 12px;&lt;br /&gt;
	line-height: 1.3;&lt;br /&gt;
	white-space: nowrap;&lt;br /&gt;
	opacity: 0;&lt;br /&gt;
	pointer-events: none;&lt;br /&gt;
	transition: opacity .12s;&lt;br /&gt;
	z-index: 20;&lt;br /&gt;
	box-shadow: 0 4px 14px rgba(0,0,0,.5);&lt;br /&gt;
}&lt;br /&gt;
.ability-hint:hover .ability-hint-tip {&lt;br /&gt;
	opacity: 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* MISC */&lt;br /&gt;
&lt;br /&gt;
/* The only ability in the game with not top indicators (range/duration/cd) at all. Custom hack to cut empty space. */&lt;br /&gt;
#hero_atlas\:citadel_ability_passive_beefy .ac-header-wrapper,&lt;br /&gt;
#hero_viper\:ability_viper_snakedash .ac-header-wrapper {&lt;br /&gt;
	height: 10px;&lt;br /&gt;
}&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
	<entry>
		<id>https://deadlock.wiki/Module:AbilityHints?diff=91926</id>
		<title>Module:AbilityHints</title>
		<link rel="alternate" type="text/html" href="https://deadlock.wiki/Module:AbilityHints?diff=91926"/>
		<updated>2026-07-12T11:50:44Z</updated>

		<summary type="html">&lt;p&gt;~2026-PurpleDynamoLeap628: Wrap hint icons in our own link to the item page (keeps click-through while icon still renders link-free) for tooltip testing (with help from vergir-bot LLM)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;-- Ability interaction hints: small item icons on ability cards showing how an&lt;br /&gt;
-- ability interacts with items (dispellable, reduced, blocked, etc.).&lt;br /&gt;
-- Membership is decided by Module:AbilityTable.is_member so these icons always&lt;br /&gt;
-- agree with the dynamic ability-interaction tables.&lt;br /&gt;
&lt;br /&gt;
local AbilityTable = require(&amp;quot;Module:AbilityTable&amp;quot;)&lt;br /&gt;
local icon_module  = require(&amp;quot;Module:Icon&amp;quot;)&lt;br /&gt;
local ability_data = mw.loadJsonData(&amp;quot;Data:AbilityData.json&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
-- Display order. Each entry:&lt;br /&gt;
--   list           AbilityTable list name (Module:AbilityTable/Lists)&lt;br /&gt;
--   item           item whose icon represents the interaction&lt;br /&gt;
--   tip            short hover text&lt;br /&gt;
--   suppressed_by  optional: hide this icon when the named list is also a member&lt;br /&gt;
local CONFIG = {&lt;br /&gt;
    { list = &amp;quot;melee&amp;quot;,           item = &amp;quot;Melee Lifesteal&amp;quot;,  tip = &amp;quot;Benefits from Melee Damage&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;reactivebarrier&amp;quot;, item = &amp;quot;Reactive Barrier&amp;quot;, tip = &amp;quot;Blocked by Reactive Barrier&amp;quot; },&lt;br /&gt;
	{ list = &amp;quot;debuffresist&amp;quot;,    item = &amp;quot;Debuff Reducer&amp;quot;,   tip = &amp;quot;Duration reduced by Debuff Reducer&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;movementbased&amp;quot;,   item = &amp;quot;Slowing Hex&amp;quot;,      tip = &amp;quot;Disabled by Slowing Hex&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;heal&amp;quot;,            item = &amp;quot;Healing Booster&amp;quot;,  tip = &amp;quot;Amplified by Healing Booster&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;dispelmagic&amp;quot;,     item = &amp;quot;Dispel Magic&amp;quot;,     tip = &amp;quot;Effect can be dispelled by Dispel Magic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;charges&amp;quot;,         item = &amp;quot;Rapid Recharge&amp;quot;,   tip = &amp;quot;Charged ability&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;divinebarrier&amp;quot;,   item = &amp;quot;Divine Barrier&amp;quot;,   tip = &amp;quot;Effect can be dispelled by Divine Barrier&amp;quot;, suppressed_by = &amp;quot;dispelmagic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;indomitable&amp;quot;,     item = &amp;quot;Indomitable&amp;quot;,      tip = &amp;quot;Duration reduced by Indomitable&amp;quot;, suppressed_by = &amp;quot;reactivebarrier&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;unstoppable&amp;quot;,     item = &amp;quot;Unstoppable&amp;quot;,      tip = &amp;quot;Prevented by Unstoppable&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;cursedrelic&amp;quot;,     item = &amp;quot;Cursed Relic&amp;quot;,     tip = &amp;quot;Interrupted by Cursed Relic&amp;quot; },&lt;br /&gt;
    { list = &amp;quot;platedarmor&amp;quot;,     item = &amp;quot;Plated Armor&amp;quot;,     tip = &amp;quot;Prevented by Plated Armor&amp;quot; },&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
-- Renders the interaction icon rail for one ability.&lt;br /&gt;
--   ability_key  the ability&#039;s internal key (AbilityCards .Key)&lt;br /&gt;
--   ability_num  the ability&#039;s slot (1-4); coerced to number&lt;br /&gt;
-- Returns rail HTML, or &#039;&#039; when the ability has no interactions.&lt;br /&gt;
function p.get_icons(ability_key, ability_num)&lt;br /&gt;
    local record = ability_data[ability_key]&lt;br /&gt;
    if record == nil then return &#039;&#039; end&lt;br /&gt;
    local num = tonumber(ability_num)&lt;br /&gt;
&lt;br /&gt;
    local member = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        member[def.list] = AbilityTable.is_member(def.list, record, num)&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    local icons = {}&lt;br /&gt;
    for _, def in ipairs(CONFIG) do&lt;br /&gt;
        if member[def.list] and not (def.suppressed_by and member[def.suppressed_by]) then&lt;br /&gt;
            local url = tostring(mw.uri.localUrl(def.item))&lt;br /&gt;
            local img = icon_module._render(def.item, { size = &#039;24px&#039;, [&#039;icon-only&#039;] = &#039;true&#039;, [&#039;no-link&#039;] = &#039;true&#039; })&lt;br /&gt;
            table.insert(icons,&lt;br /&gt;
                &#039;&amp;lt;a class=&amp;quot;ability-hint&amp;quot; href=&amp;quot;&#039; .. url .. &#039;&amp;quot;&amp;gt;&#039; .. img&lt;br /&gt;
                .. &#039;&amp;lt;span class=&amp;quot;ability-hint-tip&amp;quot;&amp;gt;&#039; .. def.tip .. &#039;&amp;lt;/span&amp;gt;&amp;lt;/a&amp;gt;&#039;&lt;br /&gt;
            )&lt;br /&gt;
        end&lt;br /&gt;
    end&lt;br /&gt;
&lt;br /&gt;
    if #icons == 0 then return &#039;&#039; end&lt;br /&gt;
    return &#039;&amp;lt;div class=&amp;quot;ability-section-hints&amp;quot;&amp;gt;&#039; .. table.concat(icons) .. &#039;&amp;lt;/div&amp;gt;&#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>~2026-PurpleDynamoLeap628</name></author>
	</entry>
</feed>