DOC add permalink to summary of collapsed details section
diff --git a/doc/conf.py b/doc/conf.py
index 1d4b061f9afb5..288aba5404ae6 100644
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -312,15 +312,18 @@
 html_show_search_summary = False
 
 
+# The "summary-anchor" IDs will be overwritten via JavaScript to be unique.
+# See `doc/theme/scikit-learn-modern/static/js/details-permalink.js`.
 rst_prolog = """
 .. |details-start| raw:: html
 
-    <details>
+    <details id="summary-anchor">
     <summary class="btn btn-light">
 
 .. |details-split| raw:: html
 
     <span class="tooltiptext">Click for more details</span>
+    <a class="headerlink" href="#summary-anchor" title="Permalink to this heading">¶</a>
     </summary>
     <div class="card">
 
diff --git a/doc/modules/grid_search.rst b/doc/modules/grid_search.rst
index 3f99e7841bb00..efdde897e841b 100644
--- a/doc/modules/grid_search.rst
+++ b/doc/modules/grid_search.rst
@@ -612,7 +612,7 @@ Here, ``<estimator>`` is the parameter name of the nested estimator,
 in this case ``estimator``.
 If the meta-estimator is constructed as a collection of estimators as in
 `pipeline.Pipeline`, then ``<estimator>`` refers to the name of the estimator,
-see :ref:`pipeline_nested_parameters`.  In practice, there can be several
+see :ref:`pipeline_nested_parameters`. In practice, there can be several
 levels of nesting::
 
   >>> from sklearn.pipeline import Pipeline
diff --git a/doc/themes/scikit-learn-modern/layout.html b/doc/themes/scikit-learn-modern/layout.html
index 191434c7ec2e2..a759ec2f8c8f0 100644
--- a/doc/themes/scikit-learn-modern/layout.html
+++ b/doc/themes/scikit-learn-modern/layout.html
@@ -36,6 +36,7 @@
   <link rel="stylesheet" href="{{ pathto('_static/' + styles[0], 1) }}" type="text/css" />
 <script id="documentation_options" data-url_root="{{ pathto('', 1) }}" src="{{ pathto('_static/documentation_options.js', 1) }}"></script>
 <script src="{{ pathto('_static/js/vendor/jquery-3.6.3.slim.min.js', 1) }}"></script>
+<script src="{{ pathto('_static/js/details-permalink.js', 1) }}"></script>
 {%- block extrahead %} {% endblock %}
 </head>
 <body>
diff --git a/doc/themes/scikit-learn-modern/static/css/theme.css b/doc/themes/scikit-learn-modern/static/css/theme.css
index 21e1a2336a553..56f208540fd70 100644
--- a/doc/themes/scikit-learn-modern/static/css/theme.css
+++ b/doc/themes/scikit-learn-modern/static/css/theme.css
@@ -149,6 +149,15 @@ div.clearer {
 
 /* details / summary */
 
+/* Enables section links to be visible when anchor-linked */
+div.sk-page-content details::before {
+  display: block;
+  height: 52px;
+  margin-top: -52px;
+  visibility: hidden;
+  content: "";
+}
+
 div.sk-page-content details {
     margin: 4ex 0pt;
 }
@@ -202,6 +211,10 @@ div.sk-page-content summary:hover .tooltiptext {
   visibility: visible;
 }
 
+div.sk-page-content summary:hover .headerlink {
+  visibility: visible;
+}
+
 /* Button */
 
 .sk-btn-primary {
diff --git a/doc/themes/scikit-learn-modern/static/js/details-permalink.js b/doc/themes/scikit-learn-modern/static/js/details-permalink.js
new file mode 100644
index 0000000000000..62392e9836f64
--- /dev/null
+++ b/doc/themes/scikit-learn-modern/static/js/details-permalink.js
@@ -0,0 +1,47 @@
+// Function to create permalink into <details> elements to be able to link them
+// The assumption is that such a block will be defined as follows:
+//     <details id="summary-anchor">
+//     <summary class="btn btn-light">
+//     Some title
+//     <span class="tooltiptext">Click for more details</span>
+//     <a class="headerlink" href="#summary-anchor" title="Permalink to this heading">¶</a>
+//     </summary>
+//     <div class="card">
+//     Some details
+//     </div>
+//     </details>
+// We seek to replace `#summary-anchor` with a unique identifier based on the
+// summary text.
+// This syntax is defined in `doc/conf.py` in the `rst_prolog` variable.
+function updateIdAndHrefBasedOnSummaryText() {
+    var allDetailsElements = document.querySelectorAll('details');
+    // Counter to store the duplicated summary text to add it as a suffix in the
+    // anchor ID
+    var anchorIDCounters = {};
+
+    allDetailsElements.forEach(function (detailsElement) {
+        // Get the <summary> element within the current <details>
+        var summaryElement = detailsElement.querySelector('summary');
+
+        // The ID uses the first line, lowercased, and spaces replaced with dashes
+        var anchorID = summaryElement.textContent.trim().split("\n")[0].replace(/\s+/g, '-').toLowerCase();
+
+        // Suffix the anchor ID with a counter if it already exists
+        if (anchorIDCounters[anchorID]) {
+            anchorIDCounters[anchorID] += 1;
+            anchorID = anchorID + '-' + anchorIDCounters[anchorID];
+        } else {
+            anchorIDCounters[anchorID] = 1;
+        }
+
+        detailsElement.setAttribute('id', anchorID);
+
+        var anchorElement = summaryElement.querySelector('a.headerlink');
+        anchorElement.setAttribute('href', '#' + anchorID);
+    });
+}
+
+// Add an event listener to execute the function when the page is loaded
+document.addEventListener('DOMContentLoaded', function () {
+    updateIdAndHrefBasedOnSummaryText();
+});

closes #27127
follow-up of #26872

Add permalink to summaries of collapsed details section.