← Roadmap

Living document

Product specification

Stakeholder-first Engineering depth below Source src/routes/product/ProductSpec.svelte.md

This document is the living product specification for Hero Sheet. It lives in the repo beside the application code. Stakeholder-friendly narrative comes first; dense engineering detail is isolated under clearly marked headings.

Overview

Hero Sheet is a digital character sheet for one user: prep characters between sessions and use them during play at the table. It stays approachable while representing rules correctly and staying fast in the moment.

Product boundary: No multiplayer—no shared campaigns, party sync, or live collaboration. Each person uses their own copy on their own device if a group adopts the app. Signed-in sync across that same user’s devices—desk and phone—is not multiplayer; see Synchronization across devices.

Scope: This repository is the product—no dependency on legacy HTML reports, predecessor code, or assets maintained outside this repo.

Rules scope: The product targets Dungeons & Dragons 5th edition (5e), with expectations aligned to Player’s Handbook–style play; deeper rules and sheet areas extend over time.

At a glance

👤

Single user

Prep and play on your own device—no party sync or shared campaigns.

⚔️

D&D 5e

First release follows Player’s Handbook–style expectations; depth grows over time.

🛡️

Trust at the table

Rules math runs on the device—fast, authoritative for solo use without server validation.

🗺️

Traceable work

Scope ties to the YAML roadmap so engineering and stakeholders share one story.

Usage flow and features

Read this top-to-bottom for a chronological tour: what you do from the first visit through a full play cycle and the between-session upkeep that follows. The strip below is a compact “map”; each step expands with behaviour detail and links into the feature sections after Vision (authentication, sources, sync, roster, sheet, prep, play, and between-session upkeep).

  1. Step 1 · Arrive

    Open Hero Sheet

    You land on marketing or go straight into the app. You sign in with Google once; cloud sync and your saved roster follow you across devices—still a single-player product.

  2. Step 2 · Sources

    Point at content you supply

    You name a source (e.g. a GitHub user/repository); you are responsible for having permission to use it. Hero Sheet does not host that catalog—the app pulls it and stores the heavy reference payload locally. Your characters, homebrew, and spellbook setup (prep, slots, associations) sync across signed-in devices, so that work is not lost. Only the bulk raw corpus is re-fetched per device—ideally one clear tap on a new install.

  3. Step 3 · Roster

    Create or choose a hero

    The roster is home: quick-create a character or open an existing one. You are always in a single-user context—many heroes over time, but no shared party state.

    Read more in this spec
  4. Step 4 · Build

    Complete the sheet

    Fill identity, stats, saves, skills, combat basics, spells, class features, and inventory into one hero record. Wire class resource tracks—sorcery points, Channel Divinity, ki, and the like—and add custom counters when the table needs something off-menu; each pool gets how it refreshes (short rest, long rest, manual, or another hook you choose). Derived values (DCs, bonuses) update as you edit—client-side rules math.

    Read more in this spec
  5. Step 5 · Prep

    Tune before the session

    Set prepared and always-prepared spells from class, subclass, or background. Add per-spell notes that appear beside the spell in play—reach, visibility, or other personal tweaks. Tune free casts, tie them to short or long rests, align slot counts with usage, and track spells you cast through items so charges stay honest. Hide extras so the sheet stays calm before you play.

    Read more in this spec
  6. Step 6 · Play

    Run the scene

    Use play-first surfaces: filter spells by level, concentration, ritual, and whether you still have the right slot—then open what you need fast. If the exact slot is gone, the flow should still surface that the spell can be cast with a higher-level slot (per 5e rules). Casting context stays visible (save DC, attack bonus, and other casting numbers). Spend slots or free casts with undo; spend and recover class resources and custom counters beside them—then run short or long rests so every pool (slots, free casts, configured tracks) refreshes according to the rules you set. Watch concentration. Alongside casting, the same in-play view keeps the rest of the hero within reach—HP, inventory, ability scores, spent hit dice, initiative, speed, size, and the other stats you rely on between turns.

    Read more in this spec
  7. Step 7 · Grow

    Between sessions

    Level up, adjust gear, archive exports for safety, and use the same account on another device—hero state and references cross the wire, not the full spell corpus.

Vision and north star

Edit on a big screen, play on a small one. Character building and deep edits belong on desktop or tablet—room for the full sheet, comfortable typing, fewer mistakes. At the table, the same hero stays usable on a phone that does not demand screen real estate or constant fiddling during the session.

In-session ease is the bar, not a nice-to-have. While a game is in progress, the app feels radically easy and intuitive—glanceable state, obvious next actions, almost no wayfinding. Common spends and lookups stay one or two taps from muscle memory; play never feels like babysitting a database between turns.

One continuous sheet online. With cloud sync, changes sync automatically and immediately through real-time updates—no save buttons or “remember to upload” rituals. The product feels like a single living state across signed-in devices.

Spells are the original motivation. Easier, more reliable spell and resource tracking across sessions remains central—especially capabilities rare elsewhere, like pre-cast spells players mark explicitly, with short-rest and long-rest (and rules-driven) resets so backgrounds, features, and edge cases stay honest without spreadsheet gymnastics.

Still one trusted surface: levels, gear, abilities, features, and spells stay together—not a spell-only sidecar. Inventory and related context grow with the sheet (gear, attunement, currency, containers).

🖥️

Edit wide, play compact

Build and revise on desktop or larger screens; during live play, the same hero stays small-screen friendly—fast, obvious, and easy to run without losing focus on the table.

Sync without saving

Signed-in edits propagate in real time—no manual save step; one continuous sheet across your devices.

🪄

Spells stay the north star

Dependable spell and slot tracking across sessions is why the app exists; the full sheet grows around that reliability.

🔮

Mark pre-casts, trust rests

Flag spells cast ahead of time that clear on short or long rest (and similar rules)—backgrounds and features included—so tracking stays visible, not buried in notes.

Authentication and account

Authentication ties cloud sync and your roster to one account—still a single-player product (see Synchronization across devices for what crosses the wire).

Identity:

  • Google is the only OAuth provider—single identity provider, fewer edge cases.
  • The account holds configuration that travels with you (saved source pointers and import preferences), not a bulk third-party spell library.

Synchronization across devices

This is multi-device for one signed-in user (desk and phone)—not party play or shared campaigns.

What syncs across signed-in devices:

  • Cloud-backed hero state — Roster, progression, inventory pointers, and spell references on the account—not bulk third-party spell text uploaded as one giant blob.
  • Real-time updates — The same hero stays current on desktop and handheld for one user as edits land—no manual sync step.
  • Hero records, homebrew, custom data, and spellbook state (preparation, slots, associations, references) sync across signed-in devices—you do not lose that work.
  • Account stores pointers — Repo coordinates and import preferences live on the account so a new device knows which repository to use for the bulk reference import (see Heavy corpus, sync, and new devices).

What does not sync as a full library: The heavy corpus (bulk spell/rule text) is local per device after import, not streamed device-to-device through the cloud. Read the plain-language split in Heavy corpus, sync, and new devices; boundaries also appear under Catalog boundary and local corpus and Content sources and import.

Product framing: Multiplayer is not part of the product; multi-device for one account matches single-user framing. Multiple devices for the same user are a sync concern, not party play—rules and spends stay client-authoritative.

Cloud-first implementation: Hero and roster state uses a cloud-backed real-time data layer as a first-class part of the build—not a later retrofit. Export and backup parity with that cloud state is not required to ship real-time sync; export timing is decided separately.

Offline and connectivity: The product should still support optional use without a live connection, but exact mechanics (local queue, merge under lag, conflict rules, and how that interacts with cloud-primary writes) are undecided—see Open questions below and the Real-time cloud data layer for hero state task on the roadmap.

Spell and reference behavior follows this hero vs corpus split.

Content sources and import

You name a source you may use—for example a GitHub user/repository. You are responsible for having permission to use that material.

Primary ingest (first release): The app does not ship a bundled rules corpus or a first-party CSV/bootstrap dataset you maintain. Ingest targets one designated upstream GitHub repository (exact URL and path conventions TBD); the corpus is JSON files spread across that tree, including index files that point at other files. The importer parses that graph into local materialized storage. Hero Sheet still does not host that upstream catalog on its own servers—see Catalog boundary and local corpus.

Import behavior:

  • Hero Sheet pulls from the source you configure and turns it into data the app can use locally.
  • Saved pointers (repo coordinates, import preferences) live on the account.
  • New devices re-fetch and materialize the bulk corpus locally after you confirm import—see Heavy corpus, sync, and new devices.

This section pairs with Catalog boundary and local corpus (what we do not host), Heavy corpus, sync, and new devices (reader-friendly model), and Synchronization across devices (what crosses the wire for heroes and spellbook state).

Catalog boundary and local corpus

Hero Sheet does not host the upstream rules/spell catalog and does not certify third-party sources. You point at content you control or may use; the app pulls it and stores the heavy reference payload on the device in a form suitable for play.

Boundary:

  • Bulk spell/rule text from the source is materialized into local storage per device and is not transferred device-to-device as a full library through the cloud.
  • References on heroes (what spells mean in your sheet) sync with hero state; the corpus files themselves are local per device after import.

For a step-by-step mental model (what is “heavy,” what syncs, what happens on a new device), see Heavy corpus, sync, and new devices.

Heavy corpus, sync, and new devices

This section is a plain-language guide to language used elsewhere in the spec (“heavy corpus,” bulk import, pointers).

What the heavy corpus is: The large reference payload pulled from the source you configure—typically spell text, rules snippets, and related bulk data from a repository such as GitHub. It is library material the app needs on the device to resolve spells and rules during play. It is not the same thing as your characters or your spellbook choices.

What syncs via your account (user content and config): Heroes, homebrew, spellbook state (prepared spells, slots, associations, notes), and similar sheet-owned data follow you across devices in real time. Which repository you use and how you import—the saved pointer and preferences—also live on the account so you are not re-typing coordinates on every new install.

What does not sync as a giant package: The bulk corpus files are not pushed phone-to-laptop through the account as a full silent library sync. Each device materializes that bulk data locally after an import step. That keeps sync focused on your work, not on re-uploading third-party text through our cloud.

Onboarding a new device: After you sign in, the app prompts you to start the import (or “sync the reference library”) for that device using the repository already saved to your account. The primary path is one clear action—for example a single button—not a hidden multi-step download you never agreed to. Hero data can already be current while the new device still finishes the local corpus step before every lookup behaves the same as on your other devices.

Roster and heroes

The roster is home: quick-create a character or open an existing one. You are always in a single-user context—multiple heroes are in scope from the first milestone (not a single-hero cut or a later unlock), no shared party state. The roster and each hero’s persisted state follow the account across signed-in devices.

Character sheet and rules

Ruleset: D&D 5th edition (5e) for the first release—stats, modifiers, spells, and rests align with core 5e expectations unless documented otherwise.

One hero record holds identity, stats, saves, skills, combat basics, spells, class features, and inventory. You wire class resource tracks—sorcery points, Channel Divinity, ki, and similar—and add custom counters when the table needs something off-menu; each pool records how it refreshes (short rest, long rest, manual, or another hook you choose).

Inventory (first playable): Manual rows—add an item with a description (and whatever free text the table needs) and an optional quantity or count. There is no inventory automation in v1: no derived weight, auto-stacking rules, or equipment-driven stat effects unless the product expands later.

Rules engine: Client-authoritative — modifiers, rolls, and spends are computed in the app; no server-side rules validation. Derived values (DCs, attack bonuses, and similar) update as you edit.

Contextual class rules: The app reads rule text from the corpus for the hero you have open and surfaces the pieces that apply to that build—for example class, subclass, level, and related choices—so you are not hunting the full rulebook. Those excerpts stay easy to open and scan when you need a reminder, including during prep and spell configuration and in-session play.

Multiplayer: Not part of the product—prep and in-session use stay single-user; several devices for the same account remain a sync topic, not party play.

Prep and spell configuration

Between building the sheet and sitting down at the table, you tune how the hero plays:

Prepared versus always-prepared: The sheet distinguishes spells that count against the character’s preparation limit (driven by level, class, and related features) from spells that are always prepared—for example from class, subclass, or background—and do not consume that limit. Each spell is clearly labeled so you always know what sits in the shared preparation pool versus what is granted on top of it.

Use the full preparation rules: Totals show how many prepared spells the character has chosen versus how many the build allows, so under-preparing is obvious before you play. The UI surfaces always-prepared spells you have earned so those entries are easy to notice and use, not lost in a long list—you get the full benefit of preparation mechanics without accidentally leaving slots empty or ignoring free always-prepared picks.

  • Set prepared and always-prepared spells from class, subclass, or background.
  • Cantrips: The app tracks cantrips the character knows and keeps cantrip budgets (where the rules define them) visible during prep and during play, alongside the preparation summary above.
  • Add per-spell notes that appear beside the spell in play (reach, visibility, table-specific tweaks).
  • Tune free casts, tie them to short or long rests, align slot counts with usage, and track spells you cast through items so charges stay honest.
  • Hide extras so the sheet stays calm before you play.

In-session play

At the table, surfaces are play-first:

  • Filter spells by level, concentration, ritual, and whether you still have the right slot—then open what you need quickly. If the exact slot is gone, the flow still shows that the spell can be cast with a higher-level slot (per 5e rules).
  • Keep casting context visible: save DC, attack bonus, and other casting numbers.
  • Spend slots or free casts with undo; spend and recover class resources and custom counters beside them; run short or long rests so every pool (slots, free casts, configured tracks) refreshes according to the rules you set. Watch concentration.
  • Alongside casting, the same in-play view keeps the rest of the hero within reach—HP, inventory, ability scores, spent hit dice, initiative, speed, size, and the other stats you rely on between turns.

Between sessions

After play, you level up, adjust gear, and archive exports for safety. The same account picks up the hero on another device: hero state and references cross the wire, not the full spell corpus (see Heavy corpus, sync, and new devices, Synchronization across devices, and Content sources and import).

Non-functional requirements

Engineering

The following material records stack choices, testing expectations, and what “client-authoritative” means in practice.

All product surfaces follow the responsive layout, touch, and testing norms in AGENTS.md.

Implementation notes (engineering):

  • Stack: SvelteKit, TypeScript, Skeleton UI, Tailwind; Markdown via mdsvex for this spec.
  • Testing: Vitest for deterministic logic; Playwright only where unit tests cannot pin behavior (see project AGENTS.md).

Quality bar

Performance

Snappy on mid-tier phones; imports show progress—no silent hangs.

Accessibility

Keyboard paths, focus, semantics, and contrast toward WCAG 2.2 AA.

📱

Responsive

Portrait and landscape phones, tablet-friendly wide layouts, touch targets per AGENTS.md.

🔁

Reliability

Survive refresh when persistence exists; reject bad exports; confirm destructive acts.

🔒

Privacy

Auth and cloud data meet clear expectations for data in motion and at rest.

Open questions

Resolved recently: The first playable sheet uses manual inventory (no automation). Ingest is remote JSON from a designated upstream repo (graph of files including indexes)—no bundled or first-party bootstrap dataset, and we do not host their catalog. Multiple heroes ship from the first milestone. Cloud-first real-time sync is the implementation target; export parity is not a gate. There is no legacy HTML or predecessor repo this product depends on.

Still open: Which power-user surfaces belong in which milestone (advanced workflows vs first playable—see the list below). Offline queue, merge under sync lag, optional offline play alongside cloud-primary data, and export timing must be decided before building the sync backend (tracked on the roadmap).

Open decisions

  • Which power-user surfaces belong in which milestone?
  • Offline queue and merge under sync lag, optional offline play alongside cloud-primary sync, and export timing—decide before building the sync backend.