@nuucognition/ncm-ui 0.1.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +129 -0
- package/dist/blocks/admonition/index.d.ts +13 -0
- package/dist/blocks/admonition/index.js +1713 -0
- package/dist/blocks/aside/index.d.ts +13 -0
- package/dist/blocks/aside/index.js +1713 -0
- package/dist/blocks/attribution/index.d.ts +13 -0
- package/dist/blocks/attribution/index.js +32 -0
- package/dist/blocks/blockquote/index.d.ts +15 -0
- package/dist/blocks/blockquote/index.js +609 -0
- package/dist/blocks/chart/index.d.ts +14 -0
- package/dist/blocks/chart/index.js +29 -0
- package/dist/blocks/code/index.d.ts +15 -0
- package/dist/blocks/code/index.js +163 -0
- package/dist/blocks/container/index.d.ts +17 -0
- package/dist/blocks/container/index.js +633 -0
- package/dist/blocks/custom-code/index.d.ts +15 -0
- package/dist/blocks/custom-code/index.js +31 -0
- package/dist/blocks/dataview/index.d.ts +14 -0
- package/dist/blocks/dataview/index.js +29 -0
- package/dist/blocks/definition/index.d.ts +13 -0
- package/dist/blocks/definition/index.js +1713 -0
- package/dist/blocks/embed/index.d.ts +12 -0
- package/dist/blocks/embed/index.js +46 -0
- package/dist/blocks/embedding/index.d.ts +13 -0
- package/dist/blocks/embedding/index.js +763 -0
- package/dist/blocks/figure/index.d.ts +13 -0
- package/dist/blocks/figure/index.js +656 -0
- package/dist/blocks/footnote/index.d.ts +13 -0
- package/dist/blocks/footnote/index.js +1713 -0
- package/dist/blocks/frontmatter/index.d.ts +16 -0
- package/dist/blocks/frontmatter/index.js +38 -0
- package/dist/blocks/header/index.d.ts +9 -0
- package/dist/blocks/header/index.js +610 -0
- package/dist/blocks/horizontal-rule/index.d.ts +9 -0
- package/dist/blocks/horizontal-rule/index.js +19 -0
- package/dist/blocks/html/index.d.ts +31 -0
- package/dist/blocks/html/index.js +52 -0
- package/dist/blocks/index.d.ts +32 -0
- package/dist/blocks/index.js +1736 -0
- package/dist/blocks/latex/index.d.ts +9 -0
- package/dist/blocks/latex/index.js +107 -0
- package/dist/blocks/link/index.d.ts +14 -0
- package/dist/blocks/link/index.js +27 -0
- package/dist/blocks/list/index.d.ts +9 -0
- package/dist/blocks/list/index.js +675 -0
- package/dist/blocks/math/index.d.ts +13 -0
- package/dist/blocks/math/index.js +88 -0
- package/dist/blocks/mermaid/index.d.ts +14 -0
- package/dist/blocks/mermaid/index.js +29 -0
- package/dist/blocks/page-breaker/index.d.ts +16 -0
- package/dist/blocks/page-breaker/index.js +21 -0
- package/dist/blocks/paragraph/index.d.ts +9 -0
- package/dist/blocks/paragraph/index.js +608 -0
- package/dist/blocks/spoiler/index.d.ts +13 -0
- package/dist/blocks/spoiler/index.js +1713 -0
- package/dist/blocks/table/index.d.ts +9 -0
- package/dist/blocks/table/index.js +619 -0
- package/dist/blocks/task-list/index.d.ts +13 -0
- package/dist/blocks/task-list/index.js +670 -0
- package/dist/components/index.d.ts +599 -0
- package/dist/components/index.js +1840 -0
- package/dist/components/ncm-block.d.ts +28 -0
- package/dist/components/ncm-block.js +1712 -0
- package/dist/components/ncm-document.d.ts +48 -0
- package/dist/components/ncm-document.js +1839 -0
- package/dist/context/index.d.ts +7 -0
- package/dist/context/index.js +284 -0
- package/dist/hooks/index.d.ts +7 -0
- package/dist/hooks/index.js +1731 -0
- package/dist/hooks/use-block-renderer.d.ts +28 -0
- package/dist/hooks/use-block-renderer.js +1731 -0
- package/dist/hooks/use-ncm-config.d.ts +6 -0
- package/dist/hooks/use-ncm-config.js +11 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +1887 -0
- package/dist/inline/index.d.ts +108 -0
- package/dist/inline/index.js +598 -0
- package/dist/inline-DwUYUmk4.d.ts +75 -0
- package/dist/lib/defaults.d.ts +24 -0
- package/dist/lib/defaults.js +1713 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/index.js +10 -0
- package/dist/lib/katex.d.ts +3 -0
- package/dist/lib/katex.js +45 -0
- package/dist/lib/utils.d.ts +8 -0
- package/dist/lib/utils.js +10 -0
- package/dist/references-Bs5wJybr.d.ts +63 -0
- package/dist/renderers-C5f41FCy.d.ts +99 -0
- package/dist/styles/fonts/OpenDyslexic3-Bold.woff +0 -0
- package/dist/styles/fonts/OpenDyslexic3-Bold.woff2 +0 -0
- package/dist/styles/fonts/OpenDyslexic3-Regular.woff +0 -0
- package/dist/styles/fonts/OpenDyslexic3-Regular.woff2 +0 -0
- package/dist/styles/nuu.css +364 -0
- package/dist/styles/paper.css +332 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.js +2 -0
- package/dist/use-ncm-config-D0doMYTH.d.ts +114 -0
- package/package.json +99 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
3
|
+
|
|
4
|
+
var katexPromise = null;
|
|
5
|
+
function loadKatex() {
|
|
6
|
+
if (!katexPromise) {
|
|
7
|
+
katexPromise = Promise.all([
|
|
8
|
+
import('katex'),
|
|
9
|
+
import('katex/dist/katex.min.css')
|
|
10
|
+
]).then(([module]) => module.default).catch(() => null);
|
|
11
|
+
}
|
|
12
|
+
return katexPromise;
|
|
13
|
+
}
|
|
14
|
+
function useKatexHtml(content, displayMode, enabled = true) {
|
|
15
|
+
const [katexModule, setKatexModule] = useState(null);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (!enabled) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
let active = true;
|
|
21
|
+
loadKatex().then((loaded) => {
|
|
22
|
+
if (active) {
|
|
23
|
+
setKatexModule(loaded);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return () => {
|
|
27
|
+
active = false;
|
|
28
|
+
};
|
|
29
|
+
}, [enabled]);
|
|
30
|
+
return useMemo(() => {
|
|
31
|
+
if (!enabled || !katexModule) {
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
return katexModule.renderToString(content, {
|
|
36
|
+
throwOnError: false,
|
|
37
|
+
displayMode
|
|
38
|
+
});
|
|
39
|
+
} catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}, [content, displayMode, enabled, katexModule]);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export { useKatexHtml };
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { ReactNode } from 'react';
|
|
3
|
+
import { Block } from '@nuucognition/ncm';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Document-order numbering for inline references (`^[ref: ...]` /
|
|
7
|
+
* `^[footnote: ...]`).
|
|
8
|
+
*
|
|
9
|
+
* The two kinds are counted **independently**: refs produce `[1] [2] …` and
|
|
10
|
+
* footnotes produce `¹ ² …`, each with its own running counter across the
|
|
11
|
+
* whole document.
|
|
12
|
+
*
|
|
13
|
+
* Numbering is computed from the `blocks` array — a pure pre-pass that does not
|
|
14
|
+
* depend on React render order — so markers stay stable even if a host
|
|
15
|
+
* virtualises blocks or renders them out of order. The pre-pass yields, per
|
|
16
|
+
* block, the count of each kind in all *preceding* blocks (the "base"); within
|
|
17
|
+
* a block, a `BlockReferenceScope` hands out sequential numbers in render
|
|
18
|
+
* order. Only the within-block step relies on the block's inline content
|
|
19
|
+
* rendering as a synchronous subtree (it always does).
|
|
20
|
+
*/
|
|
21
|
+
type ReferenceKind = "ref" | "footnote";
|
|
22
|
+
interface ReferenceCounts {
|
|
23
|
+
ref: number;
|
|
24
|
+
footnote: number;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Map each block id to the number of refs/footnotes that precede it in
|
|
28
|
+
* document order — the starting offset for that block's own markers.
|
|
29
|
+
*/
|
|
30
|
+
declare function computeReferenceBases(blocks: readonly Block[]): Map<string, ReferenceCounts>;
|
|
31
|
+
interface BlockReferenceScopeValue {
|
|
32
|
+
/** Allocate the next document-order number for `kind` within this block. */
|
|
33
|
+
next(kind: ReferenceKind): number;
|
|
34
|
+
}
|
|
35
|
+
interface NcmReferencesProviderProps {
|
|
36
|
+
blocks: readonly Block[];
|
|
37
|
+
children: ReactNode;
|
|
38
|
+
}
|
|
39
|
+
/** Document-root provider — runs the numbering pre-pass over `blocks`. */
|
|
40
|
+
declare function NcmReferencesProvider({ blocks, children }: NcmReferencesProviderProps): react_jsx_runtime.JSX.Element;
|
|
41
|
+
interface BlockReferenceScopeProps {
|
|
42
|
+
/** Block id; resolves the base offset from the document pre-pass. */
|
|
43
|
+
blockId?: string;
|
|
44
|
+
children: ReactNode;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Per-block numbering scope. Seeds a fresh counter from the block's base offset
|
|
48
|
+
* on every render and hands out sequential numbers as markers render. Resetting
|
|
49
|
+
* each render keeps numbering idempotent under React re-renders / StrictMode.
|
|
50
|
+
*/
|
|
51
|
+
declare function BlockReferenceScope({ blockId, children }: BlockReferenceScopeProps): react_jsx_runtime.JSX.Element;
|
|
52
|
+
/** Read the active per-block reference scope, if any. */
|
|
53
|
+
declare function useBlockReferenceScope(): BlockReferenceScopeValue | null;
|
|
54
|
+
/**
|
|
55
|
+
* Wrap a subtree so any inline references inside it do NOT allocate
|
|
56
|
+
* document-order numbers — used for a reference's own popover content, which
|
|
57
|
+
* the numbering pre-pass deliberately does not descend into.
|
|
58
|
+
*/
|
|
59
|
+
declare function InertReferenceScope({ children }: {
|
|
60
|
+
children: ReactNode;
|
|
61
|
+
}): react_jsx_runtime.JSX.Element;
|
|
62
|
+
|
|
63
|
+
export { BlockReferenceScope as B, InertReferenceScope as I, NcmReferencesProvider as N, type ReferenceCounts as R, type BlockReferenceScopeProps as a, type BlockReferenceScopeValue as b, type NcmReferencesProviderProps as c, type ReferenceKind as d, computeReferenceBases as e, useBlockReferenceScope as u };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { Block, ParagraphBlock, HeaderBlock, BlockquoteBlock, CodeBlock, ContainerBlock, FrontmatterBlock, HtmlBlock, ListBlock, TableBlock, EmbedBlock, EmbeddingBlock, LatexDisplayBlock, HorizontalRuleBlock, PageBreakerBlock, LinkBlock, FigureBlock, AdmonitionBlock, FootnoteBlock, TaskListBlock, DefinitionBlock, SpoilerBlock, AsideBlock, AttributionBlock, MermaidBlock, DataviewBlock, MathBlock, ChartBlock, CustomCodeBlock, EmbedType } from '@nuucognition/ncm';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Base props for all block renderers
|
|
6
|
+
*/
|
|
7
|
+
interface BlockRendererProps<T extends Block = Block> {
|
|
8
|
+
block: T;
|
|
9
|
+
className?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Type for a block renderer component
|
|
13
|
+
*/
|
|
14
|
+
type BlockRenderer<T extends Block = Block> = ComponentType<BlockRendererProps<T>>;
|
|
15
|
+
/**
|
|
16
|
+
* Registry of block renderers by type.
|
|
17
|
+
*
|
|
18
|
+
* Every key (except the language-keyed `custom_code` sub-registry and
|
|
19
|
+
* `fallback`) corresponds 1:1 to a `block.type` the parser can emit. All keys
|
|
20
|
+
* are optional here so consumers can pass partial overrides; the shipped
|
|
21
|
+
* `defaultRenderers` is typed as {@link CompleteBlockRendererRegistry}, which
|
|
22
|
+
* requires coverage for every parser block type.
|
|
23
|
+
*/
|
|
24
|
+
interface BlockRendererRegistry {
|
|
25
|
+
paragraph?: BlockRenderer<ParagraphBlock>;
|
|
26
|
+
header?: BlockRenderer<HeaderBlock>;
|
|
27
|
+
blockquote?: BlockRenderer<BlockquoteBlock>;
|
|
28
|
+
code?: BlockRenderer<CodeBlock>;
|
|
29
|
+
container?: BlockRenderer<ContainerBlock>;
|
|
30
|
+
frontmatter?: BlockRenderer<FrontmatterBlock>;
|
|
31
|
+
html?: BlockRenderer<HtmlBlock>;
|
|
32
|
+
list_ordered?: BlockRenderer<ListBlock>;
|
|
33
|
+
list_unordered?: BlockRenderer<ListBlock>;
|
|
34
|
+
table?: BlockRenderer<TableBlock>;
|
|
35
|
+
embed?: BlockRenderer<EmbedBlock>;
|
|
36
|
+
embedding?: BlockRenderer<EmbeddingBlock>;
|
|
37
|
+
latex_display?: BlockRenderer<LatexDisplayBlock>;
|
|
38
|
+
horizontal_rule?: BlockRenderer<HorizontalRuleBlock>;
|
|
39
|
+
page_breaker?: BlockRenderer<PageBreakerBlock>;
|
|
40
|
+
link?: BlockRenderer<LinkBlock>;
|
|
41
|
+
figure?: BlockRenderer<FigureBlock>;
|
|
42
|
+
admonition?: BlockRenderer<AdmonitionBlock>;
|
|
43
|
+
footnote?: BlockRenderer<FootnoteBlock>;
|
|
44
|
+
task_list?: BlockRenderer<TaskListBlock>;
|
|
45
|
+
definition?: BlockRenderer<DefinitionBlock>;
|
|
46
|
+
spoiler?: BlockRenderer<SpoilerBlock>;
|
|
47
|
+
aside?: BlockRenderer<AsideBlock>;
|
|
48
|
+
attribution?: BlockRenderer<AttributionBlock>;
|
|
49
|
+
mermaid?: BlockRenderer<MermaidBlock>;
|
|
50
|
+
dataview?: BlockRenderer<DataviewBlock>;
|
|
51
|
+
math?: BlockRenderer<MathBlock>;
|
|
52
|
+
chart?: BlockRenderer<ChartBlock>;
|
|
53
|
+
/** Custom code renderers keyed by language identifier */
|
|
54
|
+
custom_code?: Record<string, BlockRenderer<CustomCodeBlock>>;
|
|
55
|
+
/** Fallback renderer for unknown block types */
|
|
56
|
+
fallback?: BlockRenderer<Block>;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Every concrete `block.type` dispatched through the keyed registry — i.e. all
|
|
60
|
+
* parser block types except the language-keyed `custom_code`. Derived from the
|
|
61
|
+
* parser's `Block` union, so adding a block type upstream automatically widens
|
|
62
|
+
* this and breaks {@link CompleteBlockRendererRegistry} until a renderer exists.
|
|
63
|
+
*/
|
|
64
|
+
type KeyedBlockType = Exclude<Block["type"], "custom_code">;
|
|
65
|
+
/**
|
|
66
|
+
* The `Block` union member whose discriminant covers literal `K`. Distributes
|
|
67
|
+
* over `Block` and matches on `K extends T` (not `Block extends { type: K }`),
|
|
68
|
+
* so block types with a union discriminant resolve correctly — e.g. `ListBlock`
|
|
69
|
+
* (`"list_ordered" | "list_unordered"`) is found for either list key.
|
|
70
|
+
*/
|
|
71
|
+
type BlockOfType<K extends string, B = Block> = B extends {
|
|
72
|
+
type: infer T;
|
|
73
|
+
} ? K extends T ? B : never : never;
|
|
74
|
+
/**
|
|
75
|
+
* A registry that MUST provide a renderer for every keyed block type, plus the
|
|
76
|
+
* `custom_code` sub-registry. `defaultRenderers` is typed as this — the
|
|
77
|
+
* compile-time guard that keeps the block→UI mapping 1:1: omit a renderer for
|
|
78
|
+
* any parser block type and `tsc` fails.
|
|
79
|
+
*/
|
|
80
|
+
type CompleteBlockRendererRegistry = {
|
|
81
|
+
[K in KeyedBlockType]-?: BlockRenderer<BlockOfType<K> & Block>;
|
|
82
|
+
} & {
|
|
83
|
+
custom_code: Record<string, BlockRenderer<CustomCodeBlock>>;
|
|
84
|
+
fallback: BlockRenderer<Block>;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Props for embedding sub-renderers
|
|
88
|
+
*/
|
|
89
|
+
interface EmbeddingRendererProps {
|
|
90
|
+
block: EmbeddingBlock;
|
|
91
|
+
className?: string;
|
|
92
|
+
resolvedUrl: string;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Registry of embedding renderers by embed type
|
|
96
|
+
*/
|
|
97
|
+
type EmbeddingRendererRegistry = Partial<Record<EmbedType, ComponentType<EmbeddingRendererProps>>>;
|
|
98
|
+
|
|
99
|
+
export type { BlockRenderer as B, CompleteBlockRendererRegistry as C, EmbeddingRendererProps as E, KeyedBlockType as K, BlockRendererProps as a, BlockRendererRegistry as b, EmbeddingRendererRegistry as c };
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* NCM UI — NUU theme
|
|
3
|
+
*
|
|
4
|
+
* Styles NCM blocks against the @nuucognition/ui token system.
|
|
5
|
+
* Inherits --foreground, --background, --muted, --border, etc. from the host.
|
|
6
|
+
* Light/dark switches automatically when the host toggles `.dark` on the root.
|
|
7
|
+
*
|
|
8
|
+
* Selectors target the data attributes emitted by ncm-ui block components.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
[data-ncm-document].ncm-theme-nuu {
|
|
12
|
+
font-family: var(--font-sans);
|
|
13
|
+
font-size: calc(0.875rem * var(--surf-reading-scale, 1));
|
|
14
|
+
line-height: 1.55;
|
|
15
|
+
color: var(--foreground);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
[data-ncm-document].ncm-theme-nuu > * + * {
|
|
19
|
+
margin-top: 1rem;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/* Headings — Geist Sans, tracking-tight, normal weight on h1–h3 */
|
|
23
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="header"] {
|
|
24
|
+
font-family: var(--font-heading);
|
|
25
|
+
color: var(--foreground);
|
|
26
|
+
scroll-margin-top: 5rem;
|
|
27
|
+
margin-bottom: 0;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="header"][data-ncm-level="1"] {
|
|
31
|
+
font-size: calc(1.875rem * var(--surf-reading-scale, 1));
|
|
32
|
+
line-height: 2.25rem;
|
|
33
|
+
letter-spacing: -0.025em;
|
|
34
|
+
font-weight: 400;
|
|
35
|
+
margin-top: 1.5rem;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="header"][data-ncm-level="1"]:first-child {
|
|
39
|
+
margin-top: 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="header"][data-ncm-level="2"] {
|
|
43
|
+
font-size: calc(1.5rem * var(--surf-reading-scale, 1));
|
|
44
|
+
line-height: 2rem;
|
|
45
|
+
letter-spacing: -0.025em;
|
|
46
|
+
font-weight: 400;
|
|
47
|
+
margin-top: 1.25rem;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="header"][data-ncm-level="3"] {
|
|
51
|
+
font-size: calc(1.25rem * var(--surf-reading-scale, 1));
|
|
52
|
+
line-height: 1.75rem;
|
|
53
|
+
letter-spacing: -0.025em;
|
|
54
|
+
font-weight: 400;
|
|
55
|
+
margin-top: 1rem;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="header"][data-ncm-level="4"] {
|
|
59
|
+
font-size: calc(0.875rem * var(--surf-reading-scale, 1));
|
|
60
|
+
line-height: 1.25rem;
|
|
61
|
+
font-weight: 500;
|
|
62
|
+
margin-top: 0.75rem;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="header"][data-ncm-level="5"] {
|
|
66
|
+
font-size: calc(0.75rem * var(--surf-reading-scale, 1));
|
|
67
|
+
line-height: 1rem;
|
|
68
|
+
font-weight: 500;
|
|
69
|
+
letter-spacing: 0.05em;
|
|
70
|
+
text-transform: uppercase;
|
|
71
|
+
margin-top: 0.75rem;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/* Paragraph */
|
|
75
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="paragraph"] {
|
|
76
|
+
color: var(--foreground);
|
|
77
|
+
line-height: 1.55;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* Blockquote */
|
|
81
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="blockquote"] {
|
|
82
|
+
border-left: 2px solid var(--border);
|
|
83
|
+
padding-left: 0.875rem;
|
|
84
|
+
color: color-mix(in srgb, var(--foreground) 80%, transparent);
|
|
85
|
+
line-height: 1.55;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="blockquote"] p + p {
|
|
89
|
+
margin-top: 0.25rem;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/* Lists */
|
|
93
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_ordered"],
|
|
94
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_unordered"] {
|
|
95
|
+
padding-left: 1.25rem;
|
|
96
|
+
color: var(--foreground);
|
|
97
|
+
line-height: 1.55;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_ordered"] {
|
|
101
|
+
list-style-type: decimal;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_unordered"] {
|
|
105
|
+
list-style-type: disc;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_ordered"] li + li,
|
|
109
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_unordered"] li + li {
|
|
110
|
+
margin-top: 0.125rem;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_ordered"] ol,
|
|
114
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_ordered"] ul,
|
|
115
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_unordered"] ol,
|
|
116
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_unordered"] ul {
|
|
117
|
+
margin-top: 0.125rem;
|
|
118
|
+
padding-left: 1.25rem;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_ordered"] li::marker,
|
|
122
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_unordered"] li::marker {
|
|
123
|
+
color: var(--muted-foreground);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_ordered"] ol {
|
|
127
|
+
list-style-type: decimal;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_ordered"] ul,
|
|
131
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_unordered"] ul {
|
|
132
|
+
list-style-type: disc;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="list_unordered"] ol {
|
|
136
|
+
list-style-type: decimal;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Tables */
|
|
140
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="table"] {
|
|
141
|
+
width: 100%;
|
|
142
|
+
overflow-x: auto;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="table"] table {
|
|
146
|
+
width: 100%;
|
|
147
|
+
border-collapse: collapse;
|
|
148
|
+
font-size: calc(0.75rem * var(--surf-reading-scale, 1));
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="table"] th {
|
|
152
|
+
border: 1px solid var(--border);
|
|
153
|
+
padding: 0.5rem 0.75rem;
|
|
154
|
+
text-align: left;
|
|
155
|
+
font-weight: 500;
|
|
156
|
+
background-color: var(--muted);
|
|
157
|
+
color: var(--foreground);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="table"] td {
|
|
161
|
+
border: 1px solid var(--border);
|
|
162
|
+
padding: 0.5rem 0.75rem;
|
|
163
|
+
text-align: left;
|
|
164
|
+
color: var(--foreground);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="table"] tbody tr:nth-child(even) td {
|
|
168
|
+
background-color: color-mix(in srgb, var(--muted) 50%, transparent);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* Code (block) */
|
|
172
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="code"] {
|
|
173
|
+
position: relative;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="code"] pre {
|
|
177
|
+
overflow-x: auto;
|
|
178
|
+
border: 1px solid var(--border);
|
|
179
|
+
border-radius: var(--radius, 0.625rem);
|
|
180
|
+
padding: 0.75rem;
|
|
181
|
+
background-color: var(--muted);
|
|
182
|
+
color: var(--foreground);
|
|
183
|
+
font-family: var(--font-mono);
|
|
184
|
+
font-size: calc(0.875rem * var(--surf-reading-scale, 1));
|
|
185
|
+
line-height: 1.6;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* Inline code */
|
|
189
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="code"] {
|
|
190
|
+
font-family: var(--font-mono);
|
|
191
|
+
font-size: calc(0.75rem * var(--surf-reading-scale, 1));
|
|
192
|
+
padding: 0.125rem 0.25rem;
|
|
193
|
+
border-radius: 0.25rem;
|
|
194
|
+
background-color: var(--muted);
|
|
195
|
+
color: var(--foreground);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/* Links */
|
|
199
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="link"],
|
|
200
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="wiki_link"][data-ncm-wikilink-status="resolved"],
|
|
201
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="wiki_embed"]:not([data-ncm-wikiembed-status]) {
|
|
202
|
+
color: var(--brand, var(--primary));
|
|
203
|
+
text-decoration: underline;
|
|
204
|
+
text-underline-offset: 4px;
|
|
205
|
+
font-weight: 500;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="wiki_link"][data-ncm-wikilink-status="missing"],
|
|
209
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="wiki_embed"][data-ncm-wikiembed-status="missing"] {
|
|
210
|
+
color: var(--muted-foreground);
|
|
211
|
+
text-decoration: underline dashed;
|
|
212
|
+
text-underline-offset: 4px;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="wiki_link"][data-ncm-wikilink-status="ambiguous"],
|
|
216
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="wiki_embed"][data-ncm-wikiembed-status="ambiguous"] {
|
|
217
|
+
color: var(--fire-text, var(--destructive));
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/* Horizontal rule */
|
|
221
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="horizontal_rule"] {
|
|
222
|
+
border: 0;
|
|
223
|
+
border-top: 1px solid var(--border);
|
|
224
|
+
margin-top: 1.25rem;
|
|
225
|
+
margin-bottom: 1.25rem;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/* Embeddings */
|
|
229
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="embedding"] img,
|
|
230
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="embedding"] video {
|
|
231
|
+
max-width: 100%;
|
|
232
|
+
border-radius: var(--radius, 0.625rem);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="embedding"] figcaption {
|
|
236
|
+
margin-top: 0.5rem;
|
|
237
|
+
text-align: left;
|
|
238
|
+
font-size: 0.75rem;
|
|
239
|
+
color: var(--muted-foreground);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/* LaTeX display */
|
|
243
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="latex_display"] {
|
|
244
|
+
overflow-x: auto;
|
|
245
|
+
color: var(--foreground);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/* Custom code (fallback for promoted blocks without renderer) */
|
|
249
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-type="custom_code"] {
|
|
250
|
+
border: 1px dashed var(--border);
|
|
251
|
+
border-radius: var(--radius, 0.625rem);
|
|
252
|
+
padding: 0.75rem;
|
|
253
|
+
background-color: var(--muted);
|
|
254
|
+
color: var(--foreground);
|
|
255
|
+
font-family: var(--font-mono);
|
|
256
|
+
font-size: 0.875rem;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/* OpenDyslexic3 — newest, refined letterforms of the OpenDyslexic family
|
|
260
|
+
* (the original v2 that @fontsource/opendyslexic ships has visibly different
|
|
261
|
+
* glyph shapes). Fonts are bundled locally under ./fonts/ so the bundle is
|
|
262
|
+
* self-contained — no CDN dependency.
|
|
263
|
+
*
|
|
264
|
+
* Spacing matches opendyslexic.org's own About page CSS:
|
|
265
|
+
* body { font-family: OpenDyslexic3; letter-spacing: 0.07rem }
|
|
266
|
+
* article { line-height: 1.75rem }
|
|
267
|
+
* — weight stays at 400 (Regular), small letter-spacing bump separates the
|
|
268
|
+
* chunky glyphs, generous line-height gives them room to breathe. */
|
|
269
|
+
@font-face {
|
|
270
|
+
font-family: "OpenDyslexic3";
|
|
271
|
+
src: url("./fonts/OpenDyslexic3-Regular.woff2") format("woff2"),
|
|
272
|
+
url("./fonts/OpenDyslexic3-Regular.woff") format("woff");
|
|
273
|
+
font-weight: 400;
|
|
274
|
+
font-style: normal;
|
|
275
|
+
font-display: swap;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@font-face {
|
|
279
|
+
font-family: "OpenDyslexic3";
|
|
280
|
+
src: url("./fonts/OpenDyslexic3-Bold.woff2") format("woff2"),
|
|
281
|
+
url("./fonts/OpenDyslexic3-Bold.woff") format("woff");
|
|
282
|
+
font-weight: 700;
|
|
283
|
+
font-style: normal;
|
|
284
|
+
font-display: swap;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
[data-ncm-document].ncm-theme-nuu[data-ncm-dyslexic-font="true"],
|
|
288
|
+
[data-ncm-document].ncm-theme-nuu[data-ncm-dyslexic-font="true"] [data-ncm-type="header"],
|
|
289
|
+
[data-ncm-document].ncm-theme-nuu[data-ncm-dyslexic-font="true"] [data-ncm-type="paragraph"],
|
|
290
|
+
[data-ncm-document].ncm-theme-nuu[data-ncm-dyslexic-font="true"] [data-ncm-type="list"],
|
|
291
|
+
[data-ncm-document].ncm-theme-nuu[data-ncm-dyslexic-font="true"] [data-ncm-type="blockquote"],
|
|
292
|
+
[data-ncm-document].ncm-theme-nuu[data-ncm-dyslexic-font="true"] [data-ncm-type="table"] {
|
|
293
|
+
font-family: "OpenDyslexic3", var(--font-sans);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
[data-ncm-document].ncm-theme-nuu[data-ncm-dyslexic-font="true"] {
|
|
297
|
+
letter-spacing: 0.07rem;
|
|
298
|
+
line-height: 1.75;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/* Inline references — ^[ref: …] (citation, [1]) and ^[footnote: …] (¹) */
|
|
302
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="reference"],
|
|
303
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="footnote"] {
|
|
304
|
+
position: relative;
|
|
305
|
+
white-space: nowrap;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-ref-marker] {
|
|
309
|
+
cursor: pointer;
|
|
310
|
+
color: var(--brand, var(--primary));
|
|
311
|
+
font-weight: 500;
|
|
312
|
+
border-radius: 0.1875rem;
|
|
313
|
+
outline: none;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="reference"] [data-ncm-ref-marker] {
|
|
317
|
+
font-size: 0.85em;
|
|
318
|
+
padding: 0 0.0625rem;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
[data-ncm-document].ncm-theme-nuu sup[data-ncm-ref-marker] {
|
|
322
|
+
font-size: 0.7em;
|
|
323
|
+
line-height: 0;
|
|
324
|
+
padding-left: 0.0625rem;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-ref-marker]:hover,
|
|
328
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-ref-marker]:focus-visible {
|
|
329
|
+
text-decoration: underline;
|
|
330
|
+
text-underline-offset: 2px;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/* Popover — content revealed on marker hover/focus */
|
|
334
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-ref-popover] {
|
|
335
|
+
position: absolute;
|
|
336
|
+
left: 0;
|
|
337
|
+
top: 1.6em;
|
|
338
|
+
z-index: 20;
|
|
339
|
+
width: max-content;
|
|
340
|
+
max-width: min(22rem, 80vw);
|
|
341
|
+
padding: 0.5rem 0.625rem;
|
|
342
|
+
border: 1px solid var(--border);
|
|
343
|
+
border-radius: var(--radius, 0.5rem);
|
|
344
|
+
background: var(--popover, var(--background, var(--muted)));
|
|
345
|
+
color: var(--popover-foreground, var(--foreground));
|
|
346
|
+
box-shadow: 0 4px 12px rgb(0 0 0 / 0.12);
|
|
347
|
+
font-size: calc(0.8125rem * var(--surf-reading-scale, 1));
|
|
348
|
+
font-weight: 400;
|
|
349
|
+
line-height: 1.5;
|
|
350
|
+
white-space: normal;
|
|
351
|
+
opacity: 0;
|
|
352
|
+
visibility: hidden;
|
|
353
|
+
transition: opacity 0.12s ease, visibility 0.12s ease;
|
|
354
|
+
pointer-events: none;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="reference"]:hover [data-ncm-ref-popover],
|
|
358
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="reference"]:focus-within [data-ncm-ref-popover],
|
|
359
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="footnote"]:hover [data-ncm-ref-popover],
|
|
360
|
+
[data-ncm-document].ncm-theme-nuu [data-ncm-token="footnote"]:focus-within [data-ncm-ref-popover] {
|
|
361
|
+
opacity: 1;
|
|
362
|
+
visibility: visible;
|
|
363
|
+
pointer-events: auto;
|
|
364
|
+
}
|