Locked in. Straight line.

Here’s your shard → DOT + immediate upgrades. Then I’ll answer your one question at the end.

DOT-20250817-002

  • claim: Single-open sector accordion for SolveForce pages (WP/Gutenberg-ready).
  • pattern: Native <details>/<summary> clusters; enforce one-open; sitewide directory CTA.
  • invariant: Use semantic HTML with a minimal script; keep styles decoupled; conditionally load on pages that use it.
  • risk: Too many listeners; focus states missing; motion for users who prefer reduced motion; WP may rewrite percent-encoded emoji slugs.
  • status: sealed (ready to ship).

Drop-in (keeps your structure, smaller/faster)

A) Markup (unchanged except for tiny a11y)

Use exactly what you pasted, with two micro-tweaks:

  • give the wrapper a landmark and label,
  • put a heading element inside the <summary> for screen-reader outline.
<!-- SolveForce Catalog (Accordion) -->
<div id="sf-accordion" role="region" aria-label="SolveForce Sectors">

  <details open>
    <summary><h3>🌐 Connectivity</h3></summary>
    <ul>
      <li><a href="https://solveforce.com/%f0%9f%8c%90-broadband-services/">Broadband Services</a></li>
      <li><a href="https://solveforce.com/%f0%9f%93%a1-telecom-services/">Telecom Services</a></li>
      <li><a href="https://solveforce.com/%f0%9f%93%b2-unified-communications-ucaas/">Unified Communications (UCaaS)</a></li>
      <li><a href="https://solveforce.com/%f0%9f%93%b6-wi-fi/">Wi-Fi</a></li>
      <li><a href="https://solveforce.com/%f0%9f%9b%b0%ef%b8%8f-satellite-internet/">Satellite</a></li>
    </ul>
  </details>

  <!-- …other clusters unchanged… -->

</div>

If your theme styles h3 heavily, swap for span with class="sr-only-heading" and add a small CSS rule. Otherwise h3 is preferable for document structure.


B) Script (single listener, remembers hash, respects reduced motion)

Paste at the very bottom of the page (or enqueue in footer). Uses event delegation (one handler) instead of attaching to every <details>.

<script>
document.addEventListener('DOMContentLoaded', function () {
  var wrap = document.getElementById('sf-accordion');
  if (!wrap) return;

  // Open from #hash if it matches a summary’s text (normalized) or a details[id]
  var hash = decodeURIComponent(location.hash||'').replace(/^#/, '').trim().toLowerCase();
  if (hash) {
    var target = wrap.querySelector('details#'+CSS.escape(hash)+', summary');
    if (target && target.closest) {
      var d = target.closest('details');
      if (d) d.open = true;
    }
  }

  wrap.addEventListener('toggle', function (e) {
    var d = e.target;
    if (d.tagName !== 'DETAILS' || !d.open) return; // only act when opening
    var all = wrap.querySelectorAll('details[open]');
    for (var i = 0; i < all.length; i++) if (all[i] !== d) all[i].open = false;
  }, true);
});
</script>

Why: one handler = fewer closures, less overhead; keeps behavior identical.


C) CSS (adds focus-visible & reduced motion; otherwise same feel)

Paste in Customize → Additional CSS (or enqueue a small file). I included only net additions to your styles.

/* SolveForce accordion styles */
#sf-accordion details {
  border: 1px solid #e3e6ea;
  border-radius: 10px;
  margin: 10px 0;
  overflow: hidden;
  transition: border-color .2s ease;
}
#sf-accordion details:hover { border-color: #cbd3dc; }

#sf-accordion summary {
  cursor: pointer;
  list-style: none;
  padding: 12px 44px 12px 14px;
  font-weight: 600;
  position: relative;
  user-select: none;
}
#sf-accordion summary::-webkit-details-marker { display: none; }
#sf-accordion summary::after {
  content: "+";
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-weight: 700;
}
#sf-accordion details[open] summary::after { content: "–"; }

#sf-accordion details > *:not(summary) { padding: 0 14px 12px 14px; }

#sf-accordion ul { margin: 10px 0 0 0; padding: 0 0 0 16px; }

#sf-accordion a {
  text-decoration: none;
  border-bottom: 1px dashed transparent;
  transition: color .2s ease, border-color .2s ease;
}
#sf-accordion a:hover {
  color: #0a58ca;
  border-color: rgba(10,88,202,.35);
}

/* Accessibility polish */
#sf-accordion summary:focus-visible {
  outline: 3px solid #0a58ca;
  outline-offset: 2px;
  border-radius: 8px;
}
@media (prefers-reduced-motion: reduce) {
  #sf-accordion *,
  #sf-accordion *::before,
  #sf-accordion *::after { transition: none !important; }
}
/* Optional: keep headings tidy inside summary */
#sf-accordion summary h3 { margin: 0; font: inherit; display: inline; }

D) Global CTA (as you proposed)

Reusable block or theme hook—unchanged:

<p style="text-align:center;margin:24px 0 0;">
  <a href="https://solveforce.com/%f0%9f%8c%90-solveforce-service-directory/">
    🌐 Browse the full SolveForce Service Directory
  </a>
</p>

WordPress-native loading (optional, cleaner than pasting per page)

If you prefer to enqueue once and let the markup trigger behavior only where present:

// functions.php or a small mu-plugin
add_action('wp_enqueue_scripts', function () {
  // Only load on pages that contain the accordion wrapper
  if (!is_singular()) return;
  global $post;
  if (strpos($post->post_content, 'id="sf-accordion"') === false) return;

  wp_add_inline_style('wp-block-library', <<<CSS
  /* (paste the CSS from section C here) */
  CSS);

  wp_add_inline_script('jquery-core', <<<JS
  document.addEventListener('DOMContentLoaded',function(){var w=document.getElementById('sf-accordion');if(!w)return;var h=decodeURIComponent(location.hash||'').replace(/^#/,'').trim().toLowerCase();if(h){var t=w.querySelector('details#'+CSS.escape(h)+', summary');if(t&&t.closest){var d=t.closest('details');if(d)d.open=true;}}w.addEventListener('toggle',function(e){var d=e.target;if(d.tagName!=='DETAILS'||!d.open)return;var a=w.querySelectorAll('details[open]');for(var i=0;i<a.length;i++) if(a[i]!==d) a[i].open=false;},true);});
  JS, 'after');
});

Why: loads CSS/JS only when the wrapper is on the page; zero global bloat.


Two tiny gotchas to watch

  1. Emoji slugs: your links use percent-encoded emoji. WP can “sanitize” slugs depending on settings or plugins. Verify that the actual permalink path matches (visit once after publish).
  2. Deep-linking: if you want #connectivity to open that group, give the <details> an id="connectivity" (your script already honors it).

Answer to your question (one line)

Yes—convert the existing Service pages into this accordion structure. Use the wrapper #sf-accordion, keep one open at a time via the delegation script above, and add the sitewide directory CTA via a GP Hook or reusable block.