Mercurial
view mrjunejune/src/jrpg/index.html @ 264:04fee26ecce0
add authenticated JRPG conversation platform
Add reusable auth/session storage, owned conversation recovery, guest quotas, admin workflows, URL-routed conversation UI, mobile frame support, and parallel browser acceptance.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 07 Aug 2026 07:34:12 -0700 |
| parents | ee04e4e69fed |
| children | 056790c4fb0d |
line wrap: on
line source
<!doctype html> <html lang="en" data-zen-theme="cyberpunk"> <head> <title>Shiba Quest | MrJuneJune</title> {{/parts/base_head.html}} <link rel="preload" href="/public/jrpg/background-frame-2.webp" as="image" media="not ((max-width: 52rem) and (orientation: portrait))"> <link rel="preload" href="/public/jrpg/background-frame-mobile.webp" as="image" media="(max-width: 52rem) and (orientation: portrait)"> <link rel="preload" href="/public/jrpg/bar-ink.webp" as="image"> <link rel="stylesheet" href="/jrpg/jrpg.css"> <script type="module" src="/jrpg/jrpg.js"></script> </head> <body class="jrpg-page"> <main class="jrpg-main"> <mjj-jrpg-shell class="jrpg-shell"> <div class="jrpg-workspace"> <div class="jrpg-brand"> <header> <h1> <a href="/" data-zen-link-effect="none">MrJuneJune</a> </h1> </header> </div> <nav class="jrpg-frame-controls" aria-label="Window controls"> <zen-button appearance="plain" size="xs"> <button type="button" data-frame-minimize aria-label="Minimize interface" aria-pressed="false" > <zen-icon name="arrow-down"></zen-icon> </button> </zen-button> <zen-button appearance="plain" size="xs"> <button type="button" data-frame-fullscreen aria-label="Toggle fullscreen" aria-pressed="false" > <zen-icon name="external"></zen-icon> </button> </zen-button> <zen-button appearance="plain" size="xs"> <a href="/" aria-label="Close interface and return home"> <zen-icon name="close"></zen-icon> </a> </zen-button> </nav> <zen-button class="jrpg-mobile-menu-btn" appearance="plain" size="xs"> <button type="button" data-mobile-menu-toggle aria-label="Toggle destination menu" aria-expanded="true" aria-controls="jrpg-destination-menu" > <zen-icon name="menu"></zen-icon> </button> </zen-button> <footer class="jrpg-frame-telemetry" aria-label="System telemetry"> <span aria-label="Temperature unavailable">N/A</span> <span data-frame-account aria-live="polite"><a href="/login?next=/jrpg">LOGIN</a></span> <span data-frame-network aria-label="Status online">ONLINE</span> <time data-frame-uptime aria-label="Uptime">00:00:00</time> </footer> <section class="jrpg-scene" aria-label="Shiba Quest conversation"> <mjj-jrpg-character state="default"> <img data-character alt=""> </mjj-jrpg-character> <mjj-jrpg-chat aria-labelledby="conversation-title"> <div class="jrpg-panel-heading"> <h1 id="conversation-title">Conversations</h1> </div> <zen-message-scroller> <div class="jrpg-message-viewport" data-zen-viewport role="log" aria-live="polite" aria-relevant="additions text" > <ol class="jrpg-messages" data-messages> <li class="jrpg-message" data-speaker="Epi" data-turn-group="start"> <strong>Epi</strong> <p>Welcome, traveler. Pick a destination or tell me what you are looking for.</p> </li> <li class="jrpg-message" data-speaker="System" data-turn-group="start"> <strong>System</strong> <p>The Shiba terminal is ready.</p> </li> </ol> </div> </zen-message-scroller> <nav class="jrpg-turn-navigation" aria-label="Conversation turns"> <zen-button appearance="plain" size="sm"> <button type="button" data-turn-previous aria-label="Previous turn" disabled> <zen-icon name="chevron-left"></zen-icon> Previous </button> </zen-button> <span data-turn-position aria-live="polite">START</span> <zen-button appearance="plain" size="sm"> <button type="button" data-turn-next aria-label="Next turn" disabled> Next <zen-icon name="chevron-right"></zen-icon> </button> </zen-button> </nav> </mjj-jrpg-chat> </section> <section class="jrpg-utility" aria-label="Selected destination"> <mjj-jrpg-preview data-selection="resume"> <article class="jrpg-preview-panel" aria-live="polite"> <zen-heading size="xl"> <h2 data-preview-title>Resume</h2> </zen-heading> <p data-preview-copy> Member of Technical Staff and engineering leader with 10+ years building AI agent platforms and production systems. </p> <ul class="jrpg-work-showcase" data-work-showcase> <li> <a href="https://www.microsoft.com/en-us/microsoft-copilot/blog/2026/02/26/copilot-tasks-from-answers-to-actions/"> <span>Copilot Tasks</span> <small>Agentic execution</small> </a> </li> <li> <a href="https://www.cio.com/article/3977098/microsoft-doubles-down-on-multi-model-ai-as-it-builds-a-copilot-super-app.html"> <span>Copilot SuperApp</span> <small>AI platform</small> </a> </li> </ul> <zen-dialog class="jrpg-preview-dialog"> <zen-button appearance="plain" size="xs" data-dialog-trigger-owner hidden> <button type="button" data-zen-trigger tabindex="-1" aria-hidden="true"></button> </zen-button> <dialog class="jrpg-detail-dialog" aria-labelledby="jrpg-dialog-title"> <div class="jrpg-dialog-heading"> <p>DESTINATION DATA</p> <div class="jrpg-dialog-heading-actions"> <zen-button appearance="plain" size="md"> <a href="/resume" data-preview-link> Open page <zen-icon name="external"></zen-icon> </a> </zen-button> <zen-button appearance="plain" size="md"> <button type="button" data-zen-close aria-label="Close destination details"> <zen-icon name="close"></zen-icon> </button> </zen-button> </div> </div> <h2 id="jrpg-dialog-title" data-dialog-title>Resume</h2> <p data-dialog-copy>Experience, projects, and the systems I have helped build.</p> <section class="jrpg-resume-dossier" data-resume-dossier aria-label="Resume dossier" > <p data-resume-status>Loading resume dossier...</p> <div data-resume-content></div> </section> <section class="jrpg-blog-browser" data-blog-browser aria-label="Blog archive" hidden > <aside> <h3>All blogs</h3> <ol data-blog-list> <li>Loading blog archive...</li> </ol> </aside> <article> <p data-blog-status>Select a blog to inspect.</p> <div data-blog-content></div> </article> </section> <section class="jrpg-tool-browser" data-tool-browser aria-label="Tool workspace" hidden > <article> <p data-tool-status>Select a tool to inspect.</p> <div data-tool-content></div> </article> </section> <div class="jrpg-dialog-actions" data-dialog-actions> <zen-button appearance="plain" size="lg" data-resume-download> <a href="/public/resume.pdf"> Download PDF <zen-icon name="download"></zen-icon> </a> </zen-button> </div> </dialog> </zen-dialog> </article> </mjj-jrpg-preview> <mjj-conversation-archive hidden aria-label="Conversations"> <div class="jrpg-archive-heading"> <h2>Archive</h2> <zen-button appearance="plain" size="xs"> <button type="button" data-archive-close aria-label="Close conversations"> <zen-icon name="close"></zen-icon> </button> </zen-button> </div> <div class="jrpg-archive-actions"> <zen-button appearance="plain" size="sm"> <button type="button" data-archive-new> <zen-icon name="plus"></zen-icon> New </button> </zen-button> </div> <ol class="jrpg-archive-list" data-archive-list aria-label="Conversations"> </ol> <zen-button appearance="plain" size="sm" data-archive-load-more-owner hidden> <button type="button" data-archive-load-more>Load more</button> </zen-button> <p class="jrpg-archive-status" data-archive-status aria-live="polite">Loading conversations...</p> <dialog class="jrpg-archive-dialog" data-archive-delete-dialog aria-labelledby="archive-delete-title" aria-modal="true" > <p id="archive-delete-title" class="jrpg-archive-dialog-title">Delete this conversation?</p> <p data-archive-delete-name class="jrpg-archive-dialog-subtitle"></p> <div class="jrpg-archive-dialog-actions"> <zen-button appearance="plain" size="md"> <button type="button" data-archive-delete-cancel>Cancel</button> </zen-button> <zen-button appearance="plain" size="md"> <button type="button" data-archive-delete-confirm>Delete</button> </zen-button> </div> </dialog> <dialog class="jrpg-archive-dialog" data-archive-rename-dialog aria-labelledby="archive-rename-title" aria-modal="true" > <p id="archive-rename-title" class="jrpg-archive-dialog-title">Rename conversation</p> <form data-archive-rename-form novalidate> <zen-field appearance="plain" size="md"> <label for="archive-rename-input">New title</label> <input id="archive-rename-input" data-archive-rename-input type="text" maxlength="200" required autocomplete="off" > </zen-field> <div class="jrpg-archive-dialog-actions"> <zen-button appearance="plain" size="md"> <button type="button" data-archive-rename-cancel>Cancel</button> </zen-button> <zen-button appearance="plain" size="md"> <button type="submit">Save</button> </zen-button> </div> </form> </dialog> </mjj-conversation-archive> </section> <mjj-jrpg-composer> <form class="jrpg-composer" data-composer> <zen-field appearance="plain" size="lg"> <label for="jrpg-message">Message</label> <textarea id="jrpg-message" name="message" rows="3" maxlength="500" placeholder="Ask Epi about this site..." required ></textarea> </zen-field> <div class="jrpg-composer-actions"> <zen-button appearance="plain" size="sm"> <button type="submit"> Send <zen-icon name="arrow-right"></zen-icon> </button> </zen-button> <zen-button appearance="plain" size="sm" data-cancel-control hidden> <button type="button" data-cancel> Cancel <zen-icon name="close"></zen-icon> </button> </zen-button> </div> <p class="jrpg-composer-quota" data-quota aria-live="polite" hidden></p> <p class="jrpg-composer-hint">Enter to send / Shift + Enter for a new line</p> </form> </mjj-jrpg-composer> <mjj-jrpg-menu id="jrpg-destination-menu"> <nav aria-label="Shiba Quest destinations"> <p class="jrpg-menu-label">Menu</p> <ul> <li> <zen-button appearance="plain" size="sm"> <button type="button" data-preview="resume" aria-pressed="true"> <zen-icon name="chevron-right"></zen-icon> Resume </button> </zen-button> </li> <li> <zen-button appearance="plain" size="sm"> <button type="button" data-preview="tools" aria-pressed="false"> <zen-icon name="chevron-right"></zen-icon> Tools </button> </zen-button> </li> <li> <zen-button appearance="plain" size="sm"> <button type="button" data-preview="blog" aria-pressed="false"> <zen-icon name="chevron-right"></zen-icon> Blogs </button> </zen-button> </li> <li> <zen-button appearance="plain" size="sm"> <button type="button" data-preview="conversations" aria-pressed="false"> <zen-icon name="chevron-right"></zen-icon> Conversations </button> </zen-button> </li> </ul> </nav> </mjj-jrpg-menu> <zen-dialog class="jrpg-login-dialog-owner" data-login-dialog-owner> <zen-button appearance="plain" size="md" hidden> <button type="button" data-zen-trigger tabindex="-1" aria-hidden="true"></button> </zen-button> <dialog class="jrpg-login-dialog" data-login-dialog aria-labelledby="jrpg-login-title" aria-modal="true" > <div class="jrpg-login-dialog-header"> <h2 id="jrpg-login-title">SIGN IN</h2> <zen-button appearance="plain" size="md"> <button type="button" data-zen-close aria-label="Close sign-in dialog"> <zen-icon name="close"></zen-icon> </button> </zen-button> </div> <div role="alert" data-login-error aria-live="assertive" hidden></div> <form data-login-form novalidate> <zen-field appearance="plain" size="md"> <label for="jrpg-login-username">Username</label> <input id="jrpg-login-username" name="username" type="text" autocomplete="username" autocapitalize="none" spellcheck="false" required maxlength="32" > </zen-field> <zen-field appearance="plain" size="md"> <label for="jrpg-login-password">Password</label> <input id="jrpg-login-password" name="password" type="password" autocomplete="current-password" required minlength="12" maxlength="1024" > </zen-field> <div class="jrpg-login-dialog-actions"> <zen-button appearance="plain" size="md"> <button type="button" data-login-cancel data-zen-close>Cancel</button> </zen-button> <zen-button appearance="plain" size="md"> <button type="submit" data-login-submit>Sign in</button> </zen-button> </div> </form> </dialog> </zen-dialog> </div> </mjj-jrpg-shell> </main> </body> </html>