@mathscan/math-exercise-engine 1.1.2 → 1.1.3

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/dist/style.css CHANGED
@@ -188,11 +188,6 @@
188
188
  padding-bottom: calc(var(--exercise-line-gap) * 0.5);
189
189
  }
190
190
 
191
- .exercise-line-arabic {
192
- /* RTL layout handled by dir="rtl" attribute on text groups */
193
- /* No additional styling needed */
194
- }
195
-
196
191
  /* Content Styles */
197
192
 
198
193
  /**
@@ -348,6 +343,107 @@ mark {
348
343
  color: var(--exercise-text-light);
349
344
  }
350
345
 
346
+ /* ========================================
347
+ VERTICAL OPERATION
348
+ ======================================== */
349
+
350
+ .vop {
351
+ display: inline-grid;
352
+ grid-template-columns: repeat(var(--vop-cols, 4), minmax(2.2em, auto));
353
+ justify-content: end;
354
+ font-variant-numeric: tabular-nums;
355
+ font-size: 1.5em;
356
+ color: var(--exercise-text);
357
+ padding: 0.25em 0.5em;
358
+ margin: 0.5em 0;
359
+ }
360
+
361
+ .vop-row {
362
+ display: contents;
363
+ }
364
+
365
+ .vop-cell,
366
+ .vop-op-cell {
367
+ display: flex;
368
+ align-items: center;
369
+ justify-content: center;
370
+ min-height: 1.6em;
371
+ padding: 0.1em 0.15em;
372
+ }
373
+
374
+ .vop-cell-digit {
375
+ font-weight: 600;
376
+ }
377
+
378
+ .vop-cell-label {
379
+ font-weight: 600;
380
+ font-style: italic;
381
+ }
382
+
383
+ .vop-cell-color {
384
+ /* color applied inline via style prop */
385
+ font-weight: 600;
386
+ }
387
+
388
+ .vop-cell-bold {
389
+ font-weight: 700;
390
+ }
391
+
392
+ .vop-cell-highlight {
393
+ /* <mark> inside provides the highlight background */
394
+ }
395
+
396
+ .vop-carry-cell-color {
397
+ font-weight: 600;
398
+ }
399
+
400
+ .vop-carry-cell-bold {
401
+ font-weight: 700;
402
+ }
403
+
404
+ .vop-carry-cell-highlight {
405
+ /* <mark> inside provides the highlight background */
406
+ }
407
+
408
+ .vop-carry-row {
409
+ font-size: 0.65em;
410
+ line-height: 1;
411
+ align-items: flex-end;
412
+ }
413
+
414
+ .vop-carry-cell-digit,
415
+ .vop-carry-cell-label {
416
+ font-weight: 600;
417
+ }
418
+
419
+ .vop-carry-cell-empty {
420
+ /* blank placeholder in carry row */
421
+ }
422
+
423
+ .vop-carry-cell-input {
424
+ /* WidgetRenderer provides inner input box */
425
+ }
426
+
427
+ .vop-cell-empty {
428
+ /* blank shift placeholder */
429
+ }
430
+
431
+ .vop-cell-input {
432
+ /* WidgetRenderer provides the inner input box */
433
+ }
434
+
435
+ .vop-op {
436
+ /* inherit .operator color/size but align within its cell */
437
+ font-size: 1em;
438
+ }
439
+
440
+ .vop-sep {
441
+ grid-column: 1 / -1;
442
+ height: 0;
443
+ border-top: 2px solid var(--exercise-text, currentColor);
444
+ margin: 0.15em 0;
445
+ }
446
+
351
447
  /**
352
448
  * Input Styles
353
449
  *
@@ -421,6 +517,26 @@ mark {
421
517
  DRAG OPTIONS
422
518
  ======================================== */
423
519
 
520
+ .drag-options-container {
521
+ /* Container for drag options widget */
522
+ }
523
+
524
+ /*
525
+ * Shared base for every widget that sits inline within a text line.
526
+ *
527
+ * unicode-bidi: isolate — shields the widget from the surrounding bidi context
528
+ * so that symbols like > or < are never mirrored when the parent line carries
529
+ * dir="rtl" (RTL Arabic lines with inline widgets).
530
+ *
531
+ * To opt a new inline widget into this protection, simply add the class
532
+ * "inline-widget" to its root element. No other CSS changes needed.
533
+ */
534
+
535
+ .inline-widget {
536
+ unicode-bidi: isolate;
537
+ display: inline-block;
538
+ }
539
+
424
540
  .drag-options {
425
541
  display: flex;
426
542
  justify-content: center;
@@ -824,7 +940,13 @@ th.exercise-table-cell {
824
940
  fill: var(--visual-fraction-hover-color);
825
941
  }
826
942
 
827
- .visual-fraction-widget__sector[role='button']:focus-visible {
943
+ .visual-fraction-widget__sector[role="button"]:focus {
944
+ outline: none;
945
+ }
946
+
947
+ .visual-fraction-widget__sector[role="button"]:focus-visible {
948
+ /* Keyboard-only focus indicator: a drop-shadow that follows the SVG shape
949
+ instead of a rectangle, preserving accessibility without the visual glitch. */
828
950
  outline: none;
829
951
  filter: drop-shadow(0 0 0.18rem var(--exercise-border-focus, var(--exercise-primary, #007acc)));
830
952
  }
@@ -1080,8 +1202,22 @@ th.exercise-table-cell {
1080
1202
  --nl-arrow-gap: 8px;
1081
1203
  }
1082
1204
 
1083
- /* Chip zone: push the axis row down so chips overflowing upward
1084
- stay within the root boundary — no geometry side-effects on the axis */
1205
+ /* ========================================
1206
+ VALIDATION FEEDBACK
1207
+ ======================================== */
1208
+
1209
+ /* Axis colour: overriding --nl-axis-color on root propagates to track, ticks, arrows and labels. */
1210
+
1211
+ .number-line--correct { --nl-axis-color: #43B925; }
1212
+
1213
+ .number-line--incorrect { --nl-axis-color: #D6234D; }
1214
+
1215
+ /* Disable track transition for instant colour on submit. */
1216
+
1217
+ .number-line--correct .number-line-track,
1218
+ .number-line--incorrect .number-line-track { transition: none; }
1219
+
1220
+ /* Reserve space above axis for chips overflowing upward. */
1085
1221
 
1086
1222
  .number-line--drag-mode {
1087
1223
  padding-top: var(--nl-chip-zone-height);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mathscan/math-exercise-engine",
3
- "version": "1.1.2",
3
+ "version": "1.1.3",
4
4
  "description": "A DSL parser and validator for math exercises - transforms text-based exercise definitions into structured AST and JSON",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",