Add accounts, presets, live sheet panel and equipment tiles

- Login with registration code, sessions, rate limiting, per-user characters
- Share characters with other users (read-only), admin CLI
- Rules presets with a Presets tab, applied/pending changes with diff in a side sheet
- Equipment as tiles with amounts, starting kit removed
- Rename nav tab to "Character", add "New character" button
- Stop tracking _to_delete/

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HJhXuLD2Z6hv3Wqeq9UL9K
This commit is contained in:
Claude
2026-10-20 20:37:09 +00:00
parent afbdc4b139
commit 5f3b2b2874
27 changed files with 857 additions and 244 deletions
+4 -4
View File
@@ -40,8 +40,8 @@ def _sheet(ch: dict, rules: dict) -> dict:
"derived_rows": [[d["name"], str(c["derived"][d["id"]])] for d in rules["derived"]],
"skill_rows": [
[s["name"], "/".join(a["short"] for a in rules["attributes"] if a["id"] in s["attrs"]),
str(s["points"]), {0: "", 1: "Proficient", 2: "Expertise"}.get(s["pips"], ""), str(s["total"])]
for s in c["skills"] if s["points"] or s["prof"] or (s["unlocked"] and s["type"] == "advanced")
str(s["points"]), {1: "Proficient", 2: "Expertise"}.get(s["pips"]) or ("" if s["usable"] else "Locked"), str(s["total"])]
for s in c["skills"]
],
"augment_rows": [[a["name"], KIND.get(a["kind"], a["kind"]), SOURCE.get(a["source"]) or "-", str(a["cost"])]
for a in c["augments"]],
@@ -92,7 +92,7 @@ def to_docx(ch: dict, rules: dict) -> bytes:
doc.add_paragraph("-")
doc.add_heading(f"Equipment (carried {c['weight']} / {c['carry_max']} kg)", 1)
if s["gear_rows"]:
table(["", "Item", "Damage / Armor / Type", "Weight"], s["gear_rows"])
table(["Category", "Item", "Damage / Armor / Type", "Weight"], s["gear_rows"])
else:
doc.add_paragraph("-")
if s["other"]:
@@ -166,7 +166,7 @@ def to_pdf(ch: dict, rules: dict) -> bytes:
el.append(Paragraph(f"Equipment (carried {c['weight']} / {c['carry_max']} kg)", h2))
if s["gear_rows"]:
el.append(tbl(["", "Item", "Damage / Armor / Type", "Weight"], s["gear_rows"], [22 * mm, 65 * mm, 55 * mm, 22 * mm]))
el.append(tbl(["Category", "Item", "Damage / Armor / Type", "Weight"], s["gear_rows"], [30 * mm, 60 * mm, 50 * mm, 22 * mm]))
else:
el.append(Paragraph("-", body))
if s["other"]: