Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion create_deck/helpers/test_get_model_mcq.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ def test_empty_tts_lang_produces_no_tts_tag(self):

def test_back_contains_correct_row_background_color(self):
template = get_template("n2a-mcq.json")
assert "#ECFDF5" in template["styling"]
assert "#A7F3D0" in template["styling"]

def test_back_contains_incorrect_row_background_color(self):
template = get_template("n2a-mcq.json")
Expand Down
2 changes: 1 addition & 1 deletion src/templates/n2a-mcq.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@
"name": "Extra"
}
],
"styling": "html, body {\n padding: 0;\n margin: 0;\n}\n\n* {\n box-sizing: border-box;\n}\n\nhtml {\n height: 100%;\n}\n\n.card {\n text-align: center;\n margin: 0;\n padding: 1px 1px 1vh 1px;\n display: flex;\n flex-direction: column;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: clamp(16px, 2.6vmin, 20px);\n overflow: auto;\n color: #1f2937;\n}\n\n.card ul,\n.card ol,\n.card li {\n list-style: none !important;\n list-style-type: none !important;\n list-style-image: none !important;\n padding-left: 0;\n margin-left: 0;\n}\n\n.card li::marker {\n content: \"\" !important;\n color: transparent !important;\n font-size: 0 !important;\n}\n\n.card .stem ul,\n.card .stem ol {\n display: inline;\n padding: 0;\n margin: 0;\n}\n\n.card .stem li {\n display: inline;\n}\n\n.stem {\n font-size: clamp(17px, 2.8vmin, 22px);\n font-weight: 500;\n line-height: 1.55;\n margin: 0;\n padding: 3vh 4vw 2vh;\n word-break: break-word;\n text-align: left;\n max-width: 720px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.question {\n font-size: clamp(20px, 4vmin, 30px);\n line-height: 1.4;\n margin: 0;\n padding: 2vh 1vw;\n word-break: break-word;\n}\n\n#choices {\n list-style: none;\n max-width: 720px;\n width: 100%;\n padding: 0;\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n font-size: clamp(15px, 2.4vmin, 18px);\n}\n\n#choices ul {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 100%;\n}\n\n#choices li {\n list-style: none !important;\n list-style-type: none !important;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n margin: 0;\n border-radius: 8px;\n background: #f3f4f6;\n text-align: left;\n line-height: 1.45;\n word-break: break-word;\n border: none;\n outline: none;\n box-shadow: none;\n}\n\n#choices li::marker {\n content: \"\" !important;\n color: transparent !important;\n font-size: 0 !important;\n}\n\n#choices.back li input[type=\"checkbox\"] {\n display: none;\n}\n\n#choices.front li input[type=\"checkbox\"] {\n width: 22px;\n height: 22px;\n margin: 0;\n flex: 0 0 22px;\n accent-color: #10b981;\n cursor: pointer;\n pointer-events: none;\n}\n\n#choices.front li {\n cursor: pointer;\n}\n\n#choices.front li.tap {\n background: rgba(0, 0, 0, 0.10) !important;\n}\n\n.marker {\n display: inline-block;\n position: relative;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n flex: 0 0 22px;\n box-sizing: border-box;\n}\n\n.choice-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.marker[data-state=\"correct\"] {\n border: 2.5px solid #10b981;\n background: transparent;\n}\n\n.marker[data-state=\"correct\"]::before {\n content: \"\";\n position: absolute;\n width: 5px;\n height: 10px;\n border-right: 2.5px solid #10b981;\n border-bottom: 2.5px solid #10b981;\n transform: rotate(45deg);\n top: 2px;\n left: 7px;\n}\n\n.marker[data-state=\"wrong\"] {\n border: none;\n background: transparent;\n}\n\n.marker[data-state=\"wrong\"]::before,\n.marker[data-state=\"wrong\"]::after {\n content: \"\";\n position: absolute;\n width: 18px;\n height: 2.5px;\n background: #ef4444;\n border-radius: 1px;\n top: 50%;\n left: 50%;\n}\n\n.marker[data-state=\"wrong\"]::before {\n transform: translate(-50%, -50%) rotate(45deg);\n}\n\n.marker[data-state=\"wrong\"]::after {\n transform: translate(-50%, -50%) rotate(-45deg);\n}\n\n.marker[data-state=\"missed\"] {\n border: 2.5px dashed #f59e0b;\n background: transparent;\n}\n\n.marker[data-state=\"empty\"] {\n border: none;\n background: transparent;\n}\n\nli.row-success {\n background: #ECFDF5;\n}\n\nli.row-error {\n background: #FEF2F2;\n}\n\nli.row-missed {\n background: #FFFBEB;\n}\n\nli.row-neutral {\n background: #f3f4f6;\n color: #6b7280;\n}\n\n.choice-text {\n min-width: 0;\n}\n\n.choice-text b,\n.choice-text i,\n.choice-text u {\n color: inherit !important;\n}\n\n.big-button {\n display: block;\n width: 100%;\n margin: 1.5vh 0;\n padding: 2vh 6vw;\n border: none;\n outline: none;\n box-shadow: none;\n border-radius: 14px;\n background: rgba(0, 0, 0, 0.06);\n font-size: clamp(18px, 3.5vmin, 22px);\n color: inherit;\n cursor: pointer;\n user-select: none;\n text-align: center;\n transition: background 0.15s ease, transform 0.05s ease;\n}\n\n.big-button:hover {\n background: rgba(0, 0, 0, 0.10);\n}\n\n.big-button:active {\n transform: scale(0.99);\n background: rgba(0, 0, 0, 0.10);\n}\n\n.button-container {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n background: transparent;\n padding: 1.5vh 2vw;\n display: flex;\n flex-direction: column;\n gap: 1vh;\n z-index: 100;\n}\n\n@media (min-width: 768px) {\n .button-container {\n flex-direction: row;\n justify-content: center;\n padding: 2vh 5vw;\n }\n .big-button {\n width: auto;\n min-width: 30vw;\n padding: 4vh 15vw;\n }\n}\n\n.explanation-block {\n display: block;\n max-width: 720px;\n text-align: left;\n margin: 16px auto 24px;\n padding: 0 4vw;\n}\n\n.explanation-body {\n font-size: clamp(14px, 2.2vmin, 16px);\n line-height: 1.55;\n padding: 12px 16px;\n background: #f9fafb;\n border-left: 3px solid #d1d5db;\n border-radius: 0 6px 6px 0;\n color: #374151;\n}\n\nimg {\n display: block;\n max-width: 100%;\n margin: 10px auto;\n}\n\n@media (prefers-color-scheme: dark) {\n .card {\n color: #e5e7eb;\n }\n #choices li {\n background: #1f2937;\n }\n li.row-success {\n background: #064e3b;\n }\n li.row-error {\n background: #7f1d1d;\n }\n li.row-missed {\n background: #78350f;\n }\n li.row-neutral {\n background: #1f2937;\n color: #9ca3af;\n }\n .marker[data-state=\"correct\"] {\n border-color: #34d399;\n }\n .marker[data-state=\"correct\"]::before {\n border-right-color: #34d399;\n border-bottom-color: #34d399;\n }\n .marker[data-state=\"missed\"] {\n border-color: #fbbf24;\n }\n .marker[data-state=\"wrong\"]::before,\n .marker[data-state=\"wrong\"]::after {\n background: #fca5a5;\n }\n .explanation-body {\n background: #111827;\n border-left-color: #374151;\n color: #d1d5db;\n }\n}\n\n@media (max-width: 480px) {\n #choices li {\n padding: 10px 12px;\n gap: 8px;\n }\n .marker {\n width: 20px;\n height: 20px;\n flex: 0 0 20px;\n }\n}\n"
"styling": "html, body {\n padding: 0;\n margin: 0;\n}\n\n* {\n box-sizing: border-box;\n}\n\nhtml {\n height: 100%;\n}\n\n.card {\n text-align: center;\n margin: 0;\n padding: 1px 1px 1vh 1px;\n display: flex;\n flex-direction: column;\n font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n font-size: clamp(16px, 2.6vmin, 20px);\n overflow: auto;\n color: #1f2937;\n}\n\n.card ul,\n.card ol,\n.card li {\n list-style: none !important;\n list-style-type: none !important;\n list-style-image: none !important;\n padding-left: 0;\n margin-left: 0;\n}\n\n.card li::marker {\n content: \"\" !important;\n color: transparent !important;\n font-size: 0 !important;\n}\n\n.card .stem ul,\n.card .stem ol {\n display: inline;\n padding: 0;\n margin: 0;\n}\n\n.card .stem li {\n display: inline;\n}\n\n.stem {\n font-size: clamp(17px, 2.8vmin, 22px);\n font-weight: 500;\n line-height: 1.55;\n margin: 0;\n padding: 3vh 4vw 2vh;\n word-break: break-word;\n text-align: left;\n max-width: 720px;\n margin-left: auto;\n margin-right: auto;\n}\n\n.question {\n font-size: clamp(20px, 4vmin, 30px);\n line-height: 1.4;\n margin: 0;\n padding: 2vh 1vw;\n word-break: break-word;\n}\n\n#choices {\n list-style: none;\n max-width: 720px;\n width: 100%;\n padding: 0;\n margin: 0 auto;\n display: flex;\n flex-direction: column;\n gap: 8px;\n font-size: clamp(15px, 2.4vmin, 18px);\n}\n\n#choices ul {\n list-style: none;\n padding: 0;\n margin: 0;\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 100%;\n}\n\n#choices li {\n list-style: none !important;\n list-style-type: none !important;\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 16px;\n margin: 0;\n border-radius: 8px;\n background: #f3f4f6;\n text-align: left;\n line-height: 1.45;\n word-break: break-word;\n border: none;\n outline: none;\n box-shadow: none;\n}\n\n#choices li::marker {\n content: \"\" !important;\n color: transparent !important;\n font-size: 0 !important;\n}\n\n#choices.back li input[type=\"checkbox\"] {\n display: none;\n}\n\n#choices.front li input[type=\"checkbox\"] {\n width: 22px;\n height: 22px;\n margin: 0;\n flex: 0 0 22px;\n accent-color: #10b981;\n cursor: pointer;\n pointer-events: none;\n}\n\n#choices.front li {\n cursor: pointer;\n}\n\n#choices.front li.tap {\n background: rgba(0, 0, 0, 0.10) !important;\n}\n\n.marker {\n display: inline-block;\n position: relative;\n width: 22px;\n height: 22px;\n border-radius: 50%;\n flex: 0 0 22px;\n box-sizing: border-box;\n}\n\n.choice-text {\n flex: 1 1 auto;\n min-width: 0;\n}\n\n.marker[data-state=\"correct\"] {\n border: 2.5px solid #10b981;\n background: transparent;\n}\n\n.marker[data-state=\"correct\"]::before {\n content: \"\";\n position: absolute;\n width: 5px;\n height: 10px;\n border-right: 2.5px solid #10b981;\n border-bottom: 2.5px solid #10b981;\n transform: rotate(45deg);\n top: 2px;\n left: 7px;\n}\n\n.marker[data-state=\"wrong\"] {\n border: none;\n background: transparent;\n}\n\n.marker[data-state=\"wrong\"]::before,\n.marker[data-state=\"wrong\"]::after {\n content: \"\";\n position: absolute;\n width: 18px;\n height: 2.5px;\n background: #ef4444;\n border-radius: 1px;\n top: 50%;\n left: 50%;\n}\n\n.marker[data-state=\"wrong\"]::before {\n transform: translate(-50%, -50%) rotate(45deg);\n}\n\n.marker[data-state=\"wrong\"]::after {\n transform: translate(-50%, -50%) rotate(-45deg);\n}\n\n.marker[data-state=\"missed\"] {\n border: 2.5px dashed #f59e0b;\n background: transparent;\n}\n\n.marker[data-state=\"empty\"] {\n border: none;\n background: transparent;\n}\n\nli.row-success {\n background: #A7F3D0;\n box-shadow: inset 3px 0 0 #10b981;\n}\n\nli.row-error {\n background: #FEF2F2;\n}\n\nli.row-missed {\n background: #FFFBEB;\n}\n\nli.row-neutral {\n background: #f3f4f6;\n color: #6b7280;\n}\n\n.choice-text {\n min-width: 0;\n}\n\n.choice-text b,\n.choice-text i,\n.choice-text u {\n color: inherit !important;\n}\n\n.big-button {\n display: block;\n width: 100%;\n margin: 1.5vh 0;\n padding: 2vh 6vw;\n border: none;\n outline: none;\n box-shadow: none;\n border-radius: 14px;\n background: rgba(0, 0, 0, 0.06);\n font-size: clamp(18px, 3.5vmin, 22px);\n color: inherit;\n cursor: pointer;\n user-select: none;\n text-align: center;\n transition: background 0.15s ease, transform 0.05s ease;\n}\n\n.big-button:hover {\n background: rgba(0, 0, 0, 0.10);\n}\n\n.big-button:active {\n transform: scale(0.99);\n background: rgba(0, 0, 0, 0.10);\n}\n\n.button-container {\n position: fixed;\n bottom: 0;\n left: 0;\n right: 0;\n background: transparent;\n padding: 1.5vh 2vw;\n display: flex;\n flex-direction: column;\n gap: 1vh;\n z-index: 100;\n}\n\n@media (min-width: 768px) {\n .button-container {\n flex-direction: row;\n justify-content: center;\n padding: 2vh 5vw;\n }\n .big-button {\n width: auto;\n min-width: 30vw;\n padding: 4vh 15vw;\n }\n}\n\n.explanation-block {\n display: block;\n max-width: 720px;\n text-align: left;\n margin: 16px auto 24px;\n padding: 0 4vw;\n}\n\n.explanation-body {\n font-size: clamp(14px, 2.2vmin, 16px);\n line-height: 1.55;\n padding: 12px 16px;\n background: #f9fafb;\n border-left: 3px solid #d1d5db;\n border-radius: 0 6px 6px 0;\n color: #374151;\n}\n\nimg {\n display: block;\n max-width: 100%;\n margin: 10px auto;\n}\n\n@media (prefers-color-scheme: dark) {\n .card {\n color: #e5e7eb;\n }\n #choices li {\n background: #1f2937;\n }\n li.row-success {\n background: #064e3b;\n }\n li.row-error {\n background: #7f1d1d;\n }\n li.row-missed {\n background: #78350f;\n }\n li.row-neutral {\n background: #1f2937;\n color: #9ca3af;\n }\n .marker[data-state=\"correct\"] {\n border-color: #34d399;\n }\n .marker[data-state=\"correct\"]::before {\n border-right-color: #34d399;\n border-bottom-color: #34d399;\n }\n .marker[data-state=\"missed\"] {\n border-color: #fbbf24;\n }\n .marker[data-state=\"wrong\"]::before,\n .marker[data-state=\"wrong\"]::after {\n background: #fca5a5;\n }\n .explanation-body {\n background: #111827;\n border-left-color: #374151;\n color: #d1d5db;\n }\n}\n\n@media (max-width: 480px) {\n #choices li {\n padding: 10px 12px;\n gap: 8px;\n }\n .marker {\n width: 20px;\n height: 20px;\n flex: 0 0 20px;\n }\n}\n"
}
1 change: 1 addition & 0 deletions web/src/pages/WhatsNewPage/changelog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export interface ChangelogEntry {
}

export const changelog: ChangelogEntry[] = [
{ type: 'style', title: 'Multiple choice cards — correct rows stand out with a deeper green tint and a green rule on the left', date: '2026-05-18' },
{ type: 'fix', title: 'Deleting a Notion conversion from Downloads removes it in one click instead of two', date: '2026-05-18' },
{ type: 'fix', title: 'Start 1-hour trial on the upload limit screen now actually starts the trial and resumes your upload', date: '2026-05-18' },
{ type: 'feature', title: 'Multiple choice cards (opt-in) — turn it on in Card options, then mark the correct option with a checkbox or bold in Notion or markdown', date: '2026-05-18' },
Expand Down