Ctrl K
ComunidadGuías…

index.html

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<!doctype html>
<html lang="en">
	<head>
		<meta charset="UTF-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<meta
			name="description"
			content="Modern Microsoft Comic Chat port running live rooms on Cloudflare Durable Objects. Validated & built against the original 1996+ engine to render conversation as a comic strip."
		/>
		<title>Comic Chat - Web Port of the 1996 Microsoft Classic</title>
		<!--if:SITE_ORIGIN-->
		<link rel="canonical" href="%SITE_ORIGIN%/" />
		<!--/if-->
		<meta property="og:type" content="website" />
		<meta property="og:title" content="Comic Chat Web" />
		<meta
			property="og:description"
			content="Modern Microsoft Comic Chat port running live rooms on Cloudflare Durable Objects. Validated & built against the original 1996+ engine to render conversation as a comic strip."
		/>
		<!--if:SITE_ORIGIN-->
		<meta property="og:url" content="%SITE_ORIGIN%/" />
		<meta property="og:image" content="%SITE_ORIGIN%/og.jpg" />
		<meta property="og:image:width" content="1200" />
		<meta property="og:image:height" content="600" />
		<meta
			property="og:image:alt"
			content="Three-panel comic strip of Comic Chat characters discussing the TypeScript port"
		/>
		<meta name="twitter:card" content="summary_large_image" />
		<script type="application/ld+json">
			{
				"@context": "https://schema.org",
				"@type": "WebApplication",
				"name": "Comic Chat Web",
				"url": "%SITE_ORIGIN%/",
				"description": "Modern Microsoft Comic Chat port running live rooms on Cloudflare Durable Objects. Validated & built against the original 1996+ engine to render conversation as a comic strip.",
				"applicationCategory": "CommunicationApplication",
				"operatingSystem": "Any",
				"image": "%SITE_ORIGIN%/og.jpg"
			}
		</script>
		<!--/if-->
		<link rel="stylesheet" href="/src/browser/room.css" />
		<link rel="icon" href="/favicon.ico" sizes="any" />
		<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
		<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
		<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
		<link rel="manifest" href="/manifest.webmanifest" />
	</head>
	<body class="app">
		<svg width="0" height="0" class="icon-sprite" aria-hidden="true">
			<defs>
				<symbol id="ic-members" viewBox="0 0 16 16">
					<circle cx="10.6" cy="5" r="2.1" />
					<path d="M6.2 14v-2.1a4.4 4.4 0 0 1 8.8 0V14z" />
					<circle
						class="gap-s"
						cx="5.6"
						cy="6.1"
						r="2.7"
						fill="currentColor"
						stroke-width="1"
					/>
					<path
						class="gap-s"
						d="M1 14v-2.2a4.6 4.6 0 0 1 9.2 0V14z"
						fill="currentColor"
						stroke-width="1"
					/>
				</symbol>
				<symbol id="ic-member" viewBox="0 0 16 16">
					<circle cx="8" cy="6.1" r="2.7" />
					<path d="M3.4 14v-2.2a4.6 4.6 0 0 1 9.2 0V14z" />
				</symbol>
				<symbol id="ic-pose" viewBox="0 0 16 16">
					<g
						fill="none"
						stroke="currentColor"
						stroke-width="0.9"
						stroke-linejoin="round"
					>
						<circle cx="8" cy="8" r="5.4" />
						<path
							d="M8 8 L8 2.6 M8 8 L12.676 5.3 M8 8 L12.676 10.7 M8 8 L8 13.4 M8 8 L3.324 10.7 M8 8 L3.324 5.3"
						/>
					</g>
					<circle cx="8" cy="8" r="1.4" fill="currentColor" />
				</symbol>
				<symbol id="ic-bg" viewBox="0 0 16 16">
					<rect
						x="1.4"
						y="2.8"
						width="13.2"
						height="10.4"
						fill="none"
						stroke="currentColor"
						stroke-width="1.5"
					/>
					<circle cx="5" cy="6.2" r="1.5" />
					<path d="M2.2 13.2 6 8.4l2.4 3 2.1-2.6 3.3 4.4z" />
				</symbol>
				<symbol id="ic-more" viewBox="0 0 16 16">
					<circle cx="3.4" cy="8" r="1.6" />
					<circle cx="8" cy="8" r="1.6" />
					<circle cx="12.6" cy="8" r="1.6" />
				</symbol>
			</defs>
		</svg>
		<header class="titlebar">
			<div class="titlebar-heading">
				<h1 class="titlebar-title">
					<button id="title-home" class="titlebar-text" type="button">
						Comic Chat Web
					</button>
				</h1>
				<span id="title-room" class="titlebar-room"></span>
			</div>
			<span class="titlebar-actions">
				<button
					id="notify-bell"
					class="titlebar-button"
					type="button"
					aria-pressed="false"
					title="Room notifications"
					aria-label="Room notifications"
					hidden
				>
					<svg
						viewBox="0 0 16 16"
						width="18"
						height="18"
						fill="currentColor"
						aria-hidden="true"
					>
						<path
							d="M8 1.2C5.6 1.2 3.9 3 3.9 5.4v3.2L2.5 10.9v1.2h11v-1.2L12.1 8.6V5.4C12.1 3 10.4 1.2 8 1.2z"
						/>
						<path d="M6.4 13.1a1.6 1.6 0 0 0 3.2 0z" />
					</svg>
				</button>
				<a
					class="titlebar-button"
					href="/agent-skill.html"
					aria-label="Agent skill: build a strip with an AI agent"
					title="Agent skill: build a strip with an AI agent"
				>
					<img
						class="titlebar-icon"
						src="/assets/help-icon.png?v=2"
						alt=""
						width="139"
						height="128"
					/>
				</a>
				<!--if:SUPPORT_URL-->
				<a
					class="titlebar-button"
					href="%SUPPORT_URL%"
					target="_blank"
					rel="noreferrer"
					aria-label="Buy me a coffee"
					title="Buy me a coffee"
				>
					<svg
						viewBox="0 0 16 16"
						width="18"
						height="18"
						fill="none"
						stroke="currentColor"
						stroke-width="1.4"
						stroke-linejoin="round"
						stroke-linecap="round"
						aria-hidden="true"
					>
						<path
							d="M5.6 2.2c0-.9 1.1-.9 1.1-1.8M9.3 2.2c0-.9 1.1-.9 1.1-1.8"
							stroke-width="1.1"
						/>
						<rect x="2.6" y="4.2" width="10.8" height="2.1" rx="1.05" />
						<path
							d="M4 8.3h8l-0.85 5.5a1.4 1.4 0 0 1-1.39 1.2H6.24a1.4 1.4 0 0 1-1.39-1.2L4 8.3Z"
						/>
					</svg>
				</a>
				<!--/if-->
				<a
					class="titlebar-button"
					href="https://github.com/remsky/comic-chat-web"
					target="_blank"
					rel="noreferrer"
					aria-label="View source on GitHub"
					title="View source on GitHub"
				>
					<svg viewBox="0 0 16 16" width="18" height="18" aria-hidden="true">
						<path
							fill="currentColor"
							d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8c0-4.42-3.58-8-8-8Z"
						/>
					</svg>
				</a>
				<a
					class="titlebar-button"
					href="/studio.html"
					title="Build a strip panel by panel"
				>
					Studio
				</a>
			</span>
		</header>
		<main id="room" class="workspace">
			<section id="strip" class="strip" aria-label="Comic strip">
				<div id="panels" class="strip-page" aria-live="polite"></div>
				<ol id="transcript" class="transcript" aria-live="polite"></ol>
			</section>
			<div
				id="sidebar-resizer"
				class="sidebar-resizer"
				aria-hidden="true"
			></div>
			<aside class="sidebar" aria-label="Room members">
				<section class="sidebar-members">
					<h2 class="sidebar-heading">Members</h2>
					<p id="notify-count" class="notify-count" hidden></p>
					<ul id="roster" class="roster"></ul>
				</section>
				<section class="sidebar-self">
					<span class="profile-name-row">
						<input
							id="profile-name"
							maxlength="24"
							autocomplete="nickname"
							aria-label="Nickname"
						/>
						<button id="profile-name-apply" class="strip-button" type="button">
							Set
						</button>
					</span>
					<p id="profile-error" class="field-error" role="alert" hidden></p>
					<figure id="bodycam" class="bodycam" hidden>
						<canvas
							id="bodycam-canvas"
							tabindex="0"
							aria-label="Emotion wheel: drag the dot from the center toward an emotion; distance sets intensity"
						></canvas>
						<div class="bodycam-actions">
							<button
								id="bodycam-lock"
								class="bodycam-edit"
								type="button"
								aria-pressed="false"
								title="Freeze expression"
							>
								<svg class="lock-open" viewBox="0 0 16 16" aria-hidden="true">
									<path
										d="M11 1a4 4 0 0 0-4 4v2h1.8V5a2.2 2.2 0 0 1 4.4 0v1H15V5a4 4 0 0 0-4-4z"
									/>
									<rect x="1" y="7" width="10" height="8" />
								</svg>
								<svg class="lock-closed" viewBox="0 0 16 16" aria-hidden="true">
									<path
										d="M8 1a4 4 0 0 0-4 4v2h1.8V5a2.2 2.2 0 0 1 4.4 0v2H12V5a4 4 0 0 0-4-4z"
									/>
									<rect x="3" y="7" width="10" height="8" />
								</svg>
							</button>
							<button
								id="bodycam-send"
								class="bodycam-edit"
								type="button"
								title="Send expression"
							>
								<svg viewBox="0 0 16 16" aria-hidden="true">
									<path
										d="M8 1.5l5.5 5.5h-3v8h-5V7h-3z"
										fill="none"
										stroke="currentColor"
										stroke-width="1.4"
									/>
								</svg>
							</button>
						</div>
						<button
							id="avatar-edit"
							class="bodycam-edit"
							type="button"
							aria-expanded="false"
							aria-controls="profile-avatar-picker"
						>
							Change Character…
						</button>
					</figure>
					<fieldset
						id="profile-avatar-picker"
						class="character-picker profile-picker-grid"
					>
						<legend>Character</legend>
						<div id="profile-avatar-options" class="character-options"></div>
					</fieldset>
				</section>
				<div id="background-picker" class="background-picker" hidden>
					<label class="background-picker-classic">
						Background
						<select id="background-select"></select>
					</label>
					<fieldset class="background-picker-grid character-picker">
						<legend>Background</legend>
						<div id="background-options" class="character-options"></div>
					</fieldset>
				</div>
				<button
					id="sidebar-more"
					class="strip-button"
					type="button"
					aria-expanded="false"
					aria-controls="sidebar-controls"
				>
					More…
				</button>
				<div id="sidebar-controls" class="sidebar-controls">
					<div id="profile-picker" class="profile-picker">
						<fieldset class="room-picker">
							<legend>Room</legend>
							<div id="profile-room-options" class="room-options"></div>
						</fieldset>
					</div>
					<label class="tweaks-toggle">
						<input id="text-toggle" type="checkbox" />
						Plain text view
					</label>
					<label class="tweaks-toggle">
						<input id="title-toggle" type="checkbox" checked />
						Title screen
					</label>
					<label class="tweaks-toggle">
						<input
							id="modern-toggle"
							type="checkbox"
							checked
							aria-describedby="tweaks-hint"
						/>
						Modern tweaks
					</label>
					<label class="tweaks-toggle tweaks-toggle--nested">
						<input id="name-toggle" type="checkbox" />
						Show nametags
					</label>
					<p id="tweaks-hint" class="tweaks-hint">
						Smaller text fits more per balloon. Turn off for the original 1996
						layout; panels may break differently for other viewers.
					</p>
					<div class="strip-actions">
						<button id="save-strip" class="strip-button" type="button">
							Save Strip…
						</button>
						<!-- the build stamps the operator details the report draft names -->
						<button
							id="report-room"
							class="strip-button"
							type="button"
							data-site="%SITE_ORIGIN%"
							data-contact="%OPERATOR_CONTACT%"
							data-jurisdiction="%OPERATOR_JURISDICTION%"
						>
							Report…
						</button>
						<button
							id="leave-room"
							class="strip-button strip-button--leave"
							type="button"
						>
							Disconnect
						</button>
					</div>
				</div>
			</aside>
		</main>
		<div class="dock">
			<div id="mobile-sheet" class="mobile-sheet" hidden></div>
			<nav class="mobile-toolbar" aria-label="Panels">
				<button
					type="button"
					class="toolbar-button"
					data-panel="members"
					aria-expanded="false"
				>
					<svg class="toolbar-icon members-many" aria-hidden="true">
						<use href="#ic-members" />
					</svg>
					<svg class="toolbar-icon members-alone" aria-hidden="true">
						<use href="#ic-member" />
					</svg>
					<span>Members</span>
				</button>
				<button
					type="button"
					class="toolbar-button"
					data-panel="pose"
					aria-expanded="false"
				>
					<svg class="toolbar-icon" aria-hidden="true">
						<use href="#ic-pose" />
					</svg>
					<span>Pose</span>
				</button>
				<button
					type="button"
					class="toolbar-button"
					data-panel="bg"
					aria-expanded="false"
					hidden
				>
					<svg class="toolbar-icon" aria-hidden="true">
						<use href="#ic-bg" />
					</svg>
					<span>Background</span>
				</button>
				<button
					type="button"
					class="toolbar-button"
					data-panel="more"
					aria-expanded="false"
				>
					<svg class="toolbar-icon" aria-hidden="true">
						<use href="#ic-more" />
					</svg>
					<span>More</span>
				</button>
			</nav>
			<p id="filter-notice" class="filter-notice" role="alert" hidden></p>
			<form id="composer" class="composer">
				<select id="composer-mode" aria-label="Balloon type">
					<option value="1">Say</option>
					<option value="3">Think</option>
					<option value="2">Whisper</option>
					<option value="5">Action</option>
				</select>
				<input
					id="composer-text"
					maxlength="1000"
					required
					placeholder="Type your message"
					autocomplete="off"
					aria-label="Message"
				/>
				<button type="submit">Send</button>
			</form>
			<footer class="legal-footer">
				<span>© 2026 Comic Chat Web contributors</span>
				<span aria-hidden="true">·</span>
				<a href="https://github.com/remsky/comic-chat-web/blob/main/LICENSE"
					>AGPL-3.0</a
				>
				<span aria-hidden="true">·</span>
				<a href="/legal.html#terms">Terms</a>
				<span aria-hidden="true">·</span>
				<a href="/legal.html#privacy">Privacy</a>
			</footer>
		</div>
		<section id="join" class="join-overlay" aria-label="Connect to a room">
			<div class="dialog">
				<header class="dialog-titlebar">Connect</header>
				<form id="join-form" class="dialog-body">
					<label>
						Nickname
						<input
							id="join-name"
							name="name"
							required
							maxlength="24"
							placeholder="Your name"
							autocomplete="nickname"
						/>
					</label>
					<p id="join-name-error" class="field-error" role="alert" hidden></p>
					<fieldset class="room-picker">
						<legend>Room</legend>
						<div id="join-room-options" class="room-options"></div>
					</fieldset>
					<fieldset id="join-avatar" class="character-picker">
						<legend>Character</legend>
						<div class="character-options"></div>
						<p id="join-avatar-error" class="field-error" role="alert" hidden>
							Pick a character to connect.
						</p>
					</fieldset>
					<div class="dialog-buttons">
						<p class="join-consent">
							Rooms are public. By connecting you confirm you are 18 or older and
							accept the <a href="/legal.html#terms">Terms</a> and
							<a href="/legal.html#privacy">Privacy Policy</a>.
						</p>
						<label class="remember-toggle">
							<input id="join-remember" type="checkbox" />
							Remember me
						</label>
						<button type="submit">Connect</button>
					</div>
				</form>
			</div>
			<p class="join-tagline">
				Modern port of Microsoft Comic Chat (1996), drawing live chat as comic
				strips on Cloudflare Durable Objects.
			</p>
		</section>
		<dialog id="notify-dialog" class="notify-dialog">
			<header class="dialog-titlebar">Notifications</header>
			<form method="dialog" class="dialog-body">
				<p id="notify-dialog-text" class="notify-dialog-text"></p>
				<div class="dialog-buttons">
					<button type="submit">Close</button>
				</div>
			</form>
		</dialog>
		<p id="status" class="status" role="status">Loading fonts and avatar art…</p>
		<script type="module" src="/src/browser/room.ts"></script>
	</body>
</html>