Skip to content

Improve UI: accessibility, wider cards, design polish - #17

Merged
caspersimon merged 6 commits into
mainfrom
claude/wonderful-keller
Mar 25, 2026
Merged

Improve UI: accessibility, wider cards, design polish#17
caspersimon merged 6 commits into
mainfrom
claude/wonderful-keller

Conversation

@caspersimon

Copy link
Copy Markdown
Owner

Changes

Accessibility

  • Add ARIA labels and live regions for dynamic content updates
  • Add aria-hidden to decorative SVG icons
  • Improve focus states and outline contrast
  • Add prefers-reduced-motion support

Component Redesign

  • Snippet cards: Replace two action buttons with single icon toggle button showing check/X based on state
  • Subtopic sections: Similar icon button pattern, cleaner layout
  • Card widths: Increase from 270px to 340px minimum for better readability
  • Tags: Rename topic-course-chipsnippet-tag, simplify styling

Design Polish

  • Refine color palette for better contrast and visual hierarchy
  • Add subtle shadows and borders to cards
  • Improve typography with letter-spacing adjustments
  • Update spacing and padding throughout
  • Enhance hover states with smooth transitions
  • Add tabular-nums to numeric values for alignment

HTML/Performance

  • Add font preload link
  • Add autocomplete="off" to search input
  • Improve semantic structure in subtopic rendering

Code Theme

  • Simplify code block background gradient

caspersimon and others added 6 commits March 23, 2026 17:12
…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>
Copilot AI review requested due to automatic review settings March 25, 2026 05:09

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment on lines +3 to +6
running_total = 0
for key in sorted(d):
running_total += d[key]
out[key] = running_total

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
|---|---|
| `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 |

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
| `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 |

Copilot uses AI. Check for mistakes.
Comment on lines +42 to +47
- [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)

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
- [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)

Copilot uses AI. Check for mistakes.
Comment thread app/text-render-utils.js
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>");

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
return lines.map((line) => renderInlineCode(line)).join("<br>");
const renderedLines = lines.map((line) => renderInlineCode(line));
return preserveNewlines ? renderedLines.join("<br>") : renderedLines.join(" ");

Copilot uses AI. Check for mistakes.
Comment thread index.html
<p id="rejectedCount" class="stat-value" aria-live="polite">0</p>
</div>
<div>
<p class="stat-label">Visible Topics</p>

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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').

Suggested change
<p class="stat-label">Visible Topics</p>
<p class="stat-label">Visible Snippets</p>

Copilot uses AI. Check for mistakes.
@@ -0,0 +1,94 @@
# Spec: RM-009 Vision-First Exam Curation Pipeline

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment thread Makefile
Comment on lines +7 to +8
build-frontend-bundle:
python3 scripts/build_frontend_bundle.py

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Copilot uses AI. Check for mistakes.
Comment thread Makefile
node --check scripts/stress_layout_playwright.js

check-py:
check-py: build-frontend-bundle

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
check-py: build-frontend-bundle
check-py:

Copilot uses AI. Check for mistakes.
Comment thread index.html
Comment on lines +18 to 22
/>
<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"
/>

Copilot AI Mar 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
/>
<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>

Copilot uses AI. Check for mistakes.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread styles/02-topic-card.css
Comment on lines +463 to +465
.mini-toggle:has(input:checked) {
background: rgba(216, 232, 213, 0.55);
border-color: rgba(40, 68, 53, 0.16);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge 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 👍 / 👎.

@caspersimon
caspersimon merged commit 4eef90d into main Mar 25, 2026
0 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants