:root {
	--paper: #f3ead6;
	--paper-edge: #e6d9bd;
	--ink: #1c1a2e;
	--reveal-ms: 650ms;
	--word-gap-ms: 65ms;
	--bloom-blur: 4px;
	--swirl-distance: 7px;
	--swirl-angle: -9deg;
	--unit: 0.5px;
	--sheet-w: 1000;
	--sheet-h: 1400;
}
@font-face { font-family: 'EB Garamond'; src: url('/fonts/garamond.woff2') format('woff2'); font-style: italic; font-weight: 400 700; font-display: swap; }
@font-face { font-family: 'Pinyon Script'; src: url('/fonts/pinyon.woff2') format('woff2'); font-display: swap; }
@font-face { font-family: 'Great Vibes'; src: url('/fonts/greatvibes.woff2') format('woff2'); font-display: swap; }
@font-face { font-family: 'Tangerine'; src: url('/fonts/tangerine.woff2') format('woff2'); font-display: swap; }

html, body { margin: 0; height: 100%; background: var(--paper-edge); overflow: hidden; overscroll-behavior: none; }
body { display: grid; place-items: center; color: var(--ink); -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; }
/* A readable hand by default; the calligraphic ones stay a setting away. */
.script { font-family: 'EB Garamond', serif; font-style: italic; font-weight: 600; }
body[data-font="pinyon"] .script { font-family: 'Pinyon Script', cursive; font-style: normal; font-weight: 400; }
body[data-font="greatvibes"] .script { font-family: 'Great Vibes', cursive; font-style: normal; font-weight: 400; }
body[data-font="tangerine"] .script { font-family: 'Tangerine', cursive; font-style: normal; font-weight: 700; }

/* The sheet is a 1000×1400 logical page — turned on its side in landscape — fitted into the
   viewport; --unit is one logical unit in px. */
.sheet {
	position: relative;
	width: calc(var(--sheet-w) * var(--unit));
	height: calc(var(--sheet-h) * var(--unit));
	background: var(--paper) radial-gradient(ellipse at center, rgba(255, 255, 255, 0.35), rgba(120, 90, 40, 0.14));
	box-shadow: inset 0 0 calc(40 * var(--unit)) rgba(60, 40, 10, 0.22);
	overflow: hidden;
}
.sheet::after {
	content: '';
	position: absolute;
	left: 8%; right: 8%;
	bottom: calc(60 * var(--unit));
	border-bottom: 1px solid rgba(60, 40, 10, 0.15);
	pointer-events: none;
}
.ink { position: absolute; inset: 0; width: 100%; height: 100%; touch-action: none; transition: opacity .15s, filter .15s, transform .15s; }
.entry, .reply {
	position: absolute; inset: 0;
	padding: calc(70 * var(--unit)) calc(80 * var(--unit));
	box-sizing: border-box;
	font-size: calc(52 * var(--unit));
	line-height: 1.35;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	pointer-events: none;
	overflow: hidden;
	color: var(--ink);
}
.entry { transition: opacity .15s, filter .15s, transform .15s; overflow-y: auto; scrollbar-width: none; }
.entry::-webkit-scrollbar { display: none; }
.entry .interim { opacity: .45; }
.ink.sinking, .entry.sinking {
	opacity: 0;
	filter: blur(3px);
	transform: translateY(calc(6 * var(--unit)));
	transition: opacity 1.5s ease-in, filter 1.5s ease-in, transform 1.5s ease-in;
}
.reply { overflow-y: auto; scrollbar-width: none; }
.reply::-webkit-scrollbar { display: none; }
.reply.fading { opacity: 0; transition: opacity 1.2s ease-out; }
.reply .w { display: inline-block; animation: bloom var(--reveal-ms) ease-out both; }
@keyframes bloom {
	from { opacity: 0; filter: blur(var(--bloom-blur)); }
	to { opacity: 1; filter: blur(0); }
}
/* swirl: each word arrives displaced and blurred while a ghost of it spirals away — a first
   experiment; every number is a variable so it can be tuned without touching JS. */
.reply[data-effect="swirl"] .w { position: relative; animation: swirl-in var(--reveal-ms) cubic-bezier(.2, .7, .3, 1) both; }
.reply[data-effect="swirl"] .w::before {
	content: attr(data-ink);
	position: absolute; left: 0; top: 0;
	color: inherit; opacity: 0; pointer-events: none;
	animation: swirl-ghost calc(var(--reveal-ms) * 1.4) ease-out both;
	animation-delay: inherit;
}
@keyframes swirl-in {
	from { opacity: 0; filter: blur(calc(var(--bloom-blur) * 1.5)); transform: translate(calc(var(--swirl-distance) * -1), var(--swirl-distance)) rotate(var(--swirl-angle)); }
	60% { opacity: .9; filter: blur(1px); transform: translate(1px, -1px) rotate(calc(var(--swirl-angle) * -.2)); }
	to { opacity: 1; filter: blur(0); transform: none; }
}
@keyframes swirl-ghost {
	0% { opacity: .55; filter: blur(2px); transform: translate(var(--swirl-distance), calc(var(--swirl-distance) * -1)) rotate(calc(var(--swirl-angle) * -1)) scale(1.05); }
	40% { opacity: .35; transform: translate(calc(var(--swirl-distance) * -.6), calc(var(--swirl-distance) * .8)) rotate(var(--swirl-angle)) scale(1.1); }
	100% { opacity: 0; filter: blur(6px); transform: translate(0, calc(var(--swirl-distance) * -1.5)) scale(1.3); }
}
/* The reply layer lets ink through; this strip on the right is where a long reply is scrolled. */
.gutter { position: absolute; top: 0; right: 0; bottom: 0; width: calc(60 * var(--unit)); touch-action: pan-y; }

.blot {
	position: fixed; left: 50%; bottom: max(24px, env(safe-area-inset-bottom));
	width: 10px; height: 10px; margin-left: -5px; border-radius: 50%;
	background: var(--ink); opacity: .5;
	animation: pulse 1.6s ease-in-out infinite;
}
@keyframes pulse {
	0%, 100% { transform: scale(.6); opacity: .25; }
	50% { transform: scale(1.3); opacity: .6; }
}
.status { position: fixed; left: 0; right: 0; bottom: max(20px, env(safe-area-inset-bottom)); text-align: center; font-size: 24px; padding: 0 12px; }
.status .link { font: inherit; color: inherit; background: none; border: 0; text-decoration: underline; cursor: pointer; padding: 6px; }
.status .faint { opacity: .55; }
.glyph {
	position: fixed; right: max(14px, env(safe-area-inset-right)); bottom: max(14px, env(safe-area-inset-bottom));
	width: 44px; height: 44px; border: 0; background: none; color: var(--ink); opacity: .22; font-size: 24px; cursor: pointer;
}
.keyboard { position: fixed; left: 0; bottom: 0; width: 1px; height: 1px; opacity: 0; border: 0; padding: 0; resize: none; }
dialog {
	border: 0; background: var(--paper); color: var(--ink);
	padding: 24px 28px; font-size: 26px; max-width: min(90vw, 420px);
	box-shadow: 0 10px 40px rgba(0, 0, 0, .3);
}
dialog::backdrop { background: rgba(30, 20, 10, .45); }
dialog label { display: block; margin: 10px 0; }
dialog input, dialog button, dialog select { font: inherit; color: inherit; }
dialog select { background: rgba(255, 255, 255, .5); border: 1px solid rgba(60, 40, 10, .3); }
dialog input[type=range] { width: 100%; }
dialog input[type=password] {
	width: 100%; box-sizing: border-box; padding: 8px 10px; margin: 8px 0;
	background: rgba(255, 255, 255, .5); border: 1px solid rgba(60, 40, 10, .3);
	font-family: system-ui, sans-serif; font-size: 18px;
}
dialog button { display: block; width: 100%; background: none; border: 1px solid rgba(60, 40, 10, .3); padding: 6px 14px; margin-top: 10px; cursor: pointer; }
@media (prefers-reduced-motion: reduce) {
	.reply .w, .blot { animation: none; }
	.ink.sinking, .entry.sinking, .reply.fading { transition-duration: .01s; }
}
