diff --git a/docs/api.html b/docs/api.html
new file mode 100644
index 0000000..9686f92
--- /dev/null
+++ b/docs/api.html
@@ -0,0 +1,116 @@
+
+
+
+
+
+ json-trail - API
+
+
+
+
+
+
+ API Reference
+
+
+ json-trail exposes a minimal API for creating hash-linked blocks and
+ verifying their integrity. All operations use deterministic SHA-256 hashing and return plain data structures
+ containing Uint8Array fields.
+
+
+ createBlock(payload, prevBlock)
+
+
+ Creates a new hash-linked block. The payload must be a Uint8Array. If a
+ previous block is provided, its blockHash becomes the
+ prevHash of the new block.
+
+
+ Import
+ import { createBlock } from "json-trail";
+
+
+ Usage
+ const enc = new TextEncoder();
+const payload = enc.encode("hello");
+
+const block = await createBlock(payload);
+
+
+ Returns
+ {
+ index: number,
+ timestamp: number,
+ payload: Uint8Array,
+ payloadHash: Uint8Array,
+ prevHash: Uint8Array | null,
+ blockHash: Uint8Array
+}
+
+
+
+ Note: modifying a block or its payload after creation will invalidate its
+ hashes.
+
+
+
+
+ verifyBlock(block)
+
+
+ Verifies the integrity of a single block. Returns true if
+ the payloadHash and blockHash match the block
+ contents.
+
+
+ Import
+ import { verifyBlock } from "json-trail";
+
+
+ Usage
+ const ok = await verifyBlock(block);
+
+
+ Returns
+ boolean
+
+
+
+
+ verifyChain(blocks)
+
+
+ Verifies the integrity of a sequence of blocks. Ensures each block is
+ valid and that each prevHash matches the previous
+ blockHash.
+
+
+ Import
+ import { verifyChain } from "json-trail";
+
+
+ Usage
+ const ok = await verifyChain([block0, block1, block2]);
+
+
+ Returns
+ boolean
+
+
+
+ Overview
+ API
+ Examples
+ Integrity Model
+ Using json-seal with json-trail
+
+
+
+ GitHub ·
+ npm
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/examples.html b/docs/examples.html
new file mode 100644
index 0000000..35f5a1b
--- /dev/null
+++ b/docs/examples.html
@@ -0,0 +1,54 @@
+
+
+
+
+
+ json-trail - Examples
+
+
+
+
+
+
+ Examples
+
+ Basic usage
+
+ import { createBlock, verifyBlock, verifyChain } from "json-trail";
+
+const enc = new TextEncoder();
+const payload = enc.encode("hello world");
+
+const block0 = await createBlock(payload);
+const block1 = await createBlock(payload, block0);
+
+console.log(await verifyBlock(block0));
+console.log(await verifyBlock(block1));
+console.log(await verifyChain([block0, block1]));
+
+
+ Tampering detection
+
+ block1.payload[0] ^= 1;
+
+console.log(await verifyBlock(block1)); // false
+console.log(await verifyChain([block0, block1])); // false
+
+
+
+ Overview
+ API
+ Examples
+ Integrity Model
+ Using json-seal with json-trail
+
+
+
+ GitHub ·
+ npm
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/index.html b/docs/index.html
new file mode 100644
index 0000000..acc9a57
--- /dev/null
+++ b/docs/index.html
@@ -0,0 +1,58 @@
+
+
+
+
+
+ json-trail
+
+
+
+
+
+
+ json-trail
+
+ Tamper-evident, hash-linked blocks for apps. Zero dependencies.
+
+
+
+ json-trail is a tiny library for creating hash-linked blocks that detect
+ any modification to payloads or history. It provides chronological
+ integrity without keys, signatures, or complex state.
+
+
+ Why json-trail exists
+
+
+ Local-first apps store data on the device and sync when possible. Without
+ a server acting as the source of truth, you still need a way to know
+ whether your local history has been tampered with. json-trail provides a
+ minimal, deterministic, tamper-evident structure for that purpose.
+
+
+ Features
+
+ Deterministic SHA-256 hashing
+ Hash-linked blocks with prevHash
+ Pure JSON block format
+ Browser and Node support
+ Zero dependencies
+
+
+
+ Overview
+ API
+ Examples
+ Integrity Model
+ Using json-seal with json-trail
+
+
+
+ GitHub ·
+ npm
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/integrity-model.html b/docs/integrity-model.html
new file mode 100644
index 0000000..80713a4
--- /dev/null
+++ b/docs/integrity-model.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+ json-trail - Integrity Model
+
+
+
+
+
+
+ Integrity Model
+
+
+ json-trail uses a simple hashing model to detect tampering.
+
+
+ Block structure
+
+ payloadHash = SHA-256(payload)
+ prevHash = previous block's blockHash (or null for the first block)
+ blockHash = SHA-256(index + timestamp + payloadHash + prevHash)
+
+
+ Block validity
+
+ payloadHash must match the payload
+ blockHash must match the block contents
+
+
+ Chain validity
+
+ every block must be valid
+ prevHash must match the previous blockHash
+ indexes must increase by 1
+
+
+
+ Overview
+ API
+ Examples
+ Integrity Model
+ Using json-seal with json-trail
+
+
+
+ GitHub ·
+ npm
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/seal-and-trail.html b/docs/seal-and-trail.html
new file mode 100644
index 0000000..36be3af
--- /dev/null
+++ b/docs/seal-and-trail.html
@@ -0,0 +1,63 @@
+
+
+
+
+
+ json-seal + json-trail
+
+
+
+
+
+
+ json-seal + json-trail
+
+
+ json-seal provides authenticity. json-trail provides chronological integrity.
+ Together, they form a signed, tamper-evident, hash-linked log entry.
+
+
+
+ npm: json-seal
+
+
+ Example
+
+ import { generateKeyPair, signPayload, canonicalize } from "json-seal";
+import { createBlock } from "json-trail";
+
+const { privateKey, publicKey } = await generateKeyPair();
+
+const sealed = await signPayload({ foo: 123 }, privateKey, publicKey);
+
+// canonical, deterministic bytes for the block
+const canonical = canonicalize(sealed);
+const block = await createBlock(new TextEncoder().encode(canonical));
+
+
+
+ Using canonicalize ensures that the bytes passed into
+ createBlock are deterministic. json-seal produces a stable,
+ canonical representation of the sealed envelope, so hashing it with
+ json-trail yields consistent results across platforms and runtimes.
+
+
+ Verification flow
+
+ verifyBackup(sealed) checks authenticity
+ verifyBlock(block) checks integrity
+ verifyChain([...]) checks ordering
+
+
+
+ Overview
+ API
+ Examples
+ Integrity Model
+ Using json-seal with json-trail
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/style.css b/docs/style.css
new file mode 100644
index 0000000..d6f43f0
--- /dev/null
+++ b/docs/style.css
@@ -0,0 +1,106 @@
+body {
+ margin: 0;
+ padding: 0;
+ font-family: system-ui, sans-serif;
+ background: radial-gradient(circle at 50% 20%, #1a1a1a, #000);
+ color: #e6e6e6;
+ display: flex;
+ justify-content: center;
+ align-items: flex-start;
+ min-height: 100vh;
+ padding-top: 8vh;
+ overflow-x: hidden;
+ width: 100%;
+ box-sizing: border-box;
+}
+
+main {
+ max-width: 640px;
+ width: 100%;
+ padding: 0 24px;
+ box-sizing: border-box;
+ text-align: left;
+}
+
+h1 {
+ font-weight: 500;
+ letter-spacing: -0.5px;
+ margin-bottom: 1rem;
+ text-align: center;
+}
+
+h2 {
+ margin-top: 2rem;
+ font-weight: 500;
+}
+
+p,
+ul {
+ line-height: 1.6;
+ opacity: 0.9;
+}
+
+pre {
+ background: rgba(255, 255, 255, 0.05);
+ padding: 16px;
+ border-radius: 8px;
+ overflow-x: auto;
+ margin-top: 1rem;
+}
+
+nav {
+ margin-top: 2.5rem;
+ display: flex;
+ justify-content: center;
+ gap: 1.5rem;
+ flex-wrap: wrap;
+ opacity: 0.8;
+}
+
+nav a {
+ color: #e6e6e6;
+ text-decoration: none;
+ font-size: 0.95rem;
+}
+
+nav a:hover {
+ opacity: 1;
+}
+
+a {
+ color: #e6e6e6;
+ text-decoration: none;
+}
+
+a:hover {
+ opacity: 1;
+}
+
+.external-links {
+ text-align: center;
+ margin-top: 2rem;
+ opacity: 0.8;
+ margin-bottom: 3rem;
+}
+
+.subtitle {
+ text-align: center;
+}
+
+@media (max-width: 480px) {
+ body {
+ padding-top: 4vh;
+ }
+
+ main {
+ padding: 0 16px;
+ }
+
+ nav {
+ gap: 1rem;
+ }
+
+ nav a {
+ font-size: 0.9rem;
+ }
+}
\ No newline at end of file