/* ═══════════════════════════════════════════════════════════════════════
   Phosphor Refined app shell — full-height sidebar + content column.
   Mirrors prototype app.jsx: position:absolute; inset:0; display:flex.
   ═══════════════════════════════════════════════════════════════════════ */
.phosphor-shell {
	position: absolute;
	inset: 0;
	display: flex;
	overflow: hidden;
	background: var(--bg);
	background-image: var(--mud-palette-background-gradient);
}

/* Content column: topbar + scrollable main + footer/terminal */
.phosphor-content-col {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	position: relative;
}

/* ── Topbar: glass-morphism, spans content column only ── */
.phosphor-topbar {
	height: var(--topbar-h);
	flex-shrink: 0;
	display: none; /* touch chrome only (README §10 Q1: no desktop top bar) */
	align-items: center;
	gap: 0.625rem;
	padding: 0 1rem;
	border-bottom: 1px solid var(--border-soft);
	background: color-mix(in srgb, var(--surface-3) 80%, transparent);
	backdrop-filter: blur(8px);
	-webkit-backdrop-filter: blur(8px);
	position: relative;
	z-index: 5;
}

/* ── Topbar icon buttons (menu, terminal, close) ── */
.phosphor-icon-btn {
	width: 38px;
	height: 38px;
	display: grid;
	place-items: center;
	border-radius: var(--radius);
	background: transparent;
	border: none;
	cursor: pointer;
	color: var(--text-dim);
	transition: background 0.14s, color 0.14s;
	flex-shrink: 0;
	padding: 0;
}
.phosphor-icon-btn:hover {
	background: var(--surface-2);
	color: var(--text);
}
.phosphor-icon-btn--active,
.phosphor-icon-btn--active:hover {
	color: var(--accent);
	background: rgba(var(--glow), 0.12);
}

/* ── The global TopBar zone (Q1): a slim strip above main, rendered only when it has widgets ── */
.phosphor-topzone {
	flex-shrink: 0;
	display: flex;
	align-items: center;
	gap: 0.5rem;
	min-height: 44px;
	padding: 0.375rem 1rem;
	border-bottom: 1px solid var(--border-soft);
	background: var(--surface-3);
}

/* ── Scrollable main content ── */
.phosphor-main {
	flex: 1;
	min-height: 0;
	overflow-y: auto;
}
/* When the command-terminal drawer is open, reserve its height so content isn't
   hidden beneath it. The drawer is a fixed 300px on desktop and 70svh on mobile
   (see the mobile block), and this offset tracks both. */
.phosphor-main--terminal {
	padding-bottom: 18.75rem;
}

.phosphor-page {
	container: page / inline-size;
	min-height: 100%;
}

/* descendants, not children: a section page sits inside SectionShell's .kit-section-body */
.phosphor-page:has(.full-bleed) {
	max-width: none;
}

.phosphor-page:has(.full-height) {
	height: 100%;
}

@media (min-width: 1601px) {
	.phosphor-page {
		max-width: var(--content-max);
		margin-inline: auto;
	}
}

/* ── Rail (D1 §3): 72px, one 44×44 icon per section, radius 14; the current one filled
   --surface-2 with an accent icon. Desktop only: touch chrome keeps the drawer and tab bar. ── */
.phosphor-rail {
	flex-shrink: 0;
	width: var(--rail-w);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: 6px;
	padding: 14px 0;
	box-sizing: border-box;
	background: var(--rail-bg);
	border-right: 1px solid var(--border-soft);
	overflow-y: auto;
	scrollbar-width: none;
}

.phosphor-rail-logo {
	width: 44px;
	height: 44px;
	flex-shrink: 0;
	display: grid;
	place-items: center;
	border-radius: 14px;
	border: 1px solid var(--border);
	background: var(--surface);
}

.phosphor-rail-sep {
	width: 28px;
	height: 1px;
	margin: 6px 0;
	flex-shrink: 0;
	background: var(--border);
}

.phosphor-rail-item {
	position: relative;
	width: 44px;
	height: 44px;
	flex-shrink: 0;
	display: grid;
	place-items: center;
	padding: 0;
	border: 0;
	border-radius: 14px;
	background: transparent;
	color: var(--text-dim);
	cursor: pointer;
	text-decoration: none;
	transition: background var(--motion-pop), color var(--motion-pop);
}

.phosphor-rail-item:hover {
	background: var(--surface-2);
	color: var(--text);
}

.phosphor-rail-item:focus-visible {
	outline: 2px solid var(--accent);
	outline-offset: 2px;
}

.phosphor-rail-item--on,
.phosphor-rail-item--on:hover {
	background: var(--surface-2);
	color: var(--accent);
}

.phosphor-rail-dot {
	position: absolute;
	top: 9px;
	right: 9px;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--text-dim);
}

.phosphor-rail-dot--unread {
	background: var(--accent);
	box-shadow: 0 0 6px rgba(var(--glow), 0.7);
}

.phosphor-rail-spacer {
	flex: 1 1 auto;
	min-height: 12px;
}

.phosphor-rail-lang {
	width: 44px;
	height: 44px;
	display: grid;
	place-items: center;
	color: var(--text-dim);
}

/* the account in the rail is the avatar alone */
.phosphor-profile-wrap--compact {
	padding: 4px 0 0;
	border-top: 0;
}

.phosphor-profile-wrap--compact .phosphor-profile-card {
	width: 44px;
	height: 44px;
	padding: 0;
	justify-content: center;
	background: transparent;
	border: 0;
	border-radius: 14px;
}

.phosphor-profile-wrap--compact .phosphor-profile-card:hover,
.phosphor-profile-wrap--compact .phosphor-profile-card:focus-visible {
	background: var(--surface-2);
}

.phosphor-profile-wrap--compact .phosphor-avatar-wrap,
.phosphor-profile-wrap--compact .phosphor-avatar {
	width: 36px;
	height: 36px;
	border-radius: 50%;
}

/* ── Page-sidebar slot (D1 §3): a section's SectionShell fills it; empty, the column is gone ── */
.phosphor-pagebar {
	flex-shrink: 0;
	width: var(--side-w);
	min-height: 0;
	overflow-y: auto;
	overscroll-behavior: contain;
	background: var(--surface-3);
	border-right: 1px solid var(--border-soft);
	transition: width var(--motion-slide);
}

.phosphor-pagebar:not(:has(.kit-pagebar)) {
	display: none;
}

.phosphor-pagebar:has(.kit-pagebar--collapsed) {
	width: 62px;
}

/* ── Widget aside columns (left / right sidebar zones) ── */
.phosphor-widget-aside {
	flex-shrink: 0;
	border-right: 1px solid var(--border-soft);
	background: var(--surface);
	overflow-y: auto;
}
.phosphor-widget-aside--right {
	border-right: none;
	border-left: 1px solid var(--border-soft);
}

/* ── Footer widget zone ── */
.phosphor-footer {
	flex-shrink: 0;
	border-top: 1px solid var(--border-soft);
	background: var(--surface);
	padding: 0.5rem 1rem;
}

/* ── Terminal drawer: slides up over the bottom of the content column ── */
.phosphor-terminal {
	position: absolute;
	left: 0;
	right: 0;
	bottom: 0;
	height: 300px;
	display: flex;
	flex-direction: column;
	background: var(--surface);
	border-top: 1px solid var(--border);
	box-shadow: 0 -10px 40px rgba(0,0,0,0.4);
	z-index: 10;
}
.phosphor-terminal-header {
	display: flex;
	align-items: center;
	padding: 0.25rem 0.75rem;
	background: var(--surface-3);
	border-bottom: 1px solid var(--border);
	flex-shrink: 0;
}

/* ═══════════════════════════════════════════════════════════════════════
   Phosphor Refined sidebar (NavMenu) — full-height, logo · groups · profile.
   Mirrors prototype components.jsx Sidebar.
   ═══════════════════════════════════════════════════════════════════════ */
.phosphor-sidebar {
	width: 232px;
	flex-shrink: 0;
	height: 100%;
	display: none; /* touch chrome only: a desktop has the rail */
	flex-direction: column;
	overflow: hidden;
	background: var(--surface-3);
	border-right: 1px solid var(--border-soft);
}
.phosphor-sidebar--collapsed {
	width: 62px;
}

/* ── Logo / brand ── */
.phosphor-logo {
	height: 60px;
	flex-shrink: 0;
	display: flex;
	align-items: center;
	gap: 0.6875rem;
	padding: 0 1.125rem;
	cursor: pointer;
	text-decoration: none;
}
.phosphor-sidebar--collapsed .phosphor-logo {
	padding: 0;
	justify-content: center;
}
.phosphor-logo-mark {
	display: block;
	flex-shrink: 0;
	filter: drop-shadow(0 0 6px rgba(var(--glow), 0.35));
}
.phosphor-brand {
	font-family: var(--font-display);
	font-weight: 700;
	font-size: 0.9375rem;
	letter-spacing: 0.02em;
	color: var(--text);
	white-space: nowrap;
}
.phosphor-brand-tag {
	font-family: var(--font-mono);
	font-size: 0.65625rem;
	color: var(--text-faint);
	letter-spacing: 0.08em;
	white-space: nowrap;
}

/* ── Nav scroll area + groups ── */
.phosphor-nav {
	flex: 1;
	overflow-y: auto;
	padding: 0.375rem 0.625rem;
}
.nav-group {
	margin-bottom: 0.875rem;
}
/* A section that turned out to have no links is not a section. Every child of the Build group is
   permission- or data-gated, so an anonymous visitor and a registered account with no characters
   both saw a "BUILD" heading with nothing under it; Manage collapses the same way once its
   admin-only entries are gated out. Emptiness cannot be known statically — the children are
   <AuthorizeView> blocks and data-driven <ApplicationNavLinks>, and both render zero elements
   rather than an empty container — so this keys on the rendered result instead. Every nav entry,
   hardcoded or data-driven, is a .phosphor-nav-link, which is what makes the test reliable. */
.nav-group:not(:has(.phosphor-nav-link)) {
	display: none;
}
.nav-group-label {
	font-family: var(--font-mono);
	font-size: 0.625rem;
	letter-spacing: 0.16em;
	text-transform: uppercase;
	color: var(--text-faint);
	padding: 0.25rem 0.625rem 0.4375rem;
	pointer-events: none;
	user-select: none;
}
.phosphor-sidebar--collapsed .nav-group-label {
	display: none;
}

/* ── Nav links (shared with ApplicationNavLinks) ── */
.phosphor-nav-link {
	display: flex;
	align-items: center;
	gap: 0.6875rem;
	padding: 0.5625rem 0.625rem;
	margin-bottom: 0.125rem;
	border-radius: var(--radius);
	color: var(--text-dim);
	font-family: var(--font-ui);
	font-size: 0.84375rem;
	font-weight: 500;
	letter-spacing: var(--nav-letterspacing);
	text-decoration: none;
	cursor: pointer;
	position: relative;
	white-space: nowrap;
	transition: background 0.14s ease, color 0.14s ease;
}

/* Play-session status dot: present while the play terminal is active, brighter/pulsing when there is
   unread activity (output arrived while not viewing /play). */
.phosphor-nav-dot {
	position: absolute;
	top: 8px;
	right: 9px;
	width: 7px;
	height: 7px;
	border-radius: 50%;
	background: var(--accent);
	box-shadow: 0 0 4px rgba(var(--glow), 0.45);
}
.phosphor-nav-dot--unread {
	box-shadow: 0 0 9px 2px rgba(var(--glow), 0.95);
	animation: phosphor-nav-pulse 1.4s ease-in-out infinite;
}
@keyframes phosphor-nav-pulse {
	0%, 100% { opacity: 1; }
	50% { opacity: 0.5; }
}

.phosphor-nav-link:hover {
	background: var(--surface-2);
	color: var(--text);
}
.phosphor-nav-link.active {
	background: rgba(var(--glow), 0.10);
	color: var(--accent);
	font-weight: 600;
}
.phosphor-nav-link.active::before {
	content: '';
	position: absolute;
	left: 0;
	top: 8px;
	bottom: 8px;
	width: 3px;
	border-radius: 2px;
	background: var(--accent);
	box-shadow: 0 0 8px rgba(var(--glow), 0.7);
}
.phosphor-nav-icon {
	font-size: 1.125rem;
	width: 18px;
	height: 18px;
	flex-shrink: 0;
	color: inherit;
}
.phosphor-nav-text {
	flex: 1;
	text-align: left;
	overflow: hidden;
	text-overflow: ellipsis;
}
.phosphor-sidebar--collapsed .phosphor-nav-link {
	justify-content: center;
	padding: 0.625rem 0;
}

/* ── Bottom profile card ── */
.phosphor-profile-wrap {
	padding: 0.625rem;
	border-top: 1px solid var(--border-soft);
	flex-shrink: 0;
	position: relative;
}
.phosphor-profile-card {
	display: flex;
	align-items: center;
	gap: 0.625rem;
	width: 100%;
	padding: 0.5rem 0.5625rem;
	background: var(--surface-2);
	border: 1px solid var(--border-soft);
	border-radius: var(--radius);
	cursor: pointer;
	text-decoration: none;
	transition: border-color 0.14s ease;
}
.phosphor-profile-card:hover {
	border-color: rgba(var(--glow), 0.4);
}
.phosphor-sidebar--collapsed .phosphor-profile-card {
	justify-content: center;
	padding: 0.5rem 0;
}
.phosphor-avatar-wrap {
	position: relative;
	width: 28px;
	height: 28px;
	flex-shrink: 0;
}
.phosphor-avatar {
	width: 28px;
	height: 28px;
	border-radius: var(--radius);
	display: grid;
	place-items: center;
	font-size: 0.6875rem;
	font-weight: 600;
	font-family: var(--font-ui);
	letter-spacing: 0.02em;
	border: 1px solid rgba(255, 255, 255, 0.08);
}
.phosphor-avatar-dot {
	position: absolute;
	right: -2px;
	bottom: -2px;
	width: 10px;
	height: 10px;
	border-radius: 99px;
	border: 2px solid var(--surface-2);
}
.phosphor-avatar-dot--online {
	background: var(--accent);
	box-shadow: 0 0 6px rgba(var(--glow), 0.7);
}
.phosphor-avatar-dot--offline {
	background: #555;
}
.phosphor-profile-name {
	font-family: var(--font-ui);
	font-size: 0.78125rem;
	font-weight: 600;
	color: var(--text);
	white-space: nowrap;
	overflow: hidden;
	text-overflow: ellipsis;
}
.phosphor-profile-sub {
	font-family: var(--font-mono);
	font-size: 0.65625rem;
	color: var(--text-faint);
	white-space: nowrap;
}
.phosphor-profile-chevron {
	font-size: 1rem;
	flex-shrink: 0;
	color: var(--text-faint);
	transition: transform 0.14s ease, color 0.14s ease;
}
.phosphor-profile-card[aria-expanded="true"] .phosphor-profile-chevron {
	color: var(--accent);
	transform: rotate(180deg);
}

/* LOADING AREA */
@keyframes b-loading-indicator-flipper {
	100% {
		transform: rotateY(360deg);
	}
}

.b-demo-loading {
	animation: b-loading-indicator-flipper 1200ms linear infinite;
}

/* ── Terminal ── */
.sharp-terminal-container {
    display: flex;
    flex-direction: column;
    height: 100%;
    min-height: 0;
    overflow: hidden;
}

/* Fixed-grid font rules: disable ligatures/kerning so column widths are stable for NAWS grid measurement */
.sharp-terminal-output,
.term-input {
    font-family: var(--font-mono);
    font-variant-ligatures: none;
    font-feature-settings: "liga" 0, "calt" 0;
    font-kerning: none;
    letter-spacing: 0;
}

/* Stable scrollbar gutter prevents layout shift when content overflows */
.sharp-terminal-output {
    scrollbar-gutter: stable;
}

.terminal-line {
    line-height: 1.6;
    padding: 0.0625rem 0;
}

/* Sent (echoed) commands — dim cyan, prefixed with an accent caret in markup */
.terminal-sent {
    color: #7fb0c4;
    opacity: 0.85;
}

/* System/diagnostic lines — accent-dim, matches the prototype terminal */
.terminal-system {
    color: var(--accent-dim);
}

/* ── Terminal input bar (prototype MushTerminal form) ── */
.sharp-terminal-connbar {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.375rem 0.625rem;
    background: var(--surface);
    border-top: 1px solid var(--border-soft);
}

.sharp-terminal-input {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.625rem 0.875rem;
    background: var(--surface);
    border-top: 1px solid var(--border-soft);
}

.term-prompt {
    color: var(--accent);
    font-family: var(--font-mono);
    font-size: 0.875rem;
    font-weight: 700;
    flex-shrink: 0;
    line-height: 1;
}

.term-input {
    flex: 1;
    min-width: 0;
    background: transparent;
    border: none;
    outline: none;
    color: var(--text);
    font-family: var(--font-mono);
    font-size: 0.84375rem;
    caret-color: var(--accent);
}

.term-input::placeholder {
    color: var(--text-faint);
}

.term-input:disabled {
    opacity: 0.5;
}

.term-send,
.term-clear {
    display: grid;
    place-items: center;
    width: 30px;
    height: 30px;
    flex-shrink: 0;
    border-radius: var(--radius);
    cursor: pointer;
    transition: background 0.14s;
}

.term-send {
    background: rgba(var(--glow), 0.12);
    border: 1px solid rgba(var(--glow), 0.25);
    color: var(--accent);
}

.term-send:hover:not(:disabled) {
    background: rgba(var(--glow), 0.2);
}

.term-send:disabled {
    opacity: 0.4;
    cursor: not-allowed;
}

.term-clear {
    background: transparent;
    border: 1px solid var(--border);
    color: var(--text-faint);
}

.term-clear:hover {
    color: var(--text);
    border-color: var(--border);
    background: var(--surface-2);
}

/* ── MarkupString (MString) non-color attributes ──
   Colors arrive as inline `style` from the MarkupString.Html ANSI emitter; these classes
   carry the remaining text attributes. MarkupString.Html's `HtmlCss.Fixed` is the single
   source for them: every rule below is a verbatim copy of one of its rules, pinned by
   MarkupCssCoverageTests. Portal-only additions (the combined underline+strike rule, the
   --ms-fg/--ms-bg theming, and the cmd-link theming/hover/focus rules) sit alongside, never
   on top. */
.ms-bold { font-weight: bold; }
.ms-faint { opacity: 0.6; }
.ms-italic { font-style: italic; }
.ms-underline { text-decoration: underline; }
.ms-strike { text-decoration: line-through; }
.ms-underline.ms-strike { text-decoration: underline line-through; }
.ms-overline { text-decoration: overline; }
.ms-blink { animation: ms-blink 1s step-start infinite; }
/* Reverse video for a run that has neither colour set — the emitter only writes ms-invert
   when it has no colours to swap inline. HtmlCss.Fixed falls back through --ms-fg/--ms-bg,
   so pointing those at the terminal pane's own colours themes the swap without editing the
   package's rule. */
:root { --ms-fg: var(--text, #fff); --ms-bg: var(--surface, #000); }
.ms-invert { color: var(--ms-bg, #000); background-color: var(--ms-fg, #fff); }

@keyframes ms-blink { 50% { opacity: 0; } }

/* Command links (xch_cmd) — clickable, run a MUSH command. Distinct from URL links.
   The base rule mirrors HtmlCss.Fixed's .ms-cmd-link verbatim (pinned by
   MarkupCssCoverageTests); the portal-only color theming sits in its own rule below. */
.ms-cmd-link {
    cursor: pointer;
    text-decoration: underline dotted;
}
.ms-cmd-link {
    color: var(--primary, #6cf);
}
.ms-cmd-link:hover {
    text-decoration-style: solid;
}
/* Command links carry role="button" tabindex="0"; show a focus ring for keyboard users. */
.ms-cmd-link:focus-visible {
    outline: 2px solid var(--primary, #6cf);
    outline-offset: 2px;
    text-decoration-style: solid;
}

/* ── Softcode Editor ── */
.mush-editor-fill {
    width: 100%;
    height: 100%;
    background-color: #1a1a2e;
}

.mush-editor-fill .monaco-editor-container {
    height: 100%;
}

/* ── Dark DataGrid (attribute list) ── */
.mush-dark-grid .mud-table-root,
.mush-dark-grid .mud-table-container,
.mush-dark-grid .mud-table,
.mush-dark-grid thead tr,
.mush-dark-grid tbody tr {
    background-color: transparent;
}
.mush-dark-grid thead tr th {
    background-color: #1a1a1a;
    border-bottom: 1px solid #333;
    color: rgba(255,255,255,0.6);
    font-size: 0.6875rem;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}
.mush-dark-grid tbody tr td {
    border-bottom: 1px solid #282828;
    color: rgba(255,255,255,0.87);
}
.mush-dark-grid tbody tr:hover td {
    background-color: rgba(255,255,255,0.04);
}
.mush-dark-grid .mud-table-pagination {
    background-color: #1a1a1a;
    border-top: 1px solid #333;
}

/* ── Eval result panel ── */
.mush-eval-output {
    font-family: monospace;
    font-size: 0.75rem;
    white-space: pre-wrap;
    word-break: break-all;
    padding: 0.375rem 0.625rem;
    background: #111;
    color: #a3e8a0;
    border-top: 1px solid #333;
    max-height: 120px;
    overflow-y: auto;
}

/* ── HelpDrawer markdown rendering ── */
.mush-help-md {
    font-family: Consolas, 'Courier New', monospace;
    font-size: 0.8125rem;
    line-height: 1.6;
    color: #d4d4d4;
}
.mush-help-md p { margin: 0 0 0.5rem; }
.mush-help-md pre {
    background: #0d0d0d;
    border: 1px solid #333;
    border-radius: 4px;
    padding: 0.5rem 0.75rem;
    overflow-x: auto;
    white-space: pre;
}
.mush-help-md code {
    background: rgba(255,255,255,0.07);
    border-radius: 3px;
    padding: 0.0625rem 0.25rem;
    font-family: inherit;
    font-size: 0.92em;
    color: #ce9178;
}
.mush-help-md pre code {
    background: none;
    padding: 0;
    color: #d4d4d4;
}
.mush-help-md a[href^="help:"] {
    color: #4ec9b0;
    text-decoration: none;
    cursor: pointer;
}
.mush-help-md a[href^="help:"]:hover {
    text-decoration: underline;
}
.mush-help-md h1, .mush-help-md h2, .mush-help-md h3 {
    color: #9cdcfe;
    margin: 0.75rem 0 0.375rem;
}
.mush-help-md ul, .mush-help-md ol {
    padding-left: 1.25rem;
    margin: 0 0 0.5rem;
}
.mush-help-md blockquote {
    border-left: 3px solid #555;
    padding-left: 0.625rem;
    color: #888;
    margin: 0 0 0.5rem;
}
.mush-help-md strong { color: #dcdcaa; }

/* ── Scene log ── */

/* Scrollable transcript container */
.scene-log {
    display: flex;
    flex-direction: column;
    overflow-y: auto;
    font-family: Consolas, 'Courier New', monospace;
    font-size: 0.8125rem;
    line-height: 1.55;
    background: #111;
    color: #d4d4d4;
    padding: 0.5rem 0.75rem;
    border-radius: 4px;
    flex: 1;
    min-height: 0;
}

/* Live variant: fills available height and scrolls to bottom */
.scene-log--live {
    border: 1px solid #333;
}

/* Single transcript line */
.scene-line {
    padding: 0.125rem 0;
    word-break: break-word;
}

/* ── Per-type scene line colours ── */

/* A pose is prose: it is composed in a multi-line box and stored with real newlines, and HTML
   collapses whitespace, so without pre-wrap every line of a pose ran together in the archive.
   pre-wrap keeps the author's breaks and still wraps long lines. */
.scene-pose-body {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.scene-line--pose {
    color: #c8c8c8;
    font-style: italic;
}

.scene-line--say {
    color: #9cdcfe;
}

.scene-line--whisper {
    color: #888;
    font-style: italic;
}

.scene-line--ooc {
    color: #a3be8c;
}

.scene-line--system {
    color: #d7ba7d;
    font-size: 0.6875rem;
    opacity: 0.75;
}

.scene-line--normal {
    color: #d4d4d4;
}

/* Archived lines (visible in live view once scene closes) */
.scene-line--archived {
    opacity: 0.65;
}

/* Lines actively arriving in a live scene */
.scene-line--live {
    color: #d4d4d4;
}

/* ── Wiki rendered content ── */
/* Applied to the MudCard wrapping rendered wiki HTML (WikiDisplay.razor).      */
/* Colors lean on MudBlazor palette variables so they follow the active theme. */

.WikiContent {
    line-height: 1.65;
}

/* Links inside wiki content — themed color, underline on hover */
.WikiContent .mud-card-content a {
    color: var(--accent);
    text-decoration: none;
    border-bottom: 1px solid transparent;
    transition: border-color 120ms ease, color 120ms ease;
}

.WikiContent .mud-card-content a:hover,
.WikiContent .mud-card-content a:focus-visible {
    color: var(--accent-dim);
    border-bottom-color: currentColor;
}

/* External links (absolute URLs) get a subtle visual distinction */
.WikiContent .mud-card-content a[href^="http"] {
    font-style: italic;
}

/* D1 §4.8: a character link reads as a mention — body colour, a thin underline in the faint colour */
.WikiContent .mud-card-content a.mention {
    color: inherit;
    border-bottom: 0;
    text-decoration: underline 1px color-mix(in srgb, var(--name, var(--text-faint)) var(--mention-alpha), transparent);
    text-underline-offset: var(--mention-offset);
}

.WikiContent .mud-card-content a.mention:hover,
.WikiContent .mud-card-content a.mention:focus-visible {
    color: inherit;
    text-decoration-color: var(--name, var(--text-faint));
}

/* Redlinks — wiki links to pages that don't exist yet */
.WikiContent .mud-card-content a.wiki-redlink {
    color: var(--link-missing);
}

/* the dashed border is the redlink's underline; a mention already has one */
.WikiContent .mud-card-content a.wiki-redlink:not(.mention) {
    border-bottom: 1px dashed currentColor;
}

.WikiContent .mud-card-content a.wiki-redlink:hover {
    color: var(--link-missing);
}

/* Headings */
.WikiContent .mud-card-content h1,
.WikiContent .mud-card-content h2,
.WikiContent .mud-card-content h3,
.WikiContent .mud-card-content h4,
.WikiContent .mud-card-content h5,
.WikiContent .mud-card-content h6 {
    color: var(--mud-palette-text-primary, rgba(255,255,255,0.87));
    margin: 1.2em 0 0.4em;
    line-height: 1.25;
}

.WikiContent .mud-card-content h1,
.WikiContent .mud-card-content h2 {
    border-bottom: 1px solid var(--mud-palette-lines-default, #333);
    padding-bottom: 0.2em;
}

/* Paragraphs and lists */
.WikiContent .mud-card-content p {
    margin: 0 0 0.9em;
}

.WikiContent .mud-card-content ul,
.WikiContent .mud-card-content ol {
    padding-left: 1.6em;
    margin: 0 0 0.9em;
}

.WikiContent .mud-card-content li {
    margin: 0.2em 0;
}

/* Inline code and code blocks */
.WikiContent .mud-card-content code {
    background: rgba(255, 255, 255, 0.07);
    border-radius: 3px;
    padding: 0.0625rem 0.3125rem;
    font-family: Consolas, 'Courier New', monospace;
    font-size: 0.9em;
}

.WikiContent .mud-card-content pre {
    background: #0d0d0d;
    border: 1px solid var(--mud-palette-lines-default, #333);
    border-radius: 4px;
    padding: 0.625rem 0.875rem;
    overflow-x: auto;
    margin: 0 0 1em;
}

.WikiContent .mud-card-content pre code {
    background: none;
    padding: 0;
}

/* Blockquotes */
.WikiContent .mud-card-content blockquote {
    border-left: 3px solid var(--mud-palette-secondary, #80cbc4);
    margin: 0 0 1em;
    padding: 0.2em 0 0.2em 1em;
    color: var(--mud-palette-text-secondary, rgba(255,255,255,0.6));
}

/* Tables (Markdig pipe tables) */
.WikiContent .mud-card-content table {
    border-collapse: collapse;
    margin: 0 0 1em;
    width: 100%;
}

.WikiContent .mud-card-content th,
.WikiContent .mud-card-content td {
    border: 1px solid var(--mud-palette-lines-default, #333);
    padding: 0.375rem 0.75rem;
    text-align: left;
}

.WikiContent .mud-card-content th {
    background: rgba(255, 255, 255, 0.05);
}

.WikiContent .mud-card-content tbody tr:hover {
    background: rgba(255, 255, 255, 0.03);
}

/* Horizontal rules */
.WikiContent .mud-card-content hr {
    border: none;
    border-top: 1px solid var(--mud-palette-lines-default, #333);
    margin: 1.5em 0;
}

/* ── Hero mode (home page) ── */
/* The hero card uses text-align:center; these rules make block-level content
   follow suit instead of pinning to the left edge. */

/* Images are display:block, so text-align can't center them — auto margins do. */
.WikiContent--hero .wiki-img {
    margin-left: auto;
    margin-right: auto;
}

/* Lists: shrink-wrap the list box so it centers as a unit, keeping bullets
   adjacent to their (left-aligned) items instead of at the page edge. */
.WikiContent--hero .mud-card-content ul,
.WikiContent--hero .mud-card-content ol {
    display: inline-block;
    text-align: left;
}

/* ── Wiki directive blocks (dynamic listings: category / tag / pagelist / recent) ── */

.wiki-directive-block {
    border-left: 3px solid var(--mud-palette-secondary, #80cbc4);
    background: rgba(255, 255, 255, 0.03);
    border-radius: 0 4px 4px 0;
    padding: 0.6em 1.1em;
    margin: 0 0 1em;
}

.wiki-directive-block .wiki-directive-header {
    color: var(--mud-palette-text-primary, rgba(255, 255, 255, 0.87));
    font-weight: 600;
    margin-bottom: 0.35em;
}

.wiki-directive-block .wiki-directive-empty,
.wiki-directive-block .wiki-directive-loading {
    color: var(--mud-palette-text-secondary, rgba(255, 255, 255, 0.6));
    margin: 0;
}

.WikiContent .mud-card-content .wiki-directive-list,
.wiki-directive-list {
    list-style: none;
    padding-left: 0.2em;
    margin: 0.3em 0 0;
}

.wiki-directive-list li {
    margin: 0.3em 0;
}

.wiki-directive-list .wiki-directive-date {
    color: var(--mud-palette-text-secondary, rgba(255, 255, 255, 0.6));
    font-size: 0.85em;
}

/* Wiki images — lazy loading, constrained width */
.wiki-img {
    max-width: 100%;
    display: block;
    margin: 0.5rem 0;
}

/* Only auto-size images that don't carry an explicit height attribute
   (authors can size via ![alt](src){width=200 height=100}) */
.wiki-img:not([height]) {
    height: auto;
}

/* ═══════════════════════════════════════════════════════════════════════
   MOBILE TOOLKIT + RESPONSIVE SHELL
   Phone / tablet-landscape / desktop, split by width AND input capability.

   Responsive model (3 tiers, width × input capability):
     • PHONE content — `@media (max-width: 760px)`. Single-column stacking, condensed
       chrome. This is the breakpoint page authors use for content. In Razor <style>
       blocks write `@@media (max-width: 760px)` (Razor escapes `@`; a bare `@media`
       is parsed as a code transition and fails to compile).
     • TABLET / landscape phone — wider than 760px, so they KEEP the desktop
       multi-column content (more readable). Don't add a single-column rule for them.
     • TOUCH CHROME — `@media (max-width: 760px), (pointer: coarse)`. The shell nav
       (drawer + bottom bar vs. desktop sidebar) keys off this so any touch device,
       including a wide tablet or landscape phone, gets touch-friendly chrome while a
       mouse/trackpad desktop keeps the sidebar. Mirrored by sharpmushLayout.isTouchChrome().
     • TOUCH ergonomics — `@media (pointer: coarse)`: 44px min tap targets, no hover-only UI.
     • Full-height regions: size with `svh` and a `vh` fallback, e.g.
       "height: 100vh;" then "height: 100svh;" — the vh line is the fallback for
       browsers without svh; svh fits the SMALL viewport, so it never crops under
       the mobile address bar and never resizes on scroll.
       Default to `svh`, NOT `dvh`. `dvh` tracks the live viewport and recalculates
       every time the toolbar slides in/out (layout jank); reserve it for the rare
       element that must follow the visible viewport in real time.
     • Any flex/grid child holding wide content (terminal, tables, code, pre)
       needs `min-width: 0`; prefer `minmax(0, 1fr)` over a bare `1fr` track.
     • Min touch target 44px for interactive controls.
   Helper classes below are available to every page.
   ═══════════════════════════════════════════════════════════════════════ */

/* Backdrop behind the off-canvas nav drawer — inert until the shell is .nav-open. */
.phosphor-nav-backdrop {
	display: none;
}

/* ── Hybrid bottom navigation (mobile only; hidden here, shown in the @media block).
   Primary destinations stay visible; the "Menu" tab opens the full grouped drawer. ── */
.phosphor-bottomnav {
	display: none;
}
.phosphor-bottomtab {
	flex: 1;
	min-width: 0;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 0.125rem;
	background: transparent;
	border: none;
	cursor: pointer;
	text-decoration: none;
	color: var(--text-faint);
	font-family: var(--font-ui);
	transition: color 0.14s;
}
.phosphor-bottomtab-icon {
	font-size: 1.375rem;
}
.phosphor-bottomtab-label {
	max-width: 100%;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
	font-size: 0.65625rem;
	letter-spacing: 0.02em;
}
.phosphor-bottomtab--on {
	color: var(--accent);
}

/* The section button in the touch header only where the page has a section sidebar to open. */
.phosphor-shell:not(:has(.kit-pagebar)) .phosphor-pagebar-btn {
	display: none;
}

/* Play's focus mode (.play--focus): the play area is the whole app. The shell's chrome steps away with
   the page sidebar — the rail, the touch header, the TopBar zone, the footer and the widget asides —
   and the scene card's focus button brings it back. The predicate is a child chain from the shell to
   the page root because game output (tagwrap, wshtml) renders as HTML inside the terminal and can carry
   any class name; a bare descendant match would let it switch the chrome off. */
.phosphor-shell:has(> .phosphor-content-col > .phosphor-main > .phosphor-page > .kit-section-body > .play--focus) :is(.phosphor-rail, .phosphor-topbar, .phosphor-topzone, .phosphor-footer, .phosphor-widget-aside) {
	display: none;
}

/* Play merges the shell's touch header into its card header (Play.razor): while the card is mounted the
   header (or its short-landscape rail) steps away, the avatar opens the drawer, and the drawer's tools row
   carries the header's other buttons. The roster and no-character states have no card and keep the header.
   The same child chain as focus mode, so game output cannot match it. */
.phosphor-drawer-tools {
	display: none;
}
.phosphor-shell:has(> .phosphor-content-col > .phosphor-main > .phosphor-page > .kit-section-body > .play) .phosphor-topbar {
	display: none;
}
.phosphor-shell:has(> .phosphor-content-col > .phosphor-main > .phosphor-page > .kit-section-body > .play) .phosphor-drawer-tools {
	display: flex;
	align-items: center;
	justify-content: space-around;
	flex-shrink: 0;
	padding: 0.5rem 0.75rem;
	border-top: 1px solid var(--border-soft);
}

/* ══ PHONE-WIDTH content: single-column helpers + a condensed topbar. Tablets and
   landscape phones are WIDER than this, so they keep the desktop multi-column content
   (the readability win) — only their chrome goes touch-friendly (next block). ══ */
@media (max-width: 760px) {

	/* A condensed header: the search is an icon, and the language stays (a phone has no other). */
	.phosphor-topbar { gap: 0.375rem; padding: 0 0.625rem; }
}

/* ══ TOUCH CHROME: the nav becomes an off-canvas drawer + a bottom tab bar. Applies to
   any touch device (pointer: coarse) OR any narrow window — so phones, tablets, and
   landscape phones all get the touch-friendly chrome instead of the desktop sidebar,
   while a mouse/trackpad desktop (pointer: fine + wide) keeps the sidebar. Keep this
   media condition in sync with sharpmushLayout.isTouchChrome() in layout.js. ══ */
@media (max-width: 760px), (pointer: coarse) {
	/* The rail is desktop chrome; touch chrome has the drawer, the header and the bottom tab bar.
	   Anything that is not touch chrome (a fine pointer, or none at all) gets the rail alone. */
	.phosphor-rail { display: none; }
	.phosphor-sidebar { display: flex; }
	.phosphor-topbar { display: flex; }

	/* The section panel is always the full sidebar here (SectionShell ignores a desktop collapse). */
	.phosphor-shell .phosphor-pagebar .kit-pagebar-toggle { display: none; }

	/* The sidebar leaves the flex flow and slides in over the content, full-width. */
	.phosphor-sidebar {
		position: fixed;
		top: 0;
		left: 0;
		bottom: 0;
		width: 248px;
		z-index: 1001;
		transform: translateX(-100%);
		transition: transform 0.22s ease;
		box-shadow: 2px 0 24px rgba(0, 0, 0, 0.5);
	}
	.phosphor-shell--nav-open .phosphor-sidebar { transform: translateX(0); }
	/* Keep brand/labels/text visible even if the desktop rail was collapsed. */
	.phosphor-sidebar--collapsed { width: 248px; }

	/* Dimmed backdrop, shown only while the drawer is open. */
	.phosphor-nav-backdrop {
		display: block;
		position: fixed;
		inset: 0;
		z-index: 1000;
		background: rgba(0, 0, 0, 0.55);
		opacity: 0;
		pointer-events: none;
		transition: opacity 0.22s ease;
	}
	.phosphor-shell--nav-open .phosphor-nav-backdrop {
		opacity: 1;
		pointer-events: auto;
	}

	/* The page sidebar leaves the flow too: an off-canvas panel opened from the header (below). */
	.phosphor-pagebar {
		position: fixed;
		top: 0;
		left: 0;
		bottom: 0;
		width: min(280px, 86vw);
		z-index: 1001;
		transform: translateX(-100%);
		transition: transform 0.22s ease;
		box-shadow: 2px 0 24px rgba(0, 0, 0, 0.5);
	}
	.phosphor-pagebar:has(.kit-pagebar--collapsed) { width: min(280px, 86vw); }
	.phosphor-shell--pagebar-open .phosphor-pagebar { transform: translateX(0); }
	.phosphor-shell--pagebar-open .phosphor-nav-backdrop {
		opacity: 1;
		pointer-events: auto;
	}

	/* Content column owns the full width now the sidebar is out of flow. */
	.phosphor-content-col { width: 100%; }

	/* Global widget asides step aside so content keeps the full width. */
	.phosphor-widget-aside { display: none; }

	/* Bottom command-terminal drawer: svh keeps the input row on-screen under the
	   address bar without resizing on scroll. */
	.phosphor-terminal {
		height: 70vh;
		height: 70svh;
		max-height: 70svh;
	}

	/* ── Hybrid bottom navigation bar ── */
	.phosphor-bottomnav {
		display: flex;
		position: fixed;
		left: 0;
		right: 0;
		bottom: 0;
		z-index: 40;
		height: 58px;
		padding-bottom: env(safe-area-inset-bottom);
		background: color-mix(in srgb, var(--surface-3) 92%, transparent);
		backdrop-filter: blur(10px);
		-webkit-backdrop-filter: blur(10px);
		border-top: 1px solid var(--border-soft);
	}
	/* Keep page content clear of the fixed bar, via --bottomnav-clearance (tokens.css) so a
	   page's own sticky-bottom chrome can read the same offset without a media query. */
	.phosphor-shell--bottomnav {
		--bottomnav-clearance: calc(3.625rem + env(safe-area-inset-bottom));
	}
	.phosphor-shell--bottomnav .phosphor-main {
		padding-bottom: var(--bottomnav-clearance);
	}
	/* When the terminal drawer is open it grows to 70svh and covers the bottom bar,
	   so the content offset must match the drawer (not the 300px desktop value).
	   Listed after the bar rule so it wins at equal specificity. */
	.phosphor-main--terminal,
	.phosphor-shell--bottomnav .phosphor-main--terminal {
		padding-bottom: 70vh;
		padding-bottom: 70svh;
	}
}

/* ══ SHORT LANDSCAPE: a phone held sideways is short of height, not width. The touch header turns into a
   rail down the left edge — the same buttons, stacked — so the page keeps the full height. Touch chrome
   only (the condition above, ANDed with the shape); a mouse desktop already has the rail. An upright phone
   keeps the header on top: it is short of width, not height. The shape is the landscape half of
   sharpmushLayout.compactScreenQuery in layout.js. ══ */
@media (max-width: 760px) and (orientation: landscape) and (max-height: 32rem),
	(pointer: coarse) and (orientation: landscape) and (max-height: 32rem) {
	.phosphor-topbar {
		position: fixed;
		top: 0;
		bottom: 0;
		left: 0;
		width: calc(var(--touch-rail-w) + env(safe-area-inset-left));
		height: auto;
		flex-direction: column;
		gap: 4px;
		padding: max(8px, env(safe-area-inset-top)) 0 max(8px, env(safe-area-inset-bottom)) env(safe-area-inset-left);
		border-bottom: 0;
		border-right: 1px solid var(--border-soft);
	}
	.phosphor-shell {
		--touch-rail-w: 56px;
	}
	.phosphor-content-col {
		box-sizing: border-box;
		padding-left: calc(var(--touch-rail-w) + env(safe-area-inset-left));
	}
	/* Play merges the rail into its card header (above); the page gets its width back. */
	.phosphor-shell:has(> .phosphor-content-col > .phosphor-main > .phosphor-page > .kit-section-body > .play) .phosphor-content-col {
		padding-left: 0;
	}
}

/* ══ Touch ergonomics: 44px tap targets on any touch device, regardless of width. ══ */
@media (pointer: coarse) {
	.phosphor-nav-link { min-height: 44px; }
	.phosphor-icon-btn { min-width: 44px; min-height: 44px; }
	/* The D1 kit (Components/Kit): rows, capsules and chips are 30–40px on a fine pointer. */
	.kit-row, .kit-capsule, .kit-chip { min-height: 44px; }
	.kit-capsule--icon { min-width: 44px; }
	.kit-portrait, .kit-tile { min-height: 44px; }
}
