/* Grimoire — a chat-first rules reference.
   Chrome is candlelit stone; parchment is reserved for content surfaces
   (answers, rules, cards) so it reads as the artifact rather than the
   wallpaper.

   The palette below is not chosen, it is measured: every parchment, leather
   and gold value is a colour lifted straight out of the pixel-art frames in
   pixel.css. A nine-sliced surface and a plain CSS one have to meet without a
   seam, which they only do while these stay in step with the sprites. */

/* ---------- Tokens ---------- */
:root {
	/* stone (app chrome) — the frames are recoloured to these, not vice versa */
	--stone-900: #14100a;
	--stone-800: #1b1610;
	--stone-700: #241d15;
	--stone-600: #2f261b;
	--stone-500: #3d3225;
	--stone-line: #4a3c2b;

	/* parchment (content) — the page sprite's own pixels */
	--parchment: #ffd7a8;
	--parchment-2: #f0c48f;
	--parchment-line: #e5b67f;
	--outline: #493333;
	--ink: #3a2a26;      /* 10:1 on parchment */
	--ink-soft: #6b4f42; /* 5.5:1 on parchment */

	/* the book's own leather */
	--leather: #b75b5f;
	--leather-deep: #9c4351;

	/* metal + light */
	--gold: #c9a227;
	--gold-bright: #ffd071;
	--gold-dim: #8a7024;
	--ember: #ffa34d;
	--ember-deep: #e5673c;

	/* corpus accent — MTG mana blue */
	--accent: #4d7fd6;
	--accent-deep: #1d4699;
	--accent-soft: rgba(77, 127, 214, 0.16);

	/* type — four voices: prose, chrome, carved headings, pixel labels */
	--font-ui: ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
	--font-prose: "EB Garamond", "Iowan Old Style", "Palatino Linotype", Palatino, Georgia, serif;
	--font-display: "Cinzel", "Trajan Pro", var(--font-prose);
	--font-pixel: "Departure Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
	--fs-xs: 0.75rem;
	--fs-sm: 0.85rem;
	--fs-md: 0.95rem;
	--fs-lg: 1.05rem;

	/* space + shape */
	--sp-1: 0.25rem;
	--sp-2: 0.5rem;
	--sp-3: 0.75rem;
	--sp-4: 1rem;
	--sp-5: 1.5rem;
	--sp-6: 2rem;
	--r-sm: 6px;
	--r-md: 10px;
	--r-lg: 14px;
	--r-pill: 999px;

	--shadow-1: 0 1px 2px rgba(0, 0, 0, 0.4);
	--shadow-2: 0 6px 20px rgba(0, 0, 0, 0.45);
	--shadow-3: 0 18px 50px rgba(0, 0, 0, 0.6);

	--rail-w: 264px;
	--drawer-w: 380px;
	--measure: 46rem;
}

html[data-corpus="dnd"] {
	--accent: #cf5b4a;
	--accent-deep: #8a1c1c;
	--accent-soft: rgba(207, 91, 74, 0.16);
}

* { box-sizing: border-box; }

html, body {
	margin: 0;
	padding: 0;
	height: 100%;
}

body {
	font-family: var(--font-ui);
	font-size: var(--fs-md);
	color: var(--parchment);
	background: var(--stone-900);
	line-height: 1.55;
	-webkit-font-smoothing: antialiased;
	overflow: hidden;
}

button, input, textarea { font: inherit; color: inherit; }
[hidden] { display: none !important; }

:focus-visible {
	outline: 2px solid var(--gold-bright);
	outline-offset: 2px;
}

kbd {
	font-family: var(--font-pixel);
	font-size: 0.72rem;
	letter-spacing: 0.02em;
	padding: 0.1rem 0.35rem 0;
	border: 1px solid var(--stone-line);
	border-bottom-width: 2px;
	border-radius: 3px;
	background: var(--stone-700);
	color: var(--parchment);
	opacity: 0.8;
}

/* ---------- Shell ---------- */
.app {
	display: grid;
	grid-template-columns: var(--rail-w) minmax(0, 1fr) 0;
	grid-template-rows: 100%;
	height: 100%;
	overflow: hidden;
	transition: grid-template-columns 0.22s ease;
}
.app.rail-hidden { grid-template-columns: 0 minmax(0, 1fr) 0; }
.app.drawer-open { grid-template-columns: var(--rail-w) minmax(0, 1fr) var(--drawer-w); }
.app.rail-hidden.drawer-open { grid-template-columns: 0 minmax(0, 1fr) var(--drawer-w); }

/* ---------- Sidebar ---------- */
/* Chrome sits *on* the chamber, not over a hole cut in it: the panels are
   stone at 90% so the scene's light reaches around their edges. */
.rail {
	display: flex;
	flex-direction: column;
	min-width: 0;
	overflow: hidden;
	background: rgba(27, 22, 16, 0.9);
	backdrop-filter: blur(6px);
	border-right: 1px solid var(--stone-line);
}
.rail-head {
	display: flex;
	align-items: center;
	justify-content: space-between;
	gap: var(--sp-2);
	padding: var(--sp-3) var(--sp-3) var(--sp-2);
}
.wordmark {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	font-family: var(--font-display);
	font-weight: 700;
	letter-spacing: 0.1em;
	font-size: var(--fs-md);
	text-transform: uppercase;
	color: var(--gold-bright);
	white-space: nowrap;
	text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6);
}

.icon-btn {
	display: grid;
	place-items: center;
	background: none;
	border: 1px solid transparent;
	border-radius: var(--r-sm);
	color: var(--parchment);
	opacity: 0.65;
	cursor: pointer;
	padding: 0.35rem 0.5rem;
	font-size: var(--fs-lg);
	line-height: 1;
	transition: opacity 0.15s ease, background 0.15s ease, color 0.15s ease;
}
.icon-btn:hover { opacity: 1; background: rgba(255, 255, 255, 0.06); color: var(--gold-bright); }
.icon-btn.danger:hover { color: var(--ember); }

/* The primary action gets a real sprite, so it gets real height. */
.new-chat {
	margin: 0 var(--sp-3) var(--sp-3);
	padding: var(--sp-1) var(--sp-3);
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	color: #1a1208; /* ink on gold — the frame behind this is the gold */
	font-family: var(--font-display);
	font-weight: 700;
	letter-spacing: 0.1em;
	text-transform: uppercase;
	font-size: var(--fs-sm);
	cursor: pointer;
	filter: brightness(0.94);
	transition: filter 0.15s ease;
}
.new-chat:hover { filter: brightness(1.06); }
.new-chat .ico { margin: -2px 0; }

/* Two cards rather than a pill: 32px pixel art does not survive being shrunk
   to fit a segmented control, so the control grows to fit the art. */
.corpus-picker {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--sp-2);
	margin: 0 var(--sp-3) var(--sp-3);
}
.corpus-opt {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-1);
	padding: var(--sp-2) var(--sp-1) var(--sp-1);
	border: 1px solid var(--stone-line);
	border-radius: var(--r-md);
	background: var(--stone-700);
	color: var(--parchment);
	opacity: 0.55;
	font-size: var(--fs-xs);
	font-weight: 600;
	letter-spacing: 0.04em;
	cursor: pointer;
	white-space: nowrap;
	transition: all 0.15s ease;
}
.corpus-opt .ico { filter: grayscale(0.7) brightness(0.8); transition: filter 0.15s ease; }
.corpus-opt:hover { opacity: 0.85; }
.corpus-opt:hover .ico { filter: none; }
.corpus-opt.is-active {
	opacity: 1;
	border-color: var(--accent);
	background: var(--accent-soft);
	color: var(--gold-bright);
	box-shadow: var(--shadow-1);
}
.corpus-opt.is-active .ico { filter: drop-shadow(0 0 6px var(--accent)); }

.history {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	padding: 0 var(--sp-2) var(--sp-3);
}
.history-group {
	padding: var(--sp-3) var(--sp-2) var(--sp-1);
	font-family: var(--font-pixel);
	font-size: 0.7rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--gold-dim);
	opacity: 0.9;
}
.history-item {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	width: 100%;
	padding: 0.45rem var(--sp-2);
	border: none;
	border-radius: var(--r-sm);
	background: none;
	color: inherit;
	text-align: left;
	font-size: var(--fs-sm);
	cursor: pointer;
	transition: background 0.12s ease;
}
.history-item:hover { background: rgba(255, 255, 255, 0.06); }
.history-item.is-active { background: rgba(232, 198, 90, 0.14); color: var(--gold-bright); }
.history-item .h-mark { flex: none; opacity: 0.5; color: var(--accent); }
.history-item.is-active .h-mark { opacity: 1; color: var(--gold-bright); }
.history-item .h-title {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.history-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-2);
	padding: var(--sp-6) var(--sp-3);
	text-align: center;
	font-family: var(--font-prose);
	font-size: var(--fs-sm);
	opacity: 0.35;
	font-style: italic;
}
.history-empty .gi { opacity: 0.7; }

.rail-foot {
	position: relative;
	border-top: 1px solid var(--stone-line);
	padding: var(--sp-2) var(--sp-3) var(--sp-3);
}
.rail-action {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	width: 100%;
	padding: 0.45rem var(--sp-2);
	border: none;
	border-radius: var(--r-sm);
	background: none;
	color: inherit;
	opacity: 0.75;
	font-size: var(--fs-sm);
	cursor: pointer;
}
.rail-action:hover { background: rgba(255, 255, 255, 0.06); opacity: 1; color: var(--gold-bright); }
.rail-action kbd { margin-left: auto; }
.rail-action .gi { color: var(--gold-dim); }
.rail-action:hover .gi { color: var(--gold-bright); }
.rail-user {
	margin-left: auto;
	max-width: 9rem;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: var(--fs-xs);
	opacity: 0.55;
}
.model-badge {
	margin: var(--sp-2) var(--sp-2) 0;
	font-family: var(--font-pixel);
	font-size: 0.68rem;
	letter-spacing: 0.02em;
	opacity: 0.35;
	line-height: 1.5;
}

.rail-scrim { display: none; }

/* ---------- Main column ---------- */
/* Transparent on purpose — this column is where the chamber shows through. */
.main {
	display: flex;
	flex-direction: column;
	min-width: 0;
	height: 100%;
	background: none;
}

.topbar {
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	flex: none;
	padding: var(--sp-2) var(--sp-4);
	border-bottom: 1px solid var(--stone-line);
	background: rgba(20, 16, 10, 0.7);
	backdrop-filter: blur(8px);
}
.rail-open { display: none; }
.app.rail-hidden .rail-open { display: block; }
.conv-title {
	margin: 0;
	font-family: var(--font-display);
	font-size: var(--fs-md);
	font-weight: 600;
	letter-spacing: 0.04em;
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.corpus-chip {
	display: inline-flex;
	align-items: center;
	gap: 0.35rem;
	flex: none;
	padding: 0.1rem 0.55rem;
	border: 1px solid var(--accent);
	border-radius: var(--r-pill);
	background: var(--accent-soft);
	color: var(--parchment);
	font-family: var(--font-pixel);
	font-size: 0.7rem;
	letter-spacing: 0.03em;
	white-space: nowrap;
}
.corpus-chip .gi { color: var(--accent); }
.topbar-actions { margin-left: auto; display: flex; gap: var(--sp-1); flex: none; }

/* ---------- Transcript ---------- */
.transcript {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	scroll-behavior: smooth;
	padding: var(--sp-5) var(--sp-4) var(--sp-4);
}
.messages {
	max-width: var(--measure);
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	gap: var(--sp-5);
}

/* welcome / empty state — the branding lives here, not in a permanent banner */
.welcome {
	max-width: var(--measure);
	margin: clamp(1rem, 9vh, 5rem) auto var(--sp-6);
	text-align: center;
}
.welcome-sigil {
	line-height: 0;
	filter: drop-shadow(0 4px 14px rgba(255, 208, 113, 0.45));
	animation: sigil-breathe 6s ease-in-out infinite;
}
@keyframes sigil-breathe {
	0%, 100% { filter: drop-shadow(0 4px 14px rgba(255, 208, 113, 0.35)); }
	50%      { filter: drop-shadow(0 4px 20px rgba(255, 208, 113, 0.6)); }
}
.welcome-title {
	margin: var(--sp-4) 0 var(--sp-2);
	font-family: var(--font-display);
	letter-spacing: 0.16em;
	text-indent: 0.16em; /* balance the tracking on the last letter */
	text-transform: uppercase;
	font-size: clamp(1.5rem, 3.6vw, 2.1rem);
	font-weight: 700;
	color: var(--gold-bright);
	text-shadow: 0 2px 0 rgba(0, 0, 0, 0.55);
}
.welcome-sub {
	margin: 0 0 var(--sp-5);
	font-family: var(--font-prose);
	font-style: italic;
	font-size: var(--fs-lg);
	opacity: 0.65;
}
.suggestions {
	display: flex;
	flex-wrap: wrap;
	gap: var(--sp-2);
	justify-content: center;
}
.suggestion {
	padding: 0.35rem 0.6rem;
	color: var(--ink);
	font-family: var(--font-prose);
	font-size: var(--fs-sm);
	line-height: 1.35;
	cursor: pointer;
	filter: brightness(0.94);
	transition: filter 0.15s ease;
}
.suggestion:hover { filter: brightness(1.06); }

/* ---------- Messages ---------- */
.msg { display: flex; flex-direction: column; }
.msg-user { align-items: flex-end; }

.msg-user .bubble {
	max-width: 84%;
	padding: 0.6rem 0.95rem;
	border-radius: var(--r-lg) var(--r-lg) var(--r-sm) var(--r-lg);
	background: var(--accent-deep);
	color: #fff;
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	box-shadow: var(--shadow-1);
}

.msg-sage .who {
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	margin-bottom: var(--sp-1);
	font-family: var(--font-display);
	font-weight: 600;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	font-size: var(--fs-xs);
	color: var(--gold);
}
.msg-sage .who .ico { margin: -4px 0; }

/* Framed by .f-parchment in pixel.css — no border, background or radius here,
   the sprite supplies all three. */
.msg-sage .bubble {
	position: relative;
	padding: var(--sp-2) var(--sp-3) var(--sp-2);
	color: var(--ink);
	font-family: var(--font-prose);
	font-size: 1.12rem;
	line-height: 1.6;
	overflow-wrap: anywhere;
	/* the corpus's own colour, as a rule down the inside of the page */
	box-shadow: inset 3px 0 0 var(--accent), var(--shadow-2);
}
.msg-sage.is-error .bubble {
	box-shadow: inset 3px 0 0 var(--ember-deep), var(--shadow-2);
	font-style: italic;
}

/* markdown inside an answer */
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose p { margin: 0 0 0.7em; }
.prose h1, .prose h2, .prose h3 {
	margin: 1em 0 0.4em;
	font-variant: small-caps;
	letter-spacing: 0.03em;
	line-height: 1.25;
}
.prose h1 { font-size: 1.3em; }
.prose h2 { font-size: 1.18em; }
.prose h3 { font-size: 1.06em; }
.prose ul, .prose ol { margin: 0 0 0.7em; padding-left: 1.4em; }
.prose li { margin: 0.2em 0; }
.prose blockquote {
	margin: 0 0 0.7em;
	padding: 0.1em 0 0.1em 0.9em;
	border-left: 3px solid var(--parchment-line);
	font-style: italic;
	opacity: 0.85;
}
.prose code {
	font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
	font-size: 0.86em;
	padding: 0.1em 0.35em;
	border-radius: 4px;
	background: rgba(43, 29, 14, 0.09);
}
.prose pre {
	margin: 0 0 0.7em;
	padding: var(--sp-3);
	overflow-x: auto;
	border-radius: var(--r-sm);
	background: rgba(43, 29, 14, 0.08);
	border: 1px solid var(--parchment-line);
}
.prose pre code { background: none; padding: 0; }
.prose hr { border: none; border-top: 1px solid var(--parchment-line); margin: 1em 0; }
.prose strong { font-weight: 700; }
.prose a { color: var(--accent-deep); }

/* Inline rule reference produced by the markdown pass. Framed by pixel.css. */
.rule-ref {
	font-family: var(--font-pixel);
	font-size: 0.76em;
	padding: 0 0.15em;
	color: var(--accent-deep);
	cursor: pointer;
	filter: brightness(0.97);
	transition: filter 0.12s ease;
}
.rule-ref:hover { filter: brightness(1.08); }

/* Streaming caret — a hard-edged block, not a glyph, so it reads as a quill
   nib on the page rather than a text cursor from another century. */
.bubble.is-streaming .prose > :last-child::after {
	content: "";
	display: inline-block;
	width: 3px;
	height: 0.95em;
	margin-left: 2px;
	vertical-align: -0.12em;
	background: var(--ember-deep);
	animation: blink 1s steps(2, start) infinite;
}
@keyframes blink { to { visibility: hidden; } }

/* The sage casting: a hand, then the six magic scrolls, on a loop. */
.thinking {
	display: inline-flex;
	align-items: center;
	gap: var(--sp-2);
	font-family: var(--font-prose);
	font-style: italic;
	color: var(--ink-soft);
}
.thinking .ico { margin: -6px 0; }

/* citations */
.citations {
	margin-top: var(--sp-3);
	padding-top: var(--sp-2);
	border-top: 1px dashed var(--parchment-line);
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-1);
	font-family: var(--font-ui);
	font-size: var(--fs-xs);
}
.citations-label {
	color: var(--ink-soft);
	margin-right: var(--sp-1);
	font-family: var(--font-pixel);
	font-size: 0.68rem;
	text-transform: uppercase;
	letter-spacing: 0.08em;
}
/* Framed by .f-chip in pixel.css. */
.chip {
	display: inline-flex;
	align-items: center;
	gap: 0.25rem;
	padding: 0.05rem 0.3rem;
	color: var(--ink);
	cursor: pointer;
	filter: brightness(0.96);
	transition: filter 0.12s ease;
}
.chip:hover { filter: brightness(1.08); }
.chip .gi { color: var(--ink-soft); }
.chip.chip-card { color: var(--accent-deep); font-weight: 600; }
.chip.chip-miss {
	cursor: default;
	color: var(--ember-deep);
	text-decoration: line-through;
	filter: saturate(0.6);
}
/* D&D's answer to chip-card: a resolved entity, not a Magic card. Same
   treatment, because to the reader they are the same kind of citation. */
.chip.chip-entity { color: var(--accent-deep); font-weight: 600; }

/* rulings — official precedent citations under an answer */
.rulings {
	margin-top: var(--sp-3);
	padding-top: var(--sp-2);
	border-top: 1px dashed var(--parchment-line);
	display: flex;
	flex-direction: column;
	gap: var(--sp-2);
	font-family: var(--font-ui);
	font-size: var(--fs-xs);
}
.rulings-label {
	color: var(--ink-soft);
	font-family: var(--font-pixel);
	letter-spacing: 0.08em;
	text-transform: uppercase;
	font-size: 0.68rem;
}
.ruling {
	display: flex;
	flex-direction: column;
	gap: 0.15rem;
	padding-left: var(--sp-3);
	border-left: 2px solid var(--gold-dim, rgba(201, 162, 39, 0.4));
}
.ruling-comment {
	margin: 0;
	color: var(--ink);
	line-height: 1.4;
}
.ruling-attr {
	color: var(--ink-soft);
	font-size: var(--fs-xs);
	display: inline-flex;
	flex-wrap: wrap;
	gap: 0.3rem;
	align-items: baseline;
}
.ruling-card { font-weight: 600; color: var(--ink); }
.ruling-source {}
.ruling-date {}
.ruling-sep { opacity: 0.5; }

/* ---------- Composer ---------- */
.composer-dock {
	flex: none;
	padding: 0 var(--sp-4) var(--sp-3);
	background: linear-gradient(180deg, transparent, var(--stone-900) 35%);
}
/* Framed by .f-field in pixel.css, which also swaps to the gold-edged sprite
   on focus — hence no border or background here. */
.composer {
	position: relative;
	display: flex;
	align-items: flex-end;
	gap: var(--sp-2);
	max-width: var(--measure);
	margin: 0 auto;
	padding: var(--sp-1) var(--sp-1) var(--sp-1) var(--sp-3);
	box-shadow: var(--shadow-2);
}
.composer-input {
	flex: 1;
	min-width: 0;
	max-height: 40vh;
	padding: 0.45rem 0;
	border: none;
	background: none;
	color: var(--parchment);
	font-family: var(--font-prose);
	font-size: var(--fs-lg);
	line-height: 1.5;
	resize: none;
	overflow-y: auto;
}
.composer-input:focus { outline: none; }
.composer-input::placeholder { color: var(--parchment); opacity: 0.35; }
.composer-side { flex: none; display: flex; align-items: center; }
/* Framed by .f-button in pixel.css. */
.send-btn {
	width: 2.3rem;
	height: 2.3rem;
	display: grid;
	place-items: center;
	padding: 0;
	color: #1a1208;
	font-size: var(--fs-md);
	cursor: pointer;
	transition: filter 0.15s ease, opacity 0.15s ease;
}
.send-btn:hover:not(:disabled) { filter: brightness(1.1); }
.send-btn:disabled { opacity: 0.35; cursor: default; }
/* The quill-arrow is drawn flying down-left; send points right. */
.send-btn .gi { transform: rotate(-45deg); }
.stop-btn .gi { transform: none; }
.stop-btn { color: #2a0f08; filter: hue-rotate(-28deg) saturate(1.4); }
.voice-btn {
	width: 2.3rem;
	height: 2.3rem;
	display: grid;
	place-items: center;
	padding: 0;
	border: 1px solid var(--stone-line);
	border-radius: var(--r-sm);
	background: var(--stone-700);
	color: var(--parchment);
	cursor: pointer;
	opacity: 0.7;
	font-size: var(--fs-md);
	transition: opacity 0.15s ease, background 0.15s ease, border-color 0.15s ease;
}
.voice-btn:hover:not(:disabled):not(.is-unavailable) { opacity: 1; }
.voice-btn:disabled { opacity: 0.35; cursor: default; }
.voice-btn.is-unavailable { opacity: 0.4; cursor: help; }
.voice-btn.is-unavailable:hover { opacity: 0.55; }
.voice-btn.is-active {
	background: var(--accent);
	border-color: var(--accent-deep);
	color: #fff;
	opacity: 1;
	animation: voice-pulse 1.6s ease-in-out infinite;
}
@keyframes voice-pulse {
	0%, 100% { box-shadow: 0 0 0 0 var(--accent-soft); transform: scale(1); }
	50% { box-shadow: 0 0 0 6px transparent; transform: scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
	.voice-btn.is-active { animation: none; }
}
.composer-foot {
	max-width: var(--measure);
	margin: var(--sp-2) auto 0;
	font-family: var(--font-pixel);
	font-size: 0.68rem;
	letter-spacing: 0.02em;
	opacity: 0.4;
	text-align: center;
	min-height: 1.1em;
}
.composer-foot.warn { opacity: 0.85; color: var(--ember); }

/* ---------- Mode toggle (Ask / Resolve) ---------- */
.mode-toggle {
	display: flex;
	gap: 2px;
	flex: none;
	padding: 3px;
	background: var(--stone-700);
	border: 1px solid var(--stone-line);
	border-radius: var(--r-pill);
}
.mode-opt {
	display: inline-flex;
	align-items: center;
	gap: 0.3rem;
	padding: 0.2rem 0.55rem;
	border: none;
	border-radius: var(--r-pill);
	background: none;
	color: var(--parchment);
	opacity: 0.6;
	font-family: var(--font-pixel);
	font-size: 0.72rem;
	letter-spacing: 0.03em;
	white-space: nowrap;
	cursor: pointer;
	transition: all 0.15s ease;
}
.mode-opt:hover { opacity: 0.9; }
.mode-opt.is-active {
	opacity: 1;
	background: var(--accent-deep);
	color: #fff;
}

/* ---------- Resolver composer ---------- */
.composer.resolver {
	flex-direction: column;
	align-items: stretch;
	gap: var(--sp-2);
	padding: var(--sp-2);
}
.resolver-grid {
	display: grid;
	grid-template-columns: 1fr 1fr;
	gap: var(--sp-2);
}
.resolver-field,
.resolver-note-row {
	display: flex;
	flex-direction: column;
	gap: 0.2rem;
	min-width: 0;
}
.resolver-label {
	font-family: var(--font-pixel);
	font-size: 0.7rem;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	color: var(--gold-dim);
	opacity: 0.9;
}
.resolver-field textarea,
.resolver-note-row input {
	min-width: 0;
	max-height: 32vh;
	padding: 0.4rem 0.5rem;
	border: 1px solid var(--stone-line);
	border-radius: var(--r-sm);
	background: var(--stone-900);
	color: var(--parchment);
	font-family: var(--font-prose);
	font-size: var(--fs-sm);
	line-height: 1.45;
	resize: none;
	overflow-y: auto;
}
.resolver-field textarea:focus,
.resolver-note-row input:focus {
	outline: none;
	border-color: var(--gold-dim);
	box-shadow: 0 0 0 2px rgba(201, 162, 39, 0.12);
}
.resolver-field textarea::placeholder,
.resolver-note-row input::placeholder { color: var(--parchment); opacity: 0.3; }
.resolver-note-row { flex-direction: row; align-items: center; gap: var(--sp-2); }
.resolver-note-row .resolver-label { flex: none; }
.resolver-note-row input { flex: 1; }
.resolver .composer-side { align-self: flex-end; }
.resolver-caveat {
	max-width: var(--measure);
	margin: var(--sp-1) auto 0;
	font-size: var(--fs-xs);
	font-style: italic;
	opacity: 0.4;
	text-align: center;
}

/* resolver recap shown as the user turn */
.resolver-recap { display: flex; flex-direction: column; gap: var(--sp-1); min-width: 0; }
.recap-sec { display: flex; flex-direction: column; gap: 0.1rem; min-width: 0; }
.recap-k {
	font-size: var(--fs-xs);
	font-weight: 700;
	letter-spacing: 0.05em;
	text-transform: uppercase;
	opacity: 0.6;
}
.recap-v {
	white-space: pre-wrap;
	font-family: var(--font-prose);
	font-size: var(--fs-sm);
	line-height: 1.4;
}

/* slash command hints */
.slash-hints {
	position: absolute;
	left: 0;
	right: 0;
	bottom: calc(100% + var(--sp-2));
	margin: 0;
	padding: var(--sp-1);
	list-style: none;
	background: var(--stone-800);
	border: 1px solid var(--stone-line);
	border-radius: var(--r-md);
	box-shadow: var(--shadow-3);
	z-index: 5;
}
.slash-hints li {
	display: flex;
	gap: var(--sp-3);
	padding: 0.4rem var(--sp-3);
	border-radius: var(--r-sm);
	cursor: pointer;
	font-size: var(--fs-sm);
}
.slash-hints li.is-active, .slash-hints li:hover { background: rgba(255, 255, 255, 0.07); }
.slash-hints .cmd { color: var(--gold-bright); font-weight: 600; }
.slash-hints .cmd-desc { opacity: 0.55; }

/* ---------- Study surface ----------
   The flashcard deck. It takes over the main column rather than unmounting the
   transcript, so leaving study restores the open conversation exactly.

   Three framed surfaces, all wired up in pixel.css: the prompt is parchment,
   because it is text the reader reads; the answer is stone, so it reads as the
   sage answering rather than more of the same card; the grades are buttons.
   Nothing below may set a background, a border or a radius — the sprites own
   all three. */
.study {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	scroll-behavior: smooth;
	padding: var(--sp-5) var(--sp-4) var(--sp-6);
}
.main.is-studying > .transcript,
.main.is-studying > .composer-dock { display: none; }

.study-head {
	max-width: var(--measure);
	margin: 0 auto var(--sp-4);
	display: flex;
	align-items: baseline;
	gap: var(--sp-3);
	flex-wrap: wrap;
}
.study-title {
	margin: 0;
	font-family: var(--font-prose);
	font-variant: small-caps;
	letter-spacing: 0.04em;
	font-size: var(--fs-lg);
	font-weight: 600;
	color: var(--gold);
}
.study-meta {
	margin: 0;
	margin-left: auto;
	font-size: var(--fs-xs);
	opacity: 0.55;
	letter-spacing: 0.02em;
}
.study-head .icon-btn { flex: none; align-self: center; }
.study-body {
	max-width: var(--measure);
	margin: 0 auto;
	display: flex;
	flex-direction: column;
	gap: var(--sp-4);
}
.study-status { opacity: 0.55; font-size: var(--fs-sm); font-style: italic; }
.study-status.warn { opacity: 0.9; color: var(--ember); font-style: normal; }
.study-progress {
	font-family: var(--font-pixel);
	font-size: var(--fs-xs);
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--gold-dim);
}

.study-card {
	padding: var(--sp-4) var(--sp-5);
	color: var(--ink);
}
.study-card-label {
	margin: 0 0 var(--sp-2);
	font-family: var(--font-prose);
	font-variant: small-caps;
	letter-spacing: 0.08em;
	font-size: var(--fs-sm);
	color: var(--ink-soft);
}
/* Larger than the reading measure's body text: this is the one line the reader
   is being asked to answer, so it carries the surface. */
.study-prompt {
	font-family: var(--font-prose);
	font-size: 1.25rem;
	line-height: 1.45;
}
.study-reveal { margin-top: var(--sp-4); }

.study-answer {
	padding: var(--sp-3) var(--sp-4);
	color: var(--parchment);
}
.study-back-text {
	font-family: var(--font-prose);
	white-space: pre-wrap;
	overflow-wrap: anywhere;
	line-height: 1.6;
}
.study-source {
	margin: var(--sp-2) 0 0;
	font-size: var(--fs-xs);
	opacity: 0.5;
}
.study-grades {
	display: grid;
	grid-template-columns: repeat(4, 1fr);
	gap: var(--sp-2);
	margin-top: var(--sp-4);
}
.study-grade {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 0.15rem;
	padding: 0.4rem var(--sp-2);
	color: #1a1208; /* ink on gold — the frame behind this is the gold */
	cursor: pointer;
	filter: brightness(0.94);
	transition: filter 0.15s ease, opacity 0.15s ease;
}
.study-grade:hover:not(:disabled) { filter: brightness(1.06); }
.study-grade:disabled { opacity: 0.35; cursor: default; }
.study-grade-label { font-weight: 600; font-size: var(--fs-sm); }
.study-grade-hint { font-size: var(--fs-xs); opacity: 0.6; }
/* Only the failure grade is marked out, in the app's own warning colour. The
   corpus accent would read as "this is Magic", not "this one is a miss". */
.study-grade-again .study-grade-label { color: var(--ember-deep); }

.study-empty {
	max-width: 36rem;
	margin: clamp(2rem, 12vh, 6rem) auto 0;
	text-align: center;
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-2);
	font-family: var(--font-prose);
}
.study-empty .gi { color: var(--gold); opacity: 0.7; }
.study-empty-title {
	margin: var(--sp-2) 0 0;
	font-variant: small-caps;
	letter-spacing: 0.04em;
	font-size: var(--fs-lg);
}
.study-empty-sub { opacity: 0.6; font-size: var(--fs-sm); max-width: 30rem; }

/* ---------- Reference drawer ---------- */
/* The drawer is the right-hand page of the open book: spine down its inner
   edge, page-stack along the bottom. Framed by .f-page in pixel.css. */
.drawer {
	display: flex;
	flex-direction: column;
	min-width: 0;
	overflow: hidden;
	color: var(--ink);
}
.drawer-head {
	flex: none;
	display: flex;
	align-items: center;
	gap: var(--sp-2);
	padding: var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-3);
	border-bottom: 1px solid var(--parchment-line);
}
.drawer-title {
	flex: 1;
	margin: 0;
	font-family: var(--font-display);
	font-weight: 600;
	letter-spacing: 0.08em;
	text-transform: uppercase;
	font-size: var(--fs-sm);
	color: var(--ink);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}
.drawer .icon-btn { color: var(--ink-soft); opacity: 0.8; }
.drawer .icon-btn:hover { color: var(--ember-deep); background: rgba(73, 51, 51, 0.1); }
.drawer-body {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	padding: var(--sp-3);
	display: flex;
	flex-direction: column;
	gap: var(--sp-2);
}

/* Rules and cards are entries on the page, not cards floating above it — the
   drawer is already parchment, so a parchment panel inside it would be flat.
   They separate with a rule and a hanging accent bar instead. */
.rule-card {
	padding: var(--sp-2) 0 var(--sp-2) var(--sp-3);
	border-left: 3px solid var(--accent);
	color: var(--ink);
	font-family: var(--font-prose);
	font-size: var(--fs-lg);
	line-height: 1.55;
}
.rule-card + .rule-card { border-top: 1px dashed var(--parchment-line); }
.rule-card .rule-num {
	font-family: var(--font-pixel);
	font-size: 0.78rem;
	letter-spacing: 0.04em;
	color: var(--accent-deep);
}
.rule-card .rule-name { font-weight: 700; margin-left: var(--sp-2); }
.rule-card .rule-text { margin-top: var(--sp-1); white-space: pre-wrap; }
.rule-card.is-sub {
	border-left-color: var(--parchment-line);
	margin-left: var(--sp-3);
	font-size: var(--fs-md);
}
.drawer-note {
	font-family: var(--font-prose);
	font-size: var(--fs-sm);
	color: var(--ink-soft);
	font-style: italic;
	padding: var(--sp-3);
}
mark { background: var(--gold-bright); color: #1a1208; border-radius: 2px; padding: 0 1px; }

.card-view {
	padding: var(--sp-2) 0;
	color: var(--ink);
	font-family: var(--font-prose);
	font-size: var(--fs-lg);
}
.card-view img {
	display: block;
	width: 100%;
	max-width: 240px;
	margin: 0 auto var(--sp-3);
	border-radius: 9px;
	box-shadow: var(--shadow-2);
}
.card-view .c-name { font-weight: 700; font-size: var(--fs-lg); }
.card-view .c-cost { float: right; font-variant: small-caps; opacity: 0.8; }
.card-view .c-type { font-style: italic; opacity: 0.85; margin-top: var(--sp-1); }
.card-view .c-pt { font-style: normal; font-weight: 700; margin-left: var(--sp-2); }
.card-view .c-oracle { margin-top: var(--sp-2); white-space: pre-wrap; }
.card-view .c-face + .c-face { margin-top: var(--sp-2); padding-top: var(--sp-2); border-top: 1px dashed var(--parchment-line); }
.card-view .c-foot {
	margin-top: var(--sp-3);
	display: flex;
	justify-content: space-between;
	font-family: var(--font-ui);
	font-size: var(--fs-xs);
	opacity: 0.65;
}
.card-view .c-foot a { color: var(--accent-deep); }

/* ---------- Command palette ---------- */
.palette-layer {
	position: fixed;
	inset: 0;
	z-index: 60;
	display: flex;
	justify-content: center;
	align-items: flex-start;
	padding: clamp(1rem, 10vh, 7rem) var(--sp-4) var(--sp-4);
}
.palette-scrim {
	position: absolute;
	inset: 0;
	background: rgba(10, 7, 3, 0.72);
	backdrop-filter: blur(3px);
}
/* Framed by .f-stone in pixel.css. */
.palette-box {
	position: relative;
	width: 100%;
	max-width: 620px;
	max-height: 70vh;
	display: flex;
	flex-direction: column;
	overflow: hidden;
	box-shadow: var(--shadow-3);
	animation: rise 0.16s ease;
}
@keyframes rise { from { opacity: 0; transform: translateY(-6px); } }
.palette-inputwrap {
	flex: none;
	display: flex;
	align-items: center;
	gap: var(--sp-3);
	padding: var(--sp-3) var(--sp-4);
	border-bottom: 1px solid var(--stone-line);
}
.palette-icon { opacity: 0.5; }
.palette-input {
	flex: 1;
	min-width: 0;
	border: none;
	background: none;
	font-size: var(--fs-lg);
	font-family: var(--font-prose);
}
.palette-input:focus { outline: none; }
.palette-results {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
	padding: var(--sp-2);
}
.palette-group {
	padding: var(--sp-2) var(--sp-3) var(--sp-1);
	font-family: var(--font-pixel);
	font-size: 0.7rem;
	text-transform: uppercase;
	letter-spacing: 0.12em;
	color: var(--gold-dim);
}
.palette-item {
	display: flex;
	align-items: baseline;
	gap: var(--sp-3);
	width: 100%;
	padding: 0.45rem var(--sp-3);
	border: none;
	border-radius: var(--r-sm);
	background: none;
	color: inherit;
	text-align: left;
	cursor: pointer;
}
.palette-item:hover, .palette-item.is-active { background: rgba(255, 255, 255, 0.08); }
.palette-item .p-key {
	flex: none;
	font-family: var(--font-pixel);
	font-size: 0.76rem;
	color: var(--gold);
	letter-spacing: 0.03em;
	min-width: 3.6rem;
}
.palette-item .p-text {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: var(--fs-sm);
	opacity: 0.85;
}
.palette-empty {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--sp-2);
	padding: var(--sp-6) var(--sp-5);
	text-align: center;
	font-family: var(--font-prose);
	opacity: 0.4;
	font-style: italic;
}
.palette-foot {
	flex: none;
	display: flex;
	gap: var(--sp-4);
	padding: var(--sp-2) var(--sp-4);
	border-top: 1px solid var(--stone-line);
	font-size: var(--fs-xs);
	opacity: 0.5;
}
.palette-foot span:last-child { margin-left: auto; }

/* ---------- Gate (login / first-run setup) ---------- */
/* The one screen a signed-out reader ever sees, and the only place the book is
   shown shut: the cover sprite frames the card, a parchment page sits inside
   it, and the form is written on the page. Two nested nine-slices, so it
   reads as an object rather than a login box with a texture on it. */
.gate-body { overflow: auto; }
.gate {
	min-height: 100%;
	display: grid;
	place-items: center;
	padding: var(--sp-5) var(--sp-4);
}
/* Framed by .f-cover in pixel.css. */
.gate-card {
	width: 100%;
	max-width: 25rem;
	padding: var(--sp-2);
	color: var(--ink);
	box-shadow: var(--shadow-3);
	text-align: center;
	animation: rise 0.18s ease;
}
/* Framed by .f-parchment in pixel.css. */
.gate-page { padding: var(--sp-5) var(--sp-4) var(--sp-4); }
.gate-sigil {
	line-height: 0;
	filter: drop-shadow(0 3px 8px rgba(73, 51, 51, 0.4));
}
.gate-title {
	margin: var(--sp-3) 0 var(--sp-1);
	font-family: var(--font-display);
	letter-spacing: 0.16em;
	text-indent: 0.16em;
	text-transform: uppercase;
	font-size: 1.5rem;
	font-weight: 700;
	color: var(--outline);
}
.gate-sub {
	margin: 0 0 var(--sp-5);
	font-family: var(--font-prose);
	font-style: italic;
	color: var(--ink-soft);
}

.gate-form {
	display: flex;
	flex-direction: column;
	gap: var(--sp-3);
	text-align: left;
}
.gate-field { display: block; }
.gate-label {
	display: block;
	margin-bottom: var(--sp-1);
	font-family: var(--font-pixel);
	font-size: 0.7rem;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--ink-soft);
}
.gate-field input {
	width: 100%;
	padding: 0.4rem 0.6rem;
	border: 2px solid var(--parchment-line);
	border-radius: 0;
	background: rgba(255, 255, 255, 0.32);
	color: var(--ink);
	font-family: var(--font-prose);
	font-size: var(--fs-lg);
	transition: border-color 0.15s ease, box-shadow 0.15s ease;
}
.gate-field input:focus {
	outline: none;
	border-color: var(--ember-deep);
	box-shadow: 0 0 0 2px rgba(229, 103, 60, 0.25);
}

.gate-error {
	margin: 0;
	padding: var(--sp-2) var(--sp-3);
	border-left: 3px solid var(--ember-deep);
	background: rgba(229, 103, 60, 0.14);
	font-family: var(--font-prose);
	font-style: italic;
	font-size: var(--fs-sm);
}

/* Framed by .f-button in pixel.css. */
.gate-submit {
	margin-top: var(--sp-2);
	padding: 0.35rem var(--sp-4);
	color: #1a1208;
	font-family: var(--font-display);
	font-weight: 700;
	letter-spacing: 0.14em;
	text-indent: 0.14em;
	text-transform: uppercase;
	font-size: var(--fs-md);
	cursor: pointer;
	transition: filter 0.15s ease, opacity 0.15s ease;
}
.gate-submit:hover:not(:disabled) { filter: brightness(1.08); }
.gate-submit:disabled { opacity: 0.5; cursor: default; }

.gate-foot { margin: var(--sp-4) 0 0; }
.gate-link {
	border: none;
	background: none;
	padding: 0;
	color: var(--ink-soft);
	font-size: var(--fs-sm);
	text-decoration: underline;
	text-underline-offset: 3px;
	cursor: pointer;
}
.gate-link:hover { color: var(--ink); }

/* ---------- Settings popup ---------- */
/* Framed by .f-stone in pixel.css. Anchored to the rail foot rather than
   centred, because it belongs to the button that opened it. */
.settings-popup {
	position: absolute;
	left: var(--sp-2);
	right: var(--sp-2);
	bottom: calc(100% - var(--sp-2));
	z-index: 20;
	max-height: 70vh;
	overflow-y: auto;
	padding: var(--sp-2);
	box-shadow: var(--shadow-3);
	animation: rise 0.14s ease;
}
.set-title {
	margin: 0 0 var(--sp-2);
	font-family: var(--font-display);
	font-size: var(--fs-sm);
	font-weight: 700;
	letter-spacing: 0.12em;
	text-transform: uppercase;
	color: var(--gold-bright);
}
.set-group + .set-group { margin-top: var(--sp-3); }
.set-label {
	margin: 0 0 var(--sp-1);
	font-family: var(--font-pixel);
	font-size: 0.68rem;
	text-transform: uppercase;
	letter-spacing: 0.1em;
	color: var(--gold-dim);
}
.set-opt,
.set-toggle {
	display: flex;
	align-items: baseline;
	gap: var(--sp-2);
	width: 100%;
	padding: 0.3rem var(--sp-2);
	border: 1px solid transparent;
	border-radius: var(--r-sm);
	background: none;
	color: inherit;
	text-align: left;
	cursor: pointer;
	transition: background 0.12s ease, border-color 0.12s ease;
}
.set-opt:hover,
.set-toggle:hover { background: rgba(255, 255, 255, 0.06); }
.set-opt.is-active {
	border-color: var(--gold-dim);
	background: rgba(255, 208, 113, 0.12);
}
.set-opt-name { font-size: var(--fs-sm); }
.set-opt.is-active .set-opt-name { color: var(--gold-bright); }
.set-opt-note {
	margin-left: auto;
	font-size: var(--fs-xs);
	opacity: 0.4;
	white-space: nowrap;
}
.set-toggle .set-switch {
	margin-left: auto;
	width: 26px;
	height: 12px;
	flex: none;
	align-self: center;
	border: 1px solid var(--stone-line);
	background: var(--stone-900);
	position: relative;
}
.set-toggle .set-switch::after {
	content: "";
	position: absolute;
	inset: 2px auto 2px 2px;
	width: 8px;
	background: var(--stone-500);
	transition: transform 0.12s steps(2), background 0.12s ease;
}
.set-toggle.is-on .set-switch { border-color: var(--gold-dim); }
.set-toggle.is-on .set-switch::after {
	transform: translateX(12px);
	background: var(--gold-bright);
}
.set-credits { border-top: 1px solid var(--stone-line); padding-top: var(--sp-2); }
.set-credit {
	display: flex;
	gap: var(--sp-2);
	margin: 0 0 0.15rem;
	padding: 0 var(--sp-2);
	font-size: var(--fs-xs);
	opacity: 0.55;
}
.set-credit-what { flex: none; min-width: 5.5rem; color: var(--gold-dim); }
.set-credit a { color: inherit; text-decoration: none; }
.set-credit a:hover { color: var(--gold-bright); text-decoration: underline; }

/* ---------- Invitations (admin section of the settings popup) ---------- */
.set-hint {
	margin: var(--sp-1) 0 0;
	padding: 0 var(--sp-2);
	font-size: var(--fs-xs);
	opacity: 0.5;
}
.invite-new-row { margin: 0 0 var(--sp-1); }
.invite-new {
	justify-content: center;
	border-color: var(--gold-dim);
	background: rgba(255, 208, 113, 0.12);
	color: var(--gold-bright);
	font-size: var(--fs-sm);
}
.invite-new:hover:not(:disabled) { background: rgba(255, 208, 113, 0.2); }
.invite-new:disabled { opacity: 0.5; cursor: default; }
.invite-row {
	display: flex;
	flex-wrap: wrap;
	align-items: center;
	gap: var(--sp-1);
	margin: 0 0 var(--sp-1);
	padding: var(--sp-1) var(--sp-2);
	border: 1px solid var(--stone-line);
	border-radius: var(--r-sm);
}
.invite-head {
	display: flex;
	gap: var(--sp-2);
	align-items: baseline;
	flex: 1 1 100%;
}
.invite-status {
	flex: none;
	padding: 0 0.35rem;
	border: 1px solid var(--stone-line);
	border-radius: var(--r-sm);
	font-size: var(--fs-xs);
	text-transform: uppercase;
	letter-spacing: 0.08em;
	color: var(--gold-dim);
}
.invite-status.is-used,
.invite-status.is-expired { color: var(--ink-soft); opacity: 0.6; }
.invite-note { font-size: var(--fs-sm); }
.invite-meta {
	margin: 0;
	flex: 1 1 auto;
	font-size: var(--fs-xs);
	opacity: 0.55;
}
.invite-link {
	display: flex;
	gap: var(--sp-1);
	flex: 1 1 100%;
	align-items: center;
}
.invite-link.fresh { animation: rise 0.14s ease; }
.invite-url {
	flex: 1 1 auto;
	min-width: 0;
	padding: 0.2rem var(--sp-1);
	border: 1px solid var(--stone-line);
	border-radius: var(--r-sm);
	background: var(--stone-900);
	color: var(--ink);
	font-size: var(--fs-xs);
}
.invite-copy {
	flex: none;
	padding: 0.2rem var(--sp-2);
	border: 1px solid var(--gold-dim);
	border-radius: var(--r-sm);
	background: none;
	color: var(--gold-bright);
	font-size: var(--fs-xs);
	cursor: pointer;
}
.invite-copy:hover { background: rgba(255, 208, 113, 0.12); }
.invite-once {
	margin: 0;
	flex: 1 1 100%;
	font-size: var(--fs-xs);
	color: var(--gold-bright);
	opacity: 0.8;
}
.invite-revoke {
	flex: none;
	border: none;
	background: none;
	padding: 0.2rem 0;
	color: var(--ink-soft);
	font-size: var(--fs-xs);
	text-decoration: underline;
	text-underline-offset: 2px;
	cursor: pointer;
}
.invite-revoke:hover:not(:disabled) { color: var(--ink); }
.invite-revoke:disabled { opacity: 0.5; cursor: default; }

/* ---------- Magic symbols ---------- */
/* Mana ships its own sizing; these only settle it into our type. Pips inside
   prose ride a touch high so they sit on the baseline of a serif face. */
.ms { vertical-align: -0.08em; }
.prose .ms,
.rule-card .ms,
.c-oracle .ms { font-size: 0.85em; }
.c-cost .ms { font-size: 1.05em; margin-left: 0.1em; }
.ss { font-size: 1.15em; vertical-align: -0.12em; }

/* ---------- Opt-in pixel pointer ---------- */
.pixel-cursor,
.pixel-cursor * { cursor: url("/static/assets/ui/cursor.png") 2 2, auto !important; }
.pixel-cursor a,
.pixel-cursor button,
.pixel-cursor [role="button"],
.pixel-cursor .palette-item,
.pixel-cursor .chip,
.pixel-cursor .suggestion,
.pixel-cursor .rule-ref {
	cursor: url("/static/assets/ui/cursor-press.png") 2 2, pointer !important;
}

/* ---------- Responsive ---------- */
@media (max-width: 900px) {
	/* Rail and drawer are overlays on narrow screens, so the main column
	   fills the viewport in every app state. Forcing a single grid track
	   for all state combos prevents the drawer-open state (which on mobile
	   is also rail-hidden) from squishing chat to a sliver on the left. */
	html, body { height: 100dvh; }
	body { overscroll-behavior: none; }
	.app,
	.app.rail-hidden,
	.app.drawer-open,
	.app.rail-hidden.drawer-open {
		grid-template-columns: minmax(0, 1fr);
	}

	.rail {
		position: fixed;
		z-index: 40;
		top: 0;
		bottom: 0;
		left: 0;
		width: min(var(--rail-w), 88vw);
		transform: translateX(-100%);
		transition: transform 0.22s ease;
		box-shadow: var(--shadow-3);
	}
	.app:not(.rail-hidden) .rail { transform: none; }
	.app:not(.rail-hidden) .rail-scrim {
		display: block;
		position: fixed;
		inset: 0;
		z-index: 30;
		background: rgba(10, 7, 3, 0.6);
	}
	.rail-open { display: block; }
	.app.rail-hidden .rail-open { display: block; }

	.drawer {
		position: fixed;
		z-index: 45;
		top: 0;
		right: 0;
		bottom: 0;
		width: min(var(--drawer-w), 94vw);
		box-shadow: var(--shadow-3);
	}

	.transcript { padding: var(--sp-4) var(--sp-3) var(--sp-3); }
	.composer-dock { padding: 0 var(--sp-3) calc(var(--sp-3) + env(safe-area-inset-bottom)); }
	.msg-user .bubble { max-width: 92%; }
	.resolver-grid { grid-template-columns: 1fr; }
	.mode-toggle .mode-opt { padding: 0.2rem 0.4rem; }

	/* The chip and the mode toggle neither wrap nor shrink, so a long title
	   next to them can push the row past the viewport. The title already
	   ellipsises; this stops anything that cannot from spilling out. */
	.topbar { overflow: hidden; }

	/* keep chrome off the notch and home indicator */
	.topbar {
		gap: var(--sp-2);
		padding: var(--sp-2) var(--sp-3);
		padding-top: calc(var(--sp-2) + env(safe-area-inset-top));
	}
	.rail-head { padding-top: calc(var(--sp-3) + env(safe-area-inset-top)); }
	.rail-foot { padding-bottom: calc(var(--sp-3) + env(safe-area-inset-bottom)); }
	.drawer-head { padding-top: calc(var(--sp-3) + env(safe-area-inset-top)); }
	.drawer-body { padding-bottom: calc(var(--sp-3) + env(safe-area-inset-bottom)); }

	/* thumb-friendly tap targets in the chrome */
	.icon-btn { padding: 0.5rem 0.65rem; }
	.conv-title { flex: 1 1 auto; min-width: 0; }
	.welcome-title { font-size: clamp(1.5rem, 8vw, 2.2rem); }

	.study { padding: var(--sp-4) var(--sp-3) var(--sp-5); }
	.study-grades { grid-template-columns: repeat(2, 1fr); }
	.study-meta { margin-left: 0; flex-basis: 100%; }

	.gate {
		padding:
			calc(var(--sp-5) + env(safe-area-inset-top)) var(--sp-4)
			calc(var(--sp-5) + env(safe-area-inset-bottom));
	}
}

/* On a phone the topbar cannot hold labels as well as the title. Drop the
   labels, not the controls: the corpus is already named in the rail and in the
   welcome line, and the two mode icons are distinct enough on their own.
   (font-size: 0 hides the label text; the icons carry their own sizing.) */
@media (max-width: 560px) {
	.corpus-chip { padding: 0.15rem 0.4rem; font-size: 0; gap: 0; }
	.corpus-chip .gi { width: 1rem; height: 1rem; }
	.mode-opt { font-size: 0; padding: 0.25rem 0.45rem; gap: 0; }
	.mode-opt .gi { width: 1rem; height: 1rem; }

	/* The frames scale down with everything else, so the page keeps its
	   proportions instead of becoming all border. */
	.gate-card { border-width: 20px; }
	.msg-sage .bubble { border-width: 8px; padding: var(--sp-1) var(--sp-2); }
	/* The frame stays at its clean 2x — only the type and the padding inside
	   it give ground, so the parchment corners survive the narrow layout. */
	.study-card { padding: var(--sp-3) var(--sp-4); }
	.study-prompt { font-size: 1.1rem; }
}

@media (prefers-reduced-motion: reduce) {
	*, *::before, *::after {
		animation-duration: 0.01ms !important;
		animation-iteration-count: 1 !important;
		transition-duration: 0.01ms !important;
	}
	.transcript,
	.study { scroll-behavior: auto; }
}
