{"_id":"@bravely-studios/account-web","_rev":"27-b2fc812f0d2f84555363a9130ab9b50e","name":"@bravely-studios/account-web","dist-tags":{"latest":"0.7.3"},"versions":{"0.3.4":{"name":"@bravely-studios/account-web","version":"0.3.4","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.3.4","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"1cf629fd76999d2e7f0a397f351cd9fb8b20e273","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.3.4.tgz","fileCount":59,"integrity":"sha512-87a8c6wzf3TaUu/R1b4S69IkmNe8cLTWTUZV1Sn3s13jANddqGUG9QZlGyCb9/i6bsy8OWZ4xC4FtACBorwAAA==","signatures":[{"sig":"MEUCIGky9n4DU1ClonX8exSMllcom7D0uPPpPsWd39B89AyhAiEAqO5TY8DzT39FNcRqxT3IwQFE4rAfvA5VQQhzaC31Ego=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":197526},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"7dba625c6b9a7080db16764ba9aeb431f42a9f60","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"bravely-studios","email":"jeff@bravely.dev"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"10.8.2","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 9 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.3.4_1778714111969_0.4118201521453597","host":"s3://npm-registry-packages-npm-production"}},"0.3.5":{"name":"@bravely-studios/account-web","version":"0.3.5","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.3.5","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"ea15a05dd69d91db40ddd1dea0175400582bdf2f","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.3.5.tgz","fileCount":63,"integrity":"sha512-cU7gc81KdJ5xogKCvJDUU8B7I+MtdsSLNVzD3xsk06PgnU3okiqQyULdV0PMCTMHD4YWABkhVmSJ5+0j1Sddzg==","signatures":[{"sig":"MEUCIHkIW29WFuEVvsdDvKVfRWBlRLTBolrpuvOep8/caFrUAiEA+LEAz3qwGkKelgtLIBHW6kZaaJ6qqoqcF9gTVsdRJWI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":213807},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"9bc93ab12e75a71aa525530479888c078d1e3028","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"bravely-studios","email":"jeff@bravely.dev"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"10.8.2","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 9 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.3.5_1778751692261_0.5560064712828523","host":"s3://npm-registry-packages-npm-production"}},"0.3.6":{"name":"@bravely-studios/account-web","version":"0.3.6","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.3.6","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"9b600e16e4c55c0d2f8d65519a0621cb1f9a8844","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.3.6.tgz","fileCount":63,"integrity":"sha512-8WHFHETClc8P3nasaPKUEQKLeoJp9zXpFruqclRlb+t089kV90emSjx7AiHKU11A9Jt7vykdRZLSi8KXHyEV+g==","signatures":[{"sig":"MEUCIEXekDOU92qZFgyiPOHep/+V0CMzSmxOx05+8kTjKRDOAiEAq1fSICVGDlowGy7AMiVaNXrjDTENGCvVMtFfPIF+I0s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":218861},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"73941322eccbd112e7d97725cbc23c502cbe1734","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"bravely-studios","email":"jeff@bravely.dev"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"10.8.2","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 9 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.3.6_1778846423082_0.6776650495471646","host":"s3://npm-registry-packages-npm-production"}},"0.3.9":{"name":"@bravely-studios/account-web","version":"0.3.9","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.3.9","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"affc3d996fa8dadd4170659c1dc2fa580985bff0","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.3.9.tgz","fileCount":63,"integrity":"sha512-NAxbx801FX/ADzzW3s7sM4sV2wOrujarQdoMOg9hz7pVQqjDEc8B7xxgyWB8eeLeGrIOjF7b3+7DUyf+FWA8Aw==","signatures":[{"sig":"MEUCIQCy/0sXa80nNNi+m2H415a7vUabFVIZJU+QuufQryf+rwIgSh4GV5sF+3/M3zGwfCDTX6v3fIky6ScdTmi0ID+78po=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":228504},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"8e8b1b78bfcbef00e016407eb2243fb0aa9d9098","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.16.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.3.9_1780531354106_0.3108583610369797","host":"s3://npm-registry-packages-npm-production"}},"0.3.10":{"name":"@bravely-studios/account-web","version":"0.3.10","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.3.10","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"f4219061b0443e6cb838dd10541d653e27419861","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.3.10.tgz","fileCount":63,"integrity":"sha512-OAQ3Lupwl1MN4HI+rTXwJ2Wa8FqfgkPJpH8yTUGw4uiRplBwpBhUgNjIy3V90Tev9hod/RZCkxs9+Af6+dG2Eg==","signatures":[{"sig":"MEQCIHslCF8Jpixxg87kLJrkC2Q6PaABML7zDmcgCbJyLKBGAiAqGRVQnhbO6ewpxqGD0goZAdE4GnwnlzccDHEM5u0KCQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":236526},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"4e1dec57af01cd361d24b6f349d7c093e8e3616f","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.16.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.3.10_1780680410273_0.7996495602233287","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"@bravely-studios/account-web","version":"0.4.0","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.4.0","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"939b1593f9088fe7612c9b303972f4fc90dbac25","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.4.0.tgz","fileCount":75,"integrity":"sha512-40jND81KNbqlSFJHfasaXZdDFWe7HcqtN9Wt678qPMLA4oBXCqrfdhxc3+qN8ejia2YysXJJlHtM4b487Fp5mg==","signatures":[{"sig":"MEQCIGysu/1iyg52OqkcV3oVnm64M7zQD8gLzJPgEdMgzHKNAiBd0ogeU+CZO4yTEGFEMXuzWiiW+EuNBHOTSK6LY4HT0g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":363602},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"5bd875023526493cc0194f76047964c7aa369f6b","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.16.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.4.0_1781179210298_0.7482051375479442","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"@bravely-studios/account-web","version":"0.4.1","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.4.1","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"5444ca2c00c1d1fee9e15a51479b19a4a3c6f522","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.4.1.tgz","fileCount":75,"integrity":"sha512-oAnJE+DcHwRfMmTBY+P5BDUOaRTD4oONNFXiHuTST3eBHm7tLsacDCHpMjl5VzgCnjLO3fpKeV1NjoxflCZqmA==","signatures":[{"sig":"MEUCIAD8Tu4SCORvGhB1Ak57ltQmU5HIKHNN/0Agra17vn3xAiEA3FOfOA4vQdX1U7LDBlmS2QmmMYFYlrttbG7Eq9sNtwI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":373203},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"0a10cd8a264727070a2c34bd72dd632e0be0c33b","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.17.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.4.1_1781216347835_0.04154328901352056","host":"s3://npm-registry-packages-npm-production"}},"0.4.2":{"name":"@bravely-studios/account-web","version":"0.4.2","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.4.2","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"f568ca356f8f747efb23edff0185cc5627597b56","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.4.2.tgz","fileCount":75,"integrity":"sha512-EQg8ct2P806yu6De4BcIXNFLt+DRZqXIwA/L1S2KkSV/AIgtaMXwzAz+EgH52Ia6ksKxcMLeMFxwN7CNN6PMcg==","signatures":[{"sig":"MEUCIFndFPxK5IgpXTTnUQb3d//tITkcND3+/C3iOGgzlSoMAiEA050j/YC0WxZ99GU+5KLVZtY1Nr5d2wuURbS2uKmUjbU=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":373077},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"e37a654a49599ab79589b49034215beea811993b","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.17.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.4.2_1781351426393_0.7718292682468006","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"@bravely-studios/account-web","version":"0.5.0","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.5.0","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"bdb640d2f597f77552c17cb830ee5ca4cd7c9403","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.5.0.tgz","fileCount":79,"integrity":"sha512-LPdHp0pgt5UnXdYLvxrYK3HDsnkLuVl9jQelT/GlG6CHy5NOCiW2gnw9jYjzNXj0QMVpjbHX5AXFGNP0T3C96w==","signatures":[{"sig":"MEUCIQDYgCHG0fgBCVWQ1FtgoWKg1uAU71U18DZSaTodo+XaHgIgSCu8E1JMRg3Ye5pgnRKPa82cZ0vcBoV4ocUDlaPkJq4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":447279},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"eb0b48dfa9234cb7ff3dab9746381f530b855158","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.17.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.5.0_1781395328530_0.40763415102416434","host":"s3://npm-registry-packages-npm-production"}},"0.5.1":{"name":"@bravely-studios/account-web","version":"0.5.1","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.5.1","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"24af4532ea251ae027c5ce2d6f592d1eb6577278","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.5.1.tgz","fileCount":79,"integrity":"sha512-9ajj9CDReuvwAINunvevVwRRiN26+iB+RV88sVpuNY4b0Nb7kd1ojMFTdz2kZnH87IsELsazNOyxC9gpAFKOyw==","signatures":[{"sig":"MEUCIQDpIgx3Axy4S5k+Jo0NgLwf4ZydRmcWn9DQ/WLkpq3JugIgZp7bO2RAC9md8wecuqZBQlNSBoqlMiV514vwC/AH61k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":447505},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"a01b05f71d4362ee2d209bc9d10580dfd5a118e7","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.17.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^3.2.4","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^3.2.4","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.5.1_1781525623378_0.8279549147255607","host":"s3://npm-registry-packages-npm-production"}},"0.5.2":{"name":"@bravely-studios/account-web","version":"0.5.2","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.5.2","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"5975d83bea359ac09708f80d1a3d0a89a6d1411a","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.5.2.tgz","fileCount":83,"integrity":"sha512-R9svEYNw0BuS3kmQaIi9Q5XK70KcSYfdPdjCtCpXHec+IKaf1y70+XHln3NwHO2OZHesUJ9DfXRjQslP8WPdMA==","signatures":[{"sig":"MEQCIHyvxc8IM6vBok8fGWTfQ1bdfFv/+mAexYhkab5xwCfqAiBVl6Q+CWhvcKHviVswwxqCj1KiwzyYjnE97bEkfGR8pQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":464917},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"8165ba3cd834d398a972c28fe23fbf8067c56f60","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.17.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.5.2_1782011008355_0.8859734615030963","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@bravely-studios/account-web","version":"0.6.0","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.0","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"bd29890b7a64ec464a1d5cb350499fac652449d3","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.0.tgz","fileCount":163,"integrity":"sha512-ffLqNfNd6Gya1wEFiT178fb6JXSwl9H/q8LxTXuUv1q0OzvQ2S2eWkB5WrcDolFc8kLpM3v58CCv+hqet2rYUw==","signatures":[{"sig":"MEQCIELcwm1ANsDRo+I68yLrR5L6I5i4MGChGYX2OoVbkCEFAiBaXl6hdc3dOA0X3I4hv91QnfOUtnfz7Ne7mP4pfVIq7g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCICxAfXPIwhBojBrkaBmf/3pDBDVOTuaHk31ek0Rao7KfAiAY5f6BoULZ0L6As+EkYU1sIvkCDnICY+xjEQB04idbWg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":841306},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"0b9ab152e6844251f9a47e31cb818fbeba82032b","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.0_1789181312494_0.8571768218018194","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"name":"@bravely-studios/account-web","version":"0.6.1","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.1","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"1c45e7ff4d4ac2a7549c55b9daae8772bf426b13","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.1.tgz","fileCount":163,"integrity":"sha512-2X6miVZPwhoksK13b6cvjfLhPaT7BsknyRdvD3eN6o11TEIBaOh9iagaRdY59q6T5pux+QDPcJU5+QRevTvVTw==","signatures":[{"sig":"MEUCIAZberUqSFskPDm02QjgyCCyO3ulu5xGM6amC/lMX5rAAiEAxvtyQZ23VE+7I6eiMBuQdqiUOF7ltCYR6Di4u3Jretw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCICFJoXQ7J4bpm59ZRIW6SnvKnNfoxvQMNOZWvl3Z4TMRAiEA74ryiuf/8sRTesHApPjPnr3AWaQgQbmX75kjonn9MJY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":845294},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"d5a9fe7a2cc4402bea63c2be979cf603481df581","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.1_1789185638799_0.3096963949038627","host":"s3://npm-registry-packages-npm-production"}},"0.6.2":{"name":"@bravely-studios/account-web","version":"0.6.2","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.2","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"abd40972a440fde87f5b8b331811eb1fb6625194","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.2.tgz","fileCount":175,"integrity":"sha512-p4h7TCcQ6Hab8leuTNRdMxrxa1XiwACVQ8JLKhsCP8EkS4NT9REOSh/rfNhI4rgMPpQmeg8GbJ7NOATFAGwM1w==","signatures":[{"sig":"MEUCID9OiqThkTXN3MUwIRtY/0tcKb24fzpc16aa1WkWLA8nAiEAwHq3OON2RVXeMiyjgNg9nqWdsi2ieBkgQV1pjT6pLO8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQC08t27VF+ZompbQnk6BlIRpa3g5b8R1I5pAnXdEH9xPwIhAPZQbThaaKqhNmf6geAu7gz1Mm7ZACj6aYDIaWJHwF4c","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":950217},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"fb17d5a953f0955568e6d61092a64c0542c8d64b","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.2_1789189574199_0.7345945591091976","host":"s3://npm-registry-packages-npm-production"}},"0.6.3":{"name":"@bravely-studios/account-web","version":"0.6.3","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.3","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"575b129fe5d828c2c710e4ef0fcfcff90665820f","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.3.tgz","fileCount":175,"integrity":"sha512-1DyVJpQ6jft9iPAatzJKftq5GB/fZY3QUg8O2j09KQ8DIiKK2KvhJuZ3twRZnQq5lHOtl3TQ23awRjM5PQwxsA==","signatures":[{"sig":"MEUCIQC1nfNFnwBSNe/veSn3M24PJv7IWanKlXmvcCulyG/gjwIgJDO5HmcYtTBupNxX3scr3ju94YUprUUMfCUGy9z09nk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIHTMeSJSD5UY3F4VJ7xRQUIgLsxCZBIWw5XmZubWtu6sAiALt+WU8aRhgz8j0fv9opkHOQXeV4IHj0WhRCcSWv+Agw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":994514},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"099196a0df0eb61177793d37956cb781ffb272c3","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.3_1789213598393_0.3549871715882864","host":"s3://npm-registry-packages-npm-production"}},"0.6.4":{"name":"@bravely-studios/account-web","version":"0.6.4","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.4","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"bcbc4eb20b08c50a1d750d1f746b35b17dd7e369","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.4.tgz","fileCount":179,"integrity":"sha512-LSBnH3uiQfYJb/UGwO0zxDRpdE5AD3vXYwAUPc/5nGbnrEXDxx1X0bNrBcNYtDqEzO9cedea4VmGNCbLkMYJ8w==","signatures":[{"sig":"MEQCIH9F3BKyLuRfAyrRZtYEdMhy2i7Cy1C1ne9HNeV69AbtAiBhf1nyEmkZQBRKNnbxbRF32ogpShVcD2EmiEewYp9Slg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIERkqXl/jD+j7mBTOUsRZyWqGv6wJ44xRiW0nt60lpTBAiB/Ai79WCWGitk8MLJ53rnm5JnrlyW8/nRRTgqzVxOwCw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1038087},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"31465c1c54470de8ee8fac9eb96ac54c6d366414","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.4_1789223295545_0.3595576679887289","host":"s3://npm-registry-packages-npm-production"}},"0.6.5":{"name":"@bravely-studios/account-web","version":"0.6.5","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.5","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"d4e3b1bac8723f031cfdfef566b5500d08b200f8","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.5.tgz","fileCount":183,"integrity":"sha512-FozaHGtFHDn7X9o28tX6hzpZmKJwb2lFDVzOWmXz9VnxhrxdQDjsKXrunu6DLnT0MW3teB/w7HM3L6/0T9CFHw==","signatures":[{"sig":"MEUCIQCCAL3rPlnymXnYwlyJHHZQTR+p5jbSYyupWmkQi0tpWQIgMy9c4DN5PrrRyF8d4XtZ+84DfhR3SmIK0d5BAMMsJ88=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQDpN8uPl7aVob9Wq8dpRvAmeJX/7A2tvQk1rf/Dvil9DAIhAMcJraghTmW5H3fwfTP7u/KlKhVc+o+U24LO/8DBlJS5","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1065754},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"8dfe043ab988c8a62473205e9d3acc1ddd434043","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc --noEmit","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.5_1789246819487_0.5371190145616611","host":"s3://npm-registry-packages-npm-production"}},"0.6.6":{"name":"@bravely-studios/account-web","version":"0.6.6","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.6","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"bfff4ff03c5338f34ada8ad190d051d606ab5d49","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.6.tgz","fileCount":187,"integrity":"sha512-AZ/6f4kYcFEwhBzjixP0C7gTkdVJpATOqxH8QxaWM6yk4hm6G6g+nErIrwOsE/nBso2ytBskCoo4wSyKOeGEAA==","signatures":[{"sig":"MEUCIDyWRoV9R6b2OH81n+UXycnX9H6OUJoTi6KzxAlupmiRAiEAmJTxjsqPChJ2E172PITJ0q2m9G/B1zImZNsMZsHDFFg=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCT5y+e+bzKQxc5sAqsKLYJDdSRZ/L1QyvKZqyz9DAD7gIgQYQxFPsZQp+Y0Q2kkizzHDGjxF/K9EPCdnUyaIod2Z4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1096413},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"f56934a407c4147fcb1c0052b9b8a99c4eaa19f2","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.6_1789262908908_0.9024205252165709","host":"s3://npm-registry-packages-npm-production"}},"0.6.7":{"name":"@bravely-studios/account-web","version":"0.6.7","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.7","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"5d4de6698f16554ec9cffca3fe30393c82344c01","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.7.tgz","fileCount":191,"integrity":"sha512-Iq7TR7etPORkoDTlcXpzx5lXgyhTkHcJ2Bykx6BnHb2M7OxDaANkUJB671OAj1hgH1KVu0KOJsah47nGtTr2Yw==","signatures":[{"sig":"MEUCIADv8ZqrLxgCAoEQ72VfFv7Tw67gI36h8O2e4oxAZhdqAiEAhs1Iwz+eLiPAd2cQ5LxDvfW/NCww9ZYlIf1CFHitsuo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGKF8hUbN7yoiwm8AEJP+zTFKoL4LN8Qbqq/zF6MKxs/AiBu66370Q1CiiXO1kaLPQ4WMKNA/VG3o5Egh/1apAyiHQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1125953},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"d2237efa903ec94fe82f7d01bece4f8b2ac26c1d","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.7_1789346792534_0.09013794390629437","host":"s3://npm-registry-packages-npm-production"}},"0.6.8":{"name":"@bravely-studios/account-web","version":"0.6.8","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.8","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"400bd0f9fabc325c18abe9b692d61041c827aa65","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.8.tgz","fileCount":203,"integrity":"sha512-btnGZDyFgewP6GE2+3ZSVIV1av5lC72FLRHxLIt3I8EEcaplKtGdx4Bd5m2IiCCrGyjNCla/n3e1MiSPTbBTQQ==","signatures":[{"sig":"MEUCIB74pVIT5h3JNy9mdTZW0PWV6+yus0B5pYSwCiWiGgOyAiEA7HQcBGwpThsJdikNKfUG35edU4NhQIr9I8tFQPScYw4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIBmzEghYnpe2fzEWNymI1Z6yHOtPhEp8XJ2FsjH9wcBtAiEAkjLfRbeeNp+nS72LOZQk8X3g7P4+xriMoQzXTmEQhec=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1523105},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"70f881db991cbb71aca0c9c401e3aeea5dde4d70","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.9","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.9","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.8_1789425721891_0.5453214544099574","host":"s3://npm-registry-packages-npm-production"}},"0.6.9":{"name":"@bravely-studios/account-web","version":"0.6.9","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.9","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"1ed2e237e01465c7413466848c3ba44018614a94","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.9.tgz","fileCount":203,"integrity":"sha512-5gz50HbkRwHHC6tfDGH4fggV1PsUrJkcnX/yP2CaIuJqeMB5nCDU/w/vmsKHVcHfBL9MSBX9cHw5CHPf4uX9hg==","signatures":[{"sig":"MEQCIFXqsWBETT7wjC8XGGcpjhiQT4IWEpzZAlXnTS9m4UMbAiABoBWcxzGIiFx8q/Ga4/O5hTvZMONAM/Ohbe41yawFpg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEQCIGbJ+ni5h8WyE9bjr37jpFIZL4GjQLkzVFwfPky8tNSgAiBnwTb0910OhFLIchRE45VWqOd42M+z9EgGq6msPUB39Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1552672},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"59ab2699965b381f81db98bf509c119eb2d9c8d7","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"overrides":{"nanoid":"^3.3.19","postcss":"^8.5.28"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.11","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.11","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.9_1789450209036_0.6723405713207911","host":"s3://npm-registry-packages-npm-production"}},"0.6.10":{"name":"@bravely-studios/account-web","version":"0.6.10","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.10","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"6b2842613f1081c29d8226b087b4005f6839d009","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.10.tgz","fileCount":203,"integrity":"sha512-uI6Ek2V8jC2xrsOY6OLN3K5geS6Oi+OzCEPpY5UWm3nURUHt/YblAz3AQtijsFUtdV/+NYgkKk0KzyIXrG5xFA==","signatures":[{"sig":"MEUCIHypodJreH8mGcR/7OR6n3sqa1vqSUYer5SVPGiG1if4AiEA1tmXP8X0MO9HeS3om0XwbzqVQhCPn4sAHbkP33WaH+o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCn5CTdrmEaen/06VfNQ8BOr5GjFDqs7RlwM+Sc8T8DCwIgM825XpcpWFgk3Cpd6POLVvP/EvvvoLOmUdfBY29RkNQ=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1565959},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"6357fdf2c5a54e4ec1de91b12fb319d566fbd2bc","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"overrides":{"nanoid":"^3.3.19","postcss":"^8.5.28"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.11","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.11","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.10_1789480538676_0.4636685714556432","host":"s3://npm-registry-packages-npm-production"}},"0.6.11":{"name":"@bravely-studios/account-web","version":"0.6.11","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.6.11","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"018f151e3eecdc4d1017c576240115326d5bb506","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.6.11.tgz","fileCount":203,"integrity":"sha512-w2hqJrQ72nCK3qpFxDyk6I+4rEDtvUNle2L0vN3gkkFI69zyR5Hxlban1w1ZIrqGk+nd42IL2FgWEhfUxYctnw==","signatures":[{"sig":"MEUCIF8KEGQNfF/VaI3UgLJ/7GZfGzhp+aW7REzQNI45JS5EAiEAgE5oVim4ZmT2oCV5lzF4B+EyYNKfc4X+vVDqjofnYPk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQCOD/cq9LssONFyTV4tinCd5FwEBxXqdHHhvJULk9Il+gIgNUxDEDmhF4qPQv9tk4kAaZLF6qj/M6DeNgARsrBxqWA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1570091},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"62d4db7c4e4e6e9fe5f68ec304989fee426df92b","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"overrides":{"nanoid":"^3.3.19","postcss":"^8.5.28"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.19.1","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.11","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.11","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.6.11_1789520704838_0.8272098017907892","host":"s3://npm-registry-packages-npm-production"}},"0.7.0":{"name":"@bravely-studios/account-web","version":"0.7.0","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.7.0","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"f26e77e3a96f829e700e33f0555f30b3563af639","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.7.0.tgz","fileCount":235,"integrity":"sha512-835gyS5LAmTyDtoIYpJfhk+fXVWq0TKglhLLxYo7g6U5KGKN9M7sN+n1ATAxzxXouebIt+LM6zUA+T4P1ZZqEw==","signatures":[{"sig":"MEYCIQCnsi4f6A0uD4Bmd3Ro16Z4gQS5wWR/d2gR8sJKCU3N6QIhAPqCxe+P0X3ododVjhWJaxlJTIlTPg9+/eX+soM1CxMe","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEYCIQCRzQIApqeTRylp1RWowghpL0o/8t+EaaSXG/xAG2ruGQIhAMLBfhsb5VLwPvJ8ZLVtkT1X2ncZMNX63hwnDd3Q8Z+d","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1811339},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"d8b4eb9ea416bda52bacec302a34b19cc79fa143","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"overrides":{"nanoid":"^3.3.19","postcss":"^8.5.28"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.20.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.11","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.11","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.7.0_1790658080505_0.37965477171326945","host":"s3://npm-registry-packages-npm-production"}},"0.7.1":{"name":"@bravely-studios/account-web","version":"0.7.1","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.7.1","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"21d249144517fa8039547636b2dfe5e68507828e","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.7.1.tgz","fileCount":235,"integrity":"sha512-RMEWIv/KWCmltcvpra1iwXCOUOaykr9mTTt7cJfd7FZhwZRB1i/WICf1fcIaGfpNHl2MJTAcjwO68HWin5J3eg==","signatures":[{"sig":"MEUCIQD1ra3cFo4bKlhVHl5gF/xJozEkC9apPe2mveT3pS0VtAIgX24PXC7X79rzup/9lVRL75Cf4RRsrzubIbP8aahg3/k=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIFvabF4c7uGxe0dDXsqUvFMz+/nYRgS9CnTMatEge0cHAiEAtIliVfpxofDMhOWhShB/bPj9eYM4dmIxhi4weKXm6Lc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1813288},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"3bc74129ac7d8cfb7be0569b7f9ed352d5d8b51e","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"overrides":{"nanoid":"^3.3.19","postcss":"^8.5.28"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.20.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.11","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.11","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.7.1_1790658630360_0.35220939363637216","host":"s3://npm-registry-packages-npm-production"}},"0.7.2":{"name":"@bravely-studios/account-web","version":"0.7.2","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","_id":"@bravely-studios/account-web@0.7.2","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"85653fae6b14e437572b5a322652871641e7c10c","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.7.2.tgz","fileCount":235,"integrity":"sha512-UcB/oms5dX7dqPVWyW78KCdbQn3fMmaKEgZk7EC5D5iWK0wxguX33JoBTisnbDxh5z3JOvUl86bCxYQ56v71kA==","signatures":[{"sig":"MEUCIEk8pIK8KAJ5ITjpG7Eu4oEGRgSk4zmQ55jZXgKzTan+AiEAyWvIREYdZQNoOWHRwBjLHePbzoVxyhIntXcgpf8cfuk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIQClZDZC3f+etyCtMMsltkBtHPeEzVk7WRMp6vcpV3YjkwIgMvLtiglHK1+KoxrhJN6JIQS3ySS38jQGHBrnTaKN840=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":1816896},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"3a0240ef707643dd0a46e1836ac054ddc509abde","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"overrides":{"nanoid":"^3.3.19","postcss":"^8.5.28"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.20.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.11","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.11","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/account-web_0.7.2_1790670263279_0.3995867123790737","host":"s3://npm-registry-packages-npm-production"}},"0.7.3":{"_id":"@bravely-studios/account-web@0.7.3","bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"dist":{"shasum":"09ed5fee8f8dc32e772a65b8cf172aec5e9ae59a","tarball":"https://registry.npmjs.org/@bravely-studios/account-web/-/account-web-0.7.3.tgz","fileCount":235,"integrity":"sha512-eeJNWseRlTs99eFp7/p0yyUNQOdEb8iXKiVWcv0h1zgBtJcN7R45S8dbRRFJN80pkOM7yttVuR6JGwWml0Anaw==","signatures":[{"sig":"MEUCIQDklcNfsRuvfL9ZZH1J48P5FTajoxjmT9UTz7lNzVgKuwIgMGKmOt677/yONgc/C9E+uY0AjI1CNI4uozYcU/xmADo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCgjOa8wslHXHGGODntTIL5mPWUR4Z3gAYC1+GWctox0QIgOgs1x7NpnQjvwrceohY8/5wbEvHCAFeCfBzikPUqzp4="}],"unpackedSize":1822445},"main":"dist/index.js","name":"@bravely-studios/account-web","type":"module","types":"dist/index.d.ts","author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"engines":{"node":">=20"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"},"./server":{"types":"./dist/server.d.ts","import":"./dist/server.js"}},"gitHead":"a8a38b5c2d44a05f92075ac2e50535820d079242","license":"LicenseRef-Bravely-Studios-Proprietary","scripts":{"lint":"tsc --noEmit","test":"vitest run","build":"tsc","typecheck":"tsc -p tsconfig.typecheck.json","test:watch":"vitest","test:coverage":"vitest run --coverage","prepublishOnly":"npm run build && npm run test"},"version":"0.7.3","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"0bf615c5-541e-4eb8-b0ba-e1b369172ece"}},"homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","overrides":{"nanoid":"^3.3.19","postcss":"^8.5.28"},"repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"_npmVersion":"11.20.0","description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","directories":{},"maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"_nodeVersion":"20.20.2","publishConfig":{"access":"public","registry":"https://registry.npmjs.org/"},"_hasShrinkwrap":false,"devDependencies":{"react":"^19.2.6","vitest":"^4.1.11","happy-dom":"^20.9.0","react-dom":"^19.2.6","fast-check":"^4.7.0","typescript":"^5.6.0","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitest/coverage-v8":"^4.1.11","@testing-library/react":"^16.3.2"},"peerDependencies":{"react":">=18.0.0"},"peerDependenciesMeta":{"react":{"optional":true}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/account-web_0.7.3_1790698792172_0.07343819963787657"}}},"time":{"created":"2026-05-13T23:15:11.866Z","modified":"2026-09-29T16:19:52.620Z","0.3.4":"2026-05-13T23:15:12.130Z","0.3.5":"2026-05-14T09:41:32.386Z","0.3.6":"2026-05-15T12:00:23.223Z","0.3.9":"2026-06-04T00:02:34.252Z","0.3.10":"2026-06-05T17:26:50.411Z","0.4.0":"2026-06-11T12:00:10.496Z","0.4.1":"2026-06-11T22:19:07.995Z","0.4.2":"2026-06-13T11:50:26.540Z","0.5.0":"2026-06-14T00:02:08.695Z","0.5.1":"2026-06-15T12:13:43.618Z","0.5.2":"2026-06-21T03:03:28.500Z","0.6.0":"2026-09-12T02:48:32.578Z","0.6.1":"2026-09-12T04:00:38.896Z","0.6.2":"2026-09-12T05:06:14.301Z","0.6.3":"2026-09-12T11:46:38.492Z","0.6.4":"2026-09-12T14:28:15.641Z","0.6.5":"2026-09-12T21:00:19.568Z","0.6.6":"2026-09-13T01:28:28.991Z","0.6.7":"2026-09-14T00:46:32.652Z","0.6.8":"2026-09-14T22:42:01.985Z","0.6.9":"2026-09-15T05:30:09.170Z","0.6.10":"2026-09-15T13:55:38.758Z","0.6.11":"2026-09-16T01:05:05.012Z","0.7.0":"2026-09-29T05:01:20.637Z","0.7.1":"2026-09-29T05:10:30.495Z","0.7.2":"2026-09-29T08:24:23.493Z","0.7.3":"2026-09-29T16:19:52.337Z"},"bugs":{"url":"https://github.com/Bravely-Studios/bravely-account-web/issues"},"author":{"name":"Jeff Schiesser","email":"jeff@bravely.dev"},"license":"LicenseRef-Bravely-Studios-Proprietary","homepage":"https://github.com/Bravely-Studios/bravely-account-web#readme","repository":{"url":"git+https://github.com/Bravely-Studios/bravely-account-web.git","type":"git"},"description":"Bravely Account web facade: OAuth 2.1 + PKCE sign-in, BAS lifecycle, entitlement cache, activation state machine, C-ux M2/M3/M4 components. Used by all 10 utility web variants + bravely.dev.","maintainers":[{"name":"bravely-studios","email":"jeff@bravely.dev"}],"readme":"# @bravely-studios/account-web\n\nThin TypeScript facade over the Bravely identity API for browser-based\nBravely Studios apps. Used internally across the Bravely web app family.\n\n## What it does\n\n- **OAuth 2.1 + PKCE** sign-in via `auth.bravely.dev` — RFC 7636 S256.\n- **Session forever (0.4.0, D4)** — durable IndexedDB session plus the\n  `grant_type=refresh_token` rotation loop: pre-expiry background refresh,\n  401 refresh-then-retry-once, and destructive sign-out ONLY on a definitive\n  `invalid_grant` / 401-after-refresh. Transport failures never wipe tokens.\n- **Login-first screen (0.4.0, D1)** — `<BravelySignInScreen>`: icon + name\n  + ONE value-prop line + the locked provider picker + passive legal links;\n  recoverable offline state; `onShown` seam for `login_screen_shown`.\n  Compact per-step geometry (0.4.1, D3 v1.2): the column caps at\n  `SIGN_IN_COMPACT_MAX_WIDTH` (480px) — sign-in never inherits offer\n  geometry.\n- **3-slot offer grid (0.4.0, D3; 0.4.1 v1.2)** — `<OfferSlotGrid>` + the\n  locked slot-copy factory (`buildOfferSlots`), per-app themes, HEIGHT-FIRST\n  full-viewport scale-to-fit INCLUDING scale-up (scale fills\n  `viewportHeight × 0.92`, width capped at `viewportWidth × 0.95`; clamp\n  [0.5, 3.0], scroll fallback below, no max-width column cap), slot-card\n  baseline row alignment (subgrid; CTA bottom-pinned),\n  `slot_viewed`/`slot_selected` hooks.\n- **Install metrics (0.4.0, D6)** — `getOrMintInstallId()` +\n  `emitAppFirstOpenedIfNeeded()` (persist-first fire-once sentinel; the\n  host fires the actual analytics event).\n- **Entitlement cache** — 72h offline fallback.\n- **Activation state machine** — checkout-to-active flow (v1.1.0: the\n  `user_skipped` lane is removed — no skip/guest affordance).\n- **Paddle account actions** — BAS-authed checkout session and\n  customer-portal session helpers through `identity.bravely.dev`.\n- **`Bravely-Deprecation` handling** — soft warnings + hard\n  `BravelyClientKilledError` on HTTP 426 kill-switch.\n- **DPoP-ready** — RFC 9449 proof generation.\n- **Onboarding v2 (0.6.0)** — the shared launch router, the `AccessState`\n  two-clock rule, the 24-Hour No-Card Trial lane (`startTrial` /\n  `extendTrial` / `requestOnboardingPass` / `requestDownloadEmail`), the\n  headless `OnboardingFlow` step engine, the journey emitter, and the S1-S6\n  surfaces. See **Adopting onboarding v2** below.\n\n## Install\n\n```bash\nnpm install @bravely-studios/account-web\n```\n\n## Usage\n\n```ts\nimport { BravelyAccountManager } from \"@bravely-studios/account-web\";\n\nconst manager = new BravelyAccountManager({\n  authority: \"https://auth.bravely.dev\",\n  appSlug: \"diskaroo\",\n  clientVersion: \"1.3.1\",\n  // Optional: capture SECRET-FREE breadcrumbs (HTTP status + step) from the\n  // auth / checkout / activation / sign-out failure paths into the host's\n  // diagnostic ring buffer. Omit for no-op (no behavior change).\n  log: (event, ctx) => DiagnosticLog.warn(\"bravely-account\", event, ctx),\n});\n\n// On page load\nawait manager.restore();\nmanager.onStateChange((state) => {\n  if (state.kind === \"signed_in\") renderApp(state);\n});\n\n// On a sign-in button click\nawait manager.signIn();\n\n// React 19? Subscribe via useSyncExternalStore — `getState` returns a stable\n// reference between updates (0.2.1+), so no `_cachedState` workaround needed.\n//\n//   const state = useSyncExternalStore(\n//     manager.onStateChange.bind(manager),\n//     manager.getState.bind(manager),\n//   );\n\n// Entitlement gate\nif (await manager.hasEntitlement(\"diskaroo_pro\")) {\n  showProFeatures();\n}\n\n// Paid upgrade\nawait manager.openCheckout(\"annual\");\n\n// Manage subscription\nconst portal = await manager.createPaddlePortalSession();\nwindow.open(portal.url, \"_blank\");\n```\n\n## Module map\n\n| File                                    | Responsibility                                                                    |\n|-----------------------------------------|-----------------------------------------------------------------------------------|\n| `BravelyAccountManager.ts`              | Public facade. Sign-in, sign-out, entitlements, checkout, portal, activation.     |\n| `EntitlementCache.ts`                   | 72h offline cache with TTL + invalidation.                                        |\n| `ActivationStateMachine.ts`             | Port of the canonical activation machine.                                         |\n| `oauth.ts`                              | PKCE S256 helpers + authorize URL builder.                                        |\n| `storage.ts`                            | sessionStorage / IndexedDB / memory adapters.                                     |\n| `dpop.ts`                               | WebCrypto ES256 keypair + RFC 9449 proofs (Gate 2-ready).                         |\n| `deprecation.ts`                        | `Bravely-Deprecation` header parser + error classes.                              |\n| `types.ts`                              | TS types mirroring the OpenAPI 3.1 schemas.                                       |\n| `displayName.ts`                        | Slug → display-name lookup (`diskaroo` → `Diskaroo`).                             |\n| `components/ActivationLadder.tsx`       | **M3** — post-checkout 4-phase ladder (`Activating <App> Pro…`).                  |\n| `components/CrossAppCard.tsx`           | **M4** — third-quadrant card (`You own N Bravely Pro apps on this account.`).    |\n| `components/BravelyProviderButtons.tsx` | Canonical Apple/Google/Email picker — mirrors the Swift SwiftUI surface.          |\n| `components/BravelySignInScreen.tsx`    | **D1** — the login-first first screen (icon + name + value prop + picker).        |\n| `components/OfferSlotGrid.tsx`          | **D3** — locked 3-slot offer grid + copy factory + viewport fit (scale-up).       |\n| `installMetrics.ts`                     | **D6** — install-id mint + fire-once `app_first_opened` sentinel helpers.          |\n| `hooks/useActivationLaneFromUrl.ts`     | **M3** — detect `?upgraded` / `?checkout` / `?subscription` return params.        |\n| `hooks/useFreshLaunchRestoration.ts`    | **M2** — silent rehydrate + brief `Synced N items from your <device>.` toast.     |\n| `version.ts`                            | `LIB_NAME` / `LIB_VERSION` — the wire client version + `lib_version` on journey rows. |\n| `onboarding/launchRoute.ts`             | **v2** — `LaunchRoute` + `decideLaunch()` (welcome → signIn → … → experience → chooser → app). |\n| `onboarding/accessState.ts`             | **v2** — `AccessState`, the two-clock rule, `TrialState`/`PassState`, refresh sources. |\n| `onboarding/copy.ts`                    | **v2** — the ONE copy table + `savePercent()` + banned-phrase hygiene.            |\n| `onboarding/journey.ts`                 | **v2** — `JourneyEmitter`, the allowlisted step vocabulary, claim-once first value. |\n| `onboarding/nudgePolicy.ts`             | **v2** — the ≥4h trial nudge gate (persisted `last_nudge_at`).                    |\n| `onboarding/installState.ts`            | **v2** — per-install `firstRunCompleted` (the `welcome` route's gate).            |\n| `onboarding/flow.ts`                    | **v2** — the headless step engine + signals + host adapter + resume state.        |\n| `hooks/useOnboardingFlow.ts`            | **v2** — React bindings for the engine + `useAnchorRect()` for the coach mark.    |\n| `components/WelcomeScreen.tsx`          | **v2 S1** — lockup + ONE promise line + Get started.                              |\n| `components/TrialChooser.tsx`           | **v2 S4** — the two-door chooser (See Offers Now / Try Now, No Card Required).     |\n| `components/OffersPage.tsx`             | **v2 S4b** — the grid + headline + `← Back`, and `<FinalPaywall>`.                |\n| `components/TrialNudge.tsx`             | **v2 S6** — the ≥4h nudge (slots + Keep Trying for Free).                          |\n| `components/TrialExpiryChooser.tsx`     | **v2 S5** — first expiry: See Offers / +24 Hours.                                 |\n| `components/TrialChip.tsx`              | **v2 S6** — `24-Hour Trial · 19h 40m left` + See offers.                          |\n| `components/CrossDeviceStep.tsx`        | **v2 S3** — the corridor: email the link + the three ways (selectable URL).       |\n| `components/GuidedStepOverlay.tsx`      | **v2 S3** — the coach mark (scrim with a hole) + the 0.9s `<SuccessBeat>`.        |\n| `components/onboardingChrome.tsx`       | **v2** — surface tokens, the two button shapes, the account footer.               |\n\n## C-ux M2/M3/M4 exports (0.2.0)\n\nWave A of the C-ux M2-M4 rollout (`cux-m2-m4-rollout-plan.md`). New exports\nlet the four D-Web variants — `prodjectly`, `scry-web`, `printscreenly-web`,\n`todoingly-web` — mount the foundational surfaces in Wave B-D.\n\n### `<ActivationLadder>` (M3)\n\n```tsx\nimport { ActivationLadder } from \"@bravely-studios/account-web\";\n\n<ActivationLadder\n  state={manager.getActivationState()}\n  appSlug=\"diskaroo\"\n  orderId={paddleOrderId ?? null}\n  onRetry={() => manager.pollForActivation()}\n  onContactSupport={() =>\n    window.open(\"https://bravely.dev/contact?app=diskaroo&platform=web\")\n  }\n/>\n```\n\nRenders nothing unless the manager is in `post_checkout_activation`.\nAuto-ticks elapsed every second; rolls through the 4 locked phases at\n0/15s/60s/120s. Phase copy is byte-identical to\n`bravely-commerce-router/docs/activation-state-machine.json` — the\ndrift-test in `__tests__/ActivationLadder.test.tsx` enforces it.\n\n### `<CrossAppCard>` (M4)\n\n```tsx\nimport { CrossAppCard } from \"@bravely-studios/account-web\";\n\n<CrossAppCard\n  entitlements={state.entitlements}\n  currentAppSlug=\"diskaroo\"\n  variant=\"card\"        // or \"footer-chip\"\n  dismissible={false}   // journey-doc default = persistent\n/>\n```\n\nRenders nothing when the user has zero cross-app entitlements. Excludes\nthe current app's own `<slug>_pro` from the count; treats\n`bravely_premium` as a single bundle token.\n\n### `useActivationLaneFromUrl()` (M3)\n\n```tsx\nconst { inActivationLane, source, clearUrlParam } = useActivationLaneFromUrl({\n  manager,\n  autoStartPolling: true,\n});\n\nuseEffect(() => {\n  if (inActivationLane) clearUrlParam();\n}, [inActivationLane]);\n```\n\nDetects the three observed post-checkout return URL patterns:\n`?upgraded=true` (prodjectly), `?checkout=complete` (scry-web),\n`?subscription=success` (todoingly-web). Auto-calls\n`manager.notifyCheckoutCompleted()` and, if `autoStartPolling`, kicks\noff `manager.pollForActivation()`.\n\n### `<BravelyProviderButtons>` (0.3.5)\n\n```tsx\nimport { BravelyProviderButtons } from \"@bravely-studios/account-web\";\n\n<BravelyProviderButtons\n  style={{ variant: \"dark\", accent: \"#0ea5e9\" }}\n  isBusy={isAuthorizing}\n  onTap={(provider) => manager.signIn({ loginHint: provider })}\n/>\n```\n\nDrop-in 3-button provider picker (Apple / Google / Email) sized to the\nhosted shell at `auth.bravely.dev`: 48px height, 12px radius, 10px stack\ngap, 14px label. Web-mirror of the Swift `BravelyProviderButtons`\ncomponent, so the iOS/Mac/Web surfaces of the same app look identical.\nPure React + inline SVG; no UI-library or CSS-file dependency. Pass\n`style.accent` as any CSS color string — `color-mix` handles the email\nbutton tint at runtime.\n\n### `useFreshLaunchRestoration()` (M2)\n\n```tsx\nconst fresh = useFreshLaunchRestoration({\n  manager,\n  itemsLabel: \"tasks\",\n  resolveOtherDeviceName: () => null, // Gate 1 fallback\n});\n\nuseEffect(() => {\n  fresh.setSyncedCount(myCollection.length);\n}, [myCollection.length]);\n\nreturn fresh.shouldShowToast ? <Toast>{fresh.toastText}</Toast> : null;\n```\n\nFirst-launch detector. UI is silent for 3 s after sign-in; then `Synced\nN items from your <device>.` shows for the host page to dismiss. The\nbanned phrase family (`Welcome back. Restoring your Pro features`) is\nabsent by design. Gate 1 device-name resolver is null; the hook drops\nthe `from your <device>` anchor automatically.\n\n### Manager additions\n\n```ts\n// Fetch the account-wide display list (0.6.6), excluding this app's key.\nconst others = await manager.refreshCrossAppEntitlements();\n// The existing synchronous getter keeps its Entitlement[] shape:\nconst cachedOthers = manager.crossAppEntitlements();\n// Both read the account display cache. Never use either as an unlock.\n\n// Account-wide entitlement snapshot (0.3.6) — powers M4 cross-app awareness\n// card and the Pro portfolio tile. Returns one row per app in the catalog.\nconst accountEnt = await manager.getAccountEntitlements();\n// accountEnt.apps: AppEntitlement[]  — one row per catalog app\n// accountEnt.active_entitlements: string[]  — all active lookup_keys family-wide\n// accountEnt.subscription: SubscriptionInfo | null\n\n// Post-checkout polling runner — 30 retries × 1s..8s capped backoff.\nconst result = await manager.pollForActivation();\n// result.outcome: \"active\" | \"exhausted\" | \"timeout\" | \"not_signed_in\" | \"unavailable\"\n// \"unavailable\" keeps verification pending and permits a retry.\n\n// Paddle customer-portal session — callers decide how to open the URL.\nconst portal = await manager.createPaddlePortalSession();\n// portal.url is the hosted customer-portal URL.\n```\n\n## Storage adapters\n\n- **`sessionStorage`**: PKCE verifier + state ONLY (single OAuth-dance\n  secrets; they die with the tab by design).\n- **`IndexedDB`**: one atomic `session` record holds `bas`, `refresh_token`,\n  `ba_id`, `email` and `expires_at`, with `version: 1`. Legacy per-key rows are\n  read only when this record is confirmed absent. The entitlement cache,\n  DPoP thumbprint and install metrics also live here. The signing key remains\n  page-scoped; a durable key is deferred until the pre-strict work.\n- **`localStorage`**: the bounded Journey outbox (`journey_pending`) and its\n  deferred-discard marker (`journey_discard_pending`), scoped to the app and\n  installation. No session credentials are stored in it.\n- **In-memory**: explicit test storage or an unavailable-browser fallback.\n  A failed session write retains replacement credentials for this page and\n  retries persistence on subsequent session reads. Sign-in still succeeds.\n\n`manager.getStorageStatus()` reports `{ available, durability }`, where\ndurability is `persistent | session | memory | unknown`. Custom adapters may\nimplement optional `getStatus(key?)`; omitted status means unknown durability.\nA silent browser fallback reports unavailable memory. An unread session/cache\nholds restoration; it never means signed out. A dirty replacement session\nreports usable memory and logs `session_persistence_unavailable` through the\nconfigured logger. Closing the page cannot recover credentials that were\nnever durably written. Browser opens and transactions have 5-second bounds.\n\nHost pages can swap in their own ServiceWorker-backed adapter by passing\n`storage` into the manager config.\n\n## Activation state machine\n\n`getActivationState()` returns the current state from the canonical machine.\nHost pages render UI off the `name` (`restoring_session`, `verifying_entitlement`,\n`entitlement_cached_valid`, `post_checkout_activation`, etc.) and the\n`busy` flag (whether to show a spinner). CLAUDE.md hard rule\n`feedback_no_etas`: never render a predicted ETA — always elapsed time.\n\n## DPoP gate transition\n\n- **Gate 1 (today):** BAS-authed manager requests keep\n  `Authorization: Bearer <bas>` for router compatibility and also attach a\n  valid `DPoP` proof header with `ath`. The server runs in `off` mode and\n  accepts the Bearer scheme without verifying the proof.\n- **Gate 2 (next):** server enforcement can start from real client traffic\n  because `getAppDataToken()`, `openCheckout()`,\n  `createPaddlePortalSession()`, entitlement refreshes, and activation polls\n  already carry proof headers.\n\n## Login-first cutover surfaces (0.4.0)\n\n### `<BravelySignInScreen>` (D1)\n\n```tsx\nimport { BravelySignInScreen, getOrMintInstallId } from \"@bravely-studios/account-web\";\n\n<BravelySignInScreen\n  appName=\"Todoing.ly\"\n  appIconSrc=\"/icon-256.png\"\n  valueProp=\"Every task, every device, always in sync.\"\n  style={{ variant: \"dark\", accent: \"#3B6EF0\" }}\n  isBusy={isAuthorizing}\n  onContinue={(provider) => manager.signIn({ provider })}\n  offline={cantReach}\n  onRetry={() => retryProbe()}\n  onShown={async () => {\n    posthog.capture(\"login_screen_shown\", { install_id: await getOrMintInstallId() });\n  }}\n/>\n```\n\nThe first screen on first launch (spec `onboarding.login_first`). No skip,\nno guest lane, no sign-in/sign-up fork — the screen IS both. `onShown`\nfires once per mount; the host MUST emit `login_screen_shown` there.\n\n### `<OfferSlotGrid>` + `buildOfferSlots()` (D3)\n\n```tsx\nimport {\n  OfferSlotGrid, buildOfferSlots, offerThemeForSlug,\n  planTokenForSlot, telemetryValueForSlot,\n} from \"@bravely-studios/account-web\";\n\nconst slots = buildOfferSlots({ appName: \"Scry\", appSlug: \"scry\", type: \"RVA\" });\n\n<OfferSlotGrid\n  slots={slots} // provisioned slots only — filter before passing\n  theme={offerThemeForSlug(\"scry\")}\n  onSlotViewed={(s) => posthog.capture(\"slot_viewed\", { offer_slot: telemetryValueForSlot(s) })}\n  onSelect={(s) => {\n    posthog.capture(\"slot_selected\", { offer_slot: telemetryValueForSlot(s) });\n    manager.openCheckout(planTokenForSlot(s, \"RVA\"));\n  }}\n/>\n```\n\nThe web sibling of Swift `OfferSlotGrid` / C# `BravelyOfferGrid`: the locked\n3-slot copy (HOOK → GSO → FRONT_LTV) with HEIGHT-FIRST full-viewport\nscale-to-fit including scale-up (v1.2: the scale fills\n`viewportHeight × 0.92`; width binds only as a cap at\n`viewportWidth × 0.95`; clamped to [0.5, 3.0]; scroll fallback below 0.5;\nsingle-column stack under 901px; NO max-width column cap). In the 3-up\nlayout the cards share row tracks (CSS subgrid) so every section row\nbaseline-aligns to its tallest sibling and the CTAs pin to the card bottom.\nThe host fires `paywall_shown` when it presents the page.\n\n### Install metrics (D6)\n\n```ts\nimport { getOrMintInstallId, emitAppFirstOpenedIfNeeded } from \"@bravely-studios/account-web\";\n\n// At app entry, before any UI gating:\nconst { installId } = await emitAppFirstOpenedIfNeeded({\n  emit: ({ installId }) => posthog.capture(\"app_first_opened\", { install_id: installId }),\n});\nmanager.setInstallId(installId); // every auth exchange now carries install_id\n```\n\nPersist-first sentinel: the durable IndexedDB sentinel row is written BEFORE\nthe emit, so a crash can only under-count — never double-fire.\n\n## Adopting onboarding v2 (0.6.0)\n\nThe \"solve once\" layer for the family onboarding overhaul. Contracts:\n`05 - Business/Bravely/onboarding-v2/contracts/lib-contract.md` (this API),\n`api-contract.md` (the server shapes),\n`00 - AI Instructions/onboarding-v2-trial-model.md` §3-§7 (behavior + the copy\nbank), `onboarding-v2-experiences.md` (the per-app step lists),\n`onboarding-v2-journey-capture.md` (the telemetry).\n\n**Nothing here is opt-in copy.** Strings come from ONE table\n(`onboardingCopyFor(appName)`); a host may not pass its own. Prices drive the\nsaving (`savePercent`), so \"20%\" is never typed into a string.\n\n### 1. Wire the journey once, at the root\n\n**You do NOT wire tokens, a sink, or an analytics transport for the journey.\nThe lib owns it.** Take the emitter off the manager and provide it:\n\n```tsx\nimport { JourneyProvider } from \"@bravely-studios/account-web\";\n\n<JourneyProvider journey={manager.journey}>{children}</JourneyProvider>;\n```\n\nThat is the whole integration. `manager.journey` posts every step itself to\n`POST /api/analytics/events` on the same authenticated transport\n`getEntitlements` uses — `Authorization: Bearer <BAS>` plus the DPoP proof,\nwith the bearer read from storage **before each send**. Before sign-in,\n`welcome_shown`, `login_screen_shown`, and all other steps wait locally in a\nqueue of at most 32 rows; overflow drops the oldest. The default browser\nadapter persists this installation's queue so Welcome can survive a reload.\nThe manager drains it on session restoration/sign-in, before later steps,\nwith each row's original ISO `client_ts`. `journey.flush()` also attempts a\ndrain; with no bearer it leaves the rows queued. Disabled Journey queues and\nposts nothing. Custom sinks/transports continue to own their authentication\nand delivery behavior.\n\nEvery v2 surface then emits its own step with `install_id`, `platform: \"web\"`,\n`app_version`, `lib_version` and `client_ts` at the body root. Capture is\nguaranteed by construction — you cannot adopt the flow and skip the telemetry.\n\n> **Why this changed in 0.6.2.** Until 0.6.1 this section told you to pass a\n> `sink` pointed at \"your PostHog + `/api/analytics/events` path\". That advice\n> was the bug. The router writes a `journey_events` row **only for an\n> authenticated post** (`handleNativeAppEvent` gates the insert on\n> `baIdVerified`), and no app's analytics transport carries the BAS bearer. An\n> unauthenticated post still returns 200, still lands an ordinary\n> `analytics_events` row, and raises no error, so every app wired as documented\n> shipped green and reported an **empty journey funnel**. Delete any\n> journey sink, session-token provider, or \"point the journey at our analytics\"\n> wiring you added; there is nothing to replace it with.\n\n`JourneyEmitterConfig.sink` still exists, and supplying one **REPLACES** the\nbuilt-in post rather than running alongside it (two transports would double\nevery row, and a doubled impression halves every conversion rate computed from\nit). Use it to observe emission in a test, or if you genuinely have an\nauthenticated transport of your own. Otherwise, do not pass it.\n\nOne row is yours to fire, because no component owns it:\n\n```ts\njourney.emitAppLanded(manager.getAccessState().kind); // once, when the app renders\n```\n\n`manager.journey.enabled = false` disables Journey locally (default on):\ndiscard pending rows and prevent new queue additions, posts, install-id lookups\nand claim-once writes. An unread queue retains a deferred-discard marker until\nit can be read and purged. Construction also accepts\n`new JourneyEmitter({ enabled: false, ...config })`. Re-enabling permits new\nevents; it does not replay discarded queued events. `flush()` remains available.\n\nSince 0.6.5, `app_landed` is claimed once per browser installation, before\nsending, in the existing `onboarding_state` row. Reloads, remounts and account\nchanges keep the claim. `flow.reset()` drains pending journey work and clears\nthat row; a new emitter can then claim again. The per-run guard avoids repeated\nstorage reads. If the claim cannot be persisted, the landing is dropped; other\njourney steps remain fail-soft.\n\nIn 0.6.8, a failed first-value claim read/write retains the action and its\noriginal timestamp in memory for retry on `flush()`. It returns false until the\nclaim is committed. An unread pre-auth outbox keeps disk records intact and\nreconciles page additions only after a successful read. Unread nudge history\nsuppresses nudges; direct `readLastNudgeAt()` callers must handle its rejection.\n\nBefore navigation or teardown that your app controls, await the queue:\n\n```ts\nmanager.journey.emitAppLanded(manager.getAccessState().kind);\nawait manager.journey.flush();\n// Now navigate or tear down the page.\n```\n\n`flush(): Promise<void>` drains pending claims and the ordered, one-at-a-time\nsend queue. It never rejects. An optional browser fallback is:\n\n```ts\nconst flushJourney = () => { void manager.journey.flush(); };\nwindow.addEventListener(\"beforeunload\", flushJourney);\n// On cleanup: window.removeEventListener(\"beforeunload\", flushJourney);\n```\n\nBrowsers do not await promises returned by unload handlers. Await `flush()`\nbefore initiating navigation where possible; the built-in transport also uses\n`fetch` with `keepalive: true`. Abrupt closure or offline delivery can still\nlose a claimed row; persist-first prevents that failure from duplicating it.\n\nThe rest of the spine is lib-owned. `manager.startTrial()` emits\n`trial_started` itself; `<BravelySignInScreen>` emits `login_screen_shown`; and\nif you render your own sign-in surface, `flow.emitLoginScreenShown()` /\n`flow.emitSignInCompleted(provider, isNewUser)` spell the names for you. There\nis deliberately **no** `emitTrialExtended()`: `trial_extended` is server-written\n(the router does not accept it from a client), so a successful `extendTrial()`\nemits nothing.\n\n**CORS.** The browser posts straight to `identity.bravely.dev`; the router's\npreflight allows `Authorization` and `DPoP`, and its origin allowlist is\n`https://bravely.dev`, any `*.bravely.dev`, and localhost/127.0.0.1. An app\nserved from a short brand domain or a customer custom domain gets no CORS\nheaders and the browser blocks the post — which fails soft (emission never\nthrows) but reports nothing, so keep app surfaces on `<app>.bravely.dev`.\n\nA storage failure (private window, blocked site data) costs the durable\ninstall id, never the row — the emitter falls back to an in-memory one.\n\n**Tests inject storage.** Every storage-backed seam takes one:\n`new JourneyEmitter({ storage })`, `new OnboardingFlow({ storage })`,\n`new NudgePolicy({ storage })`, `new BravelyAccountManager({ storage })`,\n`getOrMintInstallId(storage)`, `isFirstRunCompleted(storage)`. Pass\n`memoryStorage()` in tests so a run never touches the real first-run,\nfirst-value or last-nudge sentinels.\n\n### 1b. Server-safe entry\n\nAnything without React — a Next.js Route Handler, an RSC module, a script —\nimports the subpath instead:\n\n```ts\nimport { decideLaunch, onboardingCopyFor } from \"@bravely-studios/account-web/server\";\n```\n\nThe root entry pulls in the surfaces, and `journeyContext.tsx` calls\n`createContext` at module scope, which kills `next build` when a route handler\nimports it. `/server` carries the manager, routing, access state, copy, the\njourney emitter + transport, install metrics, storage, DPoP and the activation\nstate machine — and a test walks its import graph to fail if any of it ever\nreaches React.\n\n### 2. Route the launch\n\n```ts\nimport {\n  decideLaunch,\n  isFirstRunCompleted,\n  markFirstRunCompleted,\n} from \"@bravely-studios/account-web\";\n\nconst decision = decideLaunch({\n  firstRunCompleted: await isFirstRunCompleted(),\n  isSignedIn: manager.getState().kind === \"signed_in\",\n  sessionUnavailable: manager.getState().kind === \"session_unavailable\",\n  access: manager.getAccessState(),\n  freshSignIn,            // true only after a completed sign-in this session\n  consentRequired,        // your jurisdiction check\n});\n```\n\n`decision.route` is one of `welcome | signIn | signInAccountAware |\nconsentConfirm | experience | trialChooser | app`. **`decision.provisional === true` means\nverification has not resolved**. This includes unread session/cache storage and\na refresh-only session awaiting a recoverable refresh. Render your neutral\nverifying state (nothing gated, no paywall) and retry `restore()` when storage\nor connectivity recovers. Carry `session_unavailable` through host wrappers;\nthe router flag holds even before the first-run/auth gates. `signInAccountAware`\nis the ADR-0032 re-entry screen: pass `signedInEmail` + `onContinueToPlans` +\n`onUseDifferentAccount` to `<BravelySignInScreen>`; never route a relaunching\nunentitled customer straight to the paywall.\n\nThe convenience helpers `decideLaunchRoute()` and `routeAfterExperience()`\nreturn `LaunchRoute | \"hold\"` in 0.6.8. Handle `hold` explicitly; callers that\nneed the full decision can use `decideLaunch()` or `decideOnboarding()`.\n\n**A non-answer must never overwrite an answer — and the money surface is a\nPRECONDITION, not a pending flag.** An unresolved entitlement read (a page\nnavigation, a transient failure, a refresh in flight) derives `unknown`, and\nrouting `unknown` as if it were a verdict breaks in both directions: it hands a\npaid app to an unentitled customer, and it flashes a paywall at a payer. Take\nthe access state from `manager.getAccessState()` (or run your own\n`deriveAccessState` calls through `AccessStateTracker`), which keeps the last\nRESOLVED answer while nothing new has landed and re-derives it against the\ncurrent clock so the two-clock rule still holds.\n\nThen gate the render on the DECISION, never on a \"loading\" boolean:\n\n```tsx\nconst decision = decideLaunch({ /* … */ });\nif (decision.provisional) return <YourNeutralVerifyingState />; // no paywall, nothing gated\nswitch (decision.route) { /* … */ }\n```\n\nThe money surface renders because routing said so. A host that renders it\nwhenever a flag is not yet false will show it during every verification pass.\n\n**`subscription.active` does not mean \"they bought it\" (0.6.3).** The FREE\n24-hour no-card trial is mirrored into RevenueCat as a **promotional**\nentitlement, and the router reports that back as\n`subscription: { active: true, platform: \"promotional\", expires_at: <the\ntrial's expiry> }`. Admin comps look the same. So the block is only ownership\nwhen a real store and this app's key establish ownership. Use\n`manager.getAccessState()` or `deriveAccessState()` for that decision; the\nlibrary checks the store and app scope together. `isPaidSubscription(active,\nplatform)` classifies store evidence only.\n\nIn 0.6.5 the subscription also needs this app's `<slug>_pro` key or\n`bravely_premium`; another app's subscription does not establish ownership.\n`isPaidSubscription()` retains its two-argument signature and checks the store\nonly. Hosts using the manager's access/activation verdict need no additional\nstore-plus-app-key check. Router 0.11.9 scopes `subscription`, `override` and\n`active_entitlements` to `?app=`; the account-wide read is display data only.\n\nThe persisted entitlement row now keeps its account/app identity, trial/pass\nclocks, subscription evidence, override flag and router `fetched_at` together.\nA legacy key-only cache is unresolved until confirmed. Known temporary expiry\nwins even after 72 hours; real cached purchases retain their 72-hour allowance.\nInline auth keys without ownership evidence cannot create a purchased cache.\n\nReads preserve a live local trial when their router timestamps cannot describe\nthat grant, including a missing trial block. A newer authoritative revocation\nstill applies. Stale start/extension conflicts trigger a fresh confirmation.\nNamed `trial`, `extension`, `checkout`, `activationPoll` and `offerOpen` reads\nsend `X-Bravely-Activation-Poll: 1`; routine `launch`, `auth`, `restore`, `gate`\nand `managerState` reads retain the edge cache. One `offerOpen` means one\nopen/resume, never a polling source, and the bypass HEADER is floored at\n`MONEY_SURFACE_BYPASS_FLOOR_MS` (10s) so an alt-tab storm or a remounting effect\ncannot spend the account's router budget; a floored open still reads, it just\ntakes the edge copy. The post-grant sources are never floored. A limited 200\nuses the cached answer and\nends that open's read. A 429 retries plain after `Retry-After` at the bounded\nladder's pace, keeping the previous access answer (or unknown). Activation\nkeeps its own cadence, uses limited bodies and never treats a 429 as an\ninactive entitlement. Legacy `confirmation: true` without a named source keeps\nits existing header behavior.\n\nActivation polling confirms ownership with the same app/store rule, an explicit\noverride, or the universal bundle key (including lifetime). A live pass, trial,\npromotional mirror, unrelated purchase or unqualified bare app key cannot\ncomplete checkout. Per-app lifetime purchases require store/override provenance;\na bare key beside temporary access is insufficient evidence.\n\n`decision.reason === \"reconnect_required\"` is the other one to handle: the\ncache is past 72h and no read has landed, so we do NOT know they are\nunentitled. Same screen, different sentence — show \"reconnect to continue\", not\n\"No active plan found\".\n\nCall `markFirstRunCompleted()` when the customer taps **Get started** (the flow\nengine also does it when S3 finishes).\n\n**The routing table resolves in this order (0.6.2).** Two rules used to\ncontradict each other on \"pass active + purchased\"; this is the resolution:\n\n1. **Entitled / purchased?** First run ⇒ `experience`, with every step optional,\n   then the app. Not first run ⇒ `app`.\n2. **Else onboarding pass active?** The 60-minute pass is *never* a route to the\n   app — it exists only so S3's server-gated first-value steps work\n   (`onboarding-v2-trial-model.md` §6/§7). Experience incomplete ⇒ `experience`;\n   experience complete ⇒ `trialChooser`.\n3. **Else** the unentitled rules above.\n\n`experience` is the new route: the person is signed in and past S1, so\nre-showing Welcome would ask them to start something they are already inside.\nRoute it to the same S3 surfaces `welcome` leads into.\n\n### 3. Run the experience\n\n```tsx\nconst flow = new OnboardingFlow({\n  config: {\n    appSlug: \"printscreenly\",\n    appName: \"PrintScreen.ly\",\n    promise: \"Screenshots and recordings that look right the first time.\",\n    valueType: \"RVA\",\n    steps: [\n      { kind: \"permission\", id: \"screen\", permission: \"screen_recording\", title: \"…\", body: \"…\" },\n      {\n        kind: \"guided\",\n        id: \"capture\",\n        title: \"Take your first screenshot\",\n        ask: \"Press\",\n        hotkey: { display: settings.captureHotkey }, // the LIVE binding, never hardcoded\n        anchor: { id: \"capture-button\" },\n        signal: \"first_capture\",\n      },\n    ],\n  },\n  journey,\n});\n\nawait flow.start();\n// …from your capture pipeline, when the shot actually lands:\nflow.signals.fire(\"first_capture\");\nvoid flow.reportFirstValue(\"first_capture\"); // claim-once per install\n```\n\nRender with `useOnboardingFlow(flow)` and `<GuidedStepOverlay>` /\n`<CrossDeviceStep>`; use `useAnchorRect(el)` to feed the spotlight a live rect.\nA guided step advances ONLY when its signal fires — wire the signal end to end\nor the step is a dead end.\n\n**Fire it whenever it happens; the engine cannot lose it (0.6.4).** The\nsubscription is armed BEFORE the step is persisted, before `host.present()` and\nbefore the awaited `onboarding_step_shown` post, and a signal that arrives while\nthat presentation is still in flight is held and honored the moment it finishes.\nSo firing from inside your own `present`, or from a listener that runs during\nthe telemetry post, is safe. What is still true: a signal fired BEFORE its step\nis shown does not pre-complete it — the bus is per-occurrence on purpose.\n\nAfter `await flow.hydrate()`, call `flow.decide(manager.getAccessState())`.\nThis uses Swift's post-auth table and grants owners/active trials Skip on every\nstep, including permissions. `flow.skip()` otherwise requires an optional\nstep. The pure forms are `OnboardingFlow.decide(access, state, hasSteps)` and\n`decideOnboarding(access, experienceCompleted, hasSteps)`. Unfinished experiences\nrun for every access state; afterward only owners/active trials reach the app.\n`unknown` and `reconnectRequired` answer `\"hold\"`: no answer has arrived, so the\nhost keeps its neutral verifying state and decides again. `decideLaunch` and\n`routeAfterExperience` have no room for a fourth value, so they render the hold\nas the `app` route with `provisional: true` — never the chooser, and never the\naccount-aware \"No active plan found\" screen.\n`flow.start()` never replays a completed experience; `flow.reset()` is the\nexplicit replay.\n\nA `crossDevice` step with `target: \"mobile\"` asks which phone and emails the\nstore links; `target: \"desktop\"` asks which computer. Wire `onEmail` straight\nto `manager.requestDownloadEmail({ platform, context, target })`.\n\nAfter it finishes, `routeAfterExperience(manager.getAccessState())` sends the\ncustomer to the app or to the chooser.\n\n### 4. The money surfaces\n\nUse this headless lifetime handle once for each wall, chooser, expiry chooser\nor final paywall. It owns one read on open and one per browser resume, with\nvisibility/focus deduplicated. Close it when the surface leaves; a custom host\ncan call `resume()` for its own lifecycle. Existing `source: \"offerOpen\"` calls\nremain supported when the host supplies one per open/resume.\n\n```ts\nconst money = manager.openMoneySurface();\nawait money.ready;\n// Re-read manager.getAccessState() before choosing the screen.\n// Subscribe to manager.onStateChange for resume results.\n// On the surface's cleanup:\nmoney.close();\n```\n\n```tsx\n// S4 — the chooser. `tryNowAvailable` is false once a no-card grant exists.\n<TrialChooser\n  appName=\"PrintScreen.ly\"\n  tryNowAvailable={manager.trial?.kind !== \"no_cc_24h\"}\n  onSeeOffers={() => setScreen(\"offers\")}\n  onTryNow={async () => {\n    const r = await manager.startTrial({ platform: \"web\" });\n    if (r.outcome === \"granted\") return setScreen(\"app\");\n    if (r.outcome === \"already_used\") return setScreen(\"expiry\"); // S5 rules\n    if (r.outcome === \"already_entitled\") return setScreen(\"app\");\n  }}\n  style={{ variant: \"dark\", accent: \"#ff6b6b\" }}\n  email={email}\n/>\n\n// S4b — the offers page. Confirm on open, then render.\nawait manager.getEntitlements({ source: \"offerOpen\" });\n<OffersPage\n  appName=\"PrintScreen.ly\"\n  slots={buildOfferSlots({ appName: \"PrintScreen.ly\", appSlug: \"printscreenly\", type: \"RVA\" })}\n  theme={offerThemeForSlug(\"printscreenly\")}\n  style={style}\n  from=\"chooser\"\n  onBack={() => setScreen(\"chooser\")}\n  onSelect={(slot) => manager.openCheckout(planTokenForSlot(slot, \"RVA\"))}\n/>\n```\n\nWith `manager.journey`, built-in offer, final-wall and nudge impressions\ninclude `intro_eligibility` without host properties: `used` for store-intro or\nlegacy trials and a remembered real-store subscription serving this app's key;\n`eligible` for an explicit no-trial wire with no such history; otherwise\n`unknown`. `manager.getIntroEligibility()` exposes the same local verdict.\nAn explicit `impressionProps.intro_eligibility` overrides it on `OffersPage`,\n`FinalPaywall`, or `TrialNudge`. This is impression context, never an unlock.\n\nThe page renders the headline and nothing else above the grid. There is no\ndefault sub-headline: a shared money surface cannot make a platform or feature\nclaim on behalf of nine different apps. Pass `subhead` if YOUR app has a true\none.\n\n`from` is where the customer came FROM, and it is a measurement, not a label —\npick the true one. `chooser` / `nudge` / `expiry` / `chip` are the v2 trial\nsurfaces; `final` is the post-extension wall. **`in_app` (0.6.3) is any entry\nfrom inside the app that is none of those** — Settings ▸ Subscription ▸ See\nplans is the canonical one:\n\n```tsx\n<OffersPage from=\"in_app\" onBack={closeSheet} /* … */ />\n```\n\nIt renders as a SHEET (Close, not \"← Back\") and its Close emits no\n`offers_back`, so `onBack` is required — a sheet with no way out is a wall.\nNever report one of these as `chip` to reuse an existing value: the chip funnel\nmeasures one specific trial affordance, and Settings visits mixed into it\ninflate chip impressions, deflate chip conversion, and cannot be split back out\nafterwards.\n\nS6: mount `<TrialChip>` while `accessState.kind === \"trialActive\"`, and gate the\n`<TrialNudge>` with `NudgePolicy` (≥4h in, ≥4h since the last, once per session,\nnever mid-action). S5: `<TrialExpiryChooser>` while\n`trialExpired.extensionAvailable`, `<FinalPaywall>` after that.\n\n### 5. What you must NOT do\n\n- No fourth tile in the grid. The chooser and the no-card door are SIBLING\n  screens (`OfferSlotGrid` stays exactly three slots).\n- No \"maybe later\", \"skip for now\", \"continue free\", or \"all 9 apps for $95.99\"\n  — `findBannedPhrases()` is the check, and it also bans vendor names.\n- Never call the trial \"free pass\", and never call the onboarding pass a trial.\n- Never gate S3 behind an entitlement — use `requestOnboardingPass()` for a\n  server-gated first-value step.\n- Never render a money surface while `accessState.kind === \"unknown\"`.\n- Never hardcode a hotkey; read the app's live binding.\n- Never put an em dash in customer copy, and never state a platform or feature\n  claim you have not grepped. The both-theme render sweep in\n  `__tests__/onboardingSurfaces.test.tsx` is the check, and since 0.6.1 it\n  renders the offer CARDS too — there is no locked-copy exemption left.\n- Never wire your own journey sink, session-token provider, or analytics\n  transport for the journey. The lib owns the authenticated post; a sink turns\n  it OFF (see §1).\n- Never say \"Restore purchases\". It is \"Sync purchases\", family-wide\n  (`bravely-account-user-journey.md` anti-pattern #15) and `findBannedPhrases()`\n  now covers the fixed spellings.\n- Never open the chip's offers page without `onBack`: §4 makes it a SHEET, the\n  component renders that affordance as **Close** for the chip origin, and the\n  Close is what produces the lane's only terminal journey row. `in_app` is a\n  sheet too and needs `onBack` for the same reason.\n- Never read `subscription.active` as ownership on its own — the FREE no-card\n  trial and every admin comp report `{active: true, platform: \"promotional\"}`.\n  Use `isPaidSubscription(active, platform)` (§2).\n- Never borrow another surface's `OffersOrigin` for an entry that has its own.\n  A wrong `from` is not a cosmetic error; it corrupts the funnel it lands in,\n  permanently and un-splittably.\n- Never count the family up for the customer. They buy ONE app and get a ton\n  of free stuff, so the pitch is \"<App> Pro for a year, plus all 8 other\n  Bravely apps, free\" — never \"9 apps in all\" / \"all 9 apps for $95.99\".\n  `findBannedPhrases()` covers both.\n- Never paint light-mode TEXT or a STROKE with the raw accent, and never fill\n  with `accentInk`. Fill takes `accent`, ink takes `accentInk`\n  (`light-mode-color-ladder.md` §3). The lib derives the light ink for you —\n  `surfaceTokens()` for the chrome, `offerLightInks()` for the offer roles — so\n  you only pass `accentInk` yourself if you MEASURED your own greys.\n\n### 6. Checking the light theme\n\nBoth themes ship on every surface, and light is opt-in (never inherited from\nthe OS). Every web app exposes the same review affordance: append\n`?ov2theme=light` to any onboarding v2 URL for the light set and\n`?ov2theme=dark` for the dark one. Sticki.ly is light-first, so there the\nparameter you need is `?ov2theme=dark`.\n\nSince 0.6.4 the light variant DERIVES its ink from your accent instead of\nsubstituting a neutral, so what you should see with `?ov2theme=light` is the\nbrand colour, deeper — accent-tinted text and strokes that are still recognisably\nyours, an accent-ink hairline around the primary CTA, and no change at all to a\nfill. Anything that reads as washed-out yellow-on-white, or as a colour that is\nnot the app's, is a bug: `lightInk(accent)` is the value the surface should be\nusing, and it is exported so you can check one in a console.\n\n## Diagnostics v2: `bravelyDiagnostics` (0.7.0, pin 0.7.3 or later)\n\nWhat a \"Send Diagnostic Report\" upload carries, built once for every web app\n(the family's diagnostic-report-v2 spec, §8.5 for web): the breadcrumb trail\n(the app's analytics events, the journey, screens, marks), `ui_state` (the\nworking surface when the report is taken), `env`, the errors ring with problem\ncodes, and the one redactor. It is the web port of bravely-account-msal's\n`BravelyDiagnostics`, and it passes the reference's 61 redaction vectors and\n§3.6 breadcrumb vectors in this repo's tests. Every\ncall is synchronous and in memory, never throws, and is exported from both\n`@bravely-studios/account-web` and `@bravely-studios/account-web/server`.\n\n**The library does these itself; apps wire nothing for them:** the journey's\nown steps (`src: lib`, recorded before the journey's consent and transport\ngates), the signed-in account and `access_state` (the manager attaches itself),\n`network` (`navigator.onLine`), page lifecycle (`visibilitychange`),\n`focus_kind` (`document.activeElement`), `env` (`display_px` is the screen in\nCSS pixels, `display_scale` is `devicePixelRatio` including the browser's zoom,\nand the UTC offset), and the family vocabulary. Web has no freeze watchdog and no\n`prev_session` (§8.5, §12), so there is no `recordCrash`, `markCleanExit` or\nlibrary-started auto report here.\n\n**An app wires these (v2 §11):**\n\n```ts\nimport {\n  bravelyDiagnostics, filterBreadcrumb, mergeVocabulary, familyVocabulary, REPORT_SURFACE_ATTRIBUTE,\n} from \"@bravely-studios/account-web\";\n\n// 1. Once at startup, before the first event: the app's §4.x vocabulary (code constants only).\nbravelyDiagnostics.configure(\"asapdf\", ASAPDF_DIAGNOSTICS_VOCABULARY);\n\n// 2. The FIRST line of the analytics choke point, above the opt-out check, with the caller's props.\nexport function track(event: string, props?: Record<string, unknown>): void {\n  bravelyDiagnostics.recordEvent(event, props);\n  if (optedOut) return;\n  // …\n}\n\n// 3. The navigation owner: a root-layout effect mapping route PATTERNS (never a filled-in path) to tokens.\n//    Settings, Help and About routes push nothing (§4.3): the report keeps the working screen.\nuseEffect(() => {\n  const token = screenTokenFor(pathname); // null for /settings, /help, /about\n  if (token) bravelyDiagnostics.setScreen(token);\n}, [pathname]);\n//    The library's onboarding screens do NOT call setScreen: push their tokens where you show them.\nbravelyDiagnostics.setScreen(\"trial_options\"); // and sign_in, offers, trial_expiry, final_wall (hold, welcome, onboarding)\n\n// 4. The ui_state provider: reads the app-level store, memory only.\nbravelyDiagnostics.setUiStateProvider(() => ({\n  modal: \"none\", modes: [], active_tool: tool, selection_kind: \"none\", doc_state: docState,\n}));\n\n// 5. The log facade: raw text in for warn and error, redacted text stored; drop lines from a previous account.\nfunction logWarn(category: string, raw: string, code?: string, error?: unknown): void {\n  bravelyDiagnostics.recordProblem(\"warn\", category, raw, code, error);\n  ring.push({ ts: new Date().toISOString(), level: \"warn\", category, msg: bravelyDiagnostics.redact(raw) });\n}\nbravelyDiagnostics.onAccountChanged((before) => ring.dropAtOrBefore(before)); // and any line with no readable ts\n\n// 6. Every mode gate that drops or downgrades input, and the safety net once.\nbravelyDiagnostics.mark(\"input_ignored\", { reason: \"field_review\", target: \"field\" });\nbravelyDiagnostics.installUnhandledInputNet();\n\n// 7. The uploader (v2 §6): v1 extra keys + the report's v2 keys, the merged log, diagnostic.json.\nconst report = bravelyDiagnostics.buildReport(\"manual\", analyticsOptedOut);\nconst metadataExtra = report.metadataExtraWith(v1Extra);\nconst diagnosticJson = report.diagnosticJson({ app, v1Extra, appLog: ring.snapshot() });\n\n// 8. So the library's onboarding screens can send one too (coverage S5).\nbravelyDiagnostics.setReportUploader(async ({ surface }) => uploadDiagnosticManual()); // resolves \"DIAG-XXXXX\"\n```\n\n- **Build exactly one `BravelyAccountManager` per page.** The recorder follows the\n  newest manager for the signed-in account and `access_state`, so a second one (a\n  throwaway, or one per component) takes the report with it.\n- **An app line after an account change** stays in the report only when its `ts`\n  is readable and later than `report.accountChangedBefore`; `mergedLogBuffer`\n  applies that rule, and the facade's own ring should too.\n- **Mark the Settings \"Help & Diagnostics\" section** with `REPORT_SURFACE_ATTRIBUTE`\n  (`data-bravely-report-surface`): focus inside it never counts as the working\n  surface's, so a report sent from Settings still says what had focus before.\n- **Catalog test (v2 §3.2):** run every event the app sends through\n  `filterBreadcrumb(name, props, mergeVocabulary(familyVocabulary(), APP_VOCAB))`\n  and assert nothing the app meant to keep comes out dropped or `other`.\n- **The library's own \"Send Diagnostic Report\" action** (`<DiagnosticReportAction>`)\n  sits in the footer of the account-aware `<BravelySignInScreen>`,\n  `<TrialChooser>`, `<OffersPage>`, `<TrialExpiryChooser>` and `<FinalPaywall>`. It\n  shows only while someone is signed in AND an uploader is registered, runs one\n  upload at a time across every surface, and shows the §4.4 / §4.5 dialogs. The\n  uploader must log the DIAG code at info and a failure at warn itself\n  (`bug-report-button-spec.md` §4.8), because a screen that has gone opens nothing.\n  An app screen can render it too: `<DiagnosticReportAction surface=\"hold\" style={style} />`.\n\n## Changelog\n\n### 0.7.3 - 2026-09-29\n\nA small diagnostics patch (no host API change; hosts pin 0.7.3):\n\n- Coalescing and error merging never join across a sign-out or an account switch: a breadcrumb or an error recorded\n  while signed out belongs to whoever signs in next, so it never folds into the previous account's entry (and is no\n  longer dropped with it when a different account signs in).\n- The redactor passes the reference's 61 vectors: a fixed path registered in absolute form under the home folder is\n  kept in its `~` form; `RedactionOptions` takes the optional `fullName` and `computerName` (a browser knows\n  neither), matched before the account and machine names; and R5 and R7 start at the ASCII boundary\n  `(?<![A-Za-z0-9_])`, the patterns every port now carries.\n- Two more version vectors record as `other`: `1.0.0-divorce.pdf` and `2.0.0-katy`.\n\n### 0.7.2 - 2026-09-29\n\nThe independent verify's should-fixes for the diagnostics port (no host API change; hosts pin 0.7.2):\n\n- `exception_type` keeps an error's `name` only when it is an identifier (`^[A-Za-z_$][A-Za-z0-9_$]{0,127}$`),\n  else `other`: any code can set `name`, and a path, a file name or a person's name used to ride through it.\n- After an account change, `mergedLogBuffer` keeps an app line only when its `ts` is readable and later than the\n  change: a line from the change's own millisecond, or one with no readable time, now goes.\n- Problem codes and the library's token mapping read only their tables' own keys (`code: \"constructor\"` used to\n  find `Object`).\n- The redaction tests run the reference's 50 vectors (three sign-in-name case variants were added).\n- The README's \"Diagnostics v2\" section says which screens an app pushes itself, that Settings, Help and About push\n  none, and to build one manager per page. The published comments name no internal paths, and the redactor's\n  private-use slot characters are spelled as escapes.\n- New tests pin what the verify found untested: the account rule through the real manager (sign in as A, act, sign\n  out, sign in as B; the report and the S5 action follow), the `ui_state` deny keys, the 8-token cap, the slot-marker\n  sanitising and the time zone's sign.\n\n### 0.7.1 - 2026-09-29\n\n- The \"Send Diagnostic Report\" dialog balances its body line as well as its title, so \"Share this code with support\n  so we can find your report:\" never ends on one lone word (it left \"report:\" alone at 380 px). The dialog is now its\n  own presentational component (`DiagnosticReportDialog`, internal), which a test renders to markup to prove it.\n\n### 0.7.0 - 2026-09-29\n\n- **`bravelyDiagnostics`: the v2 diagnostic report content** (`diagnostic-report-v2.md`, §8.5 for web), the web\n  port of bravely-account-msal 0.8.1's `BravelyDiagnostics`. The breadcrumb filter with the 2026-09-29 version rule\n  (at most 64 characters; a pre-release part of numbers and channel words only), the 200-entry ring with 60-second\n  coalescing, `ui_state` with its vocabulary checks and the §4.6 budget cut, `focus_kind` from\n  `document.activeElement`, `env`, the 50-entry errors ring with problem codes, the one redactor (R1-R8), the §6\n  assembly helpers and the §3.5 account rule. See \"Diagnostics v2\" above for the wiring.\n- The journey records every step in the report's trail (`src: lib`) before its own consent and transport gates,\n  and records the library's own non-token wire values as the tokens every port reports (`slot: \"GSO\"` → `gso`,\n  `access_state: \"trialActive\"` → `trial_active`, `kind: \"crossDevice\"` → `cross_device`). The wire itself is\n  unchanged. `JourneyEmitterConfig.diagnostics` swaps the recorder (tests; null records nothing).\n- `BravelyAccountManager` attaches itself as the account facade the report follows, so an app wires neither the\n  signed-in account nor `access_state`.\n- **\"Send Diagnostic Report\" on the library's onboarding screens** (coverage S5): `<DiagnosticReportAction>` in the\n  footer of the account-aware sign-in screen, Trial Options, the offers page, the expiry chooser and the final\n  wall, whenever someone is signed in and the app registered `bravelyDiagnostics.setReportUploader(…)`.\n  `AccountFooter` gains a `diagnosticAction` slot; the sign-in footer wraps when it holds three links.\n- Additive: nothing existing changed shape, and an app that wires nothing sees no difference on screen.\n\n### 0.6.11 - 2026-09-15\n\n- The guided-step dim is now pure black at 0.42 opacity on a light host, 0.62 on a dark host — replacing the old\n  violet-tinted `rgba(24, 18, 30, 0.55)` / `rgba(6, 3, 15, 0.74)`, which read as an oddly grey background on a light\n  card (#1373). Every place a guided step dims (the spotlight's cutout and the anchorless full-scrim pane) reads the\n  same token, so they can't drift apart. A host `palette.scrim` override still wins.\n- `<GuidedStepOverlay>` never traps on a step whose anchor did not resolve: the full scrim was already\n  `pointer-events: none` and the card already `pointer-events: auto`, so a click always reached the app underneath.\n  It now also logs one `console.warn` naming the step, so a host's anchor that fails to resolve shows up in the\n  console instead of silently dimming with no spotlight and no trace.\n- `emitAppFirstOpenedIfNeeded()`'s fire-once guard is now keyed by the store an adapter reports\n  (`Storage.getStoreId`) — the same identity `getOrMintInstallId()` already uses — instead of the adapter object\n  itself. Two adapters built over the same origin store (the manager, a journey, a flow, a host's own no-argument\n  call) now share one fire instead of each finding no sentinel and both emitting `app_first_opened`. Flagged as an\n  open item in 0.6.10; fixed here.\n\n### 0.6.10 - 2026-09-15\n\n- Per-account onboarding-experience progress (`onboarding_experience_state:<accountId>`, #1382) is now stored\n  beside the installation's own `onboarding_state` row: IndexedDB, or localStorage where the browser has no\n  IndexedDB. 0.6.9 put it in the tab's sessionStorage, so a signed-in customer's progress ended with the tab and\n  never reached a second tab, and the one-time migration moved an existing customer's completed state out of the\n  installation row into that tab. The migration now writes the adopted row before it strips the installation row,\n  and a strip that fails no longer discards the adoption. A row 0.6.9 left in the current tab's sessionStorage moves\n  to the installation tier the first time it is read, and `remove()` drops it too. Once that tab has closed the\n  progress is gone: nothing is inferred from `appLandedAt`, which belongs to the installation, not to an account.\n- One installation id per installation. `getOrMintInstallId()` shared a mint only between calls on the same adapter\n  object, while the manager, a journey, the onboarding flow and a host's no-argument call each build their own\n  default storage, so one fresh load could mint two ids milliseconds apart and the journey outbox then dropped the\n  first id's rows as another installation's. Mints are now shared by the store an adapter reports (the new optional\n  `Storage.getStoreId(key)`, reported by every built-in adapter and forwarded by the manager's wrapper), run under a\n  cross-tab lock, and adopt what storage holds once the write has landed. A storage refusal or a read that never\n  answers still rejects without minting.\n- Hosts change nothing but the pin. No wire field changed. A custom adapter that wraps another can forward\n  `getStoreId` so its calls join the same mint; one that does not still mints under the lock.\n\n### 0.6.9 - 2026-09-15\n\n- The guided-step spotlight's hole and ring now follow the anchor's own shape\n  (#1373) instead of always cutting a rectangle: `<GuidedStepOverlay>` draws\n  both as ONE element's box-shadow, so a round or pill control never keeps\n  square scrim corners over it. `useAnchorRect` measures the anchor's own\n  corner radius and `AnchorRect` carries it (optional `radius`, CSS px); a\n  control that reports none keeps the existing 12px default. The scrim's dim\n  itself is unchanged.\n- Onboarding-experience progress (current step, per-step state, the completed\n  flag) is now scoped per ACCOUNT, not per install (#1382): pass `accountId`\n  to `OnboardingFlow` (a string, or `null` for signed out) and call\n  `setAccountId()` when the signed-in account changes without a fresh page\n  load. Signing out of one account and into another on the same install — or,\n  since this library shares storage across tabs, a second tab signed into a\n  different account — no longer shows one account another's progress or lets\n  it skip the experience. A pre-existing per-install completed flag is\n  adopted by the first account that signs in after the update, and by no\n  account after that. A host that never supplies `accountId` keeps the exact\n  pre-0.6.9 behavior; `appLandedAt` and the landing claim stay per install\n  either way.\n- `/api/entitlements`'s additive `active_entitlement_details` is decoded when\n  the router sends it, matched onto `active_entitlements` by `lookup_key`:\n  `will_renew`, `expires_at`, `product_id` and `store` now reflect what the\n  router actually knows about a key instead of the previous fabricated\n  `expires_at: null, will_renew: false, store: null` for every key. When the\n  array is absent, not an array, or a key isn't in it, that key keeps exactly\n  the old fabricated default — never a guessed one.\n- Dev-dependency bump only (all six alerts were `scope=development`; this\n  package ships no runtime dependencies): `vitest`/`@vitest/coverage-v8` to\n  `^4.1.11`, and an override pinning the nested `nanoid`/`postcss` `vite`\n  pulls in to `^3.3.19`/`^8.5.28`.\n\n### 0.6.8 - 2026-09-13\n\n- Hold unread session/cache storage and refresh-only offline sessions. Add\n  `session_unavailable`, optional `sessionUnavailable` routing input and the\n  retryable activation outcome `unavailable`. While held nothing unlocks,\n  umbrella keys included.\n- A page that confirmed its session and its access live keeps both when storage\n  stops answering (lib-contract §12). Only a cold page, or evidence past its age,\n  holds; an earlier page's cache never defeats a hold, and evidence without a\n  readable age counts as expired.\n- Persist the session tuple atomically, ordered by a logical `generation`, never\n  a clock. Failed writes keep replacement credentials in memory and retry; a\n  write that lost to a newer sign-in or sign-out is dropped on the next read,\n  never served from memory.\n- Every operation binds its session generation and account before its first\n  await. Refresh results, rejections, OAuth completions, trial or pass answers\n  and requests that land after this page signed out, signed in or followed\n  another account are dropped, and a 401 retry never re-binds to another account.\n- A refresh token is reserved in durable storage (`session_refresh_reserved`, a\n  fingerprint) before it is spent. No other tab presents a reserved token, and\n  the owner rotates its own unsaved replacement.\n- `signOut()` resolves `SignOutResult` (`{ storageCleared }`) and never rejects\n  for storage. It signs the page out before any await, writes a non-secret\n  tombstone (`session_signed_out`: `{ version: 2, id, ends }`) under the session\n  write lock, and deletes only what a read shows it ended. `storageCleared` is\n  false until deferred cleanup finishes, and a reload stays signed out.\n- Every access-bearing read reconciles the durable session, so another tab's\n  sign-in or sign-out is followed without a notice. Access is bound to the\n  account the page serves.\n- `restore()` is single-flight per session, a repeated hold is not re-announced,\n  and a page already serving its session keeps it on screen while it re-reads.\n- A callback whose PKCE record does not answer holds as `session_unavailable`\n  instead of failing; `signIn()` on the same callback URL retries.\n- Preserve provisional/hold decisions in both convenience route helpers.\n- Commit complete paid live access in memory before optional persistence.\n- Bound browser storage opens/transactions, guard denied getters and expose\n  availability/durability through `StorageStatus` (`missing` marks an absent\n  API) and `getStorageStatus()`. A refusing legacy tab store is a non-answer,\n  never an absent session, and a refused IndexedDB never mints a replacement\n  installation id.\n- Journey: once-claims (`app_landed`, first value) are queued with their row and\n  committed together; claim and outbox locks are acquired within the storage\n  bound and held until their writes settle; rows carry the account they were\n  emitted under and never post with another account's bearer. An unavailable\n  installation id holds steps in memory. Unread nudge history suppresses nudges;\n  `readLastNudgeAt()` rejects a non-answer.\n- `openMoneySurface()` spends the §11 bypass on every genuine open; the 10 s\n  floor governs resumes.\n- `useActivationLaneFromUrl({ autoStartPolling })` polls again after an\n  `unavailable` outcome (2s, 4s, 8s). The error firehose keeps its events when\n  the installation id does not answer.\n- Preserve shared hydration/reset, intro defaults and the read-all cross-app\n  route. 908 tests / 51 files at 0.6.7, 971 / 59 at the first candidate, 1040 /\n  76 after the first review, 1101 / 88 after the second, 1146 / 102 after the third, 1164 / 109 after the fourth, 1188 / 118 after the fifth, 1225 / 124 after the sixth, 1258 / 130 after the seventh, 1287 / 132 after the eighth, 1298 / 135 after the ninth, 1314 / 137 after the tenth. `HANDOFF.md` has the\n  mutation evidence, the §12/§13 conformance and the W5 port note.\n- Round three: a sign-out ends every row of its session's lineage, including\n  another tab's later rotation, on every read and reload. A mark that could not\n  be read is never written over, and `storageCleared` is true only when a read\n  after the delete shows nothing it ended remains.\n- A refresh reservation records whether its owner is alive (a lifetime Web Lock,\n  or a lease without one) and a durable sent mark. A dead owner's unsent\n  reservation is taken over; a sent one is never presented again, and once its\n  access token is refused the session ends to sign-in with\n  `signed_out.reason: \"reconnect\"`. A page's own unsaved replacement is reserved\n  before it is presented.\n- Trial, extension, pass, checkout, billing portal and download-email calls act\n  only for the account the page shows. A move meanwhile posts nothing and returns\n  `stale` (`account_changed` from checkout and the portal).\n- Every request is bounded (30 s, headers and body) and composed with the\n  caller's signal. Entitlement flights are keyed by bearer. A session write holds\n  its lock at most 4 s, and a write that lands late is never adopted.\n- A trial answer never confirms or re-ages cached keys; signed-in state passes\n  the getters' filter; an activation tick that restores sends no second request;\n  sign-out deletes the shared cache row only when it is the ended account's.\n- `getAccessState()` reconciles with storage that answers synchronously\n  (`Storage.getSync?()`). New `sessionEverStored()` answers whether a session was\n  ever stored in this browser, through the session row and the tombstone.\n- Round four: an owner whose refresh answer was lost resolves its own sent\n  reservation while its page lives (backoff 2 s to 60 s, the online event, and a\n  hint that another tab past the 60 s lease sends by BroadcastChannel and a mark\n  on the reservation). Ten minutes after the first sent mark the session ends to\n  the reconnect prompt in every tab and on a reload, never by presenting the token.\n- A 0.6.8 page that rotates a session read from the legacy per-key rows deletes the\n  legacy rows still holding the replaced tokens, so a 0.6.6/0.6.7 tab left open\n  signs itself out instead of presenting the spent token and revoking the family.\n- The owner Web Lock is held only while a page owns a refresh reservation.\n- A session write is aborted when its 4 s hold ends; the default IndexedDB adapter\n  honours the signal (`Storage.set`/`remove` take optional `StorageWriteOptions`).\n- `getAppDataToken()` mints only for the account the page shows.\n- `BAS_STORAGE_KEY` is deprecated: a raw read returns `null` for 0.6.8 sign-ins; use\n  `sessionEverStored()` and the asynchronous reads. The export stays in 0.6.8.\n- Round five: no session ever ends on the clock alone. An owner keeps resolving\n  its own sent refresh token until the server answers definitively, a confirmed\n  replacement is served from memory until its save lands, and other tabs end\n  only when their own access token is refused past the 10-minute bound.\n- A session row that will never parse (garbage, or a newer library's row) answers\n  `signed_out` with `reason: \"reconnect\"` at launch, and a sign-in sets it aside\n  into `session_unreadable` before persisting; refused reads still hold.\n- A sent refresh reservation is kept through a 429 or a failed mark on a retry;\n  a rejected retry of a sent token ends to the reconnect prompt.\n- The refresh attempt lock covers only reserve, mark and release, never the\n  request; an episode ended by a session change releases the owner lock; the\n  legacy cleanup is recorded in the rotation row and survives a reload.\n- Error telemetry consent is granted only on exactly `\"true\"`; an unreadable or\n  unknown value, or a denied localStorage, suspends collection and writes no default.\n- Round six: a Journey outbox row that will never parse (garbage, or a newer\n  library's shape) is set aside into a bounded `journey_quarantine` under the\n  outbox lock,","readmeFilename":"README.md"}