/* Data loader + helpers */

const ABILITIES = ["STR", "DEX", "CON", "INT", "WIS", "CHA"];
const ABILITY_LABELS = {
  STR: "Strength", DEX: "Dexterity", CON: "Constitution",
  INT: "Intellect", WIS: "Wisdom", CHA: "Charisma",
};
const STANDARD_ARRAY = [15, 14, 13, 12, 10, 8];

const SKILL_ABILITY = {
  acrobatics: "DEX", animal_handling: "WIS", arcana: "INT",
  athletics: "STR", deception: "CHA", history: "INT",
  insight: "WIS", intimidation: "CHA", investigation: "INT",
  medicine: "WIS", nature: "INT", perception: "WIS",
  performance: "CHA", persuasion: "CHA", religion: "INT",
  sleight_of_hand: "DEX", stealth: "DEX", survival: "WIS",
};

const SKILL_LABEL = {
  acrobatics: "Acrobatics", animal_handling: "Animal Handling", arcana: "Arcana",
  athletics: "Athletics", deception: "Deception", history: "History",
  insight: "Insight", intimidation: "Intimidation", investigation: "Investigation",
  medicine: "Medicine", nature: "Nature", perception: "Perception",
  performance: "Performance", persuasion: "Persuasion", religion: "Religion",
  sleight_of_hand: "Sleight of Hand", stealth: "Stealth", survival: "Survival",
};

// Skill descriptions, framed in Theriapolis's clade-vocabulary so hover hints
// match the rest of the codex's tone.
const SKILL_DESC = {
  acrobatics:      "Tumbling, balance, and the kind of footwork that keeps you upright on a coliseum sand-floor or a warren-rope. Body-cunning under pressure.",
  animal_handling: "Reading and steering non-sentient beasts — feral hounds, draft-kine, the wild cousins of your own clade. Calming, herding, riding.",
  arcana:          "Knowledge of the older magics: scent-sorcery, blood-sigil, the half-forgotten rites that pre-date the Covenant of Claws.",
  athletics:       "Raw physical effort. Climbing scaffold, swimming the foul canal, hauling a packmate from the pit, breaking a hold.",
  deception:       "Speaking convincingly past your scent. The art of the false posture, the planted rumor, the answer that is technically true.",
  history:         "The long memory of Theriapolis — the Imperium's fall, the Compact's ratification, which clade owes which other a centuries-old debt.",
  insight:         "Reading another's true posture beneath their words. Catching the off-note in a snarl, the held breath, the lie in a friendly tail.",
  intimidation:    "Bared-teeth diplomacy. The threat made plain enough that violence is not required to extract compliance.",
  investigation:   "Methodical search and inference: scene-reading, document-sifting, the patient accumulation of small facts into a verdict.",
  medicine:        "Field surgery, poultice-craft, knowing which clade tolerates which tincture. Stabilizing the dying without finishing them.",
  nature:          "Knowledge of the wild outside the city wall — terrain, weather, plant-lore, and the unsigned beasts that observe no Covenant.",
  perception:      "Awareness through every sense your clade gives you: ear-cock, scent-prickle, the half-glimpsed shape at the edge of vision.",
  performance:     "Holding an audience — coliseum crowd, courtroom gallery, market square. Song, oratory, the body that compels watching.",
  persuasion:      "Open-handed argument. The case made on its merits, the appeal to mutual benefit, the patient construction of agreement.",
  religion:        "The hymn-cycles of the Cervid liturgy, the Compact's sacred clauses, the small household rites your clade keeps without thinking.",
  sleight_of_hand: "Quiet fingers — pickpocketing, palmed coins, the swap performed under another's nose. Useful in markets and courtrooms alike.",
  stealth:         "Movement unseen and unsmelled. Wind-checking, scent-suppression, the slow weight-shift on a creaking floor.",
  survival:        "Field-craft beyond the wall: tracking, foraging, fire-making, knowing which run-off is safe to drink and which carries the upstream butcher's leavings.",
};

const SIZE_LABEL = {
  small: "Small", medium: "Medium", medium_large: "Medium-Large", large: "Large",
};

// Class → recommended clades (informational, per design intent)
const CLASS_CLADE_REC = {
  fangsworn:        ["canidae", "felidae", "ursidae"],
  bulwark:          ["bovidae", "ursidae"],
  feral:            ["ursidae", "mustelidae", "bovidae"],
  shadow_pelt:      ["felidae", "mustelidae", "leporidae"],
  scent_broker:     ["canidae", "mustelidae"],
  covenant_keeper:  ["canidae", "bovidae", "cervidae"],
  muzzle_speaker:   ["felidae", "leporidae"],
  claw_wright:      ["mustelidae", "leporidae"],
};

// Language metadata — name + description for hover hints
const LANGUAGES = {
  common:   { name: "Common",   description: "The market-and-courthouse trade tongue of Theriapolis. Spoken by every clade; the language of contracts, guard-watches, and most of the city's signage." },
  canid:    { name: "Canid",    description: "Pack-tongue of the Canidae. Heavy with subsonic registers and scent-words — Canid sentences carry pheromonal undertones non-Canid speakers cannot fully parse." },
  felid:    { name: "Felid",    description: "Sinuous and tonal, with a parallel tail-and-ear pidgin. Felid speakers trade in implication and pause; lying in Felid is a high art." },
  mustelid: { name: "Mustelid", description: "Quick, percussive trade-speech of the Mustelidae. Famous for its dense vocabulary of musks, debts, and small grievances." },
  ursid:    { name: "Ursid",    description: "Slow, low-register growl-speech. Ursid grammar prefers final emphasis — the important word always comes last." },
  cervid:   { name: "Cervid",   description: "Old, hymn-shaped tongue of the Cervidae. Most speakers know Cervid as a song-language for funerals, treaties, and the long calendar." },
  bovid:    { name: "Bovid",    description: "Patient, formal speech of the herd-clades. Bovid is the language of guild-councils and oaths; lying in formal Bovid is itself a punishable act." },
  leporid:  { name: "Leporid",  description: "Rapid, twitch-paced chatter of the Leporidae. Leporid uses tense markers for danger and runs faster than most non-Leporidae can follow." },
};

// Pretty item names from item ids
const ITEM_NAME = {
  rend_sword: "Rend-sword", chain_shirt: "Chain Shirt", buckler: "Buckler",
  healers_kit: "Healer's Kit", rations_predator: "Rations (predator)",
  rations_prey: "Rations (prey)", hoof_club: "Hoof Club", chain_mail: "Chain Mail",
  standard_shield: "Shield", paw_axe: "Paw Axe", hide_vest: "Hide Vest",
  thorn_blade: "Thorn-blade", studded_leather: "Studded Leather",
  claw_bow: "Claw-bow", poultice_universal: "Universal Poultice",
  scent_mask_basic: "Scent-mask", fang_knife: "Fang Knife",
  leather_harness: "Leather Harness", pheromone_vial_calm: "Pheromone Vial (calm)",
  pheromone_vial_fear: "Pheromone Vial (fear)", rope_claw_braid: "Claw-braid Rope",
};

// Plain-language readings for traits/detriments — author-curated
const TRAIT_READING = {
  pack_instinct: "When a friend nearby gets attacked, you can throw your shoulder in front of them to ward off the blow.",
  superior_scent: "Your nose tells you what eyes can't — feelings, lies, fear in a room.",
  subsonic_communication: "You can talk silently with other Canid-folk over short distances.",
  pack_dependent: "Alone, your nerves fray. Crowds steady you.",
  scent_overload: "Strong smells make a noisy room.",
  retractable_claws: "Sheath them for fine work, draw them for a fight.",
  darkvision: "Dim light reads as bright; pitch dark reads as dim grey.",
  feline_grace: "You shrug off most falls and find your feet on any ledge.",
  tail_speak: "Your tail says what your mouth won't — visible to anyone who reads Felid.",
  solitary_instinct: "Help from non-Felidae mostly bounces off — you work alone or you work with kin.",
  prides_cost: "A public fumble costs you the next charm check; the room is watching.",
  sinuous_frame: "Bend through gaps the size of a saucer; slip a grapple like water.",
  burning_metabolism: "Cold doesn't stick. Hunger does.",
  ferocity: "Wounded, you bite harder for one turn.",
  high_metabolism: "Two days of rations a day — or you crash.",
  scent_marker: "Mustelid musk is unmistakable. Stealth costs extra.",
  powerful_build: "You count as one size larger for hauling and grappling.",
  thick_hide: "Your skin is armor. Blunt damage barely lands.",
  bone_crushing_jaws: "A clean bite ends fights.",
  lumbering: "You don't sneak. You arrive.",
  heat_intolerance: "Heat saps you — long hot days demand rest.",
  fleet_footed: "You're faster, and dashing past enemies is safer.",
  antlers: "A natural weapon, growing back each year.",
  wide_field_of_view: "Hard to flank — you see what's at the corners.",
  flight_response: "Sudden danger triggers a save-or-flee reflex.",
  delicate_frame: "Less HP per level. You feel hits.",
  horns: "Permanent natural weapon — bone, not bone-spurs.",
  herd_wall: "Allies at your shoulder give you AC.",
  unshakeable: "Fear and charm slide off you.",
  ponderous_gait: "Slower base speed; quick pivots aren't your thing.",
  stubborn: "Feints fool you because you commit.",
  leaping_strides: "No run-up needed for big jumps.",
  burrow_savvy: "Underground is home. You see and survive there.",
  twitch_reflexes: "First in initiative; ranged shots flinch off.",
  fragile_body: "Less HP. Easier to knock down.",
  constant_vigilance: "New places keep you wired — short rests don't take.",
};

async function loadData() {
  const fetchJson = async (p) => {
    const r = await fetch(p);
    if (!r.ok) throw new Error("Failed to load " + p);
    return r.json();
  };
  const [clades, species, classes, backgrounds] = await Promise.all([
    fetchJson("data/clades.json"),
    fetchJson("data/species.json"),
    fetchJson("data/classes.json"),
    fetchJson("data/backgrounds.json"),
  ]);
  return { clades, species, classes, backgrounds };
}

function abilityMod(score) { return Math.floor((score - 10) / 2); }
function signed(n) { return n >= 0 ? `+${n}` : `${n}`; }

window.ABILITIES = ABILITIES;
window.ABILITY_LABELS = ABILITY_LABELS;
window.STANDARD_ARRAY = STANDARD_ARRAY;
window.SKILL_ABILITY = SKILL_ABILITY;
window.SKILL_LABEL = SKILL_LABEL;
window.SKILL_DESC = SKILL_DESC;
window.SIZE_LABEL = SIZE_LABEL;
window.CLASS_CLADE_REC = CLASS_CLADE_REC;
window.ITEM_NAME = ITEM_NAME;
window.LANGUAGES = LANGUAGES;
window.TRAIT_READING = TRAIT_READING;
window.loadData = loadData;
window.abilityMod = abilityMod;
window.signed = signed;
