content,internal: remove goldmark and readme-outline experiments

Now that goldmark and readme-outline experiments are fully
rolled out we can remove related legacy code.

Change-Id: Ibb1a653726a4a58d5a26b2db308778a0c5ddcffc
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/281674
Trust: Jamal Carvalho <jamal@golang.org>
Run-TryBot: Jamal Carvalho <jamal@golang.org>
Reviewed-by: Jonathan Amsterdam <jba@google.com>
Reviewed-by: Julie Qiu <julie@golang.org>
diff --git a/content/static/css/legacy_readme.css b/content/static/css/legacy_readme.css
deleted file mode 100644
index cae35a1..0000000
--- a/content/static/css/legacy_readme.css
+++ /dev/null
@@ -1,393 +0,0 @@
-/*
-* 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.
-*/
-
-/* ---------- */
-/*
-/* The CSS classes below are generated using devtools/cmd/css/main.go
-/* If the generated CSS already exists, the file is overwritten
-/*
-/* ---------- */
-
-.Overview-readmeContent details {
-  display: block;
-}
-.Overview-readmeContent summary {
-  display: list-item;
-}
-.Overview-readmeContent a {
-  background-color: initial;
-}
-.Overview-readmeContent a:active,
-.Overview-readmeContent a:hover {
-  outline-width: 0;
-}
-.Overview-readmeContent strong {
-  font-weight: inherit;
-  font-weight: bolder;
-}
-.Overview-readmeContent h1 {
-  font-size: 2em;
-  margin: 0.67em 0;
-}
-.Overview-readmeContent img {
-  border-style: none;
-}
-.Overview-readmeContent code,
-.Overview-readmeContent kbd,
-.Overview-readmeContent pre {
-  font-family: monospace, monospace;
-  font-size: 1em;
-}
-.Overview-readmeContent hr {
-  box-sizing: initial;
-  height: 0;
-  overflow: visible;
-}
-.Overview-readmeContent input {
-  font: inherit;
-  margin: 0;
-}
-.Overview-readmeContent input {
-  overflow: visible;
-}
-.Overview-readmeContent [type='checkbox'] {
-  box-sizing: border-box;
-  padding: 0;
-}
-.Overview-readmeContent * {
-  box-sizing: border-box;
-}
-.Overview-readmeContent input {
-  font-family: inherit;
-  font-size: inherit;
-  line-height: inherit;
-}
-.Overview-readmeContent a {
-  color: #0366d6;
-  text-decoration: none;
-}
-.Overview-readmeContent a:hover {
-  text-decoration: underline;
-}
-.Overview-readmeContent strong {
-  font-weight: 600;
-}
-.Overview-readmeContent hr {
-  height: 0;
-  margin: 0.9375rem 0;
-  overflow: hidden;
-  background: transparent;
-  border: 0;
-  border-bottom: 0.0625rem solid #dfe2e5;
-}
-.Overview-readmeContent hr:after,
-.Overview-readmeContent hr:before {
-  display: table;
-  content: '';
-}
-.Overview-readmeContent hr:after {
-  clear: both;
-}
-.Overview-readmeContent table {
-  border-spacing: 0;
-  border-collapse: collapse;
-}
-.Overview-readmeContent td,
-.Overview-readmeContent th {
-  padding: 0;
-}
-.Overview-readmeContent details summary {
-  cursor: pointer;
-}
-.Overview-readmeContent kbd {
-  display: inline-block;
-  padding: 0.1875rem 0.3125rem;
-  font: 0.6875rem SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
-  line-height: 0.625rem;
-  color: #444d56;
-  vertical-align: middle;
-  background-color: #fafbfc;
-  border: 0.0625rem solid #d1d5da;
-  border-radius: 0.1875rem;
-  box-shadow: inset 0 -0.0625rem 0 #d1d5da;
-}
-.Overview-readmeContent h1,
-.Overview-readmeContent h2,
-.Overview-readmeContent h3,
-.Overview-readmeContent h4,
-.Overview-readmeContent h5,
-.Overview-readmeContent h6 {
-  margin-top: 0;
-  margin-bottom: 0;
-}
-.Overview-readmeContent h1 {
-  font-size: 2rem;
-}
-.Overview-readmeContent h1,
-.Overview-readmeContent h2 {
-  font-weight: 600;
-}
-.Overview-readmeContent h2 {
-  font-size: 1.5rem;
-}
-.Overview-readmeContent h3 {
-  font-size: 1.25rem;
-}
-.Overview-readmeContent h3,
-.Overview-readmeContent h4 {
-  font-weight: 600;
-}
-.Overview-readmeContent h4 {
-  font-size: 1rem;
-}
-.Overview-readmeContent h5 {
-  font-size: 0.875rem;
-}
-.Overview-readmeContent h5,
-.Overview-readmeContent h6 {
-  font-weight: 600;
-}
-.Overview-readmeContent h6 {
-  font-size: 0.75rem;
-}
-.Overview-readmeContent p {
-  margin-top: 0;
-  margin-bottom: 0.625rem;
-}
-.Overview-readmeContent blockquote {
-  margin: 0;
-}
-.Overview-readmeContent ol,
-.Overview-readmeContent ul {
-  padding-left: 0;
-  margin-top: 0;
-  margin-bottom: 0;
-}
-.Overview-readmeContent ol ol,
-.Overview-readmeContent ul ol {
-  list-style-type: lower-roman;
-}
-.Overview-readmeContent ol ol ol,
-.Overview-readmeContent ol ul ol,
-.Overview-readmeContent ul ol ol,
-.Overview-readmeContent ul ul ol {
-  list-style-type: lower-alpha;
-}
-.Overview-readmeContent dd {
-  margin-left: 0;
-}
-.Overview-readmeContent code,
-.Overview-readmeContent pre {
-  font-family: SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
-  font-size: 0.75rem;
-}
-.Overview-readmeContent pre {
-  margin-top: 0;
-  margin-bottom: 0;
-}
-.Overview-readmeContent input::-webkit-inner-spin-button,
-.Overview-readmeContent input::-webkit-outer-spin-button {
-  margin: 0;
-  -webkit-appearance: none;
-  appearance: none;
-}
-.Overview-readmeContent :checked + .radio-label {
-  position: relative;
-  z-index: 1;
-  border-color: #0366d6;
-}
-.Overview-readmeContent hr {
-  border-bottom-color: #eee;
-}
-.Overview-readmeContent kbd {
-  display: inline-block;
-  padding: 0.1875rem 0.3125rem;
-  font: 0.6875rem SFMono-Regular, Consolas, Liberation Mono, Menlo, monospace;
-  line-height: 0.625rem;
-  color: #444d56;
-  vertical-align: middle;
-  background-color: #fafbfc;
-  border: 0.0625rem solid #d1d5da;
-  border-radius: 0.1875rem;
-  box-shadow: inset 0 -0.0625rem 0 #d1d5da;
-}
-.Overview-readmeContent a:not([href]) {
-  color: inherit;
-  text-decoration: none;
-}
-.Overview-readmeContent blockquote,
-.Overview-readmeContent details,
-.Overview-readmeContent dl,
-.Overview-readmeContent ol,
-.Overview-readmeContent p,
-.Overview-readmeContent pre,
-.Overview-readmeContent table,
-.Overview-readmeContent ul {
-  margin-top: 0;
-  margin-bottom: 1rem;
-}
-.Overview-readmeContent hr {
-  height: 0.25em;
-  padding: 0;
-  margin: 1.5rem 0;
-  background-color: #e1e4e8;
-  border: 0;
-}
-.Overview-readmeContent blockquote {
-  padding: 0 1em;
-  color: #6a737d;
-  border-left: 0.25em solid #dfe2e5;
-}
-.Overview-readmeContent blockquote > :first-child {
-  margin-top: 0;
-}
-.Overview-readmeContent blockquote > :last-child {
-  margin-bottom: 0;
-}
-.Overview-readmeContent h1,
-.Overview-readmeContent h2,
-.Overview-readmeContent h3,
-.Overview-readmeContent h4,
-.Overview-readmeContent h5,
-.Overview-readmeContent h6 {
-  margin-top: 1.5rem;
-  margin-bottom: 1rem;
-  font-weight: 600;
-  line-height: 1.25;
-}
-.Overview-readmeContent h1 {
-  font-size: 2em;
-}
-.Overview-readmeContent h1,
-.Overview-readmeContent h2 {
-  padding-bottom: 0.3em;
-  border-bottom: 0.0625rem solid #eaecef;
-}
-.Overview-readmeContent h2 {
-  font-size: 1.5em;
-}
-.Overview-readmeContent h3 {
-  font-size: 1.25em;
-}
-.Overview-readmeContent h4 {
-  font-size: 1em;
-}
-.Overview-readmeContent h5 {
-  font-size: 0.875em;
-}
-.Overview-readmeContent h6 {
-  font-size: 0.85em;
-  color: #6a737d;
-}
-.Overview-readmeContent ol,
-.Overview-readmeContent ul {
-  padding-left: 2em;
-}
-.Overview-readmeContent ol ol,
-.Overview-readmeContent ol ul,
-.Overview-readmeContent ul ol,
-.Overview-readmeContent ul ul {
-  margin-top: 0;
-  margin-bottom: 0;
-}
-.Overview-readmeContent li {
-  word-wrap: break-all;
-}
-.Overview-readmeContent li > p {
-  margin-top: 1rem;
-}
-.Overview-readmeContent li + li {
-  margin-top: 0.25em;
-}
-.Overview-readmeContent dl {
-  padding: 0;
-}
-.Overview-readmeContent dl dt {
-  padding: 0;
-  margin-top: 1rem;
-  font-size: 1em;
-  font-style: italic;
-  font-weight: 600;
-}
-.Overview-readmeContent dl dd {
-  padding: 0 1rem;
-  margin-bottom: 1rem;
-}
-.Overview-readmeContent table {
-  display: block;
-  width: 100%;
-  overflow: auto;
-}
-.Overview-readmeContent table th {
-  font-weight: 600;
-}
-.Overview-readmeContent table td,
-.Overview-readmeContent table th {
-  padding: 0.375rem 0.8125rem;
-  border: 0.0625rem solid #dfe2e5;
-}
-.Overview-readmeContent table tr {
-  background-color: #fff;
-  border-top: 0.0625rem solid #c6cbd1;
-}
-.Overview-readmeContent table tr:nth-child(2n) {
-  background-color: #f6f8fa;
-}
-.Overview-readmeContent img {
-  max-width: 100%;
-  box-sizing: initial;
-  background-color: #fff;
-}
-.Overview-readmeContent img[align='right'] {
-  padding-left: 1.25rem;
-}
-.Overview-readmeContent img[align='left'] {
-  padding-right: 1.25rem;
-}
-.Overview-readmeContent code {
-  padding: 0.2em 0.4em;
-  margin: 0;
-  font-size: 85%;
-  background-color: rgba(27, 31, 35, 0.05);
-  border-radius: 0.1875rem;
-}
-.Overview-readmeContent pre {
-  word-wrap: normal;
-}
-.Overview-readmeContent pre > code {
-  padding: 0;
-  margin: 0;
-  font-size: 100%;
-  word-break: normal;
-  white-space: pre;
-  background: transparent;
-  border: 0;
-}
-.Overview-readmeContent pre {
-  padding: 1rem;
-  overflow: auto;
-  font-size: 85%;
-  line-height: 1.45;
-  background-color: #f6f8fa;
-  border-radius: 0.1875rem;
-}
-.Overview-readmeContent pre code {
-  display: inline;
-  max-width: auto;
-  padding: 0;
-  margin: 0;
-  overflow: visible;
-  line-height: inherit;
-  word-wrap: normal;
-  background-color: initial;
-  border: 0;
-}
-
-/* ---------- */
-/*
-/* End output from devtools/cmd/css/main.go
-/*
-/* ---------- */
diff --git a/content/static/css/legacy_unit_outline.css b/content/static/css/legacy_unit_outline.css
deleted file mode 100644
index 71c8a37..0000000
--- a/content/static/css/legacy_unit_outline.css
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Copyright 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.
- */
-
-.Documentation-index,
-.DocNav,
-.DocNav-index {
-  display: block;
-}
-.DocNav {
-  max-height: calc(100vh - var(--header-height));
-  overflow-x: unset;
-  overflow-y: unset;
-  padding-top: 0.5rem;
-  padding-left: unset;
-  position: unset;
-  top: unset;
-}
-@media only screen and (min-width: 52rem) {
-  .DocNav [role='tree'],
-  .DocNav [role='group'] {
-    padding: 0;
-  }
-}
-
-.UnitOutline {
-  display: flex;
-  flex-direction: column;
-  max-height: 100%;
-  position: sticky;
-  top: 4.5rem;
-}
-a.UnitOutline-accordion {
-  align-items: center;
-  color: var(--gray-2);
-  display: flex;
-  font-size: 1.125rem;
-  font-weight: 500;
-  height: 2.5rem;
-  padding: 1rem;
-}
-a.UnitOutline-accordion[aria-expanded='true'] {
-  background-color: var(--gray-9);
-}
-.UnitOutline-panel {
-  padding: 0 18px;
-  background-color: white;
-  display: block;
-  overflow-y: auto;
-}
-.UnitOutline-panel[aria-hidden='true'] {
-  display: none;
-}
-.UnitOutline-jumpTo {
-  display: flex;
-  margin-bottom: 0.5625rem;
-}
-.UnitOutline-jumpTo button {
-  background-color: white;
-  border: 0.0625rem solid var(--gray-8);
-  border-radius: 0.25rem;
-  color: var(--gray-4);
-  cursor: pointer;
-  height: 2rem;
-  padding-left: 1.5rem;
-  text-align: left;
-  width: 100%;
-}
-.UnitOutline-jumpTo button:hover:not([disabled]) {
-  border-color: var(--gray-7);
-}
-.UnitOutline-jumpTo::after {
-  align-self: center;
-  background-color: var(--gray-9);
-  border-radius: 0.5rem;
-  color: var(--gray-6);
-  content: 'f';
-  font-size: 0.75rem;
-  padding: 0.0625rem 0;
-  position: absolute;
-  right: 0.75rem;
-  text-align: center;
-  width: 1.5rem;
-}
-.UnitOutline-jumpTo::before {
-  align-self: center;
-  border-radius: 0.5rem;
-  color: var(--gray-6);
-  content: url('/static/img/pkg-icon-jumpTo_16x16.svg');
-  font-size: 0.75rem;
-  left: 0.4rem;
-  position: absolute;
-  text-align: center;
-  top: 0.5rem;
-}
-.UnitOutline-jumpToInput:disabled {
-  background-color: var(--gray-9);
-}
diff --git a/content/static/html/doc/outline.tmpl b/content/static/html/doc/outline.tmpl
index f888594..a48d09d 100644
--- a/content/static/html/doc/outline.tmpl
+++ b/content/static/html/doc/outline.tmpl
@@ -90,7 +90,7 @@
     </li>
   {{end}}
   {{if .Notes}}
-    <li role="none">
+    <li class="DocNav-notes" role="none">
       <a href="#pkg-notes" role="treeitem" aria-expanded="false" aria-level="2" tabindex="-1"
            aria-owns="nav-group-notes">
         Notes
diff --git a/content/static/html/doc/sidenav.tmpl b/content/static/html/doc/sidenav.tmpl
deleted file mode 100644
index 8cb5a00..0000000
--- a/content/static/html/doc/sidenav.tmpl
+++ /dev/null
@@ -1,93 +0,0 @@
-<!--
-  Copyright 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.
--->
-<nav class="DocNav js-sideNav">
-  <ul role="tree" aria-label="Outline">
-    {{if or .Doc (index .Examples.Map "")}}
-      <li class="DocNav-overview" role="none">
-        <a href="#pkg-overview" class="js-docNav" role="treeitem" aria-level="1" tabindex="0">Overview</a>
-      </li>
-    {{end}}
-    {{- if or .Consts .Vars .Funcs .Types -}}
-      <li class="DocNav-index" role="none">
-        <a href="#pkg-index" class="DocNav-groupLabel{{if not .Examples.List}} DocNav-groupLabel--empty{{end}} js-docNav"
-            role="treeitem" aria-expanded="false" aria-level="1" aria-owns="nav-group-index" tabindex="-1">
-          Index
-        </a>
-        {{if .Examples.List}}
-          <ul role="group" id="nav-group-index">
-            <li role="none">
-              <a href="#pkg-examples" role="treeitem" aria-level="2" tabindex="-1">Examples</a>
-            </li>
-          </ul>
-        {{end}}
-      </li>
-      <li class="DocNav-constants" role="none">
-        <a href="#pkg-constants" class="js-docNav" role="treeitem" aria-level="1" tabindex="-1">Constants</a>
-      </li>
-      <li class="DocNav-variables" role="none">
-        <a href="#pkg-variables" class="js-docNav" role="treeitem" aria-level="1" tabindex="-1">Variables</a>
-      </li>
-      <li class="DocNav-functions" role="none">
-        <a href="#pkg-functions" class="DocNav-groupLabel{{if eq (len .Funcs) 0}} DocNav-groupLabel--empty{{end}} js-docNav"
-            role="treeitem" aria-expanded="false" aria-level="1" aria-owns="nav-group-functions" tabindex="-1">
-          Functions
-        </a>
-        <ul role="group" id="nav-group-functions">
-          {{range .Funcs}}
-            <li role="none">
-              <a href="#{{.Name}}" title="{{render_short_synopsis .Decl}}" role="treeitem" aria-level="2" tabindex="-1">{{render_short_synopsis .Decl}}</a>
-            </li>
-          {{end}}
-        </ul>
-      </li>
-      <li class="DocNav-types" role="none">
-        <a href="#pkg-types" class="DocNav-groupLabel{{if eq (len .Types) 0}} DocNav-groupLabel--empty{{end}} js-docNav"
-            role="treeitem" aria-expanded="false" aria-level="1" aria-owns="nav-group-types" tabindex="-1">
-          Types
-        </a>
-        <ul role="group" id="nav-group-types">
-          {{range .Types}}
-            {{$tname := .Name}}
-            <li role="none">
-              {{if or .Funcs .Methods}}
-                {{$navgroupname := (printf "nav.group.%s" $tname)}}
-                {{$navgroupid := (safe_id $navgroupname)}}
-                <a class="DocNav-groupLabel js-docNavType" href="#{{$tname}}" role="treeitem" aria-expanded="false" aria-level="2" data-aria-owns="{{$navgroupid}}" tabindex="-1">type {{$tname}}</a>
-                <ul role="group" id="{{$navgroupid}}">
-                  {{range .Funcs}}
-                    <li role="none">
-                      <a href="#{{.Name}}" title="{{render_short_synopsis .Decl}}" role="treeitem" aria-level="3" tabindex="-1">{{render_short_synopsis .Decl}}</a>
-                    </li>
-                  {{end}}
-                  {{range .Methods}}
-                    <li role="none">
-                      <a href="#{{$tname}}.{{.Name}}" title="{{render_short_synopsis .Decl}}" role="treeitem" aria-level="3" tabindex="-1">{{render_short_synopsis .Decl}}</a>
-                    </li>
-                  {{end}}
-                </ul>
-              {{else}}
-                <a href="#{{$tname}}" role="treeitem" aria-level="2" tabindex="-1">type {{$tname}}</a>
-              {{end}} {{/* if or .Funcs .Methods */}}
-            </li>
-          {{end}} {{/* range .Types */}}
-        </ul>
-      </li>
-    {{end}}
-    {{if .Notes}}
-      <li class="DocNav-notes" role="none">
-        <a href="#pkg-notes" class="DocNav-groupLabel{{if eq (len .Notes) 0}} DocNav-groupLabel--empty{{end}} js-docNav"
-            role="treeitem" aria-expanded="false" aria-level="1" aria-owns="nav-group-notes" tabindex="-1">Notes</a>
-        <ul role="group" id="nav-group-notes">
-          {{range $marker, $item := .Notes}}
-            <li role="none">
-              <a href="#pkg-note-{{$marker}}" role="treeitem" aria-level="2" tabindex="-1">{{(index $.NoteHeaders $marker).Label}}s</a>
-            </li>
-          {{end}}
-        </ul>
-      </li>
-    {{end}}
-  </ul>
-</nav>
diff --git a/content/static/html/doc/unit.tmpl b/content/static/html/doc/unit.tmpl
index fcbbc6b..43ed942 100644
--- a/content/static/html/doc/unit.tmpl
+++ b/content/static/html/doc/unit.tmpl
@@ -5,7 +5,7 @@
 -->
 
 {{if or .Doc .Consts .Vars .Funcs .Types}}
-  {{template "sidenav.tmpl" .}}
+  {{template "outline.tmpl" .}}
   {{template "sidenav-mobile.tmpl" .}}
 {{end}}
 {{template "body.tmpl" .}}
diff --git a/content/static/html/helpers/_legacy_unit_outline.tmpl b/content/static/html/helpers/_legacy_unit_outline.tmpl
deleted file mode 100644
index 77f4132..0000000
--- a/content/static/html/helpers/_legacy_unit_outline.tmpl
+++ /dev/null
@@ -1,51 +0,0 @@
-<!--
-  Copyright 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.
--->
-
-{{define "legacy_unit_outline"}}
-  <div class="UnitOutline js-accordion">
-    <div class="UnitOutline-jumpTo">
-      <button class="UnitOutline-jumpToInput js-jumpToInput">
-        Jump to ...
-      </button>
-    </div>
-    {{if .Readme.String}}
-      <a href="?readme=expanded#section-readme" class="UnitOutline-accordion js-accordionTrigger js-readmeExpand"
-          role="button" aria-expanded="false" aria-controls="readme-panel" id="readme-accordion">
-        README
-      </a>
-      <div class="UnitOutline-panel js-accordionPanel"
-          id="readme-panel" role="region" aria-labelledby="readme-accordion" aria-hidden="true"></div>
-    {{end}}
-    {{if .IsPackage}}
-      <a class="UnitOutline-accordion  js-accordionTrigger" href="#section-documentation"
-          role="button" aria-expanded="false" aria-controls="outline-panel" id="outline-accordion">
-        Documentation
-      </a>
-      <div class="UnitOutline-panel js-accordionPanel"
-          id="outline-panel" role="region" aria-labelledby="outline-accordion" aria-hidden="true">
-        <div class="Documentation">
-          {{.DocOutline}}
-        </div>
-      </div>
-    {{end}}
-    {{if .SourceFiles}}
-      <a class="UnitOutline-accordion js-accordionTrigger" href="#section-sourcefiles"
-          role="button" aria-expanded="false" aria-controls="files-panel" id="files-accordion">
-        Source Files
-      </a>
-      <div class="UnitOutline-panel js-accordionPanel"
-          id="files-panel" role="region" aria-labelledby="files-accordion" aria-hidden="true"></div>
-    {{end}}
-    {{if (or .Subdirectories .NestedModules)}}
-      <a class="UnitOutline-accordion js-accordionTrigger" href="#section-directories"
-          role="button" aria-expanded="false" aria-controls="directories-panel" id="directories-accordion">
-        Directories
-      </a>
-      <div class="UnitOutline-panel js-accordionPanel"
-          id="directories-panel" role="region" aria-labelledby="directories-accordion" aria-hidden="true"></div>
-    {{end}}
-  </div>
-{{end}}
diff --git a/content/static/html/pages/unit.tmpl b/content/static/html/pages/unit.tmpl
index 18450f1..753780f 100644
--- a/content/static/html/pages/unit.tmpl
+++ b/content/static/html/pages/unit.tmpl
@@ -7,11 +7,7 @@
 {{define "pre_content"}}
   <link href="/static/css/unit.css?version={{.AppVersionLabel}}" rel="stylesheet">
   {{block "unit_pre_content" .}}{{end}}
-  {{if (.Experiments.IsActive "readme-outline")}}
-    <link href="/static/css/unit_outline.css?version={{.AppVersionLabel}}" rel="stylesheet">
-  {{else}}
-    <link href="/static/css/legacy_unit_outline.css?version={{.AppVersionLabel}}" rel="stylesheet">
-  {{end}}
+  <link href="/static/css/unit_outline.css?version={{.AppVersionLabel}}" rel="stylesheet">
 {{end}}
 
 {{define "main_content"}}
diff --git a/content/static/html/pages/unit_details.tmpl b/content/static/html/pages/unit_details.tmpl
index 804805c..6dd91d0 100644
--- a/content/static/html/pages/unit_details.tmpl
+++ b/content/static/html/pages/unit_details.tmpl
@@ -14,11 +14,7 @@
     <div class="UnitDetails-outline" role="navigation"
         aria-label="{{if eq .PageType "std"}}module
         {{else}}{{.PageType}}{{end}}details navigation">
-      {{if (.Experiments.IsActive "readme-outline")}}
-        {{block "unit_outline" .Details}}{{end}}
-      {{else}}
-        {{block "legacy_unit_outline" .Details}}{{end}}
-      {{end}}
+      {{block "unit_outline" .Details}}{{end}}
     </div>
     <div class="UnitDetails-content js-unitDetailsContent" role="main" data-test-id="UnitDetails-content">
       {{if .Details.Readme.String}}
@@ -88,13 +84,7 @@
   <script>
     loadScript("/static/js/playground.min.js", {async: true, defer: true});
   </script>
-  {{if (.Experiments.IsActive "readme-outline")}}
-    <script>
-      loadScript('/static/js/sidenav.js', {type: 'module', async: true, defer: true})
-    </script>
-  {{else}}
-    <script>
-      loadScript('/static/js/legacy_sidenav.js', {async: true, defer: true});
-    </script>
-  {{end}}
+  <script>
+    loadScript('/static/js/sidenav.js', {type: 'module', async: true, defer: true})
+  </script>
 {{end}}
diff --git a/content/static/js/legacy_sidenav.js b/content/static/js/legacy_sidenav.js
deleted file mode 100644
index a6355aa..0000000
--- a/content/static/js/legacy_sidenav.js
+++ /dev/null
@@ -1,646 +0,0 @@
-/**
- * @license
- * 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.
- */
-
-/**
- * Possible KeyboardEvent key values.
- * @private @enum {string}
- */
-const Key = {
-  UP: 'ArrowUp',
-  DOWN: 'ArrowDown',
-  LEFT: 'ArrowLeft',
-  RIGHT: 'ArrowRight',
-  ENTER: 'Enter',
-  ASTERISK: '*',
-  SPACE: ' ',
-  END: 'End',
-  HOME: 'Home',
-
-  // Global keyboard shortcuts.
-  // TODO(golang.org/issue/40246): consolidate keyboard shortcut handling to avoid
-  // this duplication.
-  Y: 'y',
-  FORWARD_SLASH: '/',
-  QUESTION_MARK: '?',
-};
-
-/**
- * The navigation tree component of the documentation page.
- */
-class DocNavTreeController {
-  /**
-   * Instantiates a navigation tree.
-   * @param {!Element} el
-   */
-  constructor(el) {
-    /** @private {!Element} */
-    this._el = el;
-
-    /**
-     * The currently selected element.
-     * @private {Element}
-     */
-    this._selectedEl = null;
-
-    /**
-     * The index of the currently focused item. Used when navigating the tree
-     * using the keyboard.
-     * @private {number}
-     */
-    this._focusedIndex = 0;
-
-    /**
-     * The elements currently visible (not within a collapsed node of the tree).
-     * @private {!Array<!Element>}
-     */
-    this._visibleItems = [];
-
-    /**
-     * The current search string.
-     * @private {string}
-     */
-    this._searchString = '';
-
-    /**
-     * The timestamp of the last keydown event. Used to track whether to use the
-     * current search string.
-     * @private {number}
-     */
-    this._lastKeyDownTimeStamp = -Infinity;
-
-    this.addEventListeners();
-    this.updateVisibleItems();
-    this.initialize();
-  }
-
-  /**
-   * Initializes the tree. Should be called only once.
-   * @private
-   */
-  initialize() {
-    this._el.querySelectorAll(`[role='treeitem']`).forEach((el, i) => {
-      el.addEventListener('click', e => this.handleItemClick(/** @type {!MouseEvent} */ (e)));
-    });
-
-    // TODO: remove once safehtml supports aria-owns with dynamic values.
-    this._el.querySelectorAll('[data-aria-owns]').forEach(el => {
-      el.setAttribute('aria-owns', el.getAttribute('data-aria-owns'));
-    });
-  }
-
-  /**
-   * @private
-   */
-  addEventListeners() {
-    this._el.addEventListener('keydown', e =>
-      this.handleKeyDown(/** @type {!KeyboardEvent} */ (e))
-    );
-  }
-
-  /**
-   * Sets the visible item with the given index with the proper tabindex and
-   * focuses it.
-   * @param {!number} index
-   * @return {undefined}
-   */
-  setFocusedIndex(index) {
-    if (index === this._focusedIndex) {
-      return;
-    }
-
-    let itemEl = this._visibleItems[this._focusedIndex];
-    itemEl.setAttribute('tabindex', '-1');
-
-    itemEl = this._visibleItems[index];
-    itemEl.setAttribute('tabindex', '0');
-    itemEl.focus();
-
-    this._focusedIndex = index;
-  }
-
-  /**
-   * Marks the navigation node with the given ID as selected. If no ID is
-   * provided, the first visible item in the tree is used.
-   * @param {!string=} opt_id
-   * @return {undefined}
-   */
-  setSelectedId(opt_id) {
-    if (this._selectedEl) {
-      this._selectedEl.removeAttribute('aria-selected');
-      this._selectedEl = null;
-    }
-    if (opt_id) {
-      this._selectedEl = this._el.querySelector(`[role='treeitem'][href='#${opt_id}']`);
-    } else if (this._visibleItems.length > 0) {
-      this._selectedEl = this._visibleItems[0];
-    }
-
-    if (!this._selectedEl) {
-      return;
-    }
-    this._selectedEl.setAttribute('aria-selected', 'true');
-    this.expandAllParents(this._selectedEl);
-    this.scrollElementIntoView(this._selectedEl);
-  }
-
-  /**
-   * Expands all sibling items of the given element.
-   * @param {!Element} el
-   * @private
-   */
-  expandAllSiblingItems(el) {
-    const level = el.getAttribute('aria-level');
-    this._el.querySelectorAll(`[aria-level='${level}'][aria-expanded='false']`).forEach(el => {
-      el.setAttribute('aria-expanded', 'true');
-    });
-    this.updateVisibleItems();
-    this._focusedIndex = this._visibleItems.indexOf(el);
-  }
-
-  /**
-   * Expands all parent items of the given element.
-   * @param {!Element} el
-   * @private
-   */
-  expandAllParents(el) {
-    if (!this._visibleItems.includes(el)) {
-      let owningItemEl = this.owningItem(el);
-      while (owningItemEl) {
-        this.expandItem(owningItemEl);
-        owningItemEl = this.owningItem(owningItemEl);
-      }
-    }
-  }
-
-  /**
-   * Scrolls the given element into view, aligning the element in the center
-   * of the viewport. If the element is already in view, no scrolling occurs.
-   * @param {!Element} el
-   * @private
-   */
-  scrollElementIntoView(el) {
-    const STICKY_HEADER_HEIGHT_PX = 55;
-    const viewportHeightPx = document.documentElement.clientHeight;
-    const elRect = el.getBoundingClientRect();
-    const verticalCenterPointPx = (viewportHeightPx - STICKY_HEADER_HEIGHT_PX) / 2;
-    if (elRect.top < STICKY_HEADER_HEIGHT_PX) {
-      // Element is occluded at top of view by header or by being offscreen.
-      this._el.scrollTop -=
-        STICKY_HEADER_HEIGHT_PX - elRect.top - elRect.height + verticalCenterPointPx;
-    } else if (elRect.bottom > viewportHeightPx) {
-      // Element is below viewport.
-      this._el.scrollTop = elRect.bottom - viewportHeightPx + verticalCenterPointPx;
-    } else {
-      return;
-    }
-  }
-
-  /**
-   * Handles when a tree item is clicked.
-   * @param {!MouseEvent} e
-   * @private
-   */
-  handleItemClick(e) {
-    const el = /** @type {!Element} */ (e.target);
-    this.setFocusedIndex(this._visibleItems.indexOf(el));
-    if (el.hasAttribute('aria-expanded')) {
-      this.toggleItemExpandedState(el);
-    }
-    this.closeInactiveDocNavGroups(el);
-    this.closeInactiveDocNavTypeGroups(el);
-  }
-
-  /**
-   * Closes inactive top level nav groups when a new tree item clicked.
-   * @param {!Element} el
-   * @private
-   */
-  closeInactiveDocNavGroups(el) {
-    if (el.classList.contains('js-docNav')) {
-      document.querySelectorAll('.js-docNav').forEach(nav => {
-        if (nav.getAttribute('aria-expanded') === 'true' && nav !== el) {
-          nav.setAttribute('aria-expanded', 'false');
-        }
-      });
-      this.updateVisibleItems();
-      this._focusedIndex = this._visibleItems.indexOf(el);
-    }
-  }
-
-  /**
-   * Closes inactive type level nav groups when a new tree item clicked.
-   * @param {!Element} el
-   * @private
-   */
-  closeInactiveDocNavTypeGroups(el) {
-    if (el.classList.contains('js-docNavType')) {
-      document.querySelectorAll('.js-docNavType').forEach(nav => {
-        if (nav.getAttribute('aria-expanded') === 'true' && nav !== el) {
-          nav.setAttribute('aria-expanded', 'false');
-        }
-      });
-      this.updateVisibleItems();
-      this._focusedIndex = this._visibleItems.indexOf(el);
-    }
-  }
-
-  /**
-   * Handles when a key is pressed when the component is in focus.
-   * @param {!KeyboardEvent} e
-   * @private
-   */
-  handleKeyDown(e) {
-    const targetEl = /** @type {!Element} */ (e.target);
-
-    switch (e.key) {
-      case Key.ASTERISK:
-        this.expandAllSiblingItems(targetEl);
-        e.stopPropagation();
-        e.preventDefault();
-        return;
-
-      // Global keyboard shortcuts.
-      // TODO(golang.org/issue/40246): consolidate keyboard shortcut handling
-      // to avoid this duplication.
-      case Key.FORWARD_SLASH:
-      case Key.QUESTION_MARK:
-        return;
-
-      case Key.DOWN:
-        this.focusNextItem();
-        break;
-
-      case Key.UP:
-        this.focusPreviousItem();
-        break;
-
-      case Key.LEFT:
-        if (e.target.getAttribute('aria-expanded') === 'true') {
-          this.collapseItem(targetEl);
-        } else {
-          this.focusParentItem(targetEl);
-        }
-        break;
-
-      case Key.RIGHT: {
-        switch (targetEl.getAttribute('aria-expanded')) {
-          case 'false':
-            this.expandItem(targetEl);
-            break;
-          case 'true':
-            // Select the first child.
-            this.focusNextItem();
-            break;
-        }
-        break;
-      }
-
-      case Key.HOME:
-        this.setFocusedIndex(0);
-        break;
-
-      case Key.END:
-        this.setFocusedIndex(this._visibleItems.length - 1);
-        break;
-
-      case Key.ENTER:
-        if (targetEl.tagName === 'A') {
-          // Enter triggers desired behavior by itself.
-          return;
-        }
-      // Fall through for non-anchor items to be handled the same as when
-      // the space key is pressed.
-      case Key.SPACE:
-        targetEl.click();
-        break;
-
-      default:
-        // Could be a typeahead search.
-        this.handleSearch(e);
-        return;
-    }
-    e.preventDefault();
-    e.stopPropagation();
-  }
-
-  /**
-   * Handles when a key event isn’t matched by shortcut handling, indicating
-   * that the user may be attempting a typeahead search.
-   * @param {!KeyboardEvent} e
-   * @private
-   */
-  handleSearch(e) {
-    if (
-      e.metaKey ||
-      e.altKey ||
-      e.ctrlKey ||
-      e.isComposing ||
-      e.key.length > 1 ||
-      !e.key.match(/\S/)
-    ) {
-      return;
-    }
-
-    // KeyDown events should be within one second of each other to be considered
-    // part of the same typeahead search string.
-    const MAX_TYPEAHEAD_THRESHOLD_MS = 1000;
-    if (e.timeStamp - this._lastKeyDownTimeStamp > MAX_TYPEAHEAD_THRESHOLD_MS) {
-      this._searchString = '';
-    }
-    this._lastKeyDownTimeStamp = e.timeStamp;
-    this._searchString += e.key.toLocaleLowerCase();
-    const focusedElementText = this._visibleItems[
-      this._focusedIndex
-    ].textContent.toLocaleLowerCase();
-    if (this._searchString.length === 1 || !focusedElementText.startsWith(this._searchString)) {
-      this.focusNextItemWithPrefix(this._searchString);
-    }
-    e.stopPropagation();
-    e.preventDefault();
-  }
-
-  /**
-   * Focuses on the next visible tree item (after the currently focused element,
-   * wrapping the tree) that has a prefix equal to the given search string.
-   * @param {string} prefix
-   */
-  focusNextItemWithPrefix(prefix) {
-    let i = this._focusedIndex + 1;
-    if (i > this._visibleItems.length - 1) {
-      i = 0;
-    }
-    while (i !== this._focusedIndex) {
-      if (this._visibleItems[i].textContent.toLocaleLowerCase().startsWith(prefix)) {
-        this.setFocusedIndex(i);
-        return;
-      }
-      if (i >= this._visibleItems.length - 1) {
-        i = 0;
-      } else {
-        i++;
-      }
-    }
-  }
-
-  /**
-   * @param {!Element} el
-   * @private
-   */
-  toggleItemExpandedState(el) {
-    el.getAttribute('aria-expanded') === 'true' ? this.collapseItem(el) : this.expandItem(el);
-  }
-
-  /**
-   * @private
-   */
-  focusPreviousItem() {
-    this.setFocusedIndex(Math.max(0, this._focusedIndex - 1));
-  }
-
-  /**
-   * @private
-   */
-  focusNextItem() {
-    this.setFocusedIndex(Math.min(this._visibleItems.length - 1, this._focusedIndex + 1));
-  }
-
-  /**
-   * @param {!Element} el
-   * @private
-   */
-  collapseItem(el) {
-    el.setAttribute('aria-expanded', 'false');
-    this.updateVisibleItems();
-  }
-
-  /**
-   * @param {!Element} el
-   * @private
-   */
-  expandItem(el) {
-    el.setAttribute('aria-expanded', 'true');
-    this.updateVisibleItems();
-  }
-
-  /**
-   * @param {!Element} el
-   * @private
-   */
-  focusParentItem(el) {
-    const owningItemEl = this.owningItem(el);
-    if (owningItemEl) {
-      this.setFocusedIndex(this._visibleItems.indexOf(owningItemEl));
-    }
-  }
-
-  /**
-   * @param {!Element} el
-   * @return {Element} The first parent item that “owns” the group that el is a member of,
-   * or null if there is none.
-   */
-  owningItem(el) {
-    const groupEl = el.closest(`[role='group']`);
-    if (!groupEl) {
-      return null;
-    }
-    return groupEl.parentElement.querySelector(`[aria-owns='${groupEl.id}']`);
-  }
-
-  /**
-   * Updates which items are visible (not a child of a collapsed item).
-   * @private
-   */
-  updateVisibleItems() {
-    const allEls = Array.from(this._el.querySelectorAll(`[role='treeitem']`));
-    const hiddenEls = Array.from(
-      this._el.querySelectorAll(`[aria-expanded='false'] + [role='group'] [role='treeitem']`)
-    );
-    this._visibleItems = allEls.filter(el => !hiddenEls.includes(el));
-  }
-}
-
-/**
- * Primary controller for the documentation page, handling coordination between
- * the navigation and content components. This class ensures that any
- * documentation elements in view are properly shown/highlighted in the
- * navigation components.
- *
- * Since navigation is essentially handled by anchor tags with fragment IDs as
- * hrefs, the fragment ID (referenced in this code as simply “ID”) is used to
- * look up both navigation and content nodes.
- */
-class DocPageController {
-  /**
-   * Instantiates the controller, setting up the navigation controller (both
-   * desktop and mobile), and event listeners. This should only be called once.
-   * @param {Element} sideNavEl
-   * @param {Element} mobileNavEl
-   * @param {Element} contentEl
-   */
-  constructor(sideNavEl, mobileNavEl, contentEl) {
-    if (!sideNavEl || !mobileNavEl || !contentEl) {
-      console.warn('Unable to find all elements needed for navigation');
-      return;
-    }
-
-    /**
-     * @type {!Element}
-     * @private
-     */
-    this._contentEl = contentEl;
-
-    window.addEventListener('hashchange', e =>
-      this.handleHashChange(/** @type {!HashChangeEvent} */ (e))
-    );
-
-    /**
-     * @type {!DocNavTreeController}
-     * @private
-     */
-    this._navController = new DocNavTreeController(sideNavEl);
-
-    /**
-     * @type {!MobileNavController}
-     * @private
-     */
-    this._mobileNavController = new MobileNavController(mobileNavEl);
-
-    this.updateSelectedIdFromWindowHash();
-  }
-
-  /**
-   * Handles when the location hash changes.
-   * @param {!HashChangeEvent} e
-   * @private
-   */
-  handleHashChange(e) {
-    this.updateSelectedIdFromWindowHash();
-  }
-
-  /**
-   * @private
-   */
-  updateSelectedIdFromWindowHash() {
-    const targetId = this.targetIdFromLocationHash();
-    this._navController.setSelectedId(targetId);
-    this._mobileNavController.setSelectedId(targetId);
-    if (targetId !== '') {
-      const targetEl = this._contentEl.querySelector(`[id='${targetId}']`);
-      if (targetEl) {
-        targetEl.focus();
-      }
-    }
-  }
-
-  /**
-   * @return {!string}
-   */
-  targetIdFromLocationHash() {
-    return window.location.hash && window.location.hash.substr(1);
-  }
-}
-
-/**
- * Controller for the navigation element used on smaller viewports. It utilizes
- * a native <select> element for interactivity and a styled <label> for
- * displaying the selected option.
- *
- * It presumes a fixed header and that the container for the control will be
- * sticky right below the header when scrolled enough.
- */
-class MobileNavController {
-  /**
-   * @param {!Element} el
-   */
-  constructor(el) {
-    /**
-     * @type {!Element}
-     * @private
-     */
-    this._el = /** @type {!Element} */ (el);
-
-    /**
-     * @type {!HTMLSelectElement}
-     * @private
-     */
-    this._selectEl = /** @type {!HTMLSelectElement} */ (el.querySelector('select'));
-
-    /**
-     * @type {!Element}
-     * @private
-     */
-    this._labelTextEl = /** @type {!Element} */ (el.querySelector('.js-mobileNavSelectText'));
-
-    this._selectEl.addEventListener('change', e =>
-      this.handleSelectChange(/** @type {!Event} */ (e))
-    );
-
-    // We use a slight hack to detect if the mobile nav container is pinned to
-    // the bottom of the site header. The root viewport of an IntersectionObserver
-    // is inset by the header height plus one pixel to ensure that the container is
-    // considered “out of view” when in a fixed position and can be styled appropriately.
-    const ROOT_TOP_MARGIN = '-57px';
-
-    this._intersectionObserver = new IntersectionObserver(
-      (entries, observer) => this.intersectionObserverCallback(entries, observer),
-      {
-        rootMargin: `${ROOT_TOP_MARGIN} 0px 0px 0px`,
-        threshold: 1.0,
-      }
-    );
-    this._intersectionObserver.observe(this._el);
-  }
-
-  /**
-   * @param {string} id
-   */
-  setSelectedId(id) {
-    this._selectEl.value = id;
-    this.updateLabelText();
-  }
-
-  /**
-   * @private
-   */
-  updateLabelText() {
-    const selectedIndex = this._selectEl.selectedIndex;
-    if (selectedIndex === -1) {
-      this._labelTextEl.textContent = '';
-      return;
-    }
-    this._labelTextEl.textContent = this._selectEl.options[selectedIndex].textContent;
-  }
-
-  /**
-   * @param {!Event} e
-   * @private
-   */
-  handleSelectChange(e) {
-    window.location.hash = `#${e.target.value}`;
-    this.updateLabelText();
-  }
-
-  /**
-   * @param {!Array<IntersectionObserverEntry>} entries
-   * @param {!IntersectionObserver} observer
-   * @private
-   */
-  intersectionObserverCallback(entries, observer) {
-    const SHADOW_CSS_CLASS = 'DocNavMobile--withShadow';
-    entries.forEach(entry => {
-      // entry.isIntersecting isn’t reliable on Firefox.
-      const fullyInView = entry.intersectionRatio === 1.0;
-      entry.target.classList.toggle(SHADOW_CSS_CLASS, !fullyInView);
-    });
-  }
-}
-
-new DocPageController(
-  document.querySelector('.js-sideNav'),
-  document.querySelector('.js-mobileNav'),
-  document.querySelector('.js-docContent')
-);
diff --git a/content/static/js/unit.js b/content/static/js/unit.js
index 492f27a..d9c5981 100644
--- a/content/static/js/unit.js
+++ b/content/static/js/unit.js
@@ -5,20 +5,10 @@
  * license that can be found in the LICENSE file.
  */
 
-import { AccordionController } from './accordion.js';
 import { CopyToClipboardController } from './clipboard.js';
 import './toggle-tip.js';
 
 /**
- * Instantiates accordion controller for the left sidebar.
- * Can be removed when readme-outline experiment is turned on.
- */
-const accordion = document.querySelector('.js-accordion');
-if (accordion) {
-  new AccordionController(accordion);
-}
-
-/**
  * Instantiates CopyToClipboardController controller copy buttons
  * on the unit page.
  */
diff --git a/internal/experiment.go b/internal/experiment.go
index b4fa136..7a8de4c 100644
--- a/internal/experiment.go
+++ b/internal/experiment.go
@@ -6,18 +6,14 @@
 package internal
 
 const (
-	ExperimentGoldmark           = "goldmark"
 	ExperimentNotAtLatest        = "not-at-latest"
-	ExperimentReadmeOutline      = "readme-outline"
 	ExperimentUnitSidebarDetails = "unit-sidebar-details"
 )
 
 // Experiments represents all of the active experiments in the codebase and
 // a description of each experiment.
 var Experiments = map[string]string{
-	ExperimentGoldmark:           "Enable the usage of rendering markdown using goldmark instead of blackfriday.",
 	ExperimentNotAtLatest:        "Enable the display of a 'not at latest' badge.",
-	ExperimentReadmeOutline:      "Enable the readme outline in the side nav.",
 	ExperimentUnitSidebarDetails: "Enable the details section in the right sidebar.",
 }
 
diff --git a/internal/frontend/readme_test.go b/internal/frontend/readme_test.go
index 888ffac..acd1aa0 100644
--- a/internal/frontend/readme_test.go
+++ b/internal/frontend/readme_test.go
@@ -18,7 +18,7 @@
 )
 
 func TestReadme(t *testing.T) {
-	ctx := experiment.NewContext(context.Background(), internal.ExperimentGoldmark)
+	ctx := experiment.NewContext(context.Background())
 	unit := sample.UnitEmpty(sample.PackagePath, sample.ModulePath, sample.VersionString)
 	for _, test := range []struct {
 		name        string
@@ -396,7 +396,7 @@
 }
 
 func TestReadmeLinks(t *testing.T) {
-	ctx := experiment.NewContext(context.Background(), internal.ExperimentGoldmark)
+	ctx := experiment.NewContext(context.Background())
 	unit := sample.UnitEmpty(sample.PackagePath, sample.ModulePath, sample.VersionString)
 	for _, test := range []struct {
 		name     string
diff --git a/internal/frontend/server_test.go b/internal/frontend/server_test.go
index 292e07d..36eb94f 100644
--- a/internal/frontend/server_test.go
+++ b/internal/frontend/server_test.go
@@ -1065,11 +1065,11 @@
 			testCasesFunc: serverTestCases,
 		},
 		{
-			name: "goldmark and readme outline experiments",
+			name: "with experiment not-at-latest",
 			testCasesFunc: func() []serverTestCase {
 				return append(serverTestCases(), linksTestCases...)
 			},
-			experiments: []string{internal.ExperimentReadmeOutline, internal.ExperimentGoldmark, internal.ExperimentNotAtLatest},
+			experiments: []string{internal.ExperimentNotAtLatest},
 		},
 	} {
 		t.Run(test.name, func(t *testing.T) {
@@ -1294,7 +1294,7 @@
 		{"unit_details", nil, UnitPage{}},
 		{
 			"unit_details",
-			[]string{"unit_outline", "legacy_unit_outline", "unit_readme", "unit_doc", "unit_files", "unit_directories"},
+			[]string{"unit_outline", "unit_readme", "unit_doc", "unit_files", "unit_directories"},
 			MainDetails{},
 		},
 		{"unit_importedby", nil, UnitPage{}},
diff --git a/internal/frontend/unit_main.go b/internal/frontend/unit_main.go
index 14aa4e4..0f2ae28 100644
--- a/internal/frontend/unit_main.go
+++ b/internal/frontend/unit_main.go
@@ -18,7 +18,6 @@
 	"golang.org/x/mod/semver"
 	"golang.org/x/pkgsite/internal"
 	"golang.org/x/pkgsite/internal/derrors"
-	"golang.org/x/pkgsite/internal/experiment"
 	"golang.org/x/pkgsite/internal/godoc"
 	"golang.org/x/pkgsite/internal/godoc/dochtml"
 	"golang.org/x/pkgsite/internal/log"
@@ -182,7 +181,7 @@
 	// links.
 	// In the unlikely event that the module is redistributable but the unit is
 	// not, we will not show the module links on the unit page.
-	if unit.Path != unit.ModulePath && unit.IsRedistributable && experiment.IsActive(ctx, internal.ExperimentGoldmark) {
+	if unit.Path != unit.ModulePath && unit.IsRedistributable {
 		modReadme, err := ds.GetModuleReadme(ctx, unit.ModulePath, unit.Version)
 		if err != nil && !errors.Is(err, derrors.NotFound) {
 			return nil, err
@@ -243,28 +242,14 @@
 }
 
 // readmeContent renders the readme to html and collects the headings
-// into an outline when the goldmark experiment active.
+// into an outline.
 func readmeContent(ctx context.Context, u *internal.Unit) (_ *Readme, err error) {
 	defer derrors.Wrap(&err, "readmeContent(%q, %q, %q)", u.Path, u.ModulePath, u.Version)
 	defer middleware.ElapsedStat(ctx, "readmeContent")()
 	if !u.IsRedistributable {
 		return &Readme{}, nil
 	}
-	mi := moduleInfo(&u.UnitMeta)
-	var readme *Readme
-	if experiment.IsActive(ctx, internal.ExperimentGoldmark) {
-		readme, err = ProcessReadme(ctx, u)
-	} else {
-		var h safehtml.HTML
-		h, err = LegacyReadmeHTML(ctx, mi, u.Readme)
-		if err == nil {
-			readme = &Readme{HTML: h}
-		}
-	}
-	if err != nil {
-		return nil, err
-	}
-	return readme, nil
+	return ProcessReadme(ctx, u)
 }
 
 func getNestedModules(ctx context.Context, ds internal.DataSource, um *internal.UnitMeta, sds []*Subdirectory) ([]*NestedModule, error) {
diff --git a/internal/godoc/dochtml/dochtml.go b/internal/godoc/dochtml/dochtml.go
index 91c17f9..bb598a9 100644
--- a/internal/godoc/dochtml/dochtml.go
+++ b/internal/godoc/dochtml/dochtml.go
@@ -25,9 +25,7 @@
 	"github.com/google/safehtml/legacyconversions"
 	"github.com/google/safehtml/template"
 	"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/godoc/dochtml/internal/render"
 	"golang.org/x/pkgsite/internal/godoc/internal/doc"
 )
@@ -144,16 +142,9 @@
 		return html
 	}
 
-	var outline safehtml.HTML
-	if experiment.IsActive(ctx, internal.ExperimentReadmeOutline) {
-		outline = exec("outline.tmpl")
-	} else {
-		outline = exec("sidenav.tmpl")
-	}
-
 	parts := &Parts{
 		Body:          exec("body.tmpl"),
-		Outline:       outline,
+		Outline:       exec("outline.tmpl"),
 		MobileOutline: exec("sidenav-mobile.tmpl"),
 		// links must be called after body, because the call to
 		// render_doc_extract_links in body.tmpl creates the links.
diff --git a/internal/godoc/dochtml/dochtml_test.go b/internal/godoc/dochtml/dochtml_test.go
index 34aaadf..fa59dcc 100644
--- a/internal/godoc/dochtml/dochtml_test.go
+++ b/internal/godoc/dochtml/dochtml_test.go
@@ -30,6 +30,7 @@
 	in           = htmlcheck.In
 	hasAttr      = htmlcheck.HasAttr
 	hasHref      = htmlcheck.HasHref
+	hasText 		 = htmlcheck.HasText
 	hasExactText = htmlcheck.HasExactText
 )
 
@@ -72,7 +73,7 @@
 	}
 
 	checker = in(".DocNav-notes",
-		in("#nav-group-notes", in("li", in("a", hasHref("#pkg-note-BUG"), hasExactText("Bugs")))))
+		in("#nav-group-notes", in("li", in("a", hasHref("#pkg-note-BUG"), hasText("Bugs")))))
 	if err := checker(htmlDoc); err != nil {
 		t.Errorf("note check: %v", err)
 	}
@@ -131,7 +132,7 @@
 	}
 
 	checker = in(".DocNav-notes",
-		in("#nav-group-notes", in("li", in("a", hasHref("#pkg-note-BUG"), hasExactText("Bugs")))))
+		in("#nav-group-notes", in("li", in("a", hasHref("#pkg-note-BUG"), hasText("Bugs")))))
 	if err := checker(sidenavDoc); err != nil {
 		t.Errorf("note check: %v", err)
 	}
diff --git a/internal/godoc/dochtml/template.go b/internal/godoc/dochtml/template.go
index 18c0cbe..d341b44 100644
--- a/internal/godoc/dochtml/template.go
+++ b/internal/godoc/dochtml/template.go
@@ -34,7 +34,6 @@
 			ParseFilesFromTrustedSources(
 				join(dir, tc("unit.tmpl")),
 				join(dir, tc("outline.tmpl")),
-				join(dir, tc("sidenav.tmpl")),
 				join(dir, tc("sidenav-mobile.tmpl")),
 				join(dir, tc("body.tmpl")),
 				example,
diff --git a/internal/middleware/secureheaders.go b/internal/middleware/secureheaders.go
index 2fe0d23..b5e8631 100644
--- a/internal/middleware/secureheaders.go
+++ b/internal/middleware/secureheaders.go
@@ -26,8 +26,7 @@
 	// From content/static/html/pages/unit_details.tmpl
 	"'sha256-CFun5NgnYeEpye8qcbQPq5Ycwavi4IXuZiIzSMNqRUw='",
 	"'sha256-IHdniK/yZ8URNA2OYbc4R7BssOAe3/dFrSQW7PxEEfM='",
-	"'sha256-5ThDRcuVP5qPTu7X6eUxhVjOI8mccPcKwzrWDReVV24='",
-	"'sha256-FZ2G7vOsuMYf1kUB+6G3sewY2N9djmeB36q2IBEdBUE='",
+	"'sha256-hb8VdkRSeBmkNlbshYmBnkYWC/BYHCPiz5s7liRcZNM='",
 }
 
 // SecureHeaders adds a content-security-policy and other security-related