Files
time/ventures/havre/index.html
T

379 lines
27 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; img-src 'self' data: blob: https://venice.ai https://outerface.venice.ai; font-src 'none'; connect-src https://api.venice.ai https://private-share.venice.ai; media-src blob: https://private-share.venice.ai; object-src 'none'; base-uri 'none'; form-action 'none'">
<meta name="referrer" content="strict-origin">
<title>Havre</title>
<meta name="description" content="A harbor for characters. Talk to Venice's characters on your own key, keep characters in a file you own, and remix the ones you love into someone new, with credit.">
<link rel="canonical" href="https://havre.yolopreneur.lol/">
<meta property="og:type" content="website">
<meta property="og:title" content="Havre: a harbor for characters">
<meta property="og:description" content="Talk to Venice's characters on your own key. No account, no server: nothing is kept but what you keep.">
<meta property="og:url" content="https://havre.yolopreneur.lol/">
<meta property="og:image" content="https://havre.yolopreneur.lol/shots/og.png">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta name="twitter:card" content="summary_large_image">
<meta name="theme-color" content="#ffffff">
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<link rel="alternate" type="text/plain" href="llms.txt" title="For agents">
<link rel="stylesheet" href="style.css">
<script type="module" src="app.js"></script>
</head>
<body>
<a class="skip" href="#chat">skip to the chat</a>
<header class="mast" id="top">
<h1>HAVRE</h1>
<p class="motto">a harbor for characters. <br>talk to venice characters on your own key. <br>no account. no server. nothing kept but what you keep.</p>
<nav class="nav" aria-label="On this page"><a href="#how">how it works</a> / <a href="#agents">for agents</a> / <a href="#costs">costs</a> / <a href="#plans">early access</a></nav>
</header>
<form class="keybar" id="keyform" autocomplete="off" aria-label="Your Venice API key">
<label for="keyin">VENICE API KEY</label>
<input id="keyin" type="password" autocomplete="off" spellcheck="false" placeholder="paste it here">
<button type="submit" class="btn inv" id="keysave">SAVE</button>
<label class="check"><input type="checkbox" id="keyremember"> remember on this device</label>
<button type="button" class="btn ghost-inv" id="keyforget" hidden>FORGET</button>
<span id="balance" class="balance" hidden></span>
<span id="keystatus" class="keystatus" role="status" aria-live="polite"></span>
<span class="keyfine">sent to api.venice.ai and nowhere else. <a href="https://venice.ai/settings/api" target="_blank" rel="noopener">get a key</a></span>
</form>
<main class="studio" id="studio">
<section class="chars" id="chars" aria-label="Your chats and the characters">
<div class="sechead lefthead">
<h2 class="sr">Your chats and the characters</h2>
<div role="tablist" aria-label="Your chats and the characters">
<button type="button" role="tab" id="lt-chats" aria-controls="lp-chats" aria-selected="false" tabindex="-1">CHATS<span id="chats-new" class="new" hidden></span></button>
<span class="sep" aria-hidden="true">/</span>
<button type="button" role="tab" id="lt-chars" aria-controls="lp-chars" aria-selected="true">CHARACTERS</button>
</div>
</div>
<div id="lp-chats" role="tabpanel" aria-labelledby="lt-chats" hidden>
<p class="filters mono" id="chats-bar"></p>
<ul id="threads" class="threads" aria-label="Your chats, the latest first"></ul>
<p id="threads-empty" class="mono pad">no chats yet. pick one of venice's characters, or one of yours, and say something: every chat you start stays here, and you can keep as many going as you like.</p>
</div>
<div id="lp-chars" role="tabpanel" aria-labelledby="lt-chars">
<p class="filters mono chars-note">venice's public characters. pick one to start a chat.</p>
<form class="filters" id="venform" role="search" aria-label="Venice characters">
<label class="sr" for="vsearch">Search Venice characters</label>
<input id="vsearch" type="search" placeholder="search by name, or #tag" autocomplete="off" maxlength="200">
<label class="pick">sort <select id="vsort">
<option value="featured">featured</option>
<option value="imports">most imported</option>
<option value="highestRating">top rated</option>
<option value="mostRecent">newest</option>
</select></label>
<label class="check"><input type="checkbox" id="vadult"> adult (18+)</label>
<button type="submit" class="btn" id="vgo">SEARCH</button>
</form>
<p id="vtags" class="tags" hidden></p>
<p id="venstatus" class="status" role="status" aria-live="polite"></p>
<ul id="vgrid" class="grid" aria-label="Venice characters"></ul>
<p class="more"><span id="vpager" hidden><button type="button" class="linkish" id="vprev">previous</button> <span id="vrange"></span> <button type="button" class="linkish" id="vnext">next</button> / </span><button type="button" class="linkish" id="plain">chat without a character</button> / <button type="button" class="linkish" id="import">import a card</button> (v1, v2, v3, json or png) / <button type="button" class="linkish" id="new">write one</button></p>
</div>
</section>
<section class="chat" id="chat" aria-labelledby="who-name">
<div class="sechead">
<button type="button" class="linkish back" id="chat-back">← characters</button>
<h2 id="who-name">CHAT</h2>
<span class="meta" id="who-meta"></span>
</div>
<ol id="log" class="log" role="log" aria-live="polite" aria-label="Conversation"></ol>
<div id="ask" class="ask" hidden></div>
<form id="composer" class="composer">
<div class="sayrow">
<label for="say" class="sr">Message</label>
<textarea id="say" rows="1" placeholder="say something" autocomplete="off" enterkeyhint="send"></textarea>
<button type="submit" class="btn solid" id="sendbtn">SEND</button>
</div>
<p id="tools" class="tools" hidden></p>
<input type="file" id="photo-in" accept="image/png,image/jpeg,image/webp" hidden>
<p id="keynote" class="keynote" hidden></p>
</form>
</section>
</main>
<section class="block harbor" id="harbor" aria-labelledby="harbor-h">
<div class="sechead">
<h2 id="harbor-h">YOUR HARBOR</h2>
<span class="meta">kept in this browser. export a file to keep a character anywhere else.</span>
</div>
<div class="tablewrap">
<table class="table">
<thead><tr><th scope="col">NAME</th><th scope="col">FROM</th><th scope="col">LICENSE</th><th scope="col">FILE</th></tr></thead>
<tbody id="roster"></tbody>
</table>
</div>
<p id="harbor-empty" class="mono pad">nothing here yet. pick one of venice's characters, import a card, or write one.</p>
</section>
<section class="block card" id="card" aria-labelledby="card-h">
<div class="sechead">
<h2 id="card-h">CARD</h2>
<span class="meta">the character as a file: edit it, remix it, export it.</span>
</div>
<p id="card-empty" class="mono pad">no character yet. the card shows up here once someone is in your harbor.</p>
<div id="card-body">
<div class="tabs" role="tablist" aria-label="Card">
<button type="button" role="tab" id="t-edit" aria-controls="p-edit" aria-selected="true">SHEET</button>
<button type="button" role="tab" id="t-remix" aria-controls="p-remix" aria-selected="false" tabindex="-1">REMIX</button>
<button type="button" role="tab" id="t-export" aria-controls="p-export" aria-selected="false" tabindex="-1">EXPORT</button>
</div>
<div class="panel" id="p-edit" role="tabpanel" aria-labelledby="t-edit">
<form id="sheet" class="sheet" autocomplete="off">
<div class="col">
<div class="portrait">
<span class="face big" id="sheet-face" aria-hidden="true"></span>
<p class="mono"><button type="button" class="linkish" id="portrait-pick">change portrait</button> / <button type="button" class="linkish" id="portrait-make">make one with ai</button> / <button type="button" class="linkish" id="portrait-clear">remove</button> <span id="portrait-status" class="status" role="status"></span></p>
<input type="file" id="portrait-file" accept="image/png,image/jpeg,image/webp,image/svg+xml" hidden>
</div>
<label>NAME <input name="name" maxlength="120" required></label>
<label>TAGLINE <input name="tagline" maxlength="200" placeholder="one line under the name"></label>
<p id="linked-note" class="note" hidden></p>
<label>GREETING <textarea name="greeting" rows="3" maxlength="4000" placeholder="the first thing they say. a blank line starts a new text."></textarea></label>
<label>PERSONA <textarea name="persona" rows="9" maxlength="20000" placeholder="You are … who they are, how they talk, what they want, what they won't do."></textarea></label>
<p id="name-note" class="note" role="status" hidden></p>
</div>
<div class="col">
<label class="check"><input type="checkbox" name="short_form"> short-form: replies come as a few short texts</label>
<label class="check"><input type="checkbox" name="adult"> adult (18+): for grown-ups only</label>
<p class="hint" id="adult-note" role="status" hidden></p>
<label>HOW THEY TALK <input name="voice_notes" maxlength="2000" placeholder="clipped, wry, asks one question at a time"></label>
<details class="group" id="flow-group">
<summary>FLOW <span class="hint">optional stages for meeting someone new</span></summary>
<ol id="flow" class="items"></ol>
<button type="button" class="btn small" id="flow-add">ADD A STAGE</button>
</details>
<details class="group" id="ex-group">
<summary>EXAMPLES <span class="hint">they teach the voice; without a key, replies come from these</span></summary>
<ol id="examples" class="items"></ol>
<button type="button" class="btn small" id="ex-add">ADD AN EXAMPLE</button>
</details>
<details class="group" id="look-group">
<summary>LOOK <span class="hint">their photos and clips are made from these pictures</span></summary>
<div class="refs" id="refs"></div>
<p class="mono"><button type="button" class="linkish" id="ref-add">add a picture</button> / <button type="button" class="linkish" id="ref-make">make one with ai</button> <span class="hint">up to three besides the portrait. ai makes the next one from the pictures they have, so it's still them, or from how they look if they have none. pictures of the character only, never a photo of a real person.</span> <span id="look-status" class="status" role="status"></span></p>
<input type="file" id="ref-file" accept="image/png,image/jpeg,image/webp" hidden>
<label>HOW THEY LOOK <textarea name="look_description" rows="3" maxlength="1500" placeholder="sixties, tall, grey braid, oilskin coat, reading glasses on a cord"></textarea></label>
</details>
<details class="group" id="speech-group">
<summary>VOICE NOTES <span class="hint">how they sound when they send one</span></summary>
<p class="mono" id="speech-model"></p>
<div class="two">
<label>VOICE <select name="speech_voice" id="speech-voice"></select></label>
<label>SPEED <select name="speech_speed" id="speech-speed"><option value="0.85">slower</option><option value="1">normal</option><option value="1.15">faster</option><option value="1.3">fast</option></select></label>
</div>
<label>MOOD <input name="speech_mood" maxlength="500" placeholder="warm, teasing, a little sleepy"></label>
<p class="hint">qwen 3 voices take the mood; other voice models ignore it.</p>
<label class="check"><input type="checkbox" id="speech-on"> replies come with a voice note</label>
<p class="mono"><button type="button" class="btn small" id="speech-sample">HEAR A SAMPLE</button> <span id="speech-status" class="status" role="status"></span></p>
</details>
<details class="group" id="memory-group">
<summary>MEMORY <span class="hint">what they remember of your chats with them</span></summary>
<p class="hint" id="memory-how"></p>
<ul id="memory-list" class="notes" aria-label="What they remember"></ul>
<label class="sr" for="memory-add">Something for them to remember</label>
<input id="memory-add" maxlength="240" autocomplete="off" enterkeyhint="done" placeholder="+ something for them to remember">
<p class="mono"><button type="button" class="linkish" id="memory-forget">forget everything</button></p>
</details>
<label>TAGS <input name="tags" maxlength="400" placeholder="comma, separated"></label>
<div class="two">
<label>MODEL <select name="model" id="model-select"></select></label>
<label>LICENSE <select name="license" id="license-select"></select></label>
</div>
<label>CREATOR <input name="creator" maxlength="120" placeholder="who made them"></label>
<div class="lineage">
<h3>LINEAGE</h3>
<ul id="lineage" class="lineage-list"></ul>
<p class="hint">where this character came from. entries are only ever added.</p>
</div>
<button type="button" class="btn danger small" id="delete">REMOVE FROM HARBOR</button>
</div>
</form>
</div>
<div class="panel" id="p-remix" role="tabpanel" aria-labelledby="t-remix" hidden>
<div class="remix">
<p class="lede">Write someone new from the idea of <b id="rx-from">this character</b>, and keep the credit.</p>
<ol class="steps">
<li><b>Distill.</b> A first pass reads the source and writes down only ideas: no names, no sentences.</li>
<li><b>Write.</b> A second pass never sees the source. It writes someone new from the ideas and your twist.</li>
<li><b>Check.</b> Havre compares the new words with the old, here in your browser, then logs the credit.</li>
</ol>
<details class="group" id="rx-paste-group">
<summary>USE A DIFFERENT SOURCE <span class="hint">paste a description you can read</span></summary>
<label class="sr" for="rx-paste">Source text</label>
<textarea id="rx-paste" rows="5" placeholder="Paste a character description. Name it on the first line."></textarea>
</details>
<p id="rx-rights" class="note" hidden></p>
<p><button type="button" class="btn solid" id="rx-distill">DISTILL THE IDEAS</button></p>
<div id="rx-ideas" class="ideas" hidden></div>
<label id="rx-twist-label" hidden>YOUR TWIST <input id="rx-twist" maxlength="400" placeholder="e.g. make them a ferry pilot"></label>
<p><button type="button" class="btn solid" id="rx-write" hidden>WRITE SOMEONE NEW</button></p>
<div id="rx-draft" class="draft" hidden></div>
<p id="rx-status" class="status" role="status" aria-live="polite"></p>
</div>
</div>
<div class="panel" id="p-export" role="tabpanel" aria-labelledby="t-export" hidden>
<ul class="exports">
<li><button type="button" class="out" data-out="havre"><b>HAVRE CARD</b><span>.havre.json, the whole character</span></button></li>
<li><button type="button" class="out" data-out="v3"><b>CHARACTER CARD V3</b><span>.json for SillyTavern, RisuAI and other card apps</span></button></li>
<li><button type="button" class="out" data-out="png"><b>CHARACTER CARD PNG</b><span>a picture with the card inside it</span></button></li>
<li><button type="button" class="out" data-out="prompt"><b>SYSTEM PROMPT</b><span>.txt for any OpenAI-compatible API</span></button></li>
</ul>
<p class="mono">files are made here, in your browser. nothing is uploaded.</p>
</div>
</div>
</section>
<section class="row" id="how" aria-labelledby="how-h">
<h2 id="how-h">HOW IT WORKS</h2>
<div class="body">
<ol>
<li>Paste your Venice API key. It stays in this browser and goes only to api.venice.ai; the page can reach nothing but Venice.</li>
<li>Pick a character: one of Venice's, a card file you import, or one you write. Venice's characters say hello first. Or chat with a model and no character at all.</li>
<li>Talk. Replies come as a few short texts, through whichever Venice model you pick. Keep as many chats going as you like, with different characters or several with the same one: a reply keeps coming while you're in another chat, and your chats show what's new. Without a key, the characters you write answer from their own examples.</li>
<li>They remember. Every dozen messages, a character you wrote, imported or remixed writes down what they remember of your chats: what you've told them, what happened, what they've said about themselves. It goes into every chat with them, so a new chat picks up where the last one left off. Read it, add to it, or make them forget, on their card.</li>
<li>More than texts. When you come back after a while, characters text first, in the chat you open and in a few of your others, and they send a photo or a voice note when it fits, out of a daily allowance you set. Ask them for a photo or a short clip whenever you like: a clip always shows Venice's price first, and is made only if you say yes. A character marked adult (18+) can send adult ones, made only from pictures made here with AI. Switch them on, and they hear your voice notes and see your photos.</li>
<li>Keep them. Export a character as a file, or remix them into someone new; the credit stays in the card.</li>
</ol>
</div>
</section>
<section class="row" id="agents" aria-labelledby="agents-h">
<h2 id="agents-h">FOR AGENTS</h2>
<div class="body">
<p>Copy this into any agent. It reads the skill, writes the character, and hands back the files. Change the second line to who you want.</p>
<pre id="agent-prompt" class="pre"></pre>
<p class="mono"><button type="button" class="btn copy" data-copy="agent-prompt">COPY PROMPT</button> files: <a href="skill.md">skill.md</a> / <a href="card.schema.json">card.schema.json</a> / <a href="card.js">card.js</a> / <a href="venice.js">venice.js</a> / <a href="abilities.js">abilities.js</a> / <a href="memory.js">memory.js</a> / <a href="llms.txt">llms.txt</a></p>
<p>What comes back: a Havre card (.havre.json) to import here, a Character Card V3 for SillyTavern, RisuAI and other card apps, and a plain system prompt for any OpenAI-compatible API.</p>
</div>
</section>
<section class="row" id="costs" aria-labelledby="costs-h">
<h2 id="costs-h">COSTS</h2>
<div class="body">
<p>You pay Venice directly, for what you use. Havre adds nothing. Rough prices, October 2026:</p>
<table class="prices">
<tbody>
<tr><th scope="row">a chat turn</th><td>$0.0007 to $0.005, by model (3,000 tokens in, 150 out)</td></tr>
<tr><th scope="row">a hello from a venice character</th><td>one chat turn</td></tr>
<tr><th scope="row">memory</th><td>one short call every dozen messages: about $0.003 on glm 5.2</td></tr>
<tr><th scope="row">a photo</th><td>$0.02 to $0.34, by model ($0.03 on grok imagine), plus a short call to write the shot</td></tr>
<tr><th scope="row">a picture for their card</th><td>the same as a photo: $0.03 on grok imagine, plus a short call to describe them if their card doesn't say how they look</td></tr>
<tr><th scope="row">a clip</th><td>venice prices it before it's made: about $0.50 for five seconds</td></tr>
<tr><th scope="row">a voice note</th><td>about $0.0007 with kokoro, up to about $0.04 with the priciest voices</td></tr>
<tr><th scope="row">hearing your voice note</th><td>$0.006 a minute</td></tr>
<tr><th scope="row">seeing your photo</th><td>part of the chat turn, or one short call if their model can't see</td></tr>
<tr><th scope="row">on their own</th><td>texting first, photos and voice notes, out of a daily allowance: 25 cents unless you change it, from 10 cents to $5; now and then a short call to decide</td></tr>
<tr><th scope="row">a remix</th><td>two short calls; five more for a venice character</td></tr>
</tbody>
</table>
<p class="mono">the model pickers show venice's prices, what you ask for shows its price before you pay, and your balance shows next to your key.</p>
</div>
</section>
<section class="row" id="plans" aria-labelledby="plans-h">
<h2 id="plans-h">PLANS</h2>
<div class="body">
<p><b>Studio, free.</b> Everything on this page, in your browser: as many characters as you like, import and export, remix with credit.</p>
<p><b>Harbor, planned at $8 a month for founding members.</b> Hosted character pages with a link of their own, an API and an MCP server, channels starting with Whop, and payouts to creators. Nothing is charged now. <a href="https://teahub.xyz/teahubxyz/time/issues/new?template=early-access.yml&amp;title=Early+access%3A+Havre&amp;venture=havre&amp;plan=Harbor+%28founding%29">Join early access</a>.</p>
<p class="mono">early access is a public issue on teahub: no email, nothing charged.</p>
</div>
</section>
<section class="row" id="next" aria-labelledby="next-h">
<h2 id="next-h">COMING NEXT</h2>
<div class="body">
<ul>
<li>Scenes: two characters take turns from your opening line.</li>
<li>A hosted harbor: a page and a link for every character, and an API and an MCP server.</li>
</ul>
</div>
</section>
<section class="row" id="fine" aria-labelledby="fine-h">
<h2 id="fine-h">FINE PRINT</h2>
<div class="body">
<p>Characters and chats are saved in this browser, and so are the photos, clips and voice notes in them. Export a character to keep them anywhere else.</p>
<p>What a character remembers of your chats is kept in this browser too, beside their card and never in it: a card you export or share carries none of it. Deleting a chat doesn't make them forget; their card does. Switch memory off under abilities.</p>
<p>Your key stays in this browser and goes only to api.venice.ai. The page's security policy blocks every other address, except the download links Venice hands out for clips from its private video models, which are fetched without your key. Conversations run on your Venice account, under Venice's terms.</p>
<p>Venice's adult characters stay hidden unless you switch them on and confirm you're 18 or older, and marking a character of yours adult asks the same. Photos and clips are safe for work: every one asks for that, and for adults only, and photos go through Venice's safe mode, which blurs anything adult. They're made only from the pictures on a card, which are for pictures of the character, never a photo of a real person.</p>
<p>The one exception is a character marked adult, once you've said you're 18 or older. When every picture on their card was made here with AI, their photos and clips can be adult: they're made on Venice's uncensored models, and every prompt opens with a hard rule that everyone shown is an adult, 18 or older. Never from a picture someone uploaded, which could be of anyone, and never when their card, the shot or the chat mentions anyone under 18: then it stays safe for work. The pictures made for their card skip safe mode too, with the same rule first, unless one is made from an uploaded picture. Switch it off under abilities.</p>
<p>What characters do on their own stays within the daily allowance you set under abilities, and you can switch it off there. A clip is never made without your yes.</p>
<p>Hearing and seeing are off until you switch them on. Your voice note goes to Venice to be written down, and your photo goes to the model you talk to, or to the one that describes it.</p>
<p>Someone else's character comes in as a link with credit, not a copy, and Remix writes someone new from ideas alone. Names and broad ideas aren't protected by copyright; a character's written expression can be. When in doubt, ask the creator. This isn't legal advice.</p>
<p>Havre is independent. It isn't part of Venice.ai and isn't endorsed by Venice.</p>
</div>
</section>
<section class="row last" id="name" aria-labelledby="name-h">
<h2 id="name-h">THE NAME</h2>
<div class="body">
<p><i>Havre</i> means harbor. In July 2025 Venice and Le Havre signed a letter of friendship: two old port cities, both on the UNESCO World Heritage list.</p>
</div>
</section>
<footer class="foot">havre.yolopreneur.lol / a venture on <a href="https://yolopreneur.lol/">yolopreneur.lol</a> / made by claude, october 2026 / not affiliated with venice.ai</footer>
<dialog id="importdlg" class="dlg" aria-labelledby="imp-h">
<form method="dialog" id="impform">
<h2 id="imp-h">IMPORT A CARD</h2>
<div class="dlgbody">
<div class="drop" id="drop" tabindex="0" role="button" aria-label="Choose a card file">
<b>DROP A CARD HERE</b><span>Havre JSON, or a character card V1, V2 or V3 (JSON or PNG)</span>
<span class="mono">or press to choose a file</span>
</div>
<input type="file" id="file" accept=".json,.png,application/json,image/png" hidden>
<label>OR PASTE A DESCRIPTION <textarea id="paste" rows="5" placeholder="Name on the first line, then who they are."></textarea></label>
<p id="impstatus" class="status" role="status"></p>
<p class="actions"><button type="button" class="btn" id="impcancel">CLOSE</button> <button type="button" class="btn solid" id="imp-paste">IMPORT TEXT</button></p>
</div>
</form>
</dialog>
<dialog id="modeldlg" class="dlg wide" aria-labelledby="model-h">
<form method="dialog" id="modelform">
<h2 id="model-h">MODEL</h2>
<div class="dlgbody">
<p class="mono" id="model-for"></p>
<label class="sr" for="msearch">Search models</label>
<input id="msearch" type="search" placeholder="search models: a name, private, uncensored…" autocomplete="off">
<div class="mtable">
<table class="table models">
<thead id="mhead"><tr><th scope="col">MODEL</th><th scope="col">PRIVACY</th><th scope="col">CAN</th><th scope="col">$ IN / OUT</th><th scope="col">CONTEXT</th></tr></thead>
<tbody id="mlist"></tbody>
</table>
</div>
<p class="mono" id="mnote">private: what you send is used for the answer and not kept. anonymized: venice passes it to the model's maker without saying who you are, and they can read it. prices are per million tokens.</p>
<p class="actions"><button type="button" class="btn" id="mclose">CLOSE</button></p>
</div>
</form>
</dialog>
<dialog id="abilitydlg" class="dlg wide" aria-labelledby="ab-h">
<form method="dialog" id="abform">
<h2 id="ab-h">ABILITIES</h2>
<div class="dlgbody">
<p class="mono">what characters can do besides texting, and what you can send them, on your venice key. what you ask for shows its price first; what they do on their own comes out of your daily allowance.</p>
<div class="tablewrap flush">
<table class="table abilities"><tbody id="ablist"></tbody></table>
</div>
<p class="mono">photos and clips are safe for work, of adults, never of a real person, and photos go through venice's safe mode; a character marked adult can send adult ones (see adult). they, and voice notes, are kept in this browser.</p>
<p class="actions"><button type="button" class="btn" id="abclose">CLOSE</button></p>
</div>
</form>
</dialog>
<div id="toast" class="toast" role="status" aria-live="polite" hidden></div>
</body>
</html>