@superbuilders/incept-renderer 0.1.11 → 0.1.13

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.
@@ -0,0 +1,29 @@
1
+ import { A as AssessmentItem, a as AssessmentStimulus } from './schema-DKduufCs.js';
2
+
3
+ interface NormalizedNode {
4
+ tagName: string;
5
+ attrs: Record<string, unknown>;
6
+ children: Array<NormalizedNode | string>;
7
+ }
8
+ declare function parseAssessmentItemXml(xml: string): AssessmentItem;
9
+ /**
10
+ * Parses a QTI 3.0 Assessment Stimulus XML document.
11
+ *
12
+ * Assessment Stimuli are standalone reading materials (articles, passages, etc.)
13
+ * that can be referenced by one or more assessment items.
14
+ *
15
+ * @param xml - The raw XML string of the stimulus
16
+ * @returns A validated AssessmentStimulus object
17
+ * @throws If the XML is invalid or missing required elements
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const stimulus = parseAssessmentStimulusXml(xmlString)
22
+ * // stimulus.identifier - unique ID
23
+ * // stimulus.title - human-readable title
24
+ * // stimulus.bodyHtml - the HTML content to render
25
+ * ```
26
+ */
27
+ declare function parseAssessmentStimulusXml(xml: string): AssessmentStimulus;
28
+
29
+ export { type NormalizedNode as N, parseAssessmentStimulusXml as a, parseAssessmentItemXml as p };
@@ -0,0 +1,178 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { e as DisplayBlock, k as DisplayItem, a as AssessmentStimulus } from './schema-DKduufCs.js';
3
+
4
+ /** Theme options for the QTI renderer */
5
+ type QTITheme = "duolingo" | "neobrutalist" | (string & {});
6
+ /** Feedback result for a single response */
7
+ interface ResponseFeedback {
8
+ isCorrect: boolean;
9
+ messageHtml?: string;
10
+ }
11
+ /** Correctness info for selected choices */
12
+ interface ChoiceCorrectness {
13
+ id: string;
14
+ isCorrect: boolean;
15
+ }
16
+ /**
17
+ * Props for the QTIRenderer component.
18
+ *
19
+ * This is a **controlled, display-only component**. It renders the question
20
+ * and captures user input, but does NOT include submit buttons or flow logic.
21
+ * The consuming app is responsible for:
22
+ * - Providing responses state
23
+ * - Handling submission
24
+ * - Providing feedback after validation
25
+ * - Rendering buttons (Check, Try Again, Continue, etc.)
26
+ */
27
+ interface QTIRendererProps {
28
+ /**
29
+ * The display-safe item to render.
30
+ * Use `buildDisplayModel()` to create this from a parsed AssessmentItem.
31
+ */
32
+ item: DisplayItem;
33
+ /**
34
+ * Current user responses, keyed by response identifier.
35
+ * This is a controlled component - you must manage this state.
36
+ * @example { "RESPONSE": "A" } or { "RESPONSE": ["A", "C"] }
37
+ */
38
+ responses: Record<string, string | string[]>;
39
+ /**
40
+ * Callback fired when user selects/changes an answer.
41
+ * Update your responses state in this callback.
42
+ */
43
+ onResponseChange: (responseId: string, value: string | string[]) => void;
44
+ /**
45
+ * Theme to apply. Defaults to "duolingo".
46
+ * Available themes: "duolingo", "neobrutalist", or any custom theme
47
+ * defined via `[data-qti-theme="your-theme"]` CSS.
48
+ */
49
+ theme?: QTITheme;
50
+ /**
51
+ * Whether to show feedback states (correct/incorrect styling).
52
+ * Set to true after validation to display results.
53
+ */
54
+ showFeedback?: boolean;
55
+ /**
56
+ * Whether to disable all interactions.
57
+ * Typically set to true when showFeedback is true.
58
+ */
59
+ disabled?: boolean;
60
+ /**
61
+ * Per-choice correctness for highlighting selected answers.
62
+ * Keyed by response identifier.
63
+ */
64
+ choiceCorrectness?: Record<string, ChoiceCorrectness[]>;
65
+ /**
66
+ * Per-response feedback messages to display.
67
+ * Keyed by response identifier.
68
+ */
69
+ responseFeedback?: Record<string, ResponseFeedback>;
70
+ /**
71
+ * Overall feedback to display at the end of the question.
72
+ */
73
+ overallFeedback?: ResponseFeedback;
74
+ /**
75
+ * Additional CSS class for the container.
76
+ */
77
+ className?: string;
78
+ }
79
+ interface ContentBlockRendererProps {
80
+ /** The content block to render */
81
+ block: DisplayBlock;
82
+ /** Current user responses */
83
+ responses?: Record<string, string | string[]>;
84
+ /** Callback when user selects an answer */
85
+ onAnswerSelect?: (responseIdentifier: string, value: string | string[]) => void;
86
+ /** Whether to show feedback */
87
+ showFeedback?: boolean;
88
+ /** Whether to disable interactions */
89
+ disabled?: boolean;
90
+ /** Selected-only correctness mapping for this render pass */
91
+ selectedChoicesByResponse?: Record<string, Array<{
92
+ id: string;
93
+ isCorrect: boolean;
94
+ }>>;
95
+ /** Optional per-response feedback messages from server */
96
+ perResponseFeedback?: Record<string, {
97
+ isCorrect: boolean;
98
+ messageHtml?: string;
99
+ }>;
100
+ }
101
+ /**
102
+ * Renders a single content block (stimulus or interaction)
103
+ */
104
+ declare function ContentBlockRenderer({ block, responses, onAnswerSelect, showFeedback, disabled, selectedChoicesByResponse, perResponseFeedback }: ContentBlockRendererProps): react_jsx_runtime.JSX.Element | null;
105
+ /**
106
+ * A controlled, display-only component for rendering QTI assessment items.
107
+ *
108
+ * **This component does NOT include buttons or submission logic.**
109
+ * The consuming app is responsible for:
110
+ * - Managing `responses` state
111
+ * - Rendering Check/Submit/Try Again buttons
112
+ * - Calling validation APIs
113
+ * - Providing feedback data after validation
114
+ *
115
+ * @example
116
+ * ```tsx
117
+ * const [responses, setResponses] = useState({})
118
+ * const [feedback, setFeedback] = useState(null)
119
+ *
120
+ * <QTIRenderer
121
+ * item={displayItem}
122
+ * responses={responses}
123
+ * onResponseChange={(id, value) => setResponses(prev => ({ ...prev, [id]: value }))}
124
+ * theme="neobrutalist"
125
+ * showFeedback={!!feedback}
126
+ * responseFeedback={feedback?.perResponse}
127
+ * overallFeedback={feedback?.overall}
128
+ * disabled={!!feedback}
129
+ * />
130
+ *
131
+ * <button onClick={handleCheck}>Check Answer</button>
132
+ * ```
133
+ */
134
+ declare function QTIRenderer({ item, responses, onResponseChange, theme, showFeedback, disabled, choiceCorrectness, responseFeedback, overallFeedback, className }: QTIRendererProps): react_jsx_runtime.JSX.Element;
135
+
136
+ /**
137
+ * Props for the QTIStimulusRenderer component.
138
+ *
139
+ * This is a simple, display-only component for rendering QTI Assessment Stimuli
140
+ * (reading materials, passages, articles).
141
+ * It does not handle interactions.
142
+ */
143
+ type QTIStimulusRendererProps = {
144
+ /**
145
+ * The parsed stimulus to render.
146
+ * Use `parseAssessmentStimulusXml()` to create this from raw XML.
147
+ */
148
+ stimulus: AssessmentStimulus;
149
+ /**
150
+ * Additional CSS class for the container.
151
+ */
152
+ className?: string;
153
+ };
154
+ /**
155
+ * Renders a QTI 3.0 Assessment Stimulus (reading material).
156
+ *
157
+ * Assessment Stimuli are standalone content (articles, passages, etc.)
158
+ * that provide context for assessment items. This component renders
159
+ * the stimulus body HTML with proper support for:
160
+ *
161
+ * - Standard HTML elements (headings, lists, paragraphs, tables)
162
+ * - Images with responsive sizing
163
+ * - MathML mathematical expressions
164
+ * - Figures and figcaptions
165
+ * - Links and text formatting
166
+ * - Collapsible details/summary sections
167
+ *
168
+ * @example
169
+ * ```tsx
170
+ * import { parseAssessmentStimulusXml, QTIStimulusRenderer } from "@superbuilders/incept-renderer"
171
+ *
172
+ * const stimulus = parseAssessmentStimulusXml(xmlString)
173
+ * <QTIStimulusRenderer stimulus={stimulus} className="my-8" />
174
+ * ```
175
+ */
176
+ declare function QTIStimulusRenderer({ stimulus, className }: QTIStimulusRendererProps): react_jsx_runtime.JSX.Element;
177
+
178
+ export { type ChoiceCorrectness as C, type QTIRendererProps as Q, type ResponseFeedback as R, type ContentBlockRendererProps as a, type QTIStimulusRendererProps as b, type QTITheme as c, ContentBlockRenderer as d, QTIRenderer as e, QTIStimulusRenderer as f };
@@ -1,138 +1,105 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { a as DisplayBlock, g as DisplayItem } from './types-B7YRTQKt.js';
3
1
  import { z } from 'zod';
4
2
 
5
- /** Theme options for the QTI renderer */
6
- type QTITheme = "duolingo" | "neobrutalist" | (string & {});
7
- /** Feedback result for a single response */
8
- interface ResponseFeedback {
9
- isCorrect: boolean;
10
- messageHtml?: string;
11
- }
12
- /** Correctness info for selected choices */
13
- interface ChoiceCorrectness {
3
+ type DisplayChoice = {
14
4
  id: string;
15
- isCorrect: boolean;
16
- }
17
- /**
18
- * Props for the QTIRenderer component.
19
- *
20
- * This is a **controlled, display-only component**. It renders the question
21
- * and captures user input, but does NOT include submit buttons or flow logic.
22
- * The consuming app is responsible for:
23
- * - Providing responses state
24
- * - Handling submission
25
- * - Providing feedback after validation
26
- * - Rendering buttons (Check, Try Again, Continue, etc.)
27
- */
28
- interface QTIRendererProps {
29
- /**
30
- * The display-safe item to render.
31
- * Use `buildDisplayModel()` to create this from a parsed AssessmentItem.
32
- */
33
- item: DisplayItem;
34
- /**
35
- * Current user responses, keyed by response identifier.
36
- * This is a controlled component - you must manage this state.
37
- * @example { "RESPONSE": "A" } or { "RESPONSE": ["A", "C"] }
38
- */
39
- responses: Record<string, string | string[]>;
40
- /**
41
- * Callback fired when user selects/changes an answer.
42
- * Update your responses state in this callback.
43
- */
44
- onResponseChange: (responseId: string, value: string | string[]) => void;
45
- /**
46
- * Theme to apply. Defaults to "duolingo".
47
- * Available themes: "duolingo", "neobrutalist", or any custom theme
48
- * defined via `[data-qti-theme="your-theme"]` CSS.
49
- */
50
- theme?: QTITheme;
51
- /**
52
- * Whether to show feedback states (correct/incorrect styling).
53
- * Set to true after validation to display results.
54
- */
55
- showFeedback?: boolean;
56
- /**
57
- * Whether to disable all interactions.
58
- * Typically set to true when showFeedback is true.
59
- */
60
- disabled?: boolean;
61
- /**
62
- * Per-choice correctness for highlighting selected answers.
63
- * Keyed by response identifier.
64
- */
65
- choiceCorrectness?: Record<string, ChoiceCorrectness[]>;
66
- /**
67
- * Per-response feedback messages to display.
68
- * Keyed by response identifier.
69
- */
70
- responseFeedback?: Record<string, ResponseFeedback>;
71
- /**
72
- * Overall feedback to display at the end of the question.
73
- */
74
- overallFeedback?: ResponseFeedback;
75
- /**
76
- * Additional CSS class for the container.
77
- */
78
- className?: string;
79
- }
80
- interface ContentBlockRendererProps {
81
- /** The content block to render */
82
- block: DisplayBlock;
83
- /** Current user responses */
84
- responses?: Record<string, string | string[]>;
85
- /** Callback when user selects an answer */
86
- onAnswerSelect?: (responseIdentifier: string, value: string | string[]) => void;
87
- /** Whether to show feedback */
88
- showFeedback?: boolean;
89
- /** Whether to disable interactions */
90
- disabled?: boolean;
91
- /** Selected-only correctness mapping for this render pass */
92
- selectedChoicesByResponse?: Record<string, Array<{
5
+ contentHtml: string;
6
+ inlineFeedbackHtml?: string;
7
+ };
8
+ type DisplayChoiceInteraction = {
9
+ type: "choice";
10
+ responseId: string;
11
+ cardinality: "single" | "multiple";
12
+ promptHtml: string;
13
+ choices: DisplayChoice[];
14
+ minChoices: number;
15
+ maxChoices: number;
16
+ };
17
+ type DisplayTextInteraction = {
18
+ type: "text";
19
+ responseId: string;
20
+ expectedLength?: number;
21
+ placeholder?: string;
22
+ patternMask?: string;
23
+ };
24
+ type DisplayTextEmbed = {
25
+ responseId: string;
26
+ expectedLength?: number;
27
+ placeholder?: string;
28
+ patternMask?: string;
29
+ };
30
+ type DisplayOrderInteraction = {
31
+ type: "order";
32
+ responseId: string;
33
+ promptHtml: string;
34
+ choices: DisplayChoice[];
35
+ orientation: "vertical" | "horizontal";
36
+ };
37
+ type DisplayGapText = {
38
+ id: string;
39
+ contentHtml: string;
40
+ matchMax: number;
41
+ };
42
+ type DisplayGap = {
43
+ id: string;
44
+ };
45
+ type DisplayGapMatchInteraction = {
46
+ type: "gapMatch";
47
+ responseId: string;
48
+ gapTexts: DisplayGapText[];
49
+ gaps: DisplayGap[];
50
+ contentHtml: string;
51
+ };
52
+ type DisplayAssociableChoice = {
53
+ id: string;
54
+ contentHtml: string;
55
+ matchMax: number;
56
+ };
57
+ type DisplayMatchInteraction = {
58
+ type: "match";
59
+ responseId: string;
60
+ promptHtml: string;
61
+ maxAssociations: number;
62
+ sourceChoices: DisplayAssociableChoice[];
63
+ targetChoices: DisplayAssociableChoice[];
64
+ };
65
+ type DisplayInteraction = DisplayChoiceInteraction | DisplayTextInteraction | DisplayOrderInteraction | DisplayGapMatchInteraction | DisplayMatchInteraction;
66
+ type DisplayInlineEmbed = {
67
+ responseId: string;
68
+ shuffle: boolean;
69
+ choices: Array<Pick<DisplayChoice, "id" | "contentHtml">>;
70
+ };
71
+ type DisplayBlock = {
72
+ type: "stimulus";
73
+ html: string;
74
+ } | {
75
+ type: "richStimulus";
76
+ html: string;
77
+ inlineEmbeds: Record<string, DisplayInlineEmbed>;
78
+ textEmbeds: Record<string, DisplayTextEmbed>;
79
+ } | {
80
+ type: "interaction";
81
+ interaction: DisplayInteraction;
82
+ };
83
+ type DisplayItem = {
84
+ title: string;
85
+ contentBlocks: DisplayBlock[];
86
+ };
87
+ type FormShape = Record<string, "single" | "multiple" | "ordered" | "directedPair">;
88
+ type ValidateResult = {
89
+ overallCorrect: boolean;
90
+ perResponse: Record<string, {
91
+ isCorrect: boolean;
92
+ messageHtml?: string;
93
+ }>;
94
+ selectedChoicesByResponse: Record<string, Array<{
93
95
  id: string;
94
96
  isCorrect: boolean;
95
97
  }>>;
96
- /** Optional per-response feedback messages from server */
97
- perResponseFeedback?: Record<string, {
98
+ overallFeedback?: {
98
99
  isCorrect: boolean;
99
100
  messageHtml?: string;
100
- }>;
101
- }
102
- /**
103
- * Renders a single content block (stimulus or interaction)
104
- */
105
- declare function ContentBlockRenderer({ block, responses, onAnswerSelect, showFeedback, disabled, selectedChoicesByResponse, perResponseFeedback }: ContentBlockRendererProps): react_jsx_runtime.JSX.Element | null;
106
- /**
107
- * A controlled, display-only component for rendering QTI assessment items.
108
- *
109
- * **This component does NOT include buttons or submission logic.**
110
- * The consuming app is responsible for:
111
- * - Managing `responses` state
112
- * - Rendering Check/Submit/Try Again buttons
113
- * - Calling validation APIs
114
- * - Providing feedback data after validation
115
- *
116
- * @example
117
- * ```tsx
118
- * const [responses, setResponses] = useState({})
119
- * const [feedback, setFeedback] = useState(null)
120
- *
121
- * <QTIRenderer
122
- * item={displayItem}
123
- * responses={responses}
124
- * onResponseChange={(id, value) => setResponses(prev => ({ ...prev, [id]: value }))}
125
- * theme="neobrutalist"
126
- * showFeedback={!!feedback}
127
- * responseFeedback={feedback?.perResponse}
128
- * overallFeedback={feedback?.overall}
129
- * disabled={!!feedback}
130
- * />
131
- *
132
- * <button onClick={handleCheck}>Check Answer</button>
133
- * ```
134
- */
135
- declare function QTIRenderer({ item, responses, onResponseChange, theme, showFeedback, disabled, choiceCorrectness, responseFeedback, overallFeedback, className }: QTIRendererProps): react_jsx_runtime.JSX.Element;
101
+ };
102
+ };
136
103
 
137
104
  declare const ChoiceInteractionSchema: z.ZodObject<{
138
105
  responseIdentifier: z.ZodString;
@@ -573,5 +540,16 @@ declare const AssessmentItemSchema: z.ZodObject<{
573
540
  }, z.core.$strip>;
574
541
  }, z.core.$strip>;
575
542
  type AssessmentItem = z.infer<typeof AssessmentItemSchema>;
543
+ /**
544
+ * Represents a QTI 3.0 Assessment Stimulus.
545
+ * Stimuli are standalone reading materials that can be referenced by assessment items.
546
+ */
547
+ declare const AssessmentStimulusSchema: z.ZodObject<{
548
+ identifier: z.ZodString;
549
+ title: z.ZodDefault<z.ZodString>;
550
+ xmlLang: z.ZodDefault<z.ZodString>;
551
+ bodyHtml: z.ZodString;
552
+ }, z.core.$strip>;
553
+ type AssessmentStimulus = z.infer<typeof AssessmentStimulusSchema>;
576
554
 
577
- export { type AnyCondition as A, type ChoiceCorrectness as C, type FeedbackBlock as F, type GapMatchInteraction as G, type InlineChoiceInteraction as I, type MatchInteraction as M, type OrderInteraction as O, type QTIRendererProps as Q, type ResponseFeedback as R, type TextEntryInteraction as T, type ContentBlockRendererProps as a, type QTITheme as b, type AnyInteraction as c, type AssessmentItem as d, type ChoiceInteraction as e, type ResponseDeclaration as f, type ResponseProcessing as g, ContentBlockRenderer as h, QTIRenderer as i, AssessmentItemSchema as j };
555
+ export { type AssessmentItem as A, type ChoiceInteraction as C, type DisplayAssociableChoice as D, type FeedbackBlock as F, type GapMatchInteraction as G, type InlineChoiceInteraction as I, type MatchInteraction as M, type OrderInteraction as O, type ResponseDeclaration as R, type TextEntryInteraction as T, type ValidateResult as V, type AssessmentStimulus as a, type AnyCondition as b, type AnyInteraction as c, type ResponseProcessing as d, type DisplayBlock as e, type DisplayChoice as f, type DisplayChoiceInteraction as g, type DisplayGap as h, type DisplayGapText as i, type DisplayInlineEmbed as j, type DisplayItem as k, type DisplayTextEmbed as l, type FormShape as m, AssessmentItemSchema as n, AssessmentStimulusSchema as o };
@@ -168,6 +168,18 @@
168
168
  .qti-html-content math mtext {
169
169
  color: inherit !important;
170
170
  }
171
+ .qti-html-content menclose[notation=top],
172
+ .qti-html-content .tml-overline,
173
+ menclose[notation=top],
174
+ .tml-overline {
175
+ border-top: 0.07em solid currentColor;
176
+ padding-top: 0.12em;
177
+ margin-right: 0.1em;
178
+ }
179
+ .qti-html-content mover > mo[stretchy=true],
180
+ mover > mo[stretchy=true] {
181
+ transform: scaleX(1.3);
182
+ }
171
183
  [data-slot=choice-indicator].rounded-xs,
172
184
  [data-slot=choice-indicator] {
173
185
  border-radius: 12px !important;
@@ -218,4 +230,12 @@
218
230
  background: oklch(0.9221 0.0087 17.31 / 0.3) !important;
219
231
  border-color: var(--duolingo-cardinal) !important;
220
232
  }
233
+ .qti-html-content math mi,
234
+ .qti-html-content math mn,
235
+ .qti-html-content math mtext,
236
+ math mi,
237
+ math mn,
238
+ math mtext {
239
+ font-weight: 600;
240
+ }
221
241
  /*# sourceMappingURL=duolingo.css.map */
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/styles/duolingo.css"],"sourcesContent":["/* ============================================\n DUOLINGO THEME FOR QTI RENDERER\n Self-contained theme - import this alongside themes.css\n Usage: import \"@qti-renderer/styles/duolingo.css\"\n ============================================ */\n\n/* ============================================\n DUOLINGO COLOR PALETTE\n ============================================ */\n\n:root {\n\t/* Grayscale */\n\t--duolingo-polar: oklch(0.9761 0 0);\n\t--duolingo-swan: oklch(0.9219 0 0);\n\t--duolingo-hare: oklch(0.754 0 0);\n\t--duolingo-wolf: oklch(0.5693 0 0);\n\t--duolingo-eel: oklch(0.4128 0 0);\n\n\t/* Reds */\n\t--duolingo-squid: oklch(0.9221 0.0087 17.31);\n\t--duolingo-walking-fish: oklch(0.9303 0.0355 15.66);\n\t--duolingo-flamingo: oklch(0.8365 0.0903 19.14);\n\t--duolingo-pig: oklch(0.7979 0.0965 19.42);\n\t--duolingo-crab: oklch(0.7314 0.1652 21.99);\n\t--duolingo-cardinal: oklch(0.6708 0.2165 25.19);\n\t--duolingo-fire-ant: oklch(0.6059 0.2241 27.19);\n\n\t/* Yellows/Oranges */\n\t--duolingo-canary: oklch(0.9693 0.0455 93.5);\n\t--duolingo-duck: oklch(0.9168 0.1416 99.05);\n\t--duolingo-bee: oklch(0.8575 0.1752 88.49);\n\t--duolingo-lion: oklch(0.8142 0.1704 76.91);\n\t--duolingo-fox: oklch(0.7669 0.1748 63.06);\n\t--duolingo-cheetah: oklch(0.8801 0.098 73.41);\n\t--duolingo-monkey: oklch(0.7625 0.1199 66.64);\n\t--duolingo-camel: oklch(0.767 0.1586 80.31);\n\t--duolingo-guinea-pig: oklch(0.6532 0.147779 63.9665);\n\t--duolingo-grizzly: oklch(0.572 0.0946 48.48);\n\n\t/* Greens */\n\t--duolingo-sea-sponge: oklch(0.9546 0.1012 131.98);\n\t--duolingo-turtle: oklch(0.8717 0.1754 133.4);\n\t--duolingo-owl: oklch(0.7478 0.2289 137.63);\n\t--duolingo-tree-frog: oklch(0.6516 0.1894 134.73);\n\n\t/* Blues */\n\t--duolingo-iguana: oklch(0.9536 0.0284 228.04);\n\t--duolingo-anchovy: oklch(0.9066 0.02 212.55);\n\t--duolingo-beluga: oklch(0.9277 0.0584 213.8);\n\t--duolingo-moon-jelly: oklch(0.8875 0.1069 196.87);\n\t--duolingo-blue-jay: oklch(0.8429 0.0982 229.43);\n\t--duolingo-macaw: oklch(0.7181 0.1513 237.07);\n\t--duolingo-whale: oklch(0.6476 0.1358 236.91);\n\t--duolingo-humpback: oklch(0.5493 0.1544 256.44);\n\t--duolingo-narwhal: oklch(0.4514 0.1434 256.99);\n\n\t/* Purples/Pinks */\n\t--duolingo-starfish: oklch(0.8359 0.1184 342.63);\n\t--duolingo-beetle: oklch(0.7345 0.1876 310.63);\n\t--duolingo-betta: oklch(0.604 0.1505 299.92);\n\t--duolingo-butterfly: oklch(0.4981 0.1306 300.05);\n\n\t/* Semantic color aliases (used by components) */\n\t--color-polar: var(--duolingo-polar);\n\t--color-swan: var(--duolingo-swan);\n\t--color-hare: var(--duolingo-hare);\n\t--color-wolf: var(--duolingo-wolf);\n\t--color-eel: var(--duolingo-eel);\n\t--color-squid: var(--duolingo-squid);\n\t--color-walking-fish: var(--duolingo-walking-fish);\n\t--color-flamingo: var(--duolingo-flamingo);\n\t--color-pig: var(--duolingo-pig);\n\t--color-crab: var(--duolingo-crab);\n\t--color-cardinal: var(--duolingo-cardinal);\n\t--color-fire-ant: var(--duolingo-fire-ant);\n\t--color-canary: var(--duolingo-canary);\n\t--color-duck: var(--duolingo-duck);\n\t--color-bee: var(--duolingo-bee);\n\t--color-lion: var(--duolingo-lion);\n\t--color-fox: var(--duolingo-fox);\n\t--color-cheetah: var(--duolingo-cheetah);\n\t--color-monkey: var(--duolingo-monkey);\n\t--color-camel: var(--duolingo-camel);\n\t--color-guinea-pig: var(--duolingo-guinea-pig);\n\t--color-grizzly: var(--duolingo-grizzly);\n\t--color-sea-sponge: var(--duolingo-sea-sponge);\n\t--color-turtle: var(--duolingo-turtle);\n\t--color-owl: var(--duolingo-owl);\n\t--color-tree-frog: var(--duolingo-tree-frog);\n\t--color-iguana: var(--duolingo-iguana);\n\t--color-anchovy: var(--duolingo-anchovy);\n\t--color-beluga: var(--duolingo-beluga);\n\t--color-moon-jelly: var(--duolingo-moon-jelly);\n\t--color-blue-jay: var(--duolingo-blue-jay);\n\t--color-macaw: var(--duolingo-macaw);\n\t--color-whale: var(--duolingo-whale);\n\t--color-humpback: var(--duolingo-humpback);\n\t--color-narwhal: var(--duolingo-narwhal);\n\t--color-starfish: var(--duolingo-starfish);\n\t--color-beetle: var(--duolingo-beetle);\n\t--color-betta: var(--duolingo-betta);\n\t--color-butterfly: var(--duolingo-butterfly);\n\n\t/* Base theme variables */\n\t--background: var(--duolingo-polar);\n\t--foreground: var(--duolingo-eel);\n\t--muted: var(--duolingo-swan);\n\t--muted-foreground: var(--duolingo-wolf);\n\t--border: var(--duolingo-swan);\n\t--input: var(--duolingo-hare);\n\t--accent: var(--duolingo-swan);\n\t--color-background: var(--background);\n\t--color-foreground: var(--foreground);\n\t--color-muted: var(--muted);\n\t--color-muted-foreground: var(--muted-foreground);\n\t--color-border: var(--border);\n\t--color-input: var(--input);\n\t--color-accent: var(--accent);\n\n\t/* Radius */\n\t--radius: 1rem;\n\t--radius-xs: 0.5rem;\n\t--radius-sm: 0.75rem;\n\t--radius-md: 0.875rem;\n\t--radius-lg: 1rem;\n}\n\n/* Dark mode */\n.dark {\n\t--background: oklch(0.2301 0.0215 228.5177);\n\t--foreground: var(--duolingo-polar);\n\t--muted: oklch(0.3847 0.0246 234.6115);\n\t--muted-foreground: oklch(0.494 0.0263 225.3177);\n\t--border: oklch(0.3847 0.0246 234.6115);\n\t--input: oklch(0.494 0.0263 225.3177);\n\t--accent: oklch(0.2949 0.0237 228.4373);\n\t--color-background: var(--background);\n\t--color-foreground: var(--foreground);\n\t--color-muted: var(--muted);\n\t--color-muted-foreground: var(--muted-foreground);\n\t--color-border: var(--border);\n\t--color-input: var(--input);\n\t--color-accent: var(--accent);\n}\n\n/* ============================================\n QTI HTML CONTENT STYLING\n Typography, lists, dark mode fixes\n ============================================ */\n\n.qti-html-content {\n\tcolor: inherit !important;\n}\n\n.qti-html-content *,\n.qti-html-content p,\n.qti-html-content div,\n.qti-html-content span,\n.qti-html-content li {\n\tcolor: inherit !important;\n}\n\n.qti-html-content .qti-feedback-preamble p,\n.qti-html-content .qti-step p,\n.qti-html-content .qti-step-title {\n\tcolor: inherit !important;\n}\n\n.qti-html-content .qti-step-index {\n\tcolor: white !important;\n}\n\n.qti-html-content .qti-step {\n\tbackground: transparent !important;\n\tborder-color: var(--border) !important;\n}\n\n.qti-html-content strong,\n.qti-html-content b {\n\tfont-weight: 700;\n}\n\n.qti-html-content em,\n.qti-html-content i {\n\tfont-style: italic;\n}\n\n.qti-html-content p {\n\tmargin-bottom: 0.5rem;\n}\n\n.qti-html-content ul {\n\tmargin-left: 1.5rem;\n\tmargin-bottom: 0.5rem;\n\tlist-style-type: disc;\n}\n\n.qti-html-content ol {\n\tmargin-left: 1.5rem;\n\tmargin-bottom: 0.5rem;\n\tlist-style-type: decimal;\n}\n\n.qti-html-content li {\n\tmargin-bottom: 0.25rem;\n}\n\n/* Math elements */\n.qti-html-content math,\n.qti-html-content math *,\n.qti-html-content math mi,\n.qti-html-content math mo,\n.qti-html-content math mn,\n.qti-html-content math mtext {\n\tcolor: inherit !important;\n}\n\n/* ============================================\n DUOLINGO CHOICE INDICATOR OVERRIDES\n Rounded squares for A, B, C, D indicators\n ============================================ */\n\n/* Base styles - rounded square shape */\n[data-slot=\"choice-indicator\"].rounded-xs,\n[data-slot=\"choice-indicator\"] {\n\tborder-radius: 12px !important;\n\tmin-width: 2rem !important;\n\tmin-height: 2rem !important;\n\twidth: 2rem !important;\n\theight: 2rem !important;\n}\n\n/* Radio buttons (NOT filled): border and text color, white background */\n[data-slot=\"choice-indicator\"][data-state=\"checked\"]:not([data-filled=\"true\"]) {\n\tbackground: var(--background) !important;\n\tborder-color: var(--duolingo-macaw) !important;\n\tcolor: var(--duolingo-macaw) !important;\n}\n\n/* Checkboxes (filled): fill with color + white inset for gap effect */\n[data-slot=\"choice-indicator\"][data-filled=\"true\"][data-state=\"checked\"] {\n\tbackground: var(--duolingo-macaw) !important;\n\tborder-color: var(--duolingo-macaw) !important;\n\tbox-shadow: inset 0 0 0 3px var(--background) !important;\n}\n\n/* Correct state - radio (not filled) */\n[data-slot=\"choice-indicator\"][data-palette=\"owl\"][data-state=\"checked\"]:not([data-filled=\"true\"]) {\n\tbackground: var(--background) !important;\n\tborder-color: var(--duolingo-tree-frog) !important;\n\tcolor: var(--duolingo-owl) !important;\n}\n\n/* Correct state - checkbox (filled) */\n[data-slot=\"choice-indicator\"][data-palette=\"owl\"][data-filled=\"true\"][data-state=\"checked\"] {\n\tbackground: var(--duolingo-owl) !important;\n\tborder-color: var(--duolingo-tree-frog) !important;\n\tbox-shadow: inset 0 0 0 3px var(--background) !important;\n}\n\n/* Incorrect state - radio (not filled) */\n[data-slot=\"choice-indicator\"][data-palette=\"cardinal\"][data-state=\"checked\"]:not([data-filled=\"true\"]) {\n\tbackground: var(--background) !important;\n\tborder-color: var(--duolingo-fire-ant) !important;\n\tcolor: var(--duolingo-cardinal) !important;\n}\n\n/* Incorrect state - checkbox (filled) */\n[data-slot=\"choice-indicator\"][data-palette=\"cardinal\"][data-filled=\"true\"][data-state=\"checked\"] {\n\tbackground: var(--duolingo-cardinal) !important;\n\tborder-color: var(--duolingo-fire-ant) !important;\n\tbox-shadow: inset 0 0 0 3px var(--background) !important;\n}\n\n/* ============================================\n DUOLINGO FIELD LABEL OVERRIDES\n Choice card styling\n ============================================ */\n\n/* Selected choice card background */\n[data-slot=\"field-label\"]:has(> [data-slot=\"field\"]):has([data-state=\"checked\"]) {\n\tbackground: oklch(0.9536 0.0284 228.04 / 0.3) !important; /* iguana/30 */\n\tborder-color: var(--duolingo-macaw) !important;\n}\n\n/* Correct choice card */\n[data-slot=\"field-label\"][data-palette=\"owl\"]:has(> [data-slot=\"field\"]):has([data-state=\"checked\"]) {\n\tbackground: oklch(0.9546 0.1012 131.98 / 0.3) !important; /* sea-sponge/30 */\n\tborder-color: var(--duolingo-owl) !important;\n}\n\n/* Incorrect choice card */\n[data-slot=\"field-label\"][data-palette=\"cardinal\"]:has(> [data-slot=\"field\"]):has([data-state=\"checked\"]) {\n\tbackground: oklch(0.9221 0.0087 17.31 / 0.3) !important; /* squid/30 */\n\tborder-color: var(--duolingo-cardinal) !important;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/styles/duolingo.css"],"sourcesContent":["/* ============================================\n DUOLINGO THEME FOR QTI RENDERER\n Self-contained theme - import this alongside themes.css\n Usage: import \"@qti-renderer/styles/duolingo.css\"\n ============================================ */\n\n/* ============================================\n DUOLINGO COLOR PALETTE\n ============================================ */\n\n:root {\n\t/* Grayscale */\n\t--duolingo-polar: oklch(0.9761 0 0);\n\t--duolingo-swan: oklch(0.9219 0 0);\n\t--duolingo-hare: oklch(0.754 0 0);\n\t--duolingo-wolf: oklch(0.5693 0 0);\n\t--duolingo-eel: oklch(0.4128 0 0);\n\n\t/* Reds */\n\t--duolingo-squid: oklch(0.9221 0.0087 17.31);\n\t--duolingo-walking-fish: oklch(0.9303 0.0355 15.66);\n\t--duolingo-flamingo: oklch(0.8365 0.0903 19.14);\n\t--duolingo-pig: oklch(0.7979 0.0965 19.42);\n\t--duolingo-crab: oklch(0.7314 0.1652 21.99);\n\t--duolingo-cardinal: oklch(0.6708 0.2165 25.19);\n\t--duolingo-fire-ant: oklch(0.6059 0.2241 27.19);\n\n\t/* Yellows/Oranges */\n\t--duolingo-canary: oklch(0.9693 0.0455 93.5);\n\t--duolingo-duck: oklch(0.9168 0.1416 99.05);\n\t--duolingo-bee: oklch(0.8575 0.1752 88.49);\n\t--duolingo-lion: oklch(0.8142 0.1704 76.91);\n\t--duolingo-fox: oklch(0.7669 0.1748 63.06);\n\t--duolingo-cheetah: oklch(0.8801 0.098 73.41);\n\t--duolingo-monkey: oklch(0.7625 0.1199 66.64);\n\t--duolingo-camel: oklch(0.767 0.1586 80.31);\n\t--duolingo-guinea-pig: oklch(0.6532 0.147779 63.9665);\n\t--duolingo-grizzly: oklch(0.572 0.0946 48.48);\n\n\t/* Greens */\n\t--duolingo-sea-sponge: oklch(0.9546 0.1012 131.98);\n\t--duolingo-turtle: oklch(0.8717 0.1754 133.4);\n\t--duolingo-owl: oklch(0.7478 0.2289 137.63);\n\t--duolingo-tree-frog: oklch(0.6516 0.1894 134.73);\n\n\t/* Blues */\n\t--duolingo-iguana: oklch(0.9536 0.0284 228.04);\n\t--duolingo-anchovy: oklch(0.9066 0.02 212.55);\n\t--duolingo-beluga: oklch(0.9277 0.0584 213.8);\n\t--duolingo-moon-jelly: oklch(0.8875 0.1069 196.87);\n\t--duolingo-blue-jay: oklch(0.8429 0.0982 229.43);\n\t--duolingo-macaw: oklch(0.7181 0.1513 237.07);\n\t--duolingo-whale: oklch(0.6476 0.1358 236.91);\n\t--duolingo-humpback: oklch(0.5493 0.1544 256.44);\n\t--duolingo-narwhal: oklch(0.4514 0.1434 256.99);\n\n\t/* Purples/Pinks */\n\t--duolingo-starfish: oklch(0.8359 0.1184 342.63);\n\t--duolingo-beetle: oklch(0.7345 0.1876 310.63);\n\t--duolingo-betta: oklch(0.604 0.1505 299.92);\n\t--duolingo-butterfly: oklch(0.4981 0.1306 300.05);\n\n\t/* Semantic color aliases (used by components) */\n\t--color-polar: var(--duolingo-polar);\n\t--color-swan: var(--duolingo-swan);\n\t--color-hare: var(--duolingo-hare);\n\t--color-wolf: var(--duolingo-wolf);\n\t--color-eel: var(--duolingo-eel);\n\t--color-squid: var(--duolingo-squid);\n\t--color-walking-fish: var(--duolingo-walking-fish);\n\t--color-flamingo: var(--duolingo-flamingo);\n\t--color-pig: var(--duolingo-pig);\n\t--color-crab: var(--duolingo-crab);\n\t--color-cardinal: var(--duolingo-cardinal);\n\t--color-fire-ant: var(--duolingo-fire-ant);\n\t--color-canary: var(--duolingo-canary);\n\t--color-duck: var(--duolingo-duck);\n\t--color-bee: var(--duolingo-bee);\n\t--color-lion: var(--duolingo-lion);\n\t--color-fox: var(--duolingo-fox);\n\t--color-cheetah: var(--duolingo-cheetah);\n\t--color-monkey: var(--duolingo-monkey);\n\t--color-camel: var(--duolingo-camel);\n\t--color-guinea-pig: var(--duolingo-guinea-pig);\n\t--color-grizzly: var(--duolingo-grizzly);\n\t--color-sea-sponge: var(--duolingo-sea-sponge);\n\t--color-turtle: var(--duolingo-turtle);\n\t--color-owl: var(--duolingo-owl);\n\t--color-tree-frog: var(--duolingo-tree-frog);\n\t--color-iguana: var(--duolingo-iguana);\n\t--color-anchovy: var(--duolingo-anchovy);\n\t--color-beluga: var(--duolingo-beluga);\n\t--color-moon-jelly: var(--duolingo-moon-jelly);\n\t--color-blue-jay: var(--duolingo-blue-jay);\n\t--color-macaw: var(--duolingo-macaw);\n\t--color-whale: var(--duolingo-whale);\n\t--color-humpback: var(--duolingo-humpback);\n\t--color-narwhal: var(--duolingo-narwhal);\n\t--color-starfish: var(--duolingo-starfish);\n\t--color-beetle: var(--duolingo-beetle);\n\t--color-betta: var(--duolingo-betta);\n\t--color-butterfly: var(--duolingo-butterfly);\n\n\t/* Base theme variables */\n\t--background: var(--duolingo-polar);\n\t--foreground: var(--duolingo-eel);\n\t--muted: var(--duolingo-swan);\n\t--muted-foreground: var(--duolingo-wolf);\n\t--border: var(--duolingo-swan);\n\t--input: var(--duolingo-hare);\n\t--accent: var(--duolingo-swan);\n\t--color-background: var(--background);\n\t--color-foreground: var(--foreground);\n\t--color-muted: var(--muted);\n\t--color-muted-foreground: var(--muted-foreground);\n\t--color-border: var(--border);\n\t--color-input: var(--input);\n\t--color-accent: var(--accent);\n\n\t/* Radius */\n\t--radius: 1rem;\n\t--radius-xs: 0.5rem;\n\t--radius-sm: 0.75rem;\n\t--radius-md: 0.875rem;\n\t--radius-lg: 1rem;\n}\n\n/* Dark mode */\n.dark {\n\t--background: oklch(0.2301 0.0215 228.5177);\n\t--foreground: var(--duolingo-polar);\n\t--muted: oklch(0.3847 0.0246 234.6115);\n\t--muted-foreground: oklch(0.494 0.0263 225.3177);\n\t--border: oklch(0.3847 0.0246 234.6115);\n\t--input: oklch(0.494 0.0263 225.3177);\n\t--accent: oklch(0.2949 0.0237 228.4373);\n\t--color-background: var(--background);\n\t--color-foreground: var(--foreground);\n\t--color-muted: var(--muted);\n\t--color-muted-foreground: var(--muted-foreground);\n\t--color-border: var(--border);\n\t--color-input: var(--input);\n\t--color-accent: var(--accent);\n}\n\n/* ============================================\n QTI HTML CONTENT STYLING\n Typography, lists, dark mode fixes\n ============================================ */\n\n.qti-html-content {\n\tcolor: inherit !important;\n}\n\n.qti-html-content *,\n.qti-html-content p,\n.qti-html-content div,\n.qti-html-content span,\n.qti-html-content li {\n\tcolor: inherit !important;\n}\n\n.qti-html-content .qti-feedback-preamble p,\n.qti-html-content .qti-step p,\n.qti-html-content .qti-step-title {\n\tcolor: inherit !important;\n}\n\n.qti-html-content .qti-step-index {\n\tcolor: white !important;\n}\n\n.qti-html-content .qti-step {\n\tbackground: transparent !important;\n\tborder-color: var(--border) !important;\n}\n\n.qti-html-content strong,\n.qti-html-content b {\n\tfont-weight: 700;\n}\n\n.qti-html-content em,\n.qti-html-content i {\n\tfont-style: italic;\n}\n\n.qti-html-content p {\n\tmargin-bottom: 0.5rem;\n}\n\n.qti-html-content ul {\n\tmargin-left: 1.5rem;\n\tmargin-bottom: 0.5rem;\n\tlist-style-type: disc;\n}\n\n.qti-html-content ol {\n\tmargin-left: 1.5rem;\n\tmargin-bottom: 0.5rem;\n\tlist-style-type: decimal;\n}\n\n.qti-html-content li {\n\tmargin-bottom: 0.25rem;\n}\n\n/* Math elements */\n.qti-html-content math,\n.qti-html-content math *,\n.qti-html-content math mi,\n.qti-html-content math mo,\n.qti-html-content math mn,\n.qti-html-content math mtext {\n\tcolor: inherit !important;\n}\n\n/* MathML menclose overline support (for line segment notation like S̅Z̅) */\n.qti-html-content menclose[notation=\"top\"],\n.qti-html-content .tml-overline,\nmenclose[notation=\"top\"],\n.tml-overline {\n\tborder-top: 0.07em solid currentColor;\n\tpadding-top: 0.12em;\n\tmargin-right: 0.1em;\n}\n\n/* MathML mover stretchy arrow - just scale the arrow wider */\n.qti-html-content mover>mo[stretchy=\"true\"],\nmover>mo[stretchy=\"true\"] {\n\ttransform: scaleX(1.3);\n}\n\n/* ============================================\n DUOLINGO CHOICE INDICATOR OVERRIDES\n Rounded squares for A, B, C, D indicators\n ============================================ */\n\n/* Base styles - rounded square shape */\n[data-slot=\"choice-indicator\"].rounded-xs,\n[data-slot=\"choice-indicator\"] {\n\tborder-radius: 12px !important;\n\tmin-width: 2rem !important;\n\tmin-height: 2rem !important;\n\twidth: 2rem !important;\n\theight: 2rem !important;\n}\n\n/* Radio buttons (NOT filled): border and text color, white background */\n[data-slot=\"choice-indicator\"][data-state=\"checked\"]:not([data-filled=\"true\"]) {\n\tbackground: var(--background) !important;\n\tborder-color: var(--duolingo-macaw) !important;\n\tcolor: var(--duolingo-macaw) !important;\n}\n\n/* Checkboxes (filled): fill with color + white inset for gap effect */\n[data-slot=\"choice-indicator\"][data-filled=\"true\"][data-state=\"checked\"] {\n\tbackground: var(--duolingo-macaw) !important;\n\tborder-color: var(--duolingo-macaw) !important;\n\tbox-shadow: inset 0 0 0 3px var(--background) !important;\n}\n\n/* Correct state - radio (not filled) */\n[data-slot=\"choice-indicator\"][data-palette=\"owl\"][data-state=\"checked\"]:not([data-filled=\"true\"]) {\n\tbackground: var(--background) !important;\n\tborder-color: var(--duolingo-tree-frog) !important;\n\tcolor: var(--duolingo-owl) !important;\n}\n\n/* Correct state - checkbox (filled) */\n[data-slot=\"choice-indicator\"][data-palette=\"owl\"][data-filled=\"true\"][data-state=\"checked\"] {\n\tbackground: var(--duolingo-owl) !important;\n\tborder-color: var(--duolingo-tree-frog) !important;\n\tbox-shadow: inset 0 0 0 3px var(--background) !important;\n}\n\n/* Incorrect state - radio (not filled) */\n[data-slot=\"choice-indicator\"][data-palette=\"cardinal\"][data-state=\"checked\"]:not([data-filled=\"true\"]) {\n\tbackground: var(--background) !important;\n\tborder-color: var(--duolingo-fire-ant) !important;\n\tcolor: var(--duolingo-cardinal) !important;\n}\n\n/* Incorrect state - checkbox (filled) */\n[data-slot=\"choice-indicator\"][data-palette=\"cardinal\"][data-filled=\"true\"][data-state=\"checked\"] {\n\tbackground: var(--duolingo-cardinal) !important;\n\tborder-color: var(--duolingo-fire-ant) !important;\n\tbox-shadow: inset 0 0 0 3px var(--background) !important;\n}\n\n/* ============================================\n DUOLINGO FIELD LABEL OVERRIDES\n Choice card styling\n ============================================ */\n\n/* Selected choice card background */\n[data-slot=\"field-label\"]:has(> [data-slot=\"field\"]):has([data-state=\"checked\"]) {\n\tbackground: oklch(0.9536 0.0284 228.04 / 0.3) !important;\n\t/* iguana/30 */\n\tborder-color: var(--duolingo-macaw) !important;\n}\n\n/* Correct choice card */\n[data-slot=\"field-label\"][data-palette=\"owl\"]:has(> [data-slot=\"field\"]):has([data-state=\"checked\"]) {\n\tbackground: oklch(0.9546 0.1012 131.98 / 0.3) !important;\n\t/* sea-sponge/30 */\n\tborder-color: var(--duolingo-owl) !important;\n}\n\n/* Incorrect choice card */\n[data-slot=\"field-label\"][data-palette=\"cardinal\"]:has(> [data-slot=\"field\"]):has([data-state=\"checked\"]) {\n\tbackground: oklch(0.9221 0.0087 17.31 / 0.3) !important;\n\t/* squid/30 */\n\tborder-color: var(--duolingo-cardinal) !important;\n}\n\n/* MathML bold text for maximum clarity */\n.qti-html-content math mi,\n.qti-html-content math mn,\n.qti-html-content math mtext,\nmath mi,\nmath mn,\nmath mtext {\n\tfont-weight: 600;\n}"],"mappings":"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","names":[]}