diff --git a/core/core.libraries.yml b/core/core.libraries.yml index 67ced51148..0a27c83506 100644 --- a/core/core.libraries.yml +++ b/core/core.libraries.yml @@ -122,6 +122,7 @@ drupal.checkbox: drupal.collapse: version: VERSION js: + misc/details.js: {} misc/details-aria.js: {} misc/collapse.js: {} dependencies: diff --git a/core/misc/collapse.es6.js b/core/misc/collapse.es6.js index 022014a64a..52fd244bc1 100644 --- a/core/misc/collapse.es6.js +++ b/core/misc/collapse.es6.js @@ -9,18 +9,12 @@ * * @constructor Drupal.CollapsibleDetails * - * @param {HTMLDetailsElement} node - * The `
` tag to process. + * @param {HTMLElement} node + * The details element. */ function CollapsibleDetails(node) { this.$node = $(node); - // Details tag polyfill. - if (!Modernizr.details) { - this.$node.addClass('collapse-processed'); - // Initialize and setup the legend, replicate summary tag functionality. - this.setupLegend(); - } - + this.$node.data('details', this); // Expand details if there are errors inside, or if it contains an // element that is targeted by the URI fragment identifier. const anchor = @@ -45,7 +39,7 @@ * @type {Array.} */ instances: [], - } + }, ); $.extend( @@ -61,22 +55,10 @@ setupSummary() { this.$summary = $(''); this.$node - .find('> summary') - .append(this.$summary); - - this.$node - .on('summaryUpdated', this.onSummaryUpdated.bind(this)) + .on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)) .trigger('summaryUpdated'); }, - /** - * Update summary. - */ - onSummaryUpdated: function () { - var text = $.trim(this.$node.drupalGetSummary()); - this.$summary.html(text ? ' (' + text + ')' : ''); - }, - /** * Initialize and setup legend markup. */ @@ -95,14 +77,16 @@ .prepend($legend.contents()) .appendTo($legend); - $legend.on('click', this.onLegendClick.bind(this)); + $legend + .append(this.$summary) + .on('click', $.proxy(this.onLegendClick, this)); }, /** * Handle legend clicks. * * @param {jQuery.Event} e - * jQuery Event object. + * The event triggered. */ onLegendClick(e) { this.toggle(); @@ -110,15 +94,24 @@ }, /** - * Toggle the value of the open attribute. + * Update summary. + */ + onSummaryUpdated() { + const text = $.trim(this.$node.drupalGetSummary()); + this.$summary.html(text ? ` (${text})` : ''); + }, + + /** + * Toggle the visibility of a details element using smooth animations. */ toggle() { const isOpen = !!this.$node.attr('open'); - const $summaryPrefix = this.$node.find('> summary span.details-summary-prefix'); + const $summaryPrefix = this.$node.find( + '> summary span.details-summary-prefix', + ); if (isOpen) { $summaryPrefix.html(Drupal.t('Show')); - } - else { + } else { $summaryPrefix.html(Drupal.t('Hide')); } // Delay setting the attribute to emulate chrome behavior and make @@ -139,10 +132,14 @@ * Attaches behavior for the details element. */ Drupal.behaviors.collapse = { - attach: function (context) { - var $collapsibleDetails = $(context) + attach(context) { + if (Modernizr.details) { + return; + } + const $collapsibleDetails = $(context) .find('details') - .once('collapse'); + .once('collapse') + .addClass('collapse-processed'); if ($collapsibleDetails.length) { for (let i = 0; i < $collapsibleDetails.length; i++) { CollapsibleDetails.instances.push( diff --git a/core/misc/collapse.js b/core/misc/collapse.js index f5693a5732..bf312b97ce 100644 --- a/core/misc/collapse.js +++ b/core/misc/collapse.js @@ -8,12 +8,7 @@ (function ($, Modernizr, Drupal) { function CollapsibleDetails(node) { this.$node = $(node); - - if (!Modernizr.details) { - this.$node.addClass('collapse-processed'); - - this.setupLegend(); - } + this.$node.data('details', this); var anchor = window.location.hash && window.location.hash !== '#' ? ", ".concat(window.location.hash) : ''; if (this.$node.find(".error".concat(anchor)).length) { @@ -21,6 +16,7 @@ } this.setupSummary(); + this.setupLegend(); } $.extend(CollapsibleDetails, { @@ -29,27 +25,22 @@ $.extend(CollapsibleDetails.prototype, { setupSummary: function setupSummary() { this.$summary = $(''); - - this.$node.find('> summary').append(this.$summary); - - this.$node.on('summaryUpdated', this.onSummaryUpdated.bind(this)).trigger('summaryUpdated'); + this.$node.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)).trigger('summaryUpdated'); }, - - onSummaryUpdated: function onSummaryUpdated() { - var text = $.trim(this.$node.drupalGetSummary()); - this.$summary.html(text ? ' (' + text + ')' : ''); - }, - setupLegend: function setupLegend() { var $legend = this.$node.find('> summary'); $('').append(this.$node.attr('open') ? Drupal.t('Hide') : Drupal.t('Show')).prependTo($legend).after(document.createTextNode(' ')); $('').attr('href', "#".concat(this.$node.attr('id'))).prepend($legend.contents()).appendTo($legend); - $legend.on('click', this.onLegendClick.bind(this)); + $legend.append(this.$summary).on('click', $.proxy(this.onLegendClick, this)); }, onLegendClick: function onLegendClick(e) { this.toggle(); e.preventDefault(); }, + onSummaryUpdated: function onSummaryUpdated() { + var text = $.trim(this.$node.drupalGetSummary()); + this.$summary.html(text ? " (".concat(text, ")") : ''); + }, toggle: function toggle() { var _this = this; @@ -69,7 +60,11 @@ }); Drupal.behaviors.collapse = { attach: function attach(context) { - var $collapsibleDetails = $(context).find('details').once('collapse'); + if (Modernizr.details) { + return; + } + + var $collapsibleDetails = $(context).find('details').once('collapse').addClass('collapse-processed'); if ($collapsibleDetails.length) { for (var i = 0; i < $collapsibleDetails.length; i++) { diff --git a/core/misc/details.es6.js b/core/misc/details.es6.js new file mode 100644 index 0000000000..1cd63a0403 --- /dev/null +++ b/core/misc/details.es6.js @@ -0,0 +1,116 @@ +/** + * @file + * Additional functionality for details and summary elements. + */ +(($, Modernizr, Drupal) => { + /** + * The DetailsElement object represents a single details element. + * + * @constructor Drupal.DetailsElement + * + * @param {HTMLElement} node + * The details element. + */ + function DetailsElement(node) { + this.$node = $(node); + this.setupSummary(); + this.setupLegend(); + } + + $.extend( + DetailsElement, + /** @lends Drupal.DetailsElement */ { + /** + * Holds references to instantiated DetailsElement objects. + * + * @type {Array.} + */ + instances: [], + }, + ); + + $.extend( + DetailsElement.prototype, + /** @lends Drupal.DetailsElement# */ { + /** + * Initialize and setup summary events and markup. + * + * @fires event:summaryUpdated + * + * @listens event:summaryUpdated + */ + setupSummary() { + this.$summary = $(Drupal.theme('detailsSummarySummary')); + this.$node + .on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)) + .trigger('summaryUpdated'); + }, + + /** + * Initialize and setup legend markup. + */ + setupLegend() { + const $legend = this.$node.find('> summary'); + $legend.append(this.$summary); + }, + + /** + * Update summary. + */ + onSummaryUpdated() { + const text = $.trim(this.$node.drupalGetSummary()); + this.$summary.html(Drupal.theme('detailsSummarySummaryText', text)); + }, + }, + ); + + /** + * Extend functionality of details element. + * + * @type {Drupal~behavior} + * + * @prop {Drupal~behaviorAttach} attach + * Attaches behavior for the details element. + */ + Drupal.behaviors.detailsSummary = { + attach(context) { + // If the browser does not support `
` natively, do not proceed + // as this functionality will be added via polyfill. + // @see core/misc/collapse.es6.js + if (!Modernizr.details) { + return; + } + const $detailsElements = $(context) + .find('details') + .once('details'); + if ($detailsElements.length) { + for (let i = 0; i < $detailsElements.length; i++) { + DetailsElement.instances.push( + new DetailsElement($detailsElements[i]), + ); + } + } + }, + }; + + /** + * The element containing supplemental summary text. + * + * @return {string} + * The markup for the element that will contain supplemental summary text. + */ + Drupal.theme.detailsSummarySummary = () => ``; + + /** + * Formats supplemental summary text. + * + * @param {string|null} [text] + * (optional) The additional text displayed by the summary. + * @return {string} + * The formatted text that will be appended to the summary element. + */ + Drupal.theme.detailsSummarySummaryText = text => (text ? ` (${text})` : ''); + + // Expose constructor in the public space. + Drupal.DetailsElements = DetailsElement; +})(jQuery, Modernizr, Drupal); diff --git a/core/misc/details.js b/core/misc/details.js new file mode 100644 index 0000000000..553994f8ce --- /dev/null +++ b/core/misc/details.js @@ -0,0 +1,57 @@ +/** +* DO NOT EDIT THIS FILE. +* See the following change record for more information, +* https://www.drupal.org/node/2815083 +* @preserve +**/ + +(function ($, Modernizr, Drupal) { + function DetailsElement(node) { + this.$node = $(node); + this.setupSummary(); + this.setupLegend(); + } + + $.extend(DetailsElement, { + instances: [] + }); + $.extend(DetailsElement.prototype, { + setupSummary: function setupSummary() { + this.$summary = $(Drupal.theme('detailsSummarySummary')); + this.$node.on('summaryUpdated', $.proxy(this.onSummaryUpdated, this)).trigger('summaryUpdated'); + }, + setupLegend: function setupLegend() { + var $legend = this.$node.find('> summary'); + $legend.append(this.$summary); + }, + onSummaryUpdated: function onSummaryUpdated() { + var text = $.trim(this.$node.drupalGetSummary()); + this.$summary.html(Drupal.theme('detailsSummarySummaryText', text)); + } + }); + Drupal.behaviors.detailsSummary = { + attach: function attach(context) { + if (!Modernizr.details) { + return; + } + + var $detailsElements = $(context).find('details').once('details'); + + if ($detailsElements.length) { + for (var i = 0; i < $detailsElements.length; i++) { + DetailsElement.instances.push(new DetailsElement($detailsElements[i])); + } + } + } + }; + + Drupal.theme.detailsSummarySummary = function () { + return ""; + }; + + Drupal.theme.detailsSummarySummaryText = function (text) { + return text ? " (".concat(text, ")") : ''; + }; + + Drupal.DetailsElements = DetailsElement; +})(jQuery, Modernizr, Drupal); \ No newline at end of file diff --git a/core/modules/comment/comment-entity-form.es6.js b/core/modules/comment/comment-entity-form.es6.js index a90a3409f8..4f25c9b761 100644 --- a/core/modules/comment/comment-entity-form.es6.js +++ b/core/modules/comment/comment-entity-form.es6.js @@ -12,14 +12,14 @@ attach(context) { const $context = $(context); $context - .find('.comment-node-settings-form') + .find('fieldset.comment-entity-settings-form') .drupalSetSummary(context => Drupal.checkPlain( $(context) - .find('.js-form-item-comment-0-status input:checked') + .find('.js-form-item-comment input:checked') .next('label') - .text() - ) + .text(), + ), ); }, }; diff --git a/core/modules/comment/comment-entity-form.js b/core/modules/comment/comment-entity-form.js index 420da34dd7..15196ca833 100644 --- a/core/modules/comment/comment-entity-form.js +++ b/core/modules/comment/comment-entity-form.js @@ -9,8 +9,8 @@ Drupal.behaviors.commentFieldsetSummaries = { attach: function attach(context) { var $context = $(context); - $context.find('.comment-node-settings-form').drupalSetSummary(function (context) { - return Drupal.checkPlain($(context).find('.js-form-item-comment-0-status input:checked').next('label').text()); + $context.find('fieldset.comment-entity-settings-form').drupalSetSummary(function (context) { + return Drupal.checkPlain($(context).find('.js-form-item-comment input:checked').next('label').text()); }); } }; diff --git a/core/profiles/demo_umami/themes/umami/css/classy/components/collapse-processed.css b/core/profiles/demo_umami/themes/umami/css/classy/components/collapse-processed.css index 40a326f6ad..16129301c8 100644 --- a/core/profiles/demo_umami/themes/umami/css/classy/components/collapse-processed.css +++ b/core/profiles/demo_umami/themes/umami/css/classy/components/collapse-processed.css @@ -30,6 +30,3 @@ transform: rotate(90deg); background-position: 75% 35%; } -.collapse-processed .details-title { - color: #333; -} diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ConfirmClassyCopiesTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ConfirmClassyCopiesTest.php index 9de5bb78fd..f760cf9f0d 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/ConfirmClassyCopiesTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/ConfirmClassyCopiesTest.php @@ -681,7 +681,7 @@ protected function getClassyHash($type, $file) { 'book-navigation.css' => 'e8219368d360bd4a10763610ada85a1c', 'breadcrumb.css' => '14268f8071dffd40ce7a39862b8fbc56', 'button.css' => '3abebf58e144fd4150d80facdbe5d10f', - 'collapse-processed.css' => 'a37822b887d80917ba465cb8b9bbee60', + 'collapse-processed.css' => 'e928df55485662a4499c9ba12def22e6', 'container-inline.css' => 'ae9caee6071b319ac97bf0bb3e14b542', 'details.css' => 'fdd0606ea856072f5e6a19ab1a2e850e', 'dialog.css' => 'f30e4423380f5f01d02ef0a93e010c53', diff --git a/core/themes/bartik/css/classy/components/collapse-processed.css b/core/themes/bartik/css/classy/components/collapse-processed.css index a4d3cbb0ed..c8c786882c 100644 --- a/core/themes/bartik/css/classy/components/collapse-processed.css +++ b/core/themes/bartik/css/classy/components/collapse-processed.css @@ -30,6 +30,3 @@ transform: rotate(90deg); background-position: 75% 35%; } -.collapse-processed .details-title { - color: #333; -} diff --git a/core/themes/claro/css/components/accordion.css b/core/themes/claro/css/components/accordion.css index ad22ee6b12..3459752060 100644 --- a/core/themes/claro/css/components/accordion.css +++ b/core/themes/claro/css/components/accordion.css @@ -89,14 +89,8 @@ rgba(0, 0, 0, 0.1); border-bottom-left-radius: 2px; } -/** - * Hide JS summary from the details polyfill to make it consistent with native - * details elements. - * - * @todo Consider removing this after https://www.drupal.org/node/2493957 has - * been solved. - */ - .accordion__item .claro-details__summary .summary { - display: none; + display: block; + color: #545560; + font-weight: normal; } diff --git a/core/themes/claro/css/components/accordion.pcss.css b/core/themes/claro/css/components/accordion.pcss.css index 57961a20db..9e43fdd2d2 100644 --- a/core/themes/claro/css/components/accordion.pcss.css +++ b/core/themes/claro/css/components/accordion.pcss.css @@ -34,13 +34,8 @@ border-bottom-left-radius: var(--details-accordion-border-size-radius); } -/** - * Hide JS summary from the details polyfill to make it consistent with native - * details elements. - * - * @todo Consider removing this after https://www.drupal.org/node/2493957 has - * been solved. - */ .accordion__item .claro-details__summary .summary { - display: none; + display: block; + color: var(--color-davysgrey); + font-weight: normal; } diff --git a/core/themes/claro/css/components/details.css b/core/themes/claro/css/components/details.css index 335b2a56f5..0f57ba85f7 100644 --- a/core/themes/claro/css/components/details.css +++ b/core/themes/claro/css/components/details.css @@ -597,18 +597,11 @@ rgba(0, 0, 0, 0.1); border-bottom-left-radius: 0; } -/** - * Hide JS summary from the details polyfill to make it consistent with native - * details elements. - * - * @todo Consider removing this after https://www.drupal.org/node/2493957 has - * been solved. - */ - -.claro-details__summary--accordion .summary, -.claro-details__summary--accordion-item .summary, -.claro-details__summary--vertical-tabs-item .summary { - display: none; +.claro-details__summary-summary { + display: block; + color: #545560; + font-size: 0.889rem; + font-weight: normal; } @media screen and (-ms-high-contrast: active) { diff --git a/core/themes/claro/css/components/details.pcss.css b/core/themes/claro/css/components/details.pcss.css index 3f1bb7f6ab..a785c80533 100644 --- a/core/themes/claro/css/components/details.pcss.css +++ b/core/themes/claro/css/components/details.pcss.css @@ -523,17 +523,11 @@ border-bottom-left-radius: 0; } -/** - * Hide JS summary from the details polyfill to make it consistent with native - * details elements. - * - * @todo Consider removing this after https://www.drupal.org/node/2493957 has - * been solved. - */ -.claro-details__summary--accordion .summary, -.claro-details__summary--accordion-item .summary, -.claro-details__summary--vertical-tabs-item .summary { - display: none; +.claro-details__summary-summary { + display: block; + color: var(--color-davysgrey); + font-size: var(--font-size-s); + font-weight: normal; } @media screen and (-ms-high-contrast: active) { diff --git a/core/themes/claro/css/components/vertical-tabs.css b/core/themes/claro/css/components/vertical-tabs.css index d36caaa806..505ea39343 100644 --- a/core/themes/claro/css/components/vertical-tabs.css +++ b/core/themes/claro/css/components/vertical-tabs.css @@ -313,8 +313,7 @@ rgba(0, 0, 0, 0.1); * Details summary in vertical tabs menu link and in the summary of the details. */ -.vertical-tabs__menu-link-summary, -.vertical-tabs__details-summary-summary { +.vertical-tabs__menu-link-summary { display: block; color: #545560; font-size: 0.889rem; diff --git a/core/themes/claro/css/components/vertical-tabs.pcss.css b/core/themes/claro/css/components/vertical-tabs.pcss.css index 46b8137012..a2def7b001 100644 --- a/core/themes/claro/css/components/vertical-tabs.pcss.css +++ b/core/themes/claro/css/components/vertical-tabs.pcss.css @@ -256,8 +256,7 @@ /** * Details summary in vertical tabs menu link and in the summary of the details. */ -.vertical-tabs__menu-link-summary, -.vertical-tabs__details-summary-summary { +.vertical-tabs__menu-link-summary { display: block; color: var(--color-davysgrey); font-size: var(--font-size-s); diff --git a/core/themes/claro/js/details.es6.js b/core/themes/claro/js/details.es6.js index f7ad00e25e..ff25f0453c 100644 --- a/core/themes/claro/js/details.es6.js +++ b/core/themes/claro/js/details.es6.js @@ -55,4 +55,23 @@ }); }, }; + + /** + * Theme override of element containing supplemental summary text. + * + * @return {string} + * The markup for the element that will contain supplemental summary text. + */ + Drupal.theme.detailsSummarySummary = () => + ``; + + /** + * Theme override of supplemental summary text. + * + * @param {string|null} [text] + * (optional) The additional text displayed by the summary. + * @return {string} + * The formatted text that will be appended to the summary element. + */ + Drupal.theme.detailsSummarySummaryText = text => text || ''; })(jQuery, Modernizr, Drupal); diff --git a/core/themes/claro/js/details.js b/core/themes/claro/js/details.js index 24630f200a..bb9462446c 100644 --- a/core/themes/claro/js/details.js +++ b/core/themes/claro/js/details.js @@ -31,4 +31,12 @@ }); } }; + + Drupal.theme.detailsSummarySummary = function () { + return ""; + }; + + Drupal.theme.detailsSummarySummaryText = function (text) { + return text || ''; + }; })(jQuery, Modernizr, Drupal); \ No newline at end of file diff --git a/core/themes/claro/js/vertical-tabs.es6.js b/core/themes/claro/js/vertical-tabs.es6.js index 7547917152..adee64487d 100644 --- a/core/themes/claro/js/vertical-tabs.es6.js +++ b/core/themes/claro/js/vertical-tabs.es6.js @@ -194,10 +194,6 @@ this.link.attr('href', `#${settings.details.attr('id')}`); - this.detailsSummaryDescription = $( - Drupal.theme.verticalTabDetailsDescription(), - ).appendTo(this.details.find('> summary')); - this.link.on('click', event => { event.preventDefault(); self.focus(); @@ -315,7 +311,6 @@ */ updateSummary() { const summary = this.details.drupalGetSummary(); - this.detailsSummaryDescription.html(summary); this.summary.html(summary); }, @@ -450,15 +445,6 @@ Drupal.theme.verticalTabListWrapper = () => '
    '; - /** - * The wrapper of the details summary message added to the summary element. - * - * @return {string} - * A string representing the DOM fragment. - */ - Drupal.theme.verticalTabDetailsDescription = () => - ''; - /** * Themes the active vertical tab menu item message. * diff --git a/core/themes/claro/js/vertical-tabs.js b/core/themes/claro/js/vertical-tabs.js index 57f420464d..8618af2d1e 100644 --- a/core/themes/claro/js/vertical-tabs.js +++ b/core/themes/claro/js/vertical-tabs.js @@ -63,7 +63,6 @@ $.extend(this, settings, Drupal.theme('verticalTab', settings)); this.item.addClass('js-vertical-tabs-menu-item'); this.link.attr('href', "#".concat(settings.details.attr('id'))); - this.detailsSummaryDescription = $(Drupal.theme.verticalTabDetailsDescription()).appendTo(this.details.find('> summary')); this.link.on('click', function (event) { event.preventDefault(); self.focus(); @@ -133,7 +132,6 @@ }, updateSummary: function updateSummary() { var summary = this.details.drupalGetSummary(); - this.detailsSummaryDescription.html(summary); this.summary.html(summary); }, tabShow: function tabShow() { @@ -176,10 +174,6 @@ return '
      '; }; - Drupal.theme.verticalTabDetailsDescription = function () { - return ''; - }; - Drupal.theme.verticalTabActiveTabIndicator = function () { return "".concat(Drupal.t('(active tab)'), ""); }; diff --git a/core/themes/classy/css/components/collapse-processed.css b/core/themes/classy/css/components/collapse-processed.css index 3d6002af1f..e9206ace9b 100644 --- a/core/themes/classy/css/components/collapse-processed.css +++ b/core/themes/classy/css/components/collapse-processed.css @@ -30,6 +30,3 @@ transform: rotate(90deg); background-position: 75% 35%; } -.collapse-processed .details-title { - color: #333; -} diff --git a/core/themes/seven/css/base/elements.css b/core/themes/seven/css/base/elements.css index 53cba224c6..4da963a391 100644 --- a/core/themes/seven/css/base/elements.css +++ b/core/themes/seven/css/base/elements.css @@ -161,16 +161,18 @@ details summary { padding: 0.95em 1.45em; } details summary:focus { - text-decoration: underline; outline: none; } /** * Unfortunately, text-decoration for details summary is not supported on all * browsers. So we add a span (which can handle text-decoration) in Seven's * templates/details.html.twig. In case there are other details templates that - * don't have the span, we leave the text-decoration in the parent selector. + * don't have the span, we provide text-decoration in the parent selector. * This provides maximum compatibility and coverage with minimal disruption. */ +details summary:not(.seven-details__summary):focus { + text-decoration: underline; +} details summary:focus span { text-decoration: underline; } diff --git a/core/themes/seven/css/classy/components/collapse-processed.css b/core/themes/seven/css/classy/components/collapse-processed.css index a4d3cbb0ed..c8c786882c 100644 --- a/core/themes/seven/css/classy/components/collapse-processed.css +++ b/core/themes/seven/css/classy/components/collapse-processed.css @@ -30,6 +30,3 @@ transform: rotate(90deg); background-position: 75% 35%; } -.collapse-processed .details-title { - color: #333; -} diff --git a/core/themes/seven/css/components/entity-meta.css b/core/themes/seven/css/components/entity-meta.css index 133021f945..696f46a521 100644 --- a/core/themes/seven/css/components/entity-meta.css +++ b/core/themes/seven/css/components/entity-meta.css @@ -59,16 +59,13 @@ padding: 0.85em 1.25em; text-shadow: 0 1px 0 white; } - -/** - * Hide JS summary from the details polyfill to make it consistent with native - * details elements. - * - * @todo Consider removing this after https://www.drupal.org/node/2493957 has - * been solved. - */ -.entity-meta details .summary { - color: #666; +.seven-details__summary > .summary { text-transform: none; - font-size: 0.85em; + color: #595959; + font-size: 0.95em; + font-weight: normal; } +.seven-details__summary:focus > .summary { + text-decoration: none; +} +