/* Bundled Fantasque Sans Mono — a programming font with built-in
   coding ligatures (==, !=, =>, ->, …), distributed under the SIL
   Open Font License 1.1 (see `assets/fonts/fantasque-sans-mono/
   LICENSE.txt`). Bundling lets the IDE render the same way on every
   machine instead of falling back to whatever monospace font the
   host happens to ship. We only carry the four `.woff2` weights —
   modern WebKit (which Tauri uses) reads woff2 natively, so the
   .woff / .ttf / .svg fallbacks the upstream `*-decl.css` snippets
   include aren't needed. `font-display: swap` is irrelevant for
   files this small served off-disk by Tauri, but it costs nothing
   and protects against the (rare) case where a slow first paint
   would otherwise FOIT. */
@font-face {
	font-family: 'Fantasque Sans Mono';
	src: url('./assets/fonts/fantasque-sans-mono/FantasqueSansMono-Regular.woff2') format('woff2');
	font-weight: 400;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Fantasque Sans Mono';
	src: url('./assets/fonts/fantasque-sans-mono/FantasqueSansMono-Italic.woff2') format('woff2');
	font-weight: 400;
	font-style: italic;
	font-display: swap;
}
@font-face {
	font-family: 'Fantasque Sans Mono';
	src: url('./assets/fonts/fantasque-sans-mono/FantasqueSansMono-Bold.woff2') format('woff2');
	font-weight: 700;
	font-style: normal;
	font-display: swap;
}
@font-face {
	font-family: 'Fantasque Sans Mono';
	src: url('./assets/fonts/fantasque-sans-mono/FantasqueSansMono-BoldItalic.woff2') format('woff2');
	font-weight: 700;
	font-style: italic;
	font-display: swap;
}

/* Theme tokens. Override in light mode by toggling the `.light` class on :root. */
:root {
	/* Tells the user agent which palette to use for *native* widgets
	   (the `<select>` dropdown menu, scrollbars, form-control chrome,
	   the focus-ring color). Without it WebKitGTK renders form
	   controls with the OS-default light skin even when our CSS
	   paints everything dark around them — the symptom is a glaring
	   white `<select>` field in dark mode. Flipped in `:root.light`
	   below. */
	color-scheme: dark;

	/* Surfaces */
	--m-bg: #0d1017;
	--m-bg-1: #11151f;
	--m-bg-2: #161c2a;
	--m-bg-3: #1c2436;
	--m-bg-overlay: rgba(255, 255, 255, 0.03);
	--m-border: #232a3d;
	--m-border-strong: #313a52;

	/* Text */
	--m-fg: #d6dcec;
	--m-fg-muted: #8a93ab;
	--m-fg-subtle: #5a6480;

	/* Accents */
	--m-accent: #7ea3ff;
	--m-accent-strong: #a8c0ff;
	--m-success: #5fd6a3;
	--m-warning: #f0b86e;
	--m-danger: #ff7a8a;

	/* Workspace identity tint (ADR 0047). Alias of `--m-accent` for
	   surfaces whose job is workspace identity (folder bar, active
	   tab, status-bar stripe) as opposed to generic interactivity —
	   both resolve to the workspace-derived accent at runtime, but
	   the separate name keeps a future "decouple identity from
	   interactive accent" change to a one-line edit. */
	--m-ws-accent: var(--m-accent);
	--m-ws-accent-soft: rgba(126, 163, 255, 0.22);

	/* Inline code accent — used by chat / Slack messages only.
	   Distinct from `--m-fg` so `\`code\`` reads as a token at a
	   glance; matches Slack's soft pink-red pill. The Markdown
	   viewer keeps a neutral surface, so this token is intentionally
	   not pulled in there. */
	--m-code-fg: #ffadc7;
	--m-code-bg: rgba(255, 173, 199, 0.12);
	--m-code-border: rgba(255, 173, 199, 0.25);

	/* Editor */
	--m-editor-bg: var(--m-bg);
	--m-editor-gutter: var(--m-fg-subtle);
	--m-editor-selection: rgba(126, 163, 255, 0.18);
	--m-editor-line-active: rgba(255, 255, 255, 0.025);

	/* Syntax highlighting tokens. The CodeMirror HighlightStyle is
	   defined once and resolves these via `var(...)`, so flipping
	   `:root.light` re-skins the editor without touching JS. Names map
	   to broad token families; we collapse close cousins (e.g. integer
	   / float / bool all hit `--m-syntax-number`) on purpose — the
	   palette stays readable. The Lezer tag → var mapping lives in
	   `editor/theme.ts`. */
	--m-syntax-comment: #6a7490;
	--m-syntax-keyword: #c792ea;
	--m-syntax-string: #a3e9a4;
	--m-syntax-number: #f0b86e;
	--m-syntax-function: #7ea3ff;
	--m-syntax-type: #5fd6a3;
	--m-syntax-property: #a8c0ff;
	--m-syntax-attribute-value: #a3e9a4;
	--m-syntax-tag: #ff7a8a;
	--m-syntax-constant: #f0b86e;
	--m-syntax-operator: #8a93ab;
	--m-syntax-regexp: #ffadc7;
	--m-syntax-meta: #8a93ab;
	--m-syntax-link: #7ea3ff;
	--m-syntax-heading: #d6dcec;
	--m-syntax-invalid: #ff7a8a;
	--m-syntax-inserted: #5fd6a3;
	--m-syntax-deleted: #ff7a8a;
	--m-syntax-changed: #f0b86e;

	/* Pierre Trees tokens. The lib reads `--trees-*-override` CSS vars on the
	   host element and forwards them into its shadow root. Names per the
	   @pierre/trees README; see also `--trees-theme-*` for the second set. */
	--trees-bg-override: var(--m-bg-1);
	--trees-fg-override: var(--m-fg);
	--trees-fg-muted-override: var(--m-fg-muted);
	--trees-bg-muted-override: var(--m-bg-overlay);
	--trees-search-bg-override: var(--m-bg-2);
	--trees-search-fg-override: var(--m-fg);
	--trees-selected-bg-override: rgba(126, 163, 255, 0.18);
	--trees-selected-fg-override: var(--m-fg);
	--trees-selected-focused-border-color-override: var(--m-accent);
	--trees-border-color-override: var(--m-border);
	--trees-focus-ring-color-override: var(--m-accent);
	/* Tighten the tree's outer left/right inset. Pierre's default
	   is 16px, which leaves a wide empty gutter to the left of
	   every row in our narrow sidebar; 6px keeps the focus ring
	   from clipping against the sidebar edge while reclaiming
	   ~20px of horizontal space for filenames. */
	--trees-padding-inline-override: 6px;

	--m-font-ui: -apple-system, 'Inter', system-ui, 'Segoe UI', Roboto, sans-serif;
	/* Fantasque Sans Mono is bundled (see the `@font-face` block at
	   the top of this file), so the first family in the stack is
	   guaranteed to load. The remaining fallbacks stay as a safety
	   net for any future host without webfont support. */
	--m-font-mono:
		'Fantasque Sans Mono', 'JetBrains Mono', 'Fira Code', ui-monospace, 'SF Mono', Menlo, Consolas, monospace;

	/* Activate the contextual-alternates OpenType feature globally
	   so Fantasque Sans Mono's coding ligatures (`==`, `!=`, `=>`,
	   `->`, `<=`, `>=`, `<-`, `|>`, `<>`, `::`, …) actually render
	   on every surface that pulls `var(--m-font-mono)`. Without
	   `calt` enabled, the glyphs sit on separate ems and read as
	   the individual characters. `font-feature-settings` inherits,
	   so setting it on `:root` cascades through every descendant
	   that doesn't override it — Inter and the system-ui fallbacks
	   define no `calt` substitutions so it's a no-op for the UI
	   font, which lets us avoid touching every component CSS.
	   `liga` is on by default in browsers, so we don't list it. */
	font-feature-settings: 'calt' 1;
}

:root.light {
	color-scheme: light;
	/* Workspace scheme light variants (ADR 0047): every token the
	   workspace generator writes has a `*-light` twin; the light
	   values below are the pre-hydrate fallbacks matching the
	   generator's defaults. `--m-ws-accent` needs no remap — it
	   aliases `--m-accent`, which is remapped like everything
	   else. */
	--m-bg: var(--m-bg-light, #fafbfd);
	--m-bg-1: var(--m-bg-1-light, #f1f3f8);
	--m-bg-2: var(--m-bg-2-light, #e9edf5);
	--m-bg-3: var(--m-bg-3-light, #dde2ee);
	--m-bg-overlay: var(--m-bg-overlay-light, rgba(0, 0, 0, 0.04));
	--m-border: var(--m-border-light, #d6dbe6);
	--m-border-strong: var(--m-border-strong-light, #b8c0d2);
	--m-fg: var(--m-fg-light, #16192a);
	--m-fg-muted: var(--m-fg-muted-light, #5e6885);
	--m-fg-subtle: var(--m-fg-subtle-light, #8a93ab);
	--m-accent: var(--m-accent-light, #4360c8);
	--m-accent-strong: var(--m-accent-strong-light, #2a3fa1);
	--m-warning: var(--m-warning-light, #b45309);
	--m-editor-selection: var(--m-editor-selection-light, rgba(67, 96, 200, 0.15));
	--m-ws-accent-soft: var(--m-ws-accent-soft-light, rgba(67, 96, 200, 0.16));
	--m-editor-bg: var(--m-bg);
	--m-editor-line-active: rgba(0, 0, 0, 0.02);
	--m-code-fg: #c7254e;
	--m-code-bg: rgba(199, 37, 78, 0.08);
	--m-code-border: rgba(199, 37, 78, 0.18);

	--m-syntax-comment: #8a93ab;
	--m-syntax-keyword: #7c3aed;
	--m-syntax-string: #1f7a3a;
	--m-syntax-number: #a8470c;
	--m-syntax-function: #2a3fa1;
	--m-syntax-type: #0b6b56;
	--m-syntax-property: #4360c8;
	--m-syntax-attribute-value: #1f7a3a;
	--m-syntax-tag: #a3204e;
	--m-syntax-constant: #a8470c;
	--m-syntax-operator: #5e6885;
	--m-syntax-regexp: #c7254e;
	--m-syntax-meta: #5e6885;
	--m-syntax-link: #2a3fa1;
	--m-syntax-heading: #16192a;
	--m-syntax-invalid: #a3204e;
	--m-syntax-inserted: #0b6b56;
	--m-syntax-deleted: #a3204e;
	--m-syntax-changed: #a8470c;
}

* {
	box-sizing: border-box;
}

html,
body,
#app {
	margin: 0;
	padding: 0;
	height: 100%;
	width: 100%;
	background: var(--m-bg);
	color: var(--m-fg);
	font-family: var(--m-font-ui);
	font-size: 13px;
	line-height: 1.4;
	-webkit-font-smoothing: antialiased;
	text-rendering: optimizeLegibility;
}

button {
	font: inherit;
	color: inherit;
	background: transparent;
	border: 1px solid transparent;
	border-radius: 4px;
	padding: 4px 10px;
	cursor: pointer;
	/* Button labels are not content; click-dragging across them to "select"
	   is always a misclick. Killing it globally is simpler than per-button. */
	user-select: none;
}

button:hover {
	background: var(--m-bg-overlay);
}

button:focus-visible {
	outline: 1px solid var(--m-accent);
	outline-offset: 1px;
}

::-webkit-scrollbar {
	width: 10px;
	height: 10px;
}
::-webkit-scrollbar-track {
	background: transparent;
}
::-webkit-scrollbar-thumb {
	background: var(--m-border);
	border-radius: 5px;
}
::-webkit-scrollbar-thumb:hover {
	background: var(--m-border-strong);
}

/* Shared rendered-Markdown styles.
 *
 * Used by the `.md` file viewer (`MarkdownView.svelte`) and the LSP
 * hover popover (`editor/lsp.ts`, built via DOM APIs). Both mount
 * sanitised HTML inside an element with class `markdown-body` and
 * inherit this stylesheet. Keeping the styles global (not scoped to
 * the Svelte component) is what lets the hover popover share them
 * without duplicating CSS — it's not a Svelte component, it's a
 * CodeMirror tooltip. */
.markdown-body {
	font-family: var(--m-font-ui);
	line-height: 1.6;
	color: var(--m-fg);
}
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
	margin: 1.6em 0 0.6em;
	line-height: 1.25;
	font-weight: 600;
}
.markdown-body h1:first-child,
.markdown-body h2:first-child,
.markdown-body h3:first-child {
	margin-top: 0;
}
.markdown-body h1 {
	font-size: 1.8em;
	border-bottom: 1px solid var(--m-border);
	padding-bottom: 0.3em;
}
.markdown-body h2 {
	font-size: 1.4em;
	border-bottom: 1px solid var(--m-border);
	padding-bottom: 0.25em;
}
.markdown-body h3 {
	font-size: 1.2em;
}
.markdown-body p,
.markdown-body ul,
.markdown-body ol,
.markdown-body blockquote,
.markdown-body table {
	margin: 0.6em 0;
}
.markdown-body ul,
.markdown-body ol {
	padding-left: 1.6em;
}
.markdown-body li + li {
	margin-top: 0.2em;
}
.markdown-body code {
	font-family: var(--m-font-mono);
	font-size: 0.92em;
	background: var(--m-bg-overlay);
	padding: 0.15em 0.35em;
	border-radius: 3px;
}
.markdown-body pre {
	background: var(--m-bg-1);
	border: 1px solid var(--m-border);
	border-radius: 4px;
	padding: 12px 14px;
	overflow-x: auto;
	margin: 0.8em 0;
	font-family: var(--m-font-mono);
	font-size: 0.9em;
	line-height: 1.5;
	/* Render literal tabs at two columns. The default 8 columns
	   is hostile to the kind of tightly-indented code the model
	   tends to paste back at the user, and our own house style
	   (ADR 0004) is two columns for display anyway — `.editorconfig`
	   pins the editor display width to 2; this is the analogous
	   knob for rendered markdown. */
	-moz-tab-size: 2;
	tab-size: 2;
}
.markdown-body pre code {
	background: transparent;
	padding: 0;
	font-size: inherit;
}
/* Fenced code blocks are wrapped by `applyFenceCopyRule` in
   `markdown.ts` so a hover-revealed "Copy" button can sit in the
   top-right corner. The wrapper is `position: relative` so the
   button is anchored to the block edge regardless of the block's
   own padding; the button is `position: absolute` so wide blocks
   that scroll horizontally don't shove the button off-screen. The
   `<pre>` keeps its own margin (`0.8em 0` above) — the wrapper
   inherits no extra spacing of its own so the rendered layout
   matches the previous bare-`<pre>` shape exactly. */
.markdown-body .md-code-block {
	position: relative;
}
.markdown-body .md-code-block > pre {
	margin: 0.8em 0;
}
.markdown-body .md-copy-code {
	position: absolute;
	top: 6px;
	right: 6px;
	padding: 2px 8px;
	font: inherit;
	font-size: 11px;
	color: var(--m-fg-muted);
	/* Solid panel-bg fill so the label doesn't bleed through the
	   syntax-highlighted code under the button. `--m-bg-overlay`
	   is a near-transparent rgba and blended into `<pre>`'s own
	   `--m-bg-1` it's invisible — `--m-bg` is one elevation step
	   lower, giving the button a clear plate. */
	background: var(--m-bg);
	border: 1px solid var(--m-border);
	border-radius: 3px;
	cursor: pointer;
	opacity: 0;
	transition:
		opacity 120ms ease,
		color 120ms ease,
		border-color 120ms ease;
}
.markdown-body .md-code-block:hover .md-copy-code,
.markdown-body .md-copy-code:focus-visible {
	opacity: 1;
}
.markdown-body .md-copy-code:hover {
	color: var(--m-fg);
	border-color: color-mix(in srgb, var(--m-accent) 40%, var(--m-border));
}
.markdown-body a {
	color: var(--m-accent);
	text-decoration: none;
}
.markdown-body a:hover {
	text-decoration: underline;
}
.markdown-body blockquote {
	border-left: 3px solid var(--m-border);
	color: var(--m-fg-muted);
	padding: 0.2em 0.8em;
	margin-left: 0;
}
.markdown-body hr {
	border: none;
	border-top: 1px solid var(--m-border);
	margin: 1.4em 0;
}
.markdown-body table {
	border-collapse: collapse;
	font-size: 0.95em;
	/* `display: block` + `width: max-content` lets the browser
	 * scroll the table horizontally when it would otherwise
	 * overflow the container (chat bubble, hover popover) while
	 * preserving column alignment via the anonymous CSS-table
	 * wrapper the engine generates around the rows. The previous
	 * `width: 100%` made the table stretch and combined badly
	 * with `table-layout: auto` under a tight container — short
	 * headers got crushed even though long columns had slack. */
	display: block;
	width: max-content;
	max-width: 100%;
	overflow-x: auto;
}
.markdown-body th,
.markdown-body td {
	border: 1px solid var(--m-border);
	padding: 6px 10px;
	text-align: left;
	/* Opt out of any ancestor `word-break: break-word` (the coder
	 * panel's chat bubble sets it). Per spec, `break-word`
	 * behaves like `overflow-wrap: anywhere` for min-content
	 * sizing, which lets the browser collapse a column's
	 * min-content width down to a single character — short
	 * headers like "New Cap" then split as "Ne / w" even when
	 * there's room to widen the column. Resetting to normal
	 * sizing keeps `table-layout: auto` honest; long
	 * unbreakable strings still wrap thanks to `overflow-wrap:
	 * break-word`, but only when the line would otherwise
	 * overflow, not as part of column-width math. */
	word-break: normal;
	overflow-wrap: break-word;
}
.markdown-body th {
	background: var(--m-bg-1);
}
.markdown-body img {
	max-width: 100%;
}

/* Leading YAML frontmatter (`---` … `---`) is split out of the body
   and rendered as a metadata table above the document — see
   `frontmatterToHtml` in `src/lib/markdown.ts`. The muted panel fill
   and dropped left border set it apart from author-written tables in
   the body without shouting. */
.markdown-body .md-frontmatter {
	margin: 0 0 1.4em;
	background: var(--m-bg-1);
	border-radius: 6px;
	overflow: hidden;
}
.markdown-body .md-frontmatter:first-child {
	margin-top: 0;
}
.markdown-body table.md-frontmatter th,
.markdown-body table.md-frontmatter td {
	border-color: var(--m-border);
	vertical-align: top;
}
.markdown-body table.md-frontmatter th[scope='row'] {
	white-space: nowrap;
	color: var(--m-fg-muted);
	font-weight: 600;
}
.markdown-body .md-frontmatter-empty {
	color: var(--m-fg-muted);
	opacity: 0.7;
}
.markdown-body .md-frontmatter-nested {
	display: block;
	white-space: pre;
	background: transparent;
	padding: 0;
}
.markdown-body .md-frontmatter-raw {
	padding: 0;
}
.markdown-body .md-frontmatter-raw pre {
	margin: 0;
	border: none;
	background: transparent;
}

/* Syntax highlighting for fenced code blocks. Classes are emitted by
 * `@lezer/highlight`'s `classHighlighter` (see
 * `src/lib/editor/highlightCode.ts`). Colours reuse the editor's
 * `--m-syntax-*` tokens so a fenced block and the live editor agree
 * on what a keyword looks like. A `:root.light` flip re-skins both
 * without touching JS. */
.tok-keyword,
.tok-atom,
.tok-bool {
	color: var(--m-syntax-keyword);
}
.tok-string,
.tok-string2 {
	color: var(--m-syntax-string);
}
.tok-number,
.tok-literal {
	color: var(--m-syntax-number);
}
.tok-variableName {
	color: var(--m-fg);
}
.tok-variableName.tok-definition,
.tok-propertyName.tok-definition,
.tok-variableName2 {
	color: var(--m-syntax-function);
}
.tok-typeName,
.tok-className {
	color: var(--m-syntax-type);
}
.tok-propertyName {
	color: var(--m-syntax-property);
}
.tok-namespace {
	color: var(--m-syntax-type);
}
.tok-macroName {
	color: var(--m-syntax-function);
}
.tok-labelName {
	color: var(--m-syntax-constant);
}
.tok-operator,
.tok-punctuation {
	color: var(--m-syntax-operator);
}
.tok-comment {
	color: var(--m-syntax-comment);
	font-style: italic;
}
.tok-meta {
	color: var(--m-syntax-meta);
	font-style: italic;
}
.tok-link,
.tok-url {
	color: var(--m-syntax-link);
	text-decoration: underline;
}
.tok-heading {
	color: var(--m-syntax-heading);
	font-weight: bold;
}
.tok-emphasis {
	font-style: italic;
}
.tok-strong {
	font-weight: bold;
}
.tok-inserted {
	color: var(--m-syntax-inserted);
}
.tok-deleted {
	color: var(--m-syntax-deleted);
}
.tok-invalid {
	color: var(--m-syntax-invalid);
	text-decoration: underline wavy;
}

/* Git blame hover popover. Lives at document.body level (see
   blame.ts) rather than inside the editor's DOM, so the .cm-*
   scoped rules don't reach it. Kept close to the editor's own
   tooltip palette so hovers across the UI feel cohesive. */
.cm-blame-hover {
	position: absolute;
	z-index: 40;
	min-width: 260px;
	max-width: 520px;
	background: var(--m-bg-2);
	border: 1px solid var(--m-border-strong);
	border-radius: 6px;
	box-shadow: 0 12px 32px rgba(0, 0, 0, 0.45);
	padding: 10px 12px;
	font-size: 12px;
	line-height: 1.5;
	color: var(--m-fg);
	pointer-events: auto;
}
.cm-blame-hover-title {
	font-weight: 600;
	margin-bottom: 6px;
	overflow-wrap: anywhere;
}
.cm-blame-hover-meta {
	color: var(--m-fg-muted);
	font-size: 11px;
	display: flex;
	flex-direction: column;
	gap: 2px;
}
.cm-blame-hover-body {
	margin-top: 8px;
	padding-top: 8px;
	border-top: 1px solid var(--m-border);
	white-space: pre-wrap;
	color: var(--m-fg);
	font-family: var(--m-font-mono);
	font-size: 11px;
	max-height: 200px;
	overflow-y: auto;
}
.cm-blame-pr-link {
	color: var(--m-accent);
	text-decoration: none;
	cursor: pointer;
}
.cm-blame-pr-link:hover {
	text-decoration: underline;
}

/* Git-change indicator: paint the line-number cell with a tinted
   background per change kind, GitHub-style. Replaces an older
   dedicated wedge gutter — keeps the chrome narrower and reuses
   the line-number column that the eye is already tracking.
   Colour families: green for additions, blue for modifications
   (matching the VSCode / Cursor convention the team has muscle
   memory for), red for deletions.

   The `cm-gitline*` classes are applied via the `gutterLineClass`
   facet from `editor/gitChanges.ts` (regular editor) and
   `editor/diffGutterTint.ts` (the diff view + aggregated review
   pseudo-tab), so the same CSS surface covers all three. The
   facet writes the class to *every* gutter row on the marked
   line (lint, fold, line numbers); the selectors below scope to
   the line-number column only to avoid colouring the lint /
   foldGutter columns. */
.cm-gutter.cm-lineNumbers .cm-gutterElement.cm-gitline-added {
	background: color-mix(in srgb, var(--m-success) 28%, transparent);
}
.cm-gutter.cm-lineNumbers .cm-gutterElement.cm-gitline-modified {
	background: color-mix(in srgb, var(--m-accent) 28%, transparent);
}
.cm-gutter.cm-lineNumbers .cm-gutterElement.cm-gitline-deleted {
	background: color-mix(in srgb, var(--m-danger) 28%, transparent);
}
/* Pure-deletion wedges in the editor (`deleted-above` /
   `deleted-below`): the line itself isn't gone — its neighbours
   are — so we mark the adjacent line-number cell with a thin
   coloured border on the appropriate edge. Combines on top of
   any other `cm-gitline-*` class the same line might carry
   (an added line that also has a deletion below it gets both
   the green background and a red bottom border). */
.cm-gutter.cm-lineNumbers .cm-gutterElement.cm-gitline-deleted-above {
	border-top: 2px solid var(--m-danger);
}
.cm-gutter.cm-lineNumbers .cm-gutterElement.cm-gitline-deleted-below {
	border-bottom: 2px solid var(--m-danger);
}

/* Merge-conflict block decoration. Two line classes:
   - `cm-conflict-block` — every line of an unresolved conflict
     range gets a soft warning tint so the eye can frame the
     block at a glance.
   - `cm-conflict-marker-line` — the `<<<<<<<` / `=======` /
     `|||||||` / `>>>>>>>` lines themselves get a stronger tint
     plus a left bar, so the structure of the block reads
     without having to count `<` characters.
   Both rules paint via `box-shadow` on the line element so they
   stack with selection / active-line backgrounds instead of
   stomping them. */
.cm-line.cm-conflict-block {
	background: color-mix(in srgb, var(--m-warning) 7%, transparent);
}
.cm-line.cm-conflict-marker-line {
	background: color-mix(in srgb, var(--m-warning) 18%, transparent);
	box-shadow: inset 2px 0 0 var(--m-warning);
	font-weight: 600;
}

/* Enclosing-symbol label appended to `@codemirror/merge`'s
   `… N unchanged lines` collapse placeholders in the Review changes
   tab (editor/diffCollapseContext.ts). GitHub-style "which function
   is this hunk in?" hint, derived from a text heuristic. Reads as a
   quiet monospace aside separated from the line count. */
.cm-collapsedLines .cm-collapseContext {
	margin-inline-start: 12px;
	padding-inline-start: 12px;
	border-inline-start: 1px solid var(--m-border);
	color: var(--m-fg-muted);
	font-family: var(--m-font-mono, monospace);
	opacity: 0.85;
}
/* The package decorates the placeholder with a trailing `⦚`
   pseudo-element; suppress it when we've appended a context label
   so the row reads `⦚ … N unchanged lines │ symbol` instead of
   trailing a stray glyph after the symbol. */
.cm-collapsedLines:has(.cm-collapseContext)::after {
	content: none;
}
/* Sticky enclosing-scope header (editor/stickyScroll.ts) — VS Code's
   "sticky scroll". A zero-height sticky wrapper prepended to
   `.cm-editor`; the rows overlay the top of whichever container
   actually scrolls (`.cm-scroller` in the editor, `.cm-mergeView`
   in the diff view). z-index sits above the gutters (200) and below
   `.cm-panels` (300). Font family/size inherit from the `.cm-editor`
   theme block; row line-height and the gutter-mirroring number
   column are set inline from live measurements. */
.cm-stickyScroll {
	position: sticky;
	top: 0;
	height: 0;
	flex: none;
	z-index: 250;
}
.cm-stickyScroll-rows {
	position: absolute;
	top: 0;
	left: 0;
	right: 0;
	overflow: hidden;
	background: var(--m-editor-bg);
	border-bottom: 1px solid var(--m-border);
	box-shadow: 0 2px 6px color-mix(in srgb, #000 14%, transparent);
}
.cm-stickyScroll-row {
	display: flex;
	white-space: pre;
	overflow: hidden;
	cursor: pointer;
}
.cm-stickyScroll-row:hover {
	background: var(--m-editor-line-active);
}
.cm-stickyScroll-num {
	flex: none;
	box-sizing: border-box;
	text-align: right;
	color: var(--m-fg-subtle);
	border-right: 1px solid var(--m-border);
	background: var(--m-editor-bg);
}
/* `.cm-line` supplies CM's own horizontal padding so columns align
   with real document lines; it also carries `flex-basis: 100%` in
   wrapped mode, hence the explicit shrink-friendly sizing. */
.cm-stickyScroll-code {
	flex: 1;
	min-width: 0;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: pre;
}
/* Per-block "Accept current / incoming / both" toolbar widget,
   anchored at end-of-line on the opening `<<<<<<<`. Inline-block
   so the marker line's text reflow stays sane on narrow widths;
   the buttons themselves are flat affordances tinted by the
   warning palette. */
.cm-conflict-toolbar {
	display: inline-flex;
	gap: 4px;
	margin-left: 12px;
	vertical-align: middle;
}
.cm-conflict-btn {
	appearance: none;
	background: color-mix(in srgb, var(--m-warning) 18%, transparent);
	color: var(--m-warning);
	border: 1px solid color-mix(in srgb, var(--m-warning) 50%, transparent);
	border-radius: 4px;
	padding: 1px 8px;
	font-size: 11px;
	font-family: var(--m-font-mono);
	cursor: pointer;
	line-height: 1.4;
}
.cm-conflict-btn:hover {
	background: color-mix(in srgb, var(--m-warning) 30%, transparent);
}
.cm-conflict-btn:focus-visible {
	outline: 2px solid var(--m-warning);
	outline-offset: 2px;
}

/* Git-change overview ruler. A thin column pinned to the editor's
   right edge, overlaying the native scrollbar, where every change
   in the file is plotted at its scaled vertical position. Invisible
   until a change exists, `pointer-events: none` on the container
   passes scrollbar interactions through to the browser, and each
   marker re-enables its own events so a click jumps the viewport
   to that line. Colour families match the per-line gutter so the
   eye reads "green = add, blue = modify, red = delete" in both
   places. */
/* The overlay is normally a child of `.cm-editor` (regular editor
   case), but the diff view re-parents it to `.cm-mergeView` so the
   strip lands on the merge view's actual scrollbar gutter — the
   inner editor frame is doc-height there. The class is unique to
   this widget, so plain `.cm-git-overview` is unambiguous. */
.cm-git-overview {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	width: 10px;
	z-index: 5;
	pointer-events: none;
}
.cm-git-overview-marker {
	position: absolute;
	right: 1px;
	width: 6px;
	/* Minimum visual height so a single-line change in a multi-
	   thousand-line file still shows up. Fractional positioning
	   stays intact because `top` is set in %; `height` is absolute. */
	height: 3px;
	margin-top: -1px;
	border-radius: 1px;
	pointer-events: auto;
	cursor: pointer;
	opacity: 0.75;
}
.cm-git-overview-marker:hover {
	opacity: 1;
	width: 8px;
	right: 0;
}
.cm-git-overview-added {
	background: var(--m-success);
}
.cm-git-overview-modified {
	background: var(--m-accent);
}
.cm-git-overview-deleted {
	background: var(--m-danger);
}

/* LSP-diagnostic overview ruler. Shares the same 10px column as
   the git overview but paints in a parallel lane to its left so
   the two surfaces don't visually collide: git markers hug the
   scrollbar (right: 1px), diagnostic markers sit just inside
   (right: 6px). Same z, pointer-events, click-to-jump shape as
   the git overview. Hover bumps width to 5px for an easier click
   target without claiming layout. */
.cm-lsp-overview {
	position: absolute;
	top: 0;
	right: 0;
	bottom: 0;
	width: 10px;
	z-index: 5;
	pointer-events: none;
}
.cm-lsp-overview-marker {
	position: absolute;
	right: 6px;
	width: 3px;
	/* Same minimum height as the git markers — single-line
	   diagnostics in a multi-thousand-line file still surface. */
	height: 3px;
	margin-top: -1px;
	border-radius: 1px;
	pointer-events: auto;
	cursor: pointer;
	opacity: 0.85;
}
.cm-lsp-overview-marker:hover {
	opacity: 1;
	width: 5px;
	right: 5px;
}
.cm-lsp-overview-error {
	background: var(--m-danger);
}
.cm-lsp-overview-warning {
	background: var(--m-warning);
}
.cm-lsp-overview-info {
	background: var(--m-accent);
}
.cm-lsp-overview-hint {
	background: var(--m-fg-muted);
}

/* Inline link-like button used by the coder tool body components
   (grep hits, read_file / write_file / edit_file path headers,
   list_dir file entries) to make file references clickable. We
   use a real `<button>` rather than `<a>` because navigation
   goes through the workspace store (tabs, splits, pending jumps)
   not URL routing. The class strips the native chrome and the
   button reads as an underlined accent string in monospace
   context — same affordance as a hyperlink, no extra surprise. */
.tool-link {
	appearance: none;
	background: transparent;
	border: 0;
	padding: 0;
	font: inherit;
	color: var(--m-accent, var(--m-fg));
	text-align: left;
	cursor: pointer;
}
.tool-link:hover,
.tool-link:focus-visible {
	text-decoration: underline;
}
.tool-link:focus-visible {
	outline: 1px solid var(--m-accent, var(--m-fg));
	outline-offset: 1px;
	border-radius: 2px;
}

/* Find-in-document highlights.
 *
 * `MarkdownView.svelte` (moon-md-*) and `CoderPanel.svelte`
 * (moon-coder-*) register Ranges with the CSS Custom Highlight API
 * under these names; the pseudo-element selectors below paint them.
 * Distinct names per surface so a markdown find and a transcript
 * find open at the same time don't clobber each other's entries in
 * the document-global `CSS.highlights` registry. They live in the
 * global stylesheet (not the components' scoped blocks) because
 * `::highlight()` is matched against the elements that contain the
 * highlighted text — Svelte's scoping would rewrite the selector
 * and the highlight wouldn't paint. */
::highlight(moon-md-find),
::highlight(moon-coder-find) {
	background-color: rgba(255, 213, 79, 0.35);
	color: inherit;
}
::highlight(moon-md-find-active),
::highlight(moon-coder-find-active) {
	background-color: rgba(255, 167, 38, 0.7);
	color: #11151f;
}
