/* Roget codex view */

.roget-codex-container {
	display: flex;
	flex-direction: column;
	height: 100%;
}

.roget-codex-scroller {
	flex: 1 1 auto;
	min-height: 0;
	overflow-y: auto;
	/* Explicit, not the default -- setting only overflow-y leaves
	 * overflow-x computed as auto too (CSS's cross-axis coupling: if
	 * either axis is non-visible, the other stops being visible as
	 * well), so even a few px of harmless whitespace overflow from the
	 * two-column flex layout's own rounding triggers a real horizontal
	 * scrollbar with nothing actually needing it (Erick, 2026-08-04:
	 * "nothing is off-screen... scrolling only adjusts how much
	 * whitespace is visible on either side"). */
	overflow-x: hidden;
	padding: var(--size-4-4) var(--size-4-6);
	font-size: var(--roget-font-size, 16px);
	font-family: var(--roget-body-font, var(--font-text));
	/* Obsidian's base styling sets user-select: none on generic view
	 * content (assuming most custom views are UI chrome, not text) —
	 * this view is text, and the lookup/replace workflow depends on
	 * being able to select words in it. */
	user-select: text;
	-webkit-user-select: text;
}

/* Display face: falls back to the body font, then Obsidian's own note
 * font, so setting only one of the two settings still looks coherent
 * rather than half-reverting to the browser default. */
.roget-codex-tier > :first-child,
.roget-codex-group-text,
.roget-head-title,
.roget-head-id,
.roget-section-label {
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
}

/* Navigation bar: back/forward + breadcrumb trail. Always visible, does
 * not scroll with the codex content. Three rows: a quiet title line,
 * buttons + search below it, the trail on its own line below that -- the
 * trail's own horizontal scrollbar (kept deliberately, see
 * .roget-navbar-trail) needs the full bar width to be worth having, not
 * whatever's left over after sharing a row with everything else. */
.roget-navbar {
	flex: 0 0 auto;
	display: flex;
	flex-direction: column;
	gap: var(--size-4-1);
	padding: var(--size-4-1) var(--size-4-3);
	border-bottom: 1px solid var(--background-modifier-border);
	background: var(--background-primary);
}

/* A title independent of the tab strip -- Obsidian shows no tab header
 * at all when this view is alone in a sidebar (the default placement),
 * so getDisplayText() alone wouldn't be visible there. */
.roget-navbar-masthead {
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
	font-size: 0.78em;
	font-weight: var(--font-semibold);
	letter-spacing: 0.06em;
	text-transform: uppercase;
	color: var(--text-normal);
}

.roget-navbar-top {
	display: flex;
	align-items: center;
	gap: var(--size-4-2);
}

.roget-navbar-controls {
	display: flex;
	gap: var(--size-4-1);
	flex: 0 0 auto;
}

.roget-nav-btn {
	display: flex;
	align-items: center;
	justify-content: center;
	background: transparent;
	border: none;
	box-shadow: none;
	cursor: pointer;
	color: var(--text-muted);
	padding: var(--size-4-1);
	border-radius: var(--radius-s);
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
}

.roget-nav-btn:hover:not(:disabled) {
	background: var(--background-modifier-hover);
	color: var(--text-normal);
}

.roget-nav-btn:disabled {
	opacity: 0.35;
	cursor: default;
}

/* Text-labeled nav buttons (column toggle, PDF/Synopsis "refocus"
 * shortcuts) -- wider padding than the plain icon buttons above need,
 * since these hold a word or two rather than a single glyph. Erick,
 * 2026-08-03: the column toggle went through two icon attempts first
 * (see NAV_ICONS' own comment) before landing on plain text -- "we have
 * the real estate... let's be more prolix". aria-pressed drives the
 * same active-tab underline the side pane's own tab bar uses, so PDF/
 * Synopsis read as "currently showing" the same way a tab would. */
.roget-nav-btn-text {
	padding: var(--size-4-1) var(--size-4-2);
	font-size: 0.85em;
	white-space: nowrap;
}
.roget-nav-btn-text[aria-pressed="true"] {
	color: var(--text-normal);
	box-shadow: inset 0 -2px 0 var(--interactive-accent);
}

/* Labels the PDF/Synopsis "refocus" pair, not a button itself. */
.roget-navbar-controls-label {
	display: flex;
	align-items: center;
	color: var(--text-normal);
	font-style: italic;
	font-size: 0.85em;
	white-space: nowrap;
	margin-left: var(--size-4-1);
}

/* The shared left pane's own tab bar (CodexView.buildSideTabBar,
 * 2026-08-03) -- switches which of DOC_TABS is showing. Wraps rather than
 * scrolling/truncating: MIN_WIDTH (layout.ts) plus MAX_FRACTION already
 * bound how narrow/wide the pane can get, so a wrapped two-row bar never
 * runs out of room entirely at either extreme. */
.roget-side-tabbar {
	display: flex;
	flex-wrap: wrap;
	flex: 0 0 auto;
	border-bottom: 1px solid var(--background-modifier-border);
}
.roget-side-tab {
	flex: 1 1 auto;
	background: transparent;
	border: none;
	box-shadow: none;
	cursor: pointer;
	color: var(--text-muted);
	padding: var(--size-4-2) var(--size-4-1);
	font-size: 0.85em;
	white-space: nowrap;
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
}
.roget-side-tab:hover {
	background: var(--background-modifier-hover);
	color: var(--text-normal);
}
.roget-side-tab.is-active {
	color: var(--text-normal);
	font-weight: var(--font-semibold);
	box-shadow: inset 0 -2px 0 var(--interactive-accent);
}

/* Mobile plan, stage 3 -- closes the full-screen drawer index.html's own
 * #side-pane.is-open media query turns this pane into below MOBILE_LAYOUT
 * (codexView.ts). Hidden everywhere else: on desktop/tablet the pane sits
 * beside the codex, where the main nav bar's own panel-toggle button
 * already reaches it. */
.roget-side-close {
	display: none;
}
@media (max-width: 600px) {
	.roget-side-close {
		display: block;
		flex: 0 0 auto;
		align-self: flex-end;
		background: transparent;
		border: none;
		box-shadow: none;
		cursor: pointer;
		color: var(--text-muted);
		font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
		font-size: 0.9em;
		padding: var(--size-4-3) var(--size-4-4);
		min-height: 44px;
	}
	.roget-side-close:hover {
		color: var(--text-normal);
	}
}

/* Placeholder content for a document not yet delivered (splash/preface/
 * how-to/content-note, 2026-08-03) -- swap for the real text/rendering
 * per doc as each is delivered, see website/TODO.md. */
.roget-doc-placeholder {
	padding: var(--size-4-4) var(--size-4-6);
	overflow-y: auto;
	/* Same cross-axis coupling fix as .roget-codex-scroller -- see its
	 * own comment. */
	overflow-x: hidden;
	width: 100%;
	color: var(--text-normal);
}
.roget-doc-placeholder h2,
.roget-doc-placeholder h3,
.roget-doc-placeholder h4 {
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
}
.roget-doc-placeholder h2 {
	color: var(--text-normal);
	margin-top: 0;
}
.roget-doc-placeholder h3 {
	color: var(--text-normal);
	margin: 1.3em 0 0.5em;
}
.roget-doc-placeholder h4 {
	color: var(--text-normal);
	margin: 1em 0 0.4em;
	font-size: 1.05em;
}
.roget-doc-placeholder p {
	margin: 0 0 0.9em;
	line-height: 1.5;
	max-width: 42em;
}
.roget-doc-placeholder-stub {
	color: var(--text-normal);
	font-style: italic;
}
.roget-doc-image {
	display: block;
	max-width: 100%;
	height: auto;
	margin: 0.4em 0 1.2em;
	border: 1px solid var(--background-modifier-border);
	border-radius: var(--radius-s);
}

.roget-navbar-trail-row {
	display: flex;
	align-items: center;
	gap: var(--size-4-1);
}

.roget-navbar-trail {
	flex: 1 1 auto;
	min-width: 0;
	overflow-x: auto;
	white-space: nowrap;
	font-size: 0.85em;
	color: var(--text-normal);
}

.roget-trail-clear-btn {
	flex: 0 0 auto;
}

.roget-trail-empty {
	color: var(--text-normal);
	font-style: italic;
}

.roget-trail-chip {
	cursor: pointer;
}

.roget-trail-chip:hover {
	text-decoration: underline;
	color: var(--text-normal);
}

.roget-trail-chip:focus-visible {
	outline: 2px solid var(--interactive-accent);
	outline-offset: 1px;
	border-radius: var(--radius-s);
}

.roget-trail-chip-active {
	color: var(--text-normal);
	font-weight: var(--font-semibold);
	cursor: default;
}

.roget-trail-sep {
	margin: 0 0.35em;
	color: var(--text-normal);
}

/* Inline word search: always visible in the nav bar, the persistent
 * alternative to invoking "Look up word" via the command palette. Anchors
 * an absolutely-positioned results dropdown so opening/closing it never
 * reflows the nav bar or the trail next to it. */
.roget-searchbar {
	position: relative;
	flex: 0 0 auto;
	width: 200px;
}

.roget-searchbar-input {
	width: 100%;
	border: 1.5px solid var(--interactive-accent);
	border-radius: var(--radius-s);
	padding: var(--size-4-1) var(--size-4-2);
	background: var(--background-primary);
	color: var(--text-normal);
}

.roget-searchbar-input:focus {
	outline: none;
	border-color: var(--interactive-accent);
	box-shadow: 0 0 0 2px color-mix(in srgb, var(--interactive-accent) 35%, transparent);
}

.roget-searchbar-results {
	position: absolute;
	top: calc(100% + var(--size-4-1));
	left: 0;
	width: max(100%, 320px);
	max-height: 320px;
	overflow-y: auto;
	background: var(--background-primary);
	border: 1px solid var(--background-modifier-border);
	border-radius: var(--radius-s);
	box-shadow: var(--shadow-s);
	z-index: var(--layer-popover);
}

.roget-searchbar-result {
	padding: var(--size-4-1) var(--size-4-2);
	cursor: pointer;
}

.roget-searchbar-result-word {
	display: block;
	color: var(--text-normal);
}

.roget-searchbar-result-meta {
	display: block;
	font-size: 0.85em;
	font-style: italic;
	color: var(--text-normal);
}

.roget-searchbar-result-active {
	background: var(--background-modifier-hover);
}

/* Mobile plan, stage 3 -- below MOBILE_LAYOUT's own breakpoint
 * (codexView.ts, 600px, kept in sync with this query), the nav bar's top
 * row (panel-toggle/?/Columns/Stack/back/forward/Refocus buttons plus the
 * search box) has no room to fit on one line: .roget-navbar-controls is
 * `flex: 0 0 auto` with no wrap, and .roget-searchbar is a fixed 200px on
 * top of that. Two changes, not one -- letting the controls wrap on their
 * own already crowds a 200px search box onto the tail of whatever row it
 * lands on, so the search box gets its own full-width row instead
 * (100% flex-basis forces the wrap), and the controls wrap freely above
 * it. Buttons also grow to a real touch target here (44px is the common
 * iOS/Android comfort minimum) -- narrower in scope than stage 4's own
 * site-wide hover-affordance pass (still not started), but a phone nav
 * bar that overflows or is too fiddly to tap isn't a usable baseline
 * either, so this much comes with the layout fix rather than waiting. */
@media (max-width: 600px) {
	.roget-navbar-top {
		flex-wrap: wrap;
	}
	/* flex-wrap here only affects .roget-navbar-controls' OWN children
	 * (the buttons) -- it does nothing unless the element itself is also
	 * width-constrained, since its base flex:0 0 auto (styles.css, the
	 * unmodified rule above) lets it grow to its content's full natural
	 * width with nothing to wrap against, overflowing the row instead of
	 * wrapping within it (caught live: buttons ran off the right edge of
	 * a 390px frame with no second row). flex-basis:100% forces it to
	 * claim the whole row (same technique .roget-searchbar already uses
	 * to force ITSELF onto its own row below), which is what makes its
	 * own wrap actually do something. */
	.roget-navbar-controls {
		flex: 1 1 100%;
		flex-wrap: wrap;
	}
	.roget-searchbar {
		flex: 1 1 100%;
		width: auto;
	}
}

/* Mobile plan, stage 4 (2026-08-04): touch-target sizing belongs on
 * hover:none, not the phone-width breakpoint above -- stage 3 first put
 * it there since it was restructuring that row anyway, but the two are
 * really separate questions. A touch-primary TABLET (Erick, stage 1:
 * "the layout would work alright on a tablet") keeps the desktop-style
 * single-row nav bar, never hits max-width:600px, and would otherwise
 * keep tiny mouse-sized buttons despite having no mouse. A resized
 * desktop window that happens to be narrow, conversely, still has a
 * precise pointer and doesn't need bigger targets just because the bar
 * wrapped. Same distinction PDF_CAPABLE (codexView.ts) already draws
 * between touch capability and screen width. */
@media (hover: none) {
	.roget-nav-btn {
		min-width: 44px;
		min-height: 44px;
		padding: var(--size-4-2);
	}
	.roget-nav-btn-text {
		min-height: 44px;
		padding: var(--size-4-2) var(--size-4-3);
	}
	.roget-side-tab {
		min-height: 44px;
		padding: var(--size-4-2);
	}

	/* The other half of stage 4: every :hover-only navigable element in
	 * the codex/synopsis/footer (classification headings, head titles,
	 * synopsis rows, the content-warning gloss, the footer link,
	 * compressed groups) has NO visual distinction from plain text until
	 * hovered or focused -- role="link" plus cursor:pointer is a real
	 * click/keyboard target, but hover doesn't exist on touch, so there's
	 * nothing signaling "tap here" at all. A permanent, subtle version of
	 * the same background-tint hover already uses elsewhere on the site
	 * (e.g. .roget-head-heading-navigable:hover), rather than inventing a
	 * new visual language. xref links are excluded on purpose --
	 * .roget-xref-clickable already has its own permanent accent color,
	 * doesn't need this. .roget-matrix has no role attribute (a
	 * pre-existing, separate keyboard-access gap, not fixed here -- it's
	 * click-only today with no keydown handler), so it's listed by class
	 * instead of folding into the role selector. */
	[role="link"]:not(.roget-xref-clickable),
	.roget-matrix {
		background: color-mix(in srgb, var(--interactive-accent) 10%, transparent);
		border-radius: var(--radius-s);
	}
}

/* Pending-replacement indicator: empty/collapsed until a "Look up ... in
 * Roget" from an outside editor arms a replacement, so it's never taking
 * up space (or attention) unless there's actually something armed. */
.roget-replace-bar {
	flex: 0 0 auto;
	display: none;
	align-items: center;
	justify-content: space-between;
	gap: var(--size-4-2);
	padding: var(--size-4-1) var(--size-4-3);
	border-bottom: 1px solid var(--background-modifier-border);
	background: var(--background-modifier-hover);
	font-size: 0.85em;
}

.roget-replace-bar-active {
	display: flex;
}

.roget-replace-bar-label {
	color: var(--text-normal);
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.roget-replace-bar-cancel {
	display: flex;
	align-items: center;
	justify-content: center;
	flex: 0 0 auto;
	background: transparent;
	border: none;
	box-shadow: none;
	cursor: pointer;
	color: var(--text-muted);
	padding: var(--size-4-1);
	border-radius: var(--radius-s);
}

.roget-replace-bar-cancel:hover {
	background: var(--background-modifier-hover);
	color: var(--text-normal);
}

/* Classification structure (Class/Division/Section/Subsection) printed
 * inline in the codex's own reading flow, the way the book's own pages do
 * it. Full width: clears any float a two-column row above it left behind
 * (each row already self-clears via .roget-row-paired.is-float::after, so
 * no explicit clear needed here). */
.roget-codex-tier {
	width: 100%;
	margin: var(--size-4-6) 0 var(--size-4-3);
}

.roget-codex-tier > :first-child {
	margin: 0;
	font-weight: var(--font-bold);
	text-wrap: balance;
}

.roget-codex-tier-class {
	margin-top: var(--size-4-8);
	padding-bottom: var(--size-4-2);
	border-bottom: 2px solid var(--text-accent);
}
.roget-codex-tier-class > :first-child {
	font-size: 1.75em;
	letter-spacing: 0.03em;
	text-transform: uppercase;
}

.roget-codex-tier-division > :first-child {
	font-size: 1.35em;
	letter-spacing: 0.02em;
	color: var(--text-accent);
}

.roget-codex-tier-section {
	padding-bottom: var(--size-4-1);
	border-bottom: 1px dashed var(--background-modifier-border);
}
.roget-codex-tier-section > :first-child {
	font-size: 1.2em;
	letter-spacing: 0.015em;
}

.roget-codex-tier-subsection > :first-child {
	font-size: 1.05em;
	color: var(--text-normal);
	text-transform: uppercase;
}

/* Group tiers (Classification.groups, schema v1.10.0) -- sub-subsection
 * captions finer than Subsection, e.g. "Special sensation" > "Sound" >
 * "Sound in General". Much lighter weight than the four tiers above,
 * matching how small the print's own captions are here; --depth (0-2)
 * drives indent, not a separate class per level. */
.roget-codex-group {
	width: 100%;
	margin: var(--size-4-2) 0 var(--size-4-1) calc(var(--depth, 0) * var(--size-4-4));
}
.roget-codex-group-text {
	font-style: italic;
	font-size: 0.88em;
	color: var(--text-normal);
}

/* Clickable inline classification headings (Class/Division/Section/
 * Subsection/group) -- jump to that exact spot in the Tabular Synopsis
 * (CodexView.setupTierNavigation()). Same hover/focus treatment as the
 * synopsis pane's own .roget-synopsis-navigable. */
.roget-codex-classification-navigable {
	cursor: pointer;
}
.roget-codex-classification-navigable:hover,
.roget-codex-classification-navigable:focus-visible {
	text-decoration: underline;
	text-underline-offset: 0.15em;
	outline: none;
}

/* --- Tabular synopsis (outline) view -------------------------------- */

.roget-synopsis-container {
	height: 100%;
	overflow: hidden;
	display: flex;
	flex-direction: column;
}

/* Density pass (Erick, 2026-08-01, after both label-beside-content and
 * multi-column reflow didn't close the gap): back to a single column,
 * capped width like the original, but tightened throughout -- smaller
 * type, tighter line-height, less padding/margin per row and heading --
 * closer to the print's own compact index typography than a card-like
 * modern list. Doesn't fix the structural "1022 heads is a lot of
 * scrolling" problem, but it's a real, low-risk reduction in how much
 * vertical space each individual thing takes, independent of whichever
 * structural direction comes next. */
/* 2026-08-04 (Erick): "the wrapper that encloses the synopsis and the
 * wrapper that encloses the pdf -- can they be the same? Why would the
 * same not be true for the synopsis?" -- it can, and now is. Everything
 * that made this element different from .roget-pdf-scroller (max-width,
 * margin: 0 auto, width: 100% -- the readable-column cap) is GONE from
 * here, moved to .roget-synopsis-content below. That combination, unique
 * to this element among every scrollable pane in the app, was the prime
 * suspect once Erick noticed this pane's own scrollbar was invisible
 * where the PDF/Preface panes' scrollbars showed immediately: a
 * max-width-capped, margin-centered, width:100% box sharing an element
 * with overflow-y: auto is exactly the shape of problem CSS's own
 * scrollbar-gutter property exists to solve. Line-for-line now matches
 * .roget-pdf-scroller's own shape; if a browser can show a scrollbar
 * there, there's no structural reason it wouldn't here too. */
.roget-synopsis-scroller {
	flex: 1 1 auto;
	overflow-y: auto;
	padding-top: var(--size-4-3);
	padding-bottom: var(--size-4-3);
	padding-left: var(--size-4-6);
	padding-right: var(--size-4-6);
}

/* The readable-column cap/centering, now living on a plain non-scrolling
 * child instead of the scroller itself (see .roget-synopsis-scroller's
 * own comment). Purely a typography concern -- max-width keeps lines
 * from stretching edge-to-edge in a wide pane, margin: 0 auto centers
 * that capped column when the pane is wider than the cap. */
.roget-synopsis-content {
	max-width: 60em;
	margin: 0 auto;
	width: 100%;
	line-height: 1.25;
}

.roget-synopsis-loading {
	color: var(--text-normal);
	font-style: italic;
}

/* Every tier below only ever set margin-top -- margin-bottom was never
 * touched, so each heading's own un-reset browser-default bottom margin
 * (h2 through h5, 16.6px-22.7px measured live, actually LARGEST on the
 * deepest/smallest-looking tiers) was quietly doing the "space below a
 * heading" job no one asked it to do, while the small deliberate
 * margin-top values did the "space above" job (Erick, 2026-08-04: "too
 * much room below the headings and too little space above them, so that
 * it looks like they belong with what precedes rather than governing
 * what follows"). Fixed at the source: margin-top raised a step on the
 * spacing scale (real separation from whatever precedes), margin-bottom
 * pinned to a small, deliberate, consistent value on every tier (tight
 * binding to what follows) instead of whatever the browser's own
 * per-tag default happened to compute to. */
/* Display face for the synopsis's own structuring headings, matching
 * .roget-codex-tier/.roget-codex-group-text's treatment in the main codex
 * view -- leaf entries below (.roget-synopsis-leaf-*) stay in the body
 * font, same reasoning as .roget-word-gloss etc. staying body-font in the
 * codex: these are the actual dictionary content, not outline structure
 * (Erick, 2026-08-04: "leave the leaves Garamond but have the structuring
 * heads all be Merriweather... would improve readability"). */
.roget-synopsis-class,
.roget-synopsis-division,
.roget-synopsis-section,
.roget-synopsis-subsection,
.roget-synopsis-group-text {
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
}

.roget-synopsis-class {
	margin-top: var(--size-4-6);
	margin-bottom: var(--size-4-1);
	padding-bottom: var(--size-4-1);
	border-bottom: 2px solid var(--background-modifier-border);
	font-size: 1.25em;
}

.roget-synopsis-division {
	margin-top: var(--size-4-4);
	margin-bottom: var(--size-4-1);
	color: var(--text-accent);
	font-size: 1.05em;
}

.roget-synopsis-section {
	margin-top: var(--size-4-3);
	margin-bottom: var(--size-4-1);
	font-size: 0.95em;
}

.roget-synopsis-subsection {
	margin-top: var(--size-4-2);
	margin-bottom: var(--size-4-1);
	margin-left: var(--size-4-3);
	color: var(--text-normal);
	font-size: 0.85em;
}

/* A tier's own footnote(s), when they immediately follow that tier's
 * heading (renderTierNotes() always renders them right after, see
 * synopsisPane.ts) -- tightened specifically for this adjacency so the
 * footnote text visually belongs to the heading above it instead of
 * reading as detached (the same complaint driving the margin-bottom fix
 * above: excess space was making a footnote like "Or those which
 * concern one's own state of feeling" hard to place). Scoped to this
 * exact adjacency via +, not a blanket .roget-notes change -- the same
 * class also renders ordinary in-text footnotes elsewhere in the codex,
 * following paragraph content rather than a heading, where the wider
 * default spacing is correct and untouched. */
.roget-synopsis-class + .roget-notes,
.roget-synopsis-division + .roget-notes,
.roget-synopsis-section + .roget-notes,
.roget-synopsis-subsection + .roget-notes {
	margin-top: 0.15em;
	padding-top: 0.25em;
}

/* Group tiers (Classification.groups, schema v1.10.0) -- --depth-driven
 * indent, nested one step further right per depth than
 * .roget-synopsis-subsection's own indent. */
.roget-synopsis-group {
	margin: 0.15rem 0 0.15rem calc(var(--size-4-3) + var(--depth, 0) * var(--size-4-3));
}
.roget-synopsis-group-text {
	font-style: italic;
	font-size: 0.8em;
	color: var(--text-normal);
}

/* content-visibility: auto (Erick, 2026-08-03 -- testing a specific clue:
 * clipping only ever reported after scrolling, never on a row visible at
 * initial load). Without this, a very tall single scroller (1022 heads)
 * is exactly the shape of container where a browser's own internal
 * layout/paint fast-path for far-offscreen content is most likely to
 * diverge from what a fresh, on-demand layout computes -- explicitly
 * opting into the browser-native mechanism built for this (recompute
 * layout for real, correctly, right as a row nears the viewport) instead
 * of leaving that entirely to whatever undocumented heuristic the engine
 * would otherwise apply on its own. contain-intrinsic-size is only a
 * placeholder used before a row has ever been laid out once -- doesn't
 * need to be exact. */
.roget-synopsis-row {
	margin: 0.12rem 0;
	content-visibility: auto;
	contain-intrinsic-size: auto 24px;
}

/* Every classification tier -- Class, Division, Section, Subsection,
 * every groups depth -- is a plain flat sequential heading with no
 * nesting/bracket relationship to any other tier (Erick, 2026-08-02, after
 * a long sequence of label-beside-content nesting tries all ran into the
 * same problem eventually: enough cumulative depth eats enough width to
 * genuinely clip row content, confirmed at "2. Sensation" -> "(2) Heat",
 * 388 Fuel cut off mid-word in both Chrome and Safari). Only the row
 * content itself still gets special treatment -- see renderRun(). */

/* Branch headings (Class/Division/Section/Subsection) are navigable --
 * click one, jump the codex to the first entry under it -- and so is every
 * leaf item below. Headings get an underline on hover/focus; leaf items
 * (see .roget-synopsis-leaf-item below) override this with a background
 * highlight instead, since text-decoration doesn't render sensibly across
 * a flex row split into separate num/title spans. */
.roget-synopsis-navigable {
	cursor: pointer;
}
.roget-synopsis-navigable:hover,
.roget-synopsis-navigable:focus-visible {
	text-decoration: underline;
	text-underline-offset: 0.15em;
	outline: none;
}

/* A pair or one-to-many group (row.left/row.right) renders as a light
 * bordered box with a divider between its sides -- background fill
 * dropped and padding tightened in the density pass (Erick, 2026-08-01)
 * so it reads closer to a compact citation than a card; a lone unpaired
 * entry (below) is plain text, no box. */
.roget-synopsis-leaf-pair,
.roget-synopsis-leaf-group {
	display: inline-flex;
	align-items: stretch;
	border: 1px solid var(--background-modifier-border);
	border-radius: var(--radius-s);
	overflow: hidden;
}

.roget-synopsis-leaf-group {
	border-color: var(--text-accent);
}

.roget-synopsis-leaf-chip {
	display: flex;
	align-items: center;
	justify-content: center;
	writing-mode: vertical-rl;
	text-orientation: mixed;
	font-family: var(--font-monospace);
	font-size: 0.56rem;
	font-weight: var(--font-bold);
	letter-spacing: 0.03em;
	text-transform: uppercase;
	color: var(--text-on-accent);
	background: var(--text-accent);
	padding: 0.2rem 0.2rem;
}

.roget-synopsis-leaf-columns {
	display: flex;
	align-items: stretch;
}

.roget-synopsis-leaf-col {
	display: flex;
	flex-direction: column;
	justify-content: center;
}

.roget-synopsis-leaf-col > .roget-synopsis-leaf-item:not(:last-child) {
	border-bottom: 1px solid var(--background-modifier-border);
}

/* The divider between a pair's two sides gets a centered ↔; a group's
 * (3+ heads, not a simple opposite pair) doesn't claim that symmetry. */
.roget-synopsis-leaf-divider {
	position: relative;
	width: 1px;
	flex-shrink: 0;
	background: var(--background-modifier-border);
}
.roget-synopsis-leaf-pair .roget-synopsis-leaf-divider::after {
	content: "\2194";
	position: absolute;
	left: 50%;
	top: 50%;
	transform: translate(-50%, -50%);
	font-size: 0.68rem;
	line-height: 1;
	color: var(--text-normal);
	background: var(--background-secondary);
	padding: 0.1em 0.1em;
}

/* white-space was nowrap here through 2026-08-03 -- a padding-right
 * "buffer" was the only thing standing between a flex item's forced
 * full-width content and the container's true edge, and that buffer had
 * to be re-guessed bigger every time a new title/width/font-rendering
 * combination beat it (see website's own git history same day: +8px,
 * then +2em, each one an empirical patch against measurements in ONE
 * browser engine -- Safari kept finding cases Chrome's own measurements
 * never surfaced). Removed instead of widened again: with normal
 * wrapping restored, the browser's own text-layout guarantee -- content
 * cannot render past its box's edge, full stop, no engine-specific
 * font-metric variance possible -- does the job no padding guess ever
 * can. min-width: 0 defeats flexbox's own default min-width: auto, which
 * would otherwise still refuse to let this item shrink/wrap below its
 * un-wrapped content width even with wrapping re-enabled (the other half
 * of the classic flex-overflow gotcha). See .roget-synopsis-leaf-title's
 * overflow-wrap for the belt-and-suspenders case (no natural space to
 * break on at all). */
.roget-synopsis-leaf-item {
	display: flex;
	align-items: baseline;
	gap: 0.3em;
	padding: 0.08rem 0.4rem;
	min-width: 0;
}
.roget-synopsis-leaf-item.roget-synopsis-navigable:hover,
.roget-synopsis-leaf-item.roget-synopsis-navigable:focus-visible {
	background: var(--background-modifier-hover);
	text-decoration: none;
	outline: none;
}

.roget-synopsis-leaf-num {
	font-family: var(--font-monospace);
	font-variant-numeric: tabular-nums;
	font-size: 0.7em;
	color: var(--text-normal);
	/* Short and shouldn't ever need to wrap on its own, unlike the title
	 * next to it (see .roget-synopsis-leaf-item's own comment). */
	white-space: nowrap;
}

.roget-synopsis-leaf-title {
	font-size: 0.85em;
	/* Belt-and-suspenders for the (rare) title with no natural space to
	 * wrap at all before the container's edge -- breaks mid-word rather
	 * than overflow, only as a last resort past normal space-based
	 * wrapping. */
	overflow-wrap: anywhere;
	min-width: 0;
}

/* A run of consecutive unpaired entries -- no box, just plain text,
 * flowing and wrapping like a paragraph instead of one stacked line per
 * entry (Erick, 2026-08-01: "let strings of unpaired categories have only
 * one row... and let the string wrap"). A run of exactly one entry looks
 * the same as the old always-its-own-row treatment (.leaf.lone in the
 * "Roget 1911 -- Classification & Pairing Proof" artifact this whole
 * display was styled after). */
/* Now holds a mix of plain leaf items AND cartouche boxes (Erick,
 * 2026-08-02 -- paired rows joined the same wrapping run instead of each
 * getting its own line), so alignment is by baseline, not stretch (a
 * cartouche's border/padding makes it taller than a bare item). The muted
 * styling below targets DIRECT children only (`>`), not a descendant
 * selector -- a cartouche's own inner leaf-items (see
 * .roget-synopsis-leaf-col below) must keep their normal, unmuted
 * treatment; a plain descendant selector would incorrectly bleed into
 * them too. */
.roget-synopsis-leaf-run {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	row-gap: 0.15rem;
	column-gap: 0.9rem;
}
.roget-synopsis-leaf-run > .roget-synopsis-leaf-item {
	padding: 0.08rem 0.1rem;
	color: var(--text-normal);
}

.roget-row {
	display: flex;
	align-items: flex-start;
	width: 100%;
}

.roget-row-placeholder {
	width: 100%;
}

/* Paired rows: two columns with a genuine gutter between them */
.roget-row-paired {
	gap: 0;
}

.roget-cell {
	flex: 1 1 0;
	min-width: 0;
	padding: var(--size-4-3) var(--size-4-4);
}

.roget-cell-left {
	text-align: left;
	border-right: none;
}

.roget-cell-right {
	text-align: left;
}

.roget-gutter {
	flex: 0 0 auto;
	width: 2px;
	align-self: stretch;
	background: var(--background-modifier-border);
	margin: var(--size-4-3) 0;
}

/* Single-column layout: antonym pairs stack instead of sitting side by
 * side (a narrow sidebar reads better this way than the print-edition
 * facing-column arrangement). Same DOM as the two-column layout — only
 * the flex direction and the gutter's orientation change. */
/* Two-column paired rows use FLOAT, not flex: the print's own device is
 * that when one of a paired entry ends, the other goes from double- to
 * single-column for its remainder. Flex and grid items are rectangles, so
 * the longer one can never reclaim the shorter's width below it; a float
 * is the primitive that does exactly this. The browser then reflows on any
 * content change for free — toggling a compressed group to stacked braces
 * makes its cell taller and the facing text re-wraps at the new boundary
 * with no measurement code. Only ONE thing needs measuring, in
 * codexView.layoutFloatRow: which side is currently shorter. */
.roget-row-paired.is-float {
	display: block;
}

.roget-row-paired.is-float::after {
	content: "";
	display: block;
	clear: both;
}

.roget-row-paired.is-float > .roget-gutter {
	display: none;
}

.roget-row-paired.is-float > .roget-cell {
	width: auto;
	float: none;
}

.roget-row-paired.is-float > .roget-cell.is-floated {
	width: calc(50% - var(--size-4-2));
	/* A blend against the pane's own foreground color, not a second named
	 * background token -- the codex opens in the sidebar by default
	 * (settings.openCodexInSidebar), where --background-secondary can
	 * already BE the ambient ground, making a token-vs-token tint
	 * invisible by coincidence. Blending text-normal into transparent
	 * darkens on a light ground and lightens on a dark one automatically,
	 * regardless of which pane or theme it's sitting in. */
	background: color-mix(in srgb, var(--text-normal) 6%, transparent);
	border-radius: var(--radius-s);
}

.roget-row-paired.is-float > .roget-cell-left.is-floated {
	float: left;
	margin-right: var(--size-4-3);
}

.roget-row-paired.is-float > .roget-cell-right.is-floated {
	float: right;
	margin-left: var(--size-4-3);
}

/* Measurement pass: both halves side by side and neither floated, so the
 * heights compared are the ones the two-column stretch would really have. */
.roget-row-paired.is-measuring {
	display: flex;
	align-items: flex-start;
}

.roget-row-paired.is-measuring > .roget-cell {
	flex: 1 1 0;
	float: none;
	width: auto;
}

.roget-row-paired.is-measuring > .roget-gutter {
	display: none;
}

.roget-single-column .roget-row-paired {
	flex-direction: column;
}

.roget-single-column .roget-gutter {
	width: auto;
	height: 2px;
	align-self: stretch;
}

/* Title page: a cropped scan, shown once above the codex's first
 * classification heading. Left at its own scanned paper tone rather than
 * matched to the pane's theme -- it's a photograph of a physical page,
 * not UI chrome, and that's as true in a dark-themed vault as a light
 * one. The shadow is what grounds it against either background. */
.roget-titlepage {
	display: flex;
	justify-content: center;
	margin: 0 0 var(--size-4-6);
}

.roget-titlepage-img {
	display: block;
	width: 100%;
	max-width: 30rem;
	height: auto;
	border-radius: 2px;
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}

/* Unpaired rows: full width, narrower centered measure, visibly distinct */
.roget-row-unpaired {
	justify-content: center;
	padding: var(--size-4-2) 0;
}

.roget-cell-full {
	max-width: 42em;
	width: 100%;
	padding: var(--size-4-3) var(--size-4-4);
	background: var(--background-secondary);
	border-radius: var(--radius-s);
}

/* Head block */
.roget-head {
	margin-bottom: var(--size-4-3);
}

.roget-head:last-child {
	margin-bottom: 0;
}

.roget-head-heading {
	display: flex;
	flex-wrap: wrap;
	align-items: baseline;
	gap: 0.35em;
	margin-bottom: 0.25em;
}

/* Click to add this head to the navigation-history breadcrumb trail
 * (CodexView.setupHeadTitleNavigation()) -- background highlight, not
 * underline, since .roget-head-heading is a flex row split into several
 * separate spans (id/glosses/title) and text-decoration doesn't render
 * sensibly across that split (same reasoning as the synopsis pane's own
 * leaf items). */
.roget-head-heading-navigable {
	cursor: pointer;
	border-radius: var(--radius-s);
}
.roget-head-heading-navigable:hover,
.roget-head-heading-navigable:focus-visible {
	background: var(--background-modifier-hover);
	outline: none;
}

.roget-head-id {
	font-variant-numeric: tabular-nums;
	color: var(--text-normal);
	font-size: 1.05em;
}

.roget-head-title {
	font-weight: var(--font-bold);
	font-size: 1.05em;
}

.roget-head-title-part + .roget-head-title-part::before {
	content: ". ";
}

.roget-head-gloss {
	color: var(--text-normal);
	font-style: italic;
	font-size: 0.92em;
}

/* Erick's flagged-categories feature (2026-08-03) -- one extra bracketed
 * note after the title on the ~54 heads in data/contentWarnings.ts.
 * Same muted-italic treatment as .roget-head-gloss above, plus the usual
 * navigable cursor/hover-underline since clicking opens the Content Note
 * tab (CodexView's delegated click handler). */
.roget-head-content-warning {
	color: var(--text-normal);
	font-style: italic;
	font-size: 0.92em;
}
.roget-head-content-warning::before {
	content: "[";
}
.roget-head-content-warning::after {
	content: "]";
}
.roget-content-warning-navigable {
	cursor: pointer;
}
.roget-content-warning-navigable:hover,
.roget-content-warning-navigable:focus-visible {
	color: var(--text-normal);
	text-decoration: underline;
	text-underline-offset: 0.15em;
	outline: none;
}

/* POS sections */
.roget-section {
	margin-top: 0.5em;
}

.roget-section-label {
	font-weight: var(--font-bold);
	margin-bottom: 0.15em;
}

.roget-group-note {
	font-style: italic;
	color: var(--text-normal);
}

.roget-group-note::before {
	content: "[";
}

.roget-group-note::after {
	content: "]";
}

.roget-paragraph {
	margin: 0 0 0.35em 0;
	padding-left: 1em;
	text-indent: -1em;
}

.roget-paragraph:last-child {
	margin-bottom: 0;
}

/* Word / xref items */
.roget-word-note {
	color: var(--text-normal);
	font-size: 0.9em;
}

.roget-word-note::before {
	content: "[";
}

.roget-word-note::after {
	content: "]";
}

.roget-word-gloss {
	color: var(--text-normal);
}

.roget-word-gloss::before {
	content: "(";
}

.roget-word-gloss::after {
	content: ")";
}

/* Footnotes */
.roget-marker-ref {
	vertical-align: super;
	font-size: 0.7em;
	color: var(--text-normal);
}

.roget-notes {
	margin-top: 0.5em;
	padding-top: 0.35em;
	border-top: 1px solid var(--background-modifier-border);
}

.roget-footnote {
	font-size: 0.9em;
	color: var(--text-normal);
}

.roget-footnote-part {
	margin: 0 0 0.25em 0;
}

.roget-footnote-part:last-child {
	margin-bottom: 0;
}

.roget-footnote-marker {
	font-weight: var(--font-bold);
}

.roget-word-italic {
	font-style: italic;
}

.roget-xref-pos {
	font-style: italic;
}

.roget-xref-clickable {
	color: var(--text-accent);
	cursor: pointer;
}

.roget-xref-clickable:hover {
	text-decoration: underline;
}

.roget-xref-clickable:focus-visible {
	outline: 2px solid var(--interactive-accent);
	outline-offset: 1px;
	border-radius: var(--radius-s);
}

/* Highlight for jump-to-head / lookup navigation */
.roget-highlight {
	animation: roget-highlight-fade 2s ease-out;
}

@keyframes roget-highlight-fade {
	from {
		background-color: var(--text-highlight-bg);
	}
	to {
		background-color: transparent;
	}
}

/* Classification footer: a fixed bar below the scroller (not part of the
 * scrolling area, so it never overlaps row content), content updated by
 * CodexView as the reader scrolls past class/section boundaries. */
.roget-footer {
	flex: 0 0 auto;
	background: var(--background-primary);
	border-top: 1px solid var(--background-modifier-border);
	padding: var(--size-4-1) var(--size-4-2);
	font-size: 0.8em;
	color: var(--text-normal);
}

/* Clickable, same destination as the nav-bar's own synopsis button
 * (CodexView wires both to openSynopsis()). */
.roget-footer-navigable {
	cursor: pointer;
}
.roget-footer-navigable:hover,
.roget-footer-navigable:focus-visible {
	color: var(--text-normal);
	text-decoration: underline;
	text-underline-offset: 0.15em;
	outline: none;
}

/* Modals */
.roget-lookup-result {
	display: flex;
	flex-direction: column;
	gap: 0.1em;
}

.roget-lookup-result-word {
	font-weight: var(--font-semibold);
}

.roget-lookup-result-meta {
	font-size: 0.85em;
	font-style: italic;
	color: var(--text-normal);
}

.roget-flag-selected-text {
	color: var(--text-normal);
	font-style: italic;
}

.roget-loading-notice {
	color: var(--text-normal);
	font-style: italic;
}

/* ---------------------------------------------------------------------
 * Compressed groups (schema v1.5.0 `matrix` items). The print's dash
 * shorthand kept as the paradigm it encodes; four display modes generated
 * from the same stored structure. See plugin/GROUP_DISPLAY_BRIEF.md.
 * ------------------------------------------------------------------ */

.roget-matrix {
	cursor: pointer;
	border-radius: 3px;
	/* text-indent inherits, and .roget-paragraph's hanging indent would
	 * otherwise reach the stacked brace groups below -- each stacked
	 * alternative is its own flex item (a block-level box), so it would
	 * pick up that indent independently on its own first line, shoving it
	 * sideways into whatever precedes it. Reset once at the matrix's own
	 * boundary rather than patching every nested piece. */
	text-indent: 0;
}

.roget-matrix:hover {
	background: var(--background-modifier-hover);
}

.roget-matrix-source {
	color: var(--text-normal);
}

/* The hyphen itself always prints at a non-spaced seam (see render.ts) --
 * this is an extra marker for the few seams where the FLATTENED spelling
 * is still undecided (hyphen vs. nothing), not for the hyphen glyph shown
 * here, which is never in doubt. */
.roget-matrix-join.is-tight {
	border-bottom: 1px dotted var(--text-normal);
}

.roget-matrix-alt-empty {
	color: var(--text-normal);
}

/* Braces are drawn with borders rather than typed as "{": a real curly
 * brace does not scale to an arbitrary stack height, and a bordered
 * bracket does, at any number of alternatives. */
.roget-matrix-stack {
	display: inline-flex;
	align-items: center;
	vertical-align: middle;
}

.roget-matrix-brace {
	align-self: stretch;
	width: 0.3em;
	border: 1px solid var(--text-normal);
	flex: 0 0 auto;
}

.roget-matrix-brace-left {
	border-right: none;
	border-radius: 0.35em 0 0 0.35em;
	margin-right: 0.15em;
}

.roget-matrix-brace-right {
	border-left: none;
	border-radius: 0 0.35em 0.35em 0;
	margin-left: 0.15em;
}

.roget-matrix-stack.is-stacked .roget-matrix-alts {
	display: inline-flex;
	flex-direction: column;
	line-height: 1.25;
}

/* --- PDF view (own PDF.js render surface, replaces Obsidian's built-in
   viewer -- see PdfView/PdfPane) --------------------------------------- */

.roget-pdf-container {
	height: 100%;
	overflow: hidden;
	display: flex;
	flex-direction: column;
	background: var(--background-secondary);
}

.roget-pdf-scroller {
	flex: 1 1 auto;
	overflow-y: auto;
	display: flex;
	flex-direction: column;
	align-items: center;
}

.roget-pdf-page {
	margin: 12px auto;
	background: #fff;
	box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
	flex: 0 0 auto;
}

.roget-pdf-page canvas {
	display: block;
	width: 100%;
	height: 100%;
}

/* First-visit tour (tour.ts) -- a dismissable modal, four mock-up beats
 * cycling automatically. Backdrop sits above everything else on the
 * page, including --layer-popover (60, styles.css's own highest z-index
 * before this), since it's meant to eclipse the whole app while open. */
.roget-tour-backdrop {
	position: fixed;
	inset: 0;
	background: rgba(0, 0, 0, 0.5);
	display: flex;
	align-items: center;
	justify-content: center;
	z-index: 500;
	padding: var(--size-4-4);
}

.roget-tour-modal {
	position: relative;
	width: 100%;
	max-width: 26em;
	background: var(--background-primary);
	border-radius: var(--radius-s);
	box-shadow: 0 4px 24px rgba(0, 0, 0, 0.35);
	padding: var(--size-4-6) var(--size-4-4) var(--size-4-4);
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--size-4-4);
}

.roget-tour-close {
	position: absolute;
	top: var(--size-4-2);
	right: var(--size-4-2);
	background: transparent;
	border: none;
	box-shadow: none;
	cursor: pointer;
	font-size: 1.3em;
	line-height: 1;
	color: var(--text-muted);
	padding: var(--size-4-1);
	border-radius: var(--radius-s);
}

.roget-tour-close:hover {
	background: var(--background-modifier-hover);
	color: var(--text-normal);
}

/* Fixed height so switching beats never resizes the modal around the
 * reader -- each mock-up centers within whatever room this leaves. */
.roget-tour-stage {
	width: 100%;
	min-height: 9em;
	display: flex;
	align-items: center;
	justify-content: center;
}

.roget-tour-caption {
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
	font-size: 1.05em;
	font-weight: var(--font-semibold);
	color: var(--text-normal);
	text-align: center;
}

.roget-tour-controls {
	display: flex;
	align-items: center;
	justify-content: center;
	gap: var(--size-4-4);
}

.roget-tour-nav-btn {
	background: transparent;
	border: none;
	box-shadow: none;
	cursor: pointer;
	font-size: 1.4em;
	line-height: 1;
	color: var(--text-muted);
	padding: var(--size-4-1) var(--size-4-2);
	border-radius: var(--radius-s);
}

.roget-tour-nav-btn:hover {
	background: var(--background-modifier-hover);
	color: var(--text-normal);
}

.roget-tour-dots {
	display: flex;
	align-items: center;
	gap: var(--size-4-2);
}

/* The visible dot is a fixed-size ::before, not the button's own
 * background -- tried making the BUTTON itself the dot first (sized 8px,
 * padded out to a larger box on touch with background-clip:content-box
 * to keep the paint at the original 8px), but background is a shorthand
 * that implicitly resets background-clip to initial wherever else it's
 * set, and .is-active sets `background` too -- whichever of the two
 * rules setting background-clip won the cascade for that property
 * specifically (not the same as winning the whole declaration block)
 * depended on specificity/source order in a way that silently broke
 * either the active dot (painted the full padded box, one big blob) or
 * the inactive ones (vanished outright). A ::before decoupled from the
 * button's own box entirely sidesteps all of that -- the button can
 * grow to any size on touch (below) and the dot stays exactly 8px,
 * centered, always. */
.roget-tour-dot {
	position: relative;
	width: 8px;
	height: 8px;
	padding: 0;
	border: none;
	background: transparent;
	cursor: pointer;
}
.roget-tour-dot::before {
	content: "";
	position: absolute;
	top: 50%;
	left: 50%;
	width: 8px;
	height: 8px;
	transform: translate(-50%, -50%);
	border-radius: 50%;
	background-color: var(--text-faint);
}
.roget-tour-dot.is-active::before {
	background-color: var(--interactive-accent);
}

/* Stage 5's own check turned up a stage-4-shaped gap tour.ts's separate
 * button family (close/prev-next/dots/skip) never got: its own comment
 * scoped that pass to .roget-nav-btn/.roget-side-tab, the main site
 * chrome, and didn't touch the tour's own controls -- but the tour is
 * the very first thing a phone visitor sees, and deserves the same
 * comfort. Same #divider technique (index.html) for the dots
 * specifically -- a small VISIBLE dot with a larger invisible hit zone
 * around it, rather than growing the dot itself and losing the tight
 * row of four it currently reads as. */
@media (hover: none) {
	.roget-tour-close,
	.roget-tour-nav-btn,
	.roget-tour-skip {
		min-width: 44px;
		min-height: 44px;
		display: flex;
		align-items: center;
		justify-content: center;
	}
	.roget-tour-dot {
		width: 32px;
		height: 32px;
	}
}

.roget-tour-skip {
	background: transparent;
	border: none;
	box-shadow: none;
	cursor: pointer;
	color: var(--text-muted);
	font-size: 0.9em;
	padding: var(--size-4-1);
}

.roget-tour-skip:hover {
	color: var(--text-normal);
	text-decoration: underline;
}

/* Beats 1-2: mock tab strip, pointing at whichever tab this beat names */
.roget-tour-tabbar {
	display: flex;
	flex-wrap: wrap;
	justify-content: center;
	gap: var(--size-4-2);
	max-width: 100%;
}

.roget-tour-tab {
	position: relative;
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
	font-size: 0.8em;
	padding: var(--size-4-1) var(--size-4-2);
	border-radius: var(--radius-s);
	background: var(--background-secondary);
	color: var(--text-muted);
}

.roget-tour-tab-target {
	background: var(--text-highlight-bg);
	color: var(--text-normal);
	font-weight: var(--font-semibold);
}

.roget-tour-tab-arrow {
	position: absolute;
	top: 100%;
	left: 50%;
	transform: translateX(-50%);
	color: var(--interactive-accent);
	font-size: 0.9em;
	line-height: 1;
	animation: roget-tour-bounce 1.2s ease-in-out infinite;
}

@keyframes roget-tour-bounce {
	0%, 100% { transform: translate(-50%, 0); }
	50% { transform: translate(-50%, 3px); }
}

/* Beat 3: mock nav bar -- toggle button + collapsible panel + codex */
.roget-tour-navmock {
	display: flex;
	align-items: stretch;
	gap: var(--size-4-2);
	width: 12em;
	height: 5em;
}

.roget-tour-navmock-btn {
	flex: 0 0 auto;
	align-self: center;
	display: flex;
	align-items: center;
	justify-content: center;
	width: 1.6em;
	height: 1.6em;
	border-radius: var(--radius-s);
	background: var(--background-modifier-hover);
	color: var(--text-muted);
	font-size: 0.85em;
}

.roget-tour-navmock-panel {
	flex: 0 0 auto;
	width: 4.5em;
	overflow: hidden;
	background: var(--background-secondary);
	border-radius: var(--radius-s);
	padding: var(--size-4-2);
	display: flex;
	flex-direction: column;
	justify-content: center;
	gap: var(--size-4-2);
	transition: width 0.5s ease, opacity 0.5s ease, padding 0.5s ease;
}

.roget-tour-navmock-panel.is-collapsed {
	width: 0;
	opacity: 0;
	padding-left: 0;
	padding-right: 0;
}

.roget-tour-navmock-panel-line {
	height: 6px;
	border-radius: 3px;
	background: var(--text-faint);
}

.roget-tour-navmock-codex {
	flex: 1 1 auto;
	background: var(--background-secondary);
	border-radius: var(--radius-s);
	opacity: 0.5;
}

/* Beat 4: mock compressed group, cycling Stack/Inline/Flat/1911 */
.roget-tour-matrixmock {
	display: flex;
	flex-direction: column;
	align-items: center;
	gap: var(--size-4-3);
}

.roget-tour-matrixmock-phrase {
	font-family: var(--roget-body-font, var(--font-text));
	font-size: 1.2em;
	text-align: center;
	color: var(--text-normal);
	min-height: 3.6em;
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
}

.roget-tour-matrixmock-phrase.is-braced {
	font-style: italic;
	color: var(--text-muted);
}

.roget-tour-matrixmock-label {
	font-family: var(--roget-display-font, var(--roget-body-font, var(--font-text)));
	font-size: 0.75em;
	font-weight: var(--font-semibold);
	text-transform: uppercase;
	letter-spacing: 0.04em;
	color: var(--text-on-accent);
	background: var(--interactive-accent);
	padding: 2px var(--size-4-2);
	border-radius: var(--radius-s);
}

/* Phone-only "opening the book" splash (splashScreen.ts) -- shows on
 * every visit, not gated by localStorage the way the tour is. z-index
 * higher than the tour's own 500: in practice the two never overlap
 * (main.ts awaits the splash's own dismissal before the tour's
 * first-visit check ever runs), but if that ordering ever changes, the
 * splash should still win -- it's the very first thing on screen, not
 * a later interruption. */
.roget-splash {
	position: fixed;
	inset: 0;
	z-index: 600;
	display: flex;
	align-items: center;
	justify-content: center;
	background: var(--background-primary);
	padding: var(--size-4-6);
	cursor: pointer;
	opacity: 1;
	transition: opacity 0.4s ease;
}

.roget-splash.is-fading {
	opacity: 0;
}

.roget-splash-img {
	max-width: 100%;
	max-height: 100%;
	object-fit: contain;
	box-shadow: 0 4px 24px rgba(0, 0, 0, 0.25);
}
