diff --git a/site/public/js/pw-crtc-collapse.css b/site/public/js/pw-crtc-collapse.css new file mode 100644 index 0000000..583149d --- /dev/null +++ b/site/public/js/pw-crtc-collapse.css @@ -0,0 +1,104 @@ +/* pw-crtc-collapse.css — styles for the CRTC page reading aid (TL;DR + accordions). */ + +.pw-tldr { + border: 1px solid #cfe0f5; + background: linear-gradient(135deg, #f0f6ff 0%, #eef9f3 100%); + border-radius: 14px; + padding: 1.1rem 1.25rem; + margin: 0 0 1.75rem; +} +.pw-tldr-head { + display: flex; + align-items: center; + gap: 0.6rem; + margin-bottom: 0.5rem; + font-size: 1.05rem; + color: #1a2744; +} +.pw-tldr-badge { + background: #059669; + color: #fff; + font-size: 0.72rem; + font-weight: 700; + letter-spacing: 0.02em; + text-transform: uppercase; + padding: 0.18rem 0.5rem; + border-radius: 999px; +} +.pw-tldr-lead { + margin: 0 0 0.85rem; + color: #334155; + font-size: 0.96rem; + line-height: 1.55; +} +.pw-tldr-jump { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.45rem; + font-size: 0.85rem; +} +.pw-tldr-jump > span { + color: #64748b; + font-weight: 600; + margin-right: 0.15rem; +} +.pw-tldr-chip { + display: inline-block; + padding: 0.28rem 0.7rem; + background: #fff; + border: 1px solid #cbd5e1; + border-radius: 999px; + color: #1d4ed8; + text-decoration: none; + font-size: 0.82rem; + transition: background 0.12s, border-color 0.12s; +} +.pw-tldr-chip:hover { + background: #1d4ed8; + color: #fff; + border-color: #1d4ed8; +} + +/* Collapsible section */ +.pw-collapse { + border: 1px solid #e2e8f0; + border-radius: 12px; + margin: 0.75rem 0; + background: #fff; + overflow: hidden; +} +.pw-collapse[open] { + box-shadow: 0 1px 4px rgba(15, 23, 42, 0.06); +} +.pw-collapse-summary { + cursor: pointer; + list-style: none; + padding: 0.95rem 1.15rem; + font-weight: 600; + font-size: 1.05rem; + color: #1a2744; + display: flex; + align-items: center; + gap: 0.6rem; + user-select: none; +} +.pw-collapse-summary::-webkit-details-marker { display: none; } +.pw-collapse-summary::before { + content: ""; + flex: 0 0 auto; + width: 0.5rem; + height: 0.5rem; + border-right: 2px solid #2d4e78; + border-bottom: 2px solid #2d4e78; + transform: rotate(-45deg); + transition: transform 0.15s ease; +} +.pw-collapse[open] > .pw-collapse-summary::before { + transform: rotate(45deg); +} +.pw-collapse-summary:hover { background: #f8fafc; } +.pw-collapse-body { + padding: 0 1.15rem 1.1rem; +} +.pw-collapse-body > h2 { display: none; } diff --git a/site/public/js/pw-crtc-collapse.js b/site/public/js/pw-crtc-collapse.js new file mode 100644 index 0000000..5d93790 --- /dev/null +++ b/site/public/js/pw-crtc-collapse.js @@ -0,0 +1,141 @@ +/* + * pw-crtc-collapse.js — progressive-enhancement reading aid for the long + * Canada CRTC carrier page (public/services/telecom/canada-crtc/index.html). + * + * Why a runtime script instead of editing the HTML: that page is a single + * 183 KB minified file with auto-generated markup whose section headings sit + * at inconsistent DOM depths. Rewriting it by hand risks corrupting the markup + * and is hard to maintain. This script enhances it non-destructively: + * + * 1. Injects a "5-minute read" TL;DR + jump menu at the top of the article. + * 2. Collapses a curated set of deep-detail H2 sections into
-style + * accordions (collapsed by default) so the page reads short, while every + * word remains present for SEO and for anyone who expands it. + * + * It is idempotent (guards against double-run) and degrades gracefully: with + * JS off, the full page renders exactly as before. + */ +(function () { + "use strict"; + if (window.__pwCrtcCollapse) return; + window.__pwCrtcCollapse = true; + + // H2 headings (matched by normalized text prefix) to collapse by default. + // Order here is also the order used in the TL;DR jump menu. + var COLLAPSE = [ + { key: "why canada", label: "Why Canada: FCC vs CRTC" }, + { key: "corporate tax comparison", label: "Corporate tax comparison (BC vs US)" }, + { key: "canada telecom m&a", label: "Canada telecom M&A climate" }, + { key: "step 6: canadian business banking", label: "Canadian business banking" }, + { key: "included: canadian wholesale", label: "Wholesale vendor directory" }, + { key: "frequently asked questions", label: "FAQ", open: false }, + { key: "us wholesale voice market", label: "US wholesale / DID restrictions" }, + { key: "the growing burden", label: "The growing burden of a US carrier" }, + { key: "what you'll need", label: "What you'll need to get started" } + ]; + + function norm(s) { + return (s || "").replace(/\s+/g, " ").trim().toLowerCase(); + } + + function ready(fn) { + if (document.readyState !== "loading") fn(); + else document.addEventListener("DOMContentLoaded", fn); + } + + ready(function () { + var h2s = Array.prototype.slice.call(document.querySelectorAll("h2")); + if (!h2s.length) return; + + var made = []; + + COLLAPSE.forEach(function (cfg) { + var h2 = h2s.find(function (h) { + return norm(h.textContent).indexOf(cfg.key) === 0 || + norm(h.textContent).indexOf(cfg.key) !== -1; + }); + if (!h2 || h2.dataset.pwCollapsed) return; + + var parent = h2.parentNode; + // Collect this H2 plus its following siblings up to the next H2 sibling. + var nodes = [h2]; + var n = h2.nextSibling; + while (n) { + if (n.nodeType === 1 && n.tagName === "H2") break; + var next = n.nextSibling; + nodes.push(n); + n = next; + } + if (nodes.length < 2) { + // Heading has no sibling body at this level (body nested elsewhere); + // skip rather than risk an empty/incorrect accordion. + return; + } + + var details = document.createElement("details"); + details.className = "pw-collapse"; + if (cfg.open) details.open = true; + + var summary = document.createElement("summary"); + summary.className = "pw-collapse-summary"; + summary.textContent = h2.textContent.replace(/\s+/g, " ").trim(); + details.appendChild(summary); + + var body = document.createElement("div"); + body.className = "pw-collapse-body"; + + // Move the original H2 (hidden, keeps heading in DOM for SEO) + siblings in. + h2.style.display = "none"; + h2.dataset.pwCollapsed = "1"; + parent.insertBefore(details, nodes[0]); + nodes.forEach(function (node) { body.appendChild(node); }); + details.appendChild(body); + + var id = "crtc-" + cfg.key.replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, ""); + details.id = id; + made.push({ id: id, label: cfg.label }); + }); + + if (!made.length) return; + + // Build the TL;DR + jump menu and insert it right after the hero/pricing card. + var anchor = document.querySelector("nav[aria-label], .max-w-4xl") || document.body; + var tldr = document.createElement("div"); + tldr.className = "pw-tldr"; + tldr.innerHTML = + '
' + + '5-min read' + + 'The short version
' + + '

Become a single Canadian CRTC/BITS carrier ' + + 'and lawfully serve US & international customers \u2014 without taking on the US ' + + 'FCC 499/USF, RMD, STIR/SHAKEN and state-PUC stack a US carrier carries. ' + + 'A Canadian carrier serving US customers as one entity is a common, established ' + + 'structure (per public FCC records). Details below are optional \u2014 tap any to expand.

' + + '
Jump to:
'; + + var jump = tldr.querySelector(".pw-tldr-jump"); + made.forEach(function (m) { + var a = document.createElement("a"); + a.href = "#" + m.id; + a.className = "pw-tldr-chip"; + a.textContent = m.label; + a.addEventListener("click", function (e) { + var d = document.getElementById(m.id); + if (d) { + d.open = true; + e.preventDefault(); + d.scrollIntoView({ behavior: "smooth", block: "start" }); + } + }); + jump.appendChild(a); + }); + + // Insert TL;DR before the first collapsed section for a clean top-of-article placement. + var firstDetails = document.querySelector("details.pw-collapse"); + if (firstDetails && firstDetails.parentNode) { + firstDetails.parentNode.insertBefore(tldr, firstDetails); + } else { + anchor.insertBefore(tldr, anchor.firstChild); + } + }); +})(); diff --git a/site/public/services/telecom/canada-crtc/index.html b/site/public/services/telecom/canada-crtc/index.html index dc95af9..f283e3b 100644 --- a/site/public/services/telecom/canada-crtc/index.html +++ b/site/public/services/telecom/canada-crtc/index.html @@ -5,7 +5,7 @@ if (h === "dev.performancewest.net") return "https://api.dev.performancewest.net"; return "https://api.performancewest.net"; })(); - Canadian CRTC Telecom Carrier Package | Performance West Inc.