Improve UI: accessibility, wider cards, design polish - #17
Conversation
…er snippet headers - aria-live on dynamic counters and overflow notice, autocomplete on search input - font preload, color-scheme declaration, tabular-nums on stat values - prefers-reduced-motion block, touch-action: manipulation, stronger focus ring - Snippet card min-width 270px → 340px, subtopic overview 180px → 220px - Rail cards get border, shadow, and hover lift; mini-toggle highlights when checked - Replace Select all / Clear pair with single smart icon toggle button - Remove duplicate subtopic heading (rail-subtopic-head was redundant) - Remove Trap-aware chip; replace pill chips with compact square snippet-tag badges - Section headers now h4 with divider rule between subtopic groups - Deeper color palette, stronger shadows, header bottom shadow, sidebar border Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the app to use a new Markdown-first snippet bank while also documenting and wiring up the repo’s vision-first exam curation workflow, alongside several UI copy/accessibility tweaks.
Changes:
- Add a new
new_database/Markdown snippet corpus (topics/subtopics/snippets/pieces) and update repo docs to reflect it - Introduce/expand vision-first exam pipeline operator docs and artifacts under
data/vision_exam_pipeline/ - Update frontend HTML and JS to reflect “snippets/pieces” UX terminology, improve accessibility live regions, and extend inline/markdown rendering utilities
Reviewed changes
Copilot reviewed 174 out of 424 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
| new_database/content/functions-and-scope/imports-lambda/imports-and-aliases/README.md | Adds snippet-family README + metadata for imports/aliases. |
| new_database/content/functions-and-scope/imports-lambda/imports-and-aliases/02_immediate-exam-rule.md | Adds alias-usage rule example. |
| new_database/content/functions-and-scope/imports-lambda/imports-and-aliases/01_import-patterns.md | Adds compact import/alias pattern table. |
| new_database/content/functions-and-scope/imports-lambda/higher-order-lambda/README.md | Adds snippet-family README + metadata for lambda/higher-order functions. |
| new_database/content/functions-and-scope/imports-lambda/higher-order-lambda/03_trap-hint.md | Adds a one-line trap hint for map(...) output. |
| new_database/content/functions-and-scope/imports-lambda/higher-order-lambda/02_exam-style-examples.md | Adds exam-style lambda examples. |
| new_database/content/functions-and-scope/imports-lambda/higher-order-lambda/01_core-forms.md | Adds core lambda/map/higher-order reference table. |
| new_database/content/dicts-and-comprehensions/dicts/dict-running-totals-and-next-links/README.md | Adds snippet-family README + metadata for dict running totals/next links. |
| new_database/content/dicts-and-comprehensions/dicts/dict-running-totals-and-next-links/03_alternative-sorted-key-approach.md | Adds alternative running-total template (sorted keys). |
| new_database/content/dicts-and-comprehensions/dicts/dict-running-totals-and-next-links/02_running-total-dictionary.md | Adds running-total dictionary template. |
| new_database/content/dicts-and-comprehensions/dicts/dict-running-totals-and-next-links/01_next-link-dictionary.md | Adds next-link dictionary template using zip. |
| new_database/content/dicts-and-comprehensions/dicts/dict-iteration-equality/README.md | Adds snippet-family README + metadata for dict iteration/equality. |
| new_database/content/dicts-and-comprehensions/dicts/dict-iteration-equality/03_odd-one-out-pattern.md | Adds trap heuristic for bad for key, value in d: option. |
| new_database/content/dicts-and-comprehensions/dicts/dict-iteration-equality/02_correct-iteration-shapes.md | Adds correct .keys()/.values()/.items() iteration shapes + equality example. |
| new_database/content/dicts-and-comprehensions/dicts/dict-iteration-equality/01_two-must-know-facts.md | Adds “two must-know facts” table for dicts. |
| new_database/content/dicts-and-comprehensions/dicts/dict-build-count-aggregate/README.md | Adds snippet-family README + metadata for building/counting/aggregating dicts. |
| new_database/content/dicts-and-comprehensions/dicts/dict-build-count-aggregate/03_fast-reminder.md | Adds quick reminders for dict iteration, .values(), and .items(). |
| new_database/content/dicts-and-comprehensions/dicts/dict-build-count-aggregate/02_aggregate-over-dictionary-values.md | Adds examples for average and max aggregations using dict values/items. |
| new_database/content/dicts-and-comprehensions/dicts/dict-build-count-aggregate/01_core-templates.md | Adds core templates for dict building + frequency counting. |
| new_database/content/dicts-and-comprehensions/comprehensions/set-vs-list-vs-dict/README.md | Adds snippet-family README + metadata for set/list/dict comparisons. |
| new_database/content/dicts-and-comprehensions/comprehensions/set-vs-list-vs-dict/02_exam-pattern.md | Adds example showing two ways to get [5,4,3,2,1]. |
| new_database/content/dicts-and-comprehensions/comprehensions/set-vs-list-vs-dict/01_one-line-facts.md | Adds comparison table for list/set/dict properties. |
| new_database/content/dicts-and-comprehensions/comprehensions/list-comprehension-patterns/README.md | Adds snippet-family README + metadata for list comprehensions. |
| new_database/content/dicts-and-comprehensions/comprehensions/list-comprehension-patterns/03_placement-trap.md | Adds reminder about if placement vs if/else expression placement. |
| new_database/content/dicts-and-comprehensions/comprehensions/list-comprehension-patterns/02_examples-from-the-bank.md | Adds example list comprehensions from the question bank. |
| new_database/content/dicts-and-comprehensions/comprehensions/list-comprehension-patterns/01_syntax-patterns.md | Adds syntax-pattern reference table for list comprehensions. |
| new_database/content/dicts-and-comprehensions/comprehensions/dict-comprehension-patterns/README.md | Adds snippet-family README + metadata for dict comprehensions. |
| new_database/content/dicts-and-comprehensions/comprehensions/dict-comprehension-patterns/03_high-frequency-mistake.md | Adds a reminder not to swap key/value expressions. |
| new_database/content/dicts-and-comprehensions/comprehensions/dict-comprehension-patterns/02_counting-with-booleans.md | Adds example using boolean summation for counting. |
| new_database/content/dicts-and-comprehensions/comprehensions/dict-comprehension-patterns/01_core-shape.md | Adds core dict comprehension shape + examples. |
| new_database/content/datetime/sequence-generation/datetime-sequence-generation/README.md | Adds snippet-family README + metadata for datetime sequence generation. |
| new_database/content/datetime/sequence-generation/datetime-sequence-generation/03_most-common-mistake.md | Adds trap note about stringifying datetime too early. |
| new_database/content/datetime/sequence-generation/datetime-sequence-generation/02_dataframe-weekly-index.md | Adds DataFrame example for weekly datetime index formatting. |
| new_database/content/datetime/sequence-generation/datetime-sequence-generation/01_list-of-weekly-dates.md | Adds list template for weekly dates from a start string. |
| new_database/content/datetime/parsing-formatting/datetime-strptime-strftime/README.md | Adds snippet-family README + metadata for parsing/formatting. |
| new_database/content/datetime/parsing-formatting/datetime-strptime-strftime/03_exam-style-examples.md | Adds parsing/format arithmetic and ambiguous date-format examples. |
| new_database/content/datetime/parsing-formatting/datetime-strptime-strftime/02_directive-mini-table.md | Adds a directive mini-reference table. |
| new_database/content/datetime/parsing-formatting/datetime-strptime-strftime/01_parse-vs-format.md | Adds parse-vs-format high-level table. |
| new_database/content/datetime/parsing-formatting/datetime-build-from-parts/README.md | Adds snippet-family README + metadata for building datetimes from parts. |
| new_database/content/datetime/parsing-formatting/datetime-build-from-parts/03_from-dataframe-columns.md | Adds DataFrame-derived datetime construction example. |
| new_database/content/datetime/parsing-formatting/datetime-build-from-parts/02_from-date-string-and-time-string.md | Adds template for building datetime from date + time strings. |
| new_database/content/datetime/parsing-formatting/datetime-build-from-parts/01_constructor-order.md | Adds constructor-order reference table. |
| new_database/content/datetime/arithmetic-and-overlap/datetime-timedelta-day-counts/README.md | Adds snippet-family README + metadata for timedelta/day-count patterns. |
| new_database/content/datetime/arithmetic-and-overlap/datetime-timedelta-day-counts/03_type-trap.md | Adds trap note about adding timedelta to strings. |
| new_database/content/datetime/arithmetic-and-overlap/datetime-timedelta-day-counts/02_inclusive-count-example.md | Adds inclusive-count example (+ 1). |
| new_database/content/datetime/arithmetic-and-overlap/datetime-timedelta-day-counts/01_core-formulas.md | Adds core timedelta/day-of-year formula table. |
| new_database/content/datetime/arithmetic-and-overlap/datetime-overlap-logic/README.md | Adds snippet-family README + metadata for overlap logic. |
| new_database/content/datetime/arithmetic-and-overlap/datetime-overlap-logic/03_trap-hints.md | Adds overlap traps (datetimes vs strings, non-overlap condition). |
| new_database/content/datetime/arithmetic-and-overlap/datetime-overlap-logic/02_lunch-meeting-pattern.md | Adds lunch overlap pattern example. |
| new_database/content/datetime/arithmetic-and-overlap/datetime-overlap-logic/01_overlap-rule.md | Adds formal overlap/non-overlap equivalence snippet. |
| new_database/content/core-python/types-conditions/types-none-bool-equality/README.md | Adds snippet-family README + metadata for types/None/bool/equality. |
| new_database/content/core-python/types-conditions/types-none-bool-equality/03_micro-examples.md | Adds small illustrative examples for equality/truthiness. |
| new_database/content/core-python/types-conditions/types-none-bool-equality/02_chains-and-booleans.md | Adds bullet rules for chained comparisons and boolean sums. |
| new_database/content/core-python/types-conditions/types-none-bool-equality/01_equality-truthiness-mini-table.md | Adds equality/truthiness mini reference table. |
| new_database/content/core-python/types-conditions/membership-and-condition-logic/README.md | Adds snippet-family README + metadata for membership/logic. |
| new_database/content/core-python/types-conditions/membership-and-condition-logic/03_tiny-examples.md | Adds small membership/condition examples. |
| new_database/content/core-python/types-conditions/membership-and-condition-logic/02_condition-patterns-worth-memorizing.md | Adds common condition “templates” as bullets. |
| new_database/content/core-python/types-conditions/membership-and-condition-logic/01_membership-semantics.md | Adds membership semantics table for container types. |
| new_database/content/core-python/types-conditions/builtins-return-values/README.md | Adds snippet-family README + metadata for built-ins return values. |
| new_database/content/core-python/types-conditions/builtins-return-values/03_common-confusion.md | Adds bullet pitfalls (sorted vs sort, type, string methods). |
| new_database/content/core-python/types-conditions/builtins-return-values/02_exam-style-comparisons.md | Adds an exam-style “same output value” example set. |
| new_database/content/core-python/types-conditions/builtins-return-values/01_built-ins-at-a-glance.md | Adds built-ins/methods reference table with return types. |
| new_database/content/core-python/lists-loops/zip-enumerate-core/README.md | Adds snippet-family README + metadata for zip/enumerate patterns. |
| new_database/content/core-python/lists-loops/zip-enumerate-core/03_exam-style-micro-examples.md | Adds zip/enumerate micro examples. |
| new_database/content/core-python/lists-loops/zip-enumerate-core/02_useful-templates.md | Adds templates using zip/enumerate (dict, counter, next-link). |
| new_database/content/core-python/lists-loops/zip-enumerate-core/01_what-they-produce.md | Adds output-shape table for zip/enumerate. |
| new_database/content/core-python/lists-loops/slicing-patterns/README.md | Adds snippet-family README + metadata for slicing patterns. |
| new_database/content/core-python/lists-loops/slicing-patterns/03_chunking-pattern.md | Adds chunking template example. |
| new_database/content/core-python/lists-loops/slicing-patterns/02_typical-exam-patterns.md | Adds representative slicing examples + “not the same” trap. |
| new_database/content/core-python/lists-loops/slicing-patterns/01_slice-syntax-table.md | Adds slice syntax reference table. |
| new_database/content/core-python/lists-loops/nested-indexing-and-negative-indices/README.md | Adds snippet-family README + metadata for nested indexing/negative indices. |
| new_database/content/core-python/lists-loops/nested-indexing-and-negative-indices/03_fast-check.md | Adds fast-check rules for nested/negative indexing. |
| new_database/content/core-python/lists-loops/nested-indexing-and-negative-indices/02_exam-style-example.md | Adds worked nested-indexing example. |
| new_database/content/core-python/lists-loops/nested-indexing-and-negative-indices/01_index-rules.md | Adds index rules reference table. |
| new_database/content/core-python/lists-loops/loop-templates/README.md | Adds snippet-family README + metadata for loop templates. |
| new_database/content/core-python/lists-loops/loop-templates/03_trap-checklist.md | Adds loop trap checklist bullets. |
| new_database/content/core-python/lists-loops/loop-templates/02_carry-the-previous-value.md | Adds an example using a carry variable. |
| new_database/content/core-python/lists-loops/loop-templates/01_core-templates.md | Adds core for/while templates. |
| new_database/content/core-python/lists-loops/list-selection-and-aggregation/README.md | Adds snippet-family README + metadata for list selection/aggregation. |
| new_database/content/core-python/lists-loops/list-selection-and-aggregation/03_max-sum-trap.md | Adds trap note about lexicographic max vs sum. |
| new_database/content/core-python/lists-loops/list-selection-and-aggregation/02_pick-the-sub-list-with-the-highest-sum.md | Adds “max sum sublist” template. |
| new_database/content/core-python/lists-loops/list-selection-and-aggregation/01_keep-elements-equal-to-their-index.md | Adds template + equivalent loop for index==value selection. |
| new_database/README.md | Adds top-level README describing the new snippet bank package. |
| index.html | Updates asset loading, accessibility live regions, filters UI, and copy to “snippets/pieces”. |
| docs/specs/RM-009-vision-first-exam-curation-pipeline.md | Adds spec for vision-first exam curation pipeline. |
| docs/data/DATASET_INFO.md | Documents new data/vision_exam_pipeline/ artifact families and policies. |
| docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md | Adds execution checklist for snippet completeness round. |
| docs/curation/OVERNIGHT_WORKER_PROMPTS.md | Adds bounded worker prompt templates for overnight runs. |
| docs/curation/OVERNIGHT_SUPERVISOR_PROMPT.txt | Adds supervisor prompt for snippet-completeness overnight loop. |
| docs/curation/OVERNIGHT_SUPERVISOR_PROMPT.md | Adds markdown version of supervisor prompt. |
| docs/curation/OVERNIGHT_AGENT_RUNBOOK.md | Adds runbook describing supervisor/worker cadence and guardrails. |
| docs/curation/HOURLY_ORCHESTRATOR_SUPERVISOR_PROMPT.txt | Adds hourly supervisor prompt and stop/steer rules. |
| docs/VISION_EXAM_PIPELINE.md | Adds operator documentation for pipeline modules/artifacts/state machine. |
| docs/TESTING.md | Documents “Vision-First Exam Curation” flow and entrypoint commands. |
| docs/ROADMAP.md | Adds RM-009 row to roadmap. |
| docs/ARCHITECTURE.md | Documents boundary between raw-ingestion and vision-first workflows. |
| data/vision_exam_pipeline/work_packets/extractions/trial-final-exam-solutions-introduction-to-python-3077951.json | Adds extraction work packet JSON for that exam. |
| data/vision_exam_pipeline/work_packets/extractions/sample-final-plus-answers.json | Adds extraction work packet JSON for sample final. |
| data/vision_exam_pipeline/work_packets/extractions/resit-solutions-for-introduction-to-python-35761538.json | Adds extraction work packet JSON for resit solutions. |
| data/vision_exam_pipeline/work_packets/extractions/introduction-to-python-trial-final-exam-solutions-py22.json | Adds extraction work packet JSON for 2024 trial final. |
| data/vision_exam_pipeline/work_packets/extractions/index.json | Adds index for extraction packets. |
| data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q04-q06-legacy-reverified.json | Adds review-drop updates for trial-final Q04–Q06. |
| data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q01-q03-legacy-reverified.json | Adds review-drop updates for trial-final Q01–Q03. |
| data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json | Adds review-drop updates for resit solutions Q08–Q12. |
| data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q05-q07-legacy-reverified.json | Adds review-drop updates for resit solutions Q05–Q07. |
| data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json | Adds review-drop updates for resit solutions Q01–Q04. |
| data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16-q18.json | Adds review-drop updates for resit guidelines Q16–Q18. |
| data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13-q15.json | Adds review-drop updates for resit guidelines Q13–Q15. |
| data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04-q06-legacy-reverified.json | Adds review-drop updates for resit guidelines Q04–Q06. |
| data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01-q03-legacy-reverified.json | Adds review-drop updates for resit guidelines Q01–Q03. |
| data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q19-q21.json | Adds review-drop updates for trial study guide Q19–Q21. |
| data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q23-q24.json | Adds review-drop updates for 2022 final Q23–Q24. |
| data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q20-q22.json | Adds review-drop updates for 2022 final Q20–Q22. |
| data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json | Adds review-drop updates for 2022 final Q16–Q19. |
| data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json | Adds review-drop updates for 2022 final Q12–Q15. |
| data/vision_exam_pipeline/review_drops/README.md | Documents review-drop JSON contract and merge command. |
| data/vision_exam_pipeline/exam_question_bank_completeness.json | Adds completeness report JSON for the question bank. |
| data/vision_exam_pipeline/analytics/round2.md | Adds round2 ranking analytics markdown summary. |
| data/vision_exam_pipeline/analytics/round1.md | Adds round1 ranking analytics markdown summary. |
| data/vision_exam_pipeline/RUNBOOK.md | Adds pipeline operator runbook under data/vision_exam_pipeline/. |
| data/vision_exam_pipeline/README.md | Adds overview of vision-first pipeline artifact layout and commands. |
| data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md | Adds mutable coordination board for the snippet completeness phase. |
| app/text-render-utils.js | Refactors inline rendering + adds lightweight markdown block compilation/rendering helpers. |
| app/preview-render.js | Updates preview entry grouping/sorting and labeling to snippet/subtopic model. |
| app/preview-history.js | Updates history guard to new state.snippets model. |
| RTK.md | Adds RTK wrapper policy doc for shell command usage. |
| README.md | Updates main project README to reflect snippet-bank loading + new counts/filters. |
| Makefile | Adds build-frontend-bundle and wires it into check/playwright targets. |
| AGENTS.md | Adds “current overnight focus” pointers + a quick status command. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| running_total = 0 | ||
| for key in sorted(d): | ||
| running_total += d[key] | ||
| out[key] = running_total |
There was a problem hiding this comment.
out is used but never initialized in this snippet, so copying it as-is will raise a NameError. Consider adding an out = {} initialization (and returning it, if this is meant to be a full template).
| |---|---| | ||
| | `lambda x: x + 5` | anonymous function with one parameter | | ||
| | `lambda a, b: a * b` | anonymous function with two parameters | | ||
| | `list(map(lambda x: x*2, x))` | apply function to each element, then force list | |
There was a problem hiding this comment.
This example uses x both as the lambda parameter and as the iterable, which is legal but confusing and easy to misread. Use distinct names (e.g., lambda n: n*2 over xs) to make the pattern unambiguous.
| | `list(map(lambda x: x*2, x))` | apply function to each element, then force list | | |
| | `list(map(lambda n: n*2, xs))` | apply function to each element, then force list | |
| - [plan_after_manual_synthesis.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/plan_after_manual_synthesis.md) | ||
| - [round1_manual_synthesis.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md) | ||
| - [exam_question_bank.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/exam_question_bank.json) | ||
| - [round1.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/evaluations/round1.json) | ||
| - [topic_cards.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/topic_cards.json) | ||
| - [study_db.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/study_db.json) |
There was a problem hiding this comment.
These links are absolute machine-local paths, which will break for other contributors and in GitHub rendering. Prefer repo-relative links (e.g. data/vision_exam_pipeline/...) so the docs remain portable.
| - [plan_after_manual_synthesis.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/plan_after_manual_synthesis.md) | |
| - [round1_manual_synthesis.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md) | |
| - [exam_question_bank.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/exam_question_bank.json) | |
| - [round1.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/evaluations/round1.json) | |
| - [topic_cards.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/topic_cards.json) | |
| - [study_db.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/study_db.json) | |
| - [plan_after_manual_synthesis.md](../../data/vision_exam_pipeline/plan_after_manual_synthesis.md) | |
| - [round1_manual_synthesis.md](../../data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md) | |
| - [exam_question_bank.json](../../data/vision_exam_pipeline/exam_question_bank.json) | |
| - [round1.json](../../data/vision_exam_pipeline/evaluations/round1.json) | |
| - [topic_cards.json](../../topic_cards.json) | |
| - [study_db.json](../../data/study_db.json) |
| function renderInlineRichText(text, { preserveNewlines = false } = {}) { | ||
| const value = preserveNewlines ? decodeDisplayEscapes(text) : String(text || ""); | ||
| const lines = normalizeNewlines(value).split("\n"); | ||
| return lines.map((line) => renderInlineCode(line)).join("<br>"); |
There was a problem hiding this comment.
preserveNewlines currently only affects escape decoding, but newlines are always rendered as <br> because the function always splits and rejoins with <br>. If callers rely on preserveNewlines=false to keep inline text as a single flow (e.g., collapse newlines to spaces), this will change layout unexpectedly; consider making the <br> join conditional.
| return lines.map((line) => renderInlineCode(line)).join("<br>"); | |
| const renderedLines = lines.map((line) => renderInlineCode(line)); | |
| return preserveNewlines ? renderedLines.join("<br>") : renderedLines.join(" "); |
| <p id="rejectedCount" class="stat-value" aria-live="polite">0</p> | ||
| </div> | ||
| <div> | ||
| <p class="stat-label">Visible Topics</p> |
There was a problem hiding this comment.
The stats labels were updated to 'Selected Snippets' / 'Selected Pieces', but this label still says 'Visible Topics'. For consistency with the new snippet-based model, consider renaming it (e.g., 'Visible Snippets').
| <p class="stat-label">Visible Topics</p> | |
| <p class="stat-label">Visible Snippets</p> |
| @@ -0,0 +1,94 @@ | |||
| # Spec: RM-009 Vision-First Exam Curation Pipeline | |||
There was a problem hiding this comment.
The PR metadata focuses on UI/accessibility/card design, but this PR also introduces a substantial new spec and supporting vision-exam pipeline documentation/artifacts. Consider updating the PR description (or splitting) so reviewers understand that pipeline docs/data are an intended part of this change set.
| build-frontend-bundle: | ||
| python3 scripts/build_frontend_bundle.py |
There was a problem hiding this comment.
Wiring build_frontend_bundle.py into check-py means a 'check' target now has side effects (generating/updating bundle outputs). In CI or local workflows this can cause surprising dirty working trees or inconsistent results; consider separating 'generate' vs 'check' (e.g., keep generation explicit, or add a follow-up verification step that asserts the generated bundle is up-to-date without modifying tracked files).
| node --check scripts/stress_layout_playwright.js | ||
|
|
||
| check-py: | ||
| check-py: build-frontend-bundle |
There was a problem hiding this comment.
Wiring build_frontend_bundle.py into check-py means a 'check' target now has side effects (generating/updating bundle outputs). In CI or local workflows this can cause surprising dirty working trees or inconsistent results; consider separating 'generate' vs 'check' (e.g., keep generation explicit, or add a follow-up verification step that asserts the generated bundle is up-to-date without modifying tracked files).
| check-py: build-frontend-bundle | |
| check-py: |
| /> | ||
| <link | ||
| href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" | ||
| rel="stylesheet" | ||
| /> |
There was a problem hiding this comment.
Preloading the Google Fonts stylesheet while also including it as a normal stylesheet link can result in duplicate fetches in some browsers/caching scenarios. Consider using the standard 'preload + onload rel=stylesheet' pattern (or removing the preload) to ensure the preload request is always reused.
| /> | |
| <link | |
| href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" | |
| rel="stylesheet" | |
| /> | |
| onload="this.onload=null;this.rel='stylesheet'" | |
| /> | |
| <noscript> | |
| <link | |
| href="https://fonts.googleapis.com/css2?family=Manrope:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500&display=swap" | |
| rel="stylesheet" | |
| /> | |
| </noscript> |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6ac9bec733
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| .mini-toggle:has(input:checked) { | ||
| background: rgba(216, 232, 213, 0.55); | ||
| border-color: rgba(40, 68, 53, 0.16); |
There was a problem hiding this comment.
Keep topic-card stylesheet within line-length gate
This addition pushes styles/02-topic-card.css to 531 lines, which now fails the enforced file-length policy in tests/test_file_length_policy.py (find_violations(..., max_lines=500) at lines 8–16). In this commit, python3 -m unittest discover -s tests -v fails on that check, so CI/validation is red until the new rules are split into another stylesheet module or the file is reduced below 500 lines.
Useful? React with 👍 / 👎.
Changes
Accessibility
aria-hiddento decorative SVG iconsprefers-reduced-motionsupportComponent Redesign
topic-course-chip→snippet-tag, simplify stylingDesign Polish
tabular-numsto numeric values for alignmentHTML/Performance
autocomplete="off"to search inputCode Theme