internal/frontend,static/frontend: remove styleguide

There was once a plan to serve a styleguide for the formatting of
this site, but it never happened.

Change-Id: Ibd15abe9e3a16abc8cedde1bee2751f334abdbe9
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/566419
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Matloob <matloob@golang.org>
kokoro-CI: kokoro <noreply+kokoro@google.com>
diff --git a/internal/experiment.go b/internal/experiment.go
index e2681b7..b4d29ce 100644
--- a/internal/experiment.go
+++ b/internal/experiment.go
@@ -7,14 +7,12 @@
 
 const (
 	ExperimentEnableStdFrontendFetch = "enable-std-frontend-fetch"
-	ExperimentStyleGuide             = "styleguide"
 )
 
 // Experiments represents all of the active experiments in the codebase and
 // a description of each experiment.
 var Experiments = map[string]string{
 	ExperimentEnableStdFrontendFetch: "Enable frontend fetching for module std.",
-	ExperimentStyleGuide:             "Enable the styleguide.",
 }
 
 // Experiment holds data associated with an experimental feature for frontend
diff --git a/internal/frontend/server.go b/internal/frontend/server.go
index e0183e4..820e5dc 100644
--- a/internal/frontend/server.go
+++ b/internal/frontend/server.go
@@ -203,7 +203,6 @@
 	handle("/license-policy", s.licensePolicyHandler())
 	handle("/about", s.staticPageHandler("about", "About"))
 	handle("/badge/", http.HandlerFunc(s.badgeHandler))
-	handle("/styleguide", http.HandlerFunc(s.errorHandler(s.serveStyleGuide)))
 	handle("/C", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
 		// Package "C" is a special case: redirect to /cmd/cgo.
 		// (This is what golang.org/C does.)
diff --git a/internal/frontend/styleguide.go b/internal/frontend/styleguide.go
deleted file mode 100644
index 3da1218..0000000
--- a/internal/frontend/styleguide.go
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2019 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package frontend
-
-import (
-	"bytes"
-	"context"
-	"html"
-	"io/fs"
-	"net/http"
-	"path"
-	"path/filepath"
-	"strings"
-
-	"github.com/google/safehtml"
-	"github.com/google/safehtml/uncheckedconversions"
-	"golang.org/x/pkgsite/internal"
-	"golang.org/x/pkgsite/internal/derrors"
-	"golang.org/x/pkgsite/internal/experiment"
-	"golang.org/x/pkgsite/internal/frontend/page"
-	"golang.org/x/pkgsite/internal/frontend/serrors"
-	"golang.org/x/text/cases"
-	"golang.org/x/text/language"
-	"rsc.io/markdown"
-)
-
-// serveStyleGuide serves the styleguide page, the content of which is
-// generated from the markdown files in static/shared.
-func (s *Server) serveStyleGuide(w http.ResponseWriter, r *http.Request, ds internal.DataSource) error {
-	ctx := r.Context()
-	if !experiment.IsActive(ctx, internal.ExperimentStyleGuide) {
-		return &serrors.ServerError{Status: http.StatusNotFound}
-	}
-	page, err := styleGuide(ctx, s.staticFS)
-	page.BasePage = s.newBasePage(r, "Style Guide")
-	page.AllowWideContent = true
-	page.UseResponsiveLayout = true
-	page.Title = "Style Guide"
-	if err != nil {
-		return err
-	}
-	s.servePage(ctx, w, "styleguide", page)
-	return nil
-}
-
-type styleGuidePage struct {
-	page.BasePage
-	Title    string
-	Sections []*StyleSection
-	Outline  []*Heading
-}
-
-// styleGuide collects the paths to the markdown files in staticFS,
-// renders them into sections for the styleguide, and merges the document
-// outlines into a single page outline.
-func styleGuide(ctx context.Context, staticFS fs.FS) (_ *styleGuidePage, err error) {
-	defer derrors.WrapStack(&err, "styleGuide)")
-	files, err := markdownFiles(staticFS)
-	if err != nil {
-		return nil, err
-	}
-	var sections []*StyleSection
-	for _, f := range files {
-		doc, err := styleSection(ctx, staticFS, f)
-		if err != nil {
-			return nil, err
-		}
-		sections = append(sections, doc)
-	}
-	var outline []*Heading
-	for _, s := range sections {
-		outline = append(outline, s.Outline...)
-	}
-	return &styleGuidePage{
-		Sections: sections,
-		Outline:  outline,
-	}, nil
-}
-
-// StyleSection represents a section on the styleguide page.
-type StyleSection struct {
-	// ID is the ID for the header element of the section.
-	ID string
-
-	// Title is the title of the section, taken from the name
-	// of the markdown file.
-	Title string
-
-	// Content is the HTML rendered from the parsed markdown file.
-	Content safehtml.HTML
-
-	// Outline is a collection of headings used in the navigation.
-	Outline []*Heading
-}
-
-// styleSection uses goldmark to parse a markdown file and render
-// a section of the styleguide.
-func styleSection(ctx context.Context, fsys fs.FS, filename string) (_ *StyleSection, err error) {
-	defer derrors.WrapStack(&err, "styleSection(%q)", filename)
-	var buf bytes.Buffer
-	source, err := fs.ReadFile(fsys, filename)
-	if err != nil {
-		return nil, err
-	}
-
-	p := markdown.Parser{
-		HeadingIDs:         true,
-		Strikethrough:      true,
-		TaskListItems:      true,
-		AutoLinkText:       true,
-		AutoLinkAssumeHTTP: true,
-		Table:              true,
-		Emoji:              true,
-	}
-	doc := p.Parse(string(source))
-	addMissingHeadingIDs(doc) // extractTOC is going to use these ids, so do this first
-	et := &extractTOC{ctx: ctx}
-	et.extract(doc)
-	renderCodeBlocks(doc)
-	doc.PrintHTML(&buf)
-
-	id := strings.TrimSuffix(filepath.Base(filename), ".md")
-	return &StyleSection{
-		ID:      id,
-		Title:   camelCase(id),
-		Content: uncheckedconversions.HTMLFromStringKnownToSatisfyTypeContract(buf.String()),
-		Outline: et.Headings,
-	}, nil
-}
-
-func writeLines(w *bytes.Buffer, lines []string) {
-	for _, l := range lines {
-		w.WriteString(l)
-		w.WriteString("\n")
-	}
-}
-
-func writeEscapedLines(w *bytes.Buffer, lines []string) {
-	for _, l := range lines {
-		w.WriteString(html.EscapeString(l))
-		w.WriteString("\n")
-	}
-}
-
-// renderFencedCodeBlock writes html code snippets twice, once as actual
-// html for the page and again as a code snippet.
-func renderCodeBlocks(doc *markdown.Document) {
-	var rewriteBlocks func([]markdown.Block)
-	rewriteBlocks = func(blocks []markdown.Block) {
-		for i, b := range blocks {
-			switch x := b.(type) {
-			case *markdown.Text:
-			case *markdown.HTMLBlock:
-			case *markdown.Table:
-			case *markdown.Empty:
-			case *markdown.ThematicBreak:
-			case *markdown.Paragraph:
-				rewriteBlocks([]markdown.Block{x.Text})
-			case *markdown.List:
-				rewriteBlocks(x.Items)
-			case *markdown.Item:
-				rewriteBlocks(x.Blocks)
-			case *markdown.Quote:
-				rewriteBlocks(x.Blocks)
-			case *markdown.Heading:
-			case *markdown.CodeBlock:
-				htmltag := &markdown.HTMLBlock{}
-				var buf bytes.Buffer
-				buf.WriteString("<span>\n")
-				writeLines(&buf, x.Text)
-				buf.WriteString("</span>\n")
-				buf.WriteString("<pre class=\"StringifyElement-markup js-clipboard\">\n")
-				writeEscapedLines(&buf, x.Text)
-				buf.WriteString("</pre>")
-				htmltag.Text = append(htmltag.Text, buf.String())
-				blocks[i] = htmltag
-			}
-		}
-	}
-	rewriteBlocks(doc.Blocks)
-}
-
-func addMissingHeadingIDs(doc *markdown.Document) {
-	walkBlocks(doc.Blocks, func(b markdown.Block) error {
-		if heading, ok := b.(*markdown.Heading); ok {
-			if heading.ID != "" {
-				return nil
-			}
-			var buf bytes.Buffer
-			for _, inl := range heading.Text.Inline {
-				inl.PrintText(&buf)
-			}
-			f := func(c rune) bool {
-				return !('a' <= c && c <= 'z') && !('A' <= c && c <= 'Z') && !('0' <= c && c <= '9')
-			}
-			heading.ID = strings.ToLower(strings.Join(strings.FieldsFunc(buf.String(), f), "-"))
-		}
-		return nil
-	})
-}
-
-// markdownFiles walks the shared directory of fsys and collects
-// the paths to markdown files.
-func markdownFiles(fsys fs.FS) ([]string, error) {
-	var matches []string
-	err := fs.WalkDir(fsys, "shared", func(filepath string, _ fs.DirEntry, err error) error {
-		if err != nil {
-			return err
-		}
-		if path.Ext(filepath) == ".md" {
-			matches = append(matches, filepath)
-		}
-		return nil
-	})
-	if err != nil {
-		return nil, err
-	}
-	return matches, nil
-}
-
-// camelCase turns a snake cased string into a camel case string.
-// For example, hello-world becomes HelloWorld. This function is
-// used to ensure proper casing in the classnames of the style
-// sections.
-func camelCase(s string) string {
-	p := strings.Split(s, "-")
-	var o []string
-	for _, v := range p {
-		o = append(o, cases.Title(language.Und).String(v))
-	}
-	return strings.Join(o, "")
-}
diff --git a/internal/frontend/templates/templates.go b/internal/frontend/templates/templates.go
index 3787460..ac22ded 100644
--- a/internal/frontend/templates/templates.go
+++ b/internal/frontend/templates/templates.go
@@ -58,7 +58,6 @@
 		{"license-policy"},
 		{"search"},
 		{"search-help"},
-		{"styleguide"},
 		{"subrepo"},
 		{"unit/importedby", "unit"},
 		{"unit/imports", "unit"},
diff --git a/internal/middleware/secureheaders.go b/internal/middleware/secureheaders.go
index 37a71dc..17bdf08 100644
--- a/internal/middleware/secureheaders.go
+++ b/internal/middleware/secureheaders.go
@@ -20,8 +20,6 @@
 	"'sha256-mxm3e8M0u3nPPBmLIBgGuMvGUIL5LGv+HzV3bLAIBgw='",
 	// From static/frontend/search/search.tmpl
 	"'sha256-+iS8jRq15Ez/Kzz0/G+SNc0geLNvTyf2NZC7MyJgpRE='",
-	// From static/frontend/styleguide/styleguide.tmpl
-	"'sha256-bL+cN9GtUg5dqjPwDiPJq4yfiEvOyEJ3rfw/YkNIAWc='",
 	// From static/frontend/unit/main/main.tmpl
 	"'sha256-UiVwSVJIK9udADqG5GZe+nRUXWK9wEot2vrxL4D2pQs='",
 	// From static/frontend/unit/unit.tmpl
diff --git a/static/frontend/styleguide/styleguide.css b/static/frontend/styleguide/styleguide.css
deleted file mode 100644
index cad0648..0000000
--- a/static/frontend/styleguide/styleguide.css
+++ /dev/null
@@ -1,158 +0,0 @@
-/*!
- * Copyright 2021 The Go Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
-
-@import url('../unit/main/_meta.css');
-
-.StyleGuide {
-  background-color: var(--color-background);
-}
-
-.StyleGuide > section {
-  align-items: center;
-  display: grid;
-  gap: 1rem 2rem;
-  grid-template-columns: 100%;
-  margin-bottom: 1rem;
-}
-
-.StyleGuide > section > header {
-  border-bottom: var(--border);
-  grid-column: 1/-1;
-  margin-bottom: 1rem;
-  padding-bottom: 1rem;
-}
-
-.StyleGuide > section > h2 {
-  grid-column: 1/-1;
-  width: max-content;
-}
-
-.StyleGuide > section > hr {
-  grid-column: 1/-1;
-}
-
-.StyleGuide > section > h3 {
-  grid-column: 1/-1;
-  margin: 1rem 0;
-}
-
-.StyleGuide > section > p {
-  grid-column: 1/-1;
-}
-
-.StyleGuide .Color,
-.StyleGuide .ColorIntent {
-  grid-template-columns: repeat(auto-fit, 5rem [col-start] minmax(12rem, auto) [col-end]);
-}
-
-.StyleGuide .Outline {
-  align-items: flex-start;
-}
-
-.StyleGuide .Outline > span {
-  margin-top: 0.5rem;
-}
-@media (min-width: 80rem) {
-  .StyleGuide .Icon {
-    grid-template-columns: 10rem 8rem auto;
-  }
-
-  .StyleGuide .Typography,
-  .StyleGuide .Button,
-  .StyleGuide .Carousel,
-  .StyleGuide .Form,
-  .StyleGuide .Modal,
-  .StyleGuide .Message,
-  .StyleGuide .Breadcrumb,
-  .StyleGuide .Chip,
-  .StyleGuide .Tooltip,
-  .StyleGuide .Outline,
-  .StyleGuide .Clipboard {
-    grid-template-columns: 20rem auto;
-  }
-}
-@media (min-width: 112rem) {
-  .StyleGuide .Icon {
-    grid-template-columns: 10rem auto 50%;
-  }
-
-  .StyleGuide .Typography,
-  .StyleGuide .Button,
-  .StyleGuide .Carousel,
-  .StyleGuide .Form,
-  .StyleGuide .Modal,
-  .StyleGuide .Message,
-  .StyleGuide .Breadcrumb,
-  .StyleGuide .Chip,
-  .StyleGuide .Tooltip,
-  .StyleGuide .Outline,
-  .StyleGuide .Clipboard {
-    grid-template-columns: auto 50%;
-  }
-}
-
-.StringifyElement {
-  align-items: baseline;
-  display: flex;
-  flex-direction: column;
-  gap: 1rem;
-  padding: 0.25rem;
-}
-
-.ElementMarkup > pre,
-.StringifyElement-markup {
-  color: var(--color-text-subtle);
-  font-size: 0.875rem;
-  margin-top: 0.5rem;
-  max-width: 100%;
-  padding-left: 2rem;
-  position: relative;
-}
-
-.ElementMarkup > pre::before,
-.StringifyElement-markup::before {
-  background: url('/static/shared/icon/content_copy_gm_grey_24dp.svg');
-  background-repeat: no-repeat;
-  background-size: contain;
-  content: ' ';
-  left: 0.5rem;
-  padding-left: 1rem;
-  position: absolute;
-  width: 1rem;
-}
-
-.StringifyElement-markup:active {
-  filter: contrast(0.9);
-}
-
-.StringifyElement-details {
-  color: var(--color-text-subtle);
-  font-size: 0.8125rem;
-  overflow-x: auto;
-}
-
-.GoColor-circle {
-  background-color: var(--color);
-  border: var(--border);
-  border-radius: 2rem;
-  height: 3rem;
-  margin: auto;
-  margin-bottom: 0.5rem;
-  width: 3rem;
-}
-
-.GoIcon-title,
-.GoColor-title {
-  text-transform: capitalize;
-}
-
-.go-Main-navDesktop a + ul {
-  text-transform: capitalize;
-}
-
-.MainHeader-toggle {
-  display: flex;
-}
diff --git a/static/frontend/styleguide/styleguide.js b/static/frontend/styleguide/styleguide.js
deleted file mode 100644
index 1f82f80..0000000
--- a/static/frontend/styleguide/styleguide.js
+++ /dev/null
@@ -1,33 +0,0 @@
-var h=class{constructor(e){this.el=e;this.setActive=e=>{this.activeIndex=(e+this.slides.length)%this.slides.length,this.el.setAttribute("data-slide-index",String(this.activeIndex));for(let t of this.dots)t.classList.remove("go-Carousel-dot--active");this.dots[this.activeIndex].classList.add("go-Carousel-dot--active");for(let t of this.slides)t.setAttribute("aria-hidden","true");this.slides[this.activeIndex].removeAttribute("aria-hidden"),this.liveRegion.textContent="Slide "+(this.activeIndex+1)+" of "+this.slides.length};var t;this.slides=Array.from(e.querySelectorAll(".go-Carousel-slide")),this.dots=[],this.liveRegion=document.createElement("div"),this.activeIndex=Number((t=e.getAttribute("data-slide-index"))!=null?t:0),this.initSlides(),this.initArrows(),this.initDots(),this.initLiveRegion()}initSlides(){for(let[e,t]of this.slides.entries())e!==this.activeIndex&&t.setAttribute("aria-hidden","true")}initArrows(){var t,i;let e=document.createElement("ul");e.classList.add("go-Carousel-arrows"),e.innerHTML=`
-      <li>
-        <button class="go-Carousel-prevSlide" aria-label="Go to previous slide">
-          <img class="go-Icon" height="24" width="24" src="/static/shared/icon/arrow_left_gm_grey_24dp.svg" alt="">
-        </button>
-      </li>
-      <li>
-        <button class="go-Carousel-nextSlide" aria-label="Go to next slide">
-          <img class="go-Icon" height="24" width="24" src="/static/shared/icon/arrow_right_gm_grey_24dp.svg" alt="">
-        </button>
-      </li>
-    `,(t=e.querySelector(".go-Carousel-prevSlide"))==null||t.addEventListener("click",()=>this.setActive(this.activeIndex-1)),(i=e.querySelector(".go-Carousel-nextSlide"))==null||i.addEventListener("click",()=>this.setActive(this.activeIndex+1)),this.el.append(e)}initDots(){let e=document.createElement("ul");e.classList.add("go-Carousel-dots");for(let t=0;t<this.slides.length;t++){let i=document.createElement("li"),s=document.createElement("button");s.classList.add("go-Carousel-dot"),t===this.activeIndex&&s.classList.add("go-Carousel-dot--active"),s.innerHTML=`<span class="go-Carousel-obscured">Slide ${t+1}</span>`,s.addEventListener("click",()=>this.setActive(t)),i.append(s),e.append(i),this.dots.push(s)}this.el.append(e)}initLiveRegion(){this.liveRegion.setAttribute("aria-live","polite"),this.liveRegion.setAttribute("aria-atomic","true"),this.liveRegion.setAttribute("class","go-Carousel-obscured"),this.liveRegion.textContent=`Slide ${this.activeIndex+1} of ${this.slides.length}`,this.el.appendChild(this.liveRegion)}};var u=class{constructor(e){this.el=e;this.el.addEventListener("change",t=>{let i=t.target,s=i.value;i.value.startsWith("/")||(s="/"+s),window.location.href=s})}};function m(l){let e=document.createElement("label");e.classList.add("go-Label"),e.setAttribute("aria-label","Menu");let t=document.createElement("select");t.classList.add("go-Select","js-selectNav"),e.appendChild(t);let i=document.createElement("optgroup");i.label="Outline",t.appendChild(i);let s={},r;for(let n of l.treeitems){if(Number(n.depth)>4)continue;n.groupTreeitem?(r=s[n.groupTreeitem.label],r||(r=s[n.groupTreeitem.label]=document.createElement("optgroup"),r.label=n.groupTreeitem.label,t.appendChild(r))):r=i;let a=document.createElement("option");a.label=n.label,a.textContent=n.label,a.value=n.el.href.replace(window.location.origin,"").replace("/",""),r.appendChild(a)}return l.addObserver(n=>{var d;let a=n.el.hash,o=(d=t.querySelector(`[value$="${a}"]`))==null?void 0:d.value;o&&(t.value=o)},50),e}var c=class{constructor(e){this.el=e;this.handleResize=()=>{this.el.style.setProperty("--js-tree-height","100vh"),this.el.style.setProperty("--js-tree-height",this.el.clientHeight+"px")};this.treeitems=[],this.firstChars=[],this.firstTreeitem=null,this.lastTreeitem=null,this.observerCallbacks=[],this.init()}init(){this.handleResize(),window.addEventListener("resize",this.handleResize),this.findTreeItems(),this.updateVisibleTreeitems(),this.observeTargets(),this.firstTreeitem&&(this.firstTreeitem.el.tabIndex=0)}observeTargets(){this.addObserver(i=>{this.expandTreeitem(i),this.setSelected(i)});let e=new Map,t=new IntersectionObserver(i=>{for(let s of i)e.set(s.target.id,s.isIntersecting||s.intersectionRatio===1);for(let[s,r]of e)if(r){let n=this.treeitems.find(a=>{var o;return(o=a.el)==null?void 0:o.href.endsWith(`#${s}`)});if(n)for(let a of this.observerCallbacks)a(n);break}},{threshold:1,rootMargin:"-60px 0px 0px 0px"});for(let i of this.treeitems.map(s=>s.el.getAttribute("href")))if(i){let s=i.replace(window.location.origin,"").replace("/","").replace("#",""),r=document.getElementById(s);r&&t.observe(r)}}addObserver(e,t=200){this.observerCallbacks.push(g(e,t))}setFocusToNextItem(e){let t=null;for(let i=e.index+1;i<this.treeitems.length;i++){let s=this.treeitems[i];if(s.isVisible){t=s;break}}t&&this.setFocusToItem(t)}setFocusToPreviousItem(e){let t=null;for(let i=e.index-1;i>-1;i--){let s=this.treeitems[i];if(s.isVisible){t=s;break}}t&&this.setFocusToItem(t)}setFocusToParentItem(e){e.groupTreeitem&&this.setFocusToItem(e.groupTreeitem)}setFocusToFirstItem(){this.firstTreeitem&&this.setFocusToItem(this.firstTreeitem)}setFocusToLastItem(){this.lastTreeitem&&this.setFocusToItem(this.lastTreeitem)}setSelected(e){var t;for(let i of this.el.querySelectorAll('[aria-expanded="true"]'))i!==e.el&&((t=i.nextElementSibling)!=null&&t.contains(e.el)||i.setAttribute("aria-expanded","false"));for(let i of this.el.querySelectorAll("[aria-selected]"))i!==e.el&&i.setAttribute("aria-selected","false");e.el.setAttribute("aria-selected","true"),this.updateVisibleTreeitems(),this.setFocusToItem(e,!1)}expandTreeitem(e){let t=e;for(;t;)t.isExpandable&&t.el.setAttribute("aria-expanded","true"),t=t.groupTreeitem;this.updateVisibleTreeitems()}expandAllSiblingItems(e){for(let t of this.treeitems)t.groupTreeitem===e.groupTreeitem&&t.isExpandable&&this.expandTreeitem(t)}collapseTreeitem(e){let t=null;e.isExpanded()?t=e:t=e.groupTreeitem,t&&(t.el.setAttribute("aria-expanded","false"),this.updateVisibleTreeitems(),this.setFocusToItem(t))}setFocusByFirstCharacter(e,t){let i,s;t=t.toLowerCase(),i=e.index+1,i===this.treeitems.length&&(i=0),s=this.getIndexFirstChars(i,t),s===-1&&(s=this.getIndexFirstChars(0,t)),s>-1&&this.setFocusToItem(this.treeitems[s])}findTreeItems(){let e=(t,i)=>{let s=i,r=t.firstElementChild;for(;r;)(r.tagName==="A"||r.tagName==="SPAN")&&(s=new p(r,this,i),this.treeitems.push(s),this.firstChars.push(s.label.substring(0,1).toLowerCase())),r.firstElementChild&&e(r,s),r=r.nextElementSibling};e(this.el,null),this.treeitems.map((t,i)=>t.index=i)}updateVisibleTreeitems(){this.firstTreeitem=this.treeitems[0];for(let e of this.treeitems){let t=e.groupTreeitem;for(e.isVisible=!0;t&&t.el!==this.el;)t.isExpanded()||(e.isVisible=!1),t=t.groupTreeitem;e.isVisible&&(this.lastTreeitem=e)}}setFocusToItem(e,t=!0){e.el.tabIndex=0,t&&e.el.focus();for(let i of this.treeitems)i!==e&&(i.el.tabIndex=-1)}getIndexFirstChars(e,t){for(let i=e;i<this.firstChars.length;i++)if(this.treeitems[i].isVisible&&t===this.firstChars[i])return i;return-1}},p=class{constructor(e,t,i){var n,a,o,d,f;e.tabIndex=-1,this.el=e,this.groupTreeitem=i,this.label=(a=(n=e.textContent)==null?void 0:n.trim())!=null?a:"",this.tree=t,this.depth=((i==null?void 0:i.depth)||0)+1,this.index=0;let s=e.parentElement;(s==null?void 0:s.tagName.toLowerCase())==="li"&&(s==null||s.setAttribute("role","none")),e.setAttribute("aria-level",this.depth+""),e.getAttribute("aria-label")&&(this.label=(d=(o=e==null?void 0:e.getAttribute("aria-label"))==null?void 0:o.trim())!=null?d:""),this.isExpandable=!1,this.isVisible=!1,this.isInGroup=!!i;let r=e.nextElementSibling;for(;r;){if(r.tagName.toLowerCase()=="ul"){let b=`${(f=i==null?void 0:i.label)!=null?f:""} nav group ${this.label}`.replace(/[\W_]+/g,"_");e.setAttribute("aria-owns",b),e.setAttribute("aria-expanded","false"),r.setAttribute("role","group"),r.setAttribute("id",b),this.isExpandable=!0;break}r=r.nextElementSibling}this.init()}init(){this.el.tabIndex=-1,this.el.getAttribute("role")||this.el.setAttribute("role","treeitem"),this.el.addEventListener("keydown",this.handleKeydown.bind(this)),this.el.addEventListener("click",this.handleClick.bind(this)),this.el.addEventListener("focus",this.handleFocus.bind(this)),this.el.addEventListener("blur",this.handleBlur.bind(this))}isExpanded(){return this.isExpandable?this.el.getAttribute("aria-expanded")==="true":!1}isSelected(){return this.el.getAttribute("aria-selected")==="true"}handleClick(e){e.target!==this.el&&e.target!==this.el.firstElementChild||(this.isExpandable&&(this.isExpanded()&&this.isSelected()?this.tree.collapseTreeitem(this):this.tree.expandTreeitem(this),e.stopPropagation()),this.tree.setSelected(this))}handleFocus(){var t;let e=this.el;this.isExpandable&&(e=(t=e.firstElementChild)!=null?t:e),e.classList.add("focus")}handleBlur(){var t;let e=this.el;this.isExpandable&&(e=(t=e.firstElementChild)!=null?t:e),e.classList.remove("focus")}handleKeydown(e){if(e.altKey||e.ctrlKey||e.metaKey)return;let t=!1;switch(e.key){case" ":case"Enter":this.isExpandable?(this.isExpanded()&&this.isSelected()?this.tree.collapseTreeitem(this):this.tree.expandTreeitem(this),t=!0):e.stopPropagation(),this.tree.setSelected(this);break;case"ArrowUp":this.tree.setFocusToPreviousItem(this),t=!0;break;case"ArrowDown":this.tree.setFocusToNextItem(this),t=!0;break;case"ArrowRight":this.isExpandable&&(this.isExpanded()?this.tree.setFocusToNextItem(this):this.tree.expandTreeitem(this)),t=!0;break;case"ArrowLeft":this.isExpandable&&this.isExpanded()?(this.tree.collapseTreeitem(this),t=!0):this.isInGroup&&(this.tree.setFocusToParentItem(this),t=!0);break;case"Home":this.tree.setFocusToFirstItem(),t=!0;break;case"End":this.tree.setFocusToLastItem(),t=!0;break;default:e.key.length===1&&e.key.match(/\S/)&&(e.key=="*"?this.tree.expandAllSiblingItems(this):this.tree.setFocusByFirstCharacter(this,e.key),t=!0);break}t&&(e.stopPropagation(),e.preventDefault())}};function g(l,e){let t;return(...i)=>{let s=()=>{t=null,l(...i)};t&&clearTimeout(t),t=setTimeout(s,e)}}window.addEventListener("load",()=>{var t,i;let l=document.querySelector(".js-tree");if(l){let s=new c(l),r=m(s);(t=document.querySelector(".js-mainNavMobile"))==null||t.appendChild(r)}let e=document.querySelector(".Outline .js-tree");if(e){let s=new c(e),r=m(s);(i=document.querySelector(".Outline .js-select"))==null||i.appendChild(r)}for(let s of document.querySelectorAll(".js-toggleTheme"))s.addEventListener("click",r=>{let n=r.currentTarget.getAttribute("data-value");document.documentElement.setAttribute("data-theme",String(n))});for(let s of document.querySelectorAll(".js-toggleLayout"))s.addEventListener("click",r=>{let n=r.currentTarget.getAttribute("data-value");document.documentElement.setAttribute("data-layout",String(n))});for(let s of document.querySelectorAll(".js-selectNav"))new u(s);for(let s of document.querySelectorAll(".js-carousel"))new h(s)});customElements.define("go-color",class extends HTMLElement{constructor(){var e;super(),this.style.setProperty("display","contents");let l=this.id;this.removeAttribute("id"),this.innerHTML=`
-        <div style="--color: var(${l});" class="GoColor-circle"></div>
-        <span>
-          <div id="${l}" class="go-textLabel GoColor-title">${l.replace("--color-","").replaceAll("-"," ")}</div>
-          <pre class="StringifyElement-markup">var(${l})</pre>
-        </span>
-      `,(e=this.querySelector("pre"))==null||e.addEventListener("click",()=>{navigator.clipboard.writeText(`var(${l})`)})}});customElements.define("go-icon",class extends HTMLElement{constructor(){super(),this.style.setProperty("display","contents");let l=this.getAttribute("name");this.innerHTML=`<p id="icon-${l}" class="go-textLabel GoIcon-title">${l.replaceAll("_"," ")}</p>
-        <stringify-el>
-          <img class="go-Icon" height="24" width="24" src="/static/shared/icon/${l}_gm_grey_24dp.svg" alt="">
-        </stringify-el>
-      `}});customElements.define("clone-el",class extends HTMLElement{constructor(){var t;super(),this.style.setProperty("display","contents");let l=this.getAttribute("selector");if(!l)return;let e="    "+((t=document.querySelector(l))==null?void 0:t.outerHTML);this.innerHTML=`
-        <stringify-el collapsed>${e}</stringify-el>
-      `}});customElements.define("stringify-el",class extends HTMLElement{constructor(){var i;super(),this.style.setProperty("display","contents");let l=this.innerHTML,e=this.id?` id="${this.id}"`:"";this.removeAttribute("id");let t='<pre class="StringifyElement-markup">'+v(T(l))+"</pre>";this.hasAttribute("collapsed")&&(t=`<details class="StringifyElement-details"><summary>Markup</summary>${t}</details>`),this.innerHTML=`<span${e}>${l}</span>${t}`,(i=this.querySelector("pre"))==null||i.addEventListener("click",()=>{navigator.clipboard.writeText(l)})}});function T(l){return l.split(`
-`).reduce((e,t)=>{if(e.result.length===0){let i=t.indexOf("<");e.start=i===-1?0:i}return t=t.slice(e.start),t&&e.result.push(t),e},{result:[],start:0}).result.join(`
-`)}function v(l){var e;return(e=l==null?void 0:l.replaceAll("<","&lt;"))==null?void 0:e.replaceAll(">","&gt;")}
-/**
- * @license
- * Copyright 2021 The Go Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
-//# sourceMappingURL=styleguide.js.map
diff --git a/static/frontend/styleguide/styleguide.js.map b/static/frontend/styleguide/styleguide.js.map
deleted file mode 100644
index a933ff7..0000000
--- a/static/frontend/styleguide/styleguide.js.map
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "version": 3,
-  "sources": ["../../shared/carousel/carousel.ts", "../../shared/outline/select.ts", "../../shared/outline/tree.ts", "styleguide.ts"],
-  "sourcesContent": ["/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * Carousel Controller adds event listeners, accessibility enhancements, and\n * control elements to a carousel component.\n */\nexport class CarouselController {\n  /**\n   * slides is a collection of slides in the carousel.\n   */\n  private slides: HTMLLIElement[];\n  /**\n   * dots is a collection of dot navigation controls, added to the carousel\n   * by this controller.\n   */\n  private dots: HTMLElement[];\n  /**\n   * liveRegion is a visually hidden element that notifies assitive devices\n   * of visual changes to the carousel. They are added to the carousel by\n   * this controller.\n   */\n  private liveRegion: HTMLElement;\n  /**\n   * activeIndex is the 0-index of the currently active slide.\n   */\n  private activeIndex: number;\n\n  constructor(private el: HTMLElement) {\n    this.slides = Array.from(el.querySelectorAll('.go-Carousel-slide'));\n    this.dots = [];\n    this.liveRegion = document.createElement('div');\n    this.activeIndex = Number(el.getAttribute('data-slide-index') ?? 0);\n\n    this.initSlides();\n    this.initArrows();\n    this.initDots();\n    this.initLiveRegion();\n  }\n\n  private initSlides() {\n    for (const [i, v] of this.slides.entries()) {\n      if (i === this.activeIndex) continue;\n      v.setAttribute('aria-hidden', 'true');\n    }\n  }\n\n  private initArrows() {\n    const arrows = document.createElement('ul');\n    arrows.classList.add('go-Carousel-arrows');\n    arrows.innerHTML = `\n      <li>\n        <button class=\"go-Carousel-prevSlide\" aria-label=\"Go to previous slide\">\n          <img class=\"go-Icon\" height=\"24\" width=\"24\" src=\"/static/shared/icon/arrow_left_gm_grey_24dp.svg\" alt=\"\">\n        </button>\n      </li>\n      <li>\n        <button class=\"go-Carousel-nextSlide\" aria-label=\"Go to next slide\">\n          <img class=\"go-Icon\" height=\"24\" width=\"24\" src=\"/static/shared/icon/arrow_right_gm_grey_24dp.svg\" alt=\"\">\n        </button>\n      </li>\n    `;\n    arrows\n      .querySelector('.go-Carousel-prevSlide')\n      ?.addEventListener('click', () => this.setActive(this.activeIndex - 1));\n    arrows\n      .querySelector('.go-Carousel-nextSlide')\n      ?.addEventListener('click', () => this.setActive(this.activeIndex + 1));\n    this.el.append(arrows);\n  }\n\n  private initDots() {\n    const dots = document.createElement('ul');\n    dots.classList.add('go-Carousel-dots');\n    for (let i = 0; i < this.slides.length; i++) {\n      const li = document.createElement('li');\n      const button = document.createElement('button');\n      button.classList.add('go-Carousel-dot');\n      if (i === this.activeIndex) {\n        button.classList.add('go-Carousel-dot--active');\n      }\n      button.innerHTML = `<span class=\"go-Carousel-obscured\">Slide ${i + 1}</span>`;\n      button.addEventListener('click', () => this.setActive(i));\n      li.append(button);\n      dots.append(li);\n      this.dots.push(button);\n    }\n    this.el.append(dots);\n  }\n\n  private initLiveRegion() {\n    this.liveRegion.setAttribute('aria-live', 'polite');\n    this.liveRegion.setAttribute('aria-atomic', 'true');\n    this.liveRegion.setAttribute('class', 'go-Carousel-obscured');\n    this.liveRegion.textContent = `Slide ${this.activeIndex + 1} of ${this.slides.length}`;\n    this.el.appendChild(this.liveRegion);\n  }\n\n  private setActive = (index: number) => {\n    this.activeIndex = (index + this.slides.length) % this.slides.length;\n    this.el.setAttribute('data-slide-index', String(this.activeIndex));\n    for (const d of this.dots) {\n      d.classList.remove('go-Carousel-dot--active');\n    }\n    this.dots[this.activeIndex].classList.add('go-Carousel-dot--active');\n    for (const s of this.slides) {\n      s.setAttribute('aria-hidden', 'true');\n    }\n    this.slides[this.activeIndex].removeAttribute('aria-hidden');\n    this.liveRegion.textContent = 'Slide ' + (this.activeIndex + 1) + ' of ' + this.slides.length;\n  };\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { TreeNavController } from './tree.js';\n\nexport class SelectNavController {\n  constructor(private el: Element) {\n    this.el.addEventListener('change', e => {\n      const target = e.target as HTMLSelectElement;\n      let href = target.value;\n      if (!target.value.startsWith('/')) {\n        href = '/' + href;\n      }\n      window.location.href = href;\n    });\n  }\n}\n\nexport function makeSelectNav(tree: TreeNavController): HTMLLabelElement {\n  const label = document.createElement('label');\n  label.classList.add('go-Label');\n  label.setAttribute('aria-label', 'Menu');\n  const select = document.createElement('select');\n  select.classList.add('go-Select', 'js-selectNav');\n  label.appendChild(select);\n  const outline = document.createElement('optgroup');\n  outline.label = 'Outline';\n  select.appendChild(outline);\n  const groupMap: Record<string, HTMLOptGroupElement> = {};\n  let group: HTMLOptGroupElement;\n  for (const t of tree.treeitems) {\n    if (Number(t.depth) > 4) continue;\n    if (t.groupTreeitem) {\n      group = groupMap[t.groupTreeitem.label];\n      if (!group) {\n        group = groupMap[t.groupTreeitem.label] = document.createElement('optgroup');\n        group.label = t.groupTreeitem.label;\n        select.appendChild(group);\n      }\n    } else {\n      group = outline;\n    }\n    const o = document.createElement('option');\n    o.label = t.label;\n    o.textContent = t.label;\n    o.value = (t.el as HTMLAnchorElement).href.replace(window.location.origin, '').replace('/', '');\n    group.appendChild(o);\n  }\n  tree.addObserver(t => {\n    const hash = (t.el as HTMLAnchorElement).hash;\n    const value = select.querySelector<HTMLOptionElement>(`[value$=\"${hash}\"]`)?.value;\n    if (value) {\n      select.value = value;\n    }\n  }, 50);\n  return label;\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n/**\n * TreeNavController is the navigation tree component of the documentation page.\n * It adds accessiblity attributes to a tree, observes the heading elements\n * focus the topmost link for headings visible on the page, and implements the\n * WAI-ARIA Treeview Design Pattern with full\n * [keyboard support](https://www.w3.org/TR/wai-aria-practices/examples/treeview/treeview-2/treeview-2a.html#kbd_label).\n */\nexport class TreeNavController {\n  treeitems: TreeItem[];\n\n  /**\n   * firstChars is the first character of each treeitem in the same order\n   * as this.treeitems. We use this array to set focus by character when\n   * navigating the tree with a keyboard.\n   */\n  private firstChars: string[];\n  private firstTreeitem: TreeItem | null;\n  private lastTreeitem: TreeItem | null;\n  private observerCallbacks: ((t: TreeItem) => void)[];\n\n  constructor(private el: HTMLElement) {\n    this.treeitems = [];\n    this.firstChars = [];\n    this.firstTreeitem = null;\n    this.lastTreeitem = null;\n    this.observerCallbacks = [];\n    this.init();\n  }\n\n  private init(): void {\n    this.handleResize();\n    window.addEventListener('resize', this.handleResize);\n    this.findTreeItems();\n    this.updateVisibleTreeitems();\n    this.observeTargets();\n    if (this.firstTreeitem) {\n      this.firstTreeitem.el.tabIndex = 0;\n    }\n  }\n\n  private handleResize = (): void => {\n    this.el.style.setProperty('--js-tree-height', '100vh');\n    this.el.style.setProperty('--js-tree-height', this.el.clientHeight + 'px');\n  };\n\n  private observeTargets() {\n    this.addObserver(treeitem => {\n      this.expandTreeitem(treeitem);\n      this.setSelected(treeitem);\n      // TODO: Fix scroll issue in https://golang.org/issue/47450.\n      // treeitem.el.scrollIntoView({ block: 'nearest' });\n    });\n\n    const targets = new Map<string, boolean>();\n    const observer = new IntersectionObserver(\n      entries => {\n        for (const entry of entries) {\n          targets.set(entry.target.id, entry.isIntersecting || entry.intersectionRatio === 1);\n        }\n        for (const [id, isIntersecting] of targets) {\n          if (isIntersecting) {\n            const active = this.treeitems.find(t =>\n              (t.el as HTMLAnchorElement)?.href.endsWith(`#${id}`)\n            );\n            if (active) {\n              for (const fn of this.observerCallbacks) {\n                fn(active);\n              }\n            }\n            break;\n          }\n        }\n      },\n      {\n        threshold: 1.0,\n        rootMargin: '-60px 0px 0px 0px',\n      }\n    );\n\n    for (const href of this.treeitems.map(t => t.el.getAttribute('href'))) {\n      if (href) {\n        const id = href.replace(window.location.origin, '').replace('/', '').replace('#', '');\n        const target = document.getElementById(id);\n        if (target) {\n          observer.observe(target);\n        }\n      }\n    }\n  }\n\n  addObserver(fn: (t: TreeItem) => void, delay = 200): void {\n    this.observerCallbacks.push(debounce(fn, delay));\n  }\n\n  setFocusToNextItem(currentItem: TreeItem): void {\n    let nextItem = null;\n    for (let i = currentItem.index + 1; i < this.treeitems.length; i++) {\n      const ti = this.treeitems[i];\n      if (ti.isVisible) {\n        nextItem = ti;\n        break;\n      }\n    }\n    if (nextItem) {\n      this.setFocusToItem(nextItem);\n    }\n  }\n\n  setFocusToPreviousItem(currentItem: TreeItem): void {\n    let prevItem = null;\n    for (let i = currentItem.index - 1; i > -1; i--) {\n      const ti = this.treeitems[i];\n      if (ti.isVisible) {\n        prevItem = ti;\n        break;\n      }\n    }\n    if (prevItem) {\n      this.setFocusToItem(prevItem);\n    }\n  }\n\n  setFocusToParentItem(currentItem: TreeItem): void {\n    if (currentItem.groupTreeitem) {\n      this.setFocusToItem(currentItem.groupTreeitem);\n    }\n  }\n\n  setFocusToFirstItem(): void {\n    this.firstTreeitem && this.setFocusToItem(this.firstTreeitem);\n  }\n\n  setFocusToLastItem(): void {\n    this.lastTreeitem && this.setFocusToItem(this.lastTreeitem);\n  }\n\n  setSelected(currentItem: TreeItem): void {\n    for (const l1 of this.el.querySelectorAll('[aria-expanded=\"true\"]')) {\n      if (l1 === currentItem.el) continue;\n      if (!l1.nextElementSibling?.contains(currentItem.el)) {\n        l1.setAttribute('aria-expanded', 'false');\n      }\n    }\n    for (const l1 of this.el.querySelectorAll('[aria-selected]')) {\n      if (l1 !== currentItem.el) {\n        l1.setAttribute('aria-selected', 'false');\n      }\n    }\n    currentItem.el.setAttribute('aria-selected', 'true');\n    this.updateVisibleTreeitems();\n    this.setFocusToItem(currentItem, false);\n  }\n\n  expandTreeitem(treeitem: TreeItem): void {\n    let currentItem: TreeItem | null = treeitem;\n    while (currentItem) {\n      if (currentItem.isExpandable) {\n        currentItem.el.setAttribute('aria-expanded', 'true');\n      }\n      currentItem = currentItem.groupTreeitem;\n    }\n    this.updateVisibleTreeitems();\n  }\n\n  expandAllSiblingItems(currentItem: TreeItem): void {\n    for (const ti of this.treeitems) {\n      if (ti.groupTreeitem === currentItem.groupTreeitem && ti.isExpandable) {\n        this.expandTreeitem(ti);\n      }\n    }\n  }\n\n  collapseTreeitem(currentItem: TreeItem): void {\n    let groupTreeitem = null;\n\n    if (currentItem.isExpanded()) {\n      groupTreeitem = currentItem;\n    } else {\n      groupTreeitem = currentItem.groupTreeitem;\n    }\n\n    if (groupTreeitem) {\n      groupTreeitem.el.setAttribute('aria-expanded', 'false');\n      this.updateVisibleTreeitems();\n      this.setFocusToItem(groupTreeitem);\n    }\n  }\n\n  setFocusByFirstCharacter(currentItem: TreeItem, char: string): void {\n    let start: number, index: number;\n    char = char.toLowerCase();\n\n    // Get start index for search based on position of currentItem\n    start = currentItem.index + 1;\n    if (start === this.treeitems.length) {\n      start = 0;\n    }\n\n    // Check remaining slots in the menu\n    index = this.getIndexFirstChars(start, char);\n\n    // If not found in remaining slots, check from beginning\n    if (index === -1) {\n      index = this.getIndexFirstChars(0, char);\n    }\n\n    // If match was found...\n    if (index > -1) {\n      this.setFocusToItem(this.treeitems[index]);\n    }\n  }\n\n  private findTreeItems() {\n    const findItems = (el: HTMLElement, group: TreeItem | null) => {\n      let ti = group;\n      let curr = el.firstElementChild as HTMLElement;\n      while (curr) {\n        if (curr.tagName === 'A' || curr.tagName === 'SPAN') {\n          ti = new TreeItem(curr, this, group);\n          this.treeitems.push(ti);\n          this.firstChars.push(ti.label.substring(0, 1).toLowerCase());\n        }\n        if (curr.firstElementChild) {\n          findItems(curr, ti);\n        }\n        curr = curr.nextElementSibling as HTMLElement;\n      }\n    };\n    findItems(this.el as HTMLElement, null);\n    this.treeitems.map((ti, idx) => (ti.index = idx));\n  }\n\n  private updateVisibleTreeitems(): void {\n    this.firstTreeitem = this.treeitems[0];\n\n    for (const ti of this.treeitems) {\n      let parent = ti.groupTreeitem;\n      ti.isVisible = true;\n      while (parent && parent.el !== this.el) {\n        if (!parent.isExpanded()) {\n          ti.isVisible = false;\n        }\n        parent = parent.groupTreeitem;\n      }\n      if (ti.isVisible) {\n        this.lastTreeitem = ti;\n      }\n    }\n  }\n\n  private setFocusToItem(treeitem: TreeItem, focusEl = true) {\n    treeitem.el.tabIndex = 0;\n    if (focusEl) {\n      treeitem.el.focus();\n    }\n    for (const ti of this.treeitems) {\n      if (ti !== treeitem) {\n        ti.el.tabIndex = -1;\n      }\n    }\n  }\n\n  private getIndexFirstChars(startIndex: number, char: string): number {\n    for (let i = startIndex; i < this.firstChars.length; i++) {\n      if (this.treeitems[i].isVisible && char === this.firstChars[i]) {\n        return i;\n      }\n    }\n    return -1;\n  }\n}\n\nclass TreeItem {\n  el: HTMLElement;\n  groupTreeitem: TreeItem | null;\n  label: string;\n  isExpandable: boolean;\n  isVisible: boolean;\n  depth: number;\n  index: number;\n\n  private tree: TreeNavController;\n  private isInGroup: boolean;\n\n  constructor(el: HTMLElement, treeObj: TreeNavController, group: TreeItem | null) {\n    el.tabIndex = -1;\n    this.el = el;\n    this.groupTreeitem = group;\n    this.label = el.textContent?.trim() ?? '';\n    this.tree = treeObj;\n    this.depth = (group?.depth || 0) + 1;\n    this.index = 0;\n\n    const parent = el.parentElement;\n    if (parent?.tagName.toLowerCase() === 'li') {\n      parent?.setAttribute('role', 'none');\n    }\n    el.setAttribute('aria-level', this.depth + '');\n    if (el.getAttribute('aria-label')) {\n      this.label = el?.getAttribute('aria-label')?.trim() ?? '';\n    }\n\n    this.isExpandable = false;\n    this.isVisible = false;\n    this.isInGroup = !!group;\n\n    let curr = el.nextElementSibling;\n    while (curr) {\n      if (curr.tagName.toLowerCase() == 'ul') {\n        const groupId = `${group?.label ?? ''} nav group ${this.label}`.replace(/[\\W_]+/g, '_');\n        el.setAttribute('aria-owns', groupId);\n        el.setAttribute('aria-expanded', 'false');\n        curr.setAttribute('role', 'group');\n        curr.setAttribute('id', groupId);\n        this.isExpandable = true;\n        break;\n      }\n\n      curr = curr.nextElementSibling;\n    }\n    this.init();\n  }\n\n  private init() {\n    this.el.tabIndex = -1;\n    if (!this.el.getAttribute('role')) {\n      this.el.setAttribute('role', 'treeitem');\n    }\n    this.el.addEventListener('keydown', this.handleKeydown.bind(this));\n    this.el.addEventListener('click', this.handleClick.bind(this));\n    this.el.addEventListener('focus', this.handleFocus.bind(this));\n    this.el.addEventListener('blur', this.handleBlur.bind(this));\n  }\n\n  isExpanded() {\n    if (this.isExpandable) {\n      return this.el.getAttribute('aria-expanded') === 'true';\n    }\n\n    return false;\n  }\n\n  isSelected() {\n    return this.el.getAttribute('aria-selected') === 'true';\n  }\n\n  private handleClick(event: MouseEvent) {\n    // only process click events that directly happened on this treeitem\n    if (event.target !== this.el && event.target !== this.el.firstElementChild) {\n      return;\n    }\n    if (this.isExpandable) {\n      if (this.isExpanded() && this.isSelected()) {\n        this.tree.collapseTreeitem(this);\n      } else {\n        this.tree.expandTreeitem(this);\n      }\n      event.stopPropagation();\n    }\n    this.tree.setSelected(this);\n  }\n\n  private handleFocus() {\n    let el = this.el;\n    if (this.isExpandable) {\n      el = (el.firstElementChild as HTMLElement) ?? el;\n    }\n    el.classList.add('focus');\n  }\n\n  private handleBlur() {\n    let el = this.el;\n    if (this.isExpandable) {\n      el = (el.firstElementChild as HTMLElement) ?? el;\n    }\n    el.classList.remove('focus');\n  }\n\n  private handleKeydown(event: KeyboardEvent) {\n    if (event.altKey || event.ctrlKey || event.metaKey) {\n      return;\n    }\n\n    let captured = false;\n    switch (event.key) {\n      case ' ':\n      case 'Enter':\n        if (this.isExpandable) {\n          if (this.isExpanded() && this.isSelected()) {\n            this.tree.collapseTreeitem(this);\n          } else {\n            this.tree.expandTreeitem(this);\n          }\n          captured = true;\n        } else {\n          event.stopPropagation();\n        }\n        this.tree.setSelected(this);\n        break;\n\n      case 'ArrowUp':\n        this.tree.setFocusToPreviousItem(this);\n        captured = true;\n        break;\n\n      case 'ArrowDown':\n        this.tree.setFocusToNextItem(this);\n        captured = true;\n        break;\n\n      case 'ArrowRight':\n        if (this.isExpandable) {\n          if (this.isExpanded()) {\n            this.tree.setFocusToNextItem(this);\n          } else {\n            this.tree.expandTreeitem(this);\n          }\n        }\n        captured = true;\n        break;\n\n      case 'ArrowLeft':\n        if (this.isExpandable && this.isExpanded()) {\n          this.tree.collapseTreeitem(this);\n          captured = true;\n        } else {\n          if (this.isInGroup) {\n            this.tree.setFocusToParentItem(this);\n            captured = true;\n          }\n        }\n        break;\n\n      case 'Home':\n        this.tree.setFocusToFirstItem();\n        captured = true;\n        break;\n\n      case 'End':\n        this.tree.setFocusToLastItem();\n        captured = true;\n        break;\n\n      default:\n        if (event.key.length === 1 && event.key.match(/\\S/)) {\n          if (event.key == '*') {\n            this.tree.expandAllSiblingItems(this);\n          } else {\n            this.tree.setFocusByFirstCharacter(this, event.key);\n          }\n          captured = true;\n        }\n        break;\n    }\n\n    if (captured) {\n      event.stopPropagation();\n      event.preventDefault();\n    }\n  }\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nfunction debounce<T extends (...args: any[]) => any>(func: T, wait: number) {\n  let timeout: ReturnType<typeof setTimeout> | null;\n  return (...args: Parameters<T>) => {\n    const later = () => {\n      timeout = null;\n      func(...args);\n    };\n    if (timeout) {\n      clearTimeout(timeout);\n    }\n    timeout = setTimeout(later, wait);\n  };\n}\n", "/**\n * @license\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\nimport { CarouselController } from '../../shared/carousel/carousel';\nimport { SelectNavController, makeSelectNav } from '../../shared/outline/select';\nimport { TreeNavController } from '../../shared/outline/tree';\n\nwindow.addEventListener('load', () => {\n  const tree = document.querySelector<HTMLElement>('.js-tree');\n  if (tree) {\n    const treeCtrl = new TreeNavController(tree);\n    const select = makeSelectNav(treeCtrl);\n    document.querySelector('.js-mainNavMobile')?.appendChild(select);\n  }\n\n  const guideTree = document.querySelector<HTMLElement>('.Outline .js-tree');\n  if (guideTree) {\n    const treeCtrl = new TreeNavController(guideTree);\n    const select = makeSelectNav(treeCtrl);\n    document.querySelector('.Outline .js-select')?.appendChild(select);\n  }\n\n  for (const el of document.querySelectorAll('.js-toggleTheme')) {\n    el.addEventListener('click', e => {\n      const value = (e.currentTarget as HTMLButtonElement).getAttribute('data-value');\n      document.documentElement.setAttribute('data-theme', String(value));\n    });\n  }\n  for (const el of document.querySelectorAll('.js-toggleLayout')) {\n    el.addEventListener('click', e => {\n      const value = (e.currentTarget as HTMLButtonElement).getAttribute('data-value');\n      document.documentElement.setAttribute('data-layout', String(value));\n    });\n  }\n\n  for (const el of document.querySelectorAll<HTMLSelectElement>('.js-selectNav')) {\n    new SelectNavController(el);\n  }\n\n  for (const el of document.querySelectorAll<HTMLSelectElement>('.js-carousel')) {\n    new CarouselController(el);\n  }\n});\n\ncustomElements.define(\n  'go-color',\n  class extends HTMLElement {\n    constructor() {\n      super();\n      this.style.setProperty('display', 'contents');\n      // The current version of TypeScript is not aware of String.replaceAll.\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      const name = this.id as any;\n      this.removeAttribute('id');\n      this.innerHTML = `\n        <div style=\"--color: var(${name});\" class=\"GoColor-circle\"></div>\n        <span>\n          <div id=\"${name}\" class=\"go-textLabel GoColor-title\">${name\n        .replace('--color-', '')\n        .replaceAll('-', ' ')}</div>\n          <pre class=\"StringifyElement-markup\">var(${name})</pre>\n        </span>\n      `;\n      this.querySelector('pre')?.addEventListener('click', () => {\n        navigator.clipboard.writeText(`var(${name})`);\n      });\n    }\n  }\n);\n\ncustomElements.define(\n  'go-icon',\n  class extends HTMLElement {\n    constructor() {\n      super();\n      this.style.setProperty('display', 'contents');\n      // The current version of TypeScript is not aware of String.replaceAll.\n      // eslint-disable-next-line @typescript-eslint/no-explicit-any\n      const name = this.getAttribute('name') as any;\n      this.innerHTML = `<p id=\"icon-${name}\" class=\"go-textLabel GoIcon-title\">${name.replaceAll(\n        '_',\n        ' '\n      )}</p>\n        <stringify-el>\n          <img class=\"go-Icon\" height=\"24\" width=\"24\" src=\"/static/shared/icon/${name}_gm_grey_24dp.svg\" alt=\"\">\n        </stringify-el>\n      `;\n    }\n  }\n);\n\ncustomElements.define(\n  'clone-el',\n  class extends HTMLElement {\n    constructor() {\n      super();\n      this.style.setProperty('display', 'contents');\n      const selector = this.getAttribute('selector');\n      if (!selector) return;\n      const html = '    ' + document.querySelector(selector)?.outerHTML;\n      this.innerHTML = `\n        <stringify-el collapsed>${html}</stringify-el>\n      `;\n    }\n  }\n);\n\ncustomElements.define(\n  'stringify-el',\n  class extends HTMLElement {\n    constructor() {\n      super();\n      this.style.setProperty('display', 'contents');\n      const html = this.innerHTML;\n      const idAttr = this.id ? ` id=\"${this.id}\"` : '';\n      this.removeAttribute('id');\n      let markup = `<pre class=\"StringifyElement-markup\">` + escape(trim(html)) + `</pre>`;\n      if (this.hasAttribute('collapsed')) {\n        markup = `<details class=\"StringifyElement-details\"><summary>Markup</summary>${markup}</details>`;\n      }\n      this.innerHTML = `<span${idAttr}>${html}</span>${markup}`;\n      this.querySelector('pre')?.addEventListener('click', () => {\n        navigator.clipboard.writeText(html);\n      });\n    }\n  }\n);\n\n/**\n * trim removes excess indentation from html markup by\n * measuring the number of spaces in the first line of\n * the given string and removing that number of spaces\n * from the beginning of each line.\n */\nfunction trim(html: string) {\n  return html\n    .split('\\n')\n    .reduce<{ result: string[]; start: number }>(\n      (acc, val) => {\n        if (acc.result.length === 0) {\n          const start = val.indexOf('<');\n          acc.start = start === -1 ? 0 : start;\n        }\n        val = val.slice(acc.start);\n        if (val) {\n          acc.result.push(val);\n        }\n        return acc;\n      },\n      { result: [], start: 0 }\n    )\n    .result.join('\\n');\n}\n\nfunction escape(html: string) {\n  // The current version of TypeScript is not aware of String.replaceAll.\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  return (html as any)?.replaceAll('<', '&lt;')?.replaceAll('>', '&gt;');\n}\n"],
-  "mappings": "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",
-  "names": ["CarouselController", "el", "index", "d", "s", "_a", "i", "v", "_b", "arrows", "dots", "li", "button", "SelectNavController", "el", "e", "target", "href", "makeSelectNav", "tree", "label", "select", "outline", "groupMap", "group", "t", "o", "_a", "hash", "value", "TreeNavController", "el", "treeitem", "targets", "observer", "entries", "entry", "id", "isIntersecting", "active", "t", "_a", "fn", "href", "target", "delay", "debounce", "currentItem", "nextItem", "ti", "prevItem", "l1", "groupTreeitem", "char", "start", "index", "findItems", "group", "curr", "TreeItem", "idx", "parent", "focusEl", "startIndex", "treeObj", "_b", "_c", "_d", "_e", "groupId", "event", "captured", "func", "wait", "timeout", "args", "later", "_a", "_b", "tree", "treeCtrl", "TreeNavController", "select", "makeSelectNav", "guideTree", "el", "e", "value", "SelectNavController", "CarouselController", "name", "selector", "html", "idAttr", "markup", "escape", "trim", "acc", "val", "start"]
-}
diff --git a/static/frontend/styleguide/styleguide.min.css b/static/frontend/styleguide/styleguide.min.css
deleted file mode 100644
index 4376c1d..0000000
--- a/static/frontend/styleguide/styleguide.min.css
+++ /dev/null
@@ -1,17 +0,0 @@
-/*!
- * Copyright 2021 The Go Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
-.UnitMeta{display:grid;gap:1rem 2rem;grid-template-columns:max-content auto;white-space:nowrap}.UnitMeta-details,.UnitMeta-links{display:flex;flex-flow:wrap;flex-direction:row;gap:1rem 2rem}.UnitMeta-repo{align-items:center;display:flex;overflow:hidden}.UnitMeta-repo a{overflow:hidden;text-overflow:ellipsis}@media (min-width: 50rem){.UnitMeta{grid-template-columns:max-content auto}.UnitMeta-details,.UnitMeta-links{flex-direction:row}}@media (min-width: 112rem){:root[data-layout=responsive] .UnitMeta{grid-template-columns:100%}:root[data-layout=responsive] .UnitMeta-details,:root[data-layout=responsive] .UnitMeta-links{flex-direction:column;white-space:nowrap}}.UnitMeta-detailsLearn{width:100%}@media (min-width: 50rem){.UnitMeta-detailsLearn{width:initial}}.StyleGuide{background-color:var(--color-background)}.StyleGuide>section{align-items:center;display:grid;gap:1rem 2rem;grid-template-columns:100%;margin-bottom:1rem}.StyleGuide>section>header{border-bottom:var(--border);grid-column:1/-1;margin-bottom:1rem;padding-bottom:1rem}.StyleGuide>section>h2{grid-column:1/-1;width:max-content}.StyleGuide>section>hr{grid-column:1/-1}.StyleGuide>section>h3{grid-column:1/-1;margin:1rem 0}.StyleGuide>section>p{grid-column:1/-1}.StyleGuide .Color,.StyleGuide .ColorIntent{grid-template-columns:repeat(auto-fit,5rem [col-start] minmax(12rem,auto) [col-end])}.StyleGuide .Outline{align-items:flex-start}.StyleGuide .Outline>span{margin-top:.5rem}@media (min-width: 80rem){.StyleGuide .Icon{grid-template-columns:10rem 8rem auto}.StyleGuide .Typography,.StyleGuide .Button,.StyleGuide .Carousel,.StyleGuide .Form,.StyleGuide .Modal,.StyleGuide .Message,.StyleGuide .Breadcrumb,.StyleGuide .Chip,.StyleGuide .Tooltip,.StyleGuide .Outline,.StyleGuide .Clipboard{grid-template-columns:20rem auto}}@media (min-width: 112rem){.StyleGuide .Icon{grid-template-columns:10rem auto 50%}.StyleGuide .Typography,.StyleGuide .Button,.StyleGuide .Carousel,.StyleGuide .Form,.StyleGuide .Modal,.StyleGuide .Message,.StyleGuide .Breadcrumb,.StyleGuide .Chip,.StyleGuide .Tooltip,.StyleGuide .Outline,.StyleGuide .Clipboard{grid-template-columns:auto 50%}}.StringifyElement{align-items:baseline;display:flex;flex-direction:column;gap:1rem;padding:.25rem}.ElementMarkup>pre,.StringifyElement-markup{color:var(--color-text-subtle);font-size:.875rem;margin-top:.5rem;max-width:100%;padding-left:2rem;position:relative}.ElementMarkup>pre:before,.StringifyElement-markup:before{background:url(/static/shared/icon/content_copy_gm_grey_24dp.svg);background-repeat:no-repeat;background-size:contain;content:" ";left:.5rem;padding-left:1rem;position:absolute;width:1rem}.StringifyElement-markup:active{filter:contrast(.9)}.StringifyElement-details{color:var(--color-text-subtle);font-size:.8125rem;overflow-x:auto}.GoColor-circle{background-color:var(--color);border:var(--border);border-radius:2rem;height:3rem;margin:auto;margin-bottom:.5rem;width:3rem}.GoIcon-title,.GoColor-title{text-transform:capitalize}.go-Main-navDesktop a+ul{text-transform:capitalize}.MainHeader-toggle{display:flex}
-/*!
-* Copyright 2019-2020 The Go Authors. All rights reserved.
-* Use of this source code is governed by a BSD-style
-* license that can be found in the LICENSE file.
-*/
-/*!
- * Copyright 2021 The Go Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
-/*# sourceMappingURL=styleguide.min.css.map */
diff --git a/static/frontend/styleguide/styleguide.min.css.map b/static/frontend/styleguide/styleguide.min.css.map
deleted file mode 100644
index ea84cfa..0000000
--- a/static/frontend/styleguide/styleguide.min.css.map
+++ /dev/null
@@ -1,7 +0,0 @@
-{
-  "version": 3,
-  "sources": ["../unit/main/_meta.css", "styleguide.css"],
-  "sourcesContent": ["/*!\n* Copyright 2019-2020 The Go Authors. All rights reserved.\n* Use of this source code is governed by a BSD-style\n* license that can be found in the LICENSE file.\n*/\n\n.UnitMeta {\n  display: grid;\n  gap: 1rem 2rem;\n  grid-template-columns: max-content auto;\n  white-space: nowrap;\n}\n\n.UnitMeta-details,\n.UnitMeta-links {\n  display: flex;\n  flex-flow: wrap;\n  flex-direction: row;\n  gap: 1rem 2rem;\n}\n\n.UnitMeta-repo {\n  align-items: center;\n  display: flex;\n  overflow: hidden;\n}\n\n.UnitMeta-repo a {\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n@media (min-width: 50rem) {\n  .UnitMeta {\n    grid-template-columns: max-content auto;\n  }\n\n  .UnitMeta-details,\n  .UnitMeta-links {\n    flex-direction: row;\n  }\n}\n@media (min-width: 112rem) {\n  :root[data-layout='responsive'] .UnitMeta {\n    grid-template-columns: 100%;\n  }\n\n  :root[data-layout='responsive'] .UnitMeta-details,\n  :root[data-layout='responsive'] .UnitMeta-links {\n    flex-direction: column;\n    white-space: nowrap;\n  }\n}\n\n.UnitMeta-detailsLearn {\n  width: 100%;\n}\n@media (min-width: 50rem) {\n  .UnitMeta-detailsLearn {\n    width: initial;\n  }\n}\n", "/*!\n * Copyright 2021 The Go Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style\n * license that can be found in the LICENSE file.\n */\n\n@import url('../unit/main/_meta.css');\n\n.StyleGuide {\n  background-color: var(--color-background);\n}\n\n.StyleGuide > section {\n  align-items: center;\n  display: grid;\n  gap: 1rem 2rem;\n  grid-template-columns: 100%;\n  margin-bottom: 1rem;\n}\n\n.StyleGuide > section > header {\n  border-bottom: var(--border);\n  grid-column: 1/-1;\n  margin-bottom: 1rem;\n  padding-bottom: 1rem;\n}\n\n.StyleGuide > section > h2 {\n  grid-column: 1/-1;\n  width: max-content;\n}\n\n.StyleGuide > section > hr {\n  grid-column: 1/-1;\n}\n\n.StyleGuide > section > h3 {\n  grid-column: 1/-1;\n  margin: 1rem 0;\n}\n\n.StyleGuide > section > p {\n  grid-column: 1/-1;\n}\n\n.StyleGuide .Color,\n.StyleGuide .ColorIntent {\n  grid-template-columns: repeat(auto-fit, 5rem [col-start] minmax(12rem, auto) [col-end]);\n}\n\n.StyleGuide .Outline {\n  align-items: flex-start;\n}\n\n.StyleGuide .Outline > span {\n  margin-top: 0.5rem;\n}\n@media (min-width: 80rem) {\n  .StyleGuide .Icon {\n    grid-template-columns: 10rem 8rem auto;\n  }\n\n  .StyleGuide .Typography,\n  .StyleGuide .Button,\n  .StyleGuide .Carousel,\n  .StyleGuide .Form,\n  .StyleGuide .Modal,\n  .StyleGuide .Message,\n  .StyleGuide .Breadcrumb,\n  .StyleGuide .Chip,\n  .StyleGuide .Tooltip,\n  .StyleGuide .Outline,\n  .StyleGuide .Clipboard {\n    grid-template-columns: 20rem auto;\n  }\n}\n@media (min-width: 112rem) {\n  .StyleGuide .Icon {\n    grid-template-columns: 10rem auto 50%;\n  }\n\n  .StyleGuide .Typography,\n  .StyleGuide .Button,\n  .StyleGuide .Carousel,\n  .StyleGuide .Form,\n  .StyleGuide .Modal,\n  .StyleGuide .Message,\n  .StyleGuide .Breadcrumb,\n  .StyleGuide .Chip,\n  .StyleGuide .Tooltip,\n  .StyleGuide .Outline,\n  .StyleGuide .Clipboard {\n    grid-template-columns: auto 50%;\n  }\n}\n\n.StringifyElement {\n  align-items: baseline;\n  display: flex;\n  flex-direction: column;\n  gap: 1rem;\n  padding: 0.25rem;\n}\n\n.ElementMarkup > pre,\n.StringifyElement-markup {\n  color: var(--color-text-subtle);\n  font-size: 0.875rem;\n  margin-top: 0.5rem;\n  max-width: 100%;\n  padding-left: 2rem;\n  position: relative;\n}\n\n.ElementMarkup > pre::before,\n.StringifyElement-markup::before {\n  background: url('/static/shared/icon/content_copy_gm_grey_24dp.svg');\n  background-repeat: no-repeat;\n  background-size: contain;\n  content: ' ';\n  left: 0.5rem;\n  padding-left: 1rem;\n  position: absolute;\n  width: 1rem;\n}\n\n.StringifyElement-markup:active {\n  filter: contrast(0.9);\n}\n\n.StringifyElement-details {\n  color: var(--color-text-subtle);\n  font-size: 0.8125rem;\n  overflow-x: auto;\n}\n\n.GoColor-circle {\n  background-color: var(--color);\n  border: var(--border);\n  border-radius: 2rem;\n  height: 3rem;\n  margin: auto;\n  margin-bottom: 0.5rem;\n  width: 3rem;\n}\n\n.GoIcon-title,\n.GoColor-title {\n  text-transform: capitalize;\n}\n\n.go-Main-navDesktop a + ul {\n  text-transform: capitalize;\n}\n\n.MainHeader-toggle {\n  display: flex;\n}\n"],
-  "mappings": ";;;;;AAMA,UACE,aACA,cACA,uCACA,mBAGF,kCAEE,aACA,eACA,mBACA,cAGF,eACE,mBACA,aACA,gBAGF,iBACE,gBACA,uBAEF,0BACE,UACE,uCAGF,kCAEE,oBAGJ,2BACE,wCACE,2BAGF,8FAEE,sBACA,oBAIJ,uBACE,WAEF,0BACE,uBACE,eClDJ,YACE,yCAGF,oBACE,mBACA,aACA,cACA,2BACA,mBAGF,2BACE,4BACA,iBACA,mBACA,oBAGF,uBACE,iBACA,kBAGF,uBACE,iBAGF,uBACE,iBArCF,cAyCA,sBACE,iBAGF,4CAEE,qFAGF,qBACE,uBAGF,0BACE,iBAEF,0BACE,kBACE,sCAGF,uOAWE,kCAGJ,2BACE,kBACE,qCAGF,uOAWE,gCAIJ,kBACE,qBACA,aACA,sBACA,SApGF,eAwGA,4CAEE,+BACA,kBACA,iBACA,eACA,kBACA,kBAGF,0DAEE,kEACA,4BACA,wBACA,YACA,WACA,kBACA,kBACA,WAGF,gCACE,oBAGF,0BACE,+BACA,mBACA,gBAGF,gBACE,8BACA,qBA1IF,mBA4IE,YA5IF,YA8IE,oBACA,WAGF,6BAEE,0BAGF,yBACE,0BAGF,mBACE",
-  "names": []
-}
diff --git a/static/frontend/styleguide/styleguide.tmpl b/static/frontend/styleguide/styleguide.tmpl
deleted file mode 100644
index 36df899..0000000
--- a/static/frontend/styleguide/styleguide.tmpl
+++ /dev/null
@@ -1,108 +0,0 @@
-<!--
-  Copyright 2021 The Go Authors. All rights reserved.
-  Use of this source code is governed by a BSD-style
-  license that can be found in the LICENSE file.
--->
-
-{{define "pre-content"}}
-  <link href="/static/frontend/unit/unit.min.css" rel="stylesheet">
-  <link href="/static/frontend/styleguide/styleguide.min.css" rel="stylesheet">
-{{end}}
-
-{{define "post-content"}}
-  <script type="module">
-    loadScript("/static/frontend/unit/unit.js", {async: true})
-    loadScript("/static/frontend/styleguide/styleguide.js", {async: true})
-  </script>
-{{end}}
-
-{{define "main"}}
-  <main class="go-Main">
-    <header class="go-Main-header js-mainHeader">
-      {{- block "main-header" .}}{{end -}}
-    </header>
-    <aside class="js-mainAside"></aside>
-    <nav class="go-Main-nav go-Main-nav--sticky js-mainNav" aria-label="Outline">
-      {{- block "main-nav" .}}{{end -}}
-    </nav>
-    <article class="go-Main-article js-mainContent">
-      {{- block "main-content" .}}{{end -}}
-    </article>
-  </main>
-{{end}}
-
-{{define "main-header"}}
-  <nav class="go-Main-headerBreadcrumb go-Breadcrumb" aria-label="Breadcrumb">
-    <ol>
-      <li><a href="/" data-gtmc="breadcrumb link">Packages</a></li>
-      <li>
-        <a href="#breadcrumb" data-gtmc="breadcrumb link" aria-current="location">Style Guide</a>
-      </li>
-    </ol>
-  </nav>
-  <div class="go-Main-headerContent">
-    <div class="go-Main-headerTitle">
-      <a class="go-Main-headerLogo" href="{{if .LocalMode}}/{{else}}https://go.dev/{{end}}" aria-hidden="true" tabindex="-1" data-gtmc="header link"
-          aria-label="Link to Go Homepage">
-        <img height="78" width="207" src="/static/shared/logo/go-blue.svg" alt="Go">
-      </a>
-      <h1>Style Guide</h1>
-    </div>
-    <div class="go-Main-headerDetails">
-      <fieldset class="go-Main-headerDetailItem go-Label go-Label--inline MainHeader-toggle">
-        <legend>Theme</legend>
-        <div class="go-InputGroup">
-          <button class="go-Button go-Button--inverted js-toggleTheme" data-value="light" title="Light"
-              aria-label="Set light theme">
-            <img class="go-Icon" height="24" width="24" src="/static/shared/icon/light_mode_gm_grey_24dp.svg"
-                alt="">
-          </button>
-          <button class="go-Button go-Button--inverted js-toggleTheme" data-value="dark" title="Dark"
-              aria-label="Set dark theme">
-            <img class="go-Icon" height="24" width="24" alt=""
-              src="/static/shared/icon/brightness_2_gm_grey_24dp.svg">
-          </button>
-        </div>
-      </fieldset>
-      <fieldset class="go-Main-headerDetailItem go-Label go-Label--inline MainHeader-toggle">
-        <legend>Layout</legend>
-        <div class="go-InputGroup">
-          <button class="go-Button go-Button--inverted js-toggleLayout" data-value="responsive"
-              title="Responsive" aria-label="Set responsive layout">
-            <img class="go-Icon" height="24" width="24" src="/static/shared/icon/responsive_layout_gm_grey_24dp.svg"
-                alt="">
-          </button>
-          <button class="go-Button go-Button--inverted js-toggleLayout" data-value="stacked"
-              title="Stacked" aria-label="Set stacked layout">
-            <img class="go-Icon" height="24" width="24" src="/static/shared/icon/table_rows_gm_grey_24dp.svg"
-                alt="">
-          </button>
-          <button class="go-Button go-Button--inverted js-toggleLayout" data-value="compact"
-              title="Compact" aria-label="Set compact layout">
-            <img class="go-Icon" height="24" width="24" src="/static/shared/icon/toolbar_gm_grey_24dp.svg"
-                alt="">
-          </button>
-        </div>
-      </fieldset>
-    </div>
-  </div>
-{{end}}
-
-{{define "main-nav"}}
-  <div class="go-Main-navDesktop">
-    {{template "tree-nav" .Outline}}
-  </div>
-  <div class="go-Main-navMobile js-mainNavMobile">
-    <!-- Generated -->
-  </div>
-{{end}}
-
-{{define "main-content"}}
-  <div class="StyleGuide">
-    {{range .Sections}}
-      <section class="{{.Title}}">
-        {{.Content}}
-      </section>
-    {{end}}
-  </div>
-{{end}}
diff --git a/static/frontend/styleguide/styleguide.ts b/static/frontend/styleguide/styleguide.ts
deleted file mode 100644
index c5f8fb9..0000000
--- a/static/frontend/styleguide/styleguide.ts
+++ /dev/null
@@ -1,163 +0,0 @@
-/**
- * @license
- * Copyright 2021 The Go Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style
- * license that can be found in the LICENSE file.
- */
-
-import { CarouselController } from '../../shared/carousel/carousel';
-import { SelectNavController, makeSelectNav } from '../../shared/outline/select';
-import { TreeNavController } from '../../shared/outline/tree';
-
-window.addEventListener('load', () => {
-  const tree = document.querySelector<HTMLElement>('.js-tree');
-  if (tree) {
-    const treeCtrl = new TreeNavController(tree);
-    const select = makeSelectNav(treeCtrl);
-    document.querySelector('.js-mainNavMobile')?.appendChild(select);
-  }
-
-  const guideTree = document.querySelector<HTMLElement>('.Outline .js-tree');
-  if (guideTree) {
-    const treeCtrl = new TreeNavController(guideTree);
-    const select = makeSelectNav(treeCtrl);
-    document.querySelector('.Outline .js-select')?.appendChild(select);
-  }
-
-  for (const el of document.querySelectorAll('.js-toggleTheme')) {
-    el.addEventListener('click', e => {
-      const value = (e.currentTarget as HTMLButtonElement).getAttribute('data-value');
-      document.documentElement.setAttribute('data-theme', String(value));
-    });
-  }
-  for (const el of document.querySelectorAll('.js-toggleLayout')) {
-    el.addEventListener('click', e => {
-      const value = (e.currentTarget as HTMLButtonElement).getAttribute('data-value');
-      document.documentElement.setAttribute('data-layout', String(value));
-    });
-  }
-
-  for (const el of document.querySelectorAll<HTMLSelectElement>('.js-selectNav')) {
-    new SelectNavController(el);
-  }
-
-  for (const el of document.querySelectorAll<HTMLSelectElement>('.js-carousel')) {
-    new CarouselController(el);
-  }
-});
-
-customElements.define(
-  'go-color',
-  class extends HTMLElement {
-    constructor() {
-      super();
-      this.style.setProperty('display', 'contents');
-      // The current version of TypeScript is not aware of String.replaceAll.
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      const name = this.id as any;
-      this.removeAttribute('id');
-      this.innerHTML = `
-        <div style="--color: var(${name});" class="GoColor-circle"></div>
-        <span>
-          <div id="${name}" class="go-textLabel GoColor-title">${name
-        .replace('--color-', '')
-        .replaceAll('-', ' ')}</div>
-          <pre class="StringifyElement-markup">var(${name})</pre>
-        </span>
-      `;
-      this.querySelector('pre')?.addEventListener('click', () => {
-        navigator.clipboard.writeText(`var(${name})`);
-      });
-    }
-  }
-);
-
-customElements.define(
-  'go-icon',
-  class extends HTMLElement {
-    constructor() {
-      super();
-      this.style.setProperty('display', 'contents');
-      // The current version of TypeScript is not aware of String.replaceAll.
-      // eslint-disable-next-line @typescript-eslint/no-explicit-any
-      const name = this.getAttribute('name') as any;
-      this.innerHTML = `<p id="icon-${name}" class="go-textLabel GoIcon-title">${name.replaceAll(
-        '_',
-        ' '
-      )}</p>
-        <stringify-el>
-          <img class="go-Icon" height="24" width="24" src="/static/shared/icon/${name}_gm_grey_24dp.svg" alt="">
-        </stringify-el>
-      `;
-    }
-  }
-);
-
-customElements.define(
-  'clone-el',
-  class extends HTMLElement {
-    constructor() {
-      super();
-      this.style.setProperty('display', 'contents');
-      const selector = this.getAttribute('selector');
-      if (!selector) return;
-      const html = '    ' + document.querySelector(selector)?.outerHTML;
-      this.innerHTML = `
-        <stringify-el collapsed>${html}</stringify-el>
-      `;
-    }
-  }
-);
-
-customElements.define(
-  'stringify-el',
-  class extends HTMLElement {
-    constructor() {
-      super();
-      this.style.setProperty('display', 'contents');
-      const html = this.innerHTML;
-      const idAttr = this.id ? ` id="${this.id}"` : '';
-      this.removeAttribute('id');
-      let markup = `<pre class="StringifyElement-markup">` + escape(trim(html)) + `</pre>`;
-      if (this.hasAttribute('collapsed')) {
-        markup = `<details class="StringifyElement-details"><summary>Markup</summary>${markup}</details>`;
-      }
-      this.innerHTML = `<span${idAttr}>${html}</span>${markup}`;
-      this.querySelector('pre')?.addEventListener('click', () => {
-        navigator.clipboard.writeText(html);
-      });
-    }
-  }
-);
-
-/**
- * trim removes excess indentation from html markup by
- * measuring the number of spaces in the first line of
- * the given string and removing that number of spaces
- * from the beginning of each line.
- */
-function trim(html: string) {
-  return html
-    .split('\n')
-    .reduce<{ result: string[]; start: number }>(
-      (acc, val) => {
-        if (acc.result.length === 0) {
-          const start = val.indexOf('<');
-          acc.start = start === -1 ? 0 : start;
-        }
-        val = val.slice(acc.start);
-        if (val) {
-          acc.result.push(val);
-        }
-        return acc;
-      },
-      { result: [], start: 0 }
-    )
-    .result.join('\n');
-}
-
-function escape(html: string) {
-  // The current version of TypeScript is not aware of String.replaceAll.
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  return (html as any)?.replaceAll('<', '&lt;')?.replaceAll('>', '&gt;');
-}
diff --git a/tests/screentest/config.yaml b/tests/screentest/config.yaml
index ff4b17b..cb27578 100644
--- a/tests/screentest/config.yaml
+++ b/tests/screentest/config.yaml
@@ -1,3 +1 @@
 experiments:
-  - name: styleguide
-    rollout: 0
\ No newline at end of file