From b77244768d0fbe61b0a1fdb6ba0a5bba7b47609f Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Mon, 9 Oct 2023 23:09:57 -0700 Subject: [PATCH 1/5] move Hint and Solution knowls to details/summary disclosure --- macros/core/PGbasicmacros.pl | 35 ++++++++++++++++++++++++++++++----- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/macros/core/PGbasicmacros.pl b/macros/core/PGbasicmacros.pl index bd5e3ae807..44327cbbce 100644 --- a/macros/core/PGbasicmacros.pl +++ b/macros/core/PGbasicmacros.pl @@ -1182,8 +1182,20 @@ sub SOLUTION { return "" if $solution_body eq ""; if ($displayMode =~ /HTML/) { - TEXT('
', - knowlLink(SOLUTION_HEADING(), value => $solution_body, type => 'solution'), '
'); + TEXT(tag( + 'div', + class => 'solution accordion border-bottom-0', + tag( + 'details', + class => 'accordion-item border-bottom-0', + tag( + 'summary', + class => 'accordion-button', + tag('div', class => 'accordion-header user-select-none', SOLUTION_HEADING()) + ) + . tag('div', class => 'accordion-body border-bottom', $solution_body) + ) + )); } elsif ($displayMode =~ /TeX/) { TEXT( "\n%%% BEGIN SOLUTION\n" @@ -1208,7 +1220,20 @@ sub HINT { my $hint_body = hint(@_); return unless $hint_body; if ($displayMode =~ /HTML/) { - TEXT('
', knowlLink(HINT_HEADING(), value => $hint_body, type => 'hint'), '
'); + TEXT(tag( + 'div', + class => 'hint accordion border-bottom-0', + tag( + 'details', + class => 'accordion-item border-bottom-0', + tag( + 'summary', + class => 'accordion-button', + tag('div', class => 'accordion-header user-select-none', HINT_HEADING()) + ) + . tag('div', class => 'accordion-body border-bottom', $hint_body) + ) + )); } elsif ($displayMode =~ /TeX/) { TEXT( "\n%%% BEGIN HINT\n" @@ -1507,7 +1532,7 @@ sub SOLUTION_HEADING { MODES( TeX => '{\\bf ' . maketext('Solution: ') . ' }', Latex2HTML => '\\par {\\bf ' . maketext('Solution:') . ' }', - HTML => '' . maketext('Solution:') . ' ', + HTML => maketext('Solution'), PTX => '' ); } @@ -1516,7 +1541,7 @@ sub HINT_HEADING { MODES( TeX => "{\\bf " . maketext('Hint: ') . "}", Latex2HTML => "\\par {\\bf " . maketext('Hint:') . " }", - HTML => "" . maketext('Hint:') . " ", + HTML => maketext('Hint'), PTX => '' ); } From ab33e8bf41692439dcc0d39c83190b2eabd770b2 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Thu, 12 Oct 2023 09:51:49 -0500 Subject: [PATCH 2/5] Details/summary accordion using css and javascript animations. --- htdocs/js/Problem/details-accordion.js | 65 +++++++++++++++++++++ htdocs/js/Problem/problem.scss | 79 +++++++++++++++++++++----- macros/PG.pl | 11 ++-- macros/core/PGbasicmacros.pl | 12 ++-- t/pg_problems/problem_file.t | 1 + 5 files changed, 142 insertions(+), 26 deletions(-) create mode 100644 htdocs/js/Problem/details-accordion.js diff --git a/htdocs/js/Problem/details-accordion.js b/htdocs/js/Problem/details-accordion.js new file mode 100644 index 0000000000..742ecae8e8 --- /dev/null +++ b/htdocs/js/Problem/details-accordion.js @@ -0,0 +1,65 @@ +(() => { + class Accordion { + constructor(details) { + this.details = details; + this.summary = details.querySelector('summary'); + this.content = details.querySelector('.accordion-body'); + this.animation = null; + this.isClosing = false; + this.isExpanding = false; + this.summary.addEventListener('click', (e) => this.onClick(e)); + } + + onClick(e) { + e.preventDefault(); + this.details.style.overflow = 'hidden'; + if (this.isClosing || !this.details.open) this.open(); + else if (this.isExpanding || this.details.open) this.shrink(); + } + + shrink() { + this.isClosing = true; + this.details.classList.add('closing'); + if (this.animation) this.animation.cancel(); + this.animation = this.details.animate( + { height: [`${this.details.offsetHeight}px`, `${this.summary.offsetHeight}px`] }, + { duration: 200, easing: 'ease-in-out' } + ); + this.animation.addEventListener('finish', () => this.onAnimationFinish(false), { once: true }); + this.animation.addEventListener('cancel', () => (this.isClosing = false), { once: true }); + } + + open() { + this.details.style.height = `${this.details.offsetHeight}px`; + this.details.open = true; + window.requestAnimationFrame(() => this.expand()); + } + + expand() { + this.isExpanding = true; + if (this.animation) this.animation.cancel(); + this.animation = this.details.animate( + { + height: [ + `${this.details.offsetHeight}px`, + `${this.summary.offsetHeight + this.content.offsetHeight}px` + ] + }, + { duration: 400, easing: 'ease-out' } + ); + this.animation.addEventListener('finish', () => this.onAnimationFinish(true), { once: true }); + this.animation.addEventListener('cancel', () => (this.isExpanding = false), { once: true }); + } + + onAnimationFinish(isOpen) { + this.details.open = isOpen; + this.details.classList.remove('closing'); + this.animation = null; + this.isClosing = false; + this.isExpanding = false; + this.details.style.height = this.details.style.overflow = ''; + } + } + + document.querySelectorAll('.solution > details,.hint > details').forEach((details) => new Accordion(details)); +})(); diff --git a/htdocs/js/Problem/problem.scss b/htdocs/js/Problem/problem.scss index 20c10cf4b2..fac151a441 100644 --- a/htdocs/js/Problem/problem.scss +++ b/htdocs/js/Problem/problem.scss @@ -33,13 +33,18 @@ } /* Problem elements */ - label, input[type=text], select, textarea { + label, + input[type='text'], + select, + textarea { font-weight: normal; line-height: 18px; width: auto; } - select, textarea, input[type=text] { + select, + textarea, + input[type='text'] { display: inline-block; padding: 4px 6px; margin-bottom: 0; @@ -50,17 +55,21 @@ background-color: white; } - textarea, input[type=text] { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + textarea, + input[type='text'] { + font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; } - input[type=text] { + input[type='text'] { height: 30px; font-size: 14px; line-height: 20px; } - select, input[type=text], input[type=radio], input[type=checkbox] { + select, + input[type='text'], + input[type='radio'], + input[type='checkbox'] { &.correct { border-color: rgba(81, 153, 81, 0.8); /* green */ outline: 0; @@ -72,11 +81,12 @@ border-color: rgba(191, 84, 84, 0.8); /* red */ outline: 0; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px 2px rgba(191, 84, 84, 0.6); - color:inherit; + color: inherit; } } - input[type=text], span.mq-editable-field { + input[type='text'], + span.mq-editable-field { background-size: 20px auto; background-position: right 4px center; background-repeat: no-repeat; @@ -92,14 +102,15 @@ } } - input[type=radio] { + input[type='radio'] { margin-right: 0.25rem; } select { cursor: pointer; - &[multiple], &[size] { + &[multiple], + &[size] { height: auto; } } @@ -108,7 +119,10 @@ max-width: 100%; } - input[type=text], input[type=radio], textarea, select { + input[type='text'], + input[type='radio'], + textarea, + select { &:focus { border-color: rgba(82, 168, 236, 0.8); outline: 0; @@ -118,11 +132,42 @@ .pg-table { text-align: center; - thead, tbody, tfoot, tr, td, th { + thead, + tbody, + tfoot, + tr, + td, + th { padding: 0.25rem; border: 1px solid black; } } + + .solution, + .hint { + details.accordion-item:not([open]) .accordion-button { + background-color: var(--bs-accordion-bg); + } + + details.accordion-item:not([open]):last-of-type .accordion-button { + border-bottom-right-radius: var(--bs-accordion-border-radius); + border-bottom-left-radius: var(--bs-accordion-border-radius); + } + + details.accordion-item:not([open]) .accordion-button::after { + background-image: var(--bs-accordion-btn-active-icon); + transform: unset; + } + + details.accordion-item[open] .accordion-button::after { + background-image: var(--bs-accordion-btn-icon); + transform: var(--bs-accordion-btn-icon-transform); + } + + details.accordion-item.closing .accordion-button::after { + transform: var(--bs-accordion-btn-icon-transition); + } + } } /* rtl:raw: @@ -179,7 +224,8 @@ table.attemptResults { border-bottom-right-radius: 4px; } - td, th { + td, + th { border-style: inset; border-width: 1px; text-align: center; @@ -230,7 +276,8 @@ table.attemptResults { height: 100%; } - a, a span { + a, + a span { color: #038; text-decoration: none; @@ -240,7 +287,9 @@ table.attemptResults { } } -div, label, span { +div, +label, +span { &.ResultsWithoutError { color: #0f5132; /* Dark Green */ background-color: #8f8; /* Light Green */ diff --git a/macros/PG.pl b/macros/PG.pl index 350292c8bd..c0cfac0fea 100644 --- a/macros/PG.pl +++ b/macros/PG.pl @@ -395,11 +395,12 @@ sub ADD_JS_FILE { # Some problems use jquery-ui still, and so the requestor should also load the js for that if those problems are used, # although those problems should also be rewritten to not use jquery-ui. sub load_js() { - ADD_JS_FILE('js/InputColor/color.js', 0, { defer => undef }); - ADD_JS_FILE('js/Base64/Base64.js', 0, { defer => undef }); - ADD_JS_FILE('js/Knowls/knowl.js', 0, { defer => undef }); - ADD_JS_FILE('js/ImageView/imageview.js', 0, { defer => undef }); - ADD_JS_FILE('js/Essay/essay.js', 0, { defer => undef }); + ADD_JS_FILE('js/InputColor/color.js', 0, { defer => undef }); + ADD_JS_FILE('js/Base64/Base64.js', 0, { defer => undef }); + ADD_JS_FILE('js/Knowls/knowl.js', 0, { defer => undef }); + ADD_JS_FILE('js/Problem/details-accordion.js', 0, { defer => undef }); + ADD_JS_FILE('js/ImageView/imageview.js', 0, { defer => undef }); + ADD_JS_FILE('js/Essay/essay.js', 0, { defer => undef }); if ($envir{useMathQuill}) { ADD_JS_FILE('node_modules/mathquill/dist/mathquill.js', 0, { defer => undef }); diff --git a/macros/core/PGbasicmacros.pl b/macros/core/PGbasicmacros.pl index 8be20580e9..7fd0c5835f 100644 --- a/macros/core/PGbasicmacros.pl +++ b/macros/core/PGbasicmacros.pl @@ -1184,16 +1184,16 @@ sub SOLUTION { if ($displayMode =~ /HTML/) { TEXT(tag( 'div', - class => 'solution accordion border-bottom-0', + class => 'solution accordion my-3', tag( 'details', - class => 'accordion-item border-bottom-0', + class => 'accordion-item', tag( 'summary', class => 'accordion-button', tag('div', class => 'accordion-header user-select-none', SOLUTION_HEADING()) ) - . tag('div', class => 'accordion-body border-bottom', $solution_body) + . tag('div', class => 'accordion-body', $solution_body) ) )); } elsif ($displayMode =~ /TeX/) { @@ -1222,16 +1222,16 @@ sub HINT { if ($displayMode =~ /HTML/) { TEXT(tag( 'div', - class => 'hint accordion border-bottom-0', + class => 'hint accordion my-3', tag( 'details', - class => 'accordion-item border-bottom-0', + class => 'accordion-item', tag( 'summary', class => 'accordion-button', tag('div', class => 'accordion-header user-select-none', HINT_HEADING()) ) - . tag('div', class => 'accordion-body border-bottom', $hint_body) + . tag('div', class => 'accordion-body', $hint_body) ) )); } elsif ($displayMode =~ /TeX/) { diff --git a/t/pg_problems/problem_file.t b/t/pg_problems/problem_file.t index 03ab3842a0..699420472b 100644 --- a/t/pg_problems/problem_file.t +++ b/t/pg_problems/problem_file.t @@ -105,6 +105,7 @@ is( { file => 'js/InputColor/color.js', external => 0, attributes => { defer => undef } }, { file => 'js/Base64/Base64.js', external => 0, attributes => { defer => undef } }, { file => 'js/Knowls/knowl.js', external => 0, attributes => { defer => undef } }, + { file => 'js/Problem/details-accordion.js', external => 0, attributes => { defer => undef } }, { file => 'js/ImageView/imageview.js', external => 0, attributes => { defer => undef } }, { file => 'js/Essay/essay.js', external => 0, attributes => { defer => undef } }, { file => 'node_modules/mathquill/dist/mathquill.js', external => 0, attributes => { defer => undef } }, From 70007dcbcbbd9b4ed691267fa4a4d6c929452697 Mon Sep 17 00:00:00 2001 From: Glenn Rice Date: Fri, 13 Oct 2023 07:58:47 -0500 Subject: [PATCH 3/5] Instead of handling styles and using a javascript animation, just use a bootstrap collapse. --- htdocs/js/Problem/details-accordion.js | 92 +++++++++----------------- htdocs/js/Problem/problem.scss | 79 +++++----------------- macros/core/PGbasicmacros.pl | 16 +++-- 3 files changed, 60 insertions(+), 127 deletions(-) diff --git a/htdocs/js/Problem/details-accordion.js b/htdocs/js/Problem/details-accordion.js index 742ecae8e8..621de1e95d 100644 --- a/htdocs/js/Problem/details-accordion.js +++ b/htdocs/js/Problem/details-accordion.js @@ -1,65 +1,39 @@ (() => { - class Accordion { - constructor(details) { - this.details = details; - this.summary = details.querySelector('summary'); - this.content = details.querySelector('.accordion-body'); - this.animation = null; - this.isClosing = false; - this.isExpanding = false; - this.summary.addEventListener('click', (e) => this.onClick(e)); - } + const setupAccordion = (accordion) => { + const collapseEl = accordion.querySelector('.collapse'); + const button = accordion.querySelector('summary.accordion-button'); + const details = accordion.querySelector('details.accordion-item'); + if (!collapseEl || !button || !details) return; - onClick(e) { - e.preventDefault(); - this.details.style.overflow = 'hidden'; - if (this.isClosing || !this.details.open) this.open(); - else if (this.isExpanding || this.details.open) this.shrink(); - } + const collapse = new bootstrap.Collapse(collapseEl, { toggle: false }); + button.addEventListener('click', () => collapse.toggle()); - shrink() { - this.isClosing = true; - this.details.classList.add('closing'); - if (this.animation) this.animation.cancel(); - this.animation = this.details.animate( - { height: [`${this.details.offsetHeight}px`, `${this.summary.offsetHeight}px`] }, - { duration: 200, easing: 'ease-in-out' } - ); - this.animation.addEventListener('finish', () => this.onAnimationFinish(false), { once: true }); - this.animation.addEventListener('cancel', () => (this.isClosing = false), { once: true }); - } + details.addEventListener('click', (e) => e.preventDefault()); + collapseEl.addEventListener('show.bs.collapse', () => { + details.open = true; + button.classList.remove('collapsed'); + }); + collapseEl.addEventListener('hide.bs.collapse', () => button.classList.add('collapsed')); + collapseEl.addEventListener('hidden.bs.collapse', () => (details.open = false)); + }; - open() { - this.details.style.height = `${this.details.offsetHeight}px`; - this.details.open = true; - window.requestAnimationFrame(() => this.expand()); - } + // Deal with solution/hint details that are already on the page. + document.querySelectorAll('.solution.accordion, .hint.accordion').forEach(setupAccordion); - expand() { - this.isExpanding = true; - if (this.animation) this.animation.cancel(); - this.animation = this.details.animate( - { - height: [ - `${this.details.offsetHeight}px`, - `${this.summary.offsetHeight + this.content.offsetHeight}px` - ] - }, - { duration: 400, easing: 'ease-out' } - ); - this.animation.addEventListener('finish', () => this.onAnimationFinish(true), { once: true }); - this.animation.addEventListener('cancel', () => (this.isExpanding = false), { once: true }); - } - - onAnimationFinish(isOpen) { - this.details.open = isOpen; - this.details.classList.remove('closing'); - this.animation = null; - this.isClosing = false; - this.isExpanding = false; - this.details.style.height = this.details.style.overflow = ''; - } - } - - document.querySelectorAll('.solution > details,.hint > details').forEach((details) => new Accordion(details)); + // Deal with solution/hint details that are added to the page later. + const observer = new MutationObserver((mutationsList) => { + mutationsList.forEach((mutation) => { + mutation.addedNodes.forEach((node) => { + if (node instanceof Element) { + if ( + (node.classList.contains('solution') || node.classList.contains('hint')) && + node.classList.contains('accordion') + ) + setupAccordion(node); + else node.querySelectorAll('.solution.accordion, .hint.accordion').forEach(setupAccordion); + } + }); + }); + }); + observer.observe(document.body, { childList: true, subtree: true }); })(); diff --git a/htdocs/js/Problem/problem.scss b/htdocs/js/Problem/problem.scss index fac151a441..20c10cf4b2 100644 --- a/htdocs/js/Problem/problem.scss +++ b/htdocs/js/Problem/problem.scss @@ -33,18 +33,13 @@ } /* Problem elements */ - label, - input[type='text'], - select, - textarea { + label, input[type=text], select, textarea { font-weight: normal; line-height: 18px; width: auto; } - select, - textarea, - input[type='text'] { + select, textarea, input[type=text] { display: inline-block; padding: 4px 6px; margin-bottom: 0; @@ -55,21 +50,17 @@ background-color: white; } - textarea, - input[type='text'] { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + textarea, input[type=text] { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } - input[type='text'] { + input[type=text] { height: 30px; font-size: 14px; line-height: 20px; } - select, - input[type='text'], - input[type='radio'], - input[type='checkbox'] { + select, input[type=text], input[type=radio], input[type=checkbox] { &.correct { border-color: rgba(81, 153, 81, 0.8); /* green */ outline: 0; @@ -81,12 +72,11 @@ border-color: rgba(191, 84, 84, 0.8); /* red */ outline: 0; box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px 2px rgba(191, 84, 84, 0.6); - color: inherit; + color:inherit; } } - input[type='text'], - span.mq-editable-field { + input[type=text], span.mq-editable-field { background-size: 20px auto; background-position: right 4px center; background-repeat: no-repeat; @@ -102,15 +92,14 @@ } } - input[type='radio'] { + input[type=radio] { margin-right: 0.25rem; } select { cursor: pointer; - &[multiple], - &[size] { + &[multiple], &[size] { height: auto; } } @@ -119,10 +108,7 @@ max-width: 100%; } - input[type='text'], - input[type='radio'], - textarea, - select { + input[type=text], input[type=radio], textarea, select { &:focus { border-color: rgba(82, 168, 236, 0.8); outline: 0; @@ -132,42 +118,11 @@ .pg-table { text-align: center; - thead, - tbody, - tfoot, - tr, - td, - th { + thead, tbody, tfoot, tr, td, th { padding: 0.25rem; border: 1px solid black; } } - - .solution, - .hint { - details.accordion-item:not([open]) .accordion-button { - background-color: var(--bs-accordion-bg); - } - - details.accordion-item:not([open]):last-of-type .accordion-button { - border-bottom-right-radius: var(--bs-accordion-border-radius); - border-bottom-left-radius: var(--bs-accordion-border-radius); - } - - details.accordion-item:not([open]) .accordion-button::after { - background-image: var(--bs-accordion-btn-active-icon); - transform: unset; - } - - details.accordion-item[open] .accordion-button::after { - background-image: var(--bs-accordion-btn-icon); - transform: var(--bs-accordion-btn-icon-transform); - } - - details.accordion-item.closing .accordion-button::after { - transform: var(--bs-accordion-btn-icon-transition); - } - } } /* rtl:raw: @@ -224,8 +179,7 @@ table.attemptResults { border-bottom-right-radius: 4px; } - td, - th { + td, th { border-style: inset; border-width: 1px; text-align: center; @@ -276,8 +230,7 @@ table.attemptResults { height: 100%; } - a, - a span { + a, a span { color: #038; text-decoration: none; @@ -287,9 +240,7 @@ table.attemptResults { } } -div, -label, -span { +div, label, span { &.ResultsWithoutError { color: #0f5132; /* Dark Green */ background-color: #8f8; /* Light Green */ diff --git a/macros/core/PGbasicmacros.pl b/macros/core/PGbasicmacros.pl index 7fd0c5835f..2df5a54fdc 100644 --- a/macros/core/PGbasicmacros.pl +++ b/macros/core/PGbasicmacros.pl @@ -1190,10 +1190,14 @@ sub SOLUTION { class => 'accordion-item', tag( 'summary', - class => 'accordion-button', + class => 'accordion-button collapsed', tag('div', class => 'accordion-header user-select-none', SOLUTION_HEADING()) ) - . tag('div', class => 'accordion-body', $solution_body) + . tag( + 'div', + class => 'accordion-collapse collapse', + tag('div', class => 'accordion-body', $solution_body) + ) ) )); } elsif ($displayMode =~ /TeX/) { @@ -1228,10 +1232,14 @@ sub HINT { class => 'accordion-item', tag( 'summary', - class => 'accordion-button', + class => 'accordion-button collapsed', tag('div', class => 'accordion-header user-select-none', HINT_HEADING()) ) - . tag('div', class => 'accordion-body', $hint_body) + . tag( + 'div', + class => 'accordion-collapse collapse', + tag('div', class => 'accordion-body', $hint_body) + ) ) )); } elsif ($displayMode =~ /TeX/) { From 122a3e1116911cbca802c6717cd6d7e57dcf2b87 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Wed, 25 Oct 2023 22:31:30 -0700 Subject: [PATCH 4/5] tweak hint/solution CSS --- htdocs/js/Problem/problem.scss | 6 ++++++ macros/core/PGbasicmacros.pl | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/htdocs/js/Problem/problem.scss b/htdocs/js/Problem/problem.scss index 20c10cf4b2..653b19f411 100644 --- a/htdocs/js/Problem/problem.scss +++ b/htdocs/js/Problem/problem.scss @@ -123,6 +123,12 @@ border: 1px solid black; } } + + /* Hints and Solutions */ + .hint summary, .solution summary { + font-weight: bold; + color: var(--bs-primary); + } } /* rtl:raw: diff --git a/macros/core/PGbasicmacros.pl b/macros/core/PGbasicmacros.pl index 2df5a54fdc..6b28fc53a1 100644 --- a/macros/core/PGbasicmacros.pl +++ b/macros/core/PGbasicmacros.pl @@ -1190,7 +1190,7 @@ sub SOLUTION { class => 'accordion-item', tag( 'summary', - class => 'accordion-button collapsed', + class => 'accordion-button collapsed p-2', tag('div', class => 'accordion-header user-select-none', SOLUTION_HEADING()) ) . tag( @@ -1232,7 +1232,7 @@ sub HINT { class => 'accordion-item', tag( 'summary', - class => 'accordion-button collapsed', + class => 'accordion-button collapsed p-2', tag('div', class => 'accordion-header user-select-none', HINT_HEADING()) ) . tag( From de174bcdcd37ef17c9a7a6bb6d3fc680eba833a9 Mon Sep 17 00:00:00 2001 From: Alex Jordan Date: Thu, 26 Oct 2023 14:42:36 -0700 Subject: [PATCH 5/5] more CSS tweaks --- htdocs/js/Problem/problem.scss | 6 ------ macros/core/PGbasicmacros.pl | 4 ++-- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/htdocs/js/Problem/problem.scss b/htdocs/js/Problem/problem.scss index 653b19f411..20c10cf4b2 100644 --- a/htdocs/js/Problem/problem.scss +++ b/htdocs/js/Problem/problem.scss @@ -123,12 +123,6 @@ border: 1px solid black; } } - - /* Hints and Solutions */ - .hint summary, .solution summary { - font-weight: bold; - color: var(--bs-primary); - } } /* rtl:raw: diff --git a/macros/core/PGbasicmacros.pl b/macros/core/PGbasicmacros.pl index 6b28fc53a1..1f52a33a33 100644 --- a/macros/core/PGbasicmacros.pl +++ b/macros/core/PGbasicmacros.pl @@ -1190,7 +1190,7 @@ sub SOLUTION { class => 'accordion-item', tag( 'summary', - class => 'accordion-button collapsed p-2', + class => 'accordion-button collapsed text-primary fw-bold py-2', tag('div', class => 'accordion-header user-select-none', SOLUTION_HEADING()) ) . tag( @@ -1232,7 +1232,7 @@ sub HINT { class => 'accordion-item', tag( 'summary', - class => 'accordion-button collapsed p-2', + class => 'accordion-button collapsed text-primary fw-bold py-2', tag('div', class => 'accordion-header user-select-none', HINT_HEADING()) ) . tag(