{
  "PirateReportCog.report": {
    "details_md": "## What it does\nSubmit a player to the **Pirate Review Queue**. Mods get a compact card with the details and can approve ❇️ or reject ❌ with one click. If you include proof, it shows inline so they can decide faster.\n\n---\n\n## How to use — `/report`\nWhen you run **/report**, a small form opens:\n\n- **In-game nickname**  \n  The name they use in game. Example: `SandStalker`\n\n- **Account (Name#12345)**  \n  Must end with a `#` and **five digits**. Example: `SomeUser#12345`  \n  > If you only know the nickname, try to get the account tag too. It removes ambiguity later.\n\n- **Proof (Discord media URL — optional but strongly encouraged)**  \n  Paste a **direct Discord CDN** link so it previews nicely:\n  - Accepts: `https://cdn.discordapp.com/...` or `https://media.discordapp.net/...`\n  - Works with: **png, jpg, jpeg, gif, webp, mp4, webm, mov**\n  - How to get the link: open the image/video in Discord ➜ “Open in browser” ➜ copy the address.\n\n> **Tip:** Images appear inside the mod card. Videos are kept as a plain link above the card so the inline video player works.\n\n---\n\n## What happens after you submit\n- You get a quick **thank-you** in the channel.\n- Mods receive an embed in their review channel with ✅ and ❌.\n- There’s a **“Jump to message”** button on the mod card so they can see the original context.\n- When a mod picks ✅/❌, the card is updated to show **Approved/Rejected** (with who decided and when). The small ack message in your channel is also edited to reflect the result.\n\nIf approved, the player is added to the pirate list (threat level starts at 0 and grows with encounters).\n\n---\n\n## Rules & limits (so you don’t run into errors)\n- **Account format:** must be `Name#12345`. Five digits. No spaces at the end.\n- **Proof link:** must be a Discord media link (see above). Non-Discord links are blocked.\n- **Duplicates:** already-approved players can’t be re-reported; exact pending duplicates are blocked too.\n- **Rate limit:** one report per user every **60 seconds**.\n\nCommon messages you might see:\n- `Invalid account format` → fix to `Name#12345`.\n- `URL must be a Discord media link` → use cdn.discordapp.com or media.discordapp.net.\n- `A report for this player is already pending` → a mod is already reviewing one.\n- `This player is already in the pirate list` → no need to report again.\n\n---\n\n## Good proof examples\n- Screenshot of **names** and actions in the **event log**.\n- Short clip (10–30s) that shows **what happened** and **who did it**.\n- If the situation is complex, add a quick text summary when you submit.\n\n---\n\n## Related actions\n- **/encounter** — log a new encounter with a known pirate.  \n  Fields:\n  - *Pirate (name or account)* — `MuadDib` or `MuadDib#12345` (account preferred)\n  - *Group size* — integer ≥ 1\n  - *Kills* — integer ≥ 0 (0 = none/unknown)\n  - *Destructive?* — `yes` / `no`\n  - *Perceived Skill* — 0–5 (0 = unknown)  \n  Limits: one encounter per same pirate per reporter every **10 minutes**. These entries automatically update the pirate’s **threat level** and **encounter count**.\n\n- **/edit_pirate** *(moderators)* — update a pirate’s nickname/account.\n- **remove_pirate** *(moderators, hybrid)* — remove an approved entry.\n- **encounters_migrate_ids** *(moderators, hybrid)* — migrate old encounter identifiers.\n\n---\n\n## FAQ\n**Q: My proof link won’t accept.**  \nA: It must be a direct Discord CDN URL (ends in a known image/video extension). Open the media in browser from Discord and copy that address.\n\n**Q: I only know their nickname and it says “ambiguous”.**  \nA: Use the **account** form `Name#12345`. Nicknames can be shared.\n\n**Q: Do I have to add proof?**  \nA: Optional, but it **really** helps mods decide quickly. Screenshots are usually enough.\n",
    "brief_html": "<h3 style=\"margin:0 0 4px 0;\">What it does</h3>\n<p style=\"margin:0 0 8px 0;\">\n  Sends a player to the <strong>Pirate Review Queue</strong>. Mods get a card with ✅/❌.\n  If you include a Discord media link, it will preview for them.\n</p>\n\n<h4 style=\"margin:10px 0 4px 0;\">Quick use — <code>/report</code></h4>\n<ul style=\"margin:0 0 8px 18px;\">\n  <li><strong>In-game nickname</strong> – e.g. <code>SandStalker</code></li>\n  <li><strong>Account</strong> – must be <code>Name#12345</code> (five digits)</li>\n  <li><strong>Proof</strong> (optional, recommended) – direct Discord CDN link\n    (<code>cdn.discordapp.com</code> / <code>media.discordapp.net</code>)</li>\n</ul>\n\n<h4 style=\"margin:10px 0 4px 0;\">Limits</h4>\n<ul style=\"margin:0 0 6px 18px;\">\n  <li>1 submission per user every 60s</li>\n  <li>No duplicates (pending or already approved)</li>\n  <li>Non-Discord media links are blocked</li>\n</ul>\n\n<p style=\"margin:6px 0 0 0; color:#9ca3af;\">\n  Tip: Images show inside the card; videos stay as a link so the inline player works.\n</p>\n",
    "details_html": "<h2 style=\"margin-top:0;\">Submit a pirate report</h2>\n<p>\n  Use <code>/report</code> to send a player to the <strong>Pirate Review Queue</strong>.\n  Mods see a compact card with your info and can approve or reject with one click.\n</p>\n\n<h3>Form fields</h3>\n<ul>\n  <li><strong>In-game nickname</strong><br>\n      The name they use in game. Example: <code>SandStalker</code></li>\n  <li><strong>Account (Name#12345)</strong><br>\n      Must end with <code>#</code> + <strong>five digits</strong>. Example: <code>SomeUser#12345</code><br>\n      If you only know the nickname, try to grab the account too – it prevents ambiguity.</li>\n  <li><strong>Proof (Discord media URL)</strong> – optional but highly encouraged<br>\n      Use a direct Discord CDN link so it previews: <code>https://cdn.discordapp.com/…</code> or\n      <code>https://media.discordapp.net/…</code><br>\n      Allowed: <em>png, jpg, jpeg, gif, webp, mp4, webm, mov</em>.<br>\n      How to get it: open the media in Discord → “Open in browser” → copy the address.</li>\n</ul>\n\n<h3>What happens next</h3>\n<ol>\n  <li>You get a short “thanks” message in the channel.</li>\n  <li>Mods receive an embed with ✅/❌. If you added an image, it shows inside the card.\n      If it’s a video, the URL is kept above the card so the inline player works.</li>\n  <li>A “Jump to message” button lets mods see your original context quickly.</li>\n  <li>When a mod decides, the card updates to show <em>Approved/Rejected</em> with who and when.\n      Your small ack message in the channel is edited to reflect the result.</li>\n  <li>If approved, the player is added to the pirate list (threat level starts at 0).</li>\n</ol>\n\n<h3>Rules & common errors</h3>\n<ul>\n  <li><strong>Account format</strong> must be <code>Name#12345</code>. Five digits – no spaces at the end.</li>\n  <li><strong>Proof link</strong> must be a Discord media URL. Non-Discord links are blocked.</li>\n  <li><strong>Duplicates</strong> are blocked (already pending or already approved).</li>\n  <li><strong>Rate limit</strong>: one report per user every 60 seconds.</li>\n</ul>\n<p style=\"color:#9ca3af\">\n  Typical messages: “Invalid account format”, “URL must be a Discord media link”, “A report for this player is already pending”.\n</p>\n\n<h3>Related actions</h3>\n<ul>\n  <li><code>/encounter</code> – log a new encounter with a known pirate (updates threat level over time).</li>\n  <li><code>/edit_pirate</code> (mods) – update a pirate’s nickname/account.</li>\n  <li><code>remove_pirate</code> (mods, hybrid) – remove an entry.</li>\n</ul>\n"
  },
  "PirateReportCog.encounter": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/encounter</code></h2>\n\n<p>Log a pirate encounter so threat scores stay fresh. Takes ~10 seconds.</p>\n\n<ul>\n  <li><b>Pirate</b> — account (<code>Name#12345</code>) or exact character name.<br>\n      <small>Account is best. Character name must be unambiguous.</small></li>\n  <li><b>Group size</b> — integer ≥ 1 (how many pirates in that group, including them).</li>\n  <li><b>Kills</b> — integer ≥ 0 (0 if none/unknown).</li>\n  <li><b>Destructive?</b> — yes/no (e.g., base or ornithopter destroyed).</li>\n  <li><b>Perceived Skill</b> — 0–5 (0 = unknown).</li>\n</ul>\n\n<p><b>Rate limit:</b> you can report the <i>same</i> pirate once every <b>10 minutes</b>.</p>\n\n<div style=\"margin-top:.75rem\">\n  <div class=\"usage\">/encounter MuadDib#12345 · group 3 · kills 1 · destructive yes · skill 4</div>\n  <div class=\"usage\" style=\"margin-top:.4rem\">/encounter SandStalker · group 5 · kills 0 · destructive no · skill 2</div>\n</div>\n\n<p style=\"margin-top:.75rem\"><small>After you submit, you’ll get a private “Encounter recorded” message and the pirate list updates shortly after.</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<p>\n  <code>/encounter</code> adds a single encounter to the pirate’s history. These entries feed the\n  threat score so the pirate list reflects how dangerous someone actually is right now.\n</p>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Form fields</h2>\n<ul>\n  <li><b>Pirate (name or account)</b><br>\n      Best: <code>Name#12345</code>. If you only know the character name, it must match exactly and not be ambiguous.\n  </li>\n  <li><b>Group size</b><br>\n      Integer <b>≥ 1</b>. How many pirates were in their group, including the reported pirate.\n  </li>\n  <li><b>Kills</b><br>\n      Integer <b>≥ 0</b>. Use 0 for none/unknown.\n  </li>\n  <li><b>Destructive?</b><br>\n      <code>yes</code>/<code>no</code>. “Yes” if a base/ornithopter was destroyed, etc.\n  </li>\n  <li><b>Perceived Skill</b><br>\n      <b>0–5</b>. Use 0 if you’re unsure. 5 = cracked aim/sweaty movement, 1–2 = casual.\n  </li>\n</ul>\n\n<div class=\"usage\" style=\"margin:.6rem 0 0\">\n  /encounter MuadDib#12345 · group 3 · kills 1 · destructive yes · skill 4\n</div>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Validation & messages</h2>\n<ul>\n  <li>If the account format is wrong, you’ll be told what to fix (<code>Name#12345</code> ending with five digits).</li>\n  <li>Character names must be an exact match. If multiple pirates share that name, you’ll be asked to use the account.</li>\n  <li><b>Rate limit:</b> one report per user per pirate every <b>10 minutes</b>.</li>\n  <li>You’ll see a private <b>“Encounter recorded”</b> confirmation on success.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">How threat is calculated (short)</h2>\n<p>\n  Each encounter contributes to a weighted score (0–100):\n</p>\n<ul>\n  <li><b>Kills</b>: higher if the pirate gets kills.</li>\n  <li><b>Destructive</b>: higher if they destroy stuff.</li>\n  <li><b>Group size</b>: higher if they roll with <code>group ≥ T</code> (T comes from config).</li>\n  <li><b>Skill</b>: your 0–5 rating normalized and averaged across encounters.</li>\n</ul>\n<p>\n  The weights are configurable (defaults: Kill 0.35, Destruction 0.30, Group 0.20, Skill 0.15). After you submit,\n  the bot recomputes the pirate’s <b>threat level</b> and <b>encounter count</b>, then refreshes the list.\n</p>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Tips</h2>\n<ul>\n  <li>Use the account (<code>Name#12345</code>) whenever possible — it guarantees the report hits the right person.</li>\n  <li>If you can’t tell skill, leave it at 0. That’s fine.</li>\n  <li>Group size includes the pirate you’re reporting.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Common errors</h2>\n<ul>\n  <li><b>“No such pirate registered.”</b> — Ask a mod to add them, or submit a <code>/report</code> first.</li>\n  <li><b>“Character name is ambiguous.”</b> — Use the account tag (<code>Name#12345</code>).</li>\n  <li><b>“You can only report the same pirate once every 10 minutes.”</b> — Wait a bit and try again.</li>\n</ul>\n"
  },
  "PirateReportCog.edit_pirate": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/edit_pirate</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n\n<p>Edit an existing pirate entry. Use this when a player changes nickname or account tag.</p>\n\n<ul>\n  <li><b>Current account</b> — the exact existing account in the list (<code>Name#12345</code>).</li>\n  <li><b>New in-game nickname</b> — optional.</li>\n  <li><b>New account</b> — optional, must be <code>Name#12345</code>.</li>\n</ul>\n\n<div class=\"usage\" style=\"margin-top:.75rem\">/edit_pirate</div>\n\n<p style=\"margin-top:.6rem\"><small>\n  You must provide <b>at least one</b> of: new nickname or new account.<br>\n  The account format is strict: <code>#</code> + <b>five digits</b>. Duplicate accounts are blocked.\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<p>\n  Updates a pirate record that’s already approved. Typical cases: the player renamed their character,\n  or moved to a new account tag.\n</p>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Form fields</h2>\n<ul>\n  <li><b>Current account</b> — must match exactly what’s in the list (e.g., <code>SomeUser#12345</code>).</li>\n  <li><b>New in-game nickname</b> — optional; leave empty to keep the current one.</li>\n  <li><b>New account</b> — optional; must be <code>Name#12345</code>. If the new value already exists on another pirate, it’s rejected.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Rules & feedback</h2>\n<ul>\n  <li><b>Moderator-only.</b></li>\n  <li>You must change at least one thing (nickname or account).</li>\n  <li>On success you’ll see “✅ Pirate updated.” (ephemeral) and the public list refreshes.</li>\n  <li>A short mod-log entry is posted for audit (“✏️ Edited pirate …”).</li>\n</ul>\n"
  },
  "PirateReportCog.encounters_migrate_ids": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/encounters_migrate_ids</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n\n<p>\n  Converts old encounter records stored by <b>character name</b> to the\n  canonical <b>account</b> (<code>Name#12345</code>).\n</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/encounters_migrate_ids</div>\n\n<p style=\"margin-top:.6rem\"><small>\n  Useful after adding pirates where past encounters referenced only nicknames.\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<p>\n  Scans stored encounters and rewrites any identifier that is a <b>character name</b> to the correct\n  <b>account</b> for that pirate. Keeps data consistent for threat calculations.\n</p>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">How matching works</h2>\n<ul>\n  <li>If the encounter already uses an account (<code>#</code> + five digits), it’s counted as “already accounts”.</li>\n  <li>If the character name maps to exactly one pirate, it’s updated to that pirate’s account.</li>\n  <li>If there’s no pirate with that name, it’s counted as “not found”.</li>\n  <li>If multiple pirates share the same nickname, it’s “ambiguous” and skipped.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Result</h2>\n<ul>\n  <li>Replies with a compact summary (updated / already / ambiguous / not found).</li>\n  <li>Refreshes the public pirate list afterwards.</li>\n</ul>\n\n<p style=\"margin-top:.6rem\"><small>\n  <b>Moderator-only.</b>\n</small></p>\n"
  },
  "PirateReportCog.remove_pirate": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/remove_pirate</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n\n<p>Remove a pirate from the approved list by <b>account</b>.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/remove_pirate account_name:&nbsp;<code>Name#12345</code></div>\n\n<p style=\"margin-top:.6rem\"><small>\n  Account format must be <code>Name#12345</code>. If the account isn’t found, you’ll get “Pirate not found.”\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<p>Deletes the matching pirate record from the approved list.</p>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Parameters</h2>\n<ul>\n  <li><b>account_name</b> — exact account tag (<code>Name#12345</code>).</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Behavior & messages</h2>\n<ul>\n  <li><b>Moderator-only.</b></li>\n  <li>If no match: “Pirate not found.”</li>\n  <li>On success: “Removed.” (ephemeral via slash).</li>\n  <li>Mod-log note is posted (“🗑️ Removed pirate …”) and the public list refreshes.</li>\n</ul>\n"
  },
  "AutoVCCog.avc_cleanup_now": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/avc_cleanup_now</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n<p>Immediately deletes empty Auto-VC rooms that have been idle past the configured delay, then renumbers the rest.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/avc_cleanup_now</div>\n\n<p style=\"margin-top:.6rem\"><small>\n  Replies “Cleanup pass complete.” on success.\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<ul>\n  <li>Scans the target category for <b>managed</b> Auto-VC rooms.</li>\n  <li>Deletes rooms that have been <b>empty</b> for at least the configured <b>delay</b> (seconds).</li>\n  <li>Renumbers remaining rooms to a clean sequence (<code>Prefix 1..N</code>).</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">When to use</h2>\n<ul>\n  <li>After a busy period to tidy up stale empties.</li>\n  <li>If numbering looks off and you want a quick clean + renumber in one go.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Permissions & notes</h2>\n<ul>\n  <li><b>Moderator-only.</b></li>\n  <li>Bot needs: <b>Manage Channels</b>, <b>Connect</b>, and <b>Move Members</b> in the target category to function smoothly.</li>\n  <li>Safe to run anytime. The bot pauses the background sweeper while this runs to avoid conflicts.</li>\n</ul>\n"
  },
  "AutoVCCog.avc_renumber": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/avc_renumber</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n<p>Force a rename of all managed rooms to a clean numeric order without deleting anything.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/avc_renumber</div>\n\n<p style=\"margin-top:.6rem\"><small>\n  Replies “Renumbered.” on success.\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<p>Renames tracked rooms to <code>{prefix} 1</code>, <code>{prefix} 2</code>, … in creation order. No rooms are deleted.</p>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">When to use</h2>\n<ul>\n  <li>Numbering drifted after manual edits or channel deletions.</li>\n  <li>You changed the name prefix and want all rooms aligned quickly.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Permissions & notes</h2>\n<ul>\n  <li><b>Moderator-only.</b></li>\n  <li>Bot needs <b>Manage Channels</b> to rename rooms.</li>\n  <li>Safe to run anytime; the bot sequences this against its background sweeper.</li>\n</ul>\n"
  },
  "AutoVCCog.avc_status": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/avc_status</code></h2>\n<p>Shows current Auto-VC setup and the list of managed rooms.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/avc_status</div>\n\n<p style=\"margin-top:.6rem\"><small>\n  Output includes trigger channel, target category, name prefix, cleanup delay, and each tracked room with its current state.\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it shows</h2>\n<ul>\n  <li><b>Trigger</b> — the voice channel that spawns new rooms.</li>\n  <li><b>Category</b> — where new rooms are created.</li>\n  <li><b>Prefix</b> — base name (e.g. <code>Room</code> → <code>Room 1</code>, <code>Room 2</code>…).</li>\n  <li><b>Delay</b> — seconds a room must stay empty before cleanup can delete it.</li>\n  <li><b>Tracked rooms</b> — each room’s name and whether it’s empty or how many are inside. If a room is empty, an “idle Ns” timer may appear.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Example output</h2>\n<pre style=\"white-space:pre-wrap;margin:.25rem 0 0\">\nAuto-VC status:\nTrigger: &lt;#1234567890&gt; | Category: &lt;#2345678901&gt; | Prefix: `Room` | Delay: 30s\n- #1: Room 1 — 3 inside\n- #2: Room 2 — empty | idle 12s\n</pre>\n\n<p style=\"margin-top:.75rem\"><small>\n  This command is read-only and safe to run anytime.\n</small></p>\n"
  },
  "NickNudgeCog.clear_nick_reviews": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/clear_nick_reviews</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n<p>Delete all <b>pending</b> nickname review records for this server.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/clear_nick_reviews</div>\n\n<p style=\"margin-top:.6rem\"><small>\nReplies with how many pending entries were removed (ephemeral).\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<ul>\n  <li>Removes every <b>pending</b> entry in the nickname review queue for this server.</li>\n  <li>Does <u>not</u> touch approved/rejected history or verification flags.</li>\n  <li>Useful when the queue got noisy or stuck after a busy period.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Result</h2>\n<p>\n  Shows: <code>Cleared N pending nickname review(s).</code> (ephemeral)\n</p>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Permissions & notes</h2>\n<ul>\n  <li><b>Moderator-only.</b></li>\n  <li>Writes a short entry to the mod log (if configured).</li>\n</ul>\n"
  },
  "NickNudgeCog.recreate_nick_review": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/recreate_nick_review</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n<p>Recreate a <b>single</b> user’s missing pending review.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/recreate_nick_review <b>user:</b> @Member</div>\n\n<p style=\"margin-top:.6rem\"><small>\nIf they’re already verified or already have a pending review, you’ll get a short explanation instead (ephemeral).\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<ul>\n  <li>Checks the selected member:</li>\n  <ul>\n    <li>If <b>already verified</b> → no action.</li>\n    <li>If a <b>pending review exists</b> → no action.</li>\n    <li>Else → marks them as claimed (if needed) and opens a new pending review in the mod channel.</li>\n  </ul>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">When to use</h2>\n<ul>\n  <li>One user fell through the cracks and needs a review opened again.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Permissions & notes</h2>\n<ul>\n  <li><b>Moderator-only.</b></li>\n  <li>Logs to the mod log (if configured) with who triggered it.</li>\n  <li>Reply is ephemeral.</li>\n</ul>\n"
  },
  "NickNudgeCog.recreate_nick_reviews": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/recreate_nick_reviews</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n<p>Scan the server and recreate any <b>missing</b> pending reviews for users who claimed but never got a review opened.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/recreate_nick_reviews</div>\n\n<p style=\"margin-top:.6rem\"><small>\nReplies: <code>Recreated X review(s); skipped Y.</code> (ephemeral)\n</small></p>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<ul>\n  <li>Looks at users who <b>claimed</b> nickname compliance but are <u>not verified</u> and have <u>no pending review</u>.</li>\n  <li>Opens a fresh review in the mod channel for each such user (one per user, no duplicates).</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">When to use</h2>\n<ul>\n  <li>After a restart/outage where some pending reviews may have gone missing.</li>\n  <li>Whenever you see “claimed” users without an open review.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Permissions & notes</h2>\n<ul>\n  <li><b>Moderator-only.</b></li>\n  <li>Posts a summary to the mod log (if configured).</li>\n  <li>Only processes this server; other servers are unaffected.</li>\n</ul>\n"
  },
  "PiratesListCog.pirates_list_refresh": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/pirates_list_refresh</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n<p>Rebuild the compact pirates list in the configured channel. Use this after adding/removing pirates or when encounter stats change.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/pirates_list_refresh</div>\n\n<ul style=\"margin:.6rem 0 0 1rem\">\n  <li>Replies: <code>Pirates list refreshed.</code> (ephemeral)</li>\n  <li>Runs per-guild cooldown: 10s</li>\n</ul>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<ul>\n  <li>Builds a compact, alphabetized list of verified pirates and posts it in the configured list channel.</li>\n  <li>Entries are chunked to stay under Discord’s 2000-character limit; old chunks are edited or deleted as needed.</li>\n  <li>No one gets pinged — all content is sanitized to avoid accidental mentions.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Entry format</h2>\n<pre style=\"margin:.5rem 0;white-space:pre-wrap\">\n- <b>Character</b> (<i>Account#12345</i>) [Threat%]\n  - In group: <i>bucket</i>. Destructive: <i>bucket</i>. Encounters: N. Last: &lt;t:UNIX:R&gt;\n</pre>\n<ul>\n  <li><b>Threat%</b> reflects combined encounter signals (kills, destructive behavior, group size, skill).</li>\n  <li><b>In group / Destructive</b> use buckets: <code>unknown</code>, <code>never</code>, <code>rarely</code>, <code>sometimes</code>, <code>often</code>, <code>always</code>.</li>\n  <li><b>Last</b> shows the most recent encounter as a relative timestamp.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">When to use</h2>\n<ul>\n  <li>After a new pirate is approved or removed.</li>\n  <li>After logging encounters that meaningfully change threat or buckets.</li>\n  <li>When the list looks stale or out of order.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Behavior & notes</h2>\n<ul>\n  <li>Sorts by character name, then account.</li>\n  <li>If there are no pirates yet, shows a single placeholder line.</li>\n  <li>If the list channel isn’t configured or can’t be found, nothing is posted (check your config).</li>\n  <li>Per-guild cooldown: 10 seconds (prevents spam).</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Config that affects output</h2>\n<ul>\n  <li><code>pirates_list_channel_id</code> — where the list is posted.</li>\n  <li><code>threat_group_threshold</code> — minimum party size that counts as “in group”.</li>\n  <li><code>threat_min_samples_for_stats</code> — encounters needed before buckets stop showing <code>unknown</code>.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Permissions</h2>\n<ul>\n  <li><b>Moderator-only.</b></li>\n  <li>Bot needs permission to read and write in the list channel.</li>\n</ul>\n"
  },
  "PowerActionsCog.power_restart": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/power restart</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n<p>Safely restarts the bot after logging a clear reason to the modlog.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/power restart reason:\"Restarting to enable new permissions sync after config change\"</div>\n\n<ul style=\"margin:.6rem 0 0 1rem\">\n  <li>Requires a descriptive reason (see details).</li>\n  <li>Replies: <code>🔁 Restart requested — logging to modlog and restarting…</code> (ephemeral)</li>\n  <li>Bot restarts a couple seconds after the reply.</li>\n</ul>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<ul>\n  <li>Checks you’re a moderator, validates your reason, and posts a restart entry to the modlog (who, when, version, reason).</li>\n  <li>Closes the bot cleanly and exits; your process manager/container brings it back up.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Reason requirements</h2>\n<p>The <code>reason</code> must be specific enough to audit later:</p>\n<ul>\n  <li>At least <b>20 characters</b></li>\n  <li>At least <b>4 words</b></li>\n  <li>At least <b>3 words</b> with length ≥ 3</li>\n  <li>Rejects vague phrases like: <code>stuck</code>, <code>idk</code>, <code>don't know</code>, <code>unknown</code>, <code>?</code>,\n      <code>lag</code>, <code>restart</code>, <code>restarting</code>, <code>update</code>, <code>updating</code>,\n      <code>bug</code>, <code>crash</code>, <code>crashed</code></li>\n</ul>\n\n<h3 style=\"margin:.75rem 0 .4rem\">Examples</h3>\n<div style=\"display:grid; gap:.5rem\">\n  <div>\n    <div style=\"font-weight:600\">✅ Good</div>\n    <pre style=\"margin:.25rem 0;white-space:pre-wrap\">/power restart reason:\"Reloading cogs after changing threat weights and enabling nick loop; avoids inconsistent state.\"</pre>\n  </div>\n  <div>\n    <div style=\"font-weight:600\">❌ Bad</div>\n    <pre style=\"margin:.25rem 0;white-space:pre-wrap\">/power restart reason:\"update\"</pre>\n  </div>\n</div>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">What you’ll see</h2>\n<ul>\n  <li>Ephemeral confirmation in chat.</li>\n  <li>Modlog post similar to:\n    <pre style=\"margin:.4rem 0;white-space:pre-wrap\">🔁 Bot Restart Requested\nBy: @YourName\nWhen: 2025-01-01 12:34 UTC\nRunning version: vX.Y.Z\nReason: Reloading cogs after threat weight change…</pre>\n  </li>\n  <li>Bot goes offline briefly, then comes back once the host restarts it.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Config that affects it</h2>\n<ul>\n  <li><code>modlog_channel_id</code> — where the restart entry is posted. If not set, it falls back to server logs only.</li>\n  <li><code>home_guild_id</code> — where the <code>/power</code> group is registered (home-guild only vs global).</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Permissions</h2>\n<ul>\n  <li><b>Moderator-only.</b> Non-mods are blocked with an ephemeral message.</li>\n  <li>Bot just needs permission to send messages in the modlog channel.</li>\n</ul>\n"
  },
  "PowerActionsCog.restart": {
    "brief_html": "<h2 style=\"margin:0 0 .5rem 0\">Quick usage — <code>/power restart</code> <small style=\"opacity:.8\">[Moderator]</small></h2>\n<p>Safely restarts the bot after logging a clear reason to the modlog.</p>\n\n<div class=\"usage\" style=\"margin-top:.5rem\">/power restart reason:\"Restarting to enable new permissions sync after config change\"</div>\n\n<ul style=\"margin:.6rem 0 0 1rem\">\n  <li>Requires a descriptive reason (see details).</li>\n  <li>Replies: <code>🔁 Restart requested — logging to modlog and restarting…</code> (ephemeral)</li>\n  <li>Bot restarts a couple seconds after the reply.</li>\n</ul>\n",
    "details_html": "<h2 style=\"margin:0 0 .5rem 0\">What it does</h2>\n<ul>\n  <li>Checks you’re a moderator, validates your reason, and posts a restart entry to the modlog (who, when, version, reason).</li>\n  <li>Closes the bot cleanly and exits; your process manager/container brings it back up.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Reason requirements</h2>\n<p>The <code>reason</code> must be specific enough to audit later:</p>\n<ul>\n  <li>At least <b>20 characters</b></li>\n  <li>At least <b>4 words</b></li>\n  <li>At least <b>3 words</b> with length ≥ 3</li>\n  <li>Rejects vague phrases like: <code>stuck</code>, <code>idk</code>, <code>don't know</code>, <code>unknown</code>, <code>?</code>,\n      <code>lag</code>, <code>restart</code>, <code>restarting</code>, <code>update</code>, <code>updating</code>,\n      <code>bug</code>, <code>crash</code>, <code>crashed</code></li>\n</ul>\n\n<h3 style=\"margin:.75rem 0 .4rem\">Examples</h3>\n<div style=\"display:grid; gap:.5rem\">\n  <div>\n    <div style=\"font-weight:600\">✅ Good</div>\n    <pre style=\"margin:.25rem 0;white-space:pre-wrap\">/power restart reason:\"Reloading cogs after changing threat weights and enabling nick loop; avoids inconsistent state.\"</pre>\n  </div>\n  <div>\n    <div style=\"font-weight:600\">❌ Bad</div>\n    <pre style=\"margin:.25rem 0;white-space:pre-wrap\">/power restart reason:\"update\"</pre>\n  </div>\n</div>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">What you’ll see</h2>\n<ul>\n  <li>Ephemeral confirmation in chat.</li>\n  <li>Modlog post similar to:\n    <pre style=\"margin:.4rem 0;white-space:pre-wrap\">🔁 Bot Restart Requested\nBy: @YourName\nWhen: 2025-01-01 12:34 UTC\nRunning version: vX.Y.Z\nReason: Reloading cogs after threat weight change…</pre>\n  </li>\n  <li>Bot goes offline briefly, then comes back once the host restarts it.</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Config that affects it</h2>\n<ul>\n  <li><code>modlog_channel_id</code> — where the restart entry is posted. If not set, it falls back to server logs only.</li>\n  <li><code>home_guild_id</code> — where the <code>/power</code> group is registered (home-guild only vs global).</li>\n</ul>\n\n<hr>\n\n<h2 style=\"margin:.75rem 0 .5rem\">Permissions</h2>\n<ul>\n  <li><b>Moderator-only.</b> Non-mods are blocked with an ephemeral message.</li>\n  <li>Bot just needs permission to send messages in the modlog channel.</li>\n</ul>\n"
  },
  "ReactionRoleCog.nick_same": {
    "brief_html": "<h2>/nick_same</h2>\n<p><strong>Nick matches my in-game name.</strong> Tells mods your current <em>server nickname</em> (or global display name if you haven’t set one) already matches your in-game name, and opens a quick review.</p>\n\n<h3>Usage</h3>\n<pre>/nick_same</pre>\n\n<ul>\n  <li>You’ll get an <em>ephemeral</em> “thanks” message.</li>\n  <li>Moderators get a review with ✅ / ❌ in the mod channel.</li>\n  <li><strong>Full Access</strong> is granted automatically when you have: Rules ✅ + Engagement ✅ + this nickname claim (pending or verified).</li>\n</ul>\n\n<h3>Tips</h3>\n<ul>\n  <li>Run it in the server (not in DMs).</li>\n  <li>If you recently changed your nick, this will trigger a re-review.</li>\n  <li>Alternative: react ✅ on the “Nickname” rules message to claim the same thing.</li>\n</ul>\n",
    "details_html": "<h1>/nick_same — Nickname claim</h1>\n<p>Use this when your <strong>server nickname</strong> already matches your in-game character name. It opens a moderator review so you can get (or keep) access without typing anything else.</p>\n\n<h2>What it does</h2>\n<ul>\n  <li>Marks your nickname as <em>claimed</em> and opens exactly <strong>one</strong> pending review for moderators.</li>\n  <li>You’ll see a short <em>ephemeral</em> confirmation in the channel.</li>\n  <li>Moderators get a message in the mod channel with ✅ Approve / ❌ Reject.</li>\n  <li><strong>Full Access</strong> is granted automatically when you have: Rules ✅ + Engagement ✅ + Nickname <em>claimed</em> (pending or verified).</li>\n</ul>\n\n<h2>How to use</h2>\n<pre>/nick_same</pre>\n<ul>\n  <li>Run it in the server, any channel where you can use slash commands.</li>\n  <li>No extra arguments. If your display name already matches the game name, that’s enough.</li>\n</ul>\n\n<h2>Typical flow</h2>\n<ol>\n  <li><strong>You</strong> run <code>/nick_same</code>. The bot replies “Thanks — your nickname claim was sent for moderator review.”</li>\n  <li><strong>Mods</strong> see a review card with your previous nick (if known) and the current one.</li>\n  <li>They press ✅ to verify or ❌ to reject. You keep (or lose) Full Access depending on Rules/Engagement and the result.</li>\n</ol>\n\n<h2>Good to know</h2>\n<ul>\n  <li>If a verified user changes their nickname later, verification is <strong>automatically revoked</strong>. Just run <code>/nick_same</code> again (or react ✅ on the nickname message) to re-claim and re-review.</li>\n  <li>The command is idempotent: if a review is already pending, it won’t open duplicates.</li>\n  <li>Alternative path: reacting ✅ on the <em>Nickname</em> rules message triggers the same review and access checks.</li>\n</ul>\n\n<h2>Troubleshooting</h2>\n<ul>\n  <li><strong>No response?</strong> Make sure you used it inside the server (not DMs) and that slash commands are allowed in the channel.</li>\n  <li><strong>Still no Full Access?</strong> You need all three: Rules ✅, Engagement ✅, and a nickname claim (pending or verified). Missing any one will remove the role.</li>\n  <li><strong>Mods didn’t get a review?</strong> Ping a moderator; the mod channel might be misconfigured.</li>\n</ul>\n"
  },
  "SpicePayCog.spicepay": {
    "brief_html": "<h2>/spicepay</h2>\n<p><strong>Open the Spice Pay wizard.</strong> Step through participants, roles, payout type (Sand or Melange), and weighting. Shows a live preview and lets you post the result.</p>\n\n<h3>Usage</h3>\n<pre>/spicepay [participants] [force_new]</pre>\n<ul>\n  <li><code>participants</code> (optional): total people, incl. owners (1–25).</li>\n  <li><code>force_new</code> (optional): start fresh if you already have a session.</li>\n</ul>\n\n<h3>Quick flow</h3>\n<ol>\n  <li>Enter the total yield and participant count.</li>\n  <li>Add/edit each participant (name, active %, owner roles).</li>\n  <li>Toggle payout: Sand ⟷ Melange (set refinery yield for Melange).</li>\n  <li>Adjust weighting factors or use a preset.</li>\n  <li>Finish → preview → Post to channel.</li>\n</ol>\n\n<h3>Notes</h3>\n<ul>\n  <li>0% active = owner-only (gets owner perks but didn’t actively join).</li>\n  <li>Melange: exactly one <em>Refiner</em> owner is required.</li>\n  <li>Rounding leftovers go to Refiner (Melange) or top earner (Sand).</li>\n</ul>",
    "details_html": "<h1>/spicepay — Guided payout</h1>\n<p>Calculate a fair split for a spice run. The wizard keeps things simple and transparent for the team.</p>\n\n<h2>Start</h2>\n<pre>/spicepay [participants] [force_new]</pre>\n<ul>\n  <li>If <code>participants</code> is omitted, you set it in the first modal (1–25).</li>\n  <li>Use <code>force_new: true</code> to discard an existing session and start clean.</li>\n</ul>\n\n<h2>Setup modal</h2>\n<ul>\n  <li><strong>Total spice yield (sand)</strong> — integer ≥ 0.</li>\n  <li><strong>Participants</strong> — include <em>owners</em> (Refiner/Carrier/Crawler). People only; vehicles/refinery are <em>owned</em> by people.</li>\n</ul>\n\n<h2>Editing participants</h2>\n<p>For each slot:</p>\n<ul>\n  <li><strong>Name</strong> — free text (mention text is fine).</li>\n  <li><strong>Active %</strong> — 0–100. <em>0% = owner-only</em> (didn’t actively join).</li>\n  <li><strong>Owner of</strong> (optional) — any of: <code>refiner</code>, <code>carrier</code>, <code>crawler</code>. Flexible input (e.g. “lsr”, “refinery”, “car”, “cr”).</li>\n</ul>\n<p>Use <em>Add / Edit participant</em>, <em>Previous/Next</em> to navigate. The preview shows filled vs. empty slots and highlights “owner-only”.</p>\n\n<h2>Payout type</h2>\n<ul>\n  <li><strong>Sand</strong> — no refinery cut; 0 or 1 Refiner owner allowed.</li>\n  <li><strong>Melange</strong> — <em>requires exactly one</em> Refiner owner. First a refinery cut % is taken and paid to the Refiner, then the rest is split.</li>\n</ul>\n<p>When switching to <strong>Melange</strong>, set the refinery yield (integer) in the modal.</p>\n\n<h2>Weighting (the math, simplified)</h2>\n<ul>\n  <li>Each person gets a <em>weight</em>: <strong>Base × Active%</strong> + bonuses for owning <strong>Carrier</strong>/<strong>Crawler</strong>.</li>\n  <li>We split the pot <em>proportionally</em> by weights (they’re normalized; only ratios matter).</li>\n  <li>Melange only: take <strong>Refinery cut %</strong> first → Refiner. Any rounding leftovers go to Refiner (Melange) or top earner (Sand).</li>\n</ul>\n\n<h3>Controls</h3>\n<ul>\n  <li><em>Toggle payout: Sand/Melange</em> — switches mode (prompts for refinery yield on Melange).</li>\n  <li><em>Adjust weighting factors</em> — change:\n    <ul>\n      <li><strong>Base × active %</strong> (default <em>server setting</em>)</li>\n      <li><strong>Carrier bonus</strong> ( + )</li>\n      <li><strong>Crawler bonus</strong> ( + )</li>\n      <li><strong>Refinery cut %</strong> (Melange only)</li>\n    </ul>\n  </li>\n  <li><em>Weights help</em> — short explanation inline.</li>\n  <li><em>Presets</em> — Owner-heavy / Participation-heavy / Fair (server defaults) / Even split.</li>\n  <li><em>Save as my defaults</em> — stores your weights for future runs (per user).</li>\n  <li><em>Finish</em> — shows a neat preview (table) and lets you <em>Post to channel</em>.</li>\n</ul>\n\n<h2>Validation & limits</h2>\n<ul>\n  <li>Participants: 1–25.</li>\n  <li>Active %: 0–100.</li>\n  <li>Melange: exactly one Refiner owner required; Sand: 0 or 1 allowed.</li>\n  <li>No duplicate names (duplicates are auto-disambiguated in preview).</li>\n</ul>\n\n<h2>Posting</h2>\n<p>The post includes:</p>\n<ul>\n  <li>Header (Sand or Melange) with the chosen emoji.</li>\n  <li>Weighting summary (Base, bonuses, and refinery cut if Melange).</li>\n  <li>A clean monospace table: Name · Active% · Owner of/Role · Amount.</li>\n</ul>\n<p><em>Footnote:</em> “0% = owner only”.</p>\n"
  },
  "SpicePayCog.spicepay_cancel": {
    "brief_html": "<h2>/spicepay_cancel</h2>\n<p><strong>Cancel your active Spice Pay session.</strong> Clears everything for you so you can start fresh.</p>\n\n<h3>Usage</h3>\n<pre>/spicepay_cancel</pre>\n\n<ul>\n  <li>Removes your in-memory session (does not post anything).</li>\n  <li>Run <code>/spicepay</code> again to start over.</li>\n</ul>\n",
    "details_html": "<h1>/spicepay_cancel — Cancel session</h1>\n<p>Discards your current wizard state. Handy if you mis-entered totals or want to restructure the roster.</p>\n\n<h2>What it does</h2>\n<ul>\n  <li>Deletes your session (you + this server).</li>\n  <li>Nothing is posted publicly.</li>\n</ul>\n\n<h2>Next steps</h2>\n<p>Run <code>/spicepay</code> to start again. You can optionally pass <code>participants</code> or just set them in the first modal.</p>\n"
  },
  "SpicePayCog.spicepay_config": {
    "brief_html": "<h2>/spicepay_config</h2>\n<p><strong>Show server SpicePay weights.</strong> Read-only view of the defaults the wizard uses.</p>\n\n<h3>Usage</h3>\n<pre>/spicepay_config</pre>\n\n<ul>\n  <li>Displays: Refinery cut %, Base × active %, Carrier bonus, Crawler bonus.</li>\n  <li>Change via ENV/INI; restart the bot to apply.</li>\n</ul>\n",
    "details_html": "<h1>/spicepay_config — Server weights</h1>\n<p>Shows the current default weighting used by the Spice Pay wizard.</p>\n\n<h2>Fields</h2>\n<ul>\n  <li><strong>Refinery cut %</strong> (Melange only) — percent taken first and paid to the Refiner owner.</li>\n  <li><strong>Base × active %</strong> — the core share, scaled by each player’s active participation.</li>\n  <li><strong>Carrier bonus</strong> — flat weight added if the person owns the carrier.</li>\n  <li><strong>Crawler bonus</strong> — flat weight added if the person owns the crawler.</li>\n</ul>\n\n<h2>Where to change</h2>\n<p>Configure via environment variables or your INI, then restart the bot. The wizard’s <em>Adjust weighting factors</em> lets users override per-run; those don’t change the server defaults.</p>\n\n<h2>Tips</h2>\n<ul>\n  <li>Use <em>Presets</em> in the wizard to quickly switch philosophy (owner-heavy, participation-heavy, etc.).</li>\n  <li>Users can <em>Save as my defaults</em> to keep their personal weights for future runs.</li>\n</ul>\n"
  },
  "SpicePayCog.spicepay_resume": {
    "brief_html": "<h2>/spicepay_resume</h2>\n<p><strong>Reopen your active Spice Pay session.</strong> Useful if you closed the wizard message by accident.</p>\n\n<h3>Usage</h3>\n<pre>/spicepay_resume</pre>\n\n<ul>\n  <li>If a session exists, the wizard view is shown again.</li>\n  <li>If not, you’ll be told to run <code>/spicepay</code>.</li>\n</ul>\n",
    "details_html": "<h1>/spicepay_resume — Resume wizard</h1>\n<p>Brings back the current session UI (if you already started one with <code>/spicepay</code>).</p>\n\n<h2>When to use</h2>\n<ul>\n  <li>You dismissed the ephemeral wizard message and want it back.</li>\n  <li>You’re mid-entry and don’t want to start over.</li>\n</ul>\n\n<h2>Behavior</h2>\n<ul>\n  <li>If a session exists (keyed to you + this server), it re-renders the progress view.</li>\n  <li>If none exists, you get a friendly nudge to start a new one.</li>\n</ul>\n"
  },
  "help": {
    "brief_html": "<h2>!help</h2>\n<p>Show a quick overview of commands or details about a specific command.</p>\n\n<h3>Usage</h3>\n<pre>!help\n!help spicepay\n!help pirate\n!help encounter</pre>\n\n<ul>\n  <li>Add a word to narrow down the list (e.g., <code>!help spice</code>).</li>\n</ul>\n",
    "details_html": "<h1>!help — Command help &amp; search</h1>\n<p>Use <code>!help</code> to see what the bot can do, or pass a keyword/command to jump straight to specifics.</p>\n\n<h2>What it does</h2>\n<ul>\n  <li>Lists available commands you can run here.</li>\n  <li>Filters by a keyword (partial matches work).</li>\n  <li>When supported, shows usage and a short explanation for a specific command.</li>\n</ul>\n\n<h2>How to use it</h2>\n<ol>\n  <li><strong>Overview:</strong> <code>!help</code> — shows a concise command list.</li>\n  <li><strong>Filter:</strong> <code>!help spice</code> — narrows to commands that match “spice”.</li>\n  <li><strong>Exact command:</strong> <code>!help encounter</code> — shows usage for a single command if available.</li>\n</ol>\n\n<h2>Examples</h2>\n<pre>!help\n!help pirate\n!help spicepay\n!help encounter</pre>\n\n<h2>Notes &amp; tips</h2>\n<ul>\n  <li>If you don’t get any results, try a simpler keyword (e.g., <em>“spice”</em> instead of <em>“spicepay resume”</em>).</li>\n</ul>\n\n<h2>Troubleshooting</h2>\n<ul>\n  <li><em>“No such command”</em> — Check your spelling or try a broader keyword.</li>\n</ul>\n"
  },
  "PirateCardsCog.pirate_cards_rebuild": {
    "brief_html": "<h2>/pirate_cards_rebuild</h2>\n<p><strong>Rebuild or update pirate cards</strong> for every known pirate in the configured channel.</p>\n\n<h3>Usage</h3>\n<pre>/pirate_cards_rebuild</pre>\n\n<ul>\n  <li><strong>Moderator-only</strong>.</li>\n  <li>Run in a server channel. The reply is ephemeral.</li>\n</ul>\n\n<h3>What it does</h3>\n<ul>\n  <li>Creates or updates one embed “card” per pirate in the pirates list channel.</li>\n  <li>Each card shows Account, Threat %, grouping/destructive behavior buckets, encounters count, and last seen date.</li>\n  <li>Card color reflects threat (unknown → gray; low → green; high → red).</li>\n</ul>\n",
    "details_html": "<h1>/pirate_cards_rebuild — Rebuild all pirate cards</h1>\n<p>Runs a full pass that makes sure each verified pirate has a fresh, accurate card in the configured channel.</p>\n\n<h2>Access</h2>\n<ul>\n  <li><strong>Moderator-only</strong>.</li>\n  <li>Must be used in a server channel (not DMs). The confirmation is sent <em>ephemerally</em>.</li>\n</ul>\n\n<h2>What it updates</h2>\n<ul>\n  <li><strong>Card fields</strong>: Account name, Threat %, “In groups” bucket, “Destructive” bucket, total encounters, and last encounter date (UTC).</li>\n  <li><strong>Colors</strong>: Unknown samples → dark gray. Otherwise a green→red gradient based on Threat %.</li>\n  <li><strong>Safety</strong>: User-provided names are escaped and mentions are neutralized (no pings).</li>\n</ul>\n\n<h2>Behavior</h2>\n<ol>\n  <li>For each pirate in the internal list:\n    <ul>\n      <li>If their card already exists, it edits the embed in place.</li>\n      <li>If it can’t find the message, it posts a new card and records the message ID.</li>\n    </ul>\n  </li>\n  <li>Works serially per guild to avoid race conditions.</li>\n</ol>\n\n<h2>Output</h2>\n<p>Ephemeral summary, e.g.:</p>\n<pre>Rebuilt/updated 27 pirate cards.</pre>\n\n<h2>Setup notes</h2>\n<ul>\n  <li>Uses <code>pirates_list_channel_id</code> for the destination channel.</li>\n  <li>Threat %, group/destructive buckets, and last seen are computed from stored encounters.</li>\n  <li>Bucket thresholds respect your server settings (e.g., <code>threat_group_threshold</code>, <code>threat_min_samples_for_stats</code>).</li>\n</ul>\n\n<h2>When to run it</h2>\n<ul>\n  <li>After importing or migrating data.</li>\n  <li>After a batch of new pirates is approved.</li>\n  <li>Any time the cards look out of date.</li>\n</ul>\n"
  },
  "UserCardsCog.usercards_rescan": {
    "brief_html": "<h2>/usercards_rescan</h2>\n<p><strong>Re-check everyone and refresh the user cards.</strong> Also repairs Roles/RoE/nickname claims from the live reaction messages, and re-opens any missing nickname reviews.</p>\n\n<h3>Usage</h3>\n<pre>/usercards_rescan</pre>\n\n<ul>\n  <li><strong>Moderator-only</strong> (requires <em>Manage Server</em>).</li>\n  <li>Runs in the server; reply is ephemeral with a short summary.</li>\n</ul>\n\n<h3>What it does</h3>\n<ul>\n  <li>Reconciles from the configured Rules / RoE / Nickname reaction messages.</li>\n  <li>Grants/removes the Rules &amp; RoE roles to match reactions.</li>\n  <li>For Nickname: opens a pending review if someone claimed but no review exists.</li>\n  <li>Rebuilds/updates every user’s status card in the list channel.</li>\n</ul>\n",
    "details_html": "<h1>/usercards_rescan — Reconcile & refresh all cards</h1>\n<p>One-shot maintenance pass that makes the server’s user cards match reality.</p>\n\n<h2>Access</h2>\n<ul>\n  <li><strong>Moderator-only</strong> — requires the Discord permission <em>Manage Server</em>.</li>\n  <li>Must be used in a server channel (not DMs). The result is sent <em>ephemerally</em>.</li>\n</ul>\n\n<h2>What it fixes</h2>\n<ol>\n  <li><strong>Rules / RoE agreement</strong>\n    <ul>\n      <liReads reactions from your configured Rules and RoE messages.</li>\n      <li>Adds/removes the corresponding roles so roles match the reactions.</li>\n    </ul>\n  </li>\n  <li><strong>Nickname claim &amp; reviews</strong>\n    <ul>\n      <li>If a member has an “accept” reaction on the Nickname message but has <em>no</em> pending/verified record and <em>no</em> open review, it opens a <em>pending nickname review</em> for them.</li>\n      <li>If a member <em>removed</em> their Nickname reaction, it clears any pending/verified state.</li>\n    </ul>\n  </li>\n  <li><strong>User cards</strong>\n    <ul>\n      <li>Updates (or recreates) the embed for each member in the configured “users list” channel.</li>\n      <li>Card color reflects: Rules, RoE, and Nickname status (✅ verified / ✔️ pending / ❌ not done).</li>\n      <li>Uses a stable footer marker (<code>UID:&lt;id&gt;</code>) to find/edit the right card; cleans up duplicates.</li>\n    </ul>\n  </li>\n</ol>\n\n<h2>Expected output</h2>\n<p>The command replies (ephemeral) with counts like:</p>\n<pre>Reconciled from messages. Changes — Rules: 3, RoE: 2, Nickname (added): 1, Nickname (removed): 0. Refreshed cards for 154 members.</pre>\n\n<h2>Setup notes</h2>\n<ul>\n  <li>Relies on your configured IDs (ENV/INI): Rules/RoE/Nickname message IDs and their role IDs, the Full Access role, the user-cards channel, and the mod/modlog channels.</li>\n  <li>Won’t ping anyone; all posts/edits are sent with <em>no mentions</em>.</li>\n</ul>\n\n<h2>Tips</h2>\n<ul>\n  <li>Run after importing a server, restoring from backup, or after downtime.</li>\n  <li>Large servers: this may take a moment while it walks members and edits cards. It’s safe to run again.</li>\n</ul>\n"
  }
}