<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" href="/favicon.svg" type="image/svg+xml">
<title data-i18n="app.title">Cartoonio — AI Cartoon Maker for Your Stories</title>
<meta name="description" content="Turn your story idea into a cartoon with AI. Create characters, plan scenes, review visuals and costs, then bring your cartoon to life." data-i18n-content="app.description">
<link rel="canonical" href="https://cartoonio.net/">
<meta name="color-scheme" content="light dark">
<script>
(() => {
const savedTheme = localStorage.getItem('cartoonio-theme');
const theme = savedTheme || 'dark';
document.documentElement.dataset.theme = theme;
const route = window.location.pathname;
const hasProjectRoute = /^\/cartoon\/[^/]+(?:\/(?:story|characters|scenes|costs))?\/?$/.test(route)
|| /^#cartoon\/[^/]+(?:\/(?:story|characters|scenes|costs))?$/.test(window.location.hash);
if (hasProjectRoute || (route === '/' && localStorage.getItem('cartoonio-project'))) {
document.documentElement.dataset.initialWorkspace = 'project';
}
})();
</script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Fredoka:wght@400;500;600;700&display=swap" rel="stylesheet">
<link rel="stylesheet" href="/css/app.css">
<link rel="stylesheet" href="/css/galaxy.css">
<link rel="stylesheet" href="/css/bug-report.css">
</head>
<body>
<div class="noise"></div>
<header class="topbar">
<a id="homeLink" class="brand" href="/explore" aria-label="Cartoonio home" data-i18n-label="nav.home"><span class="brand-mark">C</span><span data-i18n="legacy.cartoonio.867482">Cartoonio</span></a>
<div class="top-actions">
<label class="language-control"><span class="sr-only" data-i18n="nav.interfaceLanguage">Interface language</span><span id="interfaceLanguageDisplay" aria-hidden="true"></span><select id="interfaceLanguage" aria-label="Interface language" data-i18n-label="nav.interfaceLanguage"></select></label>
<span id="systemStatus" class="status-pill"><i></i><span data-i18n="legacy.checking.setup.34a4ba">Checking setup</span></span>
<button id="themeToggle" class="theme-toggle" type="button" aria-label="Switch to dark mode" data-i18n-label="legacy.switch.to.dark.mode.fc43ea" aria-pressed="false" title="Switch to dark mode" data-i18n-title="legacy.switch.to.dark.mode.fc43ea">
<span class="theme-icon theme-icon-sun" aria-hidden="true">☀</span>
<span class="theme-icon theme-icon-moon" aria-hidden="true">☾</span>
</button>
<button id="toggleDirectorChat" class="director-toggle" type="button" aria-expanded="true" aria-controls="directorPanel" aria-label="Show Director" data-i18n-label="legacy.show.director.d6751a" data-i18n="legacy.director.c149bc">Director</button>
<button id="navbarCredits" class="navbar-credits hidden" type="button" aria-label="Open generation credits" title="Open generation credits" data-i18n-label="credits.navOpen" data-i18n-title="credits.navOpen">
<svg viewBox="0 0 24 24" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="8.25"/><path d="M9.4 9.25c.6-.7 1.5-1.05 2.7-1.05 1.55 0 2.5.65 2.5 1.72 0 2.7-5.2 1.1-5.2 3.65 0 1.13 1.08 1.88 2.72 1.88 1.22 0 2.2-.4 2.83-1.17M12.1 6.6v1.55M12.1 15.5v1.55"/></svg>
<span id="navbarCreditBalance" data-i18n="credits.title">Generation credits</span>
</button>
<div class="account-control">
<button id="authButton" class="button button-ghost" type="button" aria-expanded="false" aria-controls="accountMenu" data-i18n="nav.signIn">Sign in</button>
<div id="accountMenu" class="account-menu hidden" role="dialog" aria-label="Account" data-i18n-label="nav.account"></div>
</div>
<button id="newProjectButton" class="button button-dark" data-i18n="nav.newCartoon">+ New cartoon</button>
</div>
</header>
<aside id="generationAccessNotice" class="generation-access-notice hidden" role="status" aria-live="polite" aria-atomic="true">
<span class="generation-access-icon" aria-hidden="true">!</span>
<div><strong id="generationAccessTitle"></strong><span id="generationAccessBody"></span></div>
<a id="generationAccessContact" class="button button-ghost hidden" href="mailto:[email protected]" data-i18n="generationAccess.contactSupport">Contact support</a>
</aside>
<main id="appShell" class="shell studio-shell atlas-shell">
<aside class="sidebar">
<div class="eyebrow-row"><span class="eyebrow" data-i18n="library.title">Your cartoons</span><span id="projectCount">0</span></div>
<div id="projectList" class="project-list"></div>
</aside>
<div class="studio-main">
<section id="welcomeView" class="workspace welcome-view atlas-home">
<header class="atlas-intro">
<div>
<span class="kicker" data-i18n="home.kicker">Your animation studio</span>
<h1 data-i18n="home.heading">Turn your story into a cartoon.</h1>
</div>
<div class="atlas-intro-copy">
<p data-i18n="home.description">Create a story and consistent cast from your idea. Plan each scene, review visuals and costs, then generate your cartoon.</p>
<div class="atlas-intro-actions">
<button id="homeMyCartoons" class="button button-ghost hidden" type="button" data-i18n="account.myCartoons">My cartoons</button>
<button class="button button-primary js-new-project"><span data-i18n="home.create">Create a story</span> <span aria-hidden="true">↗</span></button>
</div>
</div>
</header>
<ol class="home-production-flow" aria-label="Automatic production plan" data-i18n-label="director.new.flowLabel">
<li class="home-production-step home-production-step-story">
<span data-nosnippet class="home-production-visual" aria-hidden="true">
<svg viewBox="0 0 48 48" focusable="false">
<path d="M13 9.5h17l6 6v23H13z" />
<path d="M30 9.5v7h6M19 23h11M19 29h8" />
<path class="home-production-accent" d="M11 20v6M8 23h6M36.5 27v5M34 29.5h5" />
</svg>
<b>1</b>
</span>
<span data-nosnippet class="home-production-copy"><strong data-i18n="director.new.expandStory">Expand the story</strong><small data-i18n="director.new.ideaAutomatic">Automatic from your idea</small></span>
</li>
<li class="home-production-step home-production-step-cast">
<span data-nosnippet class="home-production-visual" aria-hidden="true">
<svg viewBox="0 0 48 48" focusable="false">
<circle cx="24" cy="17" r="6" />
<path d="M13.5 37c.7-7 4.2-10.5 10.5-10.5S33.8 30 34.5 37" />
<circle class="home-production-accent" cx="11.5" cy="22" r="4" />
<path class="home-production-accent" d="M5.5 34c.5-4.8 2.5-7.2 6-7.2 1.8 0 3.3.6 4.3 1.8M36.5 18a4 4 0 1 1 0 8M32.2 29c1-1.5 2.4-2.2 4.3-2.2 3.5 0 5.5 2.4 6 7.2" />
</svg>
<b>2</b>
</span>
<span data-nosnippet class="home-production-copy"><strong data-i18n="director.new.buildCast">Build the cast</strong><small data-i18n="director.new.castStartsAutomatically">Starts as soon as the story is ready</small></span>
</li>
<li class="home-production-step home-production-step-generate">
<span data-nosnippet class="home-production-visual" aria-hidden="true">
<svg viewBox="0 0 48 48" focusable="false">
<rect x="7.5" y="11" width="33" height="26" rx="3" />
<path d="M7.5 18h33M14 11l4 7M24 11l4 7M34 11l4 7" />
<path class="home-production-accent home-production-play" d="m21 23 8 5-8 5z" />
</svg>
<b>3</b>
</span>
<span data-nosnippet class="home-production-copy"><strong data-i18n="director.new.planGenerate">Plan & generate</strong><small data-i18n="director.new.planReviewFirst">Only after your visual and cost review</small></span>
</li>
</ol>
<section id="yourCartoons" class="cartoon-library" aria-labelledby="libraryHeading">
<div class="library-heading">
<div><span class="kicker" data-i18n="library.kicker">Your studio</span><h2 id="libraryHeading" data-i18n="library.title">Your cartoons</h2><p data-i18n="library.description">Open a cartoon to continue creating, or revisit one you have finished.</p></div>
<div class="library-controls">
<label id="libraryLanguageControl" class="hidden"><span class="sr-only" data-i18n="library.languageFilter"></span><select id="libraryLanguage" data-i18n-label="library.languageFilter"></select></label>
<span id="libraryCount" class="library-count" data-i18n="library.zeroCartoons">0 cartoons</span>
</div>
</div>
<div id="cartoonGrid" class="cartoon-grid"></div>
<div id="libraryEmpty" class="library-empty hidden">
<span aria-hidden="true">✦</span>
<h3 id="libraryEmptyTitle" data-i18n="library.emptyTitle">Your next story starts here</h3>
<p id="libraryEmptyDescription" data-i18n="library.emptyDescription">Create your first cartoon and it will appear here.</p>
<button id="libraryEmptyAction" class="button button-primary js-new-project" type="button" data-i18n="home.create">Create a story</button>
</div>
</section>
<section class="community-section" aria-labelledby="communityHeading">
<div class="community-heading">
<h2 id="communityHeading" data-i18n="feed.title">Community cartoons</h2>
<div class="community-filters">
<label><span class="sr-only" data-i18n="feed.sort">Sort cartoons</span><select id="communitySort" aria-label="Sort cartoons" data-i18n-label="feed.sort"><option value="trending" data-i18n="feed.trending">Trending</option><option value="newest" data-i18n="feed.newest">Newest</option><option value="most-voted" data-i18n="feed.mostVoted">Most upvoted</option></select></label>
</div>
</div>
<div id="communityFeed" class="community-feed"></div>
</section>
<section class="missing-story">
<div class="missing-orbit" aria-hidden="true"><span>?</span><i></i><b></b></div>
<div><span class="kicker" data-i18n="legacy.a.story.the.atlas.is.missing.8929a7">Try a starter idea</span><h2 data-i18n="legacy.who.carries.the.moon.home.573fed">The Day the Town Lost Its Colors</h2><p data-i18n="legacy.we.found.moon.folklore.from.six.regions.but.no.child.e37aea">When every color vanishes overnight, a shy young painter and a mischievous crow follow a trail of blue footprints beyond the town walls. To bring the colors back before sunset, they must first discover why the colors left.</p></div>
<button class="button button-dark js-story-seed" data-seed-i18n="legacy.we.found.moon.folklore.from.six.regions.but.no.child.e37aea" type="button" data-i18n="legacy.create.this.missing.story.1b3e37">Start with this idea →</button>
</section>
</section>
<section id="projectView" class="workspace project-view hidden">
<div id="textOnlyNotice" class="text-only-notice hidden" data-i18n="showcase.textOnlyNotice">This public preview includes free story, character, and scene writing. Image, voice, and video generation are not available yet.</div>
<div class="project-header">
<div class="project-identity"><span id="projectLanguage" class="kicker"></span><h1 id="projectTitle"></h1><p id="projectMeta"></p></div>
<div class="project-community-actions"><button id="translationProvenance" class="button button-ghost hidden" type="button" data-i18n="legacy.translation.input.fd673b">Translation input</button><div id="publicationControlHome"><div id="publicationControl" class="publication-control hidden"><div class="publication-state" role="status" aria-live="polite"><i aria-hidden="true"></i><span><strong id="publicationStatus"></strong><small id="publicationHelp"></small></span></div><button id="publishProject" class="button" type="button"></button></div></div></div>
<div class="budget-card">
<div class="budget-heading"><span data-i18n="legacy.spent.so.far.4f31ab">Spent so far</span><strong id="projectCost">$0.000</strong></div>
<div class="budget-footer">
<div class="budget-caption"><small id="costToFinish" class="cost-to-finish"></small></div>
<div class="budget-actions"><button id="viewProjectCosts" class="budget-edit" type="button" data-i18n="costs.openDetails">View costs</button></div>
</div>
</div>
<nav class="steps" aria-label="Cartoon workflow" data-i18n-label="legacy.cartoon.workflow.acda8b">
<button data-step="story"><b>1</b><span data-i18n="legacy.story.e9e509">Story</span></button>
<button data-step="characters"><b>2</b><span data-i18n="legacy.characters.6fac39">Characters</span></button>
<button data-step="scenes"><b>3</b><span data-i18n="legacy.scenes.160c05">Scenes</span></button>
</nav>
</div>
<div id="stepContent" class="step-content"></div>
</section>
</div>
<aside id="directorChat" class="director-pane">
<div id="directorPanel" class="director-panel" role="group" aria-labelledby="directorPanelTitle">
<header class="director-chat-header">
<div class="director-heading">
<strong id="directorPanelTitle" data-i18n="legacy.director.c149bc">Director</strong>
<small id="directorContext" data-i18n="legacy.describe.a.change.then.review.the.mapped.actions.bef.bdd7d0">Describe a change, then review the mapped actions before anything is saved.</small>
</div>
<div class="director-views" role="group" aria-label="Director views" data-i18n-label="legacy.director.views.8f32fe">
<button id="directorChatTab" class="director-view-tab" type="button" data-view="chat" aria-pressed="true" aria-controls="directorBody" data-i18n="legacy.edit.464c4f">Edit</button>
<button id="directorNewTab" class="director-view-tab" type="button" data-view="new" aria-pressed="false" aria-controls="directorNewProject" data-i18n="legacy.new.18fdd5">New</button>
</div>
</header>
<div id="directorBody" class="director-body">
<div id="directorLog" class="director-log" aria-live="polite"></div>
<form id="directorForm" class="director-form">
<label class="field"><span class="sr-only" data-i18n="legacy.what.should.change.e6cbf7">What should change?</span><textarea id="directorInput" name="message" maxlength="4000" required placeholder="Add two intro scenes, or ask what finishing this cartoon would cost." data-i18n-placeholder="legacy.add.two.intro.scenes.or.ask.what.finishing.this.cart.327e0c"></textarea></label>
<small class="cost-note" data-i18n="director.chat.sendCostNote"></small>
<div class="form-actions"><button class="button button-primary" type="submit" data-i18n="legacy.review.edits.05cf05">Review edits →</button></div>
</form>
</div>
<div id="directorNewProject" class="director-body director-new hidden"></div>
</div>
</aside>
</main>
<footer class="site-footer">
<span data-i18n="legal.footerCopyright">© Cartoonio</span>
<nav aria-label="Legal" data-i18n-label="legal.footerNavigation">
<a href="/privacy" data-i18n="legal.privacyLink">Privacy Policy</a>
<a href="/terms" data-i18n="legal.termsLink">Terms of Service</a>
<a href="mailto:[email protected]" data-i18n="legal.contactLink">Contact</a>
</nav>
</footer>
<div id="modal" class="modal hidden" role="dialog" aria-modal="true">
<div class="modal-backdrop js-close-modal"></div>
<div class="modal-card">
<button class="modal-close js-close-modal" aria-label="Close" data-i18n-label="legacy.close.7d9eb7">×</button>
<div id="modalContent"></div>
</div>
</div>
<div id="toast" class="toast" role="status" aria-live="polite" aria-atomic="true">
<span id="toastMessage"></span>
<div class="toast-actions">
<button id="copyToast" type="button" data-i18n="legacy.copy.e21f93">Copy</button>
<button id="closeToast" type="button" aria-label="Dismiss notification" data-i18n-label="legacy.dismiss.notification.b7bb3f">×</button>
</div>
</div>
<div id="helpTooltip" class="help-tooltip" role="tooltip" aria-hidden="true"></div>
<script src="/vendor/jquery/jquery.min.js"></script>
<script src="/js/i18n.js"></script>
<script src="/js/bug-report.js"></script>
<script src="/js/story-timeline.js"></script>
<script src="/js/scene-dialogue-timeline.js"></script>
<script src="/js/app.js"></script>
<script src="/js/analytics.js"></script>
</body>
</html>